@wji.ai/cli 0.6.1 → 0.7.1
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 +23 -3
- package/dist/index.js +7162 -76
- package/package.json +6 -9
- package/skill/backreel/SKILL.md +171 -0
- package/skill/backreel/reference/crowdfunding.md +82 -0
- package/skill/backreel/reference/enquiries.md +80 -0
- package/skill/backreel/reference/episodes.md +104 -0
- package/skill/backreel/reference/images.md +76 -0
- package/skill/npc-character/SKILL.md +111 -0
- package/skill/npc-character/examples/nagi.character.md +117 -0
- package/skill/npc-character/examples/nagi.stage.md +34 -0
- package/skill/npc-character/examples/yuzu.character.md +110 -0
- package/skill/npc-character/examples/yuzu.stage.md +30 -0
- package/skill/npc-character/reference/character-craft.md +153 -0
- package/skill/npc-character/reference/document-format.md +151 -0
- package/skill/npc-character/reference/interview.md +44 -0
- package/skill/npc-character/reference/life.md +92 -0
- package/skill/npc-character/reference/runtime.md +95 -0
- package/skill/npc-character/reference/stage-craft.md +109 -0
- package/skill/npc-character/reference/visual-kit.md +81 -0
- package/skill/npc-character/reference/voice.md +101 -0
- package/skill/wji/SKILL.md +1 -1
- package/skill/wji/reference/commands.md +25 -5
- package/dist/commands/agent.js +0 -294
- package/dist/commands/asset.js +0 -241
- package/dist/commands/auth.js +0 -216
- package/dist/commands/backreel.js +0 -320
- package/dist/commands/canvas.js +0 -1706
- package/dist/commands/class.js +0 -395
- package/dist/commands/config.js +0 -113
- package/dist/commands/crew.js +0 -205
- package/dist/commands/fsnode.js +0 -288
- package/dist/commands/gen.js +0 -352
- package/dist/commands/model.js +0 -136
- package/dist/commands/npc.js +0 -413
- package/dist/commands/org.js +0 -85
- package/dist/commands/preset.js +0 -176
- package/dist/commands/profile.js +0 -129
- package/dist/commands/skill.js +0 -272
- package/dist/commands/workspace.js +0 -470
- package/dist/core/archive.js +0 -95
- package/dist/core/client.js +0 -252
- package/dist/core/config.js +0 -95
- package/dist/core/crew.js +0 -546
- package/dist/core/members.js +0 -54
- package/dist/core/npc.js +0 -108
- package/dist/core/output.js +0 -174
- package/dist/core/prompt.js +0 -118
- package/dist/core/zip.js +0 -87
package/package.json
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wji.ai/cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.7.1",
|
|
4
4
|
"description": "Command line interface for the WJI AI platform",
|
|
5
5
|
"license": "UNLICENSED",
|
|
6
6
|
"author": "WJI AI",
|
|
7
7
|
"homepage": "https://wji.ai",
|
|
8
8
|
"repository": {
|
|
9
9
|
"type": "git",
|
|
10
|
-
"url": "git+https://github.com/ultra-instinct-ai/wji-cli.git"
|
|
10
|
+
"url": "git+https://github.com/ultra-instinct-ai/wji-cli.git",
|
|
11
|
+
"directory": "packages/cli"
|
|
11
12
|
},
|
|
12
13
|
"keywords": [
|
|
13
14
|
"wji",
|
|
@@ -30,19 +31,15 @@
|
|
|
30
31
|
"node": ">=20"
|
|
31
32
|
},
|
|
32
33
|
"scripts": {
|
|
33
|
-
"build": "
|
|
34
|
-
"dev": "
|
|
34
|
+
"build": "tsup && chmod +x dist/index.js",
|
|
35
|
+
"dev": "tsup --watch",
|
|
35
36
|
"typecheck": "tsc -p tsconfig.json --noEmit",
|
|
36
37
|
"start": "node dist/index.js",
|
|
37
|
-
"prepublishOnly": "
|
|
38
|
+
"prepublishOnly": "pnpm run build"
|
|
38
39
|
},
|
|
39
40
|
"dependencies": {
|
|
40
41
|
"commander": "^12.1.0"
|
|
41
42
|
},
|
|
42
|
-
"devDependencies": {
|
|
43
|
-
"@types/node": "^22.10.0",
|
|
44
|
-
"typescript": "^5.7.2"
|
|
45
|
-
},
|
|
46
43
|
"publishConfig": {
|
|
47
44
|
"access": "public"
|
|
48
45
|
}
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: backreel
|
|
3
|
+
description: Run a creator's works on Backreel (the film / short-drama showcase and crowdfunding site that shares accounts with WJI) with the `wji` CLI — create and publish a post (作品), prepare and upload cover / portrait / LookBook images at the right size and ratio, add cast and crew credits, upload and maintain episode videos (分集 via BytePlus VOD), set who can watch each episode, run a crowdfunding campaign with donation tiers and offline supporters, read donation records, and answer enquiries (查詢 / 合作邀請 / 投資 / 授權) — reply, accept or decline, grant partner access. Use whenever a task mentions Backreel, a Backreel post / work / reel, its episodes, trailer, cover or poster sizes, crowdfunding / 眾籌 / 捐款, supporters, or enquiries / 查詢 on a creator's work.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Backreel
|
|
7
|
+
|
|
8
|
+
Backreel shares accounts and the API with WJI, so this skill sits on the `wji`
|
|
9
|
+
skill — read that one for sign-in (`wji auth whoami`), profiles and asset
|
|
10
|
+
basics. Everything here is `wji backreel …` (alias `wji br …`). Every command
|
|
11
|
+
takes `--json`; use it when you need ids.
|
|
12
|
+
|
|
13
|
+
Only the **post's creator** can edit, publish, upload episodes or see
|
|
14
|
+
enquiries and donations for it — admins included, the post routes refuse
|
|
15
|
+
anyone else. Check who you are before touching someone's work:
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
wji auth whoami
|
|
19
|
+
wji br list # your posts, drafts included
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## How a Backreel post is built
|
|
23
|
+
|
|
24
|
+
| Part | What it is | Command |
|
|
25
|
+
| --- | --- | --- |
|
|
26
|
+
| kind | `showcase` (episodes, trailer) or `crowdfunding` (goal, supporters) — switching wipes the other side's data | `br create --kind`, `br set --kind` |
|
|
27
|
+
| title / logline / description | logline = one public line ≤200 chars; description = HTML or plain text | `br set --logline`, `-d @file.md` |
|
|
28
|
+
| images | 16:9 cover, 9:16 portrait, LookBook gallery (≤9), credit photos | `br image <file> --slot … --post` |
|
|
29
|
+
| trailer | a video asset ≤30 s | `wji asset upload` → `br set --trailer` |
|
|
30
|
+
| episodes | ≤30, each with its own viewer tier, hosted on VOD | `br episode …` |
|
|
31
|
+
| credits | cast / crew / creative, ≤30, may link a WJI user or an NPC | `br credit …` |
|
|
32
|
+
| campaign + donations | goal, offline total, deadline, donation tiers, offline supporters | `br fund …` |
|
|
33
|
+
| enquiries | messages from people who want to work with / invest in / license the work | `br enquiry …` |
|
|
34
|
+
|
|
35
|
+
Viewer tiers, lowest to highest: `public` (anyone) < `member` (signed in) <
|
|
36
|
+
`supporter` (has donated) < `partner` (granted by the creator or a verified
|
|
37
|
+
investor / company). The logline and the cards are always public.
|
|
38
|
+
|
|
39
|
+
## 1. Create a post and get it publishable
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
wji br create "港口" --kind showcase --logline "一個漁村少年的最後一夏" \
|
|
43
|
+
-d @synopsis.md --category short_drama --project-status in_production --tags drama,hk
|
|
44
|
+
wji br check <postId> # blockers (✗) and advice (!)
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
`create` always makes a **draft**. Publishing needs a title, a description
|
|
48
|
+
with text or an image, and at least one of cover / LookBook media / an
|
|
49
|
+
episode; a crowdfunding post also needs a goal ≥ 1. `br check` lists exactly
|
|
50
|
+
what is missing — run it before `br publish <postId>`. `br unpublish` takes a
|
|
51
|
+
post offline (it can be republished); `br rm` deletes it.
|
|
52
|
+
|
|
53
|
+
Categories the web offers: `narrative_short`, `movie`, `short_drama`,
|
|
54
|
+
`web_movie`, `tv_commercial`, `mv`, `animation`, `creative`, `tutorial`,
|
|
55
|
+
`other`.
|
|
56
|
+
|
|
57
|
+
## 2. Images — size and ratio
|
|
58
|
+
|
|
59
|
+
The server accepts any image and **crops to fill** every frame, so a wrong
|
|
60
|
+
ratio silently loses the edges. Prepare each slot at its own ratio:
|
|
61
|
+
|
|
62
|
+
| Slot | Ratio | Ideal | Minimum | Where |
|
|
63
|
+
| --- | --- | --- | --- | --- |
|
|
64
|
+
| `cover` | 16:9 | 1920×1080 | 1280×720 | page header, shares; also cropped to 4:3 on cards and ~16:7 in reel strips |
|
|
65
|
+
| `portrait` | 9:16 | 1080×1920 | 720×1280 | mobile hero / poster (falls back to a crop of the cover) |
|
|
66
|
+
| `media` | 3:4 | 1536×2048 | 900×1200 | LookBook tiles (≤9 items, images or videos) |
|
|
67
|
+
| `photo` | 1:1 | 800×800 | 400×400 | credit photo, supporter avatar (shown round) |
|
|
68
|
+
|
|
69
|
+
JPEG / PNG / WebP, ≤25 MB. Long edges over 3840 px are downsized and files
|
|
70
|
+
over 10 MB are re-encoded as JPEG on upload.
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
wji br image-specs # the table above
|
|
74
|
+
wji br image cover.jpg --slot cover --check # measure only
|
|
75
|
+
wji br image cover.jpg --slot cover --post <postId> # check, upload, set
|
|
76
|
+
wji br image poster.png --slot portrait --post <postId>
|
|
77
|
+
wji br image s1.jpg s2.jpg s3.jpg --slot media --post <postId> # appends to the LookBook
|
|
78
|
+
wji br set <postId> --media <assetId…> # replace / reorder the LookBook ("none" clears)
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
`br image` reads the size from the file, warns about a wrong ratio or a soft
|
|
82
|
+
(too small) image, and refuses files it cannot upload. Treat a warning as a
|
|
83
|
+
reason to re-crop, not to ignore. Read [reference/images.md](reference/images.md)
|
|
84
|
+
for composition rules (safe area for the 4:3 and 16:7 crops), making the
|
|
85
|
+
9:16 poster from the cover with AI, and credit photos.
|
|
86
|
+
|
|
87
|
+
## 3. Episodes and videos
|
|
88
|
+
|
|
89
|
+
```bash
|
|
90
|
+
wji br episode add <postId> E01.mp4 -t "第一集 重逢" # uploads to VOD, claims it, appends
|
|
91
|
+
wji br episode add <postId> E00.mp4 -t "前導" --at 1 --tier public
|
|
92
|
+
wji br episode list <postId>
|
|
93
|
+
wji br episode status <postId> # transcoding: processing → ready (refreshes from VOD)
|
|
94
|
+
wji br episode tiers <postId> --public-to 2 --member-to 5 --rest supporter
|
|
95
|
+
wji br episode set <postId> 3 -t "第三集(導演版)" # rename
|
|
96
|
+
wji br episode set <postId> 3 E03_v2.mp4 # replace the video
|
|
97
|
+
wji br episode move <postId> 4 2
|
|
98
|
+
wji br episode rm <postId> 6 -y
|
|
99
|
+
wji br episode play <postId> 1 # short-lived URL to watch it yourself
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
Episodes exist on **showcase** posts only (≤30). A local file goes straight
|
|
103
|
+
to Backreel's BytePlus VOD space, which serves short-lived signed URLs —
|
|
104
|
+
nothing on the page can be copied and shared. Transcoding takes a few minutes;
|
|
105
|
+
an episode stays `processing` until then and viewers get "still
|
|
106
|
+
transcoding". Numbers on the command line are 1-based positions. Read
|
|
107
|
+
[reference/episodes.md](reference/episodes.md) for the trailer, the legacy
|
|
108
|
+
asset path, tier strategy and failure handling.
|
|
109
|
+
|
|
110
|
+
## 4. Crowdfunding and donations
|
|
111
|
+
|
|
112
|
+
```bash
|
|
113
|
+
wji br create "下一部長片" --kind crowdfunding -d @pitch.md
|
|
114
|
+
wji br fund set <postId> --goal 500000 --deadline 2026-12-31 \
|
|
115
|
+
--donations on --currency hkd --min 50
|
|
116
|
+
wji br fund tier add <postId> --title "早鳥" --amount 200 --perks "片尾鳴謝" --limit 300
|
|
117
|
+
wji br fund supporter add <postId> --name "ABC Films" --amount 50000
|
|
118
|
+
wji br fund set <postId> --offline-raised 50000 # money raised outside Backreel
|
|
119
|
+
wji br fund show <postId> # progress, settings, tiers
|
|
120
|
+
wji br fund donations <postId> # online donations, balance, payouts
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
Progress = offline total + online donations. Donations (Stripe) work on any
|
|
124
|
+
published post, not just crowdfunding, and stop at the deadline; the currency
|
|
125
|
+
locks after the first donation. Payouts and refunds are done by Backreel
|
|
126
|
+
staff, not the CLI. Read [reference/crowdfunding.md](reference/crowdfunding.md)
|
|
127
|
+
for tier design and what supporters unlock.
|
|
128
|
+
|
|
129
|
+
## 5. Enquiries
|
|
130
|
+
|
|
131
|
+
```bash
|
|
132
|
+
wji br enquiry unread
|
|
133
|
+
wji br enquiry list # inbox, newest activity first (● = unread)
|
|
134
|
+
wji br enquiry list --type investment --status new
|
|
135
|
+
wji br enquiry get <enquiryId> # full request + thread; marks it read
|
|
136
|
+
wji br enquiry download <fileId> # an attachment (private file)
|
|
137
|
+
wji br enquiry reply <enquiryId> "多謝來信…" -a deck.pdf
|
|
138
|
+
wji br enquiry status <enquiryId> in_discussion # | accepted | declined | archived
|
|
139
|
+
wji br enquiry grant <enquiryId> # give the sender partner access
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
Types: collaboration, new_project, investment, licensing, access_request,
|
|
143
|
+
general. Accepting an **access_request** grants partner access automatically;
|
|
144
|
+
`grant` does it from any enquiry (creator only) and marks it accepted. Every
|
|
145
|
+
reply notifies the sender in-app and by email (at most every 30 min), so
|
|
146
|
+
**show the user the reply text and get their OK before sending**, and never
|
|
147
|
+
accept, decline or grant on your own judgement. Read
|
|
148
|
+
[reference/enquiries.md](reference/enquiries.md) for triage and reply
|
|
149
|
+
patterns.
|
|
150
|
+
|
|
151
|
+
## Credits
|
|
152
|
+
|
|
153
|
+
```bash
|
|
154
|
+
wji br credit add <postId> --kind creative --name "陳導" --role 導演 --photo <assetId>
|
|
155
|
+
wji br credit add <postId> --kind cast --npc @mika --role "飾 阿明"
|
|
156
|
+
wji br credit add <postId> --kind crew --user <userId> --role 攝影指導 # their name and avatar win
|
|
157
|
+
wji br credit list <postId>
|
|
158
|
+
wji br credit rm <postId> 3 -y
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
## Rules of thumb
|
|
162
|
+
|
|
163
|
+
- **Ask before anything outward-facing**: publishing, unpublishing, deleting,
|
|
164
|
+
replying to or deciding an enquiry, granting access, turning donations on.
|
|
165
|
+
Draft edits are safe to make and show.
|
|
166
|
+
- Generating images (e.g. the AI poster) spends WJI credits — confirm first.
|
|
167
|
+
- Episode uploads go to the live VOD space even from a test post; don't
|
|
168
|
+
upload throwaway clips.
|
|
169
|
+
- Re-run `br check` after big edits; run `br episode status` after uploads.
|
|
170
|
+
- Errors come back in Chinese from the server (e.g. `分集最多 30 集`); relay
|
|
171
|
+
them as they are and say what to change.
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
# Crowdfunding, donations and supporters
|
|
2
|
+
|
|
3
|
+
## Two pieces that work together
|
|
4
|
+
|
|
5
|
+
| | Campaign | Donations |
|
|
6
|
+
| --- | --- | --- |
|
|
7
|
+
| on | crowdfunding posts only | any published post |
|
|
8
|
+
| holds | goal, offline total, deadline, offline supporter list | on/off, currency, minimum, tiers |
|
|
9
|
+
| set with | `br fund set --goal --offline-raised --deadline`, `br fund supporter …` | `br fund set --donations --currency --min`, `br fund tier …` |
|
|
10
|
+
|
|
11
|
+
The public progress bar = `--offline-raised` + online donations; the
|
|
12
|
+
supporter count = offline supporters + online donors.
|
|
13
|
+
|
|
14
|
+
## Setting up a campaign
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
wji br create "下一部長片" --kind crowdfunding -d @pitch.md --logline "…"
|
|
18
|
+
wji br fund set <postId> --goal 500000 --deadline 2026-12-31
|
|
19
|
+
wji br fund set <postId> --donations on --currency hkd --min 50
|
|
20
|
+
wji br fund tier add <postId> --title "早鳥支持" --amount 200 --perks "片尾鳴謝 + 數碼海報" --limit 300
|
|
21
|
+
wji br fund tier add <postId> --title "製片人" --amount 20000 --perks "聯合製片人名銜、探班一次" --limit 5
|
|
22
|
+
wji br check <postId>
|
|
23
|
+
wji br publish <postId> # ask first
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
- A crowdfunding post cannot publish with a goal below 1.
|
|
27
|
+
- Currencies: hkd, usd, twd, sgd, eur, gbp. **Locked after the first
|
|
28
|
+
donation** — choose before publishing.
|
|
29
|
+
- Amounts are whole numbers. Every tier must be ≥ the minimum (and ≥ 1);
|
|
30
|
+
≤10 tiers; `--limit` caps the slots (`--limit 0` on `tier set` = unlimited).
|
|
31
|
+
- The deadline stops donations at that moment; `--deadline none` removes it.
|
|
32
|
+
- A single donation is capped at 100,000.
|
|
33
|
+
|
|
34
|
+
## Designing tiers
|
|
35
|
+
|
|
36
|
+
- 3–5 tiers read best: an entry tier most people can afford, a "real
|
|
37
|
+
supporter" tier, one or two premium tiers with scarce perks (`--limit`).
|
|
38
|
+
- Perks should be concrete and deliverable: credit wording, a screening,
|
|
39
|
+
a set visit, early access. Supporter **episodes** are a perk too — tiers
|
|
40
|
+
set to `supporter` unlock for anyone who has donated (see
|
|
41
|
+
[episodes.md](episodes.md)).
|
|
42
|
+
- Changing a tier's amount does not affect past donations; they keep a
|
|
43
|
+
snapshot of the tier they bought.
|
|
44
|
+
|
|
45
|
+
## Offline supporters
|
|
46
|
+
|
|
47
|
+
People who paid by bank transfer, sponsorship etc. Add them so the wall and
|
|
48
|
+
count reflect reality, and raise the offline total separately:
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
wji br fund supporter add <postId> --name "ABC Films" --amount 50000 --avatar <assetId>
|
|
52
|
+
wji br fund set <postId> --offline-raised 50000
|
|
53
|
+
wji br fund supporter list <postId>
|
|
54
|
+
wji br fund supporter rm <postId> 2 -y
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
Adding a supporter does **not** change the raised amount — update
|
|
58
|
+
`--offline-raised` yourself (keep the two consistent). Avatars are square
|
|
59
|
+
images (`br image logo.png --slot photo`).
|
|
60
|
+
|
|
61
|
+
## Donation records
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
wji br fund donations <postId>
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
Shows raised / paid out / balance, then each donation: time, donor (anonymous
|
|
68
|
+
donors stay hidden even from the creator), amount, tier, status (`paid`,
|
|
69
|
+
`partially_refunded`, `refunded`, `failed`, `cancelled`; a red *disputed*
|
|
70
|
+
marks a card chargeback) and the donor's message. Payouts and
|
|
71
|
+
refunds are handled by Backreel staff — the creator asks them, the CLI cannot
|
|
72
|
+
do it.
|
|
73
|
+
|
|
74
|
+
## Showcase posts can take donations too
|
|
75
|
+
|
|
76
|
+
A showcase post (episodes) can turn donations on to sell `supporter` access
|
|
77
|
+
to later episodes — there is just no goal or progress bar:
|
|
78
|
+
|
|
79
|
+
```bash
|
|
80
|
+
wji br fund set <postId> --donations on --currency hkd --min 30
|
|
81
|
+
wji br episode tiers <postId> --public-to 2 --rest supporter
|
|
82
|
+
```
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
# Enquiries
|
|
2
|
+
|
|
3
|
+
Anyone signed in can send an enquiry about a **published** post — to its
|
|
4
|
+
creator, or (for collaboration / new_project / general) to a credited person
|
|
5
|
+
with a linked account. The creator reads and answers them here.
|
|
6
|
+
|
|
7
|
+
## Types and what they carry
|
|
8
|
+
|
|
9
|
+
| type | meaning | extra fields shown by `enquiry get` |
|
|
10
|
+
| --- | --- | --- |
|
|
11
|
+
| `collaboration` | work together on something | — |
|
|
12
|
+
| `new_project` | an offer to hire for a project | project type, title, budget range + currency, timeline, location, role needed |
|
|
13
|
+
| `investment` | wants to invest | ticket size + currency |
|
|
14
|
+
| `licensing` | wants to license the work | territory, media, term |
|
|
15
|
+
| `access_request` | wants partner access to gated material | access purpose; `sender access` shows their current tier |
|
|
16
|
+
| `general` | anything else | — |
|
|
17
|
+
|
|
18
|
+
Every enquiry has the sender's contact block (name, email, phone, company),
|
|
19
|
+
their verification badges (✓investor, ✓production_company …) and up to 5
|
|
20
|
+
private attachments (`enquiry download <fileId>` — the link lasts 60 s).
|
|
21
|
+
|
|
22
|
+
## Status flow
|
|
23
|
+
|
|
24
|
+
```
|
|
25
|
+
new ──reply──▶ in_discussion ──▶ accepted | declined | archived
|
|
26
|
+
(sender may withdraw while new / in_discussion; nothing moves after withdrawn)
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
- The recipient (you) sets `in_discussion`, `accepted`, `declined`,
|
|
30
|
+
`archived`. Replying to a `new` enquiry moves it to `in_discussion`.
|
|
31
|
+
- `archived` hides it from the inbox (`enquiry list --archived` shows it); a
|
|
32
|
+
reply from the sender brings it back.
|
|
33
|
+
- `accepted` on an **access_request** grants partner access immediately.
|
|
34
|
+
- `enquiry grant <id>` grants partner access from any enquiry you received as
|
|
35
|
+
the creator, and marks an open one accepted. It is offered only while the
|
|
36
|
+
sender has no partner access (`can` line of `enquiry get`).
|
|
37
|
+
- Accept / decline notify the sender in-app and by email.
|
|
38
|
+
|
|
39
|
+
## Triage routine
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
wji br enquiry unread
|
|
43
|
+
wji br enquiry list --unread
|
|
44
|
+
wji br enquiry get <id> # read everything, including attachments
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
Summarise each for the user: who (name, company, verification), what they
|
|
48
|
+
want, the money / dates involved, and what the creator would need to decide.
|
|
49
|
+
Do **not** decide for them — accepting, declining and granting access are the
|
|
50
|
+
creator's calls.
|
|
51
|
+
|
|
52
|
+
## Replying
|
|
53
|
+
|
|
54
|
+
Replies are ≤4000 characters, go to the other side in-app immediately and by
|
|
55
|
+
email at most every 30 minutes. Draft the reply, show it, send only after the
|
|
56
|
+
user agrees:
|
|
57
|
+
|
|
58
|
+
```bash
|
|
59
|
+
wji br enquiry reply <id> @reply.md -a pitch-deck.pdf
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
Attachments: documents (PDF, DOCX, XLSX, PPTX, CSV) and images, ≤20 MB each,
|
|
63
|
+
≤5 per message.
|
|
64
|
+
|
|
65
|
+
Patterns that work:
|
|
66
|
+
|
|
67
|
+
- **Acknowledge + next step**: thank them, restate what they asked in one
|
|
68
|
+
line, say what happens next and when ("I'll send the budget breakdown by
|
|
69
|
+
Friday").
|
|
70
|
+
- **Need more**: ask the 2–3 specific questions you need (budget, schedule,
|
|
71
|
+
rights territory) instead of a vague "tell me more".
|
|
72
|
+
- **Decline kindly**: one line of thanks, one line of reason if the user wants
|
|
73
|
+
to give one, leave the door open — then `enquiry status <id> declined`.
|
|
74
|
+
- Match the sender's language (Cantonese / Mandarin / English).
|
|
75
|
+
|
|
76
|
+
## Limits worth knowing
|
|
77
|
+
|
|
78
|
+
Senders can have one open enquiry of the same type per post, 3 per post per
|
|
79
|
+
day and 20 per day overall — repeated spam beyond that is blocked by the
|
|
80
|
+
server. Blocking and reporting a sender are done on the web.
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
# Episodes, trailer and video upkeep
|
|
2
|
+
|
|
3
|
+
## Two kinds of video on a post
|
|
4
|
+
|
|
5
|
+
| | Trailer | Episodes |
|
|
6
|
+
| --- | --- | --- |
|
|
7
|
+
| posts | any | **showcase only** (switching to crowdfunding drops them) |
|
|
8
|
+
| count | one | ≤30 |
|
|
9
|
+
| length | ≤30 s (server allows +1 s) | no limit |
|
|
10
|
+
| storage | WJI asset (public URL) | BytePlus VOD (signed URL per play, ~5 min) |
|
|
11
|
+
| gated | no — always public | per episode: public / member / supporter / partner |
|
|
12
|
+
|
|
13
|
+
### Trailer
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
wji asset upload trailer.mp4 --json # ≤200 MB; duration is probed
|
|
17
|
+
wji br set <postId> --trailer <assetId>
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
The server rejects a trailer over 31 s when it knows the duration. Cut it to
|
|
21
|
+
≤30 s first.
|
|
22
|
+
|
|
23
|
+
## Uploading episodes
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
wji br episode add <postId> E01.mp4 -t "第一集"
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
What happens: the CLI asks Backreel for a 15-minute upload credential scoped
|
|
30
|
+
to its VOD space, uploads the file directly to BytePlus, **claims** it (the
|
|
31
|
+
server checks the space, tags it with the post, publishes it and starts
|
|
32
|
+
transcoding), then saves the episode list with the new `vodVid`.
|
|
33
|
+
|
|
34
|
+
- Formats: `.mp4`, `.mov`, `.m4v`, `.webm`. Upload the finished master;
|
|
35
|
+
VOD transcodes to MP4 for playback.
|
|
36
|
+
- The whole file goes up in one request — fine for episodes (hundreds of MB).
|
|
37
|
+
Multi-GB masters are better uploaded from the web, which chunks them.
|
|
38
|
+
- A credential lasts 15 minutes and the server allows 30 per 10 minutes —
|
|
39
|
+
upload a season one episode at a time, not in parallel.
|
|
40
|
+
- `--vid <vid>` attaches a video already in the space (e.g. uploaded on the
|
|
41
|
+
web) without re-uploading.
|
|
42
|
+
|
|
43
|
+
### Legacy path
|
|
44
|
+
|
|
45
|
+
`--legacy` (or `--asset <assetId>`) stores the episode as a plain WJI asset
|
|
46
|
+
(≤200 MB) with a permanent public URL. It plays immediately with no
|
|
47
|
+
transcoding, but anyone who sees the URL can share it, and tier locks only hide
|
|
48
|
+
it on the page. Use VOD for anything gated; legacy only for short public
|
|
49
|
+
extras.
|
|
50
|
+
|
|
51
|
+
## Transcoding status
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
wji br episode status <postId>
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
VOD status only updates when someone asks to play, so `status` asks for each
|
|
58
|
+
VOD episode as the owner and reports `processing`, `ready` or `failed`.
|
|
59
|
+
A few minutes per episode is normal. Viewers who press play before it is ready
|
|
60
|
+
see "這一集還在轉碼中". `failed` → upload the file again:
|
|
61
|
+
`wji br episode set <postId> <n> E0n_fixed.mp4`.
|
|
62
|
+
|
|
63
|
+
Publishing does **not** wait for transcoding — check `status` (or `br check`)
|
|
64
|
+
before announcing a release.
|
|
65
|
+
|
|
66
|
+
## Order and numbering
|
|
67
|
+
|
|
68
|
+
Positions on the command line are 1-based (`episode set <post> 3`). The
|
|
69
|
+
server re-numbers after every change, so after `move` / `rm` re-read
|
|
70
|
+
`episode list` before the next positional command.
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
wji br episode move <postId> 5 2 # episode 5 becomes episode 2
|
|
74
|
+
wji br episode add <postId> SP.mp4 -t "特別篇" --at 4
|
|
75
|
+
wji br episode rm <postId> 7 8 -y
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
Removing an episode does not delete the video from VOD; re-adding it later
|
|
79
|
+
with `--vid` works.
|
|
80
|
+
|
|
81
|
+
## Who can watch: tiers
|
|
82
|
+
|
|
83
|
+
`public` anyone · `member` signed in · `supporter` has donated to this post ·
|
|
84
|
+
`partner` granted by the creator (or an auto-partner verified company).
|
|
85
|
+
|
|
86
|
+
Common ladders:
|
|
87
|
+
|
|
88
|
+
```bash
|
|
89
|
+
# Free pilot, members for the first act, supporters for the rest
|
|
90
|
+
wji br episode tiers <postId> --public-to 1 --member-to 3 --rest supporter
|
|
91
|
+
# Everything public except a partner-only director's cut at the end
|
|
92
|
+
wji br episode tiers <postId> --public-to 11 --rest partner
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
`supporter` only works if people can donate — turn donations on
|
|
96
|
+
(`br fund set --donations on`) or nobody can reach those episodes. Locked
|
|
97
|
+
episodes still show their title and a lock, and never expose a URL.
|
|
98
|
+
|
|
99
|
+
## Owner checks
|
|
100
|
+
|
|
101
|
+
```bash
|
|
102
|
+
wji br episode play <postId> 1 # signed URL, ~5 minutes; watch it yourself
|
|
103
|
+
wji br check <postId> # flags episodes not ready on VOD
|
|
104
|
+
```
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
# Backreel images
|
|
2
|
+
|
|
3
|
+
## Where each image shows, and how it is cropped
|
|
4
|
+
|
|
5
|
+
Every image frame on Backreel uses *cover* fitting: the image fills the frame
|
|
6
|
+
and whatever sticks out is cut. Nothing is letterboxed, and the server does not
|
|
7
|
+
check ratios — so the only protection is preparing each slot at its own ratio.
|
|
8
|
+
|
|
9
|
+
| Slot | Field | Prepared as | Also shown as | Keep inside |
|
|
10
|
+
| --- | --- | --- | --- | --- |
|
|
11
|
+
| cover | `cover` | 16:9, 1920×1080 | 4:3 list cards, ~16:7 reel strips, share previews | the centre 4:3 *and* the middle 16:7 band — faces and title text in the centre, nothing important near the top or bottom 20% or the left/right 12% |
|
|
12
|
+
| portrait | `coverPortrait` | 9:16, 1080×1920 | mobile hero, poster tiles | the middle 80% vertically; leave the bottom third calm if the page overlays the title there |
|
|
13
|
+
| media | `assets[]` (LookBook) | 3:4, 1536×2048 | 3:4 tiles; opens full size | subject centred; stills shot 16:9 lose their sides — re-crop to 3:4 rather than upload as is |
|
|
14
|
+
| photo | credit `photo`, supporter `avatar` | 1:1, 800×800 | a circle | the face centred, head and shoulders, no text |
|
|
15
|
+
|
|
16
|
+
`--slot` names: `cover`, `portrait`, `media`, `photo`.
|
|
17
|
+
|
|
18
|
+
There is no separate "card" image on the live site yet: cards crop the 16:9
|
|
19
|
+
cover to 4:3, which is why the cover's centre matters. (A dedicated 4:3
|
|
20
|
+
`cardCover` field exists on an unreleased backend branch; once it ships it
|
|
21
|
+
will be its own slot.)
|
|
22
|
+
|
|
23
|
+
## Limits applied on upload (`/assets/v2/upload`)
|
|
24
|
+
|
|
25
|
+
- ≤25 MB per image; JPEG, PNG, WebP (AVIF and GIF are accepted too).
|
|
26
|
+
- Long edge over 3840 px → downsized to 3840.
|
|
27
|
+
- Over 10 MB → re-encoded as JPEG quality 95. Prefer a high-quality JPEG
|
|
28
|
+
around 1–4 MB; a 30 MB PNG gains nothing.
|
|
29
|
+
- A ~512 px thumbnail is generated automatically.
|
|
30
|
+
- EXIF rotation is not applied by `br image`'s size check — export images
|
|
31
|
+
already upright.
|
|
32
|
+
|
|
33
|
+
## Checking and fixing
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
wji br image still.jpg --slot media --check
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
- `! ratio … is not 3:4 — the edges will be cropped` → re-crop to the slot
|
|
40
|
+
ratio. On macOS without an editor:
|
|
41
|
+
`sips --cropToHeightWidth 2048 1536 in.jpg --out out.jpg` (crops around the
|
|
42
|
+
centre; resize first with `sips -Z 2048` if needed).
|
|
43
|
+
- `! … below 1280×720; it will look soft` → find a larger source; upscaling a
|
|
44
|
+
small frame does not add detail.
|
|
45
|
+
- `✗ not a PNG, JPEG, WebP or GIF image` → convert first
|
|
46
|
+
(`sips -s format jpeg in.heic --out out.jpg`).
|
|
47
|
+
|
|
48
|
+
## The 9:16 poster from the 16:9 cover (AI)
|
|
49
|
+
|
|
50
|
+
When there is no portrait artwork, the web offers "make portrait with AI": it
|
|
51
|
+
re-composes the cover into 9:16 with an image model. The same with the CLI —
|
|
52
|
+
**this spends WJI credits, so confirm with the user first**:
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
wji br get <postId> --json | jq -r .cover.id # the cover asset id
|
|
56
|
+
wji gen image -m gpt-image-2.5-flare-fal -r 9:16 --ref <coverAssetId> \
|
|
57
|
+
-p "Recompose this film key art as a 9:16 vertical poster. Keep the same characters, faces, wardrobe, colour grade and mood; extend the scene vertically; no text, no logos." \
|
|
58
|
+
--model-options '{"quality":"high","resolution":"1080p"}' --wait --json
|
|
59
|
+
wji br set <postId> --cover-portrait <newAssetId>
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
Look at the result before setting it — faces drift. Generate again with a
|
|
63
|
+
more specific prompt rather than accepting a changed face.
|
|
64
|
+
|
|
65
|
+
## Inline images in the description
|
|
66
|
+
|
|
67
|
+
The description is sanitized HTML; `<img src="https://…">` survives (http/https
|
|
68
|
+
only), so an uploaded asset's URL can be embedded:
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
wji asset upload still.jpg --json | jq -r .url
|
|
72
|
+
wji br set <postId> -d @description.html
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
A description that is only an image still counts as "has a description" for
|
|
76
|
+
publishing.
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: npc-character
|
|
3
|
+
description: Write a virtual character for NPC City that feels like a real person — persona, soul (drive, traits, values, fears, contradiction), background and memories, voice and speaking tone, protocols for talking to viewers, on-camera habits — and the live stages she performs on (occasion, greeting, idle loops, reply direction), then apply them with the `wji` CLI (`wji npc doc`, `wji npc memory`, `wji npc stage`). Use whenever someone wants to create, deepen, fix or review an NPC / virtual idol / AI character / VTuber / 虛擬角色 / 人設 / 角色設定 / soul / persona / background story on NPC City, write or improve its live stream stage, or asks why their NPC sounds generic.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# NPC City characters
|
|
7
|
+
|
|
8
|
+
NPC City residents ("NPCs") are virtual characters who live-stream: a viewer
|
|
9
|
+
types, a reply model writes what she **says** and **does**, and a video model
|
|
10
|
+
performs it. Everything in this skill is about making that character feel
|
|
11
|
+
like a specific person instead of a list of adjectives — and about putting
|
|
12
|
+
the words where the runtime actually reads them.
|
|
13
|
+
|
|
14
|
+
Sits on the `wji` skill (sign-in, profiles). Commands are `wji npc …`; your
|
|
15
|
+
NPC is addressed by id, `@handle` or name.
|
|
16
|
+
|
|
17
|
+
## The workflow
|
|
18
|
+
|
|
19
|
+
1. **Read what exists** — never start from a blank page if the NPC exists.
|
|
20
|
+
For a **new** NPC, create the shell first (needs NPC City spawn
|
|
21
|
+
permission; it starts private), then upload the headshot and at least one
|
|
22
|
+
scene image on the web — live stages need both:
|
|
23
|
+
```bash
|
|
24
|
+
wji npc handle nagi.npc # is the handle free?
|
|
25
|
+
wji npc create "NAGI" --role "Radio Host" --genre "Lo-fi" --handle nagi.npc
|
|
26
|
+
```
|
|
27
|
+
The handle is fixed from here on; the name is stored in capitals.
|
|
28
|
+
Visual assets (headshot 1:1, **Character Sheet 16:9** with front / back /
|
|
29
|
+
side views, outfit flat lays 3:4, scenes 16:9) have fixed formats — see
|
|
30
|
+
[reference/visual-kit.md](reference/visual-kit.md) before generating any.
|
|
31
|
+
```bash
|
|
32
|
+
wji npc list
|
|
33
|
+
wji npc doc export @yuzu.npc -o yuzu.md # profile + soul as one Markdown file
|
|
34
|
+
wji npc memory list @yuzu.npc
|
|
35
|
+
wji npc readiness @yuzu.npc # integrity %, what blocks going live
|
|
36
|
+
```
|
|
37
|
+
2. **Interview, then decide** — ask the creator the five questions in
|
|
38
|
+
[reference/interview.md](reference/interview.md), or make bold choices
|
|
39
|
+
and say which ones you made. Lock the **want, the need and the one
|
|
40
|
+
contradiction** before writing any field.
|
|
41
|
+
3. **Write the character document** with the method in
|
|
42
|
+
[reference/character-craft.md](reference/character-craft.md), in the
|
|
43
|
+
grammar of [reference/document-format.md](reference/document-format.md).
|
|
44
|
+
Spend the words where [reference/runtime.md](reference/runtime.md) says
|
|
45
|
+
the model reads them.
|
|
46
|
+
4. **Write the voice** — speaking tone, sample lines that fit one live reply
|
|
47
|
+
(40 English words / 60 CJK characters), code-switching, on-camera habits in
|
|
48
|
+
English: [reference/voice.md](reference/voice.md).
|
|
49
|
+
5. **Review** with the checklist at the end of character-craft.md, then show
|
|
50
|
+
the creator a diff before writing anything:
|
|
51
|
+
```bash
|
|
52
|
+
wji npc doc apply @yuzu.npc @yuzu.md --dry-run
|
|
53
|
+
wji npc doc apply @yuzu.npc @yuzu.md --sync-memories # asks before applying
|
|
54
|
+
```
|
|
55
|
+
`--sync-memories` matters: the document route silently ignores the
|
|
56
|
+
`## Memories` section; this flag replaces the NPC's memories with it.
|
|
57
|
+
6. **Her public life** — a work timeline (`wji npc job`) and photo albums
|
|
58
|
+
(`wji npc album`) that tell the same story as her key events and
|
|
59
|
+
memories: [reference/life.md](reference/life.md).
|
|
60
|
+
7. **Stage** — once the character is right, write a live stage document with
|
|
61
|
+
[reference/stage-craft.md](reference/stage-craft.md) and import it as a
|
|
62
|
+
free draft:
|
|
63
|
+
```bash
|
|
64
|
+
wji npc stage list @yuzu.npc
|
|
65
|
+
wji npc stage import @yuzu.npc @yuzu.stage.md # Draft — nothing rendered, no credits
|
|
66
|
+
wji npc stage export <stageId> -o stage.md
|
|
67
|
+
wji npc stage apply <stageId> @stage.md --dry-run
|
|
68
|
+
```
|
|
69
|
+
8. **Rehearse** — on a Ready stage, `wji npc stage set <stageId> --debug on`
|
|
70
|
+
makes live replies come back as text plus a full prompt trace and no
|
|
71
|
+
video (no credits for renders). Chat with her on the web, read the
|
|
72
|
+
TRACE panel, fix the document, repeat. Turn it off afterwards
|
|
73
|
+
(`--debug off`); never leave an on-air stage in debug mode.
|
|
74
|
+
|
|
75
|
+
Two complete characters with a stage each, both importing cleanly — use them
|
|
76
|
+
as the bar, not as templates to copy:
|
|
77
|
+
[YUZU](examples/yuzu.character.md) / [stage](examples/yuzu.stage.md) — a
|
|
78
|
+
Cantonese singer in her family's closing dessert shop;
|
|
79
|
+
[NAGI](examples/nagi.character.md) / [stage](examples/nagi.stage.md) — a
|
|
80
|
+
Japanese late-night radio host who reads listener letters from a closet.
|
|
81
|
+
|
|
82
|
+
## What the runtime reads (short version)
|
|
83
|
+
|
|
84
|
+
| Matters a lot | Matters | Display only (never reaches a model) |
|
|
85
|
+
| --- | --- | --- |
|
|
86
|
+
| selfDescription (first 400 chars) · speaking tone (500) · human protocol (500) · top 3 memories by weight (140 chars each) · traits · on-camera action (300, English) · languages tag | name · role · pronouns · primary drive · values · fears · origin (300) · first 8 key events · current focus & goals · trigger keywords · avoid topics · speech pattern · axes ≤30 or ≥70 · aesthetic keywords · visual style | tagline · genre · bio (unless selfDescription is empty) · creation story · NPC protocol · data source notes · activity level · post frequency · jobs · relationships · socials · colour |
|
|
87
|
+
|
|
88
|
+
Write display-only fields for the profile page and for consistency, but put
|
|
89
|
+
the character's *behaviour* into the left columns. Details and the exact
|
|
90
|
+
prompt order: [reference/runtime.md](reference/runtime.md).
|
|
91
|
+
|
|
92
|
+
## Hard rules
|
|
93
|
+
|
|
94
|
+
- **Real people**: never build an NPC that imitates a real, identifiable
|
|
95
|
+
person (name, face, voice, life story) unless the creator says they hold
|
|
96
|
+
the rights — then tag it `presenceKind=licensed-presence` (or
|
|
97
|
+
`legacy-return` for an estate-approved return). Inspired-by is fine;
|
|
98
|
+
impersonation is not.
|
|
99
|
+
- **Adults only** for anything romantic or flirtatious, and say so through
|
|
100
|
+
the story (age-feel in origin and memories), not a number in the bio.
|
|
101
|
+
Never write a character who is, or reads as, a minor in a romantic or
|
|
102
|
+
sexual frame. NSFW rating does not change this.
|
|
103
|
+
- **Avoid topics are hard limits** the reply model deflects in character —
|
|
104
|
+
add politics and real-celebrity gossip unless the creator wants otherwise.
|
|
105
|
+
- **Nothing breaks the fourth wall**: no "as an AI", no "my prompt", no
|
|
106
|
+
"language model" anywhere in the document.
|
|
107
|
+
- **Ask before** applying a document, syncing memories, importing or
|
|
108
|
+
deleting a stage, and turning a stage on air or into debug mode. Rendering
|
|
109
|
+
keyframes and clips costs credits and is done on the web, with the
|
|
110
|
+
creator's go-ahead.
|
|
111
|
+
- Do not change the `@handle` — it is fixed; a document cannot change it.
|