@wji.ai/cli 0.1.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 +242 -0
- package/dist/commands/agent.js +274 -0
- package/dist/commands/asset.js +241 -0
- package/dist/commands/auth.js +216 -0
- package/dist/commands/canvas.js +915 -0
- package/dist/commands/config.js +113 -0
- package/dist/commands/fsnode.js +252 -0
- package/dist/commands/gen.js +366 -0
- package/dist/commands/model.js +134 -0
- package/dist/commands/org.js +85 -0
- package/dist/commands/preset.js +176 -0
- package/dist/commands/profile.js +129 -0
- package/dist/commands/skill.js +272 -0
- package/dist/commands/workspace.js +305 -0
- package/dist/core/client.js +252 -0
- package/dist/core/config.js +95 -0
- package/dist/core/output.js +143 -0
- package/dist/core/prompt.js +118 -0
- package/dist/core/zip.js +87 -0
- package/dist/index.js +94 -0
- package/package.json +49 -0
- package/skill/wji/SKILL.md +398 -0
- package/skill/wji/reference/canvas-recipes.md +179 -0
- package/skill/wji/reference/commands.md +381 -0
|
@@ -0,0 +1,398 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: wji
|
|
3
|
+
description: Drive the WJI AI platform from the terminal with the `wji` CLI — sign in, manage workspaces and the fsnode/dataset tree, upload assets, generate images/video/audio and poll the results, and work on Infinite Canvas nodes (read the user's selected nodes, create generate nodes, connect references), and manage models, agents, prompt presets and your profile. Use whenever a task mentions WJI, wji-backend, a WJI workspace, canvas, fsnode, dataset node, or asks to generate media on WJI.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# WJI CLI
|
|
7
|
+
|
|
8
|
+
`wji` is a thin, scriptable client over the WJI API. Every command accepts
|
|
9
|
+
`--json`, so prefer `--json` piped through `jq` when you need to read a value,
|
|
10
|
+
and the human table output when you are showing the user a result.
|
|
11
|
+
|
|
12
|
+
## Before anything else
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
wji auth whoami --json # confirms endpoint, credential, org context
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
- `wji: command not found`: the CLI is not on PATH. From the `wji-cli` repo,
|
|
19
|
+
`npm run build`, then link it where the user can write without sudo —
|
|
20
|
+
`ln -s "$PWD/dist/index.js" ~/.local/bin/wji` (if `~/.local/bin` is on
|
|
21
|
+
PATH). `npm link` fails with `EACCES` when the global prefix is root-owned;
|
|
22
|
+
don't reach for `sudo`.
|
|
23
|
+
|
|
24
|
+
- Exit code `77` means the credential is missing or rejected. Tell the user to
|
|
25
|
+
run `wji auth login` (interactive) or export `WJI_API_KEY`. **Never ask the
|
|
26
|
+
user to paste a password into the conversation and never type one into
|
|
27
|
+
`--password` yourself** — `wji auth login` prompts without echoing.
|
|
28
|
+
- `wji config show` reveals which endpoint and profile are active. A local
|
|
29
|
+
backend is `wji config set endpoint http://localhost:3002` — `:3000` is the
|
|
30
|
+
web frontend, not the API.
|
|
31
|
+
- **Running several `wji` commands in parallel? Prefer an API key**
|
|
32
|
+
(`WJI_API_KEY`, or `wji auth key create <name> --save`). A JWT login rotates
|
|
33
|
+
its refresh token, and the server revokes *every* session if a refresh token
|
|
34
|
+
is ever replayed. The CLI serializes refreshes across processes, but a key
|
|
35
|
+
never refreshes at all. A JWT profile that keeps returning 401 needs one
|
|
36
|
+
`wji auth login`.
|
|
37
|
+
|
|
38
|
+
## The mental model
|
|
39
|
+
|
|
40
|
+
```
|
|
41
|
+
organization (X-Org-Id header, optional)
|
|
42
|
+
└── workspace wji ws
|
|
43
|
+
├── apps (Dataset, Files, InfiniteCanvas, …)
|
|
44
|
+
└── fsnode tree wji fs
|
|
45
|
+
└── dataset nodes wji dataset
|
|
46
|
+
generation ─> history entry ─> assets wji gen / wji history / wji asset
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
- A **workspace** scopes billing, quota and members.
|
|
50
|
+
- The **fsnode tree** is the file system inside a workspace: folders and files,
|
|
51
|
+
each with a free-form `content` JSON object.
|
|
52
|
+
- A **dataset node** is an fsnode with mimetype `workspace/dataset` whose
|
|
53
|
+
`content` carries `{ type, description }` — these are the "ideas"
|
|
54
|
+
(outline, screenplay, character, location, prop, outfit, scene, shot, other)
|
|
55
|
+
that feed generation. See *Character datasets* below.
|
|
56
|
+
- **Generation is asynchronous.** Submitting returns a history entry; the
|
|
57
|
+
assets inside it start `pending` and become `ready`.
|
|
58
|
+
|
|
59
|
+
## Set a working context first
|
|
60
|
+
|
|
61
|
+
Most commands take `--workspace`, but setting a default is less error-prone:
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
wji ws list
|
|
65
|
+
wji ws use <workspaceId>
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
After that, `wji ws get`, `wji fs`, `wji gen` and `wji preset list` all default
|
|
69
|
+
to that workspace. Use `wji ws use` rather than repeating `--workspace`.
|
|
70
|
+
|
|
71
|
+
## Reading and editing the tree
|
|
72
|
+
|
|
73
|
+
```bash
|
|
74
|
+
wji ws fs # whole workspace tree
|
|
75
|
+
wji ws fs --app <appId> # one app's tree
|
|
76
|
+
wji fs tree <nodeId> --depth 2
|
|
77
|
+
wji fs ls <folderId>
|
|
78
|
+
wji fs get <nodeId> --json | jq .content
|
|
79
|
+
|
|
80
|
+
wji fs mkdir <parentId> characters --nickname 角色
|
|
81
|
+
wji dataset new <folderId> "Ada" -t character -d "a tired detective"
|
|
82
|
+
wji fs describe <nodeId> @description.md
|
|
83
|
+
wji fs set <nodeId> --images <assetId> <assetId>
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
`wji fs set --content` **replaces** the whole content object. To change one
|
|
87
|
+
field, read it first (`wji fs get <id> --json | jq .content`), merge, then
|
|
88
|
+
write — or use `wji fs describe`, which merges `content.description` for you.
|
|
89
|
+
|
|
90
|
+
Several GET endpoints are cached server-side for 10 seconds, so a plain read
|
|
91
|
+
immediately after a write can come back stale. `wji fs describe` and
|
|
92
|
+
`wji preset update` already bypass that cache; if you hand-roll a
|
|
93
|
+
read-merge-write with `--json`, expect the read to lag briefly.
|
|
94
|
+
|
|
95
|
+
## Generating media
|
|
96
|
+
|
|
97
|
+
Always pick the model from the live list rather than guessing a name:
|
|
98
|
+
|
|
99
|
+
```bash
|
|
100
|
+
wji models list --feature image
|
|
101
|
+
wji models get <model> # ratios, max n, reference support, --set params
|
|
102
|
+
wji gen cost -t image -m <model> -n 4
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
**Pass the value in the MODEL column to `-m`** — that is the model's `nickname`,
|
|
106
|
+
which is unique. The `name` column is shown only when it differs, and names do
|
|
107
|
+
collide across providers (two different `seedance-2.0` entries exist), so `-m`
|
|
108
|
+
with a bare name resolves to whichever the server picks first.
|
|
109
|
+
|
|
110
|
+
Then submit. Add `--wait` when the user is waiting on the result:
|
|
111
|
+
|
|
112
|
+
```bash
|
|
113
|
+
wji gen image -m <modelName> -p "a rainy alley at dusk" -n 4 --ratio 16:9 --wait
|
|
114
|
+
wji gen video -m <modelName> -p "slow pan" -d 5 --start-image <assetId> --wait --timeout 1200
|
|
115
|
+
wji gen audio -m <modelName> -p "rain on a tin roof" --wait
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
- References are `assetId[:label[:weight]]`: `--ref 65f0…:hero:0.6`. Reference
|
|
119
|
+
*assets*, not file paths — upload first with `wji asset upload`.
|
|
120
|
+
- Model-specific parameters go through `--set` (`--set quality=high`); read the
|
|
121
|
+
valid keys from `wji models get`.
|
|
122
|
+
- `--fsnode <id>` files the result onto a node; `--tags` labels the history.
|
|
123
|
+
- Video can take minutes. Without `--wait` you get a history id back:
|
|
124
|
+
`wji history get <id> --wait` resumes polling, and `--timeout` is in seconds.
|
|
125
|
+
- On timeout the task is usually still running — re-poll rather than
|
|
126
|
+
resubmitting, which would charge credits twice.
|
|
127
|
+
- `wji models get` prints the model's own parameter list with defaults and
|
|
128
|
+
allowed values. Only `--set` keys listed there take effect; anything else is
|
|
129
|
+
ignored silently.
|
|
130
|
+
- Billing inputs are server-owned and stripped from `--set` / `--values`:
|
|
131
|
+
`num_images`, `referenceImageCount`, `referenceVideoTotalDuration`,
|
|
132
|
+
`output_resolution` and every `*Info` field. Use `-n` for the count and the
|
|
133
|
+
real reference flags (`--ref`, `--ref-video`, …) for references.
|
|
134
|
+
|
|
135
|
+
### Choosing a model (house guidance)
|
|
136
|
+
|
|
137
|
+
Use this to pick a model when the user hasn't named one, and to explain the
|
|
138
|
+
trade-off when they have. Exact nicknames differ between environments — always
|
|
139
|
+
confirm with `wji models list --feature <image|video>` and `wji models get`.
|
|
140
|
+
|
|
141
|
+
**Images:** prefer **GPT Image 2.5** (`gpt-image-2.5-sunburst` for new images
|
|
142
|
+
and big changes such as character sheets; `gpt-image-2.5-flare` for edits that
|
|
143
|
+
keep the composition), **Nano Banana 2** or **Nano Banana Pro**.
|
|
144
|
+
|
|
145
|
+
**Video — reference models over first/last-frame models.** A family usually
|
|
146
|
+
has both:
|
|
147
|
+
|
|
148
|
+
| Kind | Examples | Takes |
|
|
149
|
+
| --- | --- | --- |
|
|
150
|
+
| **Ref** (preferred) | `seedance-2.5-ref`, `seedance-2.0-ref`, `seedance-2.0-fast-ref`, `Wan 3.0 Ref`, `Wan 3.0 Prime Ref`, `minimax-h3-ref`, `minimax-h3-max-ref` | reference **images, videos and audio** together (e.g. a character sheet + a motion clip + a voice line) |
|
|
151
|
+
| First/last frame | `seedance-2.5`, `seedance-2.0`, `Wan 3.0`, `minimax-h3-i2v`, `minimax-h3-max-i2v` | only a start and/or end image |
|
|
152
|
+
|
|
153
|
+
Use a first/last-frame model only when the user explicitly wants a shot to
|
|
154
|
+
start or end on an exact frame. With a Ref model, pass images with `--ref`,
|
|
155
|
+
videos with `--ref-video` and audio with `--ref-audio` (or connect them on the
|
|
156
|
+
canvas); `wji models get` shows each model's caps (e.g. Wan 3.0 Ref: 10 images,
|
|
157
|
+
video/audio ≤ 15 s total).
|
|
158
|
+
|
|
159
|
+
**Video trade-offs** (best first):
|
|
160
|
+
|
|
161
|
+
| | Ranking |
|
|
162
|
+
| --- | --- |
|
|
163
|
+
| **Quality** | Seedance 2.5 › Seedance 2.0 ≈ Wan 3.0 › MiniMax H3 ≈ Seedance 2.0 Fast › MiniMax H3 Max |
|
|
164
|
+
| **Speed** (fastest first) | MiniMax H3 Max › Seedance 2.0 Fast › Wan 3.0 Prime › Seedance 2.0 ≈ Wan 3.0 › Seedance 2.5 |
|
|
165
|
+
| **Price** (cheapest first) | MiniMax H3 Max › Seedance 2.0 Fast › Wan 3.0 Prime › Seedance 2.0 ≈ Wan 3.0 › Seedance 2.5 |
|
|
166
|
+
|
|
167
|
+
So: **Seedance 2.5** for final, hero shots; **Seedance 2.0 / Wan 3.0** as the
|
|
168
|
+
balanced default; **Seedance 2.0 Fast / MiniMax H3 Max** for drafts, tests and
|
|
169
|
+
large batches. The ranking is a guide — quote the real number from
|
|
170
|
+
`wji gen cost` / `wji canvas gen` before spending.
|
|
171
|
+
|
|
172
|
+
### Limits (per account)
|
|
173
|
+
|
|
174
|
+
| Limit | Value | When exceeded |
|
|
175
|
+
| --- | --- | --- |
|
|
176
|
+
| Submissions per minute | image 30 · video 10 · audio 20 | HTTP 429 |
|
|
177
|
+
| Queued + running jobs | FREE 3 · VIP 10 · SVIP 25 | HTTP 429 `排隊中的任務已達上限` |
|
|
178
|
+
|
|
179
|
+
**Never fire more generations at once than the queue allows.** Submit up to the
|
|
180
|
+
cap, wait for jobs to finish (`wji history get <id> --wait`), then submit the
|
|
181
|
+
next batch. A 429 means the request was rejected before anything was charged —
|
|
182
|
+
wait and resubmit; do not retry in a tight loop.
|
|
183
|
+
|
|
184
|
+
```bash
|
|
185
|
+
wji history list --mode video
|
|
186
|
+
wji history download <historyId> -o ./out
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
## Character datasets
|
|
190
|
+
|
|
191
|
+
A character is only reusable across shots when its dataset carries all three:
|
|
192
|
+
|
|
193
|
+
1. **Headshot** — a clean front-facing portrait on a plain background (sets
|
|
194
|
+
the face). Make it the dataset's `icon`.
|
|
195
|
+
2. **Character sheet** — full-body front/side/back turnaround plus a few
|
|
196
|
+
expressions and outfit details, in the same outfit (sets body, clothes and
|
|
197
|
+
consistency). Generate it from the headshot with GPT Image 2.5 Sunburst.
|
|
198
|
+
3. **Voice** — a short, clean audio sample of the character speaking (sets the
|
|
199
|
+
voice for Ref video models that take `--ref-audio`). Set it as
|
|
200
|
+
`primaryAudio`.
|
|
201
|
+
|
|
202
|
+
All three are assets attached to the dataset node (`images` holds images and
|
|
203
|
+
audio alike). When creating or reviewing a character, check which are missing
|
|
204
|
+
and offer to make them; when generating video of that character, pass the
|
|
205
|
+
headshot and sheet as image references and the voice as an audio reference to
|
|
206
|
+
a Ref model.
|
|
207
|
+
|
|
208
|
+
```bash
|
|
209
|
+
wji fs get <datasetId> --scope full --json | jq '{images: [.images[]? | {id, type}], icon, primaryAudio}'
|
|
210
|
+
wji fs set <datasetId> --images <headshot> <sheet> <voice> --icon <headshot> --set primaryAudio=<voice>
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
`--images` replaces the whole list — read the current list first and keep
|
|
214
|
+
what is already there.
|
|
215
|
+
|
|
216
|
+
## Assets
|
|
217
|
+
|
|
218
|
+
```bash
|
|
219
|
+
wji asset upload ./ref.png # returns an asset id
|
|
220
|
+
wji asset import https://example.com/x.jpg
|
|
221
|
+
wji asset status <id> <id> # pending | ready | cancelled
|
|
222
|
+
wji asset download <id> [<id>…] -o ./out # keeps the file extension, so you can view images
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
- Uploaded assets attach to the default workspace unless you pass `--workspace`.
|
|
226
|
+
- `asset status` only returns assets you created or that sit in a workspace
|
|
227
|
+
you belong to; other ids are silently omitted (the CLI warns how many).
|
|
228
|
+
- `asset import` refuses private and internal addresses (`不允許存取該主機`).
|
|
229
|
+
Some public hosts also block server-side downloads (`無法下載或處理該圖片 URL`)
|
|
230
|
+
— download the file yourself and `wji asset upload` it instead.
|
|
231
|
+
- `.html`, `.svg` and script uploads are stored as `application/octet-stream`
|
|
232
|
+
and served as attachments, so they will not render inline.
|
|
233
|
+
|
|
234
|
+
## Skills
|
|
235
|
+
|
|
236
|
+
Skills are SKILL.md bundles. **System skills** are built-in and read-only;
|
|
237
|
+
**user skills** are yours to author and attach to agents. Only `.md` files
|
|
238
|
+
persist server-side — scripts belong to system skills.
|
|
239
|
+
|
|
240
|
+
```bash
|
|
241
|
+
wji skill system # built-in skills you can attach
|
|
242
|
+
wji skill push ./my-skill # zip a local folder (SKILL.md at root) and upload
|
|
243
|
+
wji skill list
|
|
244
|
+
wji skill pull <id> ./my-skill # write a bundle back to disk to edit it
|
|
245
|
+
wji skill get <id> # metadata + file list
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
Attach skills to an agent and manage its version history:
|
|
249
|
+
|
|
250
|
+
```bash
|
|
251
|
+
wji agent skill-add <agentId> system:image user:<skillId>
|
|
252
|
+
wji agent skills <agentId>
|
|
253
|
+
wji agent versions <agentId> # every edit auto-snapshots a version
|
|
254
|
+
wji agent restore <agentId> <versionId>
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
Skill refs are `system:<key>` or `user:<skillId>` (a bare id means `user:`).
|
|
258
|
+
System keys currently include `image`, `document`, `workspace-dataset`,
|
|
259
|
+
`canvas` and `seedance-25` — confirm with `wji skill system`.
|
|
260
|
+
When authoring, edit a pulled folder and `skill push` it again, or
|
|
261
|
+
`skill update <id> --dir ./my-skill` to replace its files.
|
|
262
|
+
|
|
263
|
+
Bundle limits: at most 200 markdown files, 2MB per file, 20MB in total and a
|
|
264
|
+
5MB zip; 50 user skills per account. `skill update --dir` sends files in the
|
|
265
|
+
request body, where each file is capped far lower, at **200,000 characters** —
|
|
266
|
+
use `skill push` for large files.
|
|
267
|
+
|
|
268
|
+
## Canvas
|
|
269
|
+
|
|
270
|
+
An Infinite Canvas holds **nodes** (text, title, comment, image, video, audio…)
|
|
271
|
+
and **edges** between them. An edge into a media node makes the source one of
|
|
272
|
+
its **references**, numbered per kind in edge order: `@image1`, `@image2`,
|
|
273
|
+
`@video1`. A media node is either a **display** node (shows an existing asset)
|
|
274
|
+
or a **generate** node (prompt + model + settings; generating fills in its
|
|
275
|
+
asset).
|
|
276
|
+
|
|
277
|
+
**The link.** The user opens a canvas in the browser and presses the link
|
|
278
|
+
button in its top bar. That stores the open workspace, canvas and **the nodes
|
|
279
|
+
they have selected** on their account for 5 minutes (the tab renews it while
|
|
280
|
+
open). Every `wji canvas` command then targets that canvas; pass
|
|
281
|
+
`--canvas <id>` to work on another one (`wji canvas list`).
|
|
282
|
+
|
|
283
|
+
```bash
|
|
284
|
+
wji canvas status # linked canvas + selected nodes (ids, asset URLs, settings)
|
|
285
|
+
wji canvas nodes # every node; * marks generate nodes
|
|
286
|
+
wji canvas get <nodeId> # full detail incl. references
|
|
287
|
+
wji asset download <assetId…> -o <dir> # then look at the images yourself
|
|
288
|
+
|
|
289
|
+
wji canvas add video --from <imgNode> <imgNode> -m <model> -r 16:9 -d 8 -p "@image1 … @image2 …"
|
|
290
|
+
wji canvas add text -t "shot list…" --at 0,600
|
|
291
|
+
wji canvas set <nodeId> -p "new prompt" # merges: other settings stay
|
|
292
|
+
wji canvas set <nodeId> -m <model> --resolution 720p --set seed=42
|
|
293
|
+
wji canvas connect <from> <to> / wji canvas disconnect <from> <to>
|
|
294
|
+
wji canvas gen <nodeId> --wait # costs credits — see Rules
|
|
295
|
+
wji canvas rm <nodeId…> # destructive — see Rules
|
|
296
|
+
```
|
|
297
|
+
|
|
298
|
+
- **Match the CLI to the site the user is on before anything else.** The
|
|
299
|
+
link is stored on the backend the browser talks to, so the CLI must use the
|
|
300
|
+
same one. `Cannot GET /canvas-link` (404) means the active profile points at
|
|
301
|
+
a backend without this feature — typically profile `prod`
|
|
302
|
+
(`https://api.wji.ai`) while the user linked on `http://localhost:3000`
|
|
303
|
+
(API `http://localhost:3002`). Check `wji config show`, then tell the user
|
|
304
|
+
which profile to use (`wji config use <profile>`), or run the commands with
|
|
305
|
+
`WJI_ENDPOINT=… WJI_API_KEY=…` for that backend. Don't switch their
|
|
306
|
+
profile silently, and never run canvas commands against production when the
|
|
307
|
+
link URL is localhost.
|
|
308
|
+
- If `status` says *Not linked*, ask the user to open the canvas and press the
|
|
309
|
+
link button (and to select the nodes they mean). Don't guess a canvas.
|
|
310
|
+
- The selection is **what the user means by "these" / "the selected images"**.
|
|
311
|
+
Use those node ids for `--from`; use each node's `assetId` to download and
|
|
312
|
+
look at the picture before writing a prompt about it.
|
|
313
|
+
- Prompts are literal: `-p "@image1 …"` is text, not a file. Use
|
|
314
|
+
`--prompt-file` for a file and `-p -` for stdin.
|
|
315
|
+
- Pick the model from `wji models list --feature video` and read
|
|
316
|
+
`wji models get <model>` for its ratios, duration range and `--set` keys.
|
|
317
|
+
`add`/`set` validate against it, fill the model's defaults, and turn
|
|
318
|
+
auto-duration off when you pass `-d`.
|
|
319
|
+
- **A model the user names may not accept references.** Check the REFS column
|
|
320
|
+
of `wji models list`: a family often has a text-only model and a `Ref`
|
|
321
|
+
variant (`Wan 3.0` has none, `Wan 3.0 Ref` takes up to 10). If the request
|
|
322
|
+
builds on selected images, use the variant with references and say so —
|
|
323
|
+
otherwise the selection is silently ignored and the person or object in the
|
|
324
|
+
video will not match.
|
|
325
|
+
- Model nicknames can contain spaces (`"Wan 3.0 Ref"`) — quote them.
|
|
326
|
+
Parameter values are case-sensitive and differ per model (`480P` for Wan,
|
|
327
|
+
`480p` for Seedance); copy them from `wji models get`.
|
|
328
|
+
- Defaults you did not ask about still shape the result: the ratio falls back
|
|
329
|
+
to the workspace's (often 16:9 — ask or pick 9:16 for a portrait-style clip),
|
|
330
|
+
`audio` may default on, and **auto-duration** lets the model choose the
|
|
331
|
+
length. With auto-duration the cost `canvas gen` shows is an estimate for
|
|
332
|
+
the node's configured seconds; the final charge follows the real length.
|
|
333
|
+
Mention these when you report the node, and pass `-d` if the user needs a
|
|
334
|
+
fixed length or a fixed price.
|
|
335
|
+
- Take new ids from the command's own output (`wji --json canvas add … | jq
|
|
336
|
+
-r .id`), not by searching names — names repeat on a canvas. In zsh a
|
|
337
|
+
variable holding several ids is not word-split; pass the ids literally.
|
|
338
|
+
- Changes show up live in the user's open canvas; there's no need to ask them
|
|
339
|
+
to reload.
|
|
340
|
+
- `canvas gen` sends exactly what the canvas's own Generate button sends
|
|
341
|
+
(references in order, text-node references prefixed to the prompt). Nodes
|
|
342
|
+
referencing dataset, bundle, table or YouTube nodes must be generated from
|
|
343
|
+
the browser.
|
|
344
|
+
|
|
345
|
+
See `reference/canvas-recipes.md` for end-to-end examples.
|
|
346
|
+
|
|
347
|
+
## Everything else
|
|
348
|
+
|
|
349
|
+
```bash
|
|
350
|
+
wji preset list -k "hero" # usable presets; also `mine`, `public`, `workspace`
|
|
351
|
+
wji preset get <id> --json | jq -r .prompt
|
|
352
|
+
wji agent list # marketplace; `wji agent mine` for yours
|
|
353
|
+
wji profile show
|
|
354
|
+
wji profile wallet # credit balance before an expensive batch
|
|
355
|
+
wji org list && wji org use <orgId>
|
|
356
|
+
```
|
|
357
|
+
|
|
358
|
+
## Rules
|
|
359
|
+
|
|
360
|
+
- **Confirm before destroying — in the conversation, one target at a time.**
|
|
361
|
+
These commands delete, revoke or overwrite, and none can be undone from the
|
|
362
|
+
CLI: `ws rm`, `ws app rm`, `ws member rm`, `fs rm`, `dataset rm`,
|
|
363
|
+
`asset rm`, `history rm`, `preset rm`, `skill rm`, `skill update --dir`,
|
|
364
|
+
`agent rm`, `auth key rm`, `auth key revoke`, `config rm`, `canvas rm`.
|
|
365
|
+
They prompt `[y/N]` in a terminal, but when you run them there is no
|
|
366
|
+
terminal, so they refuse unless you pass `--yes`. **The user's reply in the
|
|
367
|
+
chat is the only confirmation there is.** Before running one:
|
|
368
|
+
1. Look the target up and tell the user exactly what will go — name and id,
|
|
369
|
+
plus what goes with it: a workspace's apps and files, a folder's whole
|
|
370
|
+
subtree, the files `skill update --dir` replaces, anything still using an
|
|
371
|
+
API key, the credentials stored in a profile, the connections a canvas
|
|
372
|
+
node takes with it.
|
|
373
|
+
2. Wait for an explicit yes to *those* targets. A broad instruction such as
|
|
374
|
+
"clean up" or "delete the old ones" is not approval: list what you found
|
|
375
|
+
and ask.
|
|
376
|
+
3. Only then pass `--yes`. The approval covers the targets you listed, not
|
|
377
|
+
anything you find afterwards — new targets need a new question.
|
|
378
|
+
- **Overwrites don't prompt at all.** `fs set --content`, `--images` and
|
|
379
|
+
`--tags`, and the update commands' tag options, replace the whole value.
|
|
380
|
+
Read the current value first, and check with the user before replacing
|
|
381
|
+
anything they did not ask to change.
|
|
382
|
+
- **Generation costs credits.** Run `wji gen cost` first for anything large
|
|
383
|
+
(high `-n`, long video), show the user the number, and get agreement before
|
|
384
|
+
submitting a batch. `wji canvas gen` prints its exact cost and refuses
|
|
385
|
+
without `--yes`: run it once without `--yes` to get the number, tell the
|
|
386
|
+
user, and pass `--yes` only after they agree. Creating or editing a generate
|
|
387
|
+
node (`canvas add` / `canvas set`) costs nothing.
|
|
388
|
+
- **Never invent ids.** Look up workspace, node, asset and model ids with the
|
|
389
|
+
list commands; ids are Mongo ObjectIds, not names.
|
|
390
|
+
- **Stay inside the generation queue.** See *Limits* above — batch to the cap
|
|
391
|
+
and wait for completions rather than retrying 429s.
|
|
392
|
+
- **Lists are paginated.** `--limit` is capped at 100; `--limit -1` returns at
|
|
393
|
+
most 500 on most endpoints. Page with `--page` instead of assuming you got
|
|
394
|
+
everything.
|
|
395
|
+
- **Report failures honestly.** A failed generation surfaces as a non-zero exit
|
|
396
|
+
with the provider's message — pass it on rather than retrying silently.
|
|
397
|
+
|
|
398
|
+
See `reference/commands.md` for the full command and flag inventory.
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
# Canvas recipes
|
|
2
|
+
|
|
3
|
+
Worked examples for `wji canvas`. Each starts from the same place: the user has
|
|
4
|
+
the canvas open in the browser, has pressed the **link** button in its top bar,
|
|
5
|
+
and has selected the nodes they are talking about.
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
wji canvas status # confirms the link and lists the selected nodes
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
If it says *Not linked*, ask the user to press the link button (and select the
|
|
12
|
+
nodes) instead of guessing. If it fails with `Cannot GET /canvas-link`, the CLI
|
|
13
|
+
profile points at a different backend than the browser (e.g. `prod` while the
|
|
14
|
+
link URL is `localhost:3000`) — fix the profile first (see SKILL.md, Canvas).
|
|
15
|
+
The link lasts 5 minutes after the tab stops renewing it, so re-check `status`
|
|
16
|
+
if the user comes back later.
|
|
17
|
+
|
|
18
|
+
All ids below are placeholders — always take them from `status`, `nodes` or
|
|
19
|
+
`get`.
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
## 1. Selected images → suggest a video prompt → create the video node
|
|
24
|
+
|
|
25
|
+
> "Use the images I selected to make a video node. Suggest a prompt first."
|
|
26
|
+
|
|
27
|
+
1. Read the selection and keep the image nodes, in the order the user
|
|
28
|
+
selected them (that becomes `@image1`, `@image2`):
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
wji canvas status --json | jq '.selected[] | select(.kind=="image") | {id, name, assetId}'
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
2. Look at the pictures before writing about them:
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
wji asset download <assetId1> <assetId2> -o /tmp/canvas-refs
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
Open the downloaded files and describe what is actually there — subject,
|
|
41
|
+
setting, light, mood.
|
|
42
|
+
|
|
43
|
+
3. Pick a model that takes image references and read its limits:
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
wji models list --feature video -k <family> # REFS column must be non-empty
|
|
47
|
+
wji models get "<model>" # ratios, duration range, max references, --set keys (exact case)
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
If the user asked for a model by family name ("wan 3.0", "seedance"), choose
|
|
51
|
+
the member that accepts references (`Wan 3.0 Ref`, `seedance-2.0-fast-ref`)
|
|
52
|
+
and tell them why.
|
|
53
|
+
|
|
54
|
+
4. Settle the settings the user didn't mention: ratio (workspace default vs.
|
|
55
|
+
9:16 for a portrait subject), fixed duration or auto, audio. Then propose
|
|
56
|
+
2–3 prompts in the chat. Refer to the images as `@image1`,
|
|
57
|
+
`@image2`, matching the order you will connect them. Mention the model,
|
|
58
|
+
ratio and duration you would use. Wait for the user to pick or edit one.
|
|
59
|
+
|
|
60
|
+
5. Create the node. Nothing is charged yet:
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
wji canvas add video -n "Lake reunion" \
|
|
64
|
+
--from <imageNode1> <imageNode2> \
|
|
65
|
+
-m <model> -r 16:9 -d 8 --resolution 720p \
|
|
66
|
+
-p "@image1 paddles a canoe across a still turquoise lake at dawn; as she reaches the shore, @image2 trots down the forest path to greet her. Soft morning light, reflections, shallow depth of field."
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
The node appears next to the images in the user's canvas, wired to both,
|
|
70
|
+
with the prompt and settings filled in. Tell the user its name and that it is
|
|
71
|
+
ready to generate from the canvas or from here (recipe 4).
|
|
72
|
+
|
|
73
|
+
## 2. Write or rewrite the prompt of an existing generate node
|
|
74
|
+
|
|
75
|
+
> "This video node has two references wired in — write a better prompt for it."
|
|
76
|
+
|
|
77
|
+
```bash
|
|
78
|
+
wji canvas get <videoNode> # prompt, model, settings, references with labels
|
|
79
|
+
wji canvas get <referenceNode> # for each reference: kind, assetId, text
|
|
80
|
+
wji asset download <assetId…> -o /tmp/canvas-refs
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
Draft the prompt against the **labels `get` printed** (`@image1 ← <nodeId>`),
|
|
84
|
+
not against the order the user happened to mention things. Then:
|
|
85
|
+
|
|
86
|
+
```bash
|
|
87
|
+
wji canvas set <videoNode> -p "…" # only the prompt changes; model and settings stay
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
Text nodes connected into a generate node are sent ahead of the prompt as
|
|
91
|
+
`[node name]` + text. Don't repeat their content in the prompt.
|
|
92
|
+
|
|
93
|
+
## 3. Change generation settings
|
|
94
|
+
|
|
95
|
+
> "Make it vertical, 10 seconds, 720p, and fix the seed."
|
|
96
|
+
|
|
97
|
+
```bash
|
|
98
|
+
wji models get <model> # check 9:16 exists, duration range, seed key
|
|
99
|
+
wji canvas set <node> -r 9:16 -d 10 --resolution 720p --set seed=1234
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
`set` rejects values the model does not support and names the valid ones. It
|
|
103
|
+
merges `--set` into the existing parameters. Passing `-d` switches the
|
|
104
|
+
model's auto-duration off.
|
|
105
|
+
|
|
106
|
+
To switch model, pass `-m`. Settings the new model does not support fall back to
|
|
107
|
+
its defaults; check with `wji canvas get <node>` and tell the user what changed.
|
|
108
|
+
|
|
109
|
+
## 4. Generate directly
|
|
110
|
+
|
|
111
|
+
> "Go ahead and generate it."
|
|
112
|
+
|
|
113
|
+
```bash
|
|
114
|
+
wji canvas gen <node> # prints the cost and refuses (no terminal)
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
Tell the user the cost from that message. With auto-duration it is an
|
|
118
|
+
estimate for the node's configured seconds; say so, or set `-d` first for a
|
|
119
|
+
fixed price. Only after they agree:
|
|
120
|
+
|
|
121
|
+
```bash
|
|
122
|
+
wji canvas gen <node> --yes --wait
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
The result becomes the node's asset, so the user sees it on the canvas. Video
|
|
126
|
+
can take minutes: with a long wait, prefer submitting without `--wait` and
|
|
127
|
+
checking `wji canvas get <node>` (status `generating` → `done`/`failed`) later.
|
|
128
|
+
Never resubmit a node whose status is `generating` — that charges twice.
|
|
129
|
+
|
|
130
|
+
## 5. Storyboard fan-out
|
|
131
|
+
|
|
132
|
+
> "Here are my two character images. Make one video node per shot for this
|
|
133
|
+
> 4-shot scene."
|
|
134
|
+
|
|
135
|
+
1. Write the shot list in the chat and agree on it.
|
|
136
|
+
2. Optionally drop the script on the canvas:
|
|
137
|
+
|
|
138
|
+
```bash
|
|
139
|
+
wji canvas add text -n "Scene 3 shots" -t - < shots.txt
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
3. One generate node per shot, all wired to the same character images. Each
|
|
143
|
+
node is placed beside the references and below the previous one:
|
|
144
|
+
|
|
145
|
+
```bash
|
|
146
|
+
wji canvas add video -n "Shot 1" --from <char1> <char2> -m <model> -r 16:9 -d 5 -p "…shot 1…"
|
|
147
|
+
wji canvas add video -n "Shot 2" --from <char1> <char2> -m <model> -r 16:9 -d 5 -p "…shot 2…"
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
4. Total the cost (`wji canvas gen <node>` for each, without `--yes`) before
|
|
151
|
+
offering to generate them all.
|
|
152
|
+
|
|
153
|
+
## 6. Fix which image is `@image1`
|
|
154
|
+
|
|
155
|
+
References are numbered in connection order. To swap `@image1` and `@image2`,
|
|
156
|
+
reconnect the first one so it moves to the end:
|
|
157
|
+
|
|
158
|
+
```bash
|
|
159
|
+
wji canvas get <node> # @image1 ← A, @image2 ← B
|
|
160
|
+
wji canvas disconnect <A> <node>
|
|
161
|
+
wji canvas connect <A> <node> # now @image1 ← B, @image2 ← A
|
|
162
|
+
wji canvas set <node> -p "…" # update the prompt to the new labels
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
## 7. Image variation from a selected image
|
|
166
|
+
|
|
167
|
+
> "Make a watercolor version of the selected photo."
|
|
168
|
+
|
|
169
|
+
```bash
|
|
170
|
+
wji canvas add image -n "Watercolor" --from <photoNode> -m <imageModel> -r 16:9 \
|
|
171
|
+
-p "Turn @image1 into a soft watercolor illustration, keep the composition"
|
|
172
|
+
wji canvas gen <newNode> # cost → user agrees → --yes --wait
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
## Cleaning up
|
|
176
|
+
|
|
177
|
+
`wji canvas rm` deletes nodes and every connection touching them. It is on the
|
|
178
|
+
confirm list: name the nodes (and how many connections go with them) in the
|
|
179
|
+
chat, wait for a yes, then pass `--yes`.
|