@ttmg/cli 0.4.6-vibe-beta.2 → 0.4.6-vibe-beta.4

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/dist/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ttmg/cli",
3
- "version": "0.4.6-vibe-beta.2",
3
+ "version": "0.4.6-vibe-beta.4",
4
4
  "description": "TikTok Mini Game Command Line Tool",
5
5
  "license": "ISC",
6
6
  "bin": {
@@ -20,6 +20,9 @@
20
20
  "verify:agent-contract": "node scripts/verify-agent-contract.js",
21
21
  "test:network": "node -r ts-node/register src/commands/native/dev/utils/getLocalIPs.test.ts",
22
22
  "test:upload-preview": "node scripts/run-ts-test.js src/commands/common/upload.test.ts",
23
+ "test:preview-page": "node scripts/run-ts-test.js src/commands/common/previewPageServer.test.ts",
24
+ "test:preview-page-detached": "node scripts/run-ts-test.js src/commands/common/previewPageDetached.test.ts",
25
+ "test:preview-page-process": "node scripts/preview-page-server-smoke.js",
23
26
  "test:login": "node scripts/run-ts-test.js src/commands/common/login.test.ts",
24
27
  "test:auth": "node scripts/run-ts-test.js src/commands/common/auth.test.ts",
25
28
  "test:capabilities": "node scripts/run-ts-test.js src/commands/common/capabilities.test.ts",
@@ -33,7 +36,7 @@
33
36
  "test:check-ai": "node scripts/run-ts-test.js src/commands/native/check/ai.test.ts",
34
37
  "test:build-structured": "node scripts/run-ts-test.js src/commands/native/build/build.test.ts",
35
38
  "test:doctor": "node scripts/run-ts-test.js src/commands/native/doctor/doctor.test.ts",
36
- "test:agent-contract": "npm run test:login && npm run test:auth && npm run test:capabilities && npm run test:test-account && npm run test:upload-preview && npm run test:check && npm run test:check-ai && npm run test:build-structured && npm run test:doctor && npm run test:dev-session && npm run test:dev-session-command && npm run test:dev-runtime-event && npm run test:network && npx tsc --noEmit && npm run build && npm run verify:dist-version && npm run verify:agent-contract",
39
+ "test:agent-contract": "npm run test:login && npm run test:auth && npm run test:capabilities && npm run test:test-account && npm run test:upload-preview && npm run test:preview-page && npm run test:check && npm run test:check-ai && npm run test:build-structured && npm run test:doctor && npm run test:dev-session && npm run test:dev-session-command && npm run test:dev-runtime-event && npm run test:network && npx tsc --noEmit && npm run build && npm run test:preview-page-process && npm run test:preview-page-detached && npm run verify:dist-version && npm run verify:agent-contract",
37
40
  "test:agent-contract:full": "npm run test:agent-contract && npm run test:dev-default-process && npm run test:dev-game-ready-process",
38
41
  "publish:beta": "npm publish --registry=https://registry.npmjs.org/ --access public --tag beta",
39
42
  "setup": "node scripts/setup.js",
@@ -80,7 +83,7 @@
80
83
  "qs": "6.12.1",
81
84
  "semver": "^7.7.2",
82
85
  "socks-proxy-agent": "^9.0.0",
83
- "ttmg-pack": "0.4.8",
86
+ "ttmg-pack": "0.4.13-beta.1",
84
87
  "ws": "^8.18.3"
85
88
  },
