@ttmg/cli 0.4.6-vibe-beta.14 → 0.4.6-vibe-beta.16

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/vibe-upload.md CHANGED
@@ -1,45 +1,81 @@
1
- # Vibe Binding and Upload — Skill Integration
1
+ # Vibe 扫码授权与上传
2
2
 
3
- ## 中文
4
3
 
5
- 默认资料修复已在 `0.4.6-vibe-beta.11` 发布:CLI 自动补齐此前跑通的 PPE 试用资料,用户只提供标题和头像。beta.10 仅修改了输入提示,没有自动补齐字段,真实基础信息提交会被拒绝。
4
+ `ttmg upload --vibe` 将本地小游戏上传到 TikTok Mini Games。用户提供游戏标题和头像,在手机 TikTok 扫码授权后,CLI 自动完成头像、应用资料和代码包上传。Skill 负责准备工程、调用命令和读取结果;CLI 负责素材校验、打包、授权轮询及上传。
6
5
 
7
- 本次范围:本地准备 → 授权绑定 → 上传头像 → 提交应用信息 → 上传代码包 → 上传完成。不包含预览、审核或正式发布。`--web` 使用真实 PPE 授权和上传;`--mock` 的授权与素材上传仍为模拟。网页授权后自动上传的修复已在 `0.4.6-vibe-beta.9` 发布;用户输入要求已在 `0.4.6-vibe-beta.10` 修正。
6
+ 适用版本:`0.4.6-vibe-beta.16`。手机授权与真实上传已使用 PPE 测试素材验证;正式环境未开放。上传完成不代表审核通过或正式发布。
8
7
 
9
- ### Web 上传入口
8
+ ## Quick Start
10
9
 
11
- 真实授权和上传使用 `--web`。安装 `vibe-beta` 标签对应的版本,再用 `ttmg --version` 核对实际执行版本。`beta` 是另一个发布标签,不能用它判断 Web 链路是否包含最新修复。无需设置 PPE 环境变量或预先执行 `ttmg login`;用户在本次浏览器授权页完成授权。
10
+ ```sh
11
+ ttmg upload --vibe
12
+ ```
13
+
14
+ 这是扫码上传入口。实际调用时,Skill 将用户提供的标题、头像和游戏路径作为参数传入;只运行入口命令不会自动补齐标题和头像:
15
+
16
+ ```sh
17
+ ttmg upload --vibe --dir ./game --title "星环守卫" --icon ./avatar.png --format ndjson
18
+ ```
19
+
20
+ 1. 启动命令,CLI 检查素材并自动打开电脑上的二维码页。
21
+ 2. 用户使用手机 TikTok 扫码授权,保持原命令运行。
22
+ 3. CLI 自动上传头像、应用资料和代码包,页面展示进度与结果。
23
+ 4. Skill 收到 `terminal=true`、`status=uploaded`、`uploaded=true`、`simulation=false` 且退出码为 0 后,报告上传完成。
24
+
25
+ 已有 ZIP 时,用 `--package ./game.zip` 替换 `--dir ./game`。无需预先执行 `ttmg login` 或配置 PPE 环境。描述和分类可省略,CLI 使用默认资料;完整参数见下文。
12
26
 
13
- Skill 只引导开发者准备游戏名称、本地头像和工程,然后调用 CLI、读取结构化状态。不调用平台接口、不保存 Token、不自行轮询、不增加名称头像表单。
27
+ ## 安装与本地预检
14
28
 
15
- Skill 固定调用:
29
+ 安装后确认版本为 `0.4.6-vibe-beta.16`,能力查询中 `authorizationMode` 为 `qr`。支持 Node.js 20.19.1–20.x 或 22 及以上版本。
16
30
 
17
31
  ```sh
18
- npm install -g @ttmg/cli@vibe-beta
32
+ npm install -g @ttmg/cli@0.4.6-vibe-beta.16
19
33
  ttmg --version
20
34
  ttmg capabilities --format json
21
- ttmg upload --vibe --web --dir ./game --title "星环守卫" --icon ./avatar.png --format ndjson
22
35
  ```
23
36
 
24
- Skill 启动一次命令并持续读取 NDJSON。宿主工具返回会话 ID 时,继续读取同一进程;等待用户授权期间不终止、不重启,也不再调用第二次上传。`--web` 全程使用真实授权和上传;`--mock` 仅用于下方单独列出的演示。
37
+ Skill 启动一次命令并持续读取 NDJSON。宿主工具返回会话 ID 时,继续读取同一进程;等待用户授权期间不终止、不重启,也不再调用第二次上传。扫码授权后由同一进程继续真实上传。
25
38
 
26
39
  可先检查素材,不创建 task、不打开页面:
27
40
 
28
41
  ```sh
29
- ttmg upload --vibe --web --dir ./game --title "星环守卫" --icon ./avatar.png --dry-run --format json
42
+ ttmg upload --vibe --dir ./game --title "星环守卫" --icon ./avatar.png --dry-run --format json
30
43
  ```
31
44
 
32
- 已有 ZIP 时,用 `--package ./game.zip` 替换 `--dir ./game`。名称和头像必须由开发者提供;演示脚本中的临时样本不作为产品默认素材。
45
+ 预检成功仅表示本地素材准备完成,不代表平台接受或上传成功。
33
46
 
34
- ### 用户需要提供什么
47
+ ## 用户需要提供什么
35
48
 
36
49
  **只向用户收集游戏标题和本地头像,并使用当前游戏目录或代码包。** 描述、服务条款、隐私政策、版权确认及其他应用资料由 CLI 使用既有 PPE 试用默认值补齐。分类可由 Skill 按下方目录选择,未选择时仍使用默认值;不向用户索要额外资料或增加填写表单。
37
50
 
