siluzan-tso-cli 1.0.0-beta.21 → 1.0.0-beta.22

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
@@ -20,7 +20,7 @@ siluzan-tso init -d /path/to/skills # 写入自定义目录
20
20
  siluzan-tso init --force # 强制覆盖已存在文件
21
21
  ```
22
22
 
23
- > **注意**:当前为测试版(1.0.0-beta.21),供内部测试使用。正式发布后安装命令将改为 `npm install -g siluzan-tso-cli`。
23
+ > **注意**:当前为测试版(1.0.0-beta.22),供内部测试使用。正式发布后安装命令将改为 `npm install -g siluzan-tso-cli`。
24
24
 
25
25
  | 助手 | 建议 `--ai` |
26
26
  |------|-------------|
package/dist/index.js CHANGED
@@ -576,8 +576,7 @@ function writeConfigRaw(data) {
576
576
  } catch {
577
577
  }
578
578
  }
579
- async function fetchVersionByTag(tag, cfg) {
580
- const cacheKey = tag === "beta" ? "_tsoLatestBeta" : "_tsoLatestStable";
579
+ async function fetchVersionByTag(tag, cacheKey, cfg) {
581
580
  const hours24 = 24 * 60 * 60 * 1e3;
582
581
  if (cfg._tsoLastVersionCheck && cfg[cacheKey]) {
583
582
  const lastCheck = new Date(cfg._tsoLastVersionCheck).getTime();
@@ -591,22 +590,42 @@ async function notifyIfOutdated() {
591
590
  try {
592
591
  const current = getCurrentVersion2();
593
592
  const tag = npmDistTagForCurrentVersion(current);
593
+ const isBeta = tag === "beta";
594
+ const latestCacheKey = isBeta ? "_tsoLatestBeta" : "_tsoLatestStable";
595
+ const minCacheKey = isBeta ? "_tsoMinRequiredBeta" : "_tsoMinRequiredStable";
596
+ const minTag = isBeta ? "min-required-beta" : "min-required";
594
597
  const cfg = readConfigRaw();
595
- const latest = await fetchVersionByTag(tag, cfg);
596
- if (!latest) return;
597
- const cacheKey = tag === "beta" ? "_tsoLatestBeta" : "_tsoLatestStable";
598
+ const [latest, minRequired] = await Promise.all([
599
+ fetchVersionByTag(tag, latestCacheKey, cfg),
600
+ fetchVersionByTag(minTag, minCacheKey, cfg)
601
+ ]);
598
602
  writeConfigRaw({
599
603
  ...cfg,
600
604
  _tsoLastVersionCheck: (/* @__PURE__ */ new Date()).toISOString(),
601
- [cacheKey]: latest
605
+ ...latest ? { [latestCacheKey]: latest } : {},
606
+ ...minRequired ? { [minCacheKey]: minRequired } : {}
602
607
  });
603
- if (isNewer(current, latest)) {
604
- const tagLabel = tag === "beta" ? "\uFF08\u6D4B\u8BD5\u7248\uFF09" : "\uFF08\u6B63\u5F0F\u7248\uFF09";
605
- console.error(
608
+ const lastNotified = cfg._tsoLastNotified ? new Date(cfg._tsoLastNotified).getTime() : 0;
609
+ if (Date.now() - lastNotified < 24 * 60 * 60 * 1e3) return;
610
+ const tagLabel = isBeta ? "\uFF08\u6D4B\u8BD5\u7248\uFF09" : "\uFF08\u6B63\u5F0F\u7248\uFF09";
611
+ if (minRequired && isNewer(current, minRequired)) {
612
+ writeConfigRaw({ ...cfg, _tsoLastNotified: (/* @__PURE__ */ new Date()).toISOString() });
613
+ console.log(
614
+ `
615
+ [SILUZAN_FORCE_UPDATE] \u5F53\u524D\u7248\u672C ${current} \u5DF2\u8FC7\u671F\uFF0C\u6700\u4F4E\u8981\u6C42\u7248\u672C ${minRequired}${tagLabel}
616
+ \u26D4 \u5FC5\u987B\u5148\u5347\u7EA7\u624D\u80FD\u7EE7\u7EED\u4F7F\u7528\uFF0CAgent \u8BF7\u7ACB\u5373\u6267\u884C\uFF1Asiluzan-tso update
617
+ \u6216\u624B\u52A8\uFF1Anpm install -g ${PKG_NAME}@${tag}
618
+ `
619
+ );
620
+ return;
621
+ }
622
+ if (latest && isNewer(current, latest)) {
623
+ writeConfigRaw({ ...cfg, _tsoLastNotified: (/* @__PURE__ */ new Date()).toISOString() });
624
+ console.log(
606
625
  `
