siluzan-tso-cli 1.1.29-beta.5 → 1.1.29-beta.8

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
@@ -51,7 +51,7 @@ siluzan-tso init -d /path/to/skills # 写入自定义目录
51
51
  siluzan-tso init --force # 强制覆盖已存在文件
52
52
  ```
53
53
 
54
- > **注意**:当前为测试版(1.1.29-beta.5),供内部测试使用。正式发布后安装命令将改为 `npm install -g siluzan-tso-cli`。
54
+ > **注意**:当前为测试版(1.1.29-beta.8),供内部测试使用。正式发布后安装命令将改为 `npm install -g siluzan-tso-cli`。
55
55
 
56
56
  | 助手 | 建议 `--ai` |
57
57
  | ----------------------- | ------------------------------------ |
package/dist/index.js CHANGED
@@ -2338,6 +2338,18 @@ function decodeJwtClaims(token) {
2338
2338
  function decodeJwtSub(token) {
2339
2339
  return decodeJwtClaims(token)?.sub ?? null;
2340
2340
  }
2341
+ function sleep(ms) {
2342
+ return new Promise((resolve32) => setTimeout(resolve32, ms));
2343
+ }
2344
+ async function pollUntil(fn, intervalMs, timeoutMs) {
2345
+ const deadline = Date.now() + timeoutMs;
2346
+ while (Date.now() < deadline) {
2347
+ const result = await fn();
2348
+ if (result !== null) return result;
2349
+ await sleep(intervalMs);
2350
+ }
2351
+ return null;
2352
+ }
2341
2353
  function getCurrentVersion(importMetaUrl) {
2342
2354
  try {
2343
2355
  const __dirname3 = path2.dirname(fileURLToPath(importMetaUrl));
@@ -2589,6 +2601,9 @@ function pickStr(obj, key) {
2589
2601
  const v = obj[key];
2590
2602
  return typeof v === "string" && v.trim() ? v.trim() : void 0;
2591
2603
  }
2604
+ function pickPhone(data) {
2605
+ return pickStr(data, "phone") ?? pickStr(data, "mobile") ?? pickStr(data, "phoneNumber") ?? pickStr(data, "mobilePhone");
2606
+ }
2592
2607
  function pickCompanyId(data) {
2593
2608
  const direct = pickStr(data, "companyId") ?? pickStr(data, "companyID") ?? pickStr(data, "CompanyId");
2594
2609
  if (direct) return direct;
@@ -2605,10 +2620,11 @@ function parseMeResponse(text) {
2605
2620
  const data = json?.data && typeof json.data === "object" ? json.data : json;
2606
2621
  const id = pickStr(data, "entityId") ?? pickStr(data, "id") ?? pickStr(data, "userId") ?? pickStr(data, "accountId");
2607
2622
  const email = pickStr(data, "email");
2608
- const username = pickStr(data, "userName") ?? pickStr(data, "username") ?? pickStr(data, "name") ?? pickStr(data, "phone");
2623
+ const phone = pickPhone(data);
2624
+ const username = pickStr(data, "userName") ?? pickStr(data, "username") ?? pickStr(data, "name") ?? phone;
2609
2625
  const companyId = pickCompanyId(data);
2610
- if (!id && !email && !username && !companyId) return null;
2611
- return { id, email, username, companyId };
2626
+ if (!id && !email && !username && !phone && !companyId) return null;
2627
+ return { id, email, username, phone, companyId };
2612
2628
  } catch {
2613
2629
  return null;
2614
2630
  }
@@ -2633,6 +2649,7 @@ async function fetchSiluzanCurrentUser(apiBase, config) {
2633
2649
  entityId: parsed.id,
2634
2650
  email: parsed.email,
2635
2651
  username: parsed.username,
2652
+ phone: parsed.phone,
2636
2653
  companyId: parsed.companyId
2637
2654
  };
2638
2655
  } catch {
@@ -3087,6 +3104,18 @@ function normalizeChinaPhone(input) {
3087
3104
  function isValidChinaPhone(input) {
3088
3105
  return /^\+861\d{10}$/.test(normalizeChinaPhone(input));
3089
3106
  }
3107
+ function chinaPhonesEqual(a, b) {
3108
+ const na = normalizeChinaPhone(a.trim());
3109
+ const nb = normalizeChinaPhone(b.trim());
3110
+ if (isValidChinaPhone(na) && isValidChinaPhone(nb)) {
3111
+ return na === nb;
3112
+ }
3113
+ const da = a.replace(/\D/g, "");
3114
+ const db = b.replace(/\D/g, "");
3115
+ const ca = da.length >= 11 ? da.slice(-11) : da;
3116
+ const cb = db.length >= 11 ? db.slice(-11) : db;
3117
+ return ca.length === 11 && cb.length === 11 && ca === cb;
3118
+ }
3090
3119
  async function sendPhoneLoginCode(opts) {
3091
3120
  const phone = normalizeChinaPhone(opts.phone);
3092
3121
  const url = `${opts.ssoBaseUrl}/Account/SendVaildCode?Phone=${encodeURIComponent(
@@ -119367,6 +119396,89 @@ function register22(program2) {
119367
119396
  );
119368
119397
  }
119369
119398
 
119399
+ // src/commands/account-manage/me.ts
119400
+ init_dist();
119401
+ init_auth();
119402
+ init_cli_json_snapshot();
119403
+ function maskPhone(phone) {
119404
+ if (!phone) return "\u2014";
119405
+ const digits = phone.replace(/\D/g, "");
119406
+ if (digits.length < 7) return phone;
119407
+ const tail = digits.slice(-4);
119408
+ return `${digits.slice(0, 3)}****${tail}`;
119409
+ }
119410
+ async function runAccountMe(opts) {
119411
+ const config = loadConfig(opts.token);
119412
+ const me = await fetchSiluzanCurrentUser(config.apiBaseUrl, config);
119413
+ if (!me) {
119414
+ console.error(
119415
+ "\n\u274C \u65E0\u6CD5\u83B7\u53D6\u5F53\u524D\u8D26\u53F7\u4FE1\u606F\uFF08GET /query/account/me\uFF09\u3002\u8BF7\u68C0\u67E5\u51ED\u636E\u662F\u5426\u6709\u6548\uFF1Asiluzan-tso config show\n"
119416
+ );
119417
+ process.exit(1);
119418
+ }
119419
+ const phoneNormalized = me.phone ? normalizeChinaPhone(me.phone) : void 0;
119420
+ const payload = {
119421
+ entityId: me.entityId,
119422
+ email: me.email,
119423
+ username: me.username,
119424
+ phone: me.phone,
119425
+ phoneNormalized,
119426
+ companyId: me.companyId
119427
+ };
119428
+ if (opts.checkPhone?.trim()) {
119429
+ const requested = opts.checkPhone.trim();
119430
+ payload.requestedPhone = requested;
119431
+ if (!me.phone) {
119432
+ payload.matched = false;
119433
+ payload.message = "\u5F53\u524D\u767B\u5F55\u51ED\u636E\u672A\u8FD4\u56DE\u624B\u673A\u53F7\uFF0C\u65E0\u6CD5\u6821\u9A8C\u662F\u5426\u4E0E\u6307\u5B9A\u4F01\u4E1A\u7BA1\u5BB6\u8D26\u53F7\u4E00\u81F4\uFF1B\u8BF7\u4F7F\u7528\u8BE5\u624B\u673A\u53F7\u91CD\u65B0\u767B\u5F55\u540E\u518D\u67E5\u8BE2\u3002";
119434
+ } else {
119435
+ payload.matched = chinaPhonesEqual(me.phone, requested);
119436
+ if (!payload.matched) {
119437
+ payload.message = "\u6307\u5B9A\u624B\u673A\u53F7\u4E0E\u5F53\u524D\u767B\u5F55\u8D26\u53F7\u4E0D\u4E00\u81F4\uFF1B\u6682\u65F6\u4E0D\u652F\u6301\u67E5\u8BE2\u5176\u4ED6\u4E1D\u8DEF\u8D5E\u8D26\u53F7\u4E0B\u7684\u6570\u636E\uFF0C\u8BF7\u4F7F\u7528\u8BE5\u624B\u673A\u53F7\u91CD\u65B0\u767B\u5F55\u3002";
119438
+ }
119439
+ }
119440
+ }
119441
+ if (await emitCliJsonOrSnapshot(opts, {
119442
+ section: "account-me",
119443
+ commandLabel: "account me",
119444
+ payload
119445
+ })) {
119446
+ if (opts.checkPhone?.trim() && payload.matched === false) {
119447
+ process.exit(1);
119448
+ }
119449
+ return;
119450
+ }
119451
+ console.log("\n\u5F53\u524D\u767B\u5F55\u4E1D\u8DEF\u8D5E\u8D26\u53F7\uFF1A");
119452
+ console.log(` entityId : ${me.entityId ?? "\u2014"}`);
119453
+ console.log(` \u7528\u6237\u540D : ${me.username ?? "\u2014"}`);
119454
+ console.log(` \u624B\u673A\u53F7 : ${me.phone ?? "\u2014"}`);
119455
+ console.log(` \u90AE\u7BB1 : ${me.email ?? "\u2014"}`);
119456
+ console.log(` companyId : ${me.companyId ?? "\u2014"}`);
119457
+ console.log();
119458
+ if (opts.checkPhone?.trim()) {
119459
+ const requested = opts.checkPhone.trim();
119460
+ if (payload.matched) {
119461
+ console.log(`\u2705 \u624B\u673A\u53F7\u6821\u9A8C\u901A\u8FC7\uFF1A\u4E0E\u5F53\u524D\u767B\u5F55\u8D26\u53F7\u4E00\u81F4\uFF08${maskPhone(me.phone)}\uFF09
119462
+ `);
119463
+ return;
119464
+ }
119465
+ console.error(
119466
+ `
119467
+ \u274C \u6682\u65F6\u4E0D\u652F\u6301\u67E5\u8BE2\u5176\u4ED6\u4E1D\u8DEF\u8D5E\u8D26\u53F7\u4E0B\u7684\u6570\u636E\u3002
119468
+ \u60A8\u6307\u5B9A\u7684\u662F\uFF1A${requested}
119469
+ \u5F53\u524D\u767B\u5F55\u8D26\u53F7\uFF1A${me.phone ?? "\uFF08\u672A\u80FD\u8BC6\u522B\u624B\u673A\u53F7\uFF0C\u8BF7\u91CD\u65B0\u767B\u5F55\uFF09"}
119470
+
119471
+ \u5982\u9700\u67E5\u8BE2\u8BE5\u8D26\u53F7\u6570\u636E\uFF0C\u8BF7\u4F7F\u7528\u8BE5\u624B\u673A\u53F7\u91CD\u65B0\u767B\u5F55\uFF1A
119472
+ 1) siluzan-tso send-login-code --phone ${requested}
119473
+ 2) siluzan-tso login --phone ${requested} --code <\u9A8C\u8BC1\u7801>
119474
+
119475
+ \u9700\u8981\u6211\u5E2E\u60A8\u5207\u6362\u767B\u5F55\u5417\uFF1F
119476
+ `
119477
+ );
119478
+ process.exit(1);
119479
+ }
119480
+ }
119481
+
119370
119482
  // src/commands/account-manage/share.ts
119371
119483
  init_auth();
119372
119484
  init_cli_json_snapshot();
@@ -120494,6 +120606,25 @@ async function runAccountBmBind(opts) {
120494
120606
  // src/commands/account-manage-register.ts
120495
120607
  function register23(program2) {
120496
120608
  const accountCmd = program2.command("account").description("\u5E7F\u544A\u8D26\u6237\u7BA1\u7406\uFF1AOAuth \u6DFB\u52A0\u6388\u6743\u3001\u89E3\u9664\u5173\u8054\uFF08\u89E3\u7ED1\uFF09\u3001Google MCC \u7ED1\u5B9A/\u89E3\u7ED1\u3001\u8D26\u53F7\u5206\u4EAB");
120609
+ accountCmd.command("me").description(
120610
+ "\u67E5\u8BE2\u5F53\u524D\u767B\u5F55\u4E1D\u8DEF\u8D5E\u8D26\u53F7\u4FE1\u606F\uFF08GET /query/account/me\uFF09\uFF1B--check-phone \u7528\u4E8E\u6821\u9A8C\u7528\u6237\u6307\u5B9A\u7684\u4F01\u4E1A\u7BA1\u5BB6\u624B\u673A\u53F7"
120611
+ ).option("-t, --token <token>", "Auth Token").option(
120612
+ "--check-phone <phone>",
120613
+ "\u4E0E\u7528\u6237\u6D88\u606F\u4E2D\u7684\u624B\u673A\u53F7\u6BD4\u5BF9\uFF1B\u4E0D\u4E00\u81F4\u65F6\u9000\u51FA\u5E76\u63D0\u793A\u5207\u6362\u767B\u5F55\uFF08\u6682\u65F6\u4E0D\u652F\u6301\u67E5\u4ED6\u6237\u6570\u636E\uFF09"
120614
+ ).option(
120615
+ "--json-out <path>",
120616
+ "\u843D\u76D8 JSON\uFF1Bstdout \u4E00\u884C\u6458\u8981\uFF1B\u914D\u5408 --check-phone \u65F6 matched=false \u5219 exit 1",
120617
+ void 0
120618
+ ).option("--verbose", "\u8BE6\u7EC6\u9519\u8BEF\u4FE1\u606F", false).action(
120619
+ async (opts) => {
120620
+ await runAccountMe({
120621
+ token: opts.token,
120622
+ checkPhone: opts.checkPhone,
120623
+ jsonOut: opts.jsonOut,
120624
+ verbose: opts.verbose
120625
+ });
120626
+ }
120627
+ );
120497
120628
  accountCmd.command("delink").description(
120498
120629
  "\u89E3\u9664\u6388\u6743\uFF1A\u65AD\u5F00\u5E7F\u544A\u8D26\u6237\u4E0E\u5F53\u524D\u4E1D\u8DEF\u8D5E\u8D26\u53F7\u7684\u5173\u8054\uFF08\u7F51\u9875 manageAccounts\u300C\u89E3\u9664\u6388\u6743\u300D\uFF1B--id \u6216 --ids\uFF09"
120499
120630
  ).option("--id <entityId>", "\u5355\u4E2A\u8D26\u6237 entityId\uFF08\u6765\u81EA list-accounts \u7684 ma.entityId \u5B57\u6BB5\uFF09").option("--ids <entityIds>", "\u6279\u91CF entityId\uFF0C\u9017\u53F7\u5206\u9694\uFF08\u4E0E --id \u4E8C\u9009\u4E00\uFF0C\u53EF\u540C\u65F6\u4F20\uFF09").option("-t, --token <token>", "Auth Token").option("--verbose", "\u8BE6\u7EC6\u9519\u8BEF\u4FE1\u606F", false).action(async (opts) => {
@@ -121345,6 +121476,35 @@ BingV2 \u884C\u4E1A\u5217\u8868\uFF08\u7B2C 1 \u9875\uFF0C\u672C\u9875 ${list.le
121345
121476
  init_auth();
121346
121477
  import * as fs10 from "fs";
121347
121478
  import * as path15 from "path";
121479
+
121480
+ // src/commands/open-account/kwai-licence-id-type.ts
121481
+ var KWAI_LICENCE_ID_TYPE_LABELS = {
121482
+ "1": "\u7EDF\u4E00\u793E\u4F1A\u4FE1\u7528\u4EE3\u7801 / Business license Uniform social credit code",
121483
+ "2": "DUNS / Data Universal Numbering System",
121484
+ "3": "CNPJ"
121485
+ };
121486
+ var VALID = new Set(Object.keys(KWAI_LICENCE_ID_TYPE_LABELS));
121487
+ var LEGACY_ALIASES = {
121488
+ ENTERPRISE: "1",
121489
+ INDIVIDUAL: "1"
121490
+ };
121491
+ function normalizeKwaiLicenceIdType(raw) {
121492
+ const trimmed = raw.trim();
121493
+ const upper = trimmed.toUpperCase();
121494
+ const legacy = LEGACY_ALIASES[upper];
121495
+ if (legacy) {
121496
+ return { value: legacy, legacyAlias: trimmed };
121497
+ }
121498
+ if (VALID.has(trimmed)) {
121499
+ return { value: trimmed };
121500
+ }
121501
+ const options = Object.entries(KWAI_LICENCE_ID_TYPE_LABELS).map(([k, v]) => `${k}=${v.split(" / ")[0]}`).join("\uFF1B");
121502
+ throw new Error(
121503
+ `\u65E0\u6548\u7684 --licence-id-type\uFF1A${JSON.stringify(raw)}\u3002Kwai \u987B\u4F7F\u7528\u6570\u5B57\u4EE3\u7801\uFF08\u4E0E\u7F51\u9875\u4E00\u81F4\uFF09\uFF1A${options}\u3002\u52FF\u4F7F\u7528 ENTERPRISE / INDIVIDUAL\u3002`
121504
+ );
121505
+ }
121506
+
121507
+ // src/commands/open-account/kwai.ts
121348
121508
  async function uploadToKwai(filePath, apiBaseUrl, config, verbose) {
121349
121509
  const ext = path15.extname(filePath).toLowerCase().replace(".", "").replace("jpg", "jpeg");
121350
121510
  const imageType = ext || "jpeg";
@@ -121365,8 +121525,51 @@ async function uploadToKwai(filePath, apiBaseUrl, config, verbose) {
121365
121525
  }
121366
121526
  return blobstoreKey;
121367
121527
  }
121528
+ async function waitForKwaiAccountInHistory(config, accountName, verbose) {
121529
+ return pollUntil(
121530
+ async () => {
121531
+ const params = new URLSearchParams({
121532
+ MediaType: "Kwai",
121533
+ mediaAccountState: "Created,Approved,Denied",
121534
+ pageNo: "1",
121535
+ pageSize: "5",
121536
+ mediaCustomerName: accountName
121537
+ });
121538
+ const res = await apiFetchWithHeaders2(
121539
+ `${config.apiBaseUrl}/query/media-account/?${params}`,
121540
+ config,
121541
+ {},
121542
+ verbose
121543
+ );
121544
+ const hits = parseInt(res.headers["s-total-hits"] ?? "0", 10);
121545
+ if (hits > 0 && res.data?.length) {
121546
+ return res.data[0] ?? null;
121547
+ }
121548
+ return null;
121549
+ },
121550
+ 2e3,
121551
+ 3e4
121552
+ );
121553
+ }
121368
121554
  async function runOpenAccountKwai(opts) {
121369
121555
  const config = loadConfig(opts.token);
121556
+ let licenceIdType;
121557
+ try {
121558
+ const normalized = normalizeKwaiLicenceIdType(opts.licenceIdType);
121559
+ licenceIdType = normalized.value;
121560
+ if (normalized.legacyAlias) {
121561
+ console.error(
121562
+ `
121563
+ \u26A0\uFE0F --licence-id-type ${normalized.legacyAlias} \u5DF2\u5E9F\u5F03\uFF0C\u5DF2\u81EA\u52A8\u6620\u5C04\u4E3A ${licenceIdType}\uFF08\u7EDF\u4E00\u793E\u4F1A\u4FE1\u7528\u4EE3\u7801\uFF09\u3002\u8BF7\u6539\u7528\u6570\u5B57\u4EE3\u7801\uFF0C\u89C1 open-account-by-media.md \xA7 Kwai\u3002
121564
+ `
121565
+ );
121566
+ }
121567
+ } catch (err) {
121568
+ console.error(`
121569
+ \u274C ${err instanceof Error ? err.message : String(err)}
121570
+ `);
121571
+ process.exit(1);
121572
+ }
121370
121573
  if (!fs10.existsSync(opts.licenseFile)) {
121371
121574
  console.error(`
121372
121575
  \u274C \u8425\u4E1A\u6267\u7167\u6587\u4EF6\u4E0D\u5B58\u5728\uFF1A${opts.licenseFile}
@@ -121424,7 +121627,7 @@ async function runOpenAccountKwai(opts) {
121424
121627
  advertisementType: opts.adType,
121425
121628
  productUrl: opts.productUrl,
121426
121629
  currencyCode: "USD",
121427
- licenceIdType: opts.licenceIdType,
121630
+ licenceIdType,
121428
121631
  accountName: opts.accountName,
121429
121632
  legalEntityName: opts.companyName,
121430
121633
  newIndustryId1: opts.industryId1,
@@ -121446,14 +121649,31 @@ async function runOpenAccountKwai(opts) {
121446
121649
  { method: "POST", body: JSON.stringify(body) },
121447
121650
  opts.verbose
121448
121651
  );
121449
- console.log("\n\u2705 Kwai \u5F00\u6237\u7533\u8BF7\u5DF2\u63D0\u4EA4\u6210\u529F\uFF0C\u8BF7\u5728\u300C\u5F00\u6237\u8BB0\u5F55\u300D\u9875\u9762\u67E5\u770B\u5BA1\u6838\u72B6\u6001\u3002\n");
121450
- logAccountOpeningHistoryWebUrl(config.apiBaseUrl, "Kwai");
121451
121652
  } catch (err) {
121452
121653
  console.error(`
121453
121654
  \u274C \u63D0\u4EA4\u5931\u8D25\uFF1A${err instanceof Error ? err.message : String(err)}
121454
121655
  `);
121455
121656
  process.exit(1);
121456
121657
  }
121658
+ console.log("\n \u5DF2\u6536\u5230\u670D\u52A1\u7AEF\u53D7\u7406\uFF08HTTP 202\uFF09\uFF0C\u6B63\u5728\u786E\u8BA4\u5F00\u6237\u8BB0\u5F55\u662F\u5426\u843D\u5E93\u2026");
121659
+ const record = await waitForKwaiAccountInHistory(config, opts.accountName, opts.verbose);
121660
+ if (!record) {
121661
+ console.error(
121662
+ `
121663
+ \u274C \u5F00\u6237\u8BF7\u6C42\u5DF2\u53D7\u7406\uFF0C\u4F46\u5728 30 \u79D2\u5185\u672A\u5728\u300C\u5F00\u6237\u8BB0\u5F55\u300D\u4E2D\u67E5\u5230\u8D26\u6237\u300C${opts.accountName}\u300D\u3002
121664
+ \u5E38\u89C1\u539F\u56E0\uFF1A--licence-id-type \u975E\u6CD5\uFF08\u987B\u4E3A 1/2/3\uFF0C\u4E0E\u7F51\u9875 KwaiOpenAnAccount \u4E00\u81F4\uFF09\u3001\u884C\u4E1A ID \u65E0\u6548\u6216\u8D44\u8D28\u5B57\u6BB5\u88AB Kwai \u5F02\u6B65\u62D2\u7EDD\u3002
121665
+ \u8BF7\u6838\u5BF9\u53C2\u6570\u540E\u91CD\u8BD5\uFF0C\u6216\u6267\u884C\uFF1Asiluzan-tso account-history -m Kwai -k ${opts.accountName}
121666
+ `
121667
+ );
121668
+ process.exit(1);
121669
+ }
121670
+ const state = record.ma.mediaAccountState ?? "Unknown";
121671
+ console.log(
121672
+ `
121673
+ \u2705 Kwai \u5F00\u6237\u7533\u8BF7\u5DF2\u843D\u5E93\uFF08\u72B6\u6001\uFF1A${state}\uFF0C\u8D26\u6237\u540D\uFF1A${opts.accountName}\uFF09\u3002\u8BF7\u5728\u300C\u5F00\u6237\u8BB0\u5F55\u300D\u67E5\u770B\u5BA1\u6838\u8FDB\u5EA6\u3002
121674
+ `
121675
+ );
121676
+ logAccountOpeningHistoryWebUrl(config.apiBaseUrl, "Kwai");
121457
121677
  }
121458
121678
 
121459
121679
  // src/commands/open-account/google.ts
@@ -122347,7 +122567,10 @@ function register24(program2) {
122347
122567
  });
122348
122568
  }
122349
122569
  );
122350
- openAccountCmd.command("kwai").description("\u63D0\u4EA4 Kwai \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("--licence-id <id>", "\u8425\u4E1A\u6267\u7167\u53F7\uFF08\u4E3B\u4F53\u4EE3\u7801\uFF09").requiredOption("--licence-country <code>", "\u4E3B\u4F53\u6CE8\u518C\u56FD\u5BB6\u4EE3\u7801\uFF0C\u5982 CN").requiredOption("--licence-location <address>", "\u4E3B\u4F53\u6CE8\u518C\u5730\uFF08\u7701\u5E02\u533A\u8BE6\u7EC6\u5730\u5740\uFF09").requiredOption("--business-scope <scope>", "\u8425\u4E1A\u8303\u56F4").requiredOption("--product <name>", "\u4EA7\u54C1\u6216\u54C1\u724C\u540D\u79F0").requiredOption("--ad-type <n>", "\u8D26\u6237\u7C7B\u578B\uFF1A1=\u6548\u679C\u5E7F\u544A 2=\u54C1\u724C\u5E7F\u544A", parseInt).requiredOption("--product-url <url>", "\u4EA7\u54C1\u6216\u54C1\u724C\u7F51\u5740").requiredOption("--licence-id-type <type>", "\u5B9E\u4F53\u7C7B\u578B\uFF1AINDIVIDUAL\uFF08\u4E2A\u4EBA\uFF09/ ENTERPRISE\uFF08\u4F01\u4E1A\uFF09").requiredOption("--account-name <name>", "\u8D26\u6237\u540D\u79F0").requiredOption("--company-name <name>", "\u516C\u53F8\u4E3B\u4F53\u540D\u79F0").requiredOption("--industry-id1 <id>", "\u4E00\u7EA7\u884C\u4E1A ID").requiredOption("--industry-id2 <id>", "\u4E8C\u7EA7\u884C\u4E1A ID").requiredOption("--expire-type <n>", "\u6709\u6548\u671F\u7C7B\u578B\uFF1A1=\u6709\u9650\u671F 2=\u957F\u671F\u6709\u6548", parseInt).requiredOption("--target-country <code>", "\u6295\u653E\u5730\u533A\u56FD\u5BB6\u4EE3\u7801\uFF0C\u5982 US").requiredOption("--license-file <path>", "\u8425\u4E1A\u6267\u7167\u56FE\u7247\u672C\u5730\u8DEF\u5F84\uFF08JPG/PNG\uFF09").option("--expire-at <ms>", "\u5230\u671F\u65F6\u95F4\u6233\uFF08\u6BEB\u79D2\uFF09\uFF0Cexpire-type=1 \u65F6\u586B\u5199", 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(
122570
+ openAccountCmd.command("kwai").description("\u63D0\u4EA4 Kwai \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("--licence-id <id>", "\u8425\u4E1A\u6267\u7167\u53F7\uFF08\u4E3B\u4F53\u4EE3\u7801\uFF09").requiredOption("--licence-country <code>", "\u4E3B\u4F53\u6CE8\u518C\u56FD\u5BB6\u4EE3\u7801\uFF0C\u5982 CN").requiredOption("--licence-location <address>", "\u4E3B\u4F53\u6CE8\u518C\u5730\uFF08\u7701\u5E02\u533A\u8BE6\u7EC6\u5730\u5740\uFF09").requiredOption("--business-scope <scope>", "\u8425\u4E1A\u8303\u56F4").requiredOption("--product <name>", "\u4EA7\u54C1\u6216\u54C1\u724C\u540D\u79F0").requiredOption("--ad-type <n>", "\u8D26\u6237\u7C7B\u578B\uFF1A1=\u6548\u679C\u5E7F\u544A 2=\u54C1\u724C\u5E7F\u544A", parseInt).requiredOption("--product-url <url>", "\u4EA7\u54C1\u6216\u54C1\u724C\u7F51\u5740").requiredOption(
122571
+ "--licence-id-type <code>",
122572
+ "\u6267\u7167/\u8BC1\u4EF6\u7C7B\u578B\uFF1A1=\u7EDF\u4E00\u793E\u4F1A\u4FE1\u7528\u4EE3\u7801 2=DUNS 3=CNPJ\uFF08\u4E0E\u7F51\u9875 KwaiOpenAnAccount \u4E0B\u62C9 value \u4E00\u81F4\uFF09"
122573
+ ).requiredOption("--account-name <name>", "\u8D26\u6237\u540D\u79F0").requiredOption("--company-name <name>", "\u516C\u53F8\u4E3B\u4F53\u540D\u79F0").requiredOption("--industry-id1 <id>", "\u4E00\u7EA7\u884C\u4E1A ID").requiredOption("--industry-id2 <id>", "\u4E8C\u7EA7\u884C\u4E1A ID").requiredOption("--expire-type <n>", "\u6709\u6548\u671F\u7C7B\u578B\uFF1A1=\u6709\u9650\u671F 2=\u957F\u671F\u6709\u6548", parseInt).requiredOption("--target-country <code>", "\u6295\u653E\u5730\u533A\u56FD\u5BB6\u4EE3\u7801\uFF0C\u5982 US").requiredOption("--license-file <path>", "\u8425\u4E1A\u6267\u7167\u56FE\u7247\u672C\u5730\u8DEF\u5F84\uFF08JPG/PNG\uFF09").option("--expire-at <ms>", "\u5230\u671F\u65F6\u95F4\u6233\uFF08\u6BEB\u79D2\uFF09\uFF0Cexpire-type=1 \u65F6\u586B\u5199", 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(
122351
122574
  async (opts) => {
122352
122575
  await runOpenAccountKwai({
122353
122576
  token: opts.token,
@@ -14,48 +14,47 @@
14
14
 
15
15
  ## 文档域(gstack-style domains)
16
16
 
17
- | 域 | 路径 | 何时 Read |
18
- | --- | --- | --- |
19
- | **Core** | `references/core/` | 纪律、安装、tips、playbooks、workflows、subagent-orchestration |
20
- | **Handoff** | `snippets/` | P5/P6/P7 Task 派发模板(与 SKILL 同级) |
21
- | **Accounts** | `references/accounts/` | 列表、余额、开户、财务、审计 |
22
- | **Google Ads** | `references/google-ads/` | CRUD、PMax、搜索系列流水线;`rules/` 为优化 SOP |
23
- | **Analytics** | `references/analytics/` | 拉数、批处理、拓词、RAG、TSO 报告 |
24
- | **Operations** | `references/operations/` | 预警、线索、优化记录、宿主编排自动化 |
25
- | **Templates** | `assets/`、`report-templates/` | JSON 契约、报告纲要 |
17
+ | 域 | 路径 | 何时 Read |
18
+ | -------------- | ------------------------------ | -------------------------------------------------------------- |
19
+ | **Core** | `references/core/` | 纪律、安装、tips、playbooks、workflows、subagent-orchestration |
20
+ | **Handoff** | `snippets/` | P5/P6/P7 Task 派发模板(与 SKILL 同级) |
21
+ | **Accounts** | `references/accounts/` | 列表、余额、开户、财务、审计 |
22
+ | **Google Ads** | `references/google-ads/` | CRUD、PMax、搜索系列流水线;`rules/` 为优化 SOP |
23
+ | **Analytics** | `references/analytics/` | 拉数、批处理、拓词、RAG、TSO 报告 |
24
+ | **Operations** | `references/operations/` | 预警、线索、优化记录、宿主编排自动化 |
25
+ | **Templates** | `assets/`、`report-templates/` | JSON 契约、报告纲要 |
26
26
 
27
27
  ## 工作流目录
28
28
 
29
- | 类别 | 文档 | 编号 |
30
- | --- | --- | --- |
31
- | 分析 / 报告类 | `references/core/playbooks.md` | P1–P9 |
29
+ | 类别 | 文档 | 编号 |
30
+ | ------------- | ------------------------------ | ------ |
31
+ | 分析 / 报告类 | `references/core/playbooks.md` | P1–P9 |
32
32
  | 操作 / 管理类 | `references/core/workflows.md` | W1–W12 |
33
33
 
34
34
  专用报告模板(被工作流卡片引用):
35
35
 
36
- | ID | 文档 |
37
- | --- | --- |
38
- | 网站诊断 | `report-templates/website-diagnosis-report.md` |
39
- | 战略市场分析 | `report-templates/market-analysis-report.md` |
36
+ | ID | 文档 |
37
+ | ----------------- | ------------------------------------------------------------------------- |
38
+ | 网站诊断 | `report-templates/website-diagnosis-report.md` |
39
+ | 战略市场分析 | `report-templates/market-analysis-report.md` |
40
40
  | Google 周期 Excel | `report-templates/google-period-report-excel.md`(P4,先 outline 后脚本) |
41
- | OKKI 周报 | `report-templates/okki-weekly-google-client.md` |
42
- | 询盘分析 | `report-templates/google-inquiry-analysis.md` |
41
+ | OKKI 周报 | `report-templates/okki-weekly-google-client.md` |
42
+ | 询盘分析 | `report-templates/google-inquiry-analysis.md` |
43
43
 
44
44
  ## 维护
45
45
 
46
- - 结构规范:`references/core/skill-authoring.md`
47
- - 人类深读:`docs/skill-guide.md`
48
46
  - 源码唯一真相:`tso-cli/assets/siluzan-ads/`(勿编辑 `skills/siluzan-tso/` 副本)
47
+ - 通用纪律唯一真相源:`references/core/agent-conventions.md`(其他文档只单行指向,不复制规则)
49
48
 
50
49
  ## CLI 代码域(与文档对齐)
51
50
 
52
- | CLI 模块 | 文档域 |
53
- | --- | --- |
54
- | `src/commands/list-accounts/`、`accounts-digest/`、`balance-scan/` | accounts |
55
- | `src/commands/open-account/`、`account-manage-register.ts` | accounts |
56
- | `src/commands/ad/` | google-ads |
57
- | `src/commands/google-analysis/`、`google-analysis-batch.ts` | analytics |
58
- | `src/commands/website-diagnosis/` | analytics(网站诊断) |
59
- | `src/commands/market-analysis/` | analytics(战略市场分析) |
60
- | `src/commands/report/` | analytics + report-templates |
61
- | `src/commands/forewarning/`、`optimize/`、`clue.ts` | operations |
51
+ | CLI 模块 | 文档域 |
52
+ | ------------------------------------------------------------------ | ---------------------------- |
53
+ | `src/commands/list-accounts/`、`accounts-digest/`、`balance-scan/` | accounts |
54
+ | `src/commands/open-account/`、`account-manage-register.ts` | accounts |
55
+ | `src/commands/ad/` | google-ads |
56
+ | `src/commands/google-analysis/`、`google-analysis-batch.ts` | analytics |
57
+ | `src/commands/website-diagnosis/` | analytics(网站诊断) |
58
+ | `src/commands/market-analysis/` | analytics(战略市场分析) |
59
+ | `src/commands/report/` | analytics + report-templates |
60
+ | `src/commands/forewarning/`、`optimize/`、`clue.ts` | operations |
@@ -20,17 +20,9 @@ allowed-tools: Bash(siluzan-tso:*) Read Write
20
20
 
21
21
  <!-- 注入到 SKILL.md.tmpl 的 {{AGENT_PREAMBLE}};构建时由 gen-skill-docs.mjs 合并 -->
22
22
 
23
- > **Agent 纪律(每个新任务必读)**:Read `references/core/agent-conventions.md`,再按 `SKILL.md` 路由表 Read「必读文档」与对应工作流卡片(`core/playbooks.md` P1–P9 或 `core/workflows.md` W1–W12)。禁止跨话题复用参数记忆;数据类任务一律 `--json-out` + **仅用代码**读落盘 JSON(见 `references/core/tips.md`)——**禁止**用 Read 工具打开 `writtenFiles` 里的完整 `*.json`。
23
+ > **Agent 纪律(每个新任务必读)**:先 Read `references/core/agent-conventions.md`(唯一规则真相源:加载纪律、数据处理协议、时间/币种、批量约束、交付前自检),再按下方路由表 Read「必读文档」与对应工作流卡片。禁止跨话题复用参数记忆;数据类任务一律 `--json-out` + **仅用代码**读落盘 JSON(脚本示例见 `references/core/tips.md`)。
24
24
  >
25
- > **报告/Excel 交付前**:Read `references/core/deliverable-preflight.md`,**Read 最终产物**并按自检表确认币种与章节完整;币种只认当次 `list-accounts` `currencyCode`。
26
- >
27
- > **Google Excel(P4)**:Read `report-templates/google-period-report-excel.md`;`list-accounts -k` 核验用户 ID;拉数后**先读齐**各 `*.outline.txt` 再写脚本;禁止 `cat|head` 预览业务 JSON、禁止第三方 xlsx Skill、禁止猜字段名。
28
- >
29
- > **HTML 终稿类报告(用户未指定格式时默认 HTML)**:网站诊断 P8(`website-diagnosis render`)、Meta 周期 P4-FB(`facebook-analysis render`)、战略市场 P9(`market-analysis render`)。Agent 只写 JSON,**禁止**仅交付 Markdown 摘要或纯 JSON 充当终稿。
30
- >
31
- > **开户**:首次进入开户话题须先向用户罗列该媒体(或未指明媒体时六平台)**全部必填项**,见 `references/accounts/open-account-by-media.md` §「首次响应硬规范」。
32
- >
33
- > **Subagent(可选)**:若宿主支持 Task / 子会话,复杂报告(P5/P6/P7)或长 CLI 输出前 Read `references/core/subagent-orchestration.md`,**自行决定**是否委派;写操作确认与对用户的最终交付留在主 Agent。
25
+ > **默认交付格式**:用户未指定格式时,网站诊断 P8、Meta 周期 P4-FB、战略市场 P9 默认 **HTML**(各自 `render` 子命令),Google 周期 P4 默认 HTML;**禁止**仅交付 Markdown 摘要或纯 JSON 充当终稿。
34
26
 
35
27
  ---
36
28
 
@@ -71,11 +63,11 @@ siluzan-tso -h # 查看帮助
71
63
 
72
64
  | 用户意图(关键词) | 工作流 | 必读文档 |
73
65
  | ------------------ | ------ | -------- |
74
- | 账户列表 / 有哪些 / 有多少 / 列出全部某媒体 | W1 | `accounts/accounts.md`(§ list-accounts 意图速查:`-m <媒体> --page-size 999 --json-out`) |
75
- | 单户实时余额 | W1 | `accounts/accounts.md`(balance)+ `accounts/currency.md` |
76
- | 多账户余额 / 续航不足预警 | **P2** | `accounts/accounts.md`(balance-scan)+ `accounts/currency.md` |
77
- | 单户消耗 / 投放数据 | W1 / **P1** | `accounts/accounts.md`(stats)+ `accounts/currency.md` |
78
- | 多账户消耗/对比汇总 | **P3** | `accounts/accounts.md`(accounts-digest)+ `accounts/currency.md` |
66
+ | 账户列表 / 有哪些 / 有多少 / 列出全部某媒体 | W1 | `accounts/accounts.md`(§ list-accounts 意图速查) |
67
+ | 单户实时余额 | W1 | `accounts/accounts.md`(balance |
68
+ | 多账户余额 / 续航不足预警 | **P2** | `accounts/accounts.md`(balance-scan |
69
+ | 单户消耗 / 投放数据 | W1 / **P1** | `accounts/accounts.md`(stats |
70
+ | 多账户消耗/对比汇总 | **P3** | `accounts/accounts.md`(accounts-digest |
79
71
  | 激活/充值账单明细 | W1 | `accounts/accounts.md`(account-active-bills) |
80
72
  | 开户(六大媒体)/ 开户进度 | W2 | `accounts/open-account-by-media.md`(**首次须列全必填项**;Google 加 `accounts/open-account-google-ui.md`) |
81
73
  | 账户权限:分享/取消/解绑/重授权/MCC/BC/BM/关闭/提现/邮箱授权 | W9 | `accounts/accounts.md`(account 子命令) |
@@ -100,8 +92,8 @@ siluzan-tso -h # 查看帮助
100
92
 
101
93
  | 用户意图(关键词) | 工作流 | 必读文档 |
102
94
  | ------------------ | ------ | -------- |
103
- | 单账户投放画像 / 诊断 | **P1** | `analytics/account-analytics.md` + `core/tips.md` + `core/deliverable-preflight.md` |
104
- | Google 账户周期报告 | **P4** | `report-templates/google-period-report.md` + `analytics/account-analytics.md` + `core/tips.md` + `core/deliverable-preflight.md`;要 **Excel** 加 `report-templates/google-period-report-excel.md`(先 outline 后脚本,禁止第三方 xlsx Skill) |
95
+ | 单账户投放画像 / 诊断 | **P1** | `analytics/account-analytics.md` |
96
+ | Google 账户周期报告 | **P4** | `report-templates/google-period-report.md` + `analytics/account-analytics.md`;要 **Excel** 加 `report-templates/google-period-report-excel.md` |
105
97
  | Meta/Facebook 周期或诊断报告 | **P4-FB** | `report-templates/meta-period-report.md` + `assets/meta-period-report-rules.md` + `analytics/facebook-analysis-guide.md`;要 Excel 加 `meta-period-report-excel.md` |
106
98
  | TikTok / Bing 周期报告 | **P4** | `analytics/account-analytics.md`(report tiktok-*/bing-*)+ 对应 `report-templates/*-period-report.md` |
107
99
  | 多账户 × 多维度批处理 | **P5** | `analytics/google-analysis-batch.md` + `analytics/account-analytics.md` |
@@ -122,8 +114,6 @@ siluzan-tso -h # 查看帮助
122
114
  | 日/周巡检 | W12 | `core/workflows.md`(W12)+ `accounts/accounts.md` |
123
115
  | 宿主编排 / 投放自控 / 异常监控 / 自动优化 | — | `operations/hosted-automation-user-catalog.md`(索引)→ `operations/hosted-automation-*.md` |
124
116
 
125
- > **数据/报告类任务通用纪律**:一律 `--json-out` 落盘 + **仅用脚本**读 JSON(见 `core/tips.md`);交付前 Read 最终产物按 `core/deliverable-preflight.md` 自检(币种/章节)。
126
-
127
117
  ---
128
118
 
129
119
  ## Subagent 自主委派(可选)
@@ -142,10 +132,3 @@ siluzan-tso -h # 查看帮助
142
132
  | references 与命令对齐 | 批处理循环、限速、重试;**可选** subagent 并行 |
143
133
 
144
134
  详见 `operations/hosted-automation-self-control.md`、`operations/hosted-automation-monitoring-json.md`、`operations/hosted-automation-optimize-index.md`。
145
-
146
- ---
147
-
148
- ## 维护者
149
-
150
- - `references/core/skill-authoring.md` — 规范与检查清单
151
- - `docs/skill-guide.md` — 人类导读
@@ -1,5 +1,5 @@
1
1
  {
2
2
  "slug": "siluzan-tso",
3
- "version": "1.1.29-beta.5",
4
- "publishedAt": 1781081318464
3
+ "version": "1.1.29-beta.8",
4
+ "publishedAt": 1781235136696
5
5
  }