51
+ - `--title`:非空游戏标题,去除首尾空白后最多 30 个字符。
52
+ - `--icon`:本地 PNG 或 JPEG,1024×1024,不超过 5 MiB。
53
+ - `--dir`:Native 小游戏工程目录,CLI 检查后打包;未指定路径时使用当前目录。
54
+ - `--package`:已有 Native ZIP,不超过 100 MiB;与 `--dir` 二选一。
55
+
56
+ 标题和头像必须使用用户提供的素材,不用演示样本代替。
57
+
38
58
  能力查询和上传事件均返回 `inputRequirements`:`requiredUserInputs=["title","icon"]`、`additionalMetadataSource="cli-defaults"`、`requestAdditionalMetadata=false`。`--app-info` 仅兼容旧调用,当前流程不使用。
39
59
 
40
60
  CLI 在 `app_info` 请求中自动带上 `description`、`category`、`subcategory`、`terms_of_service`、`privacy_policy`、`copyright_confirmation`、`contact_email`,再填入用户标题和真实上传头像 URI。默认资料标识为 `ppe-trial`;命令中没有这些参数,不代表请求里没传。能力查询的 `appInfoFields.defaultedByCli` 列出默认字段。
41
61
 
42
- ### 查询并推荐游戏分类
62
+ ## 可选游戏描述
63
+
64
+ 默认描述为 `Discover the fun of TikTok Mini Games.`,不包含游戏名称。Skill 可根据实际玩法生成描述并传入 `--description`,无需用户额外填写:
65
+
66
+ ```sh
67
+ ttmg upload --vibe --dir ./game --title "My game" --icon ./avatar.png --description "Stack cats on a rooftop and keep the tower balanced." --format ndjson
68
+ ```
69
+
70
+ - 优先级:`--description` > 旧 `--app-info` 文件中的描述 > 默认描述。只覆盖描述,其他字段保持原有规则。
71
+
72
+ - 参数首尾空白会被去除;空白文本或无效 Unicode 返回 `VIBE_INVALID_DESCRIPTION`,不会创建任务或上传。
73
+
74
+ - `prepared` 和后续终态返回 `description` 与 `descriptionSource`(`arguments / app-info / defaults`);可用 `--dry-run` 检查。
75
+
76
+ - 描述是可选 Skill 输入,省略仍可上传,不新增用户必填项。
77
+
78
+ ## 查询并推荐游戏分类
43
79
 
44
80
  以下命令和参数从 `0.4.6-vibe-beta.14` 开始提供。查询离线执行,不登录、不创建任务、不写平台:
45
81
 
@@ -53,7 +89,7 @@ ttmg game categories --category Puzzle --format json
53
89
  Skill 根据生成游戏的核心玩法和胜负条件选择组合,给用户一句推荐理由;用户已指定分类时优先保留。不增加必填表单;无法匹配时可使用 Other/Other。
54
90
 
55
91
  ```sh
56
- ttmg upload --vibe --web --dir ./game --title "星环守卫" --icon ./avatar.png --category Puzzle --subcategory Physics --format ndjson
92
+ ttmg upload --vibe --dir ./game --title "星环守卫" --icon ./avatar.png --category Puzzle --subcategory Physics --format ndjson
57
93
  ```
58
94
 
59
95
 
@@ -69,290 +105,106 @@ ttmg upload --vibe --web --dir ./game --title "星环守卫" --icon ./avatar.png
69
105
 
70
106
  - 查询类型不存在:`GAME_CATEGORY_UNKNOWN`;格式无效:`GAME_CATEGORIES_INVALID_FORMAT`。返回非零退出码。
71
107
 
72
- ### Skill 执行顺序
108
+ ## Skill 执行顺序
73
109
 
74
- 1. 调用上方 `--web --format ndjson` 命令;本地预检可先加 `--dry-run`。
75
- 2. 收到 `waiting_authorization`,提示用户在系统浏览器完成授权,保持原进程运行。
76
- 3. 收到 `uploading`,按 `uploadStep` 展示 `avatar`、`app_info`、`package` 进度。授权轮询和上传由 CLI 完成。
77
- 4. 收到 `terminal=true`、`status=uploaded`、`uploaded=true`、`simulation=false`,确认真实上传完成。`failed`、`cancelled` 或进程中断按下方失败说明处理。
110
+ 1. 调用上方 `--vibe --format ndjson` 命令;本地预检可先加 `--dry-run`。
78
111
 
79
- ### Skill 读取什么
112
+ 2. 收到 `waiting_authorization`,提示用户用手机 TikTok 扫描本地页中的二维码,保持原进程运行。
80
113
 
81
- #### 上传时直接使用网页授权
114
+ 3. 收到 `uploading`,按 `uploadStep` 展示 `avatar`、`app_info`、`package` 进度。授权轮询和上传由 CLI 完成。
82
115
 
83
- 使用 `--web`:CLI 通过内置 `ppe_op_vc` 真实创建任务,在执行机的系统浏览器打开授权页,并持续查询真实绑定状态。服务端返回 `ready_for_input=true` 后,原进程使用同一任务依次上传头像、提交应用信息、上传代码包。Skill 不需要配置环境、再调用 `auth open` 或另发上传命令。
116
+ 4. 收到 `terminal=true`、`status=uploaded`、`uploaded=true`、`simulation=false`,确认真实上传完成。`failed`、`cancelled` 或进程中断按下方失败说明处理。
84
117
 
85
- ```sh
86
- ttmg upload --vibe --web --dir ./game --title "星环守卫" --icon ./avatar.png --format ndjson
87
- ```
118
+ ## 扫码授权与自动上传
88
119
 
89
- 原 `upload --vibe --mock` 链路不变。`--web` 与 `--mock`、`--mock-scenario`、`--vibe-api`、`--no-open` 互斥,在创建任务前报错;显式 `--web` 不继承旧 Mock 后端设置。`--dry-run` 不创建任务或打开浏览器。JSON/NDJSON 模式也会打开浏览器,但不污染结构化输出。真实上传失败时返回对应错误,不自动重试写入或降级 Mock。
120
+ CLI 使用内置 `ppe_op_vc` 创建任务,在执行机打开二维码页并持续查询绑定状态。二维码直接编码后端返回的 `landing_url`,不包装应用协议。用户在手机 TikTok 完成授权,服务端返回 `ready_for_input=true` 后,原进程依次上传头像、应用信息和代码包。
90
121
 