607
- \u{1F4A1} \u53D1\u73B0\u65B0\u7248\u672C ${latest}${tagLabel}\uFF08\u5F53\u524D ${current}\uFF09\uFF0C\u53EF\u4EFB\u9009\u5176\u4E00\u5347\u7EA7\u5E76\u5237\u65B0 Skill\uFF1A
608
- siluzan-tso update
609
- npm install -g ${PKG_NAME}@${tag}
626
+ [SILUZAN_UPDATE_AVAILABLE] \u53D1\u73B0\u65B0\u7248\u672C ${latest}${tagLabel}\uFF08\u5F53\u524D ${current}\uFF09
627
+ \u{1F4A1} Agent \u8BF7\u7ACB\u5373\u6267\u884C\uFF1Asiluzan-tso update
628
+ \u6216\u624B\u52A8\uFF1Anpm install -g ${PKG_NAME}@${tag}
610
629
  `
611
630
  );
612
631
  }
@@ -6291,8 +6310,6 @@ async function resolveGoogleMediaAccountGroupId(config, opts) {
6291
6310
  }
6292
6311
  const company = opts.company.trim();
6293
6312
  const promotionLink = normalizePromotionLinkForGoogle(opts.promotionLink);
6294
- const level1 = (opts.industryLevel1 ?? "").trim();
6295
- const level2 = (opts.industryLevel2 ?? "").trim();
6296
6313
  let profile;
6297
6314
  try {
6298
6315
  profile = await apiFetch2(
@@ -6315,7 +6332,6 @@ async function resolveGoogleMediaAccountGroupId(config, opts) {
6315
6332
  const mediaAccountGroupPayload = {
6316
6333
  advertiserName: company,
6317
6334
  StorageProvider: storageFromGroup ?? "StorageAccount",
6318
- industry: { level1, level2 },
6319
6335
  promotionLink,
6320
6336
  promotionType: opts.promotionType
6321
6337
  };
@@ -6479,9 +6495,10 @@ async function runOpenAccountBing(opts) {
6479
6495
  opts.verbose,
6480
6496
  opts.advertiserId
6481
6497
  );
6498
+ const accountCount = Math.min(Math.max(opts.accountCount ?? 1, 1), 6);
6482
6499
  const body = {
6483
6500
  MediaAccountGroupId: magKey,
6484
- AccountCount: opts.accountCount ?? 1,
6501
+ AccountCount: accountCount,
6485
6502
  BingCustomerInfo: {
6486
6503
  name: opts.advertiserName,
6487
6504
  province: opts.province,
@@ -6808,18 +6825,14 @@ async function runOpenAccountGoogle(opts) {
6808
6825
  company: opts.company,
6809
6826
  promotionLink: opts.promotionLink,
6810
6827
  promotionType: opts.promotionType,
6811
- industryLevel1: opts.industryLevel1,
6812
- industryLevel2: opts.industryLevel2,
6813
6828
  verbose: opts.verbose
6814
6829
  });
6815
- const level1 = (opts.industryLevel1 ?? "").trim();
6816
- const level2 = (opts.industryLevel2 ?? "").trim();
6817
- const industryStr = level1 || level2 ? `${level1}-${level2}` : "";
6818
6830
  const promotionLinkNorm = normalizePromotionLinkForGoogle(opts.promotionLink);
6819
6831
  const body = {
6820
- accountInfo: Array.from({ length: counts }, () => ({
6832
+ accountInfo: Array.from({ length: counts }, (_, i) => ({
6821
6833
  advertiser_info: {
6822
- name: opts.accountName,
6834
+ // 多账户时在名称末尾追加 -1, -2 … 以便区分
6835
+ name: counts > 1 ? `${opts.accountName}-${i + 1}` : opts.accountName,
6823
6836
  currency: opts.currency,
6824
6837
  timezone: opts.timezone,
6825
6838
  accounttype: "Adwords",
@@ -6827,8 +6840,7 @@ async function runOpenAccountGoogle(opts) {
6827
6840
  inviteduserrole: opts.inviteRole ?? "Standard"
6828
6841
  },
6829
6842
  customer_info: {
6830
- company: opts.company.trim(),
6831
- industry: industryStr
6843
+ company: opts.company.trim()
6832
6844
  },
6833
6845
  qualification_info: {
6834
6846
  promotion_link: promotionLinkNorm,
@@ -6887,24 +6899,6 @@ async function uploadLicenseToTikTok(filePath, businessCentreType, config, verbo
6887
6899
  }
6888
6900
  return imageId;
6889
6901
  }
6890
- async function checkUnionpayRequired(licenseNo, company, businessCentreType, config, verbose) {
6891
- try {
6892
- const params = new URLSearchParams({
6893
- license_no: licenseNo,
6894
- company_name: company,
6895
- businessCentreType
6896
- });
6897
- const res = await apiFetch2(
6898
- `${config.apiBaseUrl}/query/media-account/tiktok/TikTokAdvQuery/CheckUnionpayInfo?${params}`,
6899
- config,
6900
- {},
6901
- verbose
6902
- );
6903
- return res?.data?.unionpay_verification_required === true;
6904
- } catch {
6905
- return false;
6906
- }
6907
- }
6908
6902
  async function runOpenAccountTikTok(opts) {
6909
6903
  const config = loadConfig(opts.token);
6910
6904
  const bcType = opts.businessCentreType ?? "Shop";
@@ -6914,7 +6908,7 @@ async function runOpenAccountTikTok(opts) {
6914
6908
  `);
