@ttmg/cli 0.4.6-vibe-beta.11 → 0.4.6-vibe-beta.13

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
@@ -9,8 +9,21 @@ Vibe real web authorization and upload: use `--web` with the title, local icon a
9
9
 
10
10
  #### Installation 安装
11
11
 
12
- For Agent, Monetization and Vibe Coding workflows, install the published beta:
13
- Agent、商业化和 Vibe Coding 流程请安装已发布的 beta 版本:
12
+ For Vibe Web authorization and upload, install the `vibe-beta` release:
13
+ Vibe 网页授权上传安装 `vibe-beta` 版本:
14
+
15
+ ```bash
16
+ npm install -g @ttmg/cli@vibe-beta
17
+ ttmg --version
18
+ ttmg capabilities --format json
19
+ ttmg upload --help
20
+ ```
21
+
22
+ The package includes [vibe-upload.md](vibe-upload.md). Keep the Web upload process running during authorization and read NDJSON until a terminal event. The `beta` and `vibe-beta` tags point to different published versions.
23
+ 安装包包含 [vibe-upload.md](vibe-upload.md)。授权期间保持原 Web 上传进程运行,持续读取 NDJSON,直到收到终态。`beta` 与 `vibe-beta` 指向不同发布版本。
24
+
25
+ For Agent and Monetization workflows, the published beta is:
26
+ Agent、商业化流程的已发布 beta 为:
14
27
 
15
28
  ```bash
16
29
  npm install -g @ttmg/cli@0.4.6-agent-beta.2
@@ -55,14 +68,10 @@ Keep the upload process running; this command creates no task and reports only
55
68
  Skill 如需手动打开网页授权,读取上传进程 `waiting_authorization` 事件的 `pageUrl`,
56
69
  执行 `ttmg auth open --page-url <pageUrl> --format json`。保持原上传进程运行;
57
70
  新命令在 CLI 所在电脑打开系统浏览器,不新建任务,`open_requested` 不代表授权成功。
58
- 该功能需使用包含新命令的本地构建;已发布旧版不会因此自动增加命令。
71
+ `--web` 已自动打开授权页;上述辅助命令只用于重新打开同一任务的授权页。
59
72
 
60
- The experimental `upload --vibe` local prototype does not require platform login.
61
- Use `ttmg upload --vibe --mock` for the integration trial. No environment setup:
62
- task creation/polling use the built-in PPE lane; authorization and uploads are
63
- simulated. See [Vibe binding/upload](vibe-upload.md) for schema-v2 results.
64
- 实验性 `upload --vibe --mock` 不要求平台登录或环境配置。CLI 内置 PPE 创建/查询任务,
65
- 模拟授权和上传;本次结束于模拟上传完成,不含预览和发布。详见 [Vibe 绑定上传](vibe-upload.md)。
73
+ `ttmg upload --vibe --web` uses real browser authorization and uploads to PPE without a prior platform login or environment setup. `--mock` is a separate demo: task creation/polling are real, but authorization and material uploads are simulated. See [Vibe binding/upload](vibe-upload.md) for schema-v2 results.
74
+ `ttmg upload --vibe --web` 无需预先平台登录或配置环境,使用真实浏览器授权并上传到 PPE。`--mock` 是独立演示:真实创建/查询任务,模拟授权和素材上传。详见 [Vibe 绑定上传](vibe-upload.md)。
66
75
 
67
76
  `--mock` 现在会真实创建 PPE 任务,不再表示全程离线;真实请求失败仍报错。
68
77
  上线时由 CLI 发布版本去掉 PPE 路由,Skill 无需承担环境切换。
@@ -72,8 +81,8 @@ still fail. Production routing is a future CLI release change, not Skill configu
72
81
  当前上传只需要标题、头像和游戏目录或代码包,其他应用资料由 CLI 使用既有 PPE 试用默认值补齐。Skill 读取 `inputRequirements`,不向用户索要额外资料;本地预检使用 `--dry-run`。
73
82
  Current uploads need only the title, icon and game directory or ZIP. The CLI fills other metadata with existing PPE trial defaults. Read `inputRequirements` and do not request extra fields. Use `--dry-run` for local preparation.
74
83
 
75
- For the existing authenticated platform workflow, log in first; this does not apply to the local Vibe prototype above.
76
- 原有需要平台鉴权的流程仍先登录;上述 Vibe 本地原型不需要此步骤。
84
+ For the existing authenticated platform workflow, log in first; Vibe Web upload uses its own browser authorization.
85
+ 原有需要平台鉴权的流程仍先登录;Vibe Web 上传使用本次任务的浏览器授权。
77
86
 
78
87
  ```