91
- 等待事件返回 `authorizationMode=web` 和 `browserOpenRequested`。真实授权场景的 `nextAction=open_browser` 表示在浏览器完成授权,不代表已授权。打开失败时返回 `browserOpenErrorCode=VIBE_BROWSER_OPEN_FAILED`,仍轮询原任务,可用下面的辅助命令重试,不重新建任务。
122
+ 等待事件返回 `authorizationMode=qr`、`nextAction=scan_qr`、`pageUrl` 和 `browserOpenRequested`。页面展示本次提交的标题、头像、描述、类型和子类型;默认值与自定义值均以实际提交资料为准。
92
123
 
93
- #### 手动打开浏览器授权
124
+ text、JSON、NDJSON 均自动打开二维码页,`--no-open` 可关闭。打开失败返回 `browserOpenErrorCode=VIBE_BROWSER_OPEN_FAILED`,原任务继续等待;`--dry-run` 不创建任务、不打开页面。
94
125
 
95
- 保持上传命令运行。收到 `waiting_authorization` 后,如果事件提供 `authorizationOpenCommand`,Skill 可执行该命令,或使用同一事件的 `pageUrl`:
126
+ ## 重新打开同一任务的二维码页
127
+
128
+ 保持原上传进程运行,在同一电脑打开 `pageUrl`,或执行事件返回的 `authorizationOpenCommand`:
96
129
 
97
130
  ```sh
98
131
  ttmg auth open --page-url <pageUrl> --format json
99
132
  ```
100
133
 
101
- 命令通过临时本地页面跳转到后端原始 `landing_url`,不使用 `aweme://`,不新建任务或上传文件。凭证只留在上传进程与页面服务中,不输出到 Skill 或放进命令参数。原上传进程继续轮询,授权成功与否以其 `readyForInput` 为准。
102
-
103
- `pageUrl` 是本机绑定/上传进度页,不是平台原始授权页。`authorizationOpenCommand` 是重新打开同一任务授权页的入口;正常情况下 `--web` 已经自动打开,无需重复执行。`browserOpenRequested=true` 只代表发起打开浏览器,不能据此判定授权成功。两种页面入口都依赖原上传进程,不能把本机链接发给另一台电脑使用。
134
+ 该命令只重新打开本地二维码页。`status=open_requested`、`browserOpenRequested=true` 只表示请求打开页面,不代表授权成功。页面已结束或过期时返回 `VIBE_AUTH_PAGE_UNAVAILABLE`;不得因此自动创建新任务。
104
135
 
105
- 成功返回 `status=open_requested`、`browserOpenRequested=true`、`platformWrite=false`,只表示已请求系统浏览器打开。页面过期、流程结束或没有可用真实授权地址时,返回 `VIBE_AUTH_PAGE_UNAVAILABLE`;URL 输入错误返回 `VIBE_INVALID_PAGE_URL`,浏览器启动失败返回 `VIBE_BROWSER_OPEN_FAILED`。不得因打开失败而自动创建新任务。
136
+ `pageUrl` 只能在 CLI 所在电脑打开;手机扫描页面中的二维码,不访问本地地址。原始授权链接和凭证不进入命令参数或结构化输出。
106
137
 
107
- 命令在 CLI 所在电脑执行;远程机器不会打开开发者电脑的浏览器。二维码原路径和 `--mock` 自动推进逻辑保持不变;真实网页授权与上传使用 `--web`。
138
+ ## 结构化状态与结果判断
108
139
 
109
140
  输出 schema 为 `"2"`。每行 NDJSON 是同一 `operationId` 的状态快照;只有最后一行 `terminal=true`。`--format json` 仅在结束时向 stdout 输出一个对象,等待授权的本地页面地址写到 stderr。不要解析中文/英文文案判断状态。
110
141
 
111
- | status | Skill 处理 |
112
- | ------------------------------- | ----------------------------------------------------------------------------------------- |
113
- | precheck / packaging / prepared | 正在检查或准备素材;dry-run 的 prepared 为终态 |
114
- | creating_task | 正在准备授权绑定 |
115
- | waiting_authorization | nextAction=open_browser 时在已打开的系统浏览器完成授权;scan_qr 时提示 TikTok 扫码;wait 时等待模拟推进 |
116
- | uploading | 根据 uploadStep 显示 avatar、app_info、package 的进度,不再询问授权 |
117
- | uploaded | terminal=true 且 uploaded=true:本次上传完成;不是审核通过或正式发布 |
118
- | failed / cancelled | 根据 errorCode、message 和 nextAction 提示处理,不自动重传 |
142
+ - `precheck / packaging / prepared`:正在检查或准备素材;dry-run 的 prepared 为终态。
119
143
 
120
- 固定字段:`schemaVersion`、`command`、`mode`、`operationId`、`ts`、`status`、`terminal`、`nextAction`、`message`、`backend`、`simulation`、`platformWrite`、`uploadAttempted`、`uploaded`、`errorCode`、`error`。
144
+ - `creating_task`:正在准备授权绑定。
121
145
 
122
- 从真实创建任务请求发起前开始 `platformWrite=true`,表示已尝试平台写入,不代表创建或上传成功。只有内部离线测试、本机 HTTP 和 dry-run 保持 `platformWrite=false`。
146
+ - `waiting_authorization`:nextAction=scan_qr 时使用手机 TikTok 扫码授权,保持原进程继续等待。
123
147
 
124
- `backend=ppe-mock` 时 `simulation=true`、`simulationStartsAt=authorization`;创建任务前开始 `platformWrite=true`。`taskStatusRaw`、`readyForInput` 始终保留最后一次真实查询值,模拟状态单独放在 `simulatedTaskStatusRaw`、`simulatedReadyForInput`。终态仍为 `uploaded`,但只表示模拟上传完成,不代表真实授权或上传成功;Skill 必须保留模拟提示。
148
+ - `uploading`:根据 uploadStep 显示 avatar、app_info、package 的进度,不再询问授权。
125
149
 
