siluzan-tso-cli 1.1.54 → 1.1.55-beta.2

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.
Files changed (34) hide show
  1. package/README.md +2 -1
  2. package/dist/index.js +473 -231
  3. package/dist/skill/SKILL.md +2 -2
  4. package/dist/skill/_meta.json +2 -2
  5. package/dist/skill/references/accounts/accounts-list.md +3 -1
  6. package/dist/skill/references/accounts/accounts-permissions.md +2 -2
  7. package/dist/skill/references/accounts/finance.md +1 -1
  8. package/dist/skill/references/accounts/open-account-by-media.md +1 -1
  9. package/dist/skill/references/accounts/open-account-google-ui.md +1 -1
  10. package/dist/skill/references/analytics/rag.md +1 -1
  11. package/dist/skill/references/analytics/reporting.md +5 -5
  12. package/dist/skill/references/core/agent-conventions.md +6 -4
  13. package/dist/skill/references/core/playbooks.md +1 -1
  14. package/dist/skill/references/core/setup.md +5 -5
  15. package/dist/skill/references/core/subagent-orchestration.md +1 -1
  16. package/dist/skill/references/misc/tso-home.md +2 -2
  17. package/dist/skill/references/operations/guard.md +1 -1
  18. package/dist/skill/references/report-templates/README.md +1 -1
  19. package/dist/skill/references/report-templates/REPORT-WORKFLOW.md +1 -1
  20. package/dist/skill/references/report-templates/okki-weekly-google-client.md +55 -42
  21. package/dist/skill/report-templates/README.md +1 -1
  22. package/dist/skill/report-templates/REPORT-WORKFLOW.md +1 -1
  23. package/dist/skill/report-templates/okki-weekly-google-client.md +55 -42
  24. package/dist/skill/scripts/install.ps1 +3 -3
  25. package/dist/skill/scripts/install.sh +3 -3
  26. package/dist/skill/snippets/handoff-p6-okki.md +2 -2
  27. package/eval/cases/compat-account-balance.scenario.json +23 -0
  28. package/eval/cases/compat-cpa-risk-scan.scenario.json +26 -0
  29. package/eval/cases/compat-d-group-mcc.scenario.json +31 -0
  30. package/eval/cases/compat-google-analysis-run-is-real.scenario.json +23 -0
  31. package/eval/cases/compat-playbook-code-w1.scenario.json +23 -0
  32. package/eval/cases/hosted-sop-daily-budget-circuit-breaker.scenario.json +8 -2
  33. package/eval/cases/uj-patrol-google-balances-low.scenario.json +9 -3
  34. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -4049,7 +4049,7 @@ var DEFAULT_API_BASE;
4049
4049
  var init_defaults = __esm({
4050
4050
  "src/config/defaults.ts"() {
4051
4051
  "use strict";
4052
- DEFAULT_API_BASE = "https://tso-api.siluzan.com";
4052
+ DEFAULT_API_BASE = "https://tso-api-ci.siluzan.com";
4053
4053
  }
4054
4054
  });
4055
4055
 
@@ -4421,12 +4421,12 @@ var init_fetch_wrapper = __esm({
4421
4421
  });
4422
4422
 
4423
4423
  // src/utils/auth.ts
