@ttmg/cli 0.4.5 → 0.4.6-agent-beta.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.
Files changed (82) hide show
  1. package/README.md +644 -2
  2. package/dist/index.js +22502 -6070
  3. package/dist/index.js.map +1 -1
  4. package/dist/package.json +36 -4
  5. package/dist/public/assets/{Card-BAsimNoh.js → Card-CN2lxY0Y.js} +1 -1
  6. package/dist/public/assets/{Detail-rVxbEDgh.js → Detail-CELZZ-4h.js} +1 -1
  7. package/dist/public/assets/Detail-CELZZ-4h.js.br +0 -0
  8. package/dist/public/assets/{MonetizationMode-B20TAE9o.js → MonetizationMode-C7DNqium.js} +1 -1
  9. package/dist/public/assets/{MonetizationModeSummary-CnHqXyco.js → MonetizationModeSummary-DYE7XUq1.js} +1 -1
  10. package/dist/public/assets/{SectionHeader-Cn3FnOqh.js → SectionHeader-BKc3BWXP.js} +1 -1
  11. package/dist/public/assets/{baseForm-kBTxn8h8.js → baseForm-I9suIiQn.js} +1 -1
  12. package/dist/public/assets/baseForm-I9suIiQn.js.br +0 -0
  13. package/dist/public/assets/{col-VN3Ivd-x.js → col-w9Q-2mgM.js} +1 -1
  14. package/dist/public/assets/{compass-BabZVjAl.js → compass-D6waJ52O.js} +1 -1
  15. package/dist/public/assets/{index-DHdJsD10.js → index-8sDAOAcS.js} +1 -1
  16. package/dist/public/assets/index-8sDAOAcS.js.br +0 -0
  17. package/dist/public/assets/{index-DK4IvdRl.js → index-B6hY5GdS.js} +1 -1
  18. package/dist/public/assets/{index-Cl0_vMWE.js → index-BIrFkB6r.js} +1 -1
  19. package/dist/public/assets/index-BIrFkB6r.js.br +0 -0
  20. package/dist/public/assets/{index-BjQlJrX7.js → index-BLWgpW64.js} +1 -1
  21. package/dist/public/assets/{index-odEI7YQF.js → index-BY3eQmfP.js} +1 -1
  22. package/dist/public/assets/index-BY3eQmfP.js.br +0 -0
  23. package/dist/public/assets/{index-Bjn0ctEd.js → index-BegU9LBT.js} +2 -2
  24. package/dist/public/assets/index-BegU9LBT.js.br +0 -0
  25. package/dist/public/assets/{index-1WjGwqIV.js → index-BqwflQml.js} +1 -1
  26. package/dist/public/assets/{index-DXDZCuG4.js → index-BrOFdVbv.js} +1 -1
  27. package/dist/public/assets/{index-BxsB5E3u.js → index-BvPolBSn.js} +1 -1
  28. package/dist/public/assets/{index-BnOeYQAd.js → index-BwrZjkCc.js} +1 -1
  29. package/dist/public/assets/{index-CUuX90R9.js → index-CLKKui8G.js} +1 -1
  30. package/dist/public/assets/{index-Dohibgdp.js → index-Cb4Ja0tZ.js} +1 -1
  31. package/dist/public/assets/{index-C83QHLmD.js → index-CcUgN29Y.js} +1 -1
  32. package/dist/public/assets/{index-aSl6Wdrp.js → index-CgXOkYrX.js} +1 -1
  33. package/dist/public/assets/index-CgXOkYrX.js.br +0 -0
  34. package/dist/public/assets/{index-DulANwbq.js → index-CsiIrLKY.js} +1 -1
  35. package/dist/public/assets/{index-Ba-JWe4X.js → index-Csmg5oyu.js} +1 -1
  36. package/dist/public/assets/{index-DnnfZ7H_.js → index-DDecPuod.js} +1 -1
  37. package/dist/public/assets/{index-Clq0hTDI.js → index-DDy4PkWT.js} +1 -1
  38. package/dist/public/assets/{index-DIcz5ciL.js → index-DEQ2hVPA.js} +1 -1
  39. package/dist/public/assets/index-DEQ2hVPA.js.br +0 -0
  40. package/dist/public/assets/{index-CpM8t743.js → index-DGkgqtgJ.js} +1 -1
  41. package/dist/public/assets/{index-QNLvejKK.js → index-FVHabbDB.js} +1 -1
  42. package/dist/public/assets/{index-CzXMNZL3.js → index-M8jf-YAZ.js} +1 -1
  43. package/dist/public/assets/{index-BxokHznc.js → index-Q0GC8Irj.js} +1 -1
  44. package/dist/public/assets/index-Q0GC8Irj.js.br +0 -0
  45. package/dist/public/assets/{index--6iHQzho.js → index-YVB9ZW00.js} +1 -1
  46. package/dist/public/assets/{index-O_L1tU2b.js → index-mjEeEQcC.js} +1 -1
  47. package/dist/public/assets/index-mjEeEQcC.js.br +0 -0
  48. package/dist/public/assets/{index-BFFsJ47B.js → index-rLkONFpx.js} +1 -1
  49. package/dist/public/assets/{layers-B4zhx14P.js → layers-Dbwq9AyL.js} +1 -1
  50. package/dist/public/assets/{list-checks-Br6imjXC.js → list-checks-og1usOZf.js} +1 -1
  51. package/dist/public/assets/{sparkles-BjIkcbAi.js → sparkles-p-dZbjGb.js} +1 -1
  52. package/dist/public/assets/{triangle-alert-CgKAc3w5.js → triangle-alert-BZVAEUiL.js} +1 -1
  53. package/dist/public/assets/{zap-DFHw5liD.js → zap-BAhZUPPa.js} +1 -1
  54. package/dist/public/index.html +1 -1
  55. package/dist/scripts/acceptance-fixture.test.js +33 -0
  56. package/dist/scripts/dev-capture-smoke.js +76 -0
  57. package/dist/scripts/dev-client-preview-control-smoke.js +606 -0
  58. package/dist/scripts/dev-default-smoke.js +67 -0
  59. package/dist/scripts/dev-game-ready-smoke.js +155 -0
  60. package/dist/scripts/dev-workflow-smoke.js +260 -0
  61. package/dist/scripts/prepare-client-preview-acceptance.js +65 -0
  62. package/dist/scripts/preview-page-server-smoke.js +63 -0
  63. package/dist/scripts/run-ts-test.js +41 -0
  64. package/dist/scripts/verify-agent-contract.js +410 -0
  65. package/dist/scripts/vibe-ppe-test-preload.cjs +23 -0
  66. package/dist/scripts/vibe-upload-demo.js +72 -0
  67. package/dist/scripts/vibe-upload-smoke.js +412 -0
  68. package/dist/scripts/wasm-smoke.js +53 -0
  69. package/dist/scripts/wasm-worker.js +63 -0
  70. package/dist/scripts/worker.js +28 -22
  71. package/package.json +36 -4
  72. package/CHANGELOG.md +0 -277
  73. package/dist/public/assets/Detail-rVxbEDgh.js.br +0 -0
  74. package/dist/public/assets/baseForm-kBTxn8h8.js.br +0 -0
  75. package/dist/public/assets/index-Bjn0ctEd.js.br +0 -0
  76. package/dist/public/assets/index-BxokHznc.js.br +0 -0
  77. package/dist/public/assets/index-Cl0_vMWE.js.br +0 -0
  78. package/dist/public/assets/index-DHdJsD10.js.br +0 -0
  79. package/dist/public/assets/index-DIcz5ciL.js.br +0 -0
  80. package/dist/public/assets/index-O_L1tU2b.js.br +0 -0
  81. package/dist/public/assets/index-aSl6Wdrp.js.br +0 -0
  82. package/dist/public/assets/index-odEI7YQF.js.br +0 -0
