@ttmg/cli 0.4.6-vibe-beta.15 → 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/README.md +10 -30
- package/dist/index.js +164 -109
- package/dist/index.js.map +1 -1
- package/dist/package.json +1 -1
- package/dist/scripts/verify-agent-contract.js +3 -2
- package/dist/scripts/vibe-upload-smoke.js +33 -18
- package/package.json +1 -1
- package/vibe-upload.md +85 -273
package/dist/package.json
CHANGED
|
@@ -133,7 +133,8 @@ assert.equal(categoryCatalog.platformWrite, false);
|
|
|
133
133
|
assert.equal(categoryCatalog.categoryCount, 12);
|
|
134
134
|
assert.equal(categoryCatalog.subcategoryCount, 114);
|
|
135
135
|
assert.equal(capabilities.commands.gameCategories.catalogVersion, categoryCatalog.catalogVersion);
|
|
136
|
-
assert.match(capabilities.commands.vibeUpload.command, /--vibe --
|
|
136
|
+
assert.match(capabilities.commands.vibeUpload.command, /--vibe --dir/);
|
|
137
|
+
assert.equal(capabilities.commands.vibeUpload.webAuthorization.available, false);
|
|
137
138
|
assert.equal(capabilities.commands.vibeUpload.skillWorkflow.keepUploadProcessRunning, true);
|
|
138
139
|
assert.equal(capabilities.commands.vibeUpload.skillWorkflow.realUploadSuccess.simulation, false);
|
|
139
140
|
assert.equal(capabilities.commands.vibeUpload.appInfoFields.defaultedByCli.includes('privacy_policy'), true);
|
|
@@ -400,7 +401,7 @@ const uploadHelp = runCli(['upload', '--help']);
|
|
|
400
401
|
assert.doesNotMatch(uploadHelp.stdout, /--app-info/);
|
|
401
402
|
assert.match(uploadHelp.stdout.replace(/\s+/g, ' '), /only title and icon|只收集标题和头像/);
|
|
402
403
|
assertExit(uploadHelp, 0, 'upload help');
|
|
403
|
-
assert.match(uploadHelp.stdout, /--vibe --
|
|
404
|
+
assert.match(uploadHelp.stdout, /--vibe --dir/);
|
|
404
405
|
assert.match(uploadHelp.stdout, /authorizationOpenCommand/);
|
|
405
406
|
assert.match(uploadHelp.stdout, /simulation=false/);
|
|
406
407
|
assert.match(uploadHelp.stdout, /--category <category>/);
|
|
@@ -145,10 +145,10 @@ async function main() {
|
|
|
145
145
|
}
|
|
146
146
|
const launches = fs.readFileSync(browserReceipt, 'utf8').trim().split('\n').map(JSON.parse);
|
|
147
147
|
assert.equal(launches.length, 2);
|
|
148
|
-
assert.ok(launches.every(item => item.args.includes(ready.url
|
|
148
|
+
assert.ok(launches.every(item => item.args.includes(ready.url)));
|
|
149
149
|
const redirect = await fetch(ready.url + '/authorize', {redirect: 'manual'});
|
|
150
|
-
assert.equal(redirect.headers.get('location'),
|
|
151
|
-
assert.equal(redirect.status,
|
|
150
|
+
assert.equal(redirect.headers.get('location'), null);
|
|
151
|
+
assert.equal(redirect.status, 410);
|
|
152
152
|
rendered = workerMessage(message => message.type === 'rendered' && message.id === 2);
|
|
153
153
|
authWorker.send({type: 'render', id: 2, html: '<h1>Complete</h1>'});
|
|
154
154
|
await rendered;
|
|
@@ -389,7 +389,7 @@ async function main() {
|
|
|
389
389
|
|
|
390
390
|
const beforeWeb = requests.length;
|
|
391
391
|
const webConflict = await run([...input, '--web', '--mock', '--format', 'json']);
|
|
392
|
-
assert.equal(events(webConflict)[0].errorCode, '
|
|
392
|
+
assert.equal(events(webConflict)[0].errorCode, 'VIBE_WEB_DISABLED');
|
|
393
393
|
const legacyWeb = await run(['upload', '--web', '--format', 'json']);
|
|
394
394
|
assert.equal(events(legacyWeb)[0].errorCode, 'VIBE_OPTION_REQUIRES_VIBE');
|
|
395
395
|
assert.equal(requests.length, beforeWeb);
|
|
@@ -402,7 +402,7 @@ async function main() {
|
|
|
402
402
|
[['--category', 'Unknown', '--subcategory', 'Other'], 'VIBE_INVALID_CATEGORY'],
|
|
403
403
|
[['--category', '', '--subcategory', ''], 'VIBE_INVALID_CATEGORY'],
|
|
404
404
|
]) {
|
|
405
|
-
const invalid = await run([...input
|
|
405
|
+
const invalid = await run([...input, ...args, '--format', 'json']);
|
|
406
406
|
assert.equal(invalid.code, 1);
|
|
407
407
|
const result = events(invalid)[0];
|
|
408
408
|
assert.equal(result.errorCode, code);
|
|
@@ -412,36 +412,46 @@ async function main() {
|
|
|
412
412
|
}
|
|
413
413
|
assert.equal(requests.length, beforeWeb, 'Invalid metadata must not create tasks or upload');
|
|
414
414
|
webMode = true;
|
|
415
|
+
for (const authorizationMode of ['qr']) {
|
|
415
416
|
for (const format of ['json', 'ndjson']) {
|
|
416
417
|
expectedWebDescription = format === 'json' ? 'Discover the fun of TikTok Mini Games.' : 'Stack cats on a rooftop 🐈';
|
|
417
418
|
const descriptionArgs = format === 'json' ? [] : ['--description', expectedWebDescription];
|
|
418
419
|
expectedWebCategory = format === 'json' ? {category: 'Other', subcategory: 'Other'} : {category: 'Puzzle', subcategory: 'Physics'};
|
|
419
420
|
const categoryArgs = format === 'json' ? [] : ['--category', 'Puzzle', '--subcategory', 'Physics'];
|
|
420
|
-
const receipt = path.join(temp, `upload
|
|
421
|
+
const receipt = path.join(temp, `upload-${authorizationMode}-${format}.ndjson`);
|
|
421
422
|
const requestStart = requests.length;
|
|
422
|
-
const web = await run([...input.filter(v => v !== '--no-open'), '--web', ...categoryArgs, ...descriptionArgs, '--format', format, '--poll-interval', '0.2'], async event => {
|
|
423
|
+
const web = await run([...input.filter(v => v !== '--no-open'), ...(authorizationMode === 'web' ? ['--web'] : []), ...categoryArgs, ...descriptionArgs, '--format', format, '--poll-interval', '0.2'], async event => {
|
|
423
424
|
if (event.status === 'prepared') assert.equal(event.description, expectedWebDescription);
|
|
424
425
|
if (event.status === 'prepared') assert.deepEqual(
|
|
425
426
|
{category: event.classification.category, subcategory: event.classification.subcategory},
|
|
426
427
|
expectedWebCategory);
|
|
427
428
|
if (event.status === 'waiting_authorization') {
|
|
428
|
-
assert.equal(event.authorizationMode,
|
|
429
|
+
assert.equal(event.authorizationMode, authorizationMode);
|
|
429
430
|
assert.equal(event.browserOpenRequested, true);
|
|
430
431
|
assert.equal(event.simulation, false);
|
|
431
|
-
assert.equal(event.nextAction, 'open_browser');
|
|
432
|
-
assert.equal(event.qrPurpose, undefined);
|
|
432
|
+
assert.equal(event.nextAction, authorizationMode === 'web' ? 'open_browser' : 'scan_qr');
|
|
433
|
+
assert.equal(event.qrPurpose, authorizationMode === 'web' ? undefined : 'authorization_binding');
|
|
433
434
|
const response = await fetch(event.pageUrl + '/authorize', {redirect: 'manual'});
|
|
434
|
-
assert.equal(response.status,
|
|
435
|
-
assert.
|
|
435
|
+
assert.equal(response.status, 410);
|
|
436
|
+
assert.equal(response.headers.get('location'), null);
|
|
436
437
|
const html = await (await fetch(event.pageUrl)).text();
|
|
437
|
-
assert.
|
|
438
|
-
assert.
|
|
438
|
+
assert.ok(html.includes(expectedWebDescription));
|
|
439
|
+
assert.ok(html.includes(expectedWebCategory.category));
|
|
440
|
+
assert.ok(html.includes(expectedWebCategory.subcategory));
|
|
441
|
+
assert.doesNotMatch(html, /<header class="brand"/);
|
|
442
|
+
if (authorizationMode === 'web') {
|
|
443
|
+
assert.match(html, /Authorize in your browser/);
|
|
444
|
+
assert.doesNotMatch(html, /alt="Authorization QR"|Scan the QR code/);
|
|
445
|
+
} else {
|
|
446
|
+
assert.match(html, /alt="Authorization QR"/);
|
|
447
|
+
assert.match(html, /data:image\/png;base64/);
|
|
448
|
+
}
|
|
439
449
|
}
|
|
440
450
|
}, {
|
|
441
451
|
NODE_OPTIONS: env.NODE_OPTIONS + ' --require=' + path.join(__dirname, 'vibe-auth-open-test-preload.cjs'),
|
|
442
452
|
TTMG_AUTH_OPEN_TEST_RECEIPT: receipt,
|
|
443
453
|
// Explicit --web must not inherit an old Mock backend setting.
|
|
444
|
-
TTMG_VIBE_BACKEND: 'mock',
|
|
454
|
+
TTMG_VIBE_BACKEND: authorizationMode === 'web' ? 'mock' : '',
|
|
445
455
|
TTMG_VIBE_TEST_RETAIN_UPLOAD_SOCKET: '1',
|
|
446
456
|
});
|
|
447
457
|
assert.equal(web.code, 0, web.stderr);
|
|
@@ -468,14 +478,17 @@ async function main() {
|
|
|
468
478
|
if (format === 'json') assert.equal(output.length, 1);
|
|
469
479
|
const opens = fs.readFileSync(receipt, 'utf8').trim().split('\n').map(line => JSON.parse(line));
|
|
470
480
|
assert.equal(opens.length, 1);
|
|
471
|
-
assert.ok(opens[0].args.some(arg =>
|
|
481
|
+
assert.ok(opens[0].args.some(arg => (authorizationMode === 'web'
|
|
482
|
+
? /^http:\/\/127\.0\.0\.1:\d+\/[a-f0-9]{48}\/authorize$/
|
|
483
|
+
: /^http:\/\/127\.0\.0\.1:\d+\/[a-f0-9]{48}$/).test(arg)));
|
|
472
484
|
assert.doesNotMatch(JSON.stringify(opens) + web.stdout + web.stderr, /process-test-secret|import_token|web-icon-receipt|web-package-receipt|aweme:\/\//);
|
|
473
485
|
}
|
|
486
|
+
}
|
|
474
487
|
expectedWebCategory = {category: 'Other', subcategory: 'Other'};
|
|
475
488
|
expectedWebDescription = 'Discover the fun of TikTok Mini Games.';
|
|
476
489
|
webFailureEndpoint = '/bff/app_info/minis_import/submit_minis_import_info_for_agent/';
|
|
477
490
|
const failedStart = requests.length;
|
|
478
|
-
const webUploadFailure = await run([...input.filter(v => v !== '--no-open'), '--
|
|
491
|
+
const webUploadFailure = await run([...input.filter(v => v !== '--no-open'), '--format', 'json'], undefined, {
|
|
479
492
|
NODE_OPTIONS: env.NODE_OPTIONS + ' --require=' + path.join(__dirname, 'vibe-auth-open-test-preload.cjs'),
|
|
480
493
|
TTMG_AUTH_OPEN_TEST_RECEIPT: path.join(temp, 'web-failure-open.ndjson'),
|
|
481
494
|
TTMG_VIBE_TEST_RETAIN_UPLOAD_SOCKET: '1',
|
|
@@ -600,7 +613,9 @@ async function main() {
|
|
|
600
613
|
assert.equal(events(projectRun)[0].status, 'prepared');
|
|
601
614
|
assert.ok(events(projectRun)[0].packageSizeBytes > 0);
|
|
602
615
|
|
|
603
|
-
const missingBackend = await run([...input, '--format', 'json']
|
|
616
|
+
const missingBackend = await run([...input, '--format', 'json'], undefined, {
|
|
617
|
+
TTMG_VIBE_BACKEND: 'unsupported',
|
|
618
|
+
});
|
|
604
619
|
assert.equal(missingBackend.code, 1);
|
|
605
620
|
assert.equal(
|
|
606
621
|
events(missingBackend)[0].errorCode,
|