4424
- function requireWhitelistedBase(label, raw) {
4424
+ function requireWhitelistedBase(label2, raw) {
4425
4425
  const trimmed = raw.trim().replace(/\/$/, "");
4426
4426
  const err = validateBaseUrl(trimmed);
4427
4427
  if (err) {
4428
4428
  console.error(`
4429
- \u274C ${label} \u4E0D\u5408\u6CD5\uFF1A${err}`);
4429
+ \u274C ${label2} \u4E0D\u5408\u6CD5\uFF1A${err}`);
4430
4430
  process.exit(1);
4431
4431
  }
4432
4432
  return trimmed;
@@ -4529,10 +4529,10 @@ function normalizeNumericMediaCustomerId(raw) {
4529
4529
  if (!looksLikeNumericMediaCustomerId(raw)) return null;
4530
4530
  return stripMediaCustomerIdDecorators(raw);
4531
4531
  }
4532
- function requireNumericMediaCustomerId(raw, label = "-a, --account") {
4532
+ function requireNumericMediaCustomerId(raw, label2 = "-a, --account") {
4533
4533
  const trimmed = raw?.toString().trim() ?? "";
4534
4534
  if (!trimmed) {
4535
- throw new Error(`\u8BF7\u6307\u5B9A\u5A92\u4F53\u8D26\u6237 ID\uFF08${label}\uFF09`);
4535
+ throw new Error(`\u8BF7\u6307\u5B9A\u5A92\u4F53\u8D26\u6237 ID\uFF08${label2}\uFF09`);
4536
4536
  }
4537
4537
  const id = normalizeNumericMediaCustomerId(trimmed);
4538
4538
  if (!id) {
@@ -4609,6 +4609,24 @@ var init_currency_display = __esm({
4609
4609
  }
4610
4610
  });
4611
4611
 
4612
+ // src/utils/login-customer-id.ts
4613
+ function normalizeLoginCustomerId(value) {
4614
+ if (value == null) return "";
4615
+ return String(value).replace(/[-\s]/g, "").trim();
4616
+ }
4617
+ function filterByLoginCustomerId(items3, loginCustomerId) {
4618
+ const want = normalizeLoginCustomerId(loginCustomerId);
4619
+ if (!want) return [...items3];
4620
+ return items3.filter((item) => normalizeLoginCustomerId(item.ma?.loginCustomerId) === want);
4621
+ }
4622
+ var LOGIN_CUSTOMER_ID_OPTION_HELP;
4623
+ var init_login_customer_id = __esm({
4624
+ "src/utils/login-customer-id.ts"() {
4625
+ "use strict";
4626
+ LOGIN_CUSTOMER_ID_OPTION_HELP = "\u53EA\u4FDD\u7559 ma.loginCustomerId \u5339\u914D\u7684\u8D26\u6237\uFF08Google MCC\uFF1B397-889-3117 \u4E0E 3978893117 \u76F8\u540C\uFF09\u3002\u4E0D\u4F20\u5219\u4E0D\u8FC7\u6EE4";
4627
+ }
4628
+ });
4629
+
4612
4630
  // src/commands/google-analysis/daily-metrics-range.ts
4613
4631
  function pad2(n) {
4614
4632
  return String(n).padStart(2, "0");
@@ -5411,7 +5429,8 @@ async function runAccountsDigest(opts) {
5411
5429
  const maxPages = Math.max(1, Math.min(200, opts.maxPages ?? 20));
5412
5430
  let accountsList;
5413
5431
  let scannedFromList = false;
5414
- if (filterSet.size > 0) {
5432
+ const restrictToMcc = !!opts.loginCustomerId?.trim();
5433
+ if (filterSet.size > 0 && !restrictToMcc) {
5415
5434
  const mediaLookups = media === "MetaAd" ? await lookupMetaMediaAccounts(config, filterIds, opts.verbose) : /* @__PURE__ */ new Map();
5416
5435
  accountsList = filterIds.map((id) => {
5417
5436
  const row = mediaLookups.get(id);
@@ -5443,6 +5462,20 @@ async function runAccountsDigest(opts) {
5443
5462
  process.exit(1);
5444
5463
  }
5445
5464
  }
5465
+ if (restrictToMcc) {
5466
+ const before = accountsList.length;
5467
+ accountsList = filterByLoginCustomerId(accountsList, opts.loginCustomerId);
5468
+ if (filterSet.size > 0) {
5469
+ const wanted = new Set([...filterSet].map((id) => id.replace(/[-\s]/g, "")));
5470
+ accountsList = accountsList.filter(
5471
+ (item) => wanted.has(String(item.ma?.mediaCustomerId ?? "").replace(/[-\s]/g, ""))
5472
+ );
5473
+ }
5474
+ process.stderr.write(
5475
+ `\u23F3 [accounts-digest] --login-customer-id \u4FDD\u7559 ${accountsList.length}/${before} \u6237
5476
+ `
5477
+ );
5478
+ }
5446
5479
  const validIds = accountsList.filter((it) => it.ma?.mediaCustomerId && !it.ma?.invalidOAuthToken).map((it) => String(it.ma.mediaCustomerId));
5447
5480
  let balanceMap = /* @__PURE__ */ new Map();
5448
5481
  let overviewMap = /* @__PURE__ */ new Map();
@@ -5658,6 +5691,7 @@ var init_run = __esm({
5658
5691
  init_media_account_batch();
5659
5692
  init_media_account_lookup();
5660
5693
  init_list_fetch();
5694
+ init_login_customer_id();
5661
5695
  init_brief();
5662
5696
  init_filters();
5663
5697
  }
@@ -5682,7 +5716,7 @@ function register10(program2) {
5682
5716
  "--skip-balance",
5683
5717
  "\u53EA\u62C9\u6D88\u8017\u3001\u4E0D\u62C9\u4F59\u989D\uFF08\u8F6C\u5316\u6210\u672C/CPA \u5DE1\u68C0\u63A8\u8350\uFF1B\u53EF\u5C11\u4E00\u534A\u8BF7\u6C42\u65F6\u95F4\uFF09",
5684
5718
  false
5685
- ).option("--page-size <n>", "\u8D26\u6237\u6E05\u5355\u5206\u9875\u5927\u5C0F\uFF08\u9ED8\u8BA4 200\uFF0C\u4E0A\u9650 500\uFF09", (v) => parseInt(v, 10)).option("--max-pages <n>", "\u6700\u591A\u626B\u63CF\u9875\u6570\uFF08\u9ED8\u8BA4 20\uFF0C\u4E0A\u9650 200\uFF09", (v) => parseInt(v, 10)).option("-t, --token <token>", "Token\uFF08\u53EF\u9009\uFF1B\u4F18\u5148\u4E8E ~/.siluzan/config.json\uFF09").option(
5719
+ ).option("--page-size <n>", "\u8D26\u6237\u6E05\u5355\u5206\u9875\u5927\u5C0F\uFF08\u9ED8\u8BA4 200\uFF0C\u4E0A\u9650 500\uFF09", (v) => parseInt(v, 10)).option("--login-customer-id <id>", LOGIN_CUSTOMER_ID_OPTION_HELP).option("--max-pages <n>", "\u6700\u591A\u626B\u63CF\u9875\u6570\uFF08\u9ED8\u8BA4 20\uFF0C\u4E0A\u9650 200\uFF09", (v) => parseInt(v, 10)).option("-t, --token <token>", "Token\uFF08\u53EF\u9009\uFF1B\u4F18\u5148\u4E8E ~/.siluzan/config.json\uFF09").option(
5686
5720
  "--json-out <path>",
5687
5721
  "\u843D\u76D8\uFF08\u76EE\u5F55\u6216 *.json \u6587\u4EF6\u8DEF\u5F84\uFF09\u5E76\u66F4\u65B0 cli-manifest[-<\u67E5\u8BE2id>].json\uFF1B\u76EE\u5F55\u6A21\u5F0F\u6587\u4EF6\u540D\u4E3A `<section>[-<\u67E5\u8BE2id>].json`\uFF1Bstdout \u4E00\u884C\u6458\u8981 JSON\uFF0C\u542B outlineFile\uFF08TS \u5F0F\u7C7B\u578B\u5728 `*.outline.txt`\uFF09",
5688
5722
  void 0
@@ -5702,7 +5736,8 @@ function register10(program2) {
5702
5736
  maxPages: opts.maxPages,
5703
5737
  jsonOut: opts.jsonOut,
5704
5738
  refreshDp: opts.refreshDp,
5705
- verbose: opts.verbose
5739
+ verbose: opts.verbose,
5740
+ loginCustomerId: opts.loginCustomerId
5706
5741
  });
5707
5742
  }
5708
5743
  );
@@ -5711,6 +5746,7 @@ var init_register = __esm({
5711
5746
  "src/commands/accounts-digest/_register.ts"() {
5712
5747
  "use strict";
5713
5748
  init_run();
5749
+ init_login_customer_id();
5714
5750
  }
5715
5751
  });
5716
5752
 
@@ -6262,9 +6298,9 @@ function xfXml(x) {
6262
6298
  function stylesXml(reg) {
6263
6299
  return `<?xml version="1.0" encoding="UTF-8" standalone="yes"?><styleSheet xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main"><fonts count="${reg.fonts.length}">${reg.fonts.map(fontXml).join("")}</fonts><fills count="${reg.fills.length}">${reg.fills.map(fillXml).join("")}</fills><borders count="${reg.borders.length}">${reg.borders.map(borderXml).join("")}</borders><cellStyleXfs count="1"><xf numFmtId="0" fontId="0" fillId="0" borderId="0"/></cellStyleXfs><cellXfs count="${reg.xfs.length}">${reg.xfs.map(xfXml).join("")}</cellXfs><cellStyles count="1"><cellStyle name="\u5E38\u89C4" xfId="0" builtinId="0"/></cellStyles></styleSheet>`;
6264
6300
  }
6265
- function cellXml(ref, cell3) {
6266
- if (cell3 == null) return "";
6267
- const { value, styleId } = cell3;
6301
+ function cellXml(ref, cell5) {
6302
+ if (cell5 == null) return "";
6303
+ const { value, styleId } = cell5;
6268
6304
  const sAttr = styleId ? ` s="${styleId}"` : "";
6269
6305
  if (value == null || value === "") {
6270
6306
  return styleId ? `<c r="${ref}"${sAttr}/>` : "";
@@ -6279,7 +6315,7 @@ function sheetXml(sheet) {
6279
6315
  const rowsXml = sheet.rows.map((row, i) => {
6280
6316
  const r = i + 1;
6281
6317
  const htAttr = row.height ? ` ht="${row.height}" customHeight="1"` : "";
6282
- const cells = row.cells.map((cell3, cIdx) => cellXml(`${colLetter(cIdx)}${r}`, cell3)).join("");
6318
+ const cells = row.cells.map((cell5, cIdx) => cellXml(`${colLetter(cIdx)}${r}`, cell5)).join("");
6283
6319
  return `<row r="${r}"${htAttr}>${cells}</row>`;
6284
6320
  }).join("");
6285
6321
  const mergesXml = sheet.merges.length ? `<mergeCells count="${sheet.merges.length}">${sheet.merges.map((m) => `<mergeCell ref="${m}"/>`).join("")}</mergeCells>` : "";
@@ -6541,7 +6577,7 @@ var init_xlsx_style_engine = __esm({
6541
6577
  this.pushRow(rowCells, { height: maxHeight });
6542
6578
  return this;
6543
6579
  }
6544
- kvRow(label, value, opts = {}) {
6580
+ kvRow(label2, value, opts = {}) {
6545
6581
  const isShaded = opts.shaded ?? this.zebra % 2 === 1;
6546
6582
  this.zebra += 1;
6547
6583
  const labelStyle = this.registry.resolve({
@@ -6563,7 +6599,7 @@ var init_xlsx_style_engine = __esm({
6563
6599
  const height = estimateWrapHeight(value, this.colWidths[1] || 40);
6564
6600
  const rowIndex = this.pushRow(
6565
6601
  [
6566
- { value: label, styleId: labelStyle },
6602
+ { value: label2, styleId: labelStyle },
6567
6603
  { value: value ?? "", styleId: valueStyle }
6568
6604
  ],
6569
6605
  { height }
@@ -7209,7 +7245,7 @@ function sleep3(ms, signal) {
7209
7245
  signal?.addEventListener("abort", onAbort, { once: true });
7210
7246
  });
7211
7247
  }
7212
- async function withTaskTimeout(factory, timeoutMs, label) {
7248
+ async function withTaskTimeout(factory, timeoutMs, label2) {
7213
7249
  if (!timeoutMs || timeoutMs <= 0) return factory();
7214
7250
  let timer;
7215
7251
  try {
@@ -7217,7 +7253,7 @@ async function withTaskTimeout(factory, timeoutMs, label) {
7217
7253
  factory(),
7218
7254
  new Promise((_, reject) => {
7219
7255
  timer = setTimeout(() => {
7220
- reject(new Error(`\u8BF7\u6C42\u8D85\u65F6\uFF08${(timeoutMs / 1e3).toFixed(0)} \u79D2\uFF09\uFF1A${label}`));
7256
+ reject(new Error(`\u8BF7\u6C42\u8D85\u65F6\uFF08${(timeoutMs / 1e3).toFixed(0)} \u79D2\uFF09\uFF1A${label2}`));
7221
7257
  }, timeoutMs);
7222
7258
  })
7223
7259
  ]);
@@ -102697,19 +102733,19 @@ function buildSearchParams(def, start, end, extras) {
102697
102733
  const s = params.toString();
102698
102734
  return s ? `?${s}` : "";
102699
102735
  }
102700
- async function fetchGoogleAnalysisHttp(label, factory, http2) {
102736
+ async function fetchGoogleAnalysisHttp(label2, factory, http2) {
102701
102737
  return fetchWithRetry(factory, {
102702
- label,
102738
+ label: label2,
102703
102739
  policy: { ...DEFAULT_RETRY_POLICY, ...http2?.retry },
102704
102740
  signal: http2?.signal
102705
102741
  });
102706
102742
  }
102707
- async function fetchJson(config, pathWithQuery, verbose, label = pathWithQuery, http2) {
102743
+ async function fetchJson(config, pathWithQuery, verbose, label2 = pathWithQuery, http2) {
102708
102744
  const url = `${config.googleApiUrl}${pathWithQuery}`;
102709
- return fetchGoogleAnalysisHttp(label, () => apiFetch2(url, config, {}, verbose), http2);
102745
+ return fetchGoogleAnalysisHttp(label2, () => apiFetch2(url, config, {}, verbose), http2);
102710
102746
  }
102711
- async function fetchMainPlatformJson(url, config, verbose, label, http2) {
102712
- return fetchGoogleAnalysisHttp(label, () => apiFetch2(url, config, {}, verbose), http2);
102747
+ async function fetchMainPlatformJson(url, config, verbose, label2, http2) {
102748
+ return fetchGoogleAnalysisHttp(label2, () => apiFetch2(url, config, {}, verbose), http2);
102713
102749
  }
102714
102750
  function deviceBidModifierLookupKey(campaignId, adGroupId, deviceType) {
102715
102751
  return `${campaignId ?? ""}\0${adGroupId ?? ""}\0${deviceType ?? ""}`;
@@ -102761,8 +102797,8 @@ function rowsFromAccountDailyReportsEnvelope(raw, mediaCustomerId) {
102761
102797
  const list = block?.data;
102762
102798
  return Array.isArray(list) ? list : [];
102763
102799
  }
102764
- async function fetchGoogleAnalysisSectionJson(config, fullPath, verbose, name2, label, http2) {
102765
- const fetchSection = () => fetchJson(config, fullPath, verbose, label, http2);
102800
+ async function fetchGoogleAnalysisSectionJson(config, fullPath, verbose, name2, label2, http2) {
102801
+ const fetchSection = () => fetchJson(config, fullPath, verbose, label2, http2);
102766
102802
  switch (name2) {
102767
102803
  case "overview":
102768
102804
  return fetchSection();
@@ -103477,12 +103513,12 @@ function validateOkkiWeeklyReportContent(data) {
103477
103513
  const summary = stringList2(block?.summary);
103478
103514
  const suggestions = stringList2(block?.suggestions);
103479
103515
  sheetAnalysisCounts[key] = { summary: summary.length, suggestions: suggestions.length };
103480
- const label = SHEET_LABELS[key];
103516
+ const label2 = SHEET_LABELS[key];
103481
103517
  if (summary.length < 1) {
103482
103518
  pushMissing(
103483
103519
  missing,
103484
103520
  `sheet-${key}-summary`,
103485
- `\u8868\u672B\u5206\u6790 \xB7 ${label}`,
103521
+ `\u8868\u672B\u5206\u6790 \xB7 ${label2}`,
103486
103522
  `narrative.sheetAnalysis.${key}.summary`,
103487
103523
  `\u22651 \u6761\u603B\u7ED3\uFF08\u5F53\u524D ${summary.length} \u6761\uFF09\u3002\u8868\u4E3A\u7A7A\u65F6\u4E5F\u987B\u5199\u300C\u672C\u5468\u671F\u65E0\u8BE5\u7EF4\u5EA6\u6570\u636E\u300D`
103488
103524
  );
@@ -103491,7 +103527,7 @@ function validateOkkiWeeklyReportContent(data) {
103491
103527
  pushMissing(
103492
103528
  missing,
103493
103529
  `sheet-${key}-suggestions`,
103494
- `\u8868\u672B\u5206\u6790 \xB7 ${label}`,
103530
+ `\u8868\u672B\u5206\u6790 \xB7 ${label2}`,
103495
103531
  `narrative.sheetAnalysis.${key}.suggestions`,
103496
103532
  `\u22651 \u6761\u5EFA\u8BAE\uFF08\u5F53\u524D ${suggestions.length} \u6761\uFF09\u3002\u8868\u4E3A\u7A7A\u65F6\u4E5F\u987B\u5199\u53EF\u6267\u884C\u5EFA\u8BAE\u6216\u300C\u6682\u65E0\u8C03\u6574\u300D`
103497
103533
  );
@@ -103504,12 +103540,12 @@ function validateOkkiWeeklyReportContent(data) {
103504
103540
  const summary = textLen(block?.summary);
103505
103541
  const suggestion = textLen(block?.suggestion);
103506
103542
  reviewFilled[key] = overview > 0 && summary > 0 && suggestion > 0;
103507
- const label = REVIEW_LABELS[key];
103543
+ const label2 = REVIEW_LABELS[key];
103508
103544
  if (overview < 1) {
103509
103545
  pushMissing(
103510
103546
  missing,
103511
103547
  `review-${key}-overview`,
103512
- `\u6570\u636E\u590D\u76D8 \xB7 ${label}`,
103548
+ `\u6570\u636E\u590D\u76D8 \xB7 ${label2}`,
103513
103549
  `narrative.review.${key}.overview`,
103514
103550
  "\u5FC5\u586B\u4E00\u6BB5\u603B\u89C8\uFF08\u5F15\u7528\u8868\u4E2D\u6570\u5B57\uFF1B\u65E0\u6570\u636E\u4E5F\u987B\u5199\u660E\uFF09"
103515
103551
  );
@@ -103518,7 +103554,7 @@ function validateOkkiWeeklyReportContent(data) {
103518
103554
  pushMissing(
103519
103555
  missing,
103520
103556
  `review-${key}-summary`,
103521
- `\u6570\u636E\u590D\u76D8 \xB7 ${label}`,
103557
+ `\u6570\u636E\u590D\u76D8 \xB7 ${label2}`,
103522
103558
  `narrative.review.${key}.summary`,
103523
103559
  "\u5FC5\u586B\u300C\u603B\u7ED3\u300D"
103524
103560
  );
@@ -103527,7 +103563,7 @@ function validateOkkiWeeklyReportContent(data) {
103527
103563
  pushMissing(
103528
103564
  missing,
103529
103565
  `review-${key}-suggestion`,
103530
- `\u6570\u636E\u590D\u76D8 \xB7 ${label}`,
103566
+ `\u6570\u636E\u590D\u76D8 \xB7 ${label2}`,
103531
103567
  `narrative.review.${key}.suggestion`,
103532
103568
  "\u5FC5\u586B\u300C\u5EFA\u8BAE\u300D"
103533
103569
  );
@@ -107493,8 +107529,8 @@ async function runInit(options) {
107493
107529
  for (const entry of targets) {
107494
107530
  for (const key of entry.keys) {
107495
107531
  const destDir = entry.isGlobal ? GLOBAL_DIRS[key](home) : PROJECT_DIRS[key](options.cwd);
107496
- const label = entry.isGlobal ? `${key} global` : key;
107497
- console.log(`[${label}] \u2192 ${destDir}`);
107532
+ const label2 = entry.isGlobal ? `${key} global` : key;
107533
+ console.log(`[${label2}] \u2192 ${destDir}`);
107498
107534
  const anyWritten = await writeSkillFilesToDir(destDir, skillFiles, options.force);
107499
107535
  if (anyWritten) {
107500
107536
  installedEntries.push({
@@ -108050,6 +108086,7 @@ function wrapListJson(params) {
108050
108086
  }
108051
108087
 
108052
108088
  // src/commands/list-accounts/main.ts
108089
+ init_login_customer_id();
108053
108090
  async function runListAccounts(opts) {
108054
108091
  let config = loadConfig(opts.token);
108055
108092
  if (opts.refreshDp) {
@@ -108139,6 +108176,18 @@ async function runListAccounts(opts) {
108139
108176
  stripListAccountsEnrichmentFields(item, exposeScopeActivated);
108140
108177
  }
108141
108178
  }
108179
+ if (opts.loginCustomerId?.trim()) {
108180
+ const fetched = items3.length;
108181
+ items3 = filterByLoginCustomerId(items3, opts.loginCustomerId);
108182
+ const fetchedAll = total === void 0 || (page - 1) * pageSize + fetched >= total;
108183
+ if (fetchedAll) {
108184
+ total = items3.length;
108185
+ } else if (fetched >= pageSize) {
108186
+ console.error(
108187
+ "\u26A0\uFE0F --login-customer-id \u53EA\u8FC7\u6EE4\u4E86\u672C\u9875\u3002\u8BF7\u52A0\u5927 --page-size\uFF0C\u4EE5\u8986\u76D6\u8BE5 MCC \u7684\u5168\u90E8\u8D26\u6237\u3002\n"
108188
+ );
108189
+ }
108190
+ }
108142
108191
  const oauthFailWarning = (() => {
108143
108192
  if (items3.length < 5) return null;
108144
108193
  const allFail = items3.every((it) => it.ma?.invalidOAuthToken === true);
@@ -108215,6 +108264,7 @@ async function runListAccounts(opts) {
108215
108264
  }
108216
108265
 
108217
108266
  // src/commands/list-accounts/register.ts
108267
+ init_login_customer_id();
108218
108268
  function register6(program2) {
108219
108269
  program2.command("list-accounts").description(
108220
108270
  "\u67E5\u8BE2\u5E7F\u544A\u8D26\u6237\u5217\u8868\u3002\u5F53\u524D\u8D26\u6237\u5728 TSO \u5E73\u53F0\u5173\u8054\u7684\u5168\u90E8\u5E7F\u544A\u8D26\u6237\uFF08Google/TikTok/Yandex/MetaAd/BingV2 \u7B49\u5A92\u4F53\uFF09"
@@ -108232,7 +108282,7 @@ function register6(program2) {
108232
108282
  "--page-size <n>",
108233
108283
  "\u6BCF\u9875\u6570\u91CF\uFF08\u4EA4\u4E92\u9ED8\u8BA4 20\uFF1B\u5E26 --json-out \u4E14\u672A\u6307\u5B9A\u65F6 999\uFF09",
108234
108284
  parseInt
108235
- ).option("-t, --token <token>", "Token\uFF08\u53EF\u9009\uFF1B\u4F18\u5148\u4E8E ~/.siluzan/config.json\uFF09").option(
108285
+ ).option("--login-customer-id <id>", LOGIN_CUSTOMER_ID_OPTION_HELP).option("-t, --token <token>", "Token\uFF08\u53EF\u9009\uFF1B\u4F18\u5148\u4E8E ~/.siluzan/config.json\uFF09").option(
108236
108286
  "--json-out <path>",
108237
108287
  "\u843D\u76D8\uFF08\u76EE\u5F55\u6216 *.json \u6587\u4EF6\u8DEF\u5F84\uFF09\u5E76\u66F4\u65B0 cli-manifest[-<\u67E5\u8BE2id>].json\uFF1B\u76EE\u5F55\u6A21\u5F0F\u6587\u4EF6\u540D\u4E3A `<section>[-<\u67E5\u8BE2id>].json`\uFF1Bstdout \u4E00\u884C\u6458\u8981 JSON\uFF0C\u542B outlineFile\uFF08TS \u5F0F\u7C7B\u578B\u5728 `*.outline.txt`\uFF09",
108238
108288
  void 0
@@ -108252,7 +108302,8 @@ function register6(program2) {
108252
108302
  jsonOut: opts.jsonOut,
108253
108303
  unicode: opts.unicode,
108254
108304
  refreshDp: opts.refreshDp,
108255
- verbose: opts.verbose
108305
+ verbose: opts.verbose,
108306
+ loginCustomerId: opts.loginCustomerId
108256
108307
  });
108257
108308
  }
108258
108309
  );
@@ -108528,6 +108579,38 @@ function register8(program2) {
108528
108579
  // src/commands/balance-scan/run.ts
108529
108580
  init_auth();
108530
108581
  init_cli_json_snapshot();
108582
+
108583
+ // src/commands/balance-scan/delivery.ts
108584
+ var DELIVERY_RULE = "\u53EA\u628A userDelivery \u539F\u6837\u53D1\u7ED9\u7528\u6237\u3002\u65E0\u547D\u4E2D\u7528\u539F\u53E5\u300C\u4ECA\u65E5\u65E0\u547D\u4E2D\u300D\u3002\u4E0D\u8981\u53E6\u5199\u62A5\u544A\u3002\u5BBF\u4E3B\u8D1F\u8D23 present_files\u3002";
108585
+ var PATROL_ALL_CLEAR = "\u4ECA\u65E5\u65E0\u547D\u4E2D";
108586
+ function cell(value) {
108587
+ return value.replace(/\|/g, "\uFF5C").replace(/\r?\n/g, " ");
108588
+ }
108589
+ function label(hit) {
108590
+ return hit.advertiserName || hit.name || "-";
108591
+ }
108592
+ function buildBalanceScanDelivery(items3, dataIssueMessage) {
108593
+ if (dataIssueMessage) {
108594
+ return { allClear: false, userDelivery: dataIssueMessage, deliveryRule: DELIVERY_RULE };
108595
+ }
108596
+ const hits = items3.filter((row) => row.hitReason !== "none");
108597
+ if (hits.length === 0) {
108598
+ return { allClear: true, userDelivery: PATROL_ALL_CLEAR, deliveryRule: DELIVERY_RULE };
108599
+ }
108600
+ const header = "| \u8D26\u6237\u540D\u79F0 | \u8D26\u6237ID | \u4F59\u989D | \u5E01\u79CD |\n| --- | --- | ---: | --- |";
108601
+ const lines = hits.map((h) => {
108602
+ const balance = h.balance == null ? "\u2014" : String(h.balance);
108603
+ return `| ${cell(label(h))} | ${h.mediaCustomerId} | ${balance} | ${h.currencyCode ?? "\u2014"} |`;
108604
+ });
108605
+ return {
108606
+ allClear: false,
108607
+ userDelivery: [header, ...lines].join("\n"),
108608
+ deliveryRule: DELIVERY_RULE
108609
+ };
108610
+ }
108611
+
108612
+ // src/commands/balance-scan/run.ts
108613
+ init_login_customer_id();
108531
108614
  init_balance();
108532
108615
  init_cli_table();
108533
108616
  init_currency_display();
@@ -108788,7 +108871,7 @@ async function runBalanceScan(opts) {
108788
108871
  const pageSize = Math.max(1, Math.min(500, opts.pageSize ?? 200));
108789
108872
  const maxPages = Math.max(1, Math.min(200, opts.maxPages ?? 20));
108790
108873
  const filterIds = (opts.accounts ?? "").split(",").map((s) => s.trim()).filter(Boolean);
108791
- const isSubset = filterIds.length > 0;
108874
+ const isSubset = filterIds.length > 0 && !opts.loginCustomerId?.trim();
108792
108875
  let allItems;
108793
108876
  let total;
108794
108877
  if (isSubset) {
@@ -108817,6 +108900,20 @@ async function runBalanceScan(opts) {
108817
108900
  total = res.total;
108818
108901
  process.stderr.write(
108819
108902
  `\r\u23F3 \u8D26\u6237\u6E05\u5355\u5DF2\u62C9\u53D6\uFF1A\u5171 ${allItems.length} \u6761${total !== void 0 ? `\uFF08\u63A5\u53E3 total\u2248${total}\uFF09` : ""}
108903
+ `
108904
+ );
108905
+ }
108906
+ if (opts.loginCustomerId?.trim()) {
108907
+ const before = allItems.length;
108908
+ allItems = filterByLoginCustomerId(allItems, opts.loginCustomerId);
108909
+ if (filterIds.length > 0) {
108910
+ const wanted = new Set(filterIds.map((id) => id.replace(/[-\s]/g, "")));
108911
+ allItems = allItems.filter(
108912
+ (item) => wanted.has(String(item.ma?.mediaCustomerId ?? "").replace(/[-\s]/g, ""))
108913
+ );
108914
+ }
108915
+ process.stderr.write(
108916
+ `\u23F3 [balance-scan] --login-customer-id \u4FDD\u7559 ${allItems.length}/${before} \u6237
108820
108917
  `
108821
108918
  );
108822
108919
  }
@@ -108914,13 +109011,15 @@ async function runBalanceScan(opts) {
108914
109011
  totalReported: total ?? null,
108915
109012
  generatedAt: (/* @__PURE__ */ new Date()).toISOString()
108916
109013
  };
108917
- const scanPayload = { ok: !dataIssue, data: { items: evaluated }, meta };
109014
+ const agentBrief = buildBalanceScanDelivery(evaluated, dataIssue?.message ?? null);
109015
+ const scanPayload = { ok: !dataIssue, data: { items: evaluated }, meta, agentBrief };
108918
109016
  const wroteJson = await emitCliJsonOrSnapshot(opts, {
108919
109017
  section: `balance-scan-${media}`,
108920
109018
  commandLabel: "balance-scan",
108921
109019
  commandHint: media,
108922
109020
  payload: scanPayload,
108923
- idSuffix: media
109021
+ idSuffix: media,
109022
+ summaryExtras: { userDelivery: agentBrief.userDelivery }
108924
109023
  });
108925
109024
  if (dataIssue) {
108926
109025
  console.error(`
@@ -108994,6 +109093,7 @@ ${media} \u8D26\u6237\u4F59\u989D\u626B\u63CF\u5B8C\u6210\uFF1A\u5171\u626B\u63C
108994
109093
  }
108995
109094
 
108996
109095
  // src/commands/balance-scan/_register.ts
109096
+ init_login_customer_id();
108997
109097
  function register9(program2) {
108998
109098
  program2.command("balance-scan").description(
108999
109099
  "\u4E00\u952E\u626B\u63CF\u67D0\u5A92\u4F53\u4E0B\u6709\u6548\u8D26\u6237\u7684\u4F59\u989D\u4E0E\u65E5\u5747\u6D88\u8017\uFF0C\u8FD4\u56DE\u5168\u90E8\u5DF2\u68C0\u67E5\u8D26\u6237\uFF1B\u7528 hitReason \u6807\u8BB0\u7EED\u822A/\u4F59\u989D\u4E0D\u8DB3\u7684\u9884\u8B66\u884C\u3002\u66FF\u4EE3\u5FAA\u73AF\u8C03\u7528 balance \u7684\u4F20\u7EDF\u505A\u6CD5\u3002"
@@ -109015,7 +109115,7 @@ function register9(program2) {
109015
109115
  "--min-daily-spend <n>",
109016
109116
  "\u8FD1 N \u65E5\u65E5\u5747\u6D88\u8017 < \u6B64\u503C\u7684\u8D26\u6237\u89C6\u4E3A\u50F5\u5C38\u8D26\u6237\u4E0D\u505A\u7EED\u822A\u4F30\u7B97\uFF08\u9ED8\u8BA4 0.01\uFF1BN \u89C1 --spend-days\uFF09",
109017
109117
  (v) => parseFloat(v)
109018
- ).option("--target-days <n>", "\u5EFA\u8BAE\u5145\u503C\u6309\u6B64\u76EE\u6807\u7EED\u822A\u5929\u6570\u8BA1\u7B97\uFF08\u9ED8\u8BA4 30\uFF09", (v) => parseFloat(v)).option("--page-size <n>", "\u5206\u9875\u5927\u5C0F\uFF08\u9ED8\u8BA4 200\uFF0C\u4E0A\u9650 500\uFF09", (v) => parseInt(v, 10)).option(
109118
+ ).option("--target-days <n>", "\u5EFA\u8BAE\u5145\u503C\u6309\u6B64\u76EE\u6807\u7EED\u822A\u5929\u6570\u8BA1\u7B97\uFF08\u9ED8\u8BA4 30\uFF09", (v) => parseFloat(v)).option("--page-size <n>", "\u5206\u9875\u5927\u5C0F\uFF08\u9ED8\u8BA4 200\uFF0C\u4E0A\u9650 500\uFF09", (v) => parseInt(v, 10)).option("--login-customer-id <id>", LOGIN_CUSTOMER_ID_OPTION_HELP).option(
109019
109119
  "--max-pages <n>",
109020
109120
  "\u6700\u591A\u626B\u63CF\u9875\u6570\uFF08\u9ED8\u8BA4 20\uFF0C\u4E0A\u9650 200\uFF1B\u8D85\u51FA\u540E\u8BF7\u63D0\u9AD8 --page-size \u6216\u5206\u6B21\u626B\u63CF\uFF09",
109021
109121
  (v) => parseInt(v, 10)
@@ -109038,7 +109138,8 @@ function register9(program2) {
109038
109138
  maxPages: opts.maxPages,
109039
109139
  jsonOut: opts.jsonOut,
109040
109140
  refreshDp: opts.refreshDp,
109041
- verbose: opts.verbose
109141
+ verbose: opts.verbose,
109142
+ loginCustomerId: opts.loginCustomerId
109042
109143
  });
109043
109144
  }
109044
109145
  );
@@ -109053,13 +109154,14 @@ init_cli_json_snapshot();
109053
109154
  // src/commands/guard/shared.ts
109054
109155
  init_auth();
109055
109156
  init_list_fetch();
109157
+ init_login_customer_id();
109056
109158
 
109057
109159
  // src/commands/ad/_shared.ts
109058
109160
  init_auth();
109059
109161
  init_media_customer_id();
109060
- function resolveAdAccountId(account, label = "-a, --account") {
109162
+ function resolveAdAccountId(account, label2 = "-a, --account") {
109061
109163
  try {
109062
- return requireNumericMediaCustomerId(account, label);
109164
+ return requireNumericMediaCustomerId(account, label2);
109063
109165
  } catch (e) {
109064
109166
  console.error(`
109065
109167
  \u274C ${e instanceof Error ? e.message : String(e)}
@@ -109173,7 +109275,8 @@ function assertGoogleOnly(media) {
109173
109275
  }
109174
109276
  async function resolveGuardAccounts(opts, config) {
109175
109277
  const filterIds = (opts.accounts ?? "").split(",").map((s) => s.trim()).filter(Boolean);
109176
- if (filterIds.length > 0) {
109278
+ const wantMcc = !!opts.loginCustomerId?.trim();
109279
+ if (filterIds.length > 0 && !wantMcc) {
109177
109280
  process.stderr.write(`\u23F3 [guard] \u5B50\u96C6\u6A21\u5F0F\uFF1A\u5BF9 -a \u6307\u5B9A\u7684 ${filterIds.length} \u4E2A\u8D26\u6237\u626B\u63CF\u3002
109178
109281
  `);
109179
109282
  return filterIds.map((id) => ({ mediaCustomerId: id, name: null }));
@@ -109185,7 +109288,22 @@ async function resolveGuardAccounts(opts, config) {
109185
109288
  maxPages,
109186
109289
  verbose: opts.verbose
109187
109290
  });
109188
- return res.items.map((item) => ({
109291
+ let items3 = res.items;
109292
+ if (wantMcc) {
109293
+ const before = items3.length;
109294
+ items3 = filterByLoginCustomerId(items3, opts.loginCustomerId);
109295
+ process.stderr.write(
109296
+ `\u23F3 [guard] --login-customer-id \u4FDD\u7559 ${items3.length}/${before} \u6237
109297
+ `
109298
+ );
109299
+ }
109300
+ if (filterIds.length > 0) {
109301
+ const wanted = new Set(filterIds.map((id) => id.replace(/[-\s]/g, "")));
109302
+ items3 = items3.filter(
109303
+ (item) => wanted.has(String(item.ma?.mediaCustomerId ?? "").replace(/[-\s]/g, ""))
109304
+ );
109305
+ }
109306
+ return items3.map((item) => ({
109189
109307
  mediaCustomerId: String(item.ma?.mediaCustomerId ?? ""),
109190
109308
  name: item.ma?.mediaCustomerName ?? null
109191
109309
  })).filter((a) => a.mediaCustomerId);
@@ -109268,6 +109386,41 @@ ${title}
109268
109386
  console.log();
109269
109387
  }
109270
109388
 
109389
+ // src/commands/guard/delivery.ts
109390
+ var DELIVERY_RULE2 = "\u53EA\u628A userDelivery \u539F\u6837\u53D1\u7ED9\u7528\u6237\u3002\u65E0\u547D\u4E2D\u7528\u539F\u53E5\u300C\u4ECA\u65E5\u65E0\u547D\u4E2D\u300D\u3002\u4E0D\u8981\u53E6\u5199\u62A5\u544A\u3002\u5BBF\u4E3B\u8D1F\u8D23 present_files\u3002";
109391
+ var PATROL_ALL_CLEAR2 = "\u4ECA\u65E5\u65E0\u547D\u4E2D";
109392
+ function cell2(value) {
109393
+ return value.replace(/\|/g, "\uFF5C").replace(/\r?\n/g, " ");
109394
+ }
109395
+ function buildBudgetCircuitDelivery(hits) {
109396
+ if (hits.length === 0) {
109397
+ return { allClear: true, userDelivery: PATROL_ALL_CLEAR2, deliveryRule: DELIVERY_RULE2 };
109398
+ }
109399
+ const header = "| \u7CFB\u5217\u540D\u79F0 | \u7CFB\u5217ID | \u8D26\u6237ID | \u5F53\u65E5\u82B1\u8D39 | \u65E5\u9884\u7B97 |\n| --- | --- | --- | ---: | ---: |";
109400
+ const lines = hits.map(
109401
+ (h) => `| ${cell2(h.campaignName)} | ${h.campaignId} | ${h.mediaCustomerId} | ${h.spend} | ${h.budget} |`
109402
+ );
109403
+ return {
109404
+ allClear: false,
109405
+ userDelivery: [header, ...lines].join("\n"),
109406
+ deliveryRule: DELIVERY_RULE2
109407
+ };
109408
+ }
109409
+ function buildZeroConvDelivery(hits) {
109410
+ if (hits.length === 0) {
109411
+ return { allClear: true, userDelivery: PATROL_ALL_CLEAR2, deliveryRule: DELIVERY_RULE2 };
109412
+ }
109413
+ const header = "| \u5BF9\u8C61\u540D\u79F0 | \u5BF9\u8C61ID | \u8D26\u6237ID | \u5F53\u65E5\u82B1\u8D39 |\n| --- | --- | --- | ---: |";
109414
+ const lines = hits.map(
109415
+ (h) => `| ${cell2(h.objectName)} | ${h.objectId} | ${h.mediaCustomerId} | ${h.spend} |`
109416
+ );
109417
+ return {
109418
+ allClear: false,
109419
+ userDelivery: [header, ...lines].join("\n"),
109420
+ deliveryRule: DELIVERY_RULE2
109421
+ };
109422
+ }
109423
+
109271
109424
  // src/commands/guard/rules.ts
109272
109425
  function moneyGte(leftYuan, rightYuan) {
109273
109426
  return Math.round(leftYuan * 100) >= Math.round(rightYuan * 100);
@@ -109399,12 +109552,15 @@ async function runBudgetCircuit(opts) {
109399
109552
  errorCount: errors.length
109400
109553
  },
109401
109554
  hits,
109402
- errors
109555
+ errors,
109556
+ agentBrief: buildBudgetCircuitDelivery(hits)
109403
109557
  };
109558
+ const agentBrief = payload.agentBrief;
109404
109559
  if (await emitCliJsonOrSnapshot(opts, {
109405
109560
  section: "guard-budget-circuit",
109406
109561
  commandLabel: "guard budget-circuit",
109407
- payload
109562
+ payload,
109563
+ summaryExtras: { userDelivery: agentBrief.userDelivery }
109408
109564
  })) {
109409
109565
  }
109410
109566
  const title = `\u8D85\u9884\u7B97\u7194\u65AD\u626B\u63CF \xB7 ${date} \xB7 ratio=${ratio} \xB7 \u547D\u4E2D ${hits.length}/${checkedCampaigns}`;
@@ -109594,12 +109750,14 @@ async function runZeroConv(opts) {
109594
109750
  },
109595
109751
  hits,
109596
109752
  skipped,
109597
- errors
109753
+ errors,
109754
+ agentBrief: buildZeroConvDelivery(hits)
109598
109755
  };
109599
109756
  await emitCliJsonOrSnapshot(opts, {
109600
109757
  section: "guard-zero-conv",
109601
109758
  commandLabel: "guard zero-conv",
109602
- payload
109759
+ payload,
109760
+ summaryExtras: { userDelivery: payload.agentBrief.userDelivery }
109603
109761
  });
109604
109762
  const title = `\u7A7A\u8017\u7194\u65AD\u626B\u63CF \xB7 ${date} \xB7 \xD7${multiple} \xB7 \u547D\u4E2D ${hits.length}/${checked}`;
109605
109763
  printHitsTable(
@@ -109634,6 +109792,7 @@ async function runZeroConv(opts) {
109634
109792
  }
109635
109793
 
109636
109794
  // src/commands/guard/_register.ts
109795
+ init_login_customer_id();
109637
109796
  function register11(program2) {
109638
109797
  const guard = program2.command("guard").description(
109639
109798
  "Google \u6295\u653E\u81EA\u63A7\u7194\u65AD\u626B\u63CF\uFF1A\u5168\u6237\uFF08\u6216 -a \u5B50\u96C6\uFF09\u5217\u51FA\u5F53\u65E5\u8D85\u9884\u7B97/\u7A7A\u8017\u547D\u4E2D\uFF0C\u53EA\u8BFB\u4E0D\u6682\u505C\u3002\u8981\u505C\u6295\u653E\u987B\u5BF9\u6BCF\u4E2A\u547D\u4E2D\u5BF9\u8C61\u5355\u72EC\u6267\u884C ad campaign-status / adgroup-status / ad-status\uFF08\u5E26 --commit\uFF09\u3002\u975E Google \u5A92\u4F53\u4E0D\u652F\u6301\u3002"
@@ -109643,7 +109802,7 @@ function register11(program2) {
109643
109802
  ).requiredOption("-m, --media <type>", "\u76EE\u524D\u4EC5\u652F\u6301 Google").option(
109644
109803
  "-a, --accounts <ids>",
109645
109804
  "\u6307\u5B9A\u8D26\u6237 mediaCustomerId\uFF0C\u9017\u53F7\u5206\u9694\uFF1B\u7559\u7A7A\u5219\u626B\u63CF\u540D\u4E0B\u5168\u90E8 Google \u8D26\u6237"
109646
- ).option("--date <YYYY-MM-DD>", "\u7EDF\u8BA1\u65E5\uFF08Asia/Shanghai \u9ED8\u8BA4\u4ECA\u5929\uFF09\uFF1B\u5F3A\u5236 start=end=\u8BE5\u65E5").option("--ratio <n>", "\u9608\u503C\u7CFB\u6570\uFF1Aspend >= budget * ratio\uFF08\u9ED8\u8BA4 1.1\uFF09", (v) => parseFloat(v)).option("--status <statusV2>", "\u53EA\u68C0\u67E5\u8BE5\u72B6\u6001\u7684\u7CFB\u5217\uFF08\u9ED8\u8BA4 Enabled\uFF1B\u4F20 * \u8868\u793A\u4E0D\u8FC7\u6EE4\uFF09", "Enabled").option("--page-size <n>", "\u8D26\u6237\u6E05\u5355\u5206\u9875\u5927\u5C0F\uFF08\u9ED8\u8BA4 200\uFF09", (v) => parseInt(v, 10)).option("--max-pages <n>", "\u6700\u591A\u626B\u63CF\u9875\u6570\uFF08\u9ED8\u8BA4 20\uFF09", (v) => parseInt(v, 10)).option("-t, --token <token>", "Token\uFF08\u53EF\u9009\uFF09").option(
109805
+ ).option("--date <YYYY-MM-DD>", "\u7EDF\u8BA1\u65E5\uFF08Asia/Shanghai \u9ED8\u8BA4\u4ECA\u5929\uFF09\uFF1B\u5F3A\u5236 start=end=\u8BE5\u65E5").option("--ratio <n>", "\u9608\u503C\u7CFB\u6570\uFF1Aspend >= budget * ratio\uFF08\u9ED8\u8BA4 1.1\uFF09", (v) => parseFloat(v)).option("--status <statusV2>", "\u53EA\u68C0\u67E5\u8BE5\u72B6\u6001\u7684\u7CFB\u5217\uFF08\u9ED8\u8BA4 Enabled\uFF1B\u4F20 * \u8868\u793A\u4E0D\u8FC7\u6EE4\uFF09", "Enabled").option("--page-size <n>", "\u8D26\u6237\u6E05\u5355\u5206\u9875\u5927\u5C0F\uFF08\u9ED8\u8BA4 200\uFF09", (v) => parseInt(v, 10)).option("--login-customer-id <id>", LOGIN_CUSTOMER_ID_OPTION_HELP).option("--max-pages <n>", "\u6700\u591A\u626B\u63CF\u9875\u6570\uFF08\u9ED8\u8BA4 20\uFF09", (v) => parseInt(v, 10)).option("-t, --token <token>", "Token\uFF08\u53EF\u9009\uFF09").option(
109647
109806
  "--json-out <path>",
109648
109807
  "\u843D\u76D8\u76EE\u5F55\u6216 *.json\uFF1Bstdout \u4E00\u884C\u6458\u8981\uFF1B\u4EBA\u7C7B\u53EF\u8BFB\u8868\u59CB\u7EC8\u6253\u5370",
109649
109808
  void 0
@@ -109660,7 +109819,8 @@ function register11(program2) {
109660
109819
  token: opts.token,
109661
109820
  jsonOut: opts.jsonOut,
109662
109821
  refreshDp: opts.refreshDp,
109663
- verbose: opts.verbose
109822
+ verbose: opts.verbose,
109823
+ loginCustomerId: opts.loginCustomerId
109664
109824
  });
109665
109825
  }
109666
109826
  );
@@ -109673,7 +109833,7 @@ function register11(program2) {
109673
109833
  "--fallback-target-cpa <yuan>",
109674
109834
  "\u7EC4\u65E0 targetCpa\uFF08\u6216\u521B\u610F\u7EF4\uFF09\u65F6\u4F7F\u7528\u7684\u76EE\u6807 CPA\uFF08\u5143\uFF09",
109675
109835
  (v) => parseFloat(v)
109676
- ).option("--page-size <n>", "\u8D26\u6237\u6E05\u5355\u5206\u9875\u5927\u5C0F\uFF08\u9ED8\u8BA4 200\uFF09", (v) => parseInt(v, 10)).option("--max-pages <n>", "\u6700\u591A\u626B\u63CF\u9875\u6570\uFF08\u9ED8\u8BA4 20\uFF09", (v) => parseInt(v, 10)).option("-t, --token <token>", "Token\uFF08\u53EF\u9009\uFF09").option("--json-out <path>", "\u843D\u76D8\u76EE\u5F55\u6216 *.json", void 0).option("--refresh-dp", "\u5F3A\u5236\u91CD\u62C9 Datapermission", false).option("--verbose", "\u8BE6\u7EC6\u9519\u8BEF", false).action(
109836
+ ).option("--page-size <n>", "\u8D26\u6237\u6E05\u5355\u5206\u9875\u5927\u5C0F\uFF08\u9ED8\u8BA4 200\uFF09", (v) => parseInt(v, 10)).option("--login-customer-id <id>", LOGIN_CUSTOMER_ID_OPTION_HELP).option("--max-pages <n>", "\u6700\u591A\u626B\u63CF\u9875\u6570\uFF08\u9ED8\u8BA4 20\uFF09", (v) => parseInt(v, 10)).option("-t, --token <token>", "Token\uFF08\u53EF\u9009\uFF09").option("--json-out <path>", "\u843D\u76D8\u76EE\u5F55\u6216 *.json", void 0).option("--refresh-dp", "\u5F3A\u5236\u91CD\u62C9 Datapermission", false).option("--verbose", "\u8BE6\u7EC6\u9519\u8BEF", false).action(
109677
109837
  async (opts) => {
109678
109838
  await runZeroConv({
109679
109839
  media: opts.media,
@@ -109687,7 +109847,8 @@ function register11(program2) {
109687
109847
  token: opts.token,
109688
109848
  jsonOut: opts.jsonOut,
109689
109849
  refreshDp: opts.refreshDp,
109690
- verbose: opts.verbose
109850
+ verbose: opts.verbose,
109851
+ loginCustomerId: opts.loginCustomerId
109691
109852
  });
109692
109853
  }
109693
109854
  );
@@ -111448,10 +111609,10 @@ async function runInvoiceBillable(opts) {
111448
111609
  })) {
111449
111610
  return;
111450
111611
  }
111451
- const label = opts.wallet ? "\u94B1\u5305\u53EF\u5F00\u7968\u8BB0\u5F55" : "\u5145\u503C\u53EF\u5F00\u7968\u8BA2\u5355";
111612
+ const label2 = opts.wallet ? "\u94B1\u5305\u53EF\u5F00\u7968\u8BB0\u5F55" : "\u5145\u503C\u53EF\u5F00\u7968\u8BA2\u5355";
111452
111613
  console.log(
111453
111614
  `
111454
- ${label}\uFF08\u7B2C ${page}/${Math.max(1, Math.ceil(total / pageSize))} \u9875\uFF0C\u672C\u9875 ${items3.length} \u6761\uFF0C\u5171 ${total} \u6761\uFF09
111615
+ ${label2}\uFF08\u7B2C ${page}/${Math.max(1, Math.ceil(total / pageSize))} \u9875\uFF0C\u672C\u9875 ${items3.length} \u6761\uFF0C\u5171 ${total} \u6761\uFF09
111455
111616
  `
111456
111617
  );
111457
111618
  if (items3.length === 0) {
@@ -113596,7 +113757,7 @@ async function runAdKeywords(opts) {
113596
113757
  if (key !== void 0) seen.add(key);
113597
113758
  return true;
113598
113759
  });
113599
- const label = opts.negative ? "\u5426\u5B9A\u5173\u952E\u8BCD" : "\u5173\u952E\u8BCD";
113760
+ const label2 = opts.negative ? "\u5426\u5B9A\u5173\u952E\u8BCD" : "\u5173\u952E\u8BCD";
113600
113761
  const n = items3.length;
113601
113762
  const displayItems = opts.negative ? items3 : items3.map((row) => keywordRowToYuan(row));
113602
113763
  const kwPayload = stripLegacyGoogleFieldsIfV2Present(
@@ -113613,7 +113774,7 @@ async function runAdKeywords(opts) {
113613
113774
  }
113614
113775
  console.log(
113615
113776
  `
113616
- ${label}\uFF08\u8D26\u6237\uFF1A${opts.account}\uFF0C\u7B2C 1 \u9875\uFF0C\u672C\u9875 ${items3.length} \u6761` + (rawItems.length !== items3.length ? `\uFF0C\u539F\u59CB ${rawItems.length} \u6761\u5DF2\u53BB\u91CD` : "") + `\uFF09
113777
+ ${label2}\uFF08\u8D26\u6237\uFF1A${opts.account}\uFF0C\u7B2C 1 \u9875\uFF0C\u672C\u9875 ${items3.length} \u6761` + (rawItems.length !== items3.length ? `\uFF0C\u539F\u59CB ${rawItems.length} \u6761\u5DF2\u53BB\u91CD` : "") + `\uFF09
113617
113778
  `
113618
113779
  );
113619
113780
  if (items3.length === 0) {
@@ -114665,9 +114826,9 @@ function warnPolicyRiskTerms(campaign, warnings) {
114665
114826
  const groups = campaign["AdGroupsForBatchJob"];
114666
114827
  if (!Array.isArray(groups)) return;
114667
114828
  const hitsByLabel = /* @__PURE__ */ new Map();
114668
- const add = (label, text2) => {
114669
- let set = hitsByLabel.get(label);
114670
- if (!set) hitsByLabel.set(label, set = /* @__PURE__ */ new Set());
114829
+ const add = (label2, text2) => {
114830
+ let set = hitsByLabel.get(label2);
114831
+ if (!set) hitsByLabel.set(label2, set = /* @__PURE__ */ new Set());
114671
114832
  set.add(text2.trim());
114672
114833
  };
114673
114834
  for (const g of groups) {
@@ -114679,8 +114840,8 @@ function warnPolicyRiskTerms(campaign, warnings) {
114679
114840
  if (!Array.isArray(texts)) continue;
114680
114841
  for (const t of texts) {
114681
114842
  if (typeof t !== "string") continue;
114682
- const label = matchRisk(t);
114683
- if (label) add(label, t);
114843
+ const label2 = matchRisk(t);
114844
+ if (label2) add(label2, t);
114684
114845
  }
114685
114846
  }
114686
114847
  }
@@ -114689,16 +114850,16 @@ function warnPolicyRiskTerms(campaign, warnings) {
114689
114850
  for (const ad of ads) {
114690
114851
  if (!ad || typeof ad !== "object") continue;
114691
114852
  for (const t of collectRsaTexts(ad)) {
114692
- const label = matchRisk(t);
114693
- if (label) add(label, t);
114853
+ const label2 = matchRisk(t);
114854
+ if (label2) add(label2, t);
114694
114855
  }
114695
114856
  }
114696
114857
  }
114697
114858
  }
114698
- for (const [label, set] of hitsByLabel) {
114859
+ for (const [label2, set] of hitsByLabel) {
114699
114860
  const sample = [...set].slice(0, 5).map((s) => `\u300C${s}\u300D`).join("\u3001");
114700
114861
  warnings.push(
114701
- `\u653F\u7B56\u98CE\u9669\u8BCD\u9762\uFF08${label}\uFF09\uFF1A${sample}${set.size > 5 ? ` \u7B49 ${set.size} \u6761` : ""}\uFF1B\u7F51\u5173\u65E0\u653F\u7B56\u9884\u68C0\uFF0C\u521B\u5EFA\u540E\u53EF\u80FD\u88AB PolicyViolation \u62D2\u7EDD\u2014\u2014\u521B\u5EFA\u524D\u5411\u7528\u6237\u8BF4\u660E\u98CE\u9669\uFF0C\u5FC5\u8981\u65F6\u6539\u5199\u6216\u5220\u9664`
114862
+ `\u653F\u7B56\u98CE\u9669\u8BCD\u9762\uFF08${label2}\uFF09\uFF1A${sample}${set.size > 5 ? ` \u7B49 ${set.size} \u6761` : ""}\uFF1B\u7F51\u5173\u65E0\u653F\u7B56\u9884\u68C0\uFF0C\u521B\u5EFA\u540E\u53EF\u80FD\u88AB PolicyViolation \u62D2\u7EDD\u2014\u2014\u521B\u5EFA\u524D\u5411\u7528\u6237\u8BF4\u660E\u98CE\u9669\uFF0C\u5FC5\u8981\u65F6\u6539\u5199\u6216\u5220\u9664`
114702
114863
  );
114703
114864
  }
114704
114865
  }
@@ -114851,10 +115012,10 @@ function validateLocationsFidelity(cfg, campaign, errors) {
114851
115012
  if (id === void 0 || id === null) continue;
114852
115013
  const ti = targetedIdx.get(String(id).trim());
114853
115014
  if (ti === void 0) continue;
114854
- const label = typeof names[ti] === "string" ? `\u300C${names[ti]}\u300D` : "";
115015
+ const label2 = typeof names[ti] === "string" ? `\u300C${names[ti]}\u300D` : "";
114855
115016
  pushErr2(
114856
115017
  errors,
114857
- `campaign.excludedLocations[${i}].id=${String(id)} \u540C\u65F6\u51FA\u73B0\u5728 targetedLocations[${ti}]${label}\uFF1B\u540C\u4E00\u5730\u57DF\u65E2\u6295\u653E\u53C8\u6392\u9664\u4F1A\u4F7F BatchJob \u62A5 campaign_criterion \u2026negative immutable\u3002\u591A\u4E3A geo resolve \u628A\u6B67\u4E49\u5730\u540D\uFF08\u5982\u300C\u521A\u679C\u300Dvs\u300C\u521A\u679C\u6C11\u4E3B\u5171\u548C\u56FD\u300D\uFF09\u89E3\u6790\u6210\u540C\u4E00 ID\uFF1A\u7528 ad geo search \u6838\u5BF9\u540E\u4FEE\u6B63\u8BE5\u6761\uFF0C\u52FF\u6574\u6279\u5220\u9664\u6392\u9664\u5730\u57DF`
115018
+ `campaign.excludedLocations[${i}].id=${String(id)} \u540C\u65F6\u51FA\u73B0\u5728 targetedLocations[${ti}]${label2}\uFF1B\u540C\u4E00\u5730\u57DF\u65E2\u6295\u653E\u53C8\u6392\u9664\u4F1A\u4F7F BatchJob \u62A5 campaign_criterion \u2026negative immutable\u3002\u591A\u4E3A geo resolve \u628A\u6B67\u4E49\u5730\u540D\uFF08\u5982\u300C\u521A\u679C\u300Dvs\u300C\u521A\u679C\u6C11\u4E3B\u5171\u548C\u56FD\u300D\uFF09\u89E3\u6790\u6210\u540C\u4E00 ID\uFF1A\u7528 ad geo search \u6838\u5BF9\u540E\u4FEE\u6B63\u8BE5\u6761\uFF0C\u52FF\u6574\u6279\u5220\u9664\u6392\u9664\u5730\u57DF`
114858
115019
  );
114859
115020
  }
114860
115021
  }
@@ -114899,7 +115060,7 @@ function validateRsaDisplayPath(prefix, ad, errors, lengthViolations) {
114899
115060
  `${prefix} \u68C0\u6D4B\u5230\u5C0F\u5199 path2="${String(ad["path2"])}"\uFF0C\u540E\u7AEF\u5951\u7EA6\u5B57\u6BB5\u4E3A Path2\uFF08PascalCase\uFF09\uFF0C\u5F53\u524D\u63D0\u4EA4\u4E0D\u4F1A\u751F\u6548`
114900
115061
  );
114901
115062
  }
114902
- for (const [field, label, example] of [
115063
+ for (const [field, label2, example] of [
114903
115064
  ["Path1", "\u663E\u793A\u8DEF\u5F84\u7B2C 1 \u6BB5", '"Path1": "products"'],
114904
115065
  ["Path2", "\u663E\u793A\u8DEF\u5F84\u7B2C 2 \u6BB5", '"Path2": "steel"']
114905
115066
  ]) {
@@ -114907,7 +115068,7 @@ function validateRsaDisplayPath(prefix, ad, errors, lengthViolations) {
114907
115068
  if (raw === void 0) {
114908
115069
  pushErr2(
114909
115070
  errors,
114910
- `${prefix}.${field} \u5B57\u6BB5\u7F3A\u5931\uFF08RSA \u5FC5\u586B\uFF09\u3002${label}\uFF0C\u5C55\u793A\u4E3A finalUrl \u57DF\u540D\u540E\u7684\u8DEF\u5F84\u6BB5\uFF08\u226415 \u5B57\u7B26\uFF0CCJK \u6309 2 \u8BA1\uFF09\u3002${RSA_PATH_BACKEND_HINT}\u3002${jsonHint}\u3002\u793A\u4F8B\uFF1A${example}`
115071
+ `${prefix}.${field} \u5B57\u6BB5\u7F3A\u5931\uFF08RSA \u5FC5\u586B\uFF09\u3002${label2}\uFF0C\u5C55\u793A\u4E3A finalUrl \u57DF\u540D\u540E\u7684\u8DEF\u5F84\u6BB5\uFF08\u226415 \u5B57\u7B26\uFF0CCJK \u6309 2 \u8BA1\uFF09\u3002${RSA_PATH_BACKEND_HINT}\u3002${jsonHint}\u3002\u793A\u4F8B\uFF1A${example}`
114911
115072
  );
114912
115073
  continue;
114913
115074
  }
@@ -116253,7 +116414,7 @@ function validateRsaCliCopy(input) {
116253
116414
  }
116254
116415
  }
116255
116416
  }
116256
- for (const [label, value] of [
116417
+ for (const [label2, value] of [
116257
116418
  ["--path1", input.path1],
116258
116419
  ["--path2", input.path2]
116259
116420
  ]) {
@@ -116261,7 +116422,7 @@ function validateRsaCliCopy(input) {
116261
116422
  const len = calcGoogleCharLength(value);
116262
116423
  if (len > AD_CLI_PATH_MAX_CHARS) {
116263
116424
  errors.push(
116264
- `${label} \u8D85\u8FC7 ${AD_CLI_PATH_MAX_CHARS} \u5B57\u7B26\uFF08\u5F53\u524D ${len}\uFF0CCJK \u8BA1 2\uFF09\uFF1A${JSON.stringify(value)}`
116425
+ `${label2} \u8D85\u8FC7 ${AD_CLI_PATH_MAX_CHARS} \u5B57\u7B26\uFF08\u5F53\u524D ${len}\uFF0CCJK \u8BA1 2\uFF09\uFF1A${JSON.stringify(value)}`
116265
116426
  );
116266
116427
  }
116267
116428
  }
@@ -118013,9 +118174,9 @@ async function runAdGeoAdd(opts) {
118013
118174
  `);
118014
118175
  process.exit(1);
118015
118176
  }
118016
- const label = opts.exclude ? "\u5DF2\u6392\u9664" : "\u5DF2\u6DFB\u52A0\u5B9A\u4F4D";
118177
+ const label2 = opts.exclude ? "\u5DF2\u6392\u9664" : "\u5DF2\u6DFB\u52A0\u5B9A\u4F4D";
118017
118178
  console.log(`
118018
- \u2705 \u5730\u7406\u4F4D\u7F6E ${opts.locationId} ${label}\uFF08\u5E7F\u544A\u7CFB\u5217\uFF1A${opts.campaignId}\uFF09
118179
+ \u2705 \u5730\u7406\u4F4D\u7F6E ${opts.locationId} ${label2}\uFF08\u5E7F\u544A\u7CFB\u5217\uFF1A${opts.campaignId}\uFF09
118019
118180
  `);
118020
118181
  }
118021
118182
  async function runAdGeoRemove(opts) {
@@ -118273,7 +118434,7 @@ function buildBatchOperationSlots(cfg) {
118273
118434
  const campaign = asRecord3(cfg.campaign) ?? {};
118274
118435
  const names = Array.isArray(cfg.locations) ? cfg.locations : [];
118275
118436
  const slots = [];
118276
- const push = (kind, path55, label) => slots.push({ index: slots.length, kind, path: path55, label });
118437
+ const push = (kind, path55, label2) => slots.push({ index: slots.length, kind, path: path55, label: label2 });
118277
118438
  push("campaign_budget", "campaign.Budget", "\u7CFB\u5217\u9884\u7B97");
118278
118439
  push("campaign", "campaign.Name", `\u7CFB\u5217\u300C${pickText(campaign, "Name", "name") || "\u2014"}\u300D`);
118279
118440
  pickArray(campaign, "targetedLocations", "TargetedLocations").forEach((loc, i) => {
@@ -118822,16 +118983,16 @@ function compareCampaignCreateToLive(cfg, campaignId, live, meta) {
118822
118983
  summary: `RSA \u672A\u6BD4\u5BF9\uFF08\u7EC4\u7F3A\u5931\uFF09\uFF1AAdsForBatchJob[${ai}]`
118823
118984
  });
118824
118985
  for (const asset of rsaAssets) {
118825
- const label = asset.kind === "headline" ? "\u6807\u9898" : "\u63CF\u8FF0";
118986
+ const label2 = asset.kind === "headline" ? "\u6807\u9898" : "\u63CF\u8FF0";
118826
118987
  pushItem(items3, {
118827
118988
  layer: "ad",
118828
118989
  path: asset.path,
118829
118990
  adGroupName: groupName,
118830
118991
  adLabel,
118831
- plannedContent: `${label}: ${asset.text}`,
118992
+ plannedContent: `${label2}: ${asset.text}`,
118832
118993
  status: "skipped",
118833
118994
  liveNote: "\u5E7F\u544A\u7EC4\u672A\u521B\u5EFA\uFF0C\u8DF3\u8FC7\u6587\u6848\u6BD4\u5BF9",
118834
- summary: `RSA ${label}\u672A\u6BD4\u5BF9\uFF08\u7EC4\u7F3A\u5931\uFF09\uFF1A${asset.text}`
118995
+ summary: `RSA ${label2}\u672A\u6BD4\u5BF9\uFF08\u7EC4\u7F3A\u5931\uFF09\uFF1A${asset.text}`
118835
118996
  });
118836
118997
  }
118837
118998
  continue;
@@ -118851,7 +119012,7 @@ function compareCampaignCreateToLive(cfg, campaignId, live, meta) {
118851
119012
  summary: `\u5E7F\u544A\u521B\u610F\u672A\u6821\u9A8C\uFF08\u7F3A\u5C11 headlinePart1\uFF09\uFF1AAdsForBatchJob[${ai}]`
118852
119013
  });
118853
119014
  for (const asset of rsaAssets) {
118854
- const label = asset.kind === "headline" ? "\u6807\u9898" : "\u63CF\u8FF0";
119015
+ const label2 = asset.kind === "headline" ? "\u6807\u9898" : "\u63CF\u8FF0";
118855
119016
  const pool = asset.kind === "headline" ? liveHeadlineSet : liveDescSet;
118856
119017
  const found = livePoolHasText(pool, asset.text);
118857
119018
  pushItem(items3, {
@@ -118859,10 +119020,10 @@ function compareCampaignCreateToLive(cfg, campaignId, live, meta) {
118859
119020
  path: asset.path,
118860
119021
  adGroupName: groupName,
118861
119022
  adLabel,
118862
- plannedContent: `${label}: ${asset.text}`,
119023
+ plannedContent: `${label2}: ${asset.text}`,
118863
119024
  status: found ? "ok" : "missing",
118864
- liveNote: found ? `\u5DF2\u5728\u5BF9\u5E94 RSA \u4E0A\u627E\u5230\u6B64${label}` : `\u5BF9\u5E94 RSA \u672A\u89C1\u6B64${label}`,
118865
- summary: found ? `RSA ${label}\u5DF2\u751F\u6548\uFF1A${asset.text}` : `RSA ${label}\u672A\u751F\u6548\uFF1A${asset.text}`
119025
+ liveNote: found ? `\u5DF2\u5728\u5BF9\u5E94 RSA \u4E0A\u627E\u5230\u6B64${label2}` : `\u5BF9\u5E94 RSA \u672A\u89C1\u6B64${label2}`,
119026
+ summary: found ? `RSA ${label2}\u5DF2\u751F\u6548\uFF1A${asset.text}` : `RSA ${label2}\u672A\u751F\u6548\uFF1A${asset.text}`
118866
119027
  });
118867
119028
  }
118868
119029
  continue;
@@ -118879,7 +119040,7 @@ function compareCampaignCreateToLive(cfg, campaignId, live, meta) {
118879
119040
  summary: rsaFound ? `RSA \u5DF2\u521B\u5EFA\uFF08\u9996\u6761\u6807\u9898\u300C${primary}\u300D\uFF09` : `RSA \u672A\u521B\u5EFA\uFF08\u9996\u6761\u6807\u9898\u300C${primary}\u300D\u5728\u5BF9\u5E94\u5E7F\u544A\u4E0A\u672A\u627E\u5230\uFF09`
118880
119041
  });
118881
119042
  for (const asset of rsaAssets) {
118882
- const label = asset.kind === "headline" ? "\u6807\u9898" : "\u63CF\u8FF0";
119043
+ const label2 = asset.kind === "headline" ? "\u6807\u9898" : "\u63CF\u8FF0";
118883
119044
  const pool = asset.kind === "headline" ? liveHeadlineSet : liveDescSet;
118884
119045
  const found = livePoolHasText(pool, asset.text);
118885
119046
  pushItem(items3, {
@@ -118887,10 +119048,10 @@ function compareCampaignCreateToLive(cfg, campaignId, live, meta) {
118887
119048
  path: asset.path,
118888
119049
  adGroupName: groupName,
118889
119050
  adLabel,
118890
- plannedContent: `${label}: ${asset.text}`,
119051
+ plannedContent: `${label2}: ${asset.text}`,
118891
119052
  status: found ? "ok" : "missing",
118892
- liveNote: found ? `\u5DF2\u5728\u5BF9\u5E94 RSA \u4E0A\u627E\u5230\u6B64${label}` : `\u5BF9\u5E94 RSA \u672A\u89C1\u6B64${label}\uFF08\u8BE5\u5E7F\u544A\u6587\u6848 ${pool.size} \u6761\uFF09`,
118893
- summary: found ? `RSA ${label}\u5DF2\u751F\u6548\uFF1A${asset.text}` : `RSA ${label}\u672A\u751F\u6548\uFF1A${asset.text}`
119053
+ liveNote: found ? `\u5DF2\u5728\u5BF9\u5E94 RSA \u4E0A\u627E\u5230\u6B64${label2}` : `\u5BF9\u5E94 RSA \u672A\u89C1\u6B64${label2}\uFF08\u8BE5\u5E7F\u544A\u6587\u6848 ${pool.size} \u6761\uFF09`,
119054
+ summary: found ? `RSA ${label2}\u5DF2\u751F\u6548\uFF1A${asset.text}` : `RSA ${label2}\u672A\u751F\u6548\uFF1A${asset.text}`
118894
119055
  });
118895
119056
  }
118896
119057
  }
@@ -120256,7 +120417,7 @@ function normalizeBidding(raw) {
120256
120417
  };
120257
120418
  return byNum[n] ?? null;
120258
120419
  }
120259
- function validateTextLengths(errors, lengthViolations, texts, arrayField, kind, limit, label) {
120420
+ function validateTextLengths(errors, lengthViolations, texts, arrayField, kind, limit, label2) {
120260
120421
  texts.forEach((text2, i) => {
120261
120422
  const len = calcGoogleCharLength(text2);
120262
120423
  if (len > limit) {
@@ -120270,7 +120431,7 @@ function validateTextLengths(errors, lengthViolations, texts, arrayField, kind,
120270
120431
  countMode: "google",
120271
120432
  text: text2
120272
120433
  });
120273
- pushErr3(errors, `${label}[${i}] \u8D85\u8FC7 ${limit} \u5B57\u7B26\uFF08\u5F53\u524D ${len}\uFF0CCJK \u8BA1 2\uFF09\uFF1A"${text2}"`);
120434
+ pushErr3(errors, `${label2}[${i}] \u8D85\u8FC7 ${limit} \u5B57\u7B26\uFF08\u5F53\u524D ${len}\uFF0CCJK \u8BA1 2\uFF09\uFF1A"${text2}"`);
120274
120435
  }
120275
120436
  });
120276
120437
  }
@@ -120597,7 +120758,7 @@ function resolveImagePath(configFile, relOrAbs) {
120597
120758
  }
120598
120759
  function checkSpec(spec, width, height, fileSizeKB, errors, warnings) {
120599
120760
  const {
120600
- label,
120761
+ label: label2,
120601
120762
  ratio,
120602
120763
  ratioPct,
120603
120764
  minWidth,
@@ -120610,19 +120771,19 @@ function checkSpec(spec, width, height, fileSizeKB, errors, warnings) {
120610
120771
  const ratioOk = Math.abs(actualRatio - ratio) <= ratio * ratioPct;
120611
120772
  if (!ratioOk) {
120612
120773
  errors.push(
120613
- `${label}\uFF1A\u5BBD\u9AD8\u6BD4 ${width}\xD7${height}\uFF08${actualRatio.toFixed(3)}\uFF09\u504F\u79BB\u76EE\u6807 ${ratio}\uFF0C\u8D85\u51FA \xB1${(ratioPct * 100).toFixed(0)}% \u5BB9\u5DEE`
120774
+ `${label2}\uFF1A\u5BBD\u9AD8\u6BD4 ${width}\xD7${height}\uFF08${actualRatio.toFixed(3)}\uFF09\u504F\u79BB\u76EE\u6807 ${ratio}\uFF0C\u8D85\u51FA \xB1${(ratioPct * 100).toFixed(0)}% \u5BB9\u5DEE`
120614
120775
  );
120615
120776
  }
120616
120777
  if (width < minWidth || height < minHeight) {
120617
- errors.push(`${label}\uFF1A\u5C3A\u5BF8 ${width}\xD7${height} \u4F4E\u4E8E Google \u6700\u5C0F\u8981\u6C42 ${minWidth}\xD7${minHeight}`);
120778
+ errors.push(`${label2}\uFF1A\u5C3A\u5BF8 ${width}\xD7${height} \u4F4E\u4E8E Google \u6700\u5C0F\u8981\u6C42 ${minWidth}\xD7${minHeight}`);
120618
120779
  } else if (width < recommendedWidth || height < recommendedHeight) {
120619
120780
  warnings.push(
120620
- `${label}\uFF1A\u5C3A\u5BF8 ${width}\xD7${height} \u4F4E\u4E8E\u63A8\u8350\u5C3A\u5BF8 ${recommendedWidth}\xD7${recommendedHeight}\uFF0C\u53EF\u80FD\u5F71\u54CD\u5C55\u793A\u6548\u679C`
120781
+ `${label2}\uFF1A\u5C3A\u5BF8 ${width}\xD7${height} \u4F4E\u4E8E\u63A8\u8350\u5C3A\u5BF8 ${recommendedWidth}\xD7${recommendedHeight}\uFF0C\u53EF\u80FD\u5F71\u54CD\u5C55\u793A\u6548\u679C`
120621
120782
  );
120622
120783
  }
120623
120784
  if (fileSizeKB > maxFileSizeKB) {
120624
120785
  errors.push(
120625
- `${label}\uFF1A\u6587\u4EF6\u5927\u5C0F ${fileSizeKB.toFixed(0)} KB \u8D85\u8FC7 Google \u4E0A\u9650 ${maxFileSizeKB} KB`
120786
+ `${label2}\uFF1A\u6587\u4EF6\u5927\u5C0F ${fileSizeKB.toFixed(0)} KB \u8D85\u8FC7 Google \u4E0A\u9650 ${maxFileSizeKB} KB`
120626
120787
  );
120627
120788
  }
120628
120789
  }
@@ -121269,9 +121430,9 @@ async function attachPmaxCampaignExtensions(opts) {
121269
121430
  const header = s?.header?.trim();
121270
121431
  const values = (s?.values ?? []).map((v) => v?.trim()).filter(Boolean);
121271
121432
  if (!header || values.length < 3) continue;
121272
- const label = `${header}: ${values.join(", ")}`;
121433
+ const label2 = `${header}: ${values.join(", ")}`;
121273
121434
  if (opts.logProgress) console.log(`
121274
- \u6302\u8F7D\u7ED3\u6784\u5316\u6458\u8981\uFF1A${label}`);
121435
+ \u6302\u8F7D\u7ED3\u6784\u5316\u6458\u8981\uFF1A${label2}`);
121275
121436
  const posted = await postExtension(
121276
121437
  opts.config,
121277
121438
  opts.googleApiUrl,
@@ -121283,11 +121444,11 @@ async function attachPmaxCampaignExtensions(opts) {
121283
121444
  result.structuredSnippets.push({
121284
121445
  ok: true,
121285
121446
  id: String(posted.data["id"] ?? ""),
121286
- label
121447
+ label: label2
121287
121448
  });
121288
121449
  } else {
121289
121450
  result.allOk = false;
121290
- result.structuredSnippets.push({ ok: false, error: posted.error, label });
121451
+ result.structuredSnippets.push({ ok: false, error: posted.error, label: label2 });
121291
121452
  }
121292
121453
  }
121293
121454
  for (const link of ext.sitelinks ?? []) {
@@ -121337,9 +121498,9 @@ async function attachPmaxCampaignExtensions(opts) {
121337
121498
  }
121338
121499
  }
121339
121500
  if (ext.businessMessage) {
121340
- const label = ext.businessMessage.starterMessage?.trim().slice(0, 40) || "WhatsApp";
121501
+ const label2 = ext.businessMessage.starterMessage?.trim().slice(0, 40) || "WhatsApp";
121341
121502
  if (opts.logProgress) console.log(`
121342
- \u6302\u8F7D WhatsApp \u79C1\u4FE1\uFF1A${label}`);
121503
+ \u6302\u8F7D WhatsApp \u79C1\u4FE1\uFF1A${label2}`);
121343
121504
  const posted = await postExtension(
121344
121505
  opts.config,
121345
121506
  opts.googleApiUrl,
@@ -121351,11 +121512,11 @@ async function attachPmaxCampaignExtensions(opts) {
121351
121512
  result.whatsapp = {
121352
121513
  ok: true,
121353
121514
  id: String(posted.data["id"] ?? ""),
121354
- label
121515
+ label: label2
121355
121516
  };
121356
121517
  } else {
121357
121518
  result.allOk = false;
121358
- result.whatsapp = { ok: false, error: posted.error, label };
121519
+ result.whatsapp = { ok: false, error: posted.error, label: label2 };
121359
121520
  }
121360
121521
  }
121361
121522
  return result;
@@ -121674,8 +121835,8 @@ async function emitPmaxResult(opts, section, commandLabel, payload, idSuffix) {
121674
121835
  idSuffix: idSuffix ?? opts.account
121675
121836
  });
121676
121837
  }
121677
- function requireAccountId(account, label = "-a, --account") {
121678
- return resolveAdAccountId(account, label);
121838
+ function requireAccountId(account, label2 = "-a, --account") {
121839
+ return resolveAdAccountId(account, label2);
121679
121840
  }
121680
121841
 
121681
121842
  // src/commands/ad/pmax-video-upload.ts
@@ -125469,15 +125630,15 @@ init_cli_json_snapshot();
125469
125630
  function hasBudget(daily, lifetime) {
125470
125631
  return daily != null || lifetime != null;
125471
125632
  }
125472
- function pushBudgetPairErrors(errors, label, daily, lifetime) {
125633
+ function pushBudgetPairErrors(errors, label2, daily, lifetime) {
125473
125634
  if (daily != null && lifetime != null) {
125474
- errors.push(`${label} \u4E0D\u80FD\u540C\u65F6\u586B dailyBudget \u4E0E lifetimeBudget`);
125635
+ errors.push(`${label2} \u4E0D\u80FD\u540C\u65F6\u586B dailyBudget \u4E0E lifetimeBudget`);
125475
125636
  }
125476
125637
  if (daily != null && !(Number.isFinite(daily) && daily > 0)) {
125477
- errors.push(`${label}.dailyBudget \u987B\u4E3A\u5927\u4E8E 0 \u7684\u6570\u5B57\uFF08\u4E3B\u5E01\u79CD\u5143\uFF09`);
125638
+ errors.push(`${label2}.dailyBudget \u987B\u4E3A\u5927\u4E8E 0 \u7684\u6570\u5B57\uFF08\u4E3B\u5E01\u79CD\u5143\uFF09`);
125478
125639
  }
125479
125640
  if (lifetime != null && !(Number.isFinite(lifetime) && lifetime > 0)) {
125480
- errors.push(`${label}.lifetimeBudget \u987B\u4E3A\u5927\u4E8E 0 \u7684\u6570\u5B57\uFF08\u4E3B\u5E01\u79CD\u5143\uFF09`);
125641
+ errors.push(`${label2}.lifetimeBudget \u987B\u4E3A\u5927\u4E8E 0 \u7684\u6570\u5B57\uFF08\u4E3B\u5E01\u79CD\u5143\uFF09`);
125481
125642
  }
125482
125643
  }
125483
125644
  function runMetaLeadValidation(cfg) {
@@ -125613,16 +125774,16 @@ function runMetaLeadValidation(cfg) {
125613
125774
  );
125614
125775
  }
125615
125776
  const createStatuses = ["ACTIVE", "PAUSED", void 0, ""];
125616
- for (const [label, status] of [
125777
+ for (const [label2, status] of [
125617
125778
  ["campaign.status", campaign.status],
125618
125779
  ["adset.status", adset.status],
125619
125780
  ["ad.status", ad.status]
125620
125781
  ]) {
125621
125782
  if (status && !createStatuses.includes(status.trim().toUpperCase())) {
125622
- errors.push(`${label} \u521B\u5EFA\u65F6\u53EA\u5141\u8BB8 ACTIVE / PAUSED\uFF08\u7F3A\u7701 PAUSED\uFF09`);
125783
+ errors.push(`${label2} \u521B\u5EFA\u65F6\u53EA\u5141\u8BB8 ACTIVE / PAUSED\uFF08\u7F3A\u7701 PAUSED\uFF09`);
125623
125784
  }
125624
125785
  if (status && status.trim().toUpperCase() === "ACTIVE") {
125625
- warnings.push(`${label}=ACTIVE \u4F1A\u5728\u521B\u5EFA\u65F6\u5C1D\u8BD5\u6295\u653E\uFF1B\u5EFA\u8BAE\u7701\u7565\uFF0C\u9ED8\u8BA4 PAUSED\uFF0C\u786E\u8BA4\u540E\u518D\u6539\u72B6\u6001`);
125786
+ warnings.push(`${label2}=ACTIVE \u4F1A\u5728\u521B\u5EFA\u65F6\u5C1D\u8BD5\u6295\u653E\uFF1B\u5EFA\u8BAE\u7701\u7565\uFF0C\u9ED8\u8BA4 PAUSED\uFF0C\u786E\u8BA4\u540E\u518D\u6539\u72B6\u6001`);
125626
125787
  }
125627
125788
  }
125628
125789
  const plan = cfg.plan;
@@ -126304,8 +126465,8 @@ function writeOpsExcel(outPath, cfg) {
126304
126465
  ["\u8BA4\u8BC1\u8D44\u8D28", text(plan.certifications), "B2B\u4FE1\u4EFB\u4FE1\u53F7"],
126305
126466
  ["\u6838\u5FC3\u5356\u70B9", text(plan.sellingPoints || endorsementText(plan)), "\u5DEE\u5F02\u5316\u4F18\u52BF"]
126306
126467
  ];
126307
- for (const [label, value, note] of profileRows) {
126308
- profile.dataRow([label, value, note || "", ""], { labelColumns: [0] });
126468
+ for (const [label2, value, note] of profileRows) {
126469
+ profile.dataRow([label2, value, note || "", ""], { labelColumns: [0] });
126309
126470
  }
126310
126471
  profile.blankRow();
126311
126472
  profile.sectionBar("\u5E94\u7528\u884C\u4E1A / \u5174\u8DA3\uFF08\u82F1\u6587\u5B9A\u5411\u8BCD\uFF09", { fill: OPS.section });
@@ -130432,10 +130593,10 @@ function buildBingIndustryOptions(records) {
130432
130593
  const groups = [];
130433
130594
  for (const [parentKey, children] of byParent) {
130434
130595
  const parent = parentKey === ORPHAN_PARENT_KEY ? null : byId.get(parentKey);
130435
- const label = parent?.TranslationLanguage || parent?.name || (parentKey === ORPHAN_PARENT_KEY ? "\u2014" : parentKey);
130596
+ const label2 = parent?.TranslationLanguage || parent?.name || (parentKey === ORPHAN_PARENT_KEY ? "\u2014" : parentKey);
130436
130597
  groups.push({
130437
130598
  parentId: parentKey === ORPHAN_PARENT_KEY ? "" : parentKey,
130438
- label,
130599
+ label: label2,
130439
130600
  children: [...children].sort(cmpCode)
130440
130601
  });
130441
130602
  }
@@ -130449,10 +130610,10 @@ function buildBingIndustryOptions(records) {
130449
130610
  for (const g of groups) {
130450
130611
  for (const row of g.children) {
130451
130612
  const id = String(row.id ?? "");
130452
- const label = String(row.TranslationLanguage || row.name || id);
130613
+ const label2 = String(row.TranslationLanguage || row.name || id);
130453
130614
  out.push({
130454
130615
  id,
130455
- label,
130616
+ label: label2,
130456
130617
  group: g.label,
130457
130618
  name: String(row.name ?? "")
130458
130619
  });
@@ -130715,8 +130876,8 @@ async function runOpenAccountGoogleTimezones(opts) {
130715
130876
  const code = String(r.Code ?? "").toLowerCase();
130716
130877
  const name2 = String(r.Name ?? "").toLowerCase();
130717
130878
  const time = String(r.Time ?? "").toLowerCase();
130718
- const label = `(${r.Time ?? ""})${r.Name ?? ""}`.toLowerCase();
130719
- return code.includes(kw) || name2.includes(kw) || time.includes(kw) || label.includes(kw);
130879
+ const label2 = `(${r.Time ?? ""})${r.Name ?? ""}`.toLowerCase();
130880
+ return code.includes(kw) || name2.includes(kw) || time.includes(kw) || label2.includes(kw);
130720
130881
  });
130721
130882
  }
130722
130883
  const n = rows.length;
@@ -130753,11 +130914,11 @@ Google \u5F00\u6237\u53EF\u9009\u65F6\u533A\uFF08\u4E0E\u7F51\u9875 /openAnAccou
130753
130914
  { key: "label", header: "\u5C55\u793A\uFF08\u4E0E\u7F51\u9875\u76F8\u540C\uFF09" }
130754
130915
  ];
130755
130916
  const tableRows = rows.map((r, i) => {
130756
- const label = `(${r.Time ?? ""})${r.Name ?? ""}`;
130917
+ const label2 = `(${r.Time ?? ""})${r.Name ?? ""}`;
130757
130918
  return {
130758
130919
  idx: String(i + 1),
130759
130920
  code: String(r.Code ?? "").slice(0, codeW),
130760
- label: label.slice(0, labelW)
130921
+ label: label2.slice(0, labelW)
130761
130922
  };
130762
130923
  });
130763
130924
  printCliTable(tableRows, cols);
@@ -132613,7 +132774,7 @@ async function runMarketAnalysisCollect(opts) {
132613
132774
  websiteError = err instanceof Error ? err.message : String(err);
132614
132775
  }
132615
132776
  }
132616
- const label = normalized.customerName?.trim() || normalized.website?.trim() || normalized.industry?.trim() || normalized.coreProducts?.trim() || "market";
132777
+ const label2 = normalized.customerName?.trim() || normalized.website?.trim() || normalized.industry?.trim() || normalized.coreProducts?.trim() || "market";
132617
132778
  const payload = {
132618
132779
  customerInfo: normalized,
132619
132780
  targetMarket: normalized.targetMarket,
@@ -132629,7 +132790,7 @@ async function runMarketAnalysisCollect(opts) {
132629
132790
  {
132630
132791
  section: "market-analysis-collect",
132631
132792
  commandLabel: "market-analysis collect",
132632
- commandHint: label,
132793
+ commandHint: label2,
132633
132794
  payload
132634
132795
  }
132635
132796
  )) {
@@ -133602,7 +133763,7 @@ function buildComparisonItems(currentRows, previousRows, titleFn, keyFn) {
133602
133763
  (row) => toKeyMetricRow(titleFn(row), row, prevMap.get(keyFn(row)) ?? null)
133603
133764
  );
133604
133765
  }
133605
- function toTargetingItem(row, labelKey, label) {
133766
+ function toTargetingItem(row, labelKey, label2) {
133606
133767
  const cost = rowCost(row);
133607
133768
  const clicks = num(row.clicks);
133608
133769
  const impressions = num(row.impressions);
@@ -133612,7 +133773,7 @@ function toTargetingItem(row, labelKey, label) {
133612
133773
  const cpc = num(row.averageCpc ?? row.cpc);
133613
133774
  const cpa = conversions > 0 ? cost / conversions : num(row.costPerConversion ?? row.cpa);
133614
133775
  return {
133615
- [labelKey]: label,
133776
+ [labelKey]: label2,
133616
133777
  cost,
133617
133778
  impressions,
133618
133779
  clicks,
@@ -135814,8 +135975,8 @@ function matchConversionAction(actions, name2) {
135814
135975
  const needle = name2.trim().toLowerCase();
135815
135976
  if (!needle) return null;
135816
135977
  const hit = actions.find((row) => {
135817
- const label = String(row.name ?? row.conversionAction ?? row.id ?? "").toLowerCase();
135818
- return label.includes(needle);
135978
+ const label2 = String(row.name ?? row.conversionAction ?? row.id ?? "").toLowerCase();
135979
+ return label2.includes(needle);
135819
135980
  });
135820
135981
  if (!hit) return null;
135821
135982
  const n = num2(hit.conversions ?? hit.conversionsValue ?? hit.allConversions);
@@ -136110,9 +136271,9 @@ async function runGoogleQuarterlyCollect(opts) {
136110
136271
  const snapDir = path29.resolve(opts.jsonOut);
136111
136272
  await fs25.mkdir(snapDir, { recursive: true });
136112
136273
  let degraded = false;
136113
- const run = (label, start, end, sections) => {
136274
+ const run = (label2, start, end, sections) => {
136114
136275
  console.error(`
136115
- \u{1F4E5} ${label}\uFF1A${start} ~ ${end}\uFF08${sections}\uFF09
136276
+ \u{1F4E5} ${label2}\uFF1A${start} ~ ${end}\uFF08${sections}\uFF09
136116
136277
  `);
136117
136278
  const result = invokeGoogleAnalysisCli({
136118
136279
  account: accountId,
@@ -136126,14 +136287,14 @@ async function runGoogleQuarterlyCollect(opts) {
136126
136287
  if (!result.ok && result.status !== 2) {
136127
136288
  console.error(result.stderr || result.stdout);
136128
136289
  console.error(`
136129
- \u274C ${label} \u62C9\u6570\u5931\u8D25\u3002
136290
+ \u274C ${label2} \u62C9\u6570\u5931\u8D25\u3002
136130
136291
  `);
136131
136292
  return false;
136132
136293
  }
136133
136294
  if (!result.ok) {
136134
136295
  console.error(result.stderr || result.stdout);
136135
136296
  console.error(`
136136
- \u26A0\uFE0F ${label} \u90E8\u5206\u7EF4\u5EA6\u5931\u8D25\uFF0C\u7EE7\u7EED\u805A\u5408\u3002
136297
+ \u26A0\uFE0F ${label2} \u90E8\u5206\u7EF4\u5EA6\u5931\u8D25\uFF0C\u7EE7\u7EED\u805A\u5408\u3002
136137
136298
  `);
136138
136299
  degraded = true;
136139
136300
  }
@@ -136822,10 +136983,10 @@ function estimateColWidths(rows) {
136822
136983
  const colCount = rows.reduce((max, row) => Math.max(max, row.length), 0);
136823
136984
  const widths = new Array(colCount).fill(MIN_COL_WIDTH);
136824
136985
  for (const row of rows) {
136825
- row.forEach((cell3, idx) => {
136826
- if (cell3 == null) return;
136986
+ row.forEach((cell5, idx) => {
136987
+ if (cell5 == null) return;
136827
136988
  const longestLine = Math.max(
136828
- ...String(cell3).split("\n").map((l) => l.length)
136989
+ ...String(cell5).split("\n").map((l) => l.length)
136829
136990
  );
136830
136991
  const width = Math.min(MAX_COL_WIDTH, Math.max(MIN_COL_WIDTH, Math.ceil(longestLine * 1.3)));
136831
136992
  if (width > widths[idx]) widths[idx] = width;
@@ -138211,10 +138372,10 @@ function sumActionArray(raw) {
138211
138372
  }
138212
138373
 
138213
138374
  // src/commands/facebook-analysis/entities.ts
138214
- function fail(label, err) {
138375
+ function fail(label2, err) {
138215
138376
  const msg = err instanceof Error ? err.message : String(err);
138216
138377
  console.error(`
138217
- \u274C ${label}\uFF1A${msg}
138378
+ \u274C ${label2}\uFF1A${msg}
138218
138379
  `);
138219
138380
  process.exit(1);
138220
138381
  }
@@ -138229,7 +138390,7 @@ function parseOptionalNumber2(raw) {
138229
138390
  }
138230
138391
  return n;
138231
138392
  }
138232
- function cell(value) {
138393
+ function cell3(value) {
138233
138394
  return value == null || value === "" ? "" : String(value);
138234
138395
  }
138235
138396
  async function runFacebookAccountStatus(opts) {
@@ -138258,10 +138419,10 @@ Facebook \u8D26\u6237\u4FE1\u606F\uFF08${manifestId}\uFF09
138258
138419
  printCliTable(
138259
138420
  [
138260
138421
  {
138261
- id: cell(row.account_id ?? row.id ?? manifestId),
138262
- status: cell(row.account_status),
138263
- disableReason: cell(row.disable_reason),
138264
- timezone: cell(row.timezone_name),
138422
+ id: cell3(row.account_id ?? row.id ?? manifestId),
138423
+ status: cell3(row.account_status),
138424
+ disableReason: cell3(row.disable_reason),
138425
+ timezone: cell3(row.timezone_name),
138265
138426
  currency,
138266
138427
  balance: formatYuanDisplay(fromMinorUnitDisplay(row.balance, currency)),
138267
138428
  spendCap: formatYuanDisplay(fromMinorUnitDisplay(row.spend_cap, currency)),
@@ -138342,13 +138503,13 @@ ${meta.title}\uFF08${manifestId}\uFF0C\u5171 ${result.items.length} \u6761\uFF09
138342
138503
  if (kind === "campaigns") {
138343
138504
  printCliTable(
138344
138505
  result.items.map((r) => ({
138345
- id: cell(r.id),
138346
- name: cell(r.name),
138347
- status: cell(r.status),
138348
- effective: cell(r.effective_status),
138349
- dailyBudget: cell(r.daily_budget),
138350
- lifetimeBudget: cell(r.lifetime_budget),
138351
- bidStrategy: cell(r.bid_strategy)
138506
+ id: cell3(r.id),
138507
+ name: cell3(r.name),
138508
+ status: cell3(r.status),
138509
+ effective: cell3(r.effective_status),
138510
+ dailyBudget: cell3(r.daily_budget),
138511
+ lifetimeBudget: cell3(r.lifetime_budget),
138512
+ bidStrategy: cell3(r.bid_strategy)
138352
138513
  })),
138353
138514
  [
138354
138515
  { key: "id", header: "\u7CFB\u5217ID" },
@@ -138368,13 +138529,13 @@ ${meta.title}\uFF08${manifestId}\uFF0C\u5171 ${result.items.length} \u6761\uFF09
138368
138529
  if (kind === "adsets") {
138369
138530
  printCliTable(
138370
138531
  result.items.map((r) => ({
138371
- id: cell(r.id),
138372
- name: cell(r.name),
138373
- campaignId: cell(r.campaign_id),
138374
- status: cell(r.effective_status ?? r.status),
138375
- dailyBudget: cell(r.daily_budget),
138376
- bidAmount: cell(r.bid_amount),
138377
- bidStrategy: cell(r.bid_strategy)
138532
+ id: cell3(r.id),
138533
+ name: cell3(r.name),
138534
+ campaignId: cell3(r.campaign_id),
138535
+ status: cell3(r.effective_status ?? r.status),
138536
+ dailyBudget: cell3(r.daily_budget),
138537
+ bidAmount: cell3(r.bid_amount),
138538
+ bidStrategy: cell3(r.bid_strategy)
138378
138539
  })),
138379
138540
  [
138380
138541
  { key: "id", header: "\u7EC4ID" },
@@ -138393,11 +138554,11 @@ ${meta.title}\uFF08${manifestId}\uFF0C\u5171 ${result.items.length} \u6761\uFF09
138393
138554
  }
138394
138555
  printCliTable(
138395
138556
  result.items.map((r) => ({
138396
- id: cell(r.id),
138397
- name: cell(r.name),
138398
- campaignId: cell(r.campaign_id),
138399
- adsetId: cell(r.adset_id),
138400
- effective: cell(r.effective_status),
138557
+ id: cell3(r.id),
138558
+ name: cell3(r.name),
138559
+ campaignId: cell3(r.campaign_id),
138560
+ adsetId: cell3(r.adset_id),
138561
+ effective: cell3(r.effective_status),
138401
138562
  landing: Array.isArray(r.landing_urls) ? r.landing_urls.join(" | ") : ""
138402
138563
  })),
138403
138564
  [
@@ -138487,15 +138648,15 @@ Facebook Insights ${level} ${startDate}~${endDate}\uFF08${manifestId}\uFF0C\u517
138487
138648
  }
138488
138649
  printCliTable(
138489
138650
  items3.map((r) => ({
138490
- objectId: cell(r.ad_id ?? r.adset_id ?? r.campaign_id ?? r.account_id),
138491
- name: cell(r.ad_name ?? r.adset_name ?? r.campaign_name ?? r.account_name),
138492
- date: cell(r.date_start),
138493
- hour: cell(r.hourly_stats_aggregated_by_advertiser_time_zone),
138494
- spend: cell(r.spend),
138495
- clicks: cell(r.clicks),
138496
- impressions: cell(r.impressions),
138497
- ctr: cell(r.ctr),
138498
- conversions: cell(sumActionArray(r.conversions))
138651
+ objectId: cell3(r.ad_id ?? r.adset_id ?? r.campaign_id ?? r.account_id),
138652
+ name: cell3(r.ad_name ?? r.adset_name ?? r.campaign_name ?? r.account_name),
138653
+ date: cell3(r.date_start),
138654
+ hour: cell3(r.hourly_stats_aggregated_by_advertiser_time_zone),
138655
+ spend: cell3(r.spend),
138656
+ clicks: cell3(r.clicks),
138657
+ impressions: cell3(r.impressions),
138658
+ ctr: cell3(r.ctr),
138659
+ conversions: cell3(sumActionArray(r.conversions))
138499
138660
  })),
138500
138661
  [
138501
138662
  { key: "objectId", header: "\u5BF9\u8C61ID" },
@@ -141108,11 +141269,11 @@ function assertAdSecondaryStatusFilter(raw) {
141108
141269
  }
141109
141270
  return v;
141110
141271
  }
141111
- function unwrapTikTokEnvelope(raw, label) {
141272
+ function unwrapTikTokEnvelope(raw, label2) {
141112
141273
  const env = raw ?? {};
141113
141274
  const code = env.code;
141114
141275
  if (code !== 0 && code !== void 0) {
141115
- throw new Error(`${label} \u4E1A\u52A1\u5931\u8D25 code=${code}\uFF1A${env.message ?? "\u672A\u77E5\u9519\u8BEF"}`);
141276
+ throw new Error(`${label2} \u4E1A\u52A1\u5931\u8D25 code=${code}\uFF1A${env.message ?? "\u672A\u77E5\u9519\u8BEF"}`);
141116
141277
  }
141117
141278
  const list = Array.isArray(env.data?.list) ? env.data.list : [];
141118
141279
  const info = env.data?.page_info ?? {};
@@ -141265,10 +141426,10 @@ async function fetchOfficialReport(config, opts) {
141265
141426
  }
141266
141427
 
141267
141428
  // src/commands/tiktok-analysis/entities.ts
141268
- function fail2(label, err) {
141429
+ function fail2(label2, err) {
141269
141430
  const msg = err instanceof Error ? err.message : String(err);
141270
141431
  console.error(`
141271
- \u274C ${label}\uFF1A${msg}
141432
+ \u274C ${label2}\uFF1A${msg}
141272
141433
  `);
141273
141434
  process.exit(1);
141274
141435
  }
@@ -142067,19 +142228,19 @@ function isoWeekKey(d) {
142067
142228
  thursday.setDate(thursday.getDate() + 3);
142068
142229
  const yearStart = new Date(thursday.getFullYear(), 0, 1);
142069
142230
  const week = Math.floor((thursday.getTime() - yearStart.getTime()) / 864e5 / 7) + 1;
142070
- const label = `W${String(week).padStart(2, "0")}`;
142071
- return { key: `${thursday.getFullYear()}-${label}`, label, weekStart, weekEnd };
142231
+ const label2 = `W${String(week).padStart(2, "0")}`;
142232
+ return { key: `${thursday.getFullYear()}-${label2}`, label: label2, weekStart, weekEnd };
142072
142233
  }
142073
142234
  function aggregateDailyToWeekly(dailyRows) {
142074
142235
  const map = /* @__PURE__ */ new Map();
142075
142236
  for (const row of dailyRows) {
142076
142237
  const d = parseYmd3(row.date);
142077
142238
  if (!d) continue;
142078
- const { key, label, weekStart, weekEnd } = isoWeekKey(d);
142239
+ const { key, label: label2, weekStart, weekEnd } = isoWeekKey(d);
142079
142240
  let acc = map.get(key);
142080
142241
  if (!acc) {
142081
142242
  acc = {
142082
- label,
142243
+ label: label2,
142083
142244
  weekStart,
142084
142245
  weekEnd,
142085
142246
  days: 0,
@@ -142525,8 +142686,8 @@ function validateYandexPeriodReportContent(data) {
142525
142686
  const tables = asRecord36(data.tables) ?? {};
142526
142687
  const weeklyRows = asArray8(tables.weekly).map((r) => asRecord36(r)).filter((r) => r != null);
142527
142688
  for (const [i, row] of weeklyRows.entries()) {
142528
- const label = `${row.weekLabel ?? ""} ${row.startDate ?? ""} ${row.endDate ?? ""}`;
142529
- if (/nan/i.test(label) || !normalizeYandexDailyDate(row.startDate) || !normalizeYandexDailyDate(row.endDate)) {
142689
+ const label2 = `${row.weekLabel ?? ""} ${row.startDate ?? ""} ${row.endDate ?? ""}`;
142690
+ if (/nan/i.test(label2) || !normalizeYandexDailyDate(row.startDate) || !normalizeYandexDailyDate(row.endDate)) {
142530
142691
  pushMissing7(
142531
142692
  missing,
142532
142693
  `tables-weekly-${i}`,
@@ -142845,14 +143006,14 @@ function asRecord38(raw) {
142845
143006
  }
142846
143007
 
142847
143008
  // src/commands/yandex-analysis/entities.ts
142848
- function fail3(label, err) {
143009
+ function fail3(label2, err) {
142849
143010
  const msg = err instanceof Error ? err.message : String(err);
142850
143011
  console.error(`
142851
- \u274C ${label}\uFF1A${msg}
143012
+ \u274C ${label2}\uFF1A${msg}
142852
143013
  `);
142853
143014
  process.exit(1);
142854
143015
  }
142855
- function cell2(value) {
143016
+ function cell4(value) {
142856
143017
  if (value == null || value === "") return "";
142857
143018
  if (Array.isArray(value)) return value.map((x) => String(x)).join(" | ");
142858
143019
  return String(value);
@@ -142930,12 +143091,12 @@ async function runYandexAccountStatus(opts) {
142930
143091
  footnote: "archived=true \u8868\u793A\u5E7F\u544A\u4E3B\u5DF2\u5F52\u6863\uFF08inactive\uFF09\u3002\u5B98\u65B9\u65E0\u5C01\u6237\u72B6\u6001\u4E0E\u539F\u56E0\u3002\u4F59\u989D\u770B balance / currency\uFF1B\u5B98\u65B9\u65E0\u72EC\u7ACB\u989D\u5EA6\u3002",
142931
143092
  rows: [
142932
143093
  {
142933
- account: cell2(row.account ?? result.accountId),
142934
- archived: cell2(row.archived),
142935
- balance: cell2(row.balance),
142936
- currency: cell2(row.currency),
142937
- spend: cell2(row.spend),
142938
- conversions: cell2(row.conversions)
143094
+ account: cell4(row.account ?? result.accountId),
143095
+ archived: cell4(row.archived),
143096
+ balance: cell4(row.balance),
143097
+ currency: cell4(row.currency),
143098
+ spend: cell4(row.spend),
143099
+ conversions: cell4(row.conversions)
142939
143100
  }
142940
143101
  ],
142941
143102
  columns: [
@@ -142971,15 +143132,15 @@ async function runYandexCampaignEntities(opts) {
142971
143132
  empty: "\u5F53\u524D\u8FC7\u6EE4\u4E0B\u65E0\u7CFB\u5217\u884C\uFF08\u9ED8\u8BA4\u53EA\u51FA\u73B0\u6709\u6D88\u8017\u7684\u5BF9\u8C61\uFF09\u3002",
142972
143133
  footnote: "\u9ED8\u8BA4 SEARCH\u3002\u5168\u6E20\u9053\u82B1\u8D39\u987B --network ALL\uFF08\u884C\u5185 network \u4E3A null\uFF09\u3002budget \u662F\u7CFB\u5217\u65E5\u9884\u7B97\uFF0C\u81EA\u52A8\u7B56\u7565\u5E38\u4E3A\u7A7A\uFF1B\u5BF9\u7167 weeklyBudget\u3002\u81EA\u52A8\u51FA\u4EF7\u4E0D\u8981\u5F53\u624B\u52A8 CPC \u6539\u4EF7\u3002",
142973
143134
  rows: items3.map((r) => ({
142974
- campaignId: cell2(r.campaignId),
142975
- name: cell2(r.campaignName),
142976
- spend: cell2(r.spend),
142977
- budget: cell2(r.budget),
142978
- weeklyBudget: cell2(r.weeklyBudget),
142979
- strategy: cell2(r.strategy),
142980
- targetCpa: cell2(r.targetCpa),
142981
- status: cell2(r.status),
142982
- date: cell2(r.date)
143135
+ campaignId: cell4(r.campaignId),
143136
+ name: cell4(r.campaignName),
143137
+ spend: cell4(r.spend),
143138
+ budget: cell4(r.budget),
143139
+ weeklyBudget: cell4(r.weeklyBudget),
143140
+ strategy: cell4(r.strategy),
143141
+ targetCpa: cell4(r.targetCpa),
143142
+ status: cell4(r.status),
143143
+ date: cell4(r.date)
142983
143144
  })),
142984
143145
  columns: [
142985
143146
  { key: "campaignId", header: "\u7CFB\u5217ID" },
@@ -143017,16 +143178,16 @@ async function runYandexAdGroupEntities(opts) {
143017
143178
  empty: "\u5F53\u524D\u8FC7\u6EE4\u4E0B\u65E0\u5E7F\u544A\u7EC4\u884C\uFF08\u9ED8\u8BA4\u53EA\u51FA\u73B0\u6709\u6D88\u8017\u7684\u5BF9\u8C61\uFF09\u3002",
143018
143179
  footnote: "campaignTargetCpa \u662F\u7CFB\u5217\u76EE\u6807\uFF08\u53EA\u53D6 Search\uFF09\uFF0C\u4E0D\u662F\u7EC4\u7EA7\u76EE\u6807\u4EF7\u3002conversions<=0 \u65F6\u4E0D\u8981\u5224 CPA\u3002\u672C\u6279\u6CA1\u6709\u6539\u4EF7\u63A5\u53E3\u3002",
143019
143180
  rows: items3.map((r) => ({
143020
- adGroupId: cell2(r.adGroupId),
143021
- name: cell2(r.adGroupName),
143022
- campaignId: cell2(r.campaignId),
143023
- spend: cell2(r.spend),
143024
- conversions: cell2(r.conversions),
143025
- cpa: cell2(r.costPerConversion),
143026
- targetCpa: cell2(r.campaignTargetCpa),
143027
- weeklyBudget: cell2(r.campaignWeeklyBudget),
143028
- strategy: cell2(r.campaignStrategy),
143029
- date: cell2(r.date)
143181
+ adGroupId: cell4(r.adGroupId),
143182
+ name: cell4(r.adGroupName),
143183
+ campaignId: cell4(r.campaignId),
143184
+ spend: cell4(r.spend),
143185
+ conversions: cell4(r.conversions),
143186
+ cpa: cell4(r.costPerConversion),
143187
+ targetCpa: cell4(r.campaignTargetCpa),
143188
+ weeklyBudget: cell4(r.campaignWeeklyBudget),
143189
+ strategy: cell4(r.campaignStrategy),
143190
+ date: cell4(r.date)
143030
143191
  })),
143031
143192
  columns: [
143032
143193
  { key: "adGroupId", header: "\u7EC4ID" },
@@ -143068,15 +143229,15 @@ async function runYandexAdEntities(opts) {
143068
143229
  empty: filtered ? "\u5F53\u524D\u5BA1\u6838\u8FC7\u6EE4\u4E0B\u65E0\u8BB0\u5F55\uFF08\u7A7A\u5217\u8868=\u6210\u529F\u4E14\u6CA1\u6709\u672A\u5F52\u6863\u5339\u914D\u9879\uFF09\u3002" : "\u5F53\u524D\u8FC7\u6EE4\u4E0B\u65E0\u5E7F\u544A\u884C\uFF08\u9ED8\u8BA4\u53EA\u51FA\u73B0\u533A\u95F4\u5185\u6709\u6D88\u8017\u7684\u5E7F\u544A\uFF09\u3002",
143069
143230
  footnote: "landingUrls \u7A7A\u6570\u7EC4\u4E0D\u662F\u6B7B\u94FE\uFF08Dynamic/Smart/Shopping \u6216\u4EC5 TurboPage \u5E38\u4E3A []\uFF09\u3002CLI \u4E0D\u63A2\u6D3B HTTP\u3002\u62D2\u5BA1\u7528 --status REJECTED\uFF08\u4E0E --time-increment \u4E92\u65A5\uFF1B\u5DF2\u5F52\u6863\u4E0D\u4F1A\u51FA\u73B0\uFF09\u3002",
143070
143231
  rows: items3.map((r) => ({
143071
- adId: cell2(r.adId),
143072
- campaignId: cell2(r.campaignId),
143073
- adGroupId: cell2(r.adGroupId),
143074
- spend: cell2(r.spend),
143075
- conversions: cell2(r.conversions),
143076
- ctr: cell2(r.ctr),
143077
- roi: cell2(r.roi),
143078
- status: cell2(r.status),
143079
- landing: cell2(r.landingUrls)
143232
+ adId: cell4(r.adId),
143233
+ campaignId: cell4(r.campaignId),
143234
+ adGroupId: cell4(r.adGroupId),
143235
+ spend: cell4(r.spend),
143236
+ conversions: cell4(r.conversions),
143237
+ ctr: cell4(r.ctr),
143238
+ roi: cell4(r.roi),
143239
+ status: cell4(r.status),
143240
+ landing: cell4(r.landingUrls)
143080
143241
  })),
143081
143242
  columns: [
143082
143243
  { key: "adId", header: "\u5E7F\u544AID" },
@@ -143119,17 +143280,17 @@ async function runYandexInsights(opts) {
143119
143280
  empty: "\u65E0\u62A5\u8868\u884C\uFF08\u9ED8\u8BA4\u53EA\u51FA\u73B0\u533A\u95F4\u5185\u6709\u6D88\u8017\u7684\u5BF9\u8C61\uFF09\u3002",
143120
143281
  footnote: "revenue \u662F\u6210\u4EA4\u989D PurchaseRevenue\uFF0C\u4E0D\u662F\u76EE\u6807\u8D4B\u503C\u3002roi=(\u6210\u4EA4\u989D\u2212\u82B1\u8D39)/\u82B1\u8D39\u3002geo/devices \u9ED8\u8BA4 SEARCH\uFF0C\u5168\u7F51\u987B --network ALL\u3002\u65E0\u5C0F\u65F6\u7EF4\u5EA6\u3002",
143121
143282
  rows: items3.map((r) => ({
143122
- id: cell2(
143283
+ id: cell4(
143123
143284
  r.adId ?? r.adGroupId ?? r.campaignId ?? r.keywordId ?? r.regionName ?? r.device ?? r.date
143124
143285
  ),
143125
- name: cell2(
143286
+ name: cell4(
143126
143287
  r.adName ?? r.adGroupName ?? r.campaignName ?? r.keyword ?? r.regionName ?? r.device
143127
143288
  ),
143128
- spend: cell2(r.spend),
143129
- conversions: cell2(r.conversions),
143130
- ctr: cell2(r.ctr),
143131
- roi: cell2(r.roi),
143132
- date: cell2(r.date)
143289
+ spend: cell4(r.spend),
143290
+ conversions: cell4(r.conversions),
143291
+ ctr: cell4(r.ctr),
143292
+ roi: cell4(r.roi),
143293
+ date: cell4(r.date)
143133
143294
  })),
143134
143295
  columns: [
143135
143296
  { key: "id", header: "\u5BF9\u8C61" },
@@ -143267,37 +143428,118 @@ function hasDateFromTo(args) {
143267
143428
  (a) => a === "--date-from" || a === "--date-to" || a.startsWith("--date-from=") || a.startsWith("--date-to=")
143268
143429
  );
143269
143430
  }
143431
+ var RERUN_HINT = "\u7ACB\u523B\u6539\u8DD1\u63D0\u793A\u4E2D\u7684\u90A3\u6761\uFF0C\u4E0D\u8981\u505C\u5728\u9519\u8BEF\u547D\u4EE4\u3002";
143432
+ function fatal(body) {
143433
+ const text2 = body.replace(/\s+$/g, "");
143434
+ if (text2.includes(RERUN_HINT)) return `
143435
+ ${text2}
143436
+ `;
143437
+ return `
143438
+ ${text2}
143439
+ ${RERUN_HINT}
143440
+ `;
143441
+ }
143442
+ function playbookCodeFatal(cmd) {
143443
+ if (!/^(?:W\d+|P\d+(?:-FB)?)$/i.test(cmd)) return null;
143444
+ const key = cmd.toUpperCase();
143445
+ const known = {
143446
+ W1: "siluzan-tso list-accounts [-m Google] --json-out <dir>",
143447
+ P2: "siluzan-tso balance-scan -m Google --json-out <dir>",
143448
+ P3: "siluzan-tso accounts-digest -m Google --start <S> --end <D> --json-out <dir>"
143449
+ };
143450
+ const replacement = known[key];
143451
+ if (replacement) {
143452
+ return fatal(
143453
+ `\u274C \`${cmd}\` \u662F\u8DEF\u7531\u7F16\u53F7\uFF0C\u4E0D\u662F\u547D\u4EE4\u3002\u8BF7\u6539\u8DD1\uFF1A
143454
+ ${replacement}`
143455
+ );
143456
+ }
143457
+ return fatal(
143458
+ `\u274C \`${cmd}\` \u662F\u8DEF\u7531\u7F16\u53F7\uFF0C\u4E0D\u662F\u547D\u4EE4\u3002\u8D26\u6237\u5217\u8868\u7528 list-accounts\uFF0C\u591A\u6237\u4F59\u989D\u7528 balance-scan\uFF0C\u591A\u6237\u6D88\u8017/CPA \u7528 accounts-digest\u3002\u5176\u5B83\u7F16\u53F7\u5148 Read SKILL \u8DEF\u7531\u8868\u3002`
143459
+ );
143460
+ }
143461
+ var LOGIN_CUSTOMER_COMMANDS = /* @__PURE__ */ new Set([
143462
+ "list-accounts",
143463
+ "balance-scan",
143464
+ "accounts-digest",
143465
+ "guard"
143466
+ ]);
143467
+ function loginCustomerFlagIssue(args) {
143468
+ const cmd = args[0] ?? "";
143469
+ for (const arg of args) {
143470
+ const raw = arg.startsWith("--") ? arg.slice(2).split("=")[0] : "";
143471
+ if (!raw) continue;
143472
+ const norm = raw.toLowerCase().replace(/_/g, "-");
143473
+ const looksLike = norm.includes("login") && norm.includes("customer");
143474
+ if (!looksLike) continue;
143475
+ if (norm !== "login-customer-id") {
143476
+ return fatal(
143477
+ `\u274C \u6CA1\u6709 \`--${raw}\`\u3002MCC \u5B50\u6237\u8BF7\u7528 --login-customer-id\uFF0C\u53EA\u52A0\u5728 list-accounts\u3001balance-scan\u3001accounts-digest\u3001guard\u3002`
143478
+ );
143479
+ }
143480
+ if (!LOGIN_CUSTOMER_COMMANDS.has(cmd)) {
143481
+ return fatal(
143482
+ `\u274C \`${cmd || "\u8BE5\u547D\u4EE4"}\` \u4E0D\u652F\u6301 --login-customer-id\u3002\u8BF7\u6539\u8DD1 list-accounts\u3001balance-scan\u3001accounts-digest \u6216 guard\u3002`
143483
+ );
143484
+ }
143485
+ }
143486
+ return null;
143487
+ }
143270
143488
  function agentCompatFatalMessage(argv) {
143271
143489
  const args = argv.slice(2);
143272
143490
  if (args.includes("--period") || args.some((a) => a.startsWith("--period="))) {
143273
- return "\n\u274C \u6CA1\u6709 --period \u9009\u9879\u3002\u8BF7\u7528 --start/--end\uFF08\u6216\u517C\u5BB9\u522B\u540D --start-date/--end-date\uFF09\u6307\u5B9A YYYY-MM-DD \u533A\u95F4\u3002\n";
143491
+ return fatal(
143492
+ "\u274C \u6CA1\u6709 --period \u9009\u9879\u3002\u8BF7\u7528 --start/--end\uFF08\u6216\u517C\u5BB9\u522B\u540D --start-date/--end-date\uFF09\u6307\u5B9A YYYY-MM-DD \u533A\u95F4\u3002"
143493
+ );
143274
143494
  }
143275
143495
  if (hasDateFromTo(args)) {
143276
- return "\n\u274C \u6CA1\u6709 `--date-from` / `--date-to`\u3002\u8BF7\u7528 `--start` / `--end`\uFF08YYYY-MM-DD\uFF09\u3002\n \u5355\u65E5\u9884\u7B97/\u7A7A\u8017\u7194\u65AD\u8BF7\u7528\uFF1Asiluzan-tso guard budget-circuit|zero-conv -m Google --date <\u5F53\u65E5> --json-out <dir>\n";
143496
+ return fatal(
143497
+ "\u274C \u6CA1\u6709 `--date-from` / `--date-to`\u3002\u8BF7\u7528 `--start` / `--end`\uFF08YYYY-MM-DD\uFF09\u3002\n \u5355\u65E5\u9884\u7B97/\u7A7A\u8017\u7194\u65AD\u8BF7\u7528\uFF1Asiluzan-tso guard budget-circuit|zero-conv -m Google --date <\u5F53\u65E5> --json-out <dir>"
143498
+ );
143277
143499
  }
143278
143500
  if (jsonOutMissingPath(args)) {
143279
- return "\n\u274C `--json-out` \u5FC5\u987B\u5E26\u8DEF\u5F84\uFF08\u76EE\u5F55\u6216 *.json \u6587\u4EF6\uFF09\uFF0CJSON \u843D\u76D8\u800C\u975E\u6253\u5370\u5230 stdout\uFF0C\u4E0D\u80FD\u7BA1\u9053\u7ED9 python/jq\u3002\n \u793A\u4F8B\uFF1Asiluzan-tso ad campaigns -a <id> --json-out ./snap\n \u7136\u540E\u7528 node/python \u8BFB ./snap \u4E0B writtenFiles\uFF08\u89C1 stdout \u6458\u8981\u7684 absoluteSnapshotDir\uFF09\u3002\n";
143501
+ return fatal(
143502
+ "\u274C `--json-out` \u5FC5\u987B\u5E26\u8DEF\u5F84\uFF08\u76EE\u5F55\u6216 *.json \u6587\u4EF6\uFF09\uFF0CJSON \u843D\u76D8\u800C\u975E\u6253\u5370\u5230 stdout\uFF0C\u4E0D\u80FD\u7BA1\u9053\u7ED9 python/jq\u3002\n \u793A\u4F8B\uFF1Asiluzan-tso ad campaigns -a <id> --json-out ./snap\n \u7136\u540E\u7528 node/python \u8BFB ./snap \u4E0B writtenFiles\uFF08\u89C1 stdout \u6458\u8981\u7684 absoluteSnapshotDir\uFF09\u3002"
143503
+ );
143280
143504
  }
143281
143505
  const cmd = args[0];
143506
+ if (!cmd) return null;
143282
143507
  if (cmd === "google-ads") {
143283
- return "\n\u274C \u6CA1\u6709 `google-ads` \u547D\u540D\u7A7A\u95F4\u3002\u8BF7\u6539\u7528\uFF1A\n - \u8D26\u6237\u5206\u6790\u62C9\u6570\uFF1Asiluzan-tso google-analysis \u2026\n - \u5E7F\u544A\u7CFB\u5217/\u7EC4/\u521B\u610F/\u5173\u952E\u8BCD\uFF1Asiluzan-tso ad campaigns|groups|list|keywords \u2026\n \uFF08\u6CA1\u6709 campaign-list\uFF1B\u5217\u8868\u547D\u4EE4\u662F campaigns / groups / list / keywords\uFF09\n - \u5E7F\u544A\u8BCA\u65AD\u62A5\u544A\uFF1Asiluzan-tso google-ads-diagnosis \u2026\n - \u5B63\u5EA6\u7ECF\u8425\u62A5\u544A\uFF1Asiluzan-tso google-quarterly \u2026\n";
143508
+ return fatal(
143509
+ "\u274C \u6CA1\u6709 `google-ads` \u547D\u540D\u7A7A\u95F4\u3002\u8BF7\u6539\u7528\uFF1A\n - \u8D26\u6237\u5206\u6790\u62C9\u6570\uFF1Asiluzan-tso google-analysis \u2026\n - \u5E7F\u544A\u7CFB\u5217/\u7EC4/\u521B\u610F/\u5173\u952E\u8BCD\uFF1Asiluzan-tso ad campaigns|groups|list|keywords \u2026\n \uFF08\u6CA1\u6709 campaign-list\uFF1B\u5217\u8868\u547D\u4EE4\u662F campaigns / groups / list / keywords\uFF09\n - \u5E7F\u544A\u8BCA\u65AD\u62A5\u544A\uFF1Asiluzan-tso google-ads-diagnosis \u2026\n - \u5B63\u5EA6\u7ECF\u8425\u62A5\u544A\uFF1Asiluzan-tso google-quarterly \u2026"
143510
+ );
143284
143511
  }
143285
143512
  if (cmd === "adgroups" || cmd === "ad" && args[1] === "adgroups") {
143286
- return "\n\u274C \u6CA1\u6709 `adgroups` \u547D\u4EE4\u3002\u8BF7\u7528\uFF1Asiluzan-tso ad groups -a <mediaCustomerId> --json-out <dir>\n";
143513
+ return fatal(
143514
+ "\u274C \u6CA1\u6709 `adgroups` \u547D\u4EE4\u3002\u8BF7\u7528\uFF1Asiluzan-tso ad groups -a <mediaCustomerId> --json-out <dir>"
143515
+ );
143287
143516
  }
143288
143517
  if (adSubcommandHasMediaFlag(args)) {
143289
- return "\n\u274C `ad \u2026` \u5B50\u547D\u4EE4\u6CA1\u6709 `-m/--media`\uFF0C\u8D26\u6237\u7528 `-a/--account <mediaCustomerId>`\u3002\n \u5355\u6237\uFF1Asiluzan-tso ad campaigns -a <id> --start <\u65E5> --end <\u65E5> --json-out ./snap\n \u5168\u6237\u5F53\u65E5\u8D85\u9884\u7B97/\u7A7A\u8017\u7194\u65AD\uFF1Asiluzan-tso guard budget-circuit|zero-conv -m Google --json-out ./snap\n";
143518
+ return fatal(
143519
+ "\u274C `ad \u2026` \u5B50\u547D\u4EE4\u6CA1\u6709 `-m/--media`\uFF0C\u8D26\u6237\u7528 `-a/--account <mediaCustomerId>`\u3002\n \u5355\u6237\uFF1Asiluzan-tso ad campaigns -a <id> --start <\u65E5> --end <\u65E5> --json-out ./snap\n \u5168\u6237\u5F53\u65E5\u8D85\u9884\u7B97/\u7A7A\u8017\u7194\u65AD\uFF1Asiluzan-tso guard budget-circuit|zero-conv -m Google --json-out ./snap"
143520
+ );
143290
143521
  }
143291
143522
  if (cmd === "list" && (args.length === 1 || args[1]?.startsWith("-"))) {
143292
- return "\n\u274C \u6CA1\u6709\u9876\u5C42 `list` \u547D\u4EE4\u3002\u67E5\u8BE2\u5E7F\u544A\u8D26\u6237\u5217\u8868\u8BF7\u7528\uFF1A\n siluzan-tso list-accounts [-m Google] [-k <id\u6216\u5173\u952E\u5B57>] --json-out <dir>\n";
143523
+ return fatal(
143524
+ "\u274C \u6CA1\u6709\u9876\u5C42 `list` \u547D\u4EE4\u3002\u67E5\u8BE2\u5E7F\u544A\u8D26\u6237\u5217\u8868\u8BF7\u7528\uFF1A\n siluzan-tso list-accounts [-m Google] [-k <id\u6216\u5173\u952E\u5B57>] --json-out <dir>"
143525
+ );
143293
143526
  }
143294
143527
  if (cmd === "accounts") {
143295
- return "\n\u274C \u6CA1\u6709 `accounts` \u547D\u540D\u7A7A\u95F4\u3002\u67E5\u8BE2\u8D26\u6237\u5217\u8868\u8BF7\u7528\uFF1A\n siluzan-tso list-accounts \u2026\n \u591A\u8D26\u6237\u753B\u50CF\uFF1Asiluzan-tso accounts-digest \u2026\n";
143528
+ return fatal(
143529
+ "\u274C \u6CA1\u6709 `accounts` \u547D\u540D\u7A7A\u95F4\u3002\u67E5\u8BE2\u8D26\u6237\u5217\u8868\u8BF7\u7528\uFF1A\n siluzan-tso list-accounts \u2026\n \u591A\u8D26\u6237\u753B\u50CF\uFF1Asiluzan-tso accounts-digest \u2026"
143530
+ );
143531
+ }
143532
+ if (cmd === "account" && args[1] === "balance") {
143533
+ return fatal(
143534
+ "\u274C \u6CA1\u6709 `account balance`\u3002\u5355\u6237\uFF1Asiluzan-tso balance -m <\u5A92\u4F53> -a <id>\u3002\n \u591A\u6237\uFF1Asiluzan-tso balance-scan -m Google --json-out <dir>"
143535
+ );
143296
143536
  }
143297
143537
  if (cmd === "cpa-risk-scan" || cmd === "cpa-scan" || cmd === "cpa_risk_scan") {
143298
- return "\n\u274C \u6CA1\u6709 `cpa-risk-scan` / `cpa-scan` \u547D\u4EE4\u3002\u8F6C\u5316\u6210\u672C / CPA \u5DE1\u68C0\u8BF7\u7528\uFF1A\n siluzan-tso accounts-digest -m Google --max-cpa <\u9608\u503C> --start <S> --end <D> \\\n --skip-balance --json-out ./snap-cpa\n \u96F6\u8F6C\u5316\u4EC5\u5F53\u6D88\u8017\u5DF2\u8D85\u8FC7\u9608\u503C\u624D\u547D\u4E2D\u3002\u8BFB\u76D8\u540E\u628A agentBrief.userDelivery \u539F\u6837\u53D1\u7ED9\u7528\u6237\u3002\n";
143538
+ return fatal(
143539
+ "\u274C \u6CA1\u6709 `cpa-risk-scan` / `cpa-scan` \u547D\u4EE4\u3002\u8F6C\u5316\u6210\u672C / CPA \u5DE1\u68C0\u8BF7\u7528\uFF1A\n siluzan-tso accounts-digest -m Google --max-cpa <\u9608\u503C> --start <S> --end <D> \\\n --skip-balance --json-out ./snap-cpa\n \u96F6\u8F6C\u5316\u4EC5\u5F53\u6D88\u8017\u5DF2\u8D85\u8FC7\u9608\u503C\u624D\u547D\u4E2D\u3002\u8BFB\u76D8\u540E\u628A agentBrief.userDelivery \u539F\u6837\u53D1\u7ED9\u7528\u6237\u3002"
143540
+ );
143299
143541
  }
143300
- return null;
143542
+ return playbookCodeFatal(cmd) ?? loginCustomerFlagIssue(args);
143301
143543
  }
143302
143544
  function interceptAgentCompatArgv(argv) {
143303
143545
  const msg = agentCompatFatalMessage(argv);