86
89
  "devDependencies": {
@@ -65,8 +65,6 @@ async function run() {
65
65
  'dev',
66
66
  '--client-key',
67
67
  'smoke-client',
68
- '--format',
69
- 'json',
70
68
  '--events',
71
69
  'ndjson',
72
70
  '--no-open',
@@ -98,6 +96,33 @@ async function run() {
98
96
  const exitCode = await new Promise(resolve => child.once('close', resolve));
99
97
  assert.equal(exitCode, 0, stderr || stdout);
100
98
 
99
+ const stdoutEvents = stdout
100
+ .trim()
101
+ .split(/\r?\n/)
102
+ .filter(Boolean)
103
+ .map(line => JSON.parse(line));
104
+ assert.ok(stdoutEvents.length > 0, 'dev did not emit NDJSON events');
105
+ assert.equal(
106
+ stdoutEvents.every(
107
+ event =>
108
+ event.schemaVersion === '1' &&
109
+ typeof event.sessionId === 'string' &&
110
+ Number.isInteger(event.seq) &&
111
+ typeof event.type === 'string',
112
+ ),
113
+ true,
114
+ 'dev stdout contained a non-event JSON object',
115
+ );
116
+ assert.equal(
117
+ stdoutEvents.some(
118
+ event =>
119
+ event.type === 'lifecycle' &&
120
+ event.payload?.state === 'GAME_READY',
121
+ ),
122
+ true,
123
+ 'dev stdout did not contain the GAME_READY event',
124
+ );
125
+
101
126
  const events = fs
102
127
  .readFileSync(path.join(evidenceDirectory, 'events.ndjson'), 'utf8')
103
128
  .trim()
@@ -0,0 +1,63 @@
1
+ const assert = require('node:assert/strict');
2
+ const path = require('node:path');
3
+ const { spawn } = require('node:child_process');
4
+
5
+ const entryPath = path.resolve(__dirname, '../dist/index.js');
6
+ const child = spawn(process.execPath, [entryPath, '__preview-page-server'], {
7
+ detached: true,
8
+ windowsHide: true,
9
+ stdio: ['ignore', 'ignore', 'ignore', 'ipc'],
10
+ });
11
+
12
+ const ready = new Promise((resolve, reject) => {
13
+ const timeout = setTimeout(
14
+ () => reject(new Error('preview page worker did not become ready')),
15
+ 5000,
16
+ );
17
+ child.once('error', reject);
18
+ child.once('exit', code =>
19
+ reject(new Error(`preview page worker exited early (${code})`)),
20
+ );
21
+ child.on('message', message => {
22
+ if (message?.type === 'error') reject(new Error(message.error));
23
+ if (message?.type === 'ready') {
24
+ clearTimeout(timeout);
25
+ resolve(message);
26
+ }
27
+ });
28
+ });
29
+
30
+ async function main() {
31
+ child.send({
32
+ type: 'start',
33
+ authorizationUrl: 'https://www.tiktok.com/ttmg/dev/client-key',
34
+ previewUrl: 'https://www.tiktok.com/preview/process-smoke',
35
+ clientKey: 'client-key',
36
+ projectName: 'Process Smoke Game',
37
+ versionId: 'asset-smoke',
38
+ token: 'b'.repeat(48),
39
+ ttlMs: 5000,
40
+ });
41
+ const result = await ready;
42
+ assert.match(result.url, /^http:\/\/127\.0\.0\.1:\d+\/preview\/b{48}$/);
43
+ const response = await fetch(result.url);
44
+ assert.equal(response.status, 200);
45
+ assert.equal(
46
+ response.headers.get('content-type'),
47
+ 'text/html; charset=utf-8',
48
+ );
49
+ const html = await response.text();
50
+ assert.match(html, /Process Smoke Game/);
51
+ assert.equal((html.match(/data:image\/png;base64,/g) || []).length, 2);
52
+ console.log('preview page server process smoke passed');
53
+ }
54
+
55
+ main()
56
+ .catch(error => {
57
+ console.error(error);
58
+ process.exitCode = 1;
59
+ })
60
+ .finally(() => {
61
+ if (child.connected) child.disconnect();
62
+ child.kill();
63
+ });
@@ -94,11 +94,86 @@ assert.equal(
94
94
  );
95
95
  assert.equal(capabilities.commands.build.platformWrite, false);
96
96
  assert.equal(capabilities.commands.dev.platformWrite, false);
97
+ assert.equal(
98
+ capabilities.commands.dev.command,
99
+ 'ttmg dev --format json --no-open',
100
+ );
101
+ assert.equal(
102
+ capabilities.commands.dev.eventsCommand,
103
+ 'ttmg dev --events ndjson --no-open',
104
+ );
105
+ assert.equal(capabilities.commands.dev.outputModesMutuallyExclusive, true);
97
106
  assert.equal(capabilities.commands.uploadPreview.platformWrite, true);
107
+ assert.equal(
108
+ capabilities.commands.uploadPreview.previewPage.option,
109
+ '--serve-preview-page',
110
+ );
111
+ assert.equal(capabilities.commands.uploadPreview.previewPage.inMemory, true);
112
+ assert.equal(
113
+ capabilities.commands.uploadPreview.previewPage.reuseScope,
114
+ 'clientKey',
115
+ );
116
+ assert.equal(capabilities.commands.uploadPreview.previewPage.latestOnly, true);
117
+ assert.equal(
118
+ capabilities.commands.uploadPreview.previewPage.renewsTtlOnUpload,
119
+ true,
120
+ );
121
+ assert.equal(
122
+ capabilities.commands.uploadPreview.previewPage.textModeAutoOpen,
123
+ true,
124
+ );
125
+ assert.equal(
126
+ capabilities.commands.uploadPreview.previewPage.structuredModeAutoOpen,
127
+ false,
128
+ );
129
+ assert.equal(
130
+ capabilities.commands.uploadPreview.previewPage.noOpenOption,
131
+ '--no-open',
132
+ );
133
+ assert.equal(
134
+ capabilities.commands.uploadPreview.previewPage.presentation.preferredAction,
135
+ 'open_url',
136
+ );
137
+ assert.equal(
138
+ capabilities.commands.uploadPreview.previewPage.presentation.terminalInline,
139
+ false,
140
+ );
141
+ assert.equal(
142
+ capabilities.commands.uploadPreview.previewPage.presentation.sameHostRequired,
143
+ true,
144
+ );
145
+ assert.equal(capabilities.commands.uploadPreview.previewPage.ttlSeconds, 3600);
146
+ assert.equal(
147
+ capabilities.commands.uploadPreview.previewPage.expiredNoticeTtlSeconds,
148
+ 3600,
149
+ );
150
+ assert.equal(
151
+ capabilities.commands.uploadPreview.previewPage.localhostOnly,
152
+ true,
153
+ );
98
154
  assert.equal(capabilities.dev.gameReadyProtocol, true);
99
155
  assert.equal(capabilities.dev.gameReady, false);
100
156
  assertNoSecretKeys(capabilities, 'capabilities');
101
157
 
158
+ const conflictingDevOutput = runCli([
159
+ 'dev',
160
+ '--format',
161
+ 'json',
162
+ '--events',
163
+ 'ndjson',
164
+ '--no-open',
165
+ ]);
166
+ assertExit(conflictingDevOutput, 1, 'conflicting dev output modes');
167
+ assert.equal(
168
+ conflictingDevOutput.stdout,
169
+ '',
170
+ 'conflicting dev output modes must not write protocol data to stdout',
171
+ );
172
+ assert.match(
173
+ conflictingDevOutput.stderr,
174
+ /output modes cannot be combined|输出模式不能同时使用/,
175
+ );
176
+
102
177
  const checkHelp = runCli(['check', '--help']);
103
178
  assertExit(checkHelp, 0, 'check help');
104
179
  assert.match(checkHelp.stdout, /Usage: ttmg check \[options\]/);
@@ -115,6 +190,8 @@ assert.notEqual(
115
190
  const uploadHelp = runCli(['upload', '--help']);
116
191
  assertExit(uploadHelp, 0, 'upload help');
117
192
  assert.match(uploadHelp.stdout, /--preview\b/);
193
+ assert.match(uploadHelp.stdout, /--serve-preview-page\b/);
194
+ assert.match(uploadHelp.stdout, /--no-open\b/);
118
195
  assert.doesNotMatch(uploadHelp.stdout, /--allow-upload\b/);
119
196
 
120
197
  const tempDirectory = fs.mkdtempSync(
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ttmg/cli",
3
- "version": "0.4.6-vibe-beta.2",
3
+ "version": "0.4.6-vibe-beta.4",
4
4
  "description": "TikTok Mini Game Command Line Tool",
5
5
  "license": "ISC",
6
6
  "bin": {
@@ -20,6 +20,9 @@
20
20
  "verify:agent-contract": "node scripts/verify-agent-contract.js",
21
21
  "test:network": "node -r ts-node/register src/commands/native/dev/utils/getLocalIPs.test.ts",
22
22
  "test:upload-preview": "node scripts/run-ts-test.js src/commands/common/upload.test.ts",
23
+ "test:preview-page": "node scripts/run-ts-test.js src/commands/common/previewPageServer.test.ts",
24
+ "test:preview-page-detached": "node scripts/run-ts-test.js src/commands/common/previewPageDetached.test.ts",
25
+ "test:preview-page-process": "node scripts/preview-page-server-smoke.js",
23
26
  "test:login": "node scripts/run-ts-test.js src/commands/common/login.test.ts",
24
27
  "test:auth": "node scripts/run-ts-test.js src/commands/common/auth.test.ts",
25
28
  "test:capabilities": "node scripts/run-ts-test.js src/commands/common/capabilities.test.ts",
@@ -33,7 +36,7 @@
33
36
  "test:check-ai": "node scripts/run-ts-test.js src/commands/native/check/ai.test.ts",
34
37
  "test:build-structured": "node scripts/run-ts-test.js src/commands/native/build/build.test.ts",
35
38
  "test:doctor": "node scripts/run-ts-test.js src/commands/native/doctor/doctor.test.ts",
36
- "test:agent-contract": "npm run test:login && npm run test:auth && npm run test:capabilities && npm run test:test-account && npm run test:upload-preview && npm run test:check && npm run test:check-ai && npm run test:build-structured && npm run test:doctor && npm run test:dev-session && npm run test:dev-session-command && npm run test:dev-runtime-event && npm run test:network && npx tsc --noEmit && npm run build && npm run verify:dist-version && npm run verify:agent-contract",
39
+ "test:agent-contract": "npm run test:login && npm run test:auth && npm run test:capabilities && npm run test:test-account && npm run test:upload-preview && npm run test:preview-page && npm run test:check && npm run test:check-ai && npm run test:build-structured && npm run test:doctor && npm run test:dev-session && npm run test:dev-session-command && npm run test:dev-runtime-event && npm run test:network && npx tsc --noEmit && npm run build && npm run test:preview-page-process && npm run test:preview-page-detached && npm run verify:dist-version && npm run verify:agent-contract",
37
40
  "test:agent-contract:full": "npm run test:agent-contract && npm run test:dev-default-process && npm run test:dev-game-ready-process",
38
41
  "publish:beta": "npm publish --registry=https://registry.npmjs.org/ --access public --tag beta",
39
42
  "setup": "node scripts/setup.js",
@@ -80,7 +83,7 @@
80
83
  "qs": "6.12.1",
81
84
  "semver": "^7.7.2",
82
85
  "socks-proxy-agent": "^9.0.0",
83
- "ttmg-pack": "0.4.8",
86
+ "ttmg-pack": "0.4.13-beta.1",
84
87
  "ws": "^8.18.3"
85
88
  },
86
89
  "devDependencies": {