@ttmg/cli 0.4.6-vibe-beta.8 → 0.4.6-vibe-beta.10

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 CHANGED
@@ -1,12 +1,8 @@
1
1
  ### @ttmg/cli
2
2
 
3
- Vibe 试用安装:`npm install -g @ttmg/cli@0.4.6-vibe-beta.8`。独立升级标签:`vibe-beta`;包内保留当前 AI Friendly 代码。
3
+ Vibe 真实网页授权与上传:`ttmg upload --vibe --web --dir ./game --title "My game" --icon ./avatar.png --format ndjson`。只向用户收集标题和本地头像,并使用游戏目录或代码包;其他应用资料由平台默认处理,不需要用户填写。网页授权后,CLI 自动继续上传。见 [Vibe 接入说明](vibe-upload.md)。
4
4
 
5
- Vibe trial: install `@ttmg/cli@0.4.6-vibe-beta.8`. Updates use `vibe-beta`; current AI Friendly code is included.
6
-
7
- Vibe 真实网页授权:`ttmg upload --vibe --web --dir ./game --title "My game" --icon ./avatar.png --format ndjson`。内置 PPE 创建任务后打开系统浏览器,持续查询真实绑定状态,不模拟授权;当前真实素材上传仍受限制。`--web` 不能与 `--mock` 或 `--no-open` 同用,原 `--mock` 链路不变。详见 [Vibe 接入说明](vibe-upload.md)。
8
-
9
- Vibe real web authorization: use `--web` without `--mock`. It creates a PPE task, opens the system browser and polls real binding status; real material upload remains gated. It conflicts with `--mock` and `--no-open`. The original Mock workflow is unchanged. See [Vibe integration](vibe-upload.md).
5
+ Vibe real web authorization and upload: use `--web` with the title, local icon and game directory or ZIP. Collect only the title and icon from the user; the platform defaults all other app metadata. Upload continues after browser authorization. See [Vibe integration](vibe-upload.md).
10
6
 