6915
6909
  process.exit(1);
6916
6910
  }
6917
- console.log(" [1/4] \u6B63\u5728\u4E0A\u4F20\u8425\u4E1A\u6267\u7167\u5230 TikTok...");
6911
+ console.log(" [1/3] \u6B63\u5728\u4E0A\u4F20\u8425\u4E1A\u6267\u7167\u5230 TikTok...");
6918
6912
  let licenseImageId;
6919
6913
  try {
6920
6914
  licenseImageId = await uploadLicenseToTikTok(opts.licenseFile, bcType, config, opts.verbose);
@@ -6925,7 +6919,7 @@ async function runOpenAccountTikTok(opts) {
6925
6919
  process.exit(1);
6926
6920
  }
6927
6921
  console.log(` TikTok license_image_id: ${licenseImageId}`);
6928
- console.log(" [2/4] \u6B63\u5728\u4E0A\u4F20\u8425\u4E1A\u6267\u7167\u5230 Siluzan \u5B58\u6863...");
6922
+ console.log(" [2/3] \u6B63\u5728\u4E0A\u4F20\u8425\u4E1A\u6267\u7167\u5230 Siluzan \u5B58\u6863...");
6929
6923
  let siluzanImageId = "";
6930
6924
  try {
6931
6925
  const uploaded = await uploadAttachment(opts.licenseFile, config.apiBaseUrl, config, opts.verbose);
@@ -6934,7 +6928,7 @@ async function runOpenAccountTikTok(opts) {
6934
6928
  } catch (err) {
6935
6929
  console.warn(` \u26A0\uFE0F Siluzan \u5B58\u6863\u4E0A\u4F20\u5931\u8D25\uFF08\u4E0D\u5F71\u54CD\u5F00\u6237\uFF09\uFF1A${err instanceof Error ? err.message : String(err)}`);
6936
6930
  }
6937
- console.log(" [3/4] \u6B63\u5728\u5173\u8054\u5E7F\u544A\u4E3B\u7EC4...");
6931
+ console.log(" [3/3] \u6B63\u5728\u5173\u8054\u5E7F\u544A\u4E3B\u7EC4...");
6938
6932
  const magKey = await resolveGenericMagKey(
6939
6933
  config,
6940
6934
  opts.company,
@@ -6950,19 +6944,11 @@ async function runOpenAccountTikTok(opts) {
6950
6944
  opts.verbose,
6951
6945
  opts.advertiserId
6952
6946
  );
6953
- console.log(" [4/4] \u6B63\u5728\u68C0\u67E5\u6CD5\u4EBA\u9A8C\u8BC1\u8981\u6C42...");
6954
- const needUnionpay = await checkUnionpayRequired(opts.licenseNo, opts.company, bcType, config, opts.verbose);
6955
- if (needUnionpay && (!opts.representativeName || !opts.representativeId)) {
6956
- console.error(
6957
- "\n\u274C \u8BE5\u8425\u4E1A\u6267\u7167\u9700\u8981\u586B\u5199\u6CD5\u4EBA\u94F6\u8054\u9A8C\u8BC1\u4FE1\u606F\uFF0C\u8BF7\u8FFD\u52A0\u4EE5\u4E0B\u53C2\u6570\u518D\u91CD\u8BD5\uFF1A\n --representative-name <\u6CD5\u4EBA\u59D3\u540D>\n --representative-id <\u8EAB\u4EFD\u8BC1\u53F7>\n --unionpay-account <\u94F6\u8054\u8D26\u53F7>\n --representative-phone <\u624B\u673A\u53F7>\n"
6958
- );
6959
- process.exit(1);
6960
- }
6961
6947
  const counts = Math.min(Math.max(opts.counts ?? 1, 1), 10);
6962
6948
  const singleAccountInfo = {
6963
6949
  advertiser_info: {
6964
6950
  name: opts.accountName,
6965
- currency: opts.currency,
6951
+ currency: "USD",
6966
6952
  timezone: opts.timezone
6967
6953
  },
6968
6954
  customer_info: {
@@ -6974,18 +6960,23 @@ async function runOpenAccountTikTok(opts) {
6974
6960
  promotion_link: opts.promotionLink,
6975
6961
  license_no: opts.licenseNo,
6976
6962
  license_image_id: licenseImageId
6963
+ },
6964
+ representative_info: {
6965
+ representative_name: opts.representativeName,
6966
+ representative_id: opts.representativeId,
6967
+ unionpay_account: opts.unionpayAccount,
6968
+ representative_phone_number: opts.representativePhone
6977
6969
  }
6978
6970
  };
6979
- if (needUnionpay && opts.representativeName) {
6980
- singleAccountInfo.representative_info = {
6981
- representative_name: opts.representativeName,
6982
- representative_id: opts.representativeId ?? "",
6983
- unionpay_account: opts.unionpayAccount ?? "",
6984
- representative_phone_number: opts.representativePhone ?? ""
6985
- };
6986
- }
6987
6971
  const body = {
6988
- accountInfo: Array.from({ length: counts }, () => ({ ...singleAccountInfo })),
6972
+ accountInfo: Array.from({ length: counts }, (_, i) => ({
6973
+ ...singleAccountInfo,
6974
+ advertiser_info: {
6975
+ ...singleAccountInfo.advertiser_info,
6976
+ // 多账户时在名称末尾追加 -1, -2 … 以便区分
6977
+ name: counts > 1 ? `${opts.accountName}-${i + 1}` : opts.accountName
6978
+ }
6979
+ })),
6989
6980
  MediaAccountGroupId: magKey,
6990
6981
  IsSaltAdd: false,
6991
6982
  ManagerCustomerId: "",
@@ -8495,7 +8486,7 @@ openAccountCmd.command("yandex").description("\u63D0\u4EA4 Yandex \u5F00\u6237\u
8495
8486
  verbose: opts.verbose
8496
8487
  });
8497
8488
  });
8498
- openAccountCmd.command("bing").description("\u63D0\u4EA4 Bing/BingV2 \u5F00\u6237\u7533\u8BF7\uFF08\u9700\u4E0A\u4F20\u8425\u4E1A\u6267\u7167\u56FE\u7247\uFF0C\u6309\u516C\u53F8\u540D\u81EA\u52A8\u521B\u5EFA/\u5173\u8054\u5E7F\u544A\u4E3B\u7EC4\uFF09").requiredOption("--advertiser-name <name>", "\u5E7F\u544A\u4E3B\u540D\u79F0\uFF08\u516C\u53F8\u5168\u79F0\uFF0C\u7528\u4E8E\u5339\u914D\u6216\u521B\u5EFA\u5E7F\u544A\u4E3B\u7EC4\uFF09").requiredOption("--name-short <short>", "\u5E7F\u544A\u4E3B\u7B80\u79F0").requiredOption("--province <province>", "\u7701/\u5DDE").requiredOption("--city <city>", "\u57CE\u5E02").requiredOption("--address <address>", "\u8BE6\u7EC6\u5730\u5740").requiredOption("--promotion-link <url>", "\u63A8\u5E7F\u94FE\u63A5").requiredOption("--trade-id <name>", "\u884C\u4E1A\u540D\u79F0\uFF08\u6765\u81EA open-account bing-industries \u7684 name \u5B57\u6BB5\uFF09").requiredOption("--license-file <path>", "\u8425\u4E1A\u6267\u7167\u56FE\u7247\u672C\u5730\u8DEF\u5F84\uFF08JPG/PNG/PDF\uFF09").option("--postcode <code>", "\u90AE\u653F\u7F16\u7801").option("--advertiser-cid <cid>", "\u7ECF\u7406\u8D26\u6237 CID").option("--advertiser-name2 <name>", "\u7ECF\u7406\u8D26\u6237\u540D\u79F0").option("--account-count <n>", "\u5F00\u6237\u6570\u91CF\uFF08\u9ED8\u8BA4 1\uFF09", parseInt).option("--advertiser-id <magKey>", "\u53EF\u9009\uFF1A\u624B\u52A8\u6307\u5B9A\u5E7F\u544A\u4E3B\u7EC4 magKey\uFF08\u4E00\u822C\u65E0\u9700\u586B\u5199\uFF09").option("-t, --token <token>", "Auth Token").option("--verbose", "\u8BE6\u7EC6\u9519\u8BEF\u4FE1\u606F", false).action(async (opts) => {
8489
+ openAccountCmd.command("bing").description("\u63D0\u4EA4 Bing/BingV2 \u5F00\u6237\u7533\u8BF7\uFF08\u9700\u4E0A\u4F20\u8425\u4E1A\u6267\u7167\u56FE\u7247\uFF0C\u6309\u516C\u53F8\u540D\u81EA\u52A8\u521B\u5EFA/\u5173\u8054\u5E7F\u544A\u4E3B\u7EC4\uFF09").requiredOption("--advertiser-name <name>", "\u5E7F\u544A\u4E3B\u540D\u79F0\uFF08\u516C\u53F8\u5168\u79F0\uFF0C\u7528\u4E8E\u5339\u914D\u6216\u521B\u5EFA\u5E7F\u544A\u4E3B\u7EC4\uFF09").requiredOption("--name-short <short>", "\u5E7F\u544A\u4E3B\u7B80\u79F0").requiredOption("--province <province>", "\u7701/\u5DDE").requiredOption("--city <city>", "\u57CE\u5E02").requiredOption("--address <address>", "\u8BE6\u7EC6\u5730\u5740").requiredOption("--promotion-link <url>", "\u63A8\u5E7F\u94FE\u63A5").requiredOption("--trade-id <name>", "\u884C\u4E1A\u540D\u79F0\uFF08\u6765\u81EA open-account bing-industries \u7684 name \u5B57\u6BB5\uFF09").requiredOption("--license-file <path>", "\u8425\u4E1A\u6267\u7167\u56FE\u7247\u672C\u5730\u8DEF\u5F84\uFF08JPG/PNG/PDF\uFF09").option("--postcode <code>", "\u90AE\u653F\u7F16\u7801").option("--advertiser-cid <cid>", "\u7ECF\u7406\u8D26\u6237 CID").option("--advertiser-name2 <name>", "\u7ECF\u7406\u8D26\u6237\u540D\u79F0").option("--account-count <n>", "\u5F00\u6237\u6570\u91CF\uFF081~6\uFF0C\u9ED8\u8BA4 1\uFF09", parseInt).option("--advertiser-id <magKey>", "\u53EF\u9009\uFF1A\u624B\u52A8\u6307\u5B9A\u5E7F\u544A\u4E3B\u7EC4 magKey\uFF08\u4E00\u822C\u65E0\u9700\u586B\u5199\uFF09").option("-t, --token <token>", "Auth Token").option("--verbose", "\u8BE6\u7EC6\u9519\u8BEF\u4FE1\u606F", false).action(async (opts) => {
8499
8490
  await runOpenAccountBing({
8500
8491
  token: opts.token,
8501
8492
  advertiserId: opts.advertiserId,
@@ -8537,7 +8528,7 @@ openAccountCmd.command("google-timezones").description("\u5217\u51FA Google \u5F
8537
8528
  openAccountCmd.command("google-wizard").description("\u4EA4\u4E92\u5F0F Google \u5F00\u6237\uFF08\u5BF9\u9F50\u7F51\u9875\u4E94\u6B65\u8BF4\u660E + \u4E24\u6B65\u8868\u5355\uFF1B\u9700\u7EC8\u7AEF TTY\uFF09").option("-t, --token <token>", "Auth Token").option("--verbose", "\u8BE6\u7EC6\u9519\u8BEF\u4FE1\u606F", false).action(async (opts) => {
8538
8529
  await runOpenAccountGoogleWizard({ token: opts.token, verbose: opts.verbose });
8539
8530
  });
8540
- openAccountCmd.command("google").description("\u63D0\u4EA4 Google \u5F00\u6237\u7533\u8BF7\uFF08\u4E0E\u7F51\u9875\u8868\u5355\u4E00\u81F4\uFF1A\u6309\u516C\u53F8\u540D\u79F0\u81EA\u52A8\u521B\u5EFA/\u5173\u8054\u5E7F\u544A\u4E3B\u7EC4\uFF0C\u65E0\u9700 magKey\uFF09").option("--advertiser-id <magKey>", "\u53EF\u9009\uFF1A\u624B\u52A8\u6307\u5B9A\u5E7F\u544A\u4E3B\u7EC4 ID\uFF08\u4E00\u822C\u4E0D\u7528\uFF1B\u8C03\u8BD5\u7528\u6216\u7279\u6B8A\u573A\u666F\uFF09").requiredOption("--account-name <name>", "\u5E7F\u544A\u8D26\u6237\u540D\u79F0\uFF08\u5EFA\u8BAE 22 \u4E2A\u5B57\u7B26\u4EE5\u5185\uFF09").requiredOption("--currency <code>", "\u8D27\u5E01\uFF1AUSD | CNY").requiredOption("--timezone <tz>", "\u65F6\u533A\uFF0C\u5982 Asia/Hong_Kong\uFF08\u53EF\u5148\u67E5 open-account google-timezones\uFF09").requiredOption("--invite-email <email>", "\u53D7\u9080\u7528\u6237\u90AE\u7BB1\uFF08\u8D26\u6237\u9080\u8BF7\u5C06\u53D1\u5230\u6B64\u90AE\u7BB1\uFF09").requiredOption("--company <name>", "\u516C\u53F8\u540D\u79F0\uFF08\u7528\u4E8E\u5339\u914D\u6216\u521B\u5EFA\u5E7F\u544A\u4E3B\u7EC4\uFF0C\u4E0E\u7F51\u9875\u7B2C\u4E00\u6B65\u4E00\u81F4\uFF09").option("--industry1 <level1>", "\u53EF\u9009\uFF1A\u884C\u4E1A\u4E00\u7EA7\uFF08\u7F51\u9875\u7AEF\u5DF2\u5F31\u5316\uFF0C\u591A\u6570\u573A\u666F\u53EF\u4E0D\u586B\uFF09").option("--industry2 <level2>", "\u53EF\u9009\uFF1A\u884C\u4E1A\u4E8C\u7EA7").requiredOption("--promotion-link <url>", "\u63A8\u5E7F\u94FE\u63A5\uFF08\u516C\u53F8\u5B98\u7F51\u6216\u4EA7\u54C1\u9875\uFF1B\u53EF\u5199\u57DF\u540D\uFF0C\u4F1A\u81EA\u52A8\u8865 https://\uFF09").requiredOption("--promotion-type <type>", "\u63A8\u5E7F\u7C7B\u578B\uFF1Ab2b | b2c | app").option("--invite-role <role>", "\u53D7\u9080\u7528\u6237\u89D2\u8272\uFF1AStandard | Admin\uFF08\u9ED8\u8BA4 Standard\uFF09", "Standard").option("--auto-mailbox", "\u81EA\u52A8\u5206\u914D\u90AE\u7BB1", false).option("--counts <n>", "\u672C\u6B21\u5F00\u6237\u6570\u91CF\uFF081-3\uFF0C\u9ED8\u8BA4 1\uFF09", parseInt).option("--manager-customer-id <id>", "MCC \u7ECF\u7406\u8D26\u6237 ID\uFF08\u53EF\u9009\uFF09").option("-t, --token <token>", "Auth Token").option("--verbose", "\u8BE6\u7EC6\u9519\u8BEF\u4FE1\u606F", false).action(async (opts) => {
8531
+ openAccountCmd.command("google").description("\u63D0\u4EA4 Google \u5F00\u6237\u7533\u8BF7\uFF08\u4E0E\u7F51\u9875\u8868\u5355\u4E00\u81F4\uFF1A\u6309\u516C\u53F8\u540D\u79F0\u81EA\u52A8\u521B\u5EFA/\u5173\u8054\u5E7F\u544A\u4E3B\u7EC4\uFF0C\u65E0\u9700 magKey\uFF09").option("--advertiser-id <magKey>", "\u53EF\u9009\uFF1A\u624B\u52A8\u6307\u5B9A\u5E7F\u544A\u4E3B\u7EC4 ID\uFF08\u4E00\u822C\u4E0D\u7528\uFF1B\u8C03\u8BD5\u7528\u6216\u7279\u6B8A\u573A\u666F\uFF09").requiredOption("--account-name <name>", "\u5E7F\u544A\u8D26\u6237\u540D\u79F0\uFF08\u5EFA\u8BAE 22 \u4E2A\u5B57\u7B26\u4EE5\u5185\uFF09").requiredOption("--currency <code>", "\u8D27\u5E01\uFF1AUSD | CNY").requiredOption("--timezone <tz>", "\u65F6\u533A\uFF0C\u5982 Asia/Hong_Kong\uFF08\u53EF\u5148\u67E5 open-account google-timezones\uFF09").requiredOption("--invite-email <email>", "\u53D7\u9080\u7528\u6237\u90AE\u7BB1\uFF08\u8D26\u6237\u9080\u8BF7\u5C06\u53D1\u5230\u6B64\u90AE\u7BB1\uFF09").requiredOption("--company <name>", "\u516C\u53F8\u540D\u79F0\uFF08\u7528\u4E8E\u5339\u914D\u6216\u521B\u5EFA\u5E7F\u544A\u4E3B\u7EC4\uFF0C\u4E0E\u7F51\u9875\u7B2C\u4E00\u6B65\u4E00\u81F4\uFF09").requiredOption("--promotion-link <url>", "\u63A8\u5E7F\u94FE\u63A5\uFF08\u516C\u53F8\u5B98\u7F51\u6216\u4EA7\u54C1\u9875\uFF1B\u53EF\u5199\u57DF\u540D\uFF0C\u4F1A\u81EA\u52A8\u8865 https://\uFF09").requiredOption("--promotion-type <type>", "\u63A8\u5E7F\u7C7B\u578B\uFF1Ab2b | b2c | app").option("--invite-role <role>", "\u53D7\u9080\u7528\u6237\u89D2\u8272\uFF1AStandard | Admin\uFF08\u9ED8\u8BA4 Standard\uFF09", "Standard").option("--auto-mailbox", "\u81EA\u52A8\u5206\u914D\u90AE\u7BB1", false).option("--counts <n>", "\u672C\u6B21\u5F00\u6237\u6570\u91CF\uFF081-3\uFF0C\u9ED8\u8BA4 1\uFF09", parseInt).option("--manager-customer-id <id>", "MCC \u7ECF\u7406\u8D26\u6237 ID\uFF08\u53EF\u9009\uFF09").option("-t, --token <token>", "Auth Token").option("--verbose", "\u8BE6\u7EC6\u9519\u8BEF\u4FE1\u606F", false).action(async (opts) => {
8541
8532
  await runOpenAccountGoogle({
8542
8533
  token: opts.token,
8543
8534
  advertiserId: opts.advertiserId,
@@ -8546,8 +8537,6 @@ openAccountCmd.command("google").description("\u63D0\u4EA4 Google \u5F00\u6237\u
8546
8537
  timezone: opts.timezone,
8547
8538
  inviteEmail: opts.inviteEmail,
8548
8539
  company: opts.company,
8549
- industryLevel1: opts.industry1,
8550
- industryLevel2: opts.industry2,
8551
8540
  promotionLink: opts.promotionLink,
8552
8541
  promotionType: opts.promotionType,
8553
8542
  inviteRole: opts.inviteRole,
@@ -8557,12 +8546,11 @@ openAccountCmd.command("google").description("\u63D0\u4EA4 Google \u5F00\u6237\u
8557
8546
  verbose: opts.verbose
8558
8547
  });
8559
8548
  });
8560
- openAccountCmd.command("tiktok").description("\u63D0\u4EA4 TikTok \u5F00\u6237\u7533\u8BF7\uFF08\u9700\u4E0A\u4F20\u8425\u4E1A\u6267\u7167\u56FE\u7247\uFF0C\u6309\u516C\u53F8\u540D\u81EA\u52A8\u521B\u5EFA/\u5173\u8054\u5E7F\u544A\u4E3B\u7EC4\uFF09").requiredOption("--account-name <name>", "\u5E7F\u544A\u8D26\u6237\u540D\u79F0").requiredOption("--currency <code>", "\u8D27\u5E01\uFF1AUSD | CNY").requiredOption("--timezone <tz>", "\u65F6\u533A\uFF0C\u5982 UTC+8\uFF08\u53EF\u5148\u67E5 open-account tiktok-timezones\uFF09").requiredOption("--company <name>", "\u516C\u53F8\u540D\u79F0").requiredOption("--industry-id <id>", "\u884C\u4E1A ID\uFF08\u6570\u5B57\uFF0CTikTok \u884C\u4E1A\u53F6\u5B50\u8282\u70B9 ID\uFF09", parseInt).requiredOption("--registered-area <code>", "\u6CE8\u518C\u5730\u56FD\u5BB6\u4EE3\u7801\uFF0C\u5982 CN").requiredOption("--promotion-link <url>", "\u63A8\u5E7F\u94FE\u63A5").requiredOption("--license-no <no>", "\u8425\u4E1A\u6267\u7167\u7F16\u7801\uFF08\u793E\u4F1A\u7EDF\u4E00\u4FE1\u7528\u4EE3\u7801\uFF09").requiredOption("--license-file <path>", "\u8425\u4E1A\u6267\u7167\u56FE\u7247\u672C\u5730\u8DEF\u5F84\uFF08JPG/PNG\uFF09").option("--bc-type <type>", "\u4E1A\u52A1\u4E2D\u5FC3\u7C7B\u578B\uFF1AShop | Store | App | B2B | Other\uFF08\u9ED8\u8BA4 Shop\uFF09", "Shop").option("--partner-id <id>", "BC \u5408\u4F5C\u4F19\u4F34 ID\uFF08bc_id\uFF0C\u53EF\u9009\uFF09").option("--counts <n>", "\u672C\u6B21\u5F00\u6237\u6570\u91CF\uFF081-10\uFF0C\u9ED8\u8BA4 1\uFF09", parseInt).option("--representative-name <name>", "\u6CD5\u4EBA\u59D3\u540D\uFF08\u82E5\u9700\u8981\u94F6\u8054\u9A8C\u8BC1\u65F6\u586B\u5199\uFF09").option("--representative-id <id>", "\u6CD5\u4EBA\u8EAB\u4EFD\u8BC1\u53F7").option("--unionpay-account <no>", "\u6CD5\u4EBA\u94F6\u8054\u8D26\u53F7").option("--representative-phone <phone>", "\u6CD5\u4EBA\u624B\u673A\u53F7").option("--advertiser-id <magKey>", "\u53EF\u9009\uFF1A\u624B\u52A8\u6307\u5B9A\u5E7F\u544A\u4E3B\u7EC4 magKey\uFF08\u4E00\u822C\u65E0\u9700\u586B\u5199\uFF09").option("-t, --token <token>", "Auth Token").option("--verbose", "\u8BE6\u7EC6\u9519\u8BEF\u4FE1\u606F", false).action(async (opts) => {
8549
+ openAccountCmd.command("tiktok").description("\u63D0\u4EA4 TikTok \u5F00\u6237\u7533\u8BF7\uFF08\u9700\u4E0A\u4F20\u8425\u4E1A\u6267\u7167\u56FE\u7247\uFF0C\u6309\u516C\u53F8\u540D\u81EA\u52A8\u521B\u5EFA/\u5173\u8054\u5E7F\u544A\u4E3B\u7EC4\uFF09").requiredOption("--account-name <name>", "\u5E7F\u544A\u8D26\u6237\u540D\u79F0").requiredOption("--timezone <tz>", "\u65F6\u533A\uFF0C\u5982 UTC+8\uFF08\u53EF\u5148\u67E5 open-account tiktok-timezones\uFF09").requiredOption("--company <name>", "\u516C\u53F8\u540D\u79F0").requiredOption("--industry-id <id>", "\u884C\u4E1A ID\uFF08\u6570\u5B57\uFF0CTikTok \u884C\u4E1A\u53F6\u5B50\u8282\u70B9 ID\uFF09", parseInt).requiredOption("--registered-area <code>", "\u6CE8\u518C\u5730\u56FD\u5BB6\u4EE3\u7801\uFF0C\u5982 CN").requiredOption("--promotion-link <url>", "\u63A8\u5E7F\u94FE\u63A5").requiredOption("--license-no <no>", "\u8425\u4E1A\u6267\u7167\u7F16\u7801\uFF08\u793E\u4F1A\u7EDF\u4E00\u4FE1\u7528\u4EE3\u7801\uFF09").requiredOption("--license-file <path>", "\u8425\u4E1A\u6267\u7167\u56FE\u7247\u672C\u5730\u8DEF\u5F84\uFF08JPG/PNG\uFF09").option("--bc-type <type>", "\u4E1A\u52A1\u4E2D\u5FC3\u7C7B\u578B\uFF1AShop | Store | App | B2B | Other\uFF08\u9ED8\u8BA4 Shop\uFF09", "Shop").option("--partner-id <id>", "BC \u5408\u4F5C\u4F19\u4F34 ID\uFF08bc_id\uFF0C\u53EF\u9009\uFF09").option("--counts <n>", "\u672C\u6B21\u5F00\u6237\u6570\u91CF\uFF081-10\uFF0C\u9ED8\u8BA4 1\uFF09", parseInt).requiredOption("--representative-name <name>", "\u6CD5\u4EBA\u59D3\u540D\uFF08\u94F6\u8054\u9A8C\u8BC1\u5FC5\u586B\uFF09").requiredOption("--representative-id <id>", "\u6CD5\u4EBA\u8EAB\u4EFD\u8BC1\u53F7\uFF08\u94F6\u8054\u9A8C\u8BC1\u5FC5\u586B\uFF09").requiredOption("--unionpay-account <no>", "\u6CD5\u4EBA\u94F6\u8054\u8D26\u53F7\uFF08\u94F6\u8054\u9A8C\u8BC1\u5FC5\u586B\uFF09").requiredOption("--representative-phone <phone>", "\u6CD5\u4EBA\u624B\u673A\u53F7\uFF08\u94F6\u8054\u9A8C\u8BC1\u5FC5\u586B\uFF09").option("--advertiser-id <magKey>", "\u53EF\u9009\uFF1A\u624B\u52A8\u6307\u5B9A\u5E7F\u544A\u4E3B\u7EC4 magKey\uFF08\u4E00\u822C\u65E0\u9700\u586B\u5199\uFF09").option("-t, --token <token>", "Auth Token").option("--verbose", "\u8BE6\u7EC6\u9519\u8BEF\u4FE1\u606F", false).action(async (opts) => {
8561
8550
  await runOpenAccountTikTok({
8562
8551
  token: opts.token,
8563
8552
  advertiserId: opts.advertiserId,
8564
8553
  accountName: opts.accountName,
8565
- currency: opts.currency,
8566
8554
  timezone: opts.timezone,
8567
8555
  company: opts.company,
8568
8556
  industryId: opts.industryId,
@@ -115,6 +115,29 @@ description: >-
115
115
 
116
116
  ---
117
117
 
118
+ ## 自动更新规则(必须遵守)
119
+
120
+ CLI 命令执行后可能在输出末尾出现以下两种标记,Agent 必须按对应规则处理:
121
+
122
+ ### `[SILUZAN_FORCE_UPDATE]` — 强制更新(必须,不可跳过)
123
+
124
+ 当前版本已低于最低要求版本,**必须先升级再继续**:
125
+
126
+ 1. 立即执行 `siluzan-tso update`
127
+ 2. 告知用户:当前版本过旧,已自动升级,请重新执行刚才的操作
128
+ 3. 不得在升级前继续执行任何业务命令
129
+
130
+ ### `[SILUZAN_UPDATE_AVAILABLE]` — 可选更新
131
+
132
+ 有新版本可用,但当前版本仍可正常使用:
133
+
134
+ 1. 执行 `siluzan-tso update`
135
+ 2. 更新完成后继续执行原本的用户任务
136
+
137
+ > 两种情况下,`siluzan-tso update` 都会同步刷新 Skill 文件,新版本可能包含参数或流程变更。
138
+
139
+ ---
140
+
118
141
  ## AI 行为规范
119
142
 
120
143
  - **先查账户再操作**:对具体账户做操作前,先通过 `list-accounts` 确认 ID。
@@ -1,5 +1,5 @@
1
1
  {
2
2
  "slug": "siluzan-tso",
3
- "version": "1.0.0-beta.21",
4
- "publishedAt": 1774409821808
3
+ "version": "1.0.0-beta.22",
4
+ "publishedAt": 1774420324671
5
5
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "siluzan-tso-cli",
3
- "version": "1.0.0-beta.21",
3
+ "version": "1.0.0-beta.22",
4
4
  "description": "Siluzan 广告账户管理 CLI — 查询账户、余额、消耗数据,管理绑定关系与充值。",
5
5
  "type": "module",
6
6
  "bin": {