126
- 按阶段补充:`taskId`(字符串,禁止转成 JS Number)、`pollIntervalSeconds`、`readyForInput`、`taskStatusRaw`(仅诊断)、`uploadStep`、`loadedBytes`、`totalBytes`、`pageUrl`、`qrPurpose=authorization_binding`、素材大小和包 SHA256。代码包字节进度达到 100% 不代表成功,必须等待最终上传回执。
150
+ - `uploaded`:terminal=true、uploaded=true、simulation=false 且退出码 0:本次上传完成;不是审核通过或正式发布。
127
151
 
128
- `nextAction` 取值:`wait`、`open_browser`、`scan_qr`、`fix_input`、`restart_authorization`、`check_task`、`none`。已开始上传后发生失败/超时,先检查 task,不能直接再次创建并重传。若上传已完成但页面失败,仍保留 `uploaded=true`,同时返回错误;Skill 提示上传已完成但展示失败。
152
+ - `failed / cancelled`:根据 errorCode、message 和 nextAction 提示处理,不自动重传。
129
153
 
130
- 退出码:成功/dry-run 为 0,失败为 1,Ctrl+C 为 130。进程或宿主意外终止导致没有终态时,不得认定上传成功。模拟必须显示为模拟:即使 `uploaded=true`,`simulation=true` 时也只表示模拟步骤完成。纯 Mock 的 `platformWrite=false`;混合联调创建过真实任务时为 true,但都不代表真实上传。
131
154
 
132
- ### Mock 覆盖与演示
155
+ 固定字段:`schemaVersion`、`command`、`mode`、`operationId`、`ts`、`status`、`terminal`、`nextAction`、`message`、`backend`、`simulation`、`platformWrite`、`uploadAttempted`、`uploaded`、`errorCode`、`error`。
133
156
 
134
- `npm run demo:vibe` 会构建并用临时工程和头像运行 CLI;真实检查、ZIP 打包和 PPE 创建/查询,模拟授权与上传。需要后端可访问,无需完成手机授权。结果页在进程结束后继续保留至到期。
157
+ 从真实创建任务请求发起前开始 `platformWrite=true`,表示已尝试平台写入,不代表创建或上传成功。只有内部离线测试、本机 HTTP 和 dry-run 保持 `platformWrite=false`。
135
158
 
136
- ```sh
137
- ttmg upload --vibe --package ./game.zip --title "测试游戏" --icon ./avatar.png --mock --format ndjson
138
- ttmg upload --vibe --package ./game.zip --title "测试游戏" --icon ./avatar.png --mock --mock-scenario denied --format ndjson
139
- ttmg upload --vibe --package ./game.zip --title "测试游戏" --icon ./avatar.png --mock --mock-scenario timeout --timeout 5 --format ndjson
140
- ttmg upload --vibe --package ./game.zip --title "测试游戏" --icon ./avatar.png --mock --mock-scenario upload-failed --format ndjson
141
- ```
159
+ 按阶段补充:`taskId`(字符串,禁止转成 JS Number)、`pollIntervalSeconds`、`readyForInput`、`taskStatusRaw`(仅诊断)、`uploadStep`、`loadedBytes`、`totalBytes`、`pageUrl`、`qrPurpose=authorization_binding`、素材大小和包 SHA256。代码包字节进度达到 100% 不代表成功,必须等待最终上传回执。
142
160
 
143
- | 场景 | 结果 |
144
- | ----------------------------------------- | -------------------------------------------------------------------- |
145
- | success | 第三次轮询允许上传,头像/信息/代码包依次完成 |
146
- | denied | 授权取消,VIBE_AUTH_DENIED,不上传 |
147
- | expired | 授权过期,VIBE_AUTH_EXPIRED,不上传 |
148
- | timeout | 持续等待,直到整体超时 VIBE_TIMEOUT |
149
- | icon-failed / info-failed / upload-failed | 在对应上传步骤失败,uploadStep 指明位置 |
150
- | processing | 包已上传,后端状态仍为 PROCESSING;CLI 返回 uploaded,不等 SUCCEEDED |
161
+ `nextAction` 取值:`wait`、`scan_qr`、`fix_input`、`restart_authorization`、`check_task`、`none`。已开始上传后发生失败/超时,先检查 task,不能直接再次创建并重传。若上传已完成但页面失败,仍保留 `uploaded=true`,同时返回错误;Skill 提示上传已完成但展示失败。
151
162
 
152
- Mock 的 denied 是交互测试场景,真实端内拒绝授权如何映射错误仍待后端确认。独立离线测试通过注入传输实现;用户执行的 `--mock` 会真实创建并查询 PPE 任务,但不调用真实素材上传接口。
163
+ 退出码:成功/dry-run 为 0,失败为 1,Ctrl+C 为 130。进程或宿主意外终止导致没有终态时,不得认定上传成功。
153
164
 
154
- 轮询间隔使用创建任务返回的 `poll_interval_seconds`,第三次真实查询后模拟授权。`--poll-interval` 仅用于覆盖测试间隔。`--timeout` 是整体超时,默认 300 秒。不自动重试写接口、不实现跨进程续传。
165
+ 轮询间隔使用创建任务返回的 `poll_interval_seconds`。`--timeout` 是整体超时,默认 300 秒。不自动重试写接口、不实现跨进程续传。
155
166
 
156
- ### 页面与素材
167
+ ## 页面与素材
157
168
 