package/README.md CHANGED
@@ -1,8 +1,18 @@
1
1
  ### @ttmg/cli
2
+
2
3
  `ttmg` is a command-line tool designed for managing and developing mini-game projects. It supports initialization, development, debugging, and packaging for both H5 and native mini-games.
3
4
  `ttmg` 是一款专为小游戏项目管理与开发设计的命令行工具,支持 H5 小游戏和原生小游戏的初始化、开发调试及打包构建。
5
+
4
6
  #### Installation 安装
5
7
 
8
+ The Wasm split binding loads only when preparing or splitting Unity Wasm. A
9
+ missing platform binding does not block CLI startup or unrelated commands.
10
+ The split dependency `@anrans001/ttmg-wasmtool@0.3.3` provides Linux x64/arm64
11
+ bindings for GNU and musl. CLI execution on Linux still needs validation.
12
+ Unity Wasm 原生分包依赖仅在 prepare / split 时加载,缺少对应平台二进制不会阻断
13
+ CLI 启动及其他命令;`@anrans001/ttmg-wasmtool@0.3.3` 已提供 Linux x64/arm64
14
+ 的 GNU、musl 原生包,CLI 在实际 Linux 环境的运行仍待验证。
15
+
6
16
  You can install `ttmg` globally or as a project dependency via npm:
7
17
  你可以通过 npm 全局或本地安装 `ttmg`:
8
18
 
@@ -19,13 +29,77 @@ npm install @ttmg/cli --save-dev
19
29
 
20
30
  #### Login 登录
21
31
 
22
- Before running any `ttmg` commands, please log in with your TikTok account. Once logged in, the tool will automatically use your account for project initialization, development, debugging, and packaging.
23
- 在首次使用 `ttmg` 命令前,请先登录你的 TikTok 账号。登录后,工具会自动使用该账号进行项目初始化、开发调试和打包构建。
32
+ The experimental `upload --vibe` local prototype does not require platform login.
33
+ Use `ttmg upload --vibe --mock` for the integration trial. No environment setup:
34
+ task creation/polling use the built-in PPE lane; authorization and uploads are
35
+ simulated. See [Vibe binding/upload](vibe-upload.md) for schema-v2 results.
36
+ 实验性 `upload --vibe --mock` 不要求平台登录或环境配置。CLI 内置 PPE 创建/查询任务,
37
+ 模拟授权和上传;本次结束于模拟上传完成,不含预览和发布。详见 [Vibe 绑定上传](vibe-upload.md)。
38
+
39
+ `--mock` 现在会真实创建 PPE 任务,不再表示全程离线;真实请求失败仍报错。
40
+ 上线时由 CLI 发布版本去掉 PPE 路由,Skill 无需承担环境切换。
41
+ `--mock` now creates real PPE tasks, not a fully offline run. Real request failures
42
+ still fail. Production routing is a future CLI release change, not Skill configuration.
43
+
44
+ 维护者可用 `--app-info ./app-info.json --dry-run` 校验完整应用信息和平台头像要求;文件字段见 [Vibe 绑定上传](vibe-upload.md)。不传此选项时,现有 Mock 输入保持不变。真实上传仍未开放。
45
+ Maintainers can add `--app-info ./app-info.json --dry-run` to validate complete metadata and platform icon requirements; see [Vibe binding/upload](vibe-upload.md). Existing Mock inputs remain unchanged without this option. Real upload remains disabled.
46
+
47
+ For the existing authenticated platform workflow, log in first; this does not apply to the local Vibe prototype above.
48
+ 原有需要平台鉴权的流程仍先登录;上述 Vibe 本地原型不需要此步骤。
24
49
 
25
50
  ```
26
51
  ttmg login
27
52
  ```
28
53
 
54
+ For Agent usage, implicit mode accepts credentials without terminal prompts,
55
+ keeps the existing `~/.ttmgrc` write behavior, and returns one JSON result on
56
+ stdout. The result never contains the password or session Cookie.
57
+ Agent 可使用 implicit 模式传入账号密码,无需终端交互;登录成功后继续按原逻辑写入 `~/.ttmgrc`,stdout 返回一个 JSON 结果,结果中不包含密码或会话 Cookie。
58
+
59
+ ```
60
+ ttmg login --implicit --email <email> --password <password>
61
+ ```
62
+
63
+ `TTMG_LOGIN_EMAIL` and `TTMG_LOGIN_PASSWORD` can replace the two credential
64
+ options when credentials are provided by the execution environment.
65
+ 执行环境也可以通过 `TTMG_LOGIN_EMAIL` 和 `TTMG_LOGIN_PASSWORD` 提供凭据。
66
+
67
+ Inspect the reusable local session without exposing its Cookie. The status is
68
+ local-only; it does not make a network request. `--require-auth` is useful for
69
+ Agent preflight because it exits non-zero when login is missing.
70
+ 可在不暴露 Cookie 的情况下读取本地会话是否可复用。该状态只检查本地配置,不发起网络请求;Agent 预检可增加 `--require-auth`,未登录时以非零状态退出。
71
+
72
+ ```
73
+ ttmg auth status --format json
74
+ ttmg auth status --format json --require-auth
75
+ ```
76
+
77
+ Agents can discover the exact command and runtime capability surface before
78
+ acting. Unsupported device and Runtime features are explicitly reported as
79
+ `false`; commands that create a platform version are marked with
80
+ `platformWrite: true`.
81
+ Agent 可在执行前读取当前 CLI 的准确能力;尚未支持的设备和 Runtime 能力明确返回 `false`,会创建平台版本的命令明确标记 `platformWrite: true`。
82
+
83
+ ```
84
+ ttmg capabilities --format json
85
+ ```
86
+
87
+ #### Test Account 测试账号
88
+
89
+ Generate the TikTok authorization link and QR code for a Mini Game test account.
90
+ This command does not write to Developer Platform automatically; verify the
91
+ account in the project's Test User list after scanning.
92
+ 为小游戏生成 TikTok 测试账号授权链接和二维码。该命令不会自动写入 Developer Platform;扫码后仍需在项目 Test User 列表确认账号状态。
93
+
94
+ ```
95
+ ttmg test-account add --client-key <client-key>
96
+ ttmg test-account add --client-key <client-key> --format json
97
+ ```
98
+
99
+ The QR code is written to `.ttmg/test-account-<client-key>.png` by default. Use
100
+ `--qr-output <path>` to choose another path.
101
+ 二维码默认写入 `.ttmg/test-account-<client-key>.png`,可通过 `--qr-output <path>` 指定其他路径。
102
+
29
103
  #### Debugging 调试
30
104
 
31
105
  - By default, debug native mini-games:
@@ -35,6 +109,574 @@ ttmg login
35
109
  ttmg dev