79
88
  ttmg login
package/dist/index.js CHANGED
@@ -7233,6 +7233,18 @@ const messages = {
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
7235
  'cli.command.upload.vibeWeb': 'Authorize in the browser, then upload to PPE (--vibe; no Mock or --no-open)',
7236
+ 'cli.command.upload.vibeWebGuide': `
7237
+ Vibe web upload (real PPE trial):
7238
+ ttmg upload --vibe --web --dir ./game --title "My game" --icon ./avatar.png --format ndjson
7239
+ Use --package ./game.zip instead of --dir for an existing ZIP.
7240
+ Collect only title and icon; the CLI fills other app_info fields with PPE trial defaults.
7241
+ Keep this process running. At waiting_authorization, complete authorization in the system browser on the CLI computer.
7242
+ pageUrl is the local binding/progress page. To reopen authorization, execute the returned authorizationOpenCommand.
7243
+ The CLI polls and uploads avatar, app_info and package automatically after authorization. Do not start a second upload.
7244
+ Real success: terminal=true, status=uploaded, uploaded=true, simulation=false. On failure, read errorCode and nextAction.
7245
+ --web opens the browser for every output format. --mock is a separate simulation mode.
7246
+ Upload completion is not review approval or production release. See bundled vibe-upload.md and ttmg capabilities --format json.
7247
+ `,
7236
7248
  'cli.command.auth.open.pageUrl': 'Local pageUrl returned by the running Vibe upload command',
7237
7249
  'cli.command.auth.open.requested': 'Browser open requested. Complete authorization there; the existing upload process continues polling.',
7238
7250
  'cli.command.auth.open.invalidPage': 'Pass the local pageUrl from the running Vibe upload command, not the platform URL.',
@@ -7646,6 +7658,18 @@ const messages = {
7646
7658
  'cli.command.auth.desc': '查看本地登录状态',
7647
7659
  'cli.command.auth.open.desc': '在系统浏览器打开已有 Vibe 任务的授权页',
7648
7660
  'cli.command.upload.vibeWeb': '网页授权就绪后自动上传到 PPE(--vibe;不能与 Mock 或 --no-open 同用)',
7661
+ 'cli.command.upload.vibeWebGuide': `
7662
+ Vibe 网页上传(真实 PPE 试用):
7663
+ ttmg upload --vibe --web --dir ./game --title "游戏名称" --icon ./avatar.png --format ndjson
7664
+ 已有 ZIP 时,用 --package ./game.zip 替换 --dir。
7665
+ 只收集标题和头像;其他 app_info 字段由 CLI 使用 PPE 试用默认值补齐。
7666
+ 保持原进程运行。在 waiting_authorization 阶段,在 CLI 所在电脑的系统浏览器完成授权。
7667
+ pageUrl 是本机绑定/进度页;重新打开授权页时,执行返回的 authorizationOpenCommand。
7668
+ CLI 负责轮询,授权后自动上传 avatar、app_info、package,不再启动第二次上传。
7669
+ 真实成功:terminal=true、status=uploaded、uploaded=true、simulation=false。失败时读取 errorCode 和 nextAction。
7670
+ --web 在所有输出格式下都会打开浏览器;--mock 是独立的模拟模式。
7671
+ 上传完成不代表审核通过或正式上线。详见包内 vibe-upload.md 和 ttmg capabilities --format json。
7672
+ `,
7649
7673
  'cli.command.auth.open.pageUrl': '正在运行的 Vibe 上传命令返回的本地 pageUrl',
7650
7674
  'cli.command.auth.open.requested': '已请求浏览器打开授权页。请在页面完成授权,原上传进程继续轮询。',
7651
7675
  'cli.command.auth.open.invalidPage': '请传入正在运行的 Vibe 上传命令返回的本地 pageUrl,不是平台授权链接。',
@@ -16308,7 +16332,7 @@ async function authStatus(options = {}) {
16308
16332
  return result;
16309
16333
  }
16310
16334
 
16311
- var version = "0.4.6-vibe-beta.11";
16335
+ var version = "0.4.6-vibe-beta.13";
16312
16336
  var engines = {
16313
16337
  node: ">=20.19.1 <21 || >=22"
16314
16338
  };
@@ -16332,6 +16356,113 @@ class VibeError extends Error {
16332
16356
  }
16333
16357
  }
16334
16358
 
16359
+ // Current PPE trial defaults: the owner-approved metadata used by the successful
16360
+ // real upload fixture on 2026-09-14, with owner-specified legal URLs updated on
16361
+ // 2026-09-15. This is not a production metadata profile.
16362
+ const VIBE_PPE_DEFAULT_APP_INFO = Object.freeze({
16363
+ description: 'DevTool PPE integration test fixture. Not a production game.',
16364
+ category: 'Other',
16365
+ subcategory: 'Other',
16366
+ terms_of_service: 'https://www.tiktok.com',
16367
+ privacy_policy: 'https://www.tiktok.com',
16368
+ copyright_confirmation: true,
16369
+ contact_email: 'devtool-test@example.invalid',
16370
+ });
16371
+ // BFF IDL + Import Service ValidateAppInfo, feat-minis-import (2026-09-14).
16372
+ // Keep credentials, app_name and icon_uri out of this file: CLI owns those fields.
16373
+ const requiredStrings = [
16374
+ 'description', 'category', 'subcategory', 'terms_of_service', 'privacy_policy',
16375
+ ];
16376
+ const optionalStrings = ['apple_team_id', 'contact_email', 'region', 'min_sdk_version'];
16377
+ function readVibeAppInfo(file) {
16378
+ if (file === undefined)
16379
+ return undefined;
16380
+ try {
16381
+ const stat = fs.statSync(file);
16382
+ if (!stat.isFile() || stat.size > 64 * 1024)
16383
+ throw new Error();
16384
+ const value = JSON.parse(fs.readFileSync(file, 'utf8'));
16385
+ if (!value || typeof value !== 'object' || Array.isArray(value))
16386
+ throw new Error();
16387
+ const allowed = new Set([...requiredStrings, ...optionalStrings, 'copyright_confirmation']);
16388
+ if (Object.keys(value).some(key => !allowed.has(key)))
16389
+ throw new Error();
16390
+ // JSON can encode lone surrogates that Go rejects as invalid UTF-8 input.
16391
+ for (const item of Object.values(value)) {
16392
+ if (typeof item === 'string' && [...item].some(char => /^[\uD800-\uDFFF]$/.test(char)))
16393
+ throw new Error();
16394
+ }
16395
+ for (const key of requiredStrings) {
16396
+ if (typeof value[key] !== 'string' || !value[key].trim())
16397
+ throw new Error();
16398
+ }
16399
+ for (const key of optionalStrings) {
16400
+ if (value[key] !== undefined && (typeof value[key] !== 'string' || !value[key].trim()))
16401
+ throw new Error();
16402
+ }
16403
+ // An explicit declaration is required; never infer consent or supply a default.
16404
+ if (value.copyright_confirmation !== true)
16405
+ throw new Error();
16406
+ for (const key of ['terms_of_service', 'privacy_policy']) {
16407
+ if (/\s/.test(value[key]))
16408
+ throw new Error();
16409
+ const url = new URL(value[key]);
16410
+ if (!['http:', 'https:'].includes(url.protocol) || !url.hostname || url.username || url.password)
16411
+ throw new Error();
16412
+ }
16413
+ if (value.contact_email !== undefined && !/^[^\s<>@]+@[^\s<>@]+$/.test(value.contact_email))
16414
+ throw new Error();
16415
+ return value;
16416
+ }
16417
+ catch {
16418
+ // Do not expose paths, file contents or parser errors in structured output.
16419
+ throw new VibeError('VIBE_INVALID_APP_INFO');
16420
+ }
16421
+ }
16422
+ const VIBE_PLATFORM_ICON_LIMIT = 5 * 1024 * 1024;
16423
+ // Header preflight only. The BFF remains responsible for decoding the image.
16424
+ function validateVibeUploadInput(input) {
16425
+ if ([...input.title].length > 30)
16426
+ throw new VibeError('VIBE_TITLE_TOO_LONG');
16427
+ const image = input.icon.bytes;
16428
+ if (image.length > VIBE_PLATFORM_ICON_LIMIT)
16429
+ throw new VibeError('VIBE_PLATFORM_ICON_INVALID');
16430
+ let width = 0, height = 0;
16431
+ if (image.length >= 33 && image.subarray(0, 8).equals(Buffer.from('89504e470d0a1a0a', 'hex')) &&
16432
+ image.readUInt32BE(8) === 13 && image.toString('ascii', 12, 16) === 'IHDR') {
16433
+ width = image.readUInt32BE(16);
16434
+ height = image.readUInt32BE(20);
16435
+ }
16436
+ else if (image[0] === 0xff && image[1] === 0xd8) {
16437
+ let offset = 2;
16438
+ while (offset + 4 <= image.length) {
16439
+ if (image[offset++] !== 0xff)
16440
+ break;
16441
+ while (image[offset] === 0xff)
16442
+ offset++;
16443
+ const marker = image[offset++];
16444
+ if (marker === 0xda || marker === 0xd9)
16445
+ break;
16446
+ if (marker === 0x01 || (marker >= 0xd0 && marker <= 0xd7))
16447
+ continue;
16448
+ if (offset + 2 > image.length)
16449
+ break;
16450
+ const length = image.readUInt16BE(offset);
16451
+ if (length < 2 || offset + length > image.length)
16452
+ break;
16453
+ // Go image/jpeg accepts baseline, extended sequential and progressive SOF.
16454
+ if ([0xc0, 0xc1, 0xc2].includes(marker) && length >= 8) {
16455
+ height = image.readUInt16BE(offset + 3);
16456
+ width = image.readUInt16BE(offset + 5);
16457
+ break;
16458
+ }
16459
+ offset += length;
16460
+ }
16461
+ }
16462
+ if (width !== 1024 || height !== 1024)
16463
+ throw new VibeError('VIBE_PLATFORM_ICON_INVALID');
16464
+ }
16465
+
16335
16466
  function getCapabilities() {
16336
16467
  return {
16337
16468
  schemaVersion: '1',
@@ -16344,7 +16475,9 @@ function getCapabilities() {
16344
16475
  },
16345
16476
  commands: {
16346
16477
  vibeUpload: {
16347
- command: 'ttmg upload --vibe --mock --format ndjson',
16478
+ command: 'ttmg upload --vibe --web --dir <gameDir> --title <title> --icon <iconPath> --format ndjson',
16479
+ mockCommand: 'ttmg upload --vibe --mock --dir <gameDir> --title <title> --icon <iconPath> --format ndjson',
16480
+ guide: 'vibe-upload.md',
16348
16481
  option: '--vibe',
16349
16482
  available: true,
16350
16483
  platformWrite: true,
@@ -16375,11 +16508,32 @@ function getCapabilities() {
16375
16508
  metadataInputs: ['title', 'icon', 'dir|package'],
16376
16509
  inputRequirements: VIBE_INPUT_REQUIREMENTS,
16377
16510
  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 },
16511
+ skillWorkflow: {
16512
+ preferredFormat: 'ndjson',
16513
+ packageAlternative: '--package <zipPath> replaces --dir <gameDir>',
16514
+ keepUploadProcessRunning: true,
16515
+ pollingOwner: 'cli',
16516
+ uploadOwner: 'cli',
16517
+ waitingAuthorization: {
16518
+ status: 'waiting_authorization',
16519
+ userAction: 'complete authorization in the system browser on the CLI computer',
16520
+ pageUrlField: 'pageUrl',
16521
+ pageUrlPurpose: 'local binding and upload progress page',
16522
+ reopenCommandField: 'authorizationOpenCommand',
16523
+ browserOpenRequestedProvesAuthorization: false,
16524
+ createAnotherUploadTask: false,
16525
+ },
16526
+ realUploadSuccess: { terminal: true, status: 'uploaded', uploaded: true, simulation: false },
16527
+ failure: 'Read errorCode and nextAction; do not automatically create another task or reupload',
16528
+ completionMeaning: 'materials uploaded to PPE; review and production release are separate',
16529
+ sameHostRequired: true,
16530
+ },
16378
16531
  optionalMetadataFile: '--app-info',
16379
16532
  appInfoFields: {
16380
16533
  required: [],
16381
16534
  optional: [],
16382
16535
  suppliedByCli: ['app_name', 'icon_uri'],
16536
+ defaultedByCli: Object.keys(VIBE_PPE_DEFAULT_APP_INFO),
16383
16537
  additionalMetadataSource: 'cli-defaults',
16384
16538
  defaultMetadataProfile: 'ppe-trial',
16385
16539
  requestFromUser: false,
@@ -16410,8 +16564,9 @@ function getCapabilities() {
16410
16564
  httpContract: 'minis-import-task',
16411
16565
  authorizationQr: true,
16412
16566
  previewQr: false,
16413
- realAuthorizationVerified: false,
16414
- realUploadVerified: false,
16567
+ realAuthorizationVerified: true,
16568
+ realUploadVerified: true,
16569
+ verificationScope: { backend: 'ppe', assets: 'test-fixtures', date: '2026-09-15', production: false },
16415
16570
  autoUploadAfterAuthorization: true,
16416
16571
  boundedPolling: true,
16417
16572
  cancellation: true,
@@ -17155,7 +17310,8 @@ withVerboseOption(program
17155
17310
  .option('--vibe-authorize-url <url>', t('cli.command.upload.vibeAuthorizeUrl'))
17156
17311
  .option('--poll-interval <seconds>', t('cli.command.upload.vibePollInterval'))
17157
17312
  .option('--timeout <seconds>', t('cli.command.upload.vibeTimeout'))
17158
- .option('--format <format>', t('cli.command.upload.format'), 'text')).action(async (cmd) => {
17313
+ .option('--format <format>', t('cli.command.upload.format'), 'text')
17314
+ .addHelpText('after', t('cli.command.upload.vibeWebGuide'))).action(async (cmd) => {
17159
17315
  if (cmd.vibe) {
17160
17316
  const { vibeUpload } = await Promise.resolve().then(function () { return index$1; });
17161
17317
  await vibeUpload(cmd);
@@ -17707,112 +17863,6 @@ var authOpen = /*#__PURE__*/Object.freeze({
17707
17863
  vibeAuthOpen: vibeAuthOpen
17708
17864
  });
17709
17865
 
17710
- // Current PPE trial defaults: the owner-approved metadata used by the successful
17711
- // real upload fixture on 2026-09-14. This is not a production metadata profile.
17712
- const VIBE_PPE_DEFAULT_APP_INFO = Object.freeze({
17713
- description: 'DevTool PPE integration test fixture. Not a production game.',
17714
- category: 'Other',
17715
- subcategory: 'Other',
17716
- terms_of_service: 'https://example.invalid/devtool-ppe-test/terms',
17717
- privacy_policy: 'https://example.invalid/devtool-ppe-test/privacy',
17718
- copyright_confirmation: true,
17719
- contact_email: 'devtool-test@example.invalid',
17720
- });
17721
- // BFF IDL + Import Service ValidateAppInfo, feat-minis-import (2026-09-14).
17722
- // Keep credentials, app_name and icon_uri out of this file: CLI owns those fields.
17723
- const requiredStrings = [
17724
- 'description', 'category', 'subcategory', 'terms_of_service', 'privacy_policy',
17725
- ];
17726
- const optionalStrings = ['apple_team_id', 'contact_email', 'region', 'min_sdk_version'];
17727
- function readVibeAppInfo(file) {
17728
- if (file === undefined)
17729
- return undefined;
17730
- try {
17731
- const stat = fs.statSync(file);
17732
- if (!stat.isFile() || stat.size > 64 * 1024)
17733
- throw new Error();
17734
- const value = JSON.parse(fs.readFileSync(file, 'utf8'));
17735
- if (!value || typeof value !== 'object' || Array.isArray(value))
17736
- throw new Error();
17737
- const allowed = new Set([...requiredStrings, ...optionalStrings, 'copyright_confirmation']);
17738
- if (Object.keys(value).some(key => !allowed.has(key)))
17739
- throw new Error();
17740
- // JSON can encode lone surrogates that Go rejects as invalid UTF-8 input.
17741
- for (const item of Object.values(value)) {
17742
- if (typeof item === 'string' && [...item].some(char => /^[\uD800-\uDFFF]$/.test(char)))
17743
- throw new Error();
17744
- }
17745
- for (const key of requiredStrings) {
17746
- if (typeof value[key] !== 'string' || !value[key].trim())
17747
- throw new Error();
17748
- }
17749
- for (const key of optionalStrings) {
17750
- if (value[key] !== undefined && (typeof value[key] !== 'string' || !value[key].trim()))
17751
- throw new Error();
17752
- }
17753
- // An explicit declaration is required; never infer consent or supply a default.
17754
- if (value.copyright_confirmation !== true)
17755
- throw new Error();
17756
- for (const key of ['terms_of_service', 'privacy_policy']) {
17757
- if (/\s/.test(value[key]))
17758
- throw new Error();
17759
- const url = new URL(value[key]);
17760
- if (!['http:', 'https:'].includes(url.protocol) || !url.hostname || url.username || url.password)
17761
- throw new Error();
17762
- }
17763
- if (value.contact_email !== undefined && !/^[^\s<>@]+@[^\s<>@]+$/.test(value.contact_email))
17764
- throw new Error();
17765
- return value;
17766
- }
17767
- catch {
17768
- // Do not expose paths, file contents or parser errors in structured output.
17769
- throw new VibeError('VIBE_INVALID_APP_INFO');
17770
- }
17771
- }
17772
- const VIBE_PLATFORM_ICON_LIMIT = 5 * 1024 * 1024;
17773
- // Header preflight only. The BFF remains responsible for decoding the image.
17774
- function validateVibeUploadInput(input) {
17775
- if ([...input.title].length > 30)
17776
- throw new VibeError('VIBE_TITLE_TOO_LONG');
17777
- const image = input.icon.bytes;
17778
- if (image.length > VIBE_PLATFORM_ICON_LIMIT)
17779
- throw new VibeError('VIBE_PLATFORM_ICON_INVALID');
17780
- let width = 0, height = 0;
17781
- if (image.length >= 33 && image.subarray(0, 8).equals(Buffer.from('89504e470d0a1a0a', 'hex')) &&
17782
- image.readUInt32BE(8) === 13 && image.toString('ascii', 12, 16) === 'IHDR') {
17783
- width = image.readUInt32BE(16);
17784
- height = image.readUInt32BE(20);
17785
- }
17786
- else if (image[0] === 0xff && image[1] === 0xd8) {
17787
- let offset = 2;
17788
- while (offset + 4 <= image.length) {
17789
- if (image[offset++] !== 0xff)
17790
- break;
17791
- while (image[offset] === 0xff)
17792
- offset++;
17793
- const marker = image[offset++];
17794
- if (marker === 0xda || marker === 0xd9)
17795
- break;
17796
- if (marker === 0x01 || (marker >= 0xd0 && marker <= 0xd7))
17797
- continue;
17798
- if (offset + 2 > image.length)
17799
- break;
17800
- const length = image.readUInt16BE(offset);
17801
- if (length < 2 || offset + length > image.length)
17802
- break;
17803
- // Go image/jpeg accepts baseline, extended sequential and progressive SOF.
17804
- if ([0xc0, 0xc1, 0xc2].includes(marker) && length >= 8) {
17805
- height = image.readUInt16BE(offset + 3);
17806
- width = image.readUInt16BE(offset + 5);
17807
- break;
17808
- }
17809
- offset += length;
17810
- }
17811
- }
17812
- if (width !== 1024 || height !== 1024)
17813
- throw new VibeError('VIBE_PLATFORM_ICON_INVALID');
17814
- }
17815
-
17816
17866
  // BFF IDL: feat-minis-import. PPE import flow; no production adapter.
17817
17867
  const prefix = '/bff/app_info/minis_import/';
17818
17868
  const MINIS_IMPORT_PATHS = {