158
- 同一电脑本地页显示绑定状态、上传进度、上传完成;二维码模式显示授权绑定码,Web 模式在系统浏览器完成授权。失败时清除授权码并显示失败原因。`--web` 在 text、JSON、NDJSON 格式下均自动打开授权页;其他模式只有 text 默认打开本地页,可用 `--no-open` 关闭。Skill 可用 `pageUrl` 展示本地进度页。
169
+ 本地页在扫码、上传、成功或失败时均展示本次资料。后台查询状态,只更新变化内容,不整页刷新;完成或失败后停止查询。授权完成或失败后移除二维码。Skill 可用 `pageUrl` 重新打开同一页面。
159
170
 
160
171
  页面只监听 127.0.0.1,二维码才由手机扫描,手机不访问 pageUrl。默认 15 分钟后关闭,内容驻留内存;测试可设置 `TTMG_VIBE_PAGE_TTL_MS`(1—900000)。取消进程会关闭页面;成功与可显示的失败页面保留至到期。不要分享本地页面地址。
161
172
 
162
- 真实执行的部分包括本地项目检查和 ZIP 打包。文件直接输入只检查非空、大小与文件头,不代表完整图像解码、ZIP 内容检查或平台审核。现有 10 MiB 头像、100 MiB ZIP 为本地保护阈值,不是后端已确认限制。图片识别 PNG/JPEG/WebP。
173
+ CLI 执行本地项目检查和 ZIP 打包,并按 PNG/JPEG、1024×1024、5 MiB 校验上传头像。文件头检查不等于完整图像解码;ZIP 非空、大小和文件头检查不等于完整内容、解压总大小校验或平台审核。
163
174
 
164
175
  准备完成后固定本次素材字节,授权期间不会重新读取。打包排除 .ttmg、.env\*、PEM 和 KEY 等文件,但不保证识别所有业务秘密。
165
176
 
166
177
  CLI 在工程目录的 `.ttmg/vibe-project.json` 保存并复用非敏感 source_project_id;使用 --package 时保存在 ZIP 所在目录。不要将多个独立游戏的 ZIP 放在同一身份目录。dry-run 不创建此文件。每次运行使用新的 task_idempotency_id,当前不支持中断续传。凭证只驻留进程内存,不进入事件、文件、日志或错误信息。
167
178
 
168
- ### HTTP 适配边界
169
-
170
- Mock 与本地 HTTP 共用请求构造、业务响应校验及状态映射,基于 2026-09-12 的 Minis Import BFF IDL:
179
+ ## HTTP 适配边界
171
180
 
172
- | 方法 / 接口(统一前缀 /bff/app_info/minis_import/) | 请求 | 响应 |
173
- | --------------------------------------------------- | --------------------------------------------------------------------------- | --------------------------------------------------------- |
174
- | POST create_minis_import_task_for_agent/ | source_type=1、source_project_id、task_idempotency_id、minis_type=MINI_GAME | task_id、import_token、landing_url、poll_interval_seconds |
175
- | GET get_minis_import_task_status_for_agent/ | Query:task_id、import_token | status、ready_for_input |
176
- | POST upload_minis_import_app_icon_for_agent/ | Multipart:task_id、import_token、file | icon_uri |
177
- | POST submit_minis_import_info_for_agent/ | JSON:task_id、import_token、app_info(完整应用信息,加 CLI 提供的 app_name、icon_uri) | error_info |
178
- | POST upload_minis_import_package_for_agent/ | Multipart:task_id、import_token、asset_type=2、file | package_uri、status |
179
-
180
- 所有响应必须业务 `error_info.code=0`。最后一步还要求非空 package_uri 和合法非失败状态;完成后不再轮询。HTTP 200、进度100% 都不能单独作为成功判定。19位 task_id 在 CLI 内保留字符串,提交 i64 JSON 时无损编码。
181
-
182
- ```sh
183
- TTMG_VIBE_BACKEND=local-http TTMG_VIBE_API=http://127.0.0.1:3100 ttmg upload --vibe --package ./game.zip --title "测试游戏" --icon ./avatar.png --format ndjson
184
- ```
185
-
186
- 维护者可使用 `--vibe-api http://127.0.0.1:3100` 验证本机 HTTP 合同,只接受回环 IP,不跟随重定向、不读取 Cookie;本地服务需实现上表协议。博华试用无需此选项,直接 `--mock`,PPE 路由由 CLI 内置。正式环境未开放。
187
-
188
- **v1 → v2 兼容性变化**:旧 UUID 换 Token 的三接口协议废弃,`--vibe-authorize-url` 返回明确错误;授权地址来自 landing_url。不再输出 preview_ready、game_preview、uploadId、reviewStatus。Skill 必须校验 schemaVersion=2,并按新终态处理。普通不带 --vibe 的 upload 不变。
181
+ 上传使用以下 Minis Import BFF 接口:
189
182
 
190
- 2026-09-14 已核对 BFF 源码:头像 PNG/JPEG、1024×1024、5 MiB;Native ZIP 和解压总大小上限 100 MiB。本地暂未实现完整 ZIP 内容及解压总大小校验。2026-09-15 修复构建使用自有测试素材跑通真实 PPE 网页授权、头像、默认资料和代码包上传;该验证不覆盖全部游戏、手机授权或正式环境。后端接口调整留在适配层处理;若用户动作或成功语义改变,应协商升级 CLI schema。
183
+ - `POST create_minis_import_task_for_agent/`:请求 source_type=1、source_project_id、task_idempotency_id、minis_type=MINI_GAME。响应 task_id、import_token、landing_url、poll_interval_seconds。
191
184
 
192
- ### 验证
193
-
194
- `npm run test:vibe`:Mock、HTTP 合同、请求顺序、i64、失败、取消、输入和页面测试。
195
-
196
- `npm run test:vibe-process`:构建后的真实命令、JSON/NDJSON、环境配置、页面生命周期与退出码。完整 CLI 回归仍为 `npm run test:agent-contract`。测试通过不等于真实绑定上传已验证。
197
-
198
- ## English
199
-
200
- The default-metadata fix shipped in `0.4.6-vibe-beta.11`. The CLI fills the existing PPE trial metadata automatically; users provide only title and icon. Beta.10 changed input guidance without filling the fields, and its real app-info submission was rejected.
201
-
202
- ### Web upload entry
203
-
204
- Scope: local preparation → authorization binding → avatar upload → app-info submission → package upload → **upload complete**. No preview, review or production release. `--web` uses real PPE authorization and uploads; `--mock` still simulates authorization and material uploads.
205
-
206
- Automatic upload was fixed in `0.4.6-vibe-beta.9`; the user-input clarification ships in `0.4.6-vibe-beta.10`.
207
-
208
- Use `--web` for real authorization and upload. Install `vibe-beta` and check the executable with `ttmg --version`. The separate `beta` tag does not identify the latest Web fixes. No PPE environment variables or prior `ttmg login` are required; the user authorizes in the browser for this task.
209
-
210
- ```sh
211
- npm install -g @ttmg/cli@vibe-beta
212
- ttmg --version
213
- ttmg capabilities --format json
214
- ttmg upload --vibe --web --dir ./game --title "My game" --icon ./avatar.png --format ndjson
215
- ```
185
+ - `GET get_minis_import_task_status_for_agent/`:请求 Query:task_id、import_token。响应 status、ready_for_input。
216
186
 
217
- Use `--package ./game.zip` instead of `--dir` for an existing ZIP. Add `--dry-run --format json` to the Web command for local preparation only; it creates no task and opens no browser.
187
+ - `POST upload_minis_import_app_icon_for_agent/`:请求 Multipart:task_id、import_token、file。响应 icon_uri。
218
188
 
219
- Start one command and keep reading its NDJSON. If the host tool returns a session ID, keep reading that same process while the user authorizes. Do not stop, restart or launch another upload. `--web` uses real authorization and uploads throughout; `--mock` is the separate demo mode below. The Skill does not call platform APIs, store credentials or add a metadata form.
189
+ - `POST submit_minis_import_info_for_agent/`:请求 JSON:task_id、import_token、app_info(完整应用信息,加 CLI 提供的 app_name、icon_uri)。响应 error_info。
220
190
 
221
- ### User inputs
191
+ - `POST upload_minis_import_package_for_agent/`:请求 Multipart:task_id、import_token、asset_type=2、file。响应 package_uri、status。
222
192
 
223
- **Collect only the game title and local icon, using the current game directory or ZIP.** The CLI fills other app metadata with existing PPE trial defaults. The Skill may select a category pair from the catalog below; omission keeps the defaults. Do not ask the user for extra fields or add a form.
224
193
 
225
- Capabilities and upload events include `inputRequirements` with `requiredUserInputs=["title","icon"]`, `additionalMetadataSource="cli-defaults"` and `requestAdditionalMetadata=false`.
226
-
227
- The `--app-info` option remains for legacy callers only; the current workflow does not use it.
228
-
229
- The CLI submits `description`, `category`, `subcategory`, `terms_of_service`, `privacy_policy`, `copyright_confirmation` and `contact_email` inside `app_info`, together with the user title and uploaded icon URI. The profile is `ppe-trial`; missing command-line arguments do not mean missing request fields. Capabilities list the defaults under `appInfoFields.defaultedByCli`.
230
-
231
- Source checked on 2026-09-14: BFF enforces PNG/JPEG, 1024×1024, 5 MiB icons and a 100 MiB Native ZIP/uncompressed-size limit. Full local ZIP-content/uncompressed-size validation is not implemented. On 2026-09-15, a corrected build completed real PPE web authorization and icon, default app-info and package uploads with owned test fixtures. This does not cover every game, phone authorization or production.
232
-
233
- ### Query and recommend game categories
234
-
235
- These commands and options are available from `0.4.6-vibe-beta.14`. Queries run offline without login, task creation or platform writes:
236
-
237
- ```sh
238
- ttmg game categories --format json
239
- ttmg game categories --category Puzzle --format json
240
- ```
241
-
242
- The result includes `schemaVersion="1"`, `catalogVersion`, `source=bundled`, `platformWrite=false`, `categories[].value` and `subcategories[].value/description`.
243
-
244
- There are 12 categories and 114 subcategories with English gameplay descriptions. Filtering uses the exact category value. The version identifies a bundled snapshot, not a live platform fetch.
245
-
246
- The Skill selects a valid pair from the generated game's core gameplay and win conditions and gives a short reason. Preserve a user's explicit choice. Do not add a required form; use Other/Other when no category matches.
247
-
248
- ```sh
249
- ttmg upload --vibe --web --dir ./game --title "My game" --icon ./avatar.png --category Puzzle --subcategory Physics --format ndjson
250
- ```
251
-
252
-
253
- - Omit both: keep `Other / Other`; existing Skill commands work unchanged.
254
-
255
- - Supply both: override only category fields after validation; other metadata defaults remain.
256
-
257
- - Supply one: `VIBE_CATEGORY_PAIR_REQUIRED`. Invalid values or a mismatched pair: `VIBE_INVALID_CATEGORY`. Fail before task creation or browser opening, without a silent fallback.
258
-
259
- - Legacy `--app-info` calls retain file values and existing validation when new options are absent. Explicit category options override file category fields. New callers need no metadata file.
260
-
261
- - The `prepared` and subsequent terminal events return `classification={category, subcategory, source, catalogVersion}`, with source `arguments / defaults / app-info`. Use `--dry-run` to inspect the effective selection.
262
-
263
- - Unknown query category: `GAME_CATEGORY_UNKNOWN`. Invalid format: `GAME_CATEGORIES_INVALID_FORMAT`. Both return nonzero exit codes.
264
-
265
- ### Skill execution order
266
-
267
- 1. Run the `--web --format ndjson` command above; optionally precheck with `--dry-run`.
268
- 2. At `waiting_authorization`, ask the user to authorize in the system browser and keep the process running.
269
- 3. At `uploading`, display `uploadStep`: `avatar`, `app_info`, then `package`. The CLI owns polling and uploads.
270
- 4. Confirm real completion only when `terminal=true`, `status=uploaded`, `uploaded=true`, `simulation=false`. Handle failure, cancellation or interruption as described below.
271
-
272
- ### Output and decisions
273
-
274
- #### Use browser authorization during upload
275
-
276
- Use `--web` for real authorization. The CLI creates a task through the built-in `ppe_op_vc` lane, opens authorization in the execution machine's system browser and polls real binding status. Once the server returns `ready_for_input=true`, the same process uploads the icon, submits app information and uploads the package using the same task. No environment setup, `auth open` helper or second upload command is required.
277
-
278
- ```sh
279
- ttmg upload --vibe --web --dir ./game --title "My game" --icon ./avatar.png --format ndjson
280
- ```
281
-
282
- The original `upload --vibe --mock` workflow is unchanged. `--web` conflicts with `--mock`, `--mock-scenario`, `--vibe-api` and `--no-open` before task creation, and does not inherit an old Mock backend environment setting. Dry-run creates no task and opens no browser. JSON/NDJSON also open the browser without contaminating stdout. Real upload failures return an error; writes are not automatically retried or replaced by Mock results.
283
-
284
- Waiting events add `authorizationMode=web` and `browserOpenRequested`. For real authorization, `nextAction=open_browser` requests browser approval; it does not prove approval. If opening fails, `browserOpenErrorCode=VIBE_BROWSER_OPEN_FAILED` is returned while polling continues. Retry the helper below against the same task instead of creating another one.
285
-
286
- #### Open browser authorization manually
287
-
288
- Keep the upload process running. On `waiting_authorization`, execute its optional
289
- `authorizationOpenCommand`, or use the `pageUrl` from that event:
194
+ 所有响应必须业务 `error_info.code=0`。最后一步还要求非空 package_uri 和合法非失败状态;完成后不再轮询。HTTP 200、进度100% 都不能单独作为成功判定。19位 task_id 在 CLI 内保留字符串,提交 i64 JSON 时无损编码。
290
195
 