36
110
  ```
37
111
 
112
+ For Agent usage, pass the Client Key explicitly, suppress the browser, and
113
+ choose either one JSON session manifest or an NDJSON lifecycle event stream.
114
+ The two stdout modes are mutually exclusive. The existing interactive `ttmg
115
+ dev` flow is unchanged.
116
+ Agent 调用时需显式传入 Client Key、禁止自动打开浏览器,并在单份 JSON 会话描述和 NDJSON 生命周期事件流中二选一;两种 stdout 模式不能同时使用。原有交互式 `ttmg dev` 流程保持不变。
117
+
118
+ ```
119
+ ttmg dev --client-key <client-key> --format json --no-open
120
+ ttmg dev --client-key <client-key> --events ndjson --no-open
121
+ ttmg dev --client-key <client-key> --events ndjson --no-open --timeout 120
122
+ ```
123
+
124
+ ### Manual iteration workflow / 按轮更新与验证
125
+
126
+ Use a converted Native game project and an existing Client Key. The following
127
+ commands run on the same executor, which must be reachable from the phone and
128
+ able to reach the phone. The first command returns while the preview runs in
129
+ the background; it reuses a compatible owner in the current project. Scan the
130
+ returned QR once, then submit and observe each update.
131
+
132
+ 在已转换的 Native 游戏工程目录调用,使用已有 Client Key。命令在同一执行机
133
+ 运行,执行机与手机须双向可达。启动命令返回后,预览进程继续在后台运行;同一
134
+ 工程有配置匹配的预览时会复用。首次扫描返回的二维码,然后逐轮提交更新与读取结果。
135
+
136
+ ```bash
137
+ ttmg dev --mode client-preview --update-mode manual --background --client-key <CLIENT_KEY> --record-logs --format json
138
+ ttmg dev sync --request-id round-1 --format json
139
+ ttmg dev observe --iteration round-1 --timeout 30 --format json
140
+ ttmg dev session stop <SESSION_ID> --format json
141
+ ```
142
+
143
+ - `sync` freezes project inputs before compilation and returns an iteration ID
144
+ and build ID. Reusing a request ID returns that same iteration, even if files
145
+ changed; use a new ID for new code. Keys are retained for the owner lifetime,
146
+ up to 1000 updates. Wait for an update to settle before editing the next one.
147
+ - `observe` waits up to `--timeout` seconds (0–300, default 30) for deployment.
148
+ It then collects at most five log pages (200 records by default, at most 1000
149
+ records / 1 MiB) and one JPEG screenshot, with a separate 65-second IPC limit.
150
+ Each observation starts at the deployment window; repeated calls overlap.
151
+ - Results are `pending` (query again; timeout does not resubmit), `needs_action`
152
+ (connect the phone using `launch`), `observed`, `partial` (inspect gaps/issues),
153
+ `superseded`, or `failed`. `partial` exits 2; failures exit 1; other states exit 0.
154
+ A truncated log result includes `nextLogQuery` for the existing `dev logs` command.
155
+ - A deployment has a 120-second deadline; shutdown or a new Runtime cancels its
156
+ network requests. Connecting a new Runtime can redeploy the same captured build
157
+ without a new request ID or compilation. Query that iteration again afterward.
158
+ - Log/screenshot results identify the deployment and Runtime and reject changes
159
+ during collection. The client has no active-build acknowledgment:
160
+ `runtimeBuildVerified: false`, `attribution: deployment_window`, and
161
+ `gameplayValidation: not_evaluated` remain explicit. Logs can include records
162
+ from the previous game during delivery; the Agent must inspect gameplay.
163
+ - Manual owners pin their Client Key without changing global configuration and
164
+ use a session-specific build directory. Concurrent update/observation requests
165
+ return busy. Project symlinks and special files are rejected; `.git`, `.ttmg`,
166
+ `node_modules` and `__TTMG_TEMP__` are excluded from source snapshots.
167
+ - Background mode defaults to a 1800-second lifetime (`--timeout`, max 86400).
168
+ It requires the default evidence directory; custom directories and external
169
+ supervisors can use foreground `--update-mode manual`. Startup waits at most
170
+ 60 seconds. Reuse does not renew an owner's lifetime. A crashed start leaves
171
+ `.ttmg/preview-start.lock`; verify the starter has exited before removing it.
172
+
173
+ - `sync` 固定工程输入后构建,返回本轮与构建标识。相同请求标识始终返回同一轮,
174
+ 即使文件已经改变;新代码使用新标识。标识在进程存活期间保留,最多 1000 轮。
175
+ 等本轮完成后再编辑下一轮代码。
176
+ - `observe` 等待部署 0–300 秒,默认 30 秒;之后最多读取 5 页日志和一张 JPEG
177
+ 截图,采集另有 65 秒 IPC 上限。默认 200 条日志,上限 1000 条 / 1 MiB。
178
+ 每次从该次部署的观察窗口读取,重复调用会有重叠日志。
179
+ - `pending` 继续查询;超时不重新提交。`needs_action` 使用 `launch` 连接手机。
180
+ `observed` 可读取结果;`partial` 检查缺失与错误;`superseded` 选择新轮次;
181
+ `failed` 按原因修复。`partial` 退出码为 2,失败为 1,其余为 0。
182
+ 日志截断时,可将 `nextLogQuery` 交给已有 `dev logs` 命令续读。
183
+ - 部署设有 120 秒超时;停止会话或切换 Runtime 会取消部署中的网络请求。
184
+ 连接新的 Runtime 可继续部署同一份构建,无须换请求标识或重新编译;之后查询原轮次。
185
+ - 结果关联部署与 Runtime,采集中发生变化会拒绝返回。客户端尚无已激活构建确认,
186
+ 因此明确返回 `runtimeBuildVerified: false`、`attribution: deployment_window`
187
+ 和 `gameplayValidation: not_evaluated`。日志可能含部署期间的旧游戏记录,仍需
188
+ Agent 判断画面与玩法。
189
+ - 手动更新模式固定本进程的 Client Key,不修改全局配置;每个会话独立存放构建
190
+ 产物。更新或观察期间的并发请求返回忙碌。输入不支持符号链接和特殊文件;快照
191
+ 排除 `.git`、`.ttmg`、`node_modules` 和 `__TTMG_TEMP__`。
192
+ - 后台默认存活 1800 秒,可通过 `--timeout` 指定,最大 86400 秒;复用不延长
193
+ 原进程寿命。后台使用默认结果目录,启动最多等待 60 秒。自定义目录或已有进程
194
+ 托管器可直接使用前台 `--update-mode manual`。启动器崩溃遗留
195
+ `.ttmg/preview-start.lock` 时,确认启动器已退出后再删除锁。
196
+
197
+ ### Wasm prepare and split / Wasm 准备与分包
198
+
199
+ ```bash
200
+ ttmg wasm prepare --input original.wasm.br --output prepared --format json
201
+ ttmg wasm split --input original.wasm.br --collection collection.json --output split --format json
202
+ ```
203
+
204
+ These experimental commands create artifacts in a new directory; they do not
205
+ rewrite the original Wasm, `game.json` or Unity plugin configuration. Supply
206
+ collection JSON with `schemaVersion: "1"`, `wasmSha256` from prepare's
207
+ `input.wasmSha256`, nonempty `funcIds`, and optional `bootFuncIds`. The hash is
208
+ for the uncompressed original Wasm, never the instrumented file. Collection must
209
+ come from running the corresponding instrumented project.
210
+
211
+ `--dry-run` validates inputs without loading the native library or writing final
212
+ outputs. Native work has a 300-second default deadline (`--timeout`, 1–3600).
213
+ Existing output directories are rejected. Successful results include artifact
214
+ sizes, SHA256 hashes and a `manifest.json` completion marker; they leave
215
+ `gameValidation: not_evaluated`. Binary validation uses the current Node.js
216
+ WebAssembly engine. Version 0.3.3 provides Linux bindings; Linux execution remains unverified;
217
+ an unavailable binding returns `WASM_BINDING_UNAVAILABLE` for this operation.
218
+
219
+ 命令把产物写入新目录,不改写原始 Wasm、`game.json` 或 Unity 插件配置。
220
+ 采集 JSON 包含 `schemaVersion: "1"`、prepare 返回的 `input.wasmSha256`、
221
+ 非空 `funcIds` 和可选 `bootFuncIds`。哈希对应解压后的原始 Wasm,不能使用
222
+ 插桩文件的哈希;函数数据来自对应插桩工程的玩法采集。
223
+
224
+ `--dry-run` 校验输入,不加载原生库或写入最终产物。原生操作默认超时 300 秒,
225
+ `--timeout` 范围 1–3600 秒。已有输出目录会被拒绝。成功结果含文件大小、SHA256
226
+ 与完成标记 `manifest.json`,`gameValidation` 仍为 `not_evaluated`。二进制结构
227
+ 使用当前 Node.js 的 WebAssembly 引擎校验。0.3.3 已提供 Linux 原生包,实际 Linux 运行仍待验证;
228
+ 原生库不可用时,此操作返回 `WASM_BINDING_UNAVAILABLE`。
229
+
230
+ Native `ttmg build` now performs the same local debug build in text and JSON
231
+ modes. This replaces the former text-mode placeholder; the JSON schema remains
232
+ version 1. It does not create a platform version. Existing watch-mode `dev` and
233
+ atomic log/screenshot commands retain their behavior.
234
+
235
+ Native `ttmg build` 的 text 与 JSON 模式现执行相同本地调试构建,取代原来的
236
+ text 占位提示;JSON schema 保持版本 1,不创建平台版本。原有自动监听 `dev`
237
+ 和单独日志、截图命令保持可用。
238
+
239
+ For an Agent-owned iOS client-preview session, opt in explicitly. TikTok must
240
+ still be opened by a human scanning the generated QR code. The resident `ttmg
241
+ dev` process then owns the Runtime Debug WebSocket and performs client setup,
242
+ package upload, and metadata delivery without opening the browser IDE.
243
+ Agent 真机预览需显式开启;仍由用户使用 TikTok 扫描生成的二维码。扫码后,常驻
244
+ `ttmg dev` 进程会独占 Runtime Debug WebSocket,并在不打开浏览器 IDE 的情况下完成
245
+ 客户端初始化、包上传和 meta 下发。
246
+
247
+ ```
248
+ ttmg dev --mode client-preview --client-key <client-key> --events ndjson --no-open --timeout 600
249
+ ```
250
+
251
+ The lifecycle includes `READY_FOR_SCAN`, `DEVICE_DISCOVERED`,
252
+ `RUNTIME_AUTHENTICATED`, `UPLOAD_START`, `UPLOAD_READY`, and `PREVIEW_READY`.
253
+ The initial integration scope is iOS `native_runtime` and `structured_trace`,
254
+ while the V1 record schema preserves open `source`, `kind`, and extension
255
+ fields for Android and future runtimes. Runtime credentials remain in the
256
+ owner process memory and are never written to the session manifest or event
257
+ files.
258
+ 生命周期依次包含 `READY_FOR_SCAN`、`DEVICE_DISCOVERED`、
259
+ `RUNTIME_AUTHENTICATED`、`UPLOAD_START`、`UPLOAD_READY` 和 `PREVIEW_READY`。
260
+
261
+ 真机预览模式会串行编译,并将每次成功编译的文件与包元数据保存为配套的临时快照。
262
+ 上传期间再次编译时,当前部署完成后会继续部署最新的一版;中间待部署版本可被合并。
263
+ `PREVIEW_READY` 只在一版实际上传和 meta 请求完成后输出。旧快照在替换或 session
264
+ 关闭时清理;普通浏览器 `ttmg dev` 的编译与上传流程不变。
265
+ 首期接入范围仍是 iOS `native_runtime` 与 `structured_trace`,但 V1 记录模型会
266
+ 保留开放的 `source`、`kind` 和扩展字段,可兼容 Android 与后续 Runtime。
267
+ Runtime 凭据仅保存在 owner 进程内存中,不会写入 manifest 或事件文件。
268
+
269
+ The command writes `manifest.json`, `events.ndjson`, `actions.ndjson`,
270
+ `screenshots/`, `summary.json`, and `launch.png` under
271
+ `.ttmg/sessions/<session-id>/` by default. `launch.rawUrl` and
272
+ `launch.qrPayload` are identical. This beta exposes the local DevTool session
273
+ and client connection events. Compile events also include the normalized
274
+ project diagnostics produced by the existing checker. The existing runtime
275
+ `reportScene({ sceneId: 9999 })` signal is forwarded to the CLI as a
276
+ `GAME_READY` lifecycle event; an ordinary browser session is only marked `passed`
277
+ after that signal is observed. A client-preview session uses `PREVIEW_READY`
278
+ instead: this confirms package and metadata delivery, not gameplay acceptance.
279
+ Device launch and remote actions remain unavailable.
280
+ Runtime logs and screenshots expose an experimental iOS/V1 protocol surface,
281
+ but remain reported as unverified (`false`) top-level capabilities until
282
+ real-device acceptance. The
283
+ manifest keeps `gameReady=false` until this path completes real-device
284
+ verification, while `gameReadyProtocol=true` only declares local protocol
285
+ support.
286
+ 命令默认在 `.ttmg/sessions/<session-id>/` 写入 `manifest.json`、`events.ndjson`、`actions.ndjson`、`screenshots/`、`summary.json` 和 `launch.png`,其中 `launch.rawUrl` 与 `launch.qrPayload` 完全一致。本 beta 会把现有运行时 `reportScene({ sceneId: 9999 })` 信号旁路转发为 CLI 的 `GAME_READY` 生命周期事件;普通浏览器会话观察到该信号后才把 `summary.json` 写为 `passed`。client-preview 会话使用 `PREVIEW_READY` 判断,只表示包和元数据下发完成,不代表玩法验收通过。设备直开和远程操作仍不可用;运行时日志与截图已提供实验性的 iOS/V1 协议入口,但真实设备验收完成前,顶层 capabilities 仍保持 `false`,不伪造已完成状态。真实设备联调完成前,manifest 保持 `gameReady=false`,仅用 `gameReadyProtocol=true` 表示本地协议已经接通。
287
+ 编译事件会同时包含现有检查器产生的标准化项目诊断,Agent 不需要再从拼接后的错误文本反推问题位置。
288
+
289
+ Structured sessions can be discovered, inspected, and safely stopped from a
290
+ new CLI process. Stop verifies that the recorded PID is a `ttmg dev` process
291
+ before sending SIGTERM.
292
+ 结构化会话可以由新的 CLI 进程列出、查询和安全停止;停止前会确认 manifest 中记录的 PID 确实属于 `ttmg dev`,不会直接终止无法验证的进程。
293
+
294
+ ```
295
+ ttmg dev session list --format json
296
+ ttmg dev session inspect <session-id> --format json
297
+ ttmg dev session events <session-id> --after <seq> --limit <count> --format json
298
+ ttmg dev session stop <session-id> --format json
299
+ ```
300
+
301
+ For terminal development, start client preview from the game project. Scan the
302
+ QR on the automatically opened local scan page or in the terminal with TikTok;
303
+ compilation, connection status, and live Runtime logs
304
+ appear in the same terminal. Code changes deploy to the connected device. This
305
+ mode does not open the browser IDE; ordinary `ttmg dev` remains unchanged.
306
+ 在游戏工程目录启动真机预览,用 TikTok 扫描自动打开的本地网页或终端二维码,
307
+ 在同一终端查看编译、
308
+ 连接状态和实时 Runtime 日志;代码修改后更新到已连接设备。这个模式不打开浏览器
309
+ IDE,普通 `ttmg dev` 的行为不变。
310
+
311
+ ```bash
312
+ ttmg dev --mode client-preview --client-key <CLIENT_KEY>
313
+ # Keep both QR options without opening a browser / 保留两种扫码方式,但不自动打开浏览器
314
+ ttmg dev --mode client-preview --client-key <CLIENT_KEY> --no-open
315
+ # Another terminal in the same project / 在同一工程的另一个终端
316
+ ttmg dev screenshot
317
+ ttmg dev logs
318
+ ttmg dev logs --follow --timeout 30
319
+ ```
320
+
321
+ The scan page shows the project and QR, compile/connection/upload/update stages,
322
+ upload percentage and the last completed delivery. Manual sessions also show the
323
+ current `request-id`, matching the `iterationId` returned by `dev sync`; before the
324
+ first sync they show “No update submitted”. Agents generate a new ID per update
325
+ and reuse it when retrying the same update. It shows whether updates are
326
+ manual (`dev sync`) or automatic. Developer options cover request-domain checks,
327
+ mock ads/purchases, vConsole and the developer info panel. Save explicitly;
328
+ preferences last for this preview session. Before connecting, saving prepares the
329
+ next launch. When connected, “Save and reload game” reinitializes the game, sends
330
+ the options, uploads the current compiled build and sends game metadata. Changes
331
+ saved during loading queue another setup with the latest options. This reuses the
332
+ build and request ID without recompiling. The `reload` status is `pending`,
333
+ `reloading`, `delivered` or `failed`; `delivered` confirms redelivery, not game activation.
334
+ Agents can read the same values and delivery state from `developerOptions` at
335
+ `<launch.scanPageUrl>/status` (or `debugSettings` in IPC `session.status`).
336
+ The page is computer-local and served by the same CLI process;
337
+ refreshing it never establishes another Runtime connection. Both QR forms carry
338
+ the same device launch URL. The page link is for the computer, not the phone.
339
+ `--no-open` and `TTMG_DEV_NO_OPEN=1` suppress automatic opening. JSON/NDJSON modes
340
+ never open a browser or draw a terminal QR; they expose `launch.scanPageUrl` in
341
+ the manifest and `scanPageUrl` in `READY_FOR_SCAN`, retaining the PNG path and
342
+ raw launch URL. If browser opening fails, use the printed page link or PNG.
343
+ When the CLI stops, the page detects the unavailable service and hides the QR.
344
+ 扫码页展示工程、二维码、编译/连接/上传/配置下发状态、上传百分比和最近下发完成时间,
345
+ 并区分手动 `dev sync` 与自动更新。
346
+ 手动模式显示当前 `request-id`,与 `dev sync` 返回的 `iterationId` 对应;首次 sync
347
+ 前显示“尚未提交更新”。每轮 ID 由 Agent 生成,同一轮重试复用原 ID。
348
+ 开发者选项支持请求域名校验、广告和内购模拟、vConsole、开发者信息面板;点击保存后
349
+ 仅保留在本次会话。连接前保存供下次启动使用;连接后点击“保存并重新加载”,
350
+ 会重新初始化游戏、发送配置、上传当前编译包并下发游戏信息。加载中再次保存会排队,
351
+ 随后按最新配置重新执行;复用当前构建和 request-id,不重新编译。
352
+ `reload` 分别为 `pending`、`reloading`、`delivered`、`failed`;
353
+ 下发完成后仍需在手机确认游戏结果。Agent 可读取
354
+ `<launch.scanPageUrl>/status` 的 `developerOptions`,或 IPC `session.status`
355
+ 的 `debugSettings`,取得相同配置及发送状态。
356
+ 页面由同一 CLI 进程提供,仅允许本机访问;刷新网页不会另建 Runtime 连接。
357
+ 两种二维码使用同一个真机启动链接,
358
+ 网页地址供电脑打开,不是让手机访问 localhost。`--no-open` 和
359
+ `TTMG_DEV_NO_OPEN=1` 禁止自动打开。JSON/NDJSON 模式不打开浏览器、不绘制终端
360
+ 二维码,通过 manifest 的 `launch.scanPageUrl` 和 `READY_FOR_SCAN` 的
361
+ `scanPageUrl` 返回网页地址,原 PNG 路径与启动链接保留。浏览器打开失败时可手动
362
+ 打开输出链接或 PNG。CLI 停止后,网页检测到服务不可用并隐藏二维码。
363
+
364
+ These shortcuts find the unique running client-preview session in this project,
365
+ including from a subdirectory. If multiple sessions are running, the command
366
+ lists them and requires `--session <session-id>`; it never silently picks one.
367
+ Use `--sessions-dir <path>` for a custom session collection or the exact directory
368
+ specified with `--evidence-dir`. Screenshot output prints the saved file path;
369
+ use `--output <path>` for a custom destination. Log follow ends after 30 seconds
370
+ by default without stopping preview; the owner terminal streams logs until you
371
+ stop preview with Ctrl+C. Both logs and screenshots require a compatible client.
372
+ 快捷命令自动找到当前工程(含子目录)唯一的运行中真机预览会话;多个会话时列出
373
+ 候选,需用 `--session <session-id>` 明确选择,不会自动连接任意设备。
374
+ 自定义证据目录使用 `--sessions-dir <path>`,可以指定会话集合目录或启动时的
375
+ `--evidence-dir`。截图完成后输出本地保存路径,支持 `--output <path>`。
376
+ `logs --follow` 默认读取 30 秒后退出,不停止预览;主终端持续输出日志,Ctrl+C
377
+ 停止预览。日志和截图均需要客户端支持对应协议。
378
+
379
+ For automation, use `dev logs --format json`, `dev logs --follow --format ndjson`,
380
+ or `dev screenshot --format json`. Successful results reuse the existing
381
+ `dev.session.logs` / `dev.session.screenshot` schema and command names. Session
382
+ selection failures return `DEV_SESSION_NOT_RUNNING` or `DEV_SESSION_AMBIGUOUS`
383
+ with a non-zero exit code. The explicit `dev session ...` commands below remain
384
+ available without changing their default output format.
385
+ 自动化可用 `dev logs --format json`、`dev logs --follow --format ndjson` 或
386
+ `dev screenshot --format json`,成功结果沿用原有 `dev.session.logs` /
387
+ `dev.session.screenshot` 的 schema 和 command 字段。未找到运行中会话或存在多个
388
+ 会话时返回 `DEV_SESSION_NOT_RUNNING` / `DEV_SESSION_AMBIGUOUS`,并以非零状态退出。
389
+ 下方显式 `dev session ...` 命令及默认输出格式保持兼容。
390
+
391
+ While a client-preview owner is running, another CLI process can read a bounded
392
+ snapshot, follow logs for a bounded interval, or request a screenshot. Runtime
393
+ cursor values are decimal strings and must not be parsed as JavaScript numbers.
394
+ By default logs remain in bounded memory and are not copied into `events.ndjson`
395
+ or a log file. Screenshot stdout contains metadata only; the binary is written to disk
396
+ without overwriting an existing explicit destination.
397
+ 真机预览 owner 运行期间,另一个 CLI 进程可读取有界日志快照、在有界时间内 follow,
398
+ 或请求截图。Runtime cursor 是十进制字符串,不应转换为 JavaScript Number。默认日志只在
399
+ 有界内存中保留,不写入 `events.ndjson` 或额外日志文件;截图 stdout 只返回元数据,
400
+ 图片写入磁盘,且不会覆盖显式指定的已有文件。
401
+
402
+ `--follow` 先订阅再请求一次受 `--limit` 限制的历史快照,缓存请求期间到达的实时
403
+ 日志并排序去重后继续输出;不会自动分页全部历史(`hasMore` 表示仍有历史可补拉)。
404
+ 过渡缓存限制为 10000 条/10 MiB,超限返回明确错误,可从最后收到的 cursor 重试;
405
+ 等待初始快照也计入 follow 超时。中文和 emoji 的跨 IPC 分块传输保持完整。
406
+
407
+ Runtime Session 切换(例如重新扫码)会使正在运行的 `--follow` 以
408
+ `RUNTIME_SESSION_MISMATCH` 结束,包括仍在等待初始快照的监听。新会话就绪后,
409
+ 用同一个 CLI session-id 重新执行命令,但不要复用旧 Runtime 的 `--after`/`--until`
410
+ 游标;同一 Runtime Session 的普通断线重连不会终止 follow。
411
+
412
+ ```
413
+ ttmg dev session logs <session-id> --after <cursor> --until <cursor> --limit 200 --format json
414
+ ttmg dev session logs <session-id> --after <cursor> --follow --timeout 30 --format ndjson
415
+ ttmg dev session screenshot <session-id> --image-format jpeg --quality 0.8 --output <path> --format json
416
+ ```
417
+
418
+ If an older client does not advertise Runtime Debug V1, the original preview
419
+ flow remains compatible, while the new session commands return
420
+ `RUNTIME_DEBUG_UNSUPPORTED`. If the owner process has exited, they return
421
+ `DEV_SESSION_NOT_RUNNING` for live reads; explicit archive reads are described below.
422
+ 旧客户端未声明 Runtime Debug V1 时,原预览链路保持兼容,新 session 命令返回
423
+ `RUNTIME_DEBUG_UNSUPPORTED`。owner 退出后实时查询返回 `DEV_SESSION_NOT_RUNNING`;
424
+ 本地留存日志必须显式选择 archive,不会冒充实时结果。
425
+
426
+ ### Agent log retrieval / AI 日志读取
427
+
428
+ #### Capture screen and session logs / 一次获取画面和会话日志
429
+
430
+ ```bash
431
+ ttmg dev capture --format json
432
+ ```
433
+
434
+ English: In a project with a connected client-preview session, this command
435
+ captures the current game screen and automatically exports retained logs from
436
+ the current Runtime session start to a fixed query snapshot.
437
+
438
+ No iteration ID is required. Use `--session` when multiple preview sessions are running.
439
+
440
+ The single JSON result contains `screenshot.path`, `logs.path`, `logs.records`,
441
+ `logs.severityCounts`, `logs.complete`, and a manifest path.
442
+
443
+ Logs are written as NDJSON under the session's `captures/` directory. The command leaves the
444
+ game source unchanged. Exit codes are 0 for success, 2 for partial results,
445
+ and 1 for failure.
446
+
447
+ Collection is capped at 64 MiB and defaults to a 120-second budget
448
+ (`--timeout`, 1–300; an in-flight request may add up to 10 seconds).
449
+
450
+ Expired device history and interrupted exports are explicit partial results;
451
+ `nextQuery` supplies log-resume parameters when collection stops early.
452
+
453
+ The command does not merge saved archives or recover already discarded logs.
454
+ Record content retains the Runtime's own truncation and redaction.
455
+
456
+ Screenshots and logs share a Runtime identity but are not an atomic snapshot:
457
+ the screenshot shows the current view, while logs cover the whole session,
458
+ including earlier views.
459
+
460
+ Runtime replacement rejects the capture. A screenshot
461
+ failure can retain a complete log file; inspect both `status` and `logs.complete`.
462
+
463
+ 中文:在已连接 client-preview 的工程中执行该命令,即可截取当前游戏画面,并自动
464
+ 分页导出当前 Runtime 会话开始至查询快照的保留日志,无须提供轮次编号。
465
+ 多个预览同时运行时,用 `--session` 选择会话。
466
+
467
+ 结果只输出一个 JSON,包含截图路径 `screenshot.path`、日志文件 `logs.path`、
468
+ 条数 `logs.records`、分级统计 `logs.severityCounts`、完整性 `logs.complete`
469
+ 及 manifest 路径。日志按 NDJSON 写入会话的 `captures/`,不修改游戏源码。
470
+ 成功退出码为 0,部分成功为 2,失败为 1。
471
+
472
+ 导出上限为 64 MiB,默认收集预算 120 秒。`--timeout` 可设为 1–300 秒,在途请求
473
+ 最多额外等待 10 秒。历史淘汰或中途停止会明确返回部分结果,未读完时可按
474
+ `nextQuery` 继续取日志。本命令不合并本地归档,也不能恢复已丢弃日志。
475
+ 日志内容保留 Runtime 自身的截断和脱敏处理。
476
+
477
+ 截图和日志绑定同一 Runtime,但不是同一时刻的原子快照。截图显示当前页面,日志
478
+ 覆盖当前会话,包括此前页面。会话切换会拒绝本次采集;截图失败仍可保留完整日志,
479
+ 因此须同时检查 `status` 和 `logs.complete`。
480
+
481
+ ```bash
482
+ # Opt in to local recording when starting preview; keep this process running.
483
+ ttmg dev --mode client-preview --client-key <CLIENT_KEY> --record-logs --format json --no-open
484
+
485
+ # Read a finite snapshot from another process in the same project.
486
+ ttmg dev logs --format json --limit 200
487
+
488
+ # Follow the returned nextQuery fields. Pin both CLI and Runtime sessions.
489
+ ttmg dev logs --session <session-id> --runtime-session <runtime-id> --after <cursor> --format json
490
+
491
+ # Capture the same Runtime session as the logs.
492
+ ttmg dev screenshot --session <session-id> --runtime-session <runtime-id> --format json
493
+
494
+ # After the owner exits, read saved evidence through the same command.
495
+ ttmg dev logs --session <session-id> --source archive --runtime-session <runtime-id> --format json
496
+ ```
497
+
498
+ English: Start the long-running preview once, retain the returned `sessionId`, and
499
+ let the user scan the QR. Use finite JSON snapshots for Agent work, not terminal
500
+ scraping or an unbounded follow. Snapshot results include `source`,
501
+ `runtimeSessionId`, `cursor`, and `nextQuery` (option values for the next call;
502
+ not a shell string), including `sessionsDir`, `format`, and the bounded `limit`.
503
+ For pagination, carry `until` while `hasMore=true`; the next query drops it once
504
+ that snapshot is drained so subsequent logs can be read. `--runtime-session`
505
+ rejects stale cursors with `RUNTIME_SESSION_MISMATCH`, including a replacement
506
+ during the request. On mismatch, read a fresh snapshot without old cursors and
507
+ confirm the new session. Follow frames also carry the Runtime identity.
508
+
509
+ 中文:启动一次常驻预览,保留返回的 `sessionId`,由用户扫码连接设备。AI 按需读取
510
+ 有限条数的 JSON 快照,不抓取终端内容,也不依赖持续阻塞的 follow。结果包含来源
511
+ `source`、设备会话 `runtimeSessionId`、游标 `cursor` 和下一次调用的参数 `nextQuery`
512
+ (参数对象,不是可执行 shell 字符串),同时带回证据目录、JSON 格式和条数上限。
513
+ `hasMore=true` 时带上 `until` 翻页;读完当前快照后,下一次参数会移除 `until`,以读取
514
+ 后续新增日志。使用 `--runtime-session` 时,设备在两次查询间或请求中途切换都会返回
515
+ `RUNTIME_SESSION_MISMATCH`;此时不再沿用旧游标,重新读取快照并确认新设备会话。
516
+ follow 输出帧也携带设备会话标识。
517
+
518
+ English: Screenshots return `runtimeSessionId` alongside the absolute image
519
+ `path`. Pass the ID from your log snapshot through `--runtime-session` to either
520
+ `dev screenshot` or `dev session screenshot`.
521
+
522
+ A stale selector fails before capture. Replacement during capture fails before
523
+ saving. Older owners without a matching identity fail pinned requests.
524
+ Omitting the option keeps the existing behavior.
525
+
526
+ 中文:截图结果同时返回 `runtimeSessionId` 和图片绝对路径 `path`。将日志快照中的
527
+ 设备会话 ID 通过 `--runtime-session` 传给任一截图命令,即可校验日志与画面是否属于
528
+ 同一 Runtime 会话。旧会话参数在截图前被拒绝,截图中途切换会话时不保存图片;旧版本
529
+ 常驻进程无法返回匹配标识时,绑定请求也会报错。不传该参数仍可按原方式截图。
530
+
531
+ English: Wait for the initial `PREVIEW_READY` through `dev session events` before
532
+ capturing. After changing code, read events after your last `seq` and wait for the
533
+ new compile and its `PREVIEW_READY`. Then read incremental logs and capture again.
534
+
535
+ That event confirms package and metadata delivery. Verify actual game behavior
536
+ with the screenshot, logs and game checkpoints.
537
+
538
+ 中文:首次截图前通过 `dev session events` 等待 `PREVIEW_READY`。修改代码后从上次
539
+ `seq` 继续读事件,等待新编译及其 `PREVIEW_READY`,再取增量日志和截图。该事件只证明
540
+ 包和 meta 已送达;游戏行为是否正确仍需通过画面、日志和游戏检查点验证。
541
+
542
+ English: `--record-logs` is off by default and only valid for client-preview.
543
+ The manifest exposes `evidence.runtimeLogs`, normally
544
+ `.ttmg/sessions/<session-id>/runtime-logs/`. It records only logs actually received
545
+ by the CLI, after credential redaction; it cannot recover unseen device logs.
546
+ Keep at most two 5 MiB NDJSON segments per CLI session; rotation discards the
547
+ oldest segment. Each retained record is at most 64 KiB; oversized records are
548
+ counted as dropped, not silently truncated. Archive results report
549
+ `retentionLimited`, `droppedRecords`, `partialTail`, and recording state. Treat
550
+ these as evidence gaps, not an all-clear. A recording state of `recording` after
551
+ the owner exits means it did not close cleanly. A write failure emits
552
+ `LOG_ARCHIVE_FAILED` and stops recording without stopping live preview. Files
553
+ are local, not uploaded, and persist until the developer removes the session's
554
+ evidence. Redaction is best effort; do not log secrets or share evidence blindly.
555
+
556
+ 中文:`--record-logs` 默认关闭,仅支持 client-preview。manifest 通过
557
+ `evidence.runtimeLogs` 给出目录,默认是 `.ttmg/sessions/<session-id>/runtime-logs/`。
558
+ 只留存 CLI 实际收到并脱敏后的日志,不代表已收全客户端日志。每个 CLI 会话最多保留
559
+ 两个 5 MiB 的 NDJSON 分段,超限轮转丢弃最旧分段;单条超过 64 KiB 时计入丢弃数量。
560
+ 查询返回 `retentionLimited`、`droppedRecords`、`partialTail` 和留存状态,有缺口不能
561
+ 判断为“没有问题”。CLI 已退出但状态仍为 `recording` 表示未正常关闭。写入失败会发出
562
+ `LOG_ARCHIVE_FAILED` 并停止留存,不停止实时预览。文件不会上传,开发者删除该会话
563
+ 证据前持续保留。脱敏不能替代安全日志规范,不要主动打印凭据或直接分享原始证据。
564
+
565
+ English: Archive reads require an explicit CLI session, do not connect to a device,
566
+ and do not support `--follow`. Multiple retained Runtime sessions return
567
+ `RUNTIME_SESSION_AMBIGUOUS` with `runtimeSessions`; choose one explicitly rather
568
+ than mixing identical cursors. Missing recordings return `DEV_LOG_ARCHIVE_NOT_FOUND`;
569
+ corrupt data returns `DEV_LOG_ARCHIVE_READ_FAILED`. Snapshot reads during active
570
+ rotation may return `DEV_LOG_ARCHIVE_BUSY`; retry that same query. These are local
571
+ protocol guarantees, not real-device log-coverage acceptance.
572
+
573
+ 中文:archive 查询必须指定 CLI 会话,不连接设备,不支持 `--follow`。同一 CLI 会话
574
+ 包含多次设备运行时,返回 `RUNTIME_SESSION_AMBIGUOUS` 和候选 `runtimeSessions`,需
575
+ 明确选择,不混用相同数值的游标。未开启留存返回 `DEV_LOG_ARCHIVE_NOT_FOUND`,文件
576
+ 损坏返回 `DEV_LOG_ARCHIVE_READ_FAILED`;读取遇到持续轮转返回 `DEV_LOG_ARCHIVE_BUSY`,
577
+ 可按原参数重试。这些保证只覆盖本地协议,客户端日志收集完整性仍需真机验收。
578
+
579
+ #### Project Check 项目检查
580
+
581
+ Run the existing project, package-size, subpackage, path, and API checks without
582
+ starting DevTool or writing to Developer Platform. Text remains the default for
583
+ developers; Agents should request one JSON report.
584
+ 无需启动 DevTool 或写入 Developer Platform,即可执行现有的项目配置、包体、分包、路径和 API 检查。开发者默认读取文本结果;Agent 使用单个 JSON 报告。
585
+
586
+ ```
587
+ ttmg check
588
+ ttmg check --dir <game-dir> --format json
589
+ ttmg check --dir <game-dir> --format json --include-passed
590
+ ttmg check --dir <game-dir> --format json --fail-on warning
591
+ ```
592
+
593
+ The JSON result includes a stable operation ID, overall status, counts, stable
594
+ diagnostic codes, severity, file locations, byte sizes, and help links. Errors
595
+ exit non-zero. Warnings do not block by default; use `--fail-on warning` in a
596
+ strict Agent or CI workflow.
597
+ JSON 结果包含稳定 operation ID、整体状态、数量汇总、稳定诊断码、严重级别、文件位置、字节数和帮助链接。错误默认以非零状态退出;warning 默认不阻断,严格的 Agent 或 CI 流程可增加 `--fail-on warning`。
598
+
599
+ Use the `--ai` option to add static Agent-debug readiness checks to the existing
600
+ checks. It currently detects a direct
601
+ `reportScene({ sceneId: 9999 })` checkpoint, reports the matching file and scan
602
+ coverage, and keeps `platformWrite: false`. Static detection proves integration
603
+ evidence only; real-device `GAME_READY` is still required.
604
+ 使用 `--ai` option 可在现有检查之外增加 Agent 调试准备度检查。目前会静态识别直接的 `reportScene({ sceneId: 9999 })` 检查点,返回命中文件和扫描范围,并保持 `platformWrite: false`。静态检出只证明代码已接入,最终仍需真机收到 `GAME_READY`。
605
+
606
+ ```
607
+ ttmg check --ai --dir <game-dir> --format json
608
+ ttmg check --ai --dir <game-dir> --format json --fail-on warning
609
+ ```
610
+
611
+ Use the read-only doctor before debugging to inspect the CLI and Node version,
612
+ project detection, reusable local login, selected LAN hosts, and whether proxy
613
+ environment variables are present. Proxy values and session Cookies are never
614
+ returned.
615
+ 调试前可执行只读 doctor,检查 CLI 与 Node 版本、工程识别、本地登录是否可复用、选中的局域网地址以及是否存在代理环境变量;结果不返回代理值或会话 Cookie。
616
+
617
+ ```
618
+ ttmg doctor --dir <game-dir> --format json
619
+ ttmg doctor --dir <game-dir> --format json --fail-on warning
620
+ ```
621
+
622
+ #### Structured Build 结构化构建
623
+
624
+ The existing native `ttmg build` default behavior is unchanged. Agents can
625
+ explicitly request a local structured build; artifacts are written outside the
626
+ game project under `~/__TTMG__/build/<operation-id>/`, and no platform write is
627
+ performed.
628
+ 现有 Native `ttmg build` 默认行为不变。Agent 可显式执行本地结构化构建;产物写入游戏工程外的 `~/__TTMG__/build/<operation-id>/`,不会写入平台。
629
+
630
+ ```
631
+ ttmg build --dir <game-dir> --format json
632
+ ttmg build --dir <game-dir> --format json --include-passed
633
+ ```
634
+
635
+ The report includes duration, engine, source size, package summaries, output
636
+ directory, package manifest, normalized diagnostics, and
637
+ `platformWrite: false`.
638
+ 结果包含耗时、引擎、源码大小、各包摘要、产物目录、package manifest、标准化诊断以及 `platformWrite: false`。
639
+
640
+ #### Platform Preview Upload 平台预览版本上传
641
+
642
+ The upload command packages the project and creates a new Developer Platform
643
+ version. With `--preview`, it also waits for platform processing and returns the
644
+ preview payload.
645
+ 上传命令会打包项目并在 Developer Platform 创建新版本;增加 `--preview` 后还会等待平台处理完成并返回预览地址。
646
+ The upload ZIP excludes the root `.agents`, `.claude`, and `.trae` directories.
647
+ 上传 ZIP 不包含项目根目录下的 `.agents`、`.claude` 和 `.trae`。
648
+
649
+ ```
650
+ ttmg upload --preview --client-key <client-key> --dir <game-dir> --format ndjson
651
+ ttmg upload --preview --serve-preview-page --client-key <client-key> --dir <game-dir> --format ndjson
652
+ ttmg upload --preview --serve-preview-page --client-key <client-key> --dir <game-dir>
653
+ ```
654
+
655
+ The NDJSON states are `precheck`, `packaging`, `uploading`,
656
+ `processing`, and `ready` or `failed`. A ready result includes `previewUrl`,
657
+ the identical `qrPayload`, the platform version URL, and `platformWrite: true`.
658
+ During platform processing, `platformStatus` uses readable values such as
659
+ `waiting_for_asset`, `pending`, `processing`, `success`, and `failed`; the
660
+ optional `platformStatusRaw` retains the original platform enum for debugging.
661
+ With `--serve-preview-page`, every successful upload returns a new
662
+ `previewPage.url`. The responsive local page guides users through test-account
663
+ authorization and preview launch with two QR codes and direct links. Its HTML
664
+ and QR images remain in memory. Repeated uploads for the same Client Key reuse
665
+ one localhost service: the new URL replaces the previous page immediately and
666
+ renews the one-hour TTL. When the page expires, its QR content is removed from
667
+ memory and the same URL shows a retry command for one more hour before the
668
+ service exits. Different Client Keys use independent services. In default text
669
+ mode the CLI prints a browser-oriented result block and opens the page in the
670
+ default browser; `--no-open` suppresses that action. JSON and NDJSON modes never
671
+ open a system browser and instead return a `presentation` contract with
672
+ `preferredAction: "open_url"` and a clickable-link fallback for Agents. Only
673
+ minimal process-coordination metadata is stored in the operating system's temp
674
+ directory; no page assets are written to the project or disk. If the local page
675
+ fails, the platform upload remains `ready` and `previewPage.status` is `failed`,
676
+ so callers must not retry the upload just to recreate the page.
677
+ NDJSON 状态依次为 `precheck`、`packaging`、`uploading`、`processing`,最终进入 `ready` 或 `failed`。平台处理阶段的 `platformStatus` 使用 `waiting_for_asset`、`pending`、`processing`、`success`、`failed` 等可读值;可选的 `platformStatusRaw` 仅保留平台原始枚举用于排障。成功结果包含 `previewUrl`、与其一致的 `qrPayload`、平台版本地址和 `platformWrite: true`。
678
+ 增加 `--serve-preview-page` 后,每次成功上传都会返回新的 `previewPage.url`。响应式本地页面通过两个二维码和直接链接依次承接测试账号授权与预览启动;HTML 和二维码只驻留内存。同一个 Client Key 反复上传时复用同一个 localhost 服务,新地址会立即替换旧页面并重新计算 1 小时有效期;到期后清除内存中的二维码,原地址继续显示 1 小时的重新执行提示,随后服务退出。不同 Client Key 使用独立服务。默认文本模式会打印浏览器展示信息并自动打开页面,`--no-open` 可关闭自动打开;JSON 和 NDJSON 模式不会调用系统浏览器,而是返回 `preferredAction: "open_url"` 和链接降级方式供 Agent 执行。系统临时目录只保存最小进程协同信息,不写入页面资源或项目内容。如果本地页面失败,平台上传仍保持 `ready`,并通过 `previewPage.status=failed` 返回局部失败;调用方不能为重新生成页面而重复上传。
679
+
38
680
  - 调试 H5 小游戏:
39
681
  - To debug H5 mini-games:
40
682
  ttmg dev --h5