11
7
  `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.
12
8
  `ttmg` 是一款专为小游戏项目管理与开发设计的命令行工具,支持 H5 小游戏和原生小游戏的初始化、开发调试及打包构建。
@@ -73,8 +69,8 @@ simulated. See [Vibe binding/upload](vibe-upload.md) for schema-v2 results.
73
69
  `--mock` now creates real PPE tasks, not a fully offline run. Real request failures
74
70
  still fail. Production routing is a future CLI release change, not Skill configuration.
75
71
 
76
- 维护者可用 `--app-info ./app-info.json --dry-run` 校验完整应用信息和平台头像要求;文件字段见 [Vibe 绑定上传](vibe-upload.md)。不传此选项时,现有 Mock 输入保持不变。真实上传仍未开放。
77
- 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.
72
+ 当前上传只需要标题、头像和游戏目录或代码包,其他应用资料由平台默认处理。Skill 读取 `inputRequirements`,不向用户索要额外资料;本地预检使用 `--dry-run`。
73
+ Current uploads need only the title, icon and game directory or ZIP. The platform defaults other metadata. Read `inputRequirements` and do not request extra fields. Use `--dry-run` for local preparation.
78
74
 
79
75
  For the existing authenticated platform workflow, log in first; this does not apply to the local Vibe prototype above.
80
76
  原有需要平台鉴权的流程仍先登录;上述 Vibe 本地原型不需要此步骤。
package/dist/index.js CHANGED
@@ -21,6 +21,7 @@ var express = require('express');
21
21
  var cheerio = require('cheerio');
22
22
  var archiver = require('archiver');
23
23
  var FormData$1 = require('form-data');
24
+ var https = require('https');
24
25
  var promises = require('timers/promises');
25
26
  var chokidar = require('chokidar');
26
27
  var WebSocket = require('ws');
@@ -34,7 +35,6 @@ var require$$0 = require('util');
34
35
  var require$$0$1 = require('events');
35
36
  var require$$0$2 = require('buffer');
36
37
  var require$$1$2 = require('stream');
37
- var https = require('https');
38
38
  var dns = require('dns');
39
39
  var boxen = require('boxen');
40
40
  var semver = require('semver');
@@ -7232,7 +7232,7 @@ const messages = {
7232
7232
  'cli.command.logout.desc': 'Logout and clear local user data',
7233
7233
  'cli.command.auth.desc': 'Inspect local authentication state',
7234
7234
  'cli.command.auth.open.desc': 'Open an existing Vibe task authorization page in the system browser',
7235
- 'cli.command.upload.vibeWeb': 'Real browser authorization in PPE; keep polling (--vibe; no Mock or --no-open)',
7235
+ 'cli.command.upload.vibeWeb': 'Authorize in the browser, then upload to PPE (--vibe; no Mock or --no-open)',
7236
7236
  'cli.command.auth.open.pageUrl': 'Local pageUrl returned by the running Vibe upload command',
7237
7237
  'cli.command.auth.open.requested': 'Browser open requested. Complete authorization there; the existing upload process continues polling.',
7238
7238
  'cli.command.auth.open.invalidPage': 'Pass the local pageUrl from the running Vibe upload command, not the platform URL.',
@@ -7435,9 +7435,9 @@ const messages = {
7435
7435
  'cli.command.upload.servePreviewPage': 'Serve a temporary local preview page with test-account and preview QR codes',
7436
7436
  'cli.command.upload.noOpen': 'Do not open the local preview page in the default browser',
7437
7437
  'cli.command.upload.format': 'Output format: text | json | ndjson',
7438
- 'cli.command.upload.vibe': 'Skill-guided binding and upload (schema v2; use --mock for the integration trial)',
7438
+ 'cli.command.upload.vibe': 'Binding and upload: collect only title and icon; other app metadata uses platform defaults (schema v2)',
7439
7439
  'cli.command.upload.vibeTitle': 'Game title supplied by the Skill (--vibe)',
7440
- 'cli.command.upload.vibeAppInfo': 'Local JSON with complete app metadata; validates platform title/icon requirements (--vibe)',
7440
+ 'cli.command.upload.vibeAppInfo': 'Legacy metadata file compatibility; not needed for current uploads and must not be requested from users',
7441
7441
  'cli.command.upload.vibeIcon': 'Local PNG/JPEG/WebP selected by the user (--vibe)',
7442
7442
  'cli.command.upload.vibePackage': 'Prepared ZIP instead of --dir (--vibe)',
7443
7443
  'cli.command.upload.vibeDryRun': 'Validate and package locally without authorization or upload (--vibe)',
@@ -7645,7 +7645,7 @@ const messages = {
7645
7645
  'cli.command.logout.desc': '退出登录并清除本地用户信息',
7646
7646
  'cli.command.auth.desc': '查看本地登录状态',
7647
7647
  'cli.command.auth.open.desc': '在系统浏览器打开已有 Vibe 任务的授权页',
7648
- 'cli.command.upload.vibeWeb': '真实 PPE 网页授权并继续轮询(--vibe;不能与 Mock 或 --no-open 同用)',
7648
+ 'cli.command.upload.vibeWeb': '网页授权就绪后自动上传到 PPE(--vibe;不能与 Mock 或 --no-open 同用)',
7649
7649
  'cli.command.auth.open.pageUrl': '正在运行的 Vibe 上传命令返回的本地 pageUrl',
7650
7650
  'cli.command.auth.open.requested': '已请求浏览器打开授权页。请在页面完成授权,原上传进程继续轮询。',
7651
7651
  'cli.command.auth.open.invalidPage': '请传入正在运行的 Vibe 上传命令返回的本地 pageUrl,不是平台授权链接。',
@@ -7848,8 +7848,8 @@ const messages = {
7848
7848
  'cli.command.upload.servePreviewPage': '启动包含测试账号与预览二维码的临时本地页面',
7849
7849
  'cli.command.upload.noOpen': '不使用默认浏览器打开本地预览页面',
7850
7850
  'cli.command.upload.format': '输出格式:text | json | ndjson',
7851
- 'cli.command.upload.vibe': 'Skill 引导绑定上传(schema v2;使用 --mock 联调试用)',
7852
- 'cli.command.upload.vibeAppInfo': '完整应用信息 JSON 文件,同时检查平台名称和头像要求(--vibe)',
7851
+ 'cli.command.upload.vibe': '绑定上传:只收集标题和头像,其他应用资料由平台默认处理(schema v2',
7852
+ 'cli.command.upload.vibeAppInfo': '仅兼容旧资料文件;当前上传无需此参数,不应向用户索要',
7853
7853
  'cli.command.upload.vibeTitle': 'Skill 提供的游戏标题(--vibe)',
7854
7854
  'cli.command.upload.vibeIcon': '用户指定的本地 PNG/JPEG/WebP 图片(--vibe)',
7855
7855
  'cli.command.upload.vibePackage': '已准备的 ZIP,与 --dir 二选一(--vibe)',
@@ -16308,7 +16308,7 @@ async function authStatus(options = {}) {
16308
16308
  return result;
16309
16309
  }
16310
16310
 
16311
- var version = "0.4.6-vibe-beta.8";
16311
+ var version = "0.4.6-vibe-beta.10";
16312
16312
  var engines = {
16313
16313
  node: ">=20.19.1 <21 || >=22"
16314
16314
  };
@@ -16317,6 +16317,20 @@ var pkg = {
16317
16317
  engines: engines
16318
16318
  };
16319
16319
 
16320
+ // Skill-facing v2 contract. Backend credentials never cross this boundary.
16321
+ const VIBE_INPUT_REQUIREMENTS = {
16322
+ requiredUserInputs: ['title', 'icon'],
16323
+ codeSource: ['dir', 'package'],
16324
+ additionalMetadataSource: 'platform-defaults',
16325
+ requestAdditionalMetadata: false,
16326
+ };
16327
+ class VibeError extends Error {
16328
+ constructor(code) {
16329
+ super(code);
16330
+ this.code = code;
16331
+ }
16332
+ }
16333
+
16320
16334
  function getCapabilities() {
16321
16335
  return {
16322
16336
  schemaVersion: '1',
@@ -16351,20 +16365,24 @@ function getCapabilities() {
16351
16365
  taskCreation: true,
16352
16366
  statusPolling: true,
16353
16367
  authorizationScheme: 'aweme://webview?url=<encoded landing_url>',
16354
- uploadEnabled: false,
16355
- uploadBlockedError: 'VIBE_REAL_UPLOAD_NOT_READY',
16368
+ uploadEnabled: true,
16356
16369
  },
16357
16370
  terminalSuccess: 'uploaded',
16358
16371
  stages: ['precheck', 'packaging', 'prepared', 'creating_task', 'waiting_authorization', 'uploading', 'uploaded', 'failed', 'cancelled'],
16359
16372
  uploadSteps: ['avatar', 'app_info', 'package'],
16360
16373
  sourceProjectIdentity: '.ttmg/vibe-project.json',
16361
16374
  metadataInputs: ['title', 'icon', 'dir|package'],
16362
- webAuthorization: { option: '--web', backend: 'ppe', defaultLane: 'ppe_op_vc', simulation: false, opensSystemBrowser: true, continuesPolling: true, formatIndependent: true, conflictsWith: ['--mock', '--mock-scenario', '--vibe-api', '--no-open'], mockBehaviorUnchanged: true, materialUploadEnabled: false },
16375
+ inputRequirements: VIBE_INPUT_REQUIREMENTS,
16376
+ webAuthorization: { option: '--web', backend: 'ppe', defaultLane: 'ppe_op_vc', simulation: false, opensSystemBrowser: true, continuesPolling: true, formatIndependent: true, conflictsWith: ['--mock', '--mock-scenario', '--vibe-api', '--no-open'], mockBehaviorUnchanged: true, materialUploadEnabled: true },
16363
16377
  optionalMetadataFile: '--app-info',
16364
16378
  appInfoFields: {
16365
- required: ['description', 'category', 'subcategory', 'terms_of_service', 'privacy_policy', 'copyright_confirmation'],
16366
- optional: ['apple_team_id', 'contact_email', 'region', 'min_sdk_version'],
16379
+ required: [],
16380
+ optional: [],
16367
16381
  suppliedByCli: ['app_name', 'icon_uri'],
16382
+ additionalMetadataSource: 'platform-defaults',
16383
+ requestFromUser: false,
16384
+ legacyFileOption: '--app-info',
16385
+ legacyFileOptionRecommended: false,
16368
16386
  },
16369
16387
  appInfoPreflight: {
16370
16388
  titleMaxCharacters: 30,
@@ -17126,7 +17144,7 @@ withVerboseOption(program
17126
17144
  // Vibe v2 backend selection (including opt-in ppe-mock) stays outside the Skill workflow.
17127
17145
  .option('--title <title>', t('cli.command.upload.vibeTitle'))
17128
17146
  .option('--icon <path>', t('cli.command.upload.vibeIcon'))
17129
- .option('--app-info <path>', t('cli.command.upload.vibeAppInfo'))
17147
+ .addOption(new commander.Option('--app-info <path>', t('cli.command.upload.vibeAppInfo')).hideHelp())
17130
17148
  .option('--package <path>', t('cli.command.upload.vibePackage'))
17131
17149
  .option('--dry-run', t('cli.command.upload.vibeDryRun'))
17132
17150
  .option('--mock', t('cli.command.upload.vibeMock'))
@@ -17576,13 +17594,6 @@ else {
17576
17594
  program.parse(process.argv);
17577
17595
  }
17578
17596
 
17579
- class VibeError extends Error {
17580
- constructor(code) {
17581
- super(code);
17582
- this.code = code;
17583
- }
17584
- }
17585
-
17586
17597
  // Only the backend-owned authorization page can be a browser redirect target.
17587
17598
  // Never return its import_token to Skill stdout or put it in a CLI argument.
17588
17599
  function browserLandingUrl(value) {
@@ -17694,7 +17705,7 @@ var authOpen = /*#__PURE__*/Object.freeze({
17694
17705
  vibeAuthOpen: vibeAuthOpen
17695
17706
  });
17696
17707
 
17697
- // BFF IDL: feat-minis-import. PPE task creation/polling only; no production adapter.
17708
+ // BFF IDL: feat-minis-import. PPE import flow; no production adapter.
17698
17709
  const prefix = '/bff/app_info/minis_import/';
17699
17710
  const MINIS_IMPORT_PATHS = {
17700
17711
  create: `${prefix}create_minis_import_task_for_agent/`,
@@ -17862,15 +17873,9 @@ function createPpeBackend(lane, adapter) {
17862
17873
  'x-use-ppe': '1',
17863
17874
  'x-tt-env': lane,
17864
17875
  }, adapter);
17865
- const uploadUnavailable = async () => {
17866
- throw new VibeError('VIBE_REAL_UPLOAD_NOT_READY');
17867
- };
17868
17876
  return {
17869
17877
  ...backend,
17870
- uploadAvailable: false,
17871
- uploadIcon: uploadUnavailable,
17872
- submitInfo: uploadUnavailable,
17873
- uploadPackage: uploadUnavailable,
17878
+ uploadAvailable: true,
17874
17879
  };
17875
17880
  }
17876
17881
  /** Opt-in integration demo: only creation and polling can reach PPE. */
@@ -17894,6 +17899,7 @@ function createPpeMockBackend(lane, adapter, scenario = 'success') {
17894
17899
  return {
17895
17900
  mode: 'ppe-mock',
17896
17901
  uploadAvailable: true,
17902
+ dispose: () => real.dispose?.(),
17897
17903
  async createTask(input, signal) {
17898
17904
  if (realTask)
17899
17905
  throw new VibeError('VIBE_TASK_NOT_ACCEPTING_INPUT');
@@ -17925,14 +17931,20 @@ function createPpeMockBackend(lane, adapter, scenario = 'success') {
17925
17931
  };
17926
17932
  }
17927
17933
  function createHttpBackend(mode, baseURL, environmentHeaders = {}, adapter) {
17934
+ // Own the agents so an early multipart response cannot leave upload sockets
17935
+ // keeping the CLI alive after its terminal result. Never destroy global agents.
17936
+ const httpAgent = new http.Agent();
17937
+ const httpsAgent = new https.Agent();
17928
17938
  const client = axios.create({
17929
17939
  baseURL,
17930
17940
  timeout: 30000,
17931
17941
  maxRedirects: 0,
17932
17942
  proxy: false,
17933
17943
  adapter,
17944
+ httpAgent,
17945
+ httpsAgent,
17934
17946
  });
17935
- return createBackend(mode, async (request) => {
17947
+ const backend = createBackend(mode, async (request) => {
17936
17948
  try {
17937
17949
  let body;
17938
17950
  let headers = {};
@@ -17971,6 +17983,13 @@ function createHttpBackend(mode, baseURL, environmentHeaders = {}, adapter) {
17971
17983
  : 'VIBE_BACKEND_REQUEST_FAILED');
17972
17984
  }
17973
17985
  });
17986
+ return {
17987
+ ...backend,
17988
+ dispose() {
17989
+ httpAgent.destroy();
17990
+ httpsAgent.destroy();
17991
+ },
17992
+ };
17974
17993
  }
17975
17994
  const MOCK_SCENARIOS = [
17976
17995
  'success',
@@ -18837,6 +18856,7 @@ async function executeVibeUpload(options, onEvent = () => { }, dependencies = {}
18837
18856
  let timeout;
18838
18857
  let timedOut = false;
18839
18858
  let page;
18859
+ let backend = deps.backend;
18840
18860
  let detached = false;
18841
18861
  let progressUpdates = Promise.resolve();
18842
18862
  let ppeLane;
@@ -18846,6 +18866,7 @@ async function executeVibeUpload(options, onEvent = () => { }, dependencies = {}
18846
18866
  schemaVersion: '2',
18847
18867
  command: 'upload',
18848
18868
  mode: 'vibe',
18869
+ inputRequirements: VIBE_INPUT_REQUIREMENTS,
18849
18870
  operationId: `vibe_${crypto.randomUUID()}`,
18850
18871
  ts: Date.now(),
18851
18872
  status: 'precheck',
@@ -18926,7 +18947,6 @@ async function executeVibeUpload(options, onEvent = () => { }, dependencies = {}
18926
18947
  timedOut = true;
18927
18948
  controller.abort();
18928
18949
  }, timeoutMs);
18929
- let backend = deps.backend;
18930
18950
  if (!options.dryRun && !backend) {
18931
18951
  if (options.mock)
18932
18952
  backend = deps.createTrialBackend(options.mockScenario);
@@ -19159,8 +19179,8 @@ async function executeVibeUpload(options, onEvent = () => { }, dependencies = {}
19159
19179
  VIBE_TITLE_REQUIRED: ['请提供游戏名称。', 'Provide a game title.'],
19160
19180
  VIBE_TITLE_TOO_LONG: ['游戏名称不能超过 30 个字符。', 'The game title must not exceed 30 characters.'],
19161
19181
  VIBE_INVALID_APP_INFO: [
19162
- '请检查 --app-info JSON:需要简介、分类、子分类、有效的条款及隐私链接、明确的版权确认;不要填写任务凭据、名称或头像 URI。',
19163
- 'Check --app-info JSON: description, category, subcategory, valid terms/privacy URLs and explicit copyright confirmation are required. Do not include credentials, app_name or icon_uri.',
19182
+ ' --app-info 文件无效。当前上传只需标题和头像,其他资料由平台默认处理;移除 --app-info 后重试,不要向用户索要额外资料。',
19183
+ 'Invalid legacy --app-info file. Current uploads need only title and icon; the platform defaults other metadata. Remove --app-info and retry without requesting extra fields from the user.',
19164
19184
  ],
19165
19185
  VIBE_PLATFORM_ICON_INVALID: [
19166
19186
  '平台头像要求 PNG/JPEG、1024×1024,且不超过 5 MiB,请重新选择本地图片。',
@@ -19265,6 +19285,7 @@ async function executeVibeUpload(options, onEvent = () => { }, dependencies = {}
19265
19285
  finally {
19266
19286
  clearTimeout(timeout);
19267
19287
  externalSignal?.removeEventListener('abort', cancel);
19288
+ backend?.dispose?.();
19268
19289
  if (page && !detached)
19269
19290
  page.close();
19270
19291
  }