291
196
  ```sh
292
- ttmg auth open --page-url <pageUrl> --format json
197
+ TTMG_VIBE_BACKEND=local-http TTMG_VIBE_API=http://127.0.0.1:3100 ttmg upload --vibe --package ./game.zip --title "测试游戏" --icon ./avatar.png --format ndjson
293
198
  ```
294
199
 
295
- The temporary loopback page redirects the system browser to the original backend
296
- `landing_url`, without the `aweme://` wrapper. No new task or upload is performed.
297
- Credentials stay inside the uploader/page worker, not in Skill output or command
298
- arguments. The original uploader keeps polling; its `readyForInput` determines
299
- authorization readiness.
300
-
301
- `pageUrl` is the local binding/upload-progress page, not the original platform authorization URL. To reopen authorization for the same task, execute `authorizationOpenCommand`. Normally `--web` has already opened it. `browserOpenRequested=true` only confirms the open request, not authorization. Both page entry points depend on the original uploader and the CLI computer; do not send localhost links to another computer.
302
-
303
- Success reports `status=open_requested`, `browserOpenRequested=true`, and
304
- `platformWrite=false`; it does not mean authorization succeeded. Expired,
305
- completed, or unavailable authorization pages return `VIBE_AUTH_PAGE_UNAVAILABLE`;
306
- bad input returns `VIBE_INVALID_PAGE_URL`, and browser launch failures return
307
- `VIBE_BROWSER_OPEN_FAILED`. Do not create another task automatically on failure.
308
-
309
- This opens the browser on the CLI computer, not a remote user's computer. Existing
310
- QR behavior and `--mock` auto-advance stay unchanged. Use `--web` for real browser
311
- authorization followed by upload.
312
-
313
- Schema **2** provides NDJSON snapshots under one operationId, with exactly one final `terminal=true` event. JSON mode emits one final object on stdout and the authorization page address on stderr. With `--web`, all output formats open the system browser automatically. Other modes open pageUrl automatically only in text mode unless --no-open is set.
314
-
315
- | status | Skill action |
316
- | ------------------------------- | ----------------------------------------------------------------------------------------- |
317
- | precheck / packaging / prepared | Wait for input preparation; prepared is terminal only for dry-run |
318
- | creating_task | Preparing binding |
319
- | waiting_authorization | open_browser requests approval in the opened system browser; scan_qr requests a TikTok scan; wait means simulation advances automatically |
320
- | uploading | Follow uploadStep: avatar, app_info, package |
321
- | uploaded | terminal=true and uploaded=true mean upload complete, not release |
322
- | failed / cancelled | Read errorCode, message and nextAction; do not blindly repeat uploads |
323
-
324
- Stable fields: schemaVersion, command, mode, operationId, ts, status, terminal, nextAction, message, backend, simulation, platformWrite, uploadAttempted, uploaded, errorCode, error. Optional evidence: taskId (string), taskStatusRaw (diagnostics only), pollIntervalSeconds, readyForInput, uploadStep, loadedBytes, totalBytes, pageUrl, qrPurpose=authorization_binding, sizes and packageSha256.
200
+ 维护者可使用 `--vibe-api http://127.0.0.1:3100` 验证本机 HTTP 合同,只接受回环 IP,不跟随重定向、不读取 Cookie;本地服务需实现上表协议。Skill 使用 `--vibe`,PPE 路由由 CLI 内置。正式环境未开放。
325
201
 
326
- platformWrite becomes true immediately before attempting real task creation, not as proof of successful creation or upload. Only injected offline tests, loopback HTTP and dry-run keep platformWrite=false.
327
-
328
- For backend=ppe-mock, simulation=true and simulationStartsAt=authorization. platformWrite becomes true before real task creation. taskStatusRaw and readyForInput retain the last real observation; simulatedTaskStatusRaw and simulatedReadyForInput describe the local demo separately. The uploaded terminal state means simulated completion only; the Skill must retain the simulation label.
329
-
330
- nextAction is wait, open_browser, scan_qr, fix_input, restart_authorization, check_task or none. If upload was attempted, verify the task before retrying. If a result page fails after confirmed upload, uploaded remains true alongside the error. Progress at 100% is not a receipt. Missing terminal output after a killed process is not success. Exit codes: 0 success/dry-run, 1 failure, 130 cancellation.
331
-
332
- Pure Mock reports simulation=true and platformWrite=false. Hybrid PPE + Mock reports platformWrite=true once real task creation is attempted, but uploaded=true still means simulated completion only. No backend exposes credentials or raw HTTP errors. Backend integration must preserve this public contract; changes to user actions or completion semantics require an explicit schema migration.
333
-
334
- ### Mock, UI and inputs
335
-
336
- Run `npm run demo:vibe` for the CLI with temporary game/icon fixtures. Local checking, ZIP creation and PPE task creation/polling are real; authorization and uploads are simulated. Backend access is required, phone authorization is not. Scenarios: success, denied, expired, timeout, upload-failed, processing, icon-failed, info-failed. Use --mock-scenario and --timeout to test failures. Denial is a mock interaction scenario, not a confirmed backend error mapping.
337
-
338
- The same local page changes from binding QR to upload progress and completion, without preview QR or metadata form. Failures clear the binding QR. It listens only on 127.0.0.1, retains content in memory, and expires after 15 minutes; the phone scans the QR rather than visiting pageUrl. Success/failure pages remain after CLI completion; cancellation closes the page. Test TTL: TTMG_VIBE_PAGE_TTL_MS=1..900000.
339
-
340
- The trial follows poll_interval_seconds and simulates input readiness after the third real query; --poll-interval is a testing override. The overall --timeout defaults to 300 seconds. No automatic write retries or cross-process resume.
341
-
342
- The supplied title/icon/package bytes are fixed before authorization. Direct files are checked for size and signatures, not decoded or fully inspected. PNG/JPEG/WebP and 10 MiB icon / 100 MiB ZIP limits are provisional local guards, not confirmed platform rules. Project packaging excludes .ttmg, .env\*, PEM and KEY files, not every possible secret.
343
-
344
- A non-secret source_project_id is persisted in .ttmg/vibe-project.json under the project, or the ZIP parent for --package. Keep distinct games in separate directories. Dry-run does not create identity metadata. Each invocation has a new task_idempotency_id; credentials are held only in memory.
345
-
346
- ### Adapter and verification
347
-
348
- The five endpoint contracts are listed in the table above. Mock and loopback HTTP share request construction and response validation. The HTTP adapter implements POST create → GET status with task_id/import_token query parameters → Multipart icon → JSON app_info → Multipart package with asset_type=2 (Native). Multipart Content-Type includes its generated boundary; JSON i64 task IDs are encoded losslessly.
349
-
350
- A business-success response requires error_info.code=0. Package completion additionally requires package_uri and a valid non-failure status; no polling until SUCCEEDED. No platform Cookies or redirects are used. Configure TTMG_VIBE_BACKEND=local-http plus TTMG_VIBE_API=http://127.0.0.1:3100, or pass --vibe-api explicitly; this option rejects remote hosts.
202
+ **v1 → v2 兼容性变化**:旧 UUID 换 Token 的三接口协议废弃,`--vibe-authorize-url` 返回明确错误;授权地址来自 landing_url。不再输出 preview_ready、game_preview、uploadId、reviewStatus。Skill 必须校验 schemaVersion=2,并按新终态处理。普通不带 --vibe 的 upload 不变。
351
203
 
352
- For internal PPE integration, set TTMG_VIBE_BACKEND=ppe and TTMG_VIBE_PPE=ppe_op_vc without changing the Skill command. This uses real creation/polling on developers.tiktok.com and encodes the QR as aweme://webview?url=<encodeURIComponent(landing_url)>. The phone must use the same lane. OAuth is not bypassed or simulated. After authorization, the CLI uploads the icon, submits the title and icon URI, and uploads the package. The CLI fills other app metadata with existing PPE trial defaults. The regular --web entry configures PPE internally and opens the system browser.
204
+ 2026-09-14 已核对 BFF 源码:头像 PNG/JPEG、1024×1024、5 MiB;Native ZIP 和解压总大小上限 100 MiB。本地暂未实现完整 ZIP 内容及解压总大小校验。2026-09-16 本地构建使用自有测试素材跑通真实 PPE 手机扫码授权、头像、默认资料和代码包上传。该验证不覆盖全部游戏或正式环境。后端接口调整留在适配层处理;若用户动作或成功语义改变,应协商升级 CLI schema。
353
205
 
354
- The normal --mock trial internally uses ppe_op_vc without environment variables. Task creation, QR and three polls are real; authorization, icon, app-info and package uploads are simulated with separate in-memory credentials. This changes --mock from an offline run into a PPE integration trial: platformWrite becomes true when task creation is attempted, while simulation remains true. No real material-upload endpoint is called, and real request failures still fail. --mock-scenario controls only simulated steps. Offline unit/process tests use injected transports, not a separate developer configuration.
206
+ ## 验证
355
207
 
356
- Schema-v1 UUID endpoints, --vibe-authorize-url, preview_ready, game_preview, uploadId and reviewStatus are retired. The deprecated option returns an explicit error. Ordinary upload without --vibe is unchanged.
208
+ `npm run test:vibe`:HTTP 合同、请求顺序、i64、失败、取消、输入和页面测试。
357
209
 
358
- Unconfirmed: token expiry/retry rules, actual denial mapping and in-client PPE Cookie behavior. Run test:vibe, built test:vibe-process, and test:agent-contract. Local contract tests do not establish real platform or device results; the PPE test-fixture result above is recorded separately.
210
+ `npm run test:vibe-process`:构建后的真实命令、JSON/NDJSON、环境配置、页面生命周期与退出码。完整 CLI 回归仍为 `npm run test:agent-contract`。测试通过不等于真实绑定上传已验证。