siluzan-tso-cli 1.1.37-beta.10 → 1.1.37-beta.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -51,7 +51,7 @@ siluzan-tso init -d /path/to/skills # 写入自定义目录
51
51
  siluzan-tso init --force # 强制覆盖已存在文件
52
52
  ```
53
53
 
54
- > **注意**:当前为测试版(1.1.37-beta.10),供内部测试使用。正式发布后安装命令将改为 `npm install -g siluzan-tso-cli`。
54
+ > **注意**:当前为测试版(1.1.37-beta.12),供内部测试使用。正式发布后安装命令将改为 `npm install -g siluzan-tso-cli`。
55
55
 
56
56
  | 助手 | 建议 `--ai` |
57
57
  | ----------------------- | ------------------------------------ |
package/dist/index.js CHANGED
@@ -2202,6 +2202,11 @@ function skipAuthSetupInAgentEnv(commandLabel) {
2202
2202
  }
2203
2203
  return true;
2204
2204
  }
2205
+ function blockMediaAccountOAuthInAgentEnv(_commandLabel) {
2206
+ if (!isSiluzanAgentEnv()) return false;
2207
+ console.log("\u8BF7\u4F7F\u7528 present_reauth \u5B8C\u6210\u6388\u6743");
2208
+ return true;
2209
+ }
2205
2210
  function trimOrUndefined(value) {
2206
2211
  const trimmed = value?.trim();
2207
2212
  return trimmed ? trimmed : void 0;
@@ -105657,7 +105662,8 @@ var COL_META = [
105657
105662
  { key: "company", header: "\u516C\u53F8\u540D\u79F0" },
105658
105663
  { key: "id", header: "\u8D26\u6237ID" },
105659
105664
  { key: "name", header: "\u8D26\u6237\u540D\u79F0" },
105660
- { key: "oauthState", header: "\u72B6\u6001" },
105665
+ /** 对应 JSON `ma.invalidOAuthToken`(true=失效 / false=正常) */
105666
+ { key: "authStatus", header: "\u6388\u6743\u72B6\u6001" },
105661
105667
  { key: "auditState", header: "\u5BA1\u6838\u72B6\u6001" },
105662
105668
  { key: "authType", header: "\u6388\u6743\u7C7B\u578B" },
105663
105669
  { key: "createdAt", header: "\u6388\u6743/\u5F00\u6237\u65F6\u95F4" }
@@ -105757,8 +105763,8 @@ function formatMetaAuthType(mediaAccountType) {
105757
105763
  if (mediaAccountType === "FacebookAds") return "Facebook \u5E7F\u544A\u8D26\u6237";
105758
105764
  return mediaAccountType ?? "-";
105759
105765
  }
105760
- function formatMetaOAuthColumn(ma) {
105761
- return ma.invalidOAuthToken ? "\u5931\u6548" : "\u6B63\u5E38";
105766
+ function formatOAuthAuthStatus(ma) {
105767
+ return ma.invalidOAuthToken ? "\u26A0\uFE0F \u5931\u6548" : "\u2705 \u6B63\u5E38";
105762
105768
  }
105763
105769
  function formatMetaAuditStatus(ma) {
105764
105770
  const ms = ma.mediaAccountState ?? "";
@@ -105805,7 +105811,7 @@ function printMetaTable(items2, tableOpts) {
105805
105811
  company: item.mag?.advertiserName ?? "-",
105806
105812
  id: displayMetaAccountId(ma.mediaCustomerId),
105807
105813
  name: ma.mediaCustomerName ?? "-",
105808
- oauthState: formatMetaOAuthColumn(ma),
105814
+ authStatus: formatOAuthAuthStatus(ma),
105809
105815
  auditState: formatMetaAuditStatus(ma),
105810
105816
  authType: formatMetaAuthType(ma.mediaAccountType),
105811
105817
  createdAt: fmtDate(ma.createdDateTime)
@@ -105816,7 +105822,6 @@ function printMetaTable(items2, tableOpts) {
105816
105822
  function printSpendMetricsAccountTable(items2, tableOpts) {
105817
105823
  const rows = items2.map((item) => {
105818
105824
  const ma = item.ma;
105819
- const authStatus = ma.invalidOAuthToken ? "\u26A0\uFE0F \u5931\u6548" : "\u2705 \u6B63\u5E38";
105820
105825
  const sharedCount = Array.isArray(ma.accountIds) ? String(Math.max(0, ma.accountIds.length - 1)) : "-";
105821
105826
  return {
105822
105827
  company: item.mag?.advertiserName ?? "-",
@@ -105828,7 +105833,7 @@ function printSpendMetricsAccountTable(items2, tableOpts) {
105828
105833
  conversions: fmtNum(ma["conversions"], 0),
105829
105834
  clicks: fmtNum(ma["clicks"], 0),
105830
105835
  cpc: fmtNum(ma["costPerClick"]),
105831
- authStatus,
105836
+ authStatus: formatOAuthAuthStatus(ma),
105832
105837
  createdAt: fmtDate(ma.createdDateTime),
105833
105838
  shared: sharedCount
105834
105839
  };
@@ -105838,7 +105843,6 @@ function printSpendMetricsAccountTable(items2, tableOpts) {
105838
105843
  function printYandexTable(items2, tableOpts) {
105839
105844
  const rows = items2.map((item) => {
105840
105845
  const ma = item.ma;
105841
- const authStatus = ma.invalidOAuthToken ? "\u26A0\uFE0F \u5931\u6548" : "\u2705 \u6B63\u5E38";
105842
105846
  const sharedCount = Array.isArray(ma.accountIds) ? String(Math.max(0, ma.accountIds.length - 1)) : "-";
105843
105847
  const pwd = ma.mediaPassword != null && String(ma.mediaPassword).trim() !== "" ? String(ma.mediaPassword) : "-";
105844
105848
  return {
@@ -105851,7 +105855,7 @@ function printYandexTable(items2, tableOpts) {
105851
105855
  conversions: fmtNum(ma["conversions"], 0),
105852
105856
  clicks: fmtNum(ma["clicks"], 0),
105853
105857
  cpc: fmtNum(ma["costPerClick"]),
105854
- authStatus,
105858
+ authStatus: formatOAuthAuthStatus(ma),
105855
105859
  createdAt: fmtDate(ma.createdDateTime),
105856
105860
  shared: sharedCount
105857
105861
  };
@@ -105861,7 +105865,6 @@ function printYandexTable(items2, tableOpts) {
105861
105865
  function printTikTokTable(items2, tableOpts) {
105862
105866
  const rows = items2.map((item) => {
105863
105867
  const ma = item.ma;
105864
- const authStatus = ma.invalidOAuthToken ? "\u26A0\uFE0F \u5931\u6548" : "\u2705 \u6B63\u5E38";
105865
105868
  const sharedCount = Array.isArray(ma.accountIds) ? String(Math.max(0, ma.accountIds.length - 1)) : "-";
105866
105869
  return {
105867
105870
  company: item.mag?.advertiserName ?? "-",
@@ -105874,7 +105877,7 @@ function printTikTokTable(items2, tableOpts) {
105874
105877
  clicks: fmtNum(ma["clicks"], 0),
105875
105878
  cpc: fmtNum(ma["costPerClick"]),
105876
105879
  bc: formatTikTokBcColumn(ma),
105877
- authStatus,
105880
+ authStatus: formatOAuthAuthStatus(ma),
105878
105881
  auditStatus: formatTikTokAuditStatus(ma),
105879
105882
  createdAt: fmtDate(ma.createdDateTime),
105880
105883
  shared: sharedCount
@@ -105885,7 +105888,6 @@ function printTikTokTable(items2, tableOpts) {
105885
105888
  function printGoogleTable(items2, tableOpts) {
105886
105889
  const rows = items2.map((item) => {
105887
105890
  const ma = item.ma;
105888
- const authStatus = ma.invalidOAuthToken ? "\u26A0\uFE0F \u5931\u6548" : "\u2705 \u6B63\u5E38";
105889
105891
  const platformStatus = ma.platformStatus ?? "-";
105890
105892
  const sharedCount = Array.isArray(ma.accountIds) ? String(Math.max(0, ma.accountIds.length - 1)) : "-";
105891
105893
  return {
@@ -105900,7 +105902,7 @@ function printGoogleTable(items2, tableOpts) {
105900
105902
  cpc: fmtNum(ma["costPerClick"]),
105901
105903
  arit: String(ma.aritScore ?? "-"),
105902
105904
  platformStatus,
105903
- authStatus,
105905
+ authStatus: formatOAuthAuthStatus(ma),
105904
105906
  createdAt: fmtDate(ma.createdDateTime),
105905
105907
  shared: sharedCount
105906
105908
  };
@@ -105913,7 +105915,8 @@ var COL_DEFAULT_WITH_MEDIA = [
105913
105915
  { key: "advertiserName", header: "\u5E7F\u544A\u4E3B" },
105914
105916
  { key: "mediaCustomerName", header: "\u8D26\u6237\u540D\u79F0" },
105915
105917
  COL_CURRENCY,
105916
- { key: "status", header: "\u8D26\u6237\u72B6\u6001" }
105918
+ { key: "status", header: "\u8D26\u6237\u72B6\u6001" },
105919
+ { key: "authStatus", header: "\u6388\u6743\u72B6\u6001" }
105917
105920
  ];
105918
105921
  var COL_DEFAULT_SINGLE = COL_DEFAULT_WITH_MEDIA.filter(
105919
105922
  (c) => c.key !== "mediaType"
@@ -105926,10 +105929,8 @@ function printDefaultTable(items2, media, tableOpts) {
105926
105929
  statusLabel = "\u{1F6AB} \u5DF2\u7981\u7528";
105927
105930
  } else if (!ma.mediaCustomerId) {
105928
105931
  statusLabel = "\u23F3 \u672A\u5F00\u901A";
105929
- } else if (ma.invalidOAuthToken) {
105930
- statusLabel = "\u26A0\uFE0F OAuth\u5931\u6548";
105931
105932
  } else {
105932
- statusLabel = "\u2705 \u6B63\u5E38";
105933
+ statusLabel = ma.mediaAccountState?.trim() ? ma.mediaAccountState : "\u2705 \u6B63\u5E38";
105933
105934
  }
105934
105935
  return {
105935
105936
  mediaType: ma.mediaAccountType ?? "",
@@ -105937,7 +105938,8 @@ function printDefaultTable(items2, media, tableOpts) {
105937
105938
  advertiserName: item.mag?.advertiserName ?? "",
105938
105939
  mediaCustomerName: ma.mediaCustomerName ?? "",
105939
105940
  currency: formatCurrencyCodeLabel(ma.currencyCode),
105940
- status: statusLabel
105941
+ status: statusLabel,
105942
+ authStatus: formatOAuthAuthStatus(ma)
105941
105943
  };
105942
105944
  });
105943
105945
  const columns = media ? COL_DEFAULT_SINGLE : COL_DEFAULT_WITH_MEDIA;
@@ -121649,6 +121651,15 @@ async function runAccountMccUnbind(opts) {
121649
121651
  }
121650
121652
 
121651
121653
  // src/commands/account-manage/google-access-permission.ts
121654
+ function hintGoogleOAuth(kind) {
121655
+ if (isSiluzanAgentEnv()) {
121656
+ return "\u8BF7\u4F7F\u7528 present_reauth \u5B8C\u6210\u6388\u6743";
121657
+ }
121658
+ if (kind === "reauth") {
121659
+ return "list-accounts --json-out \u53D6 ma.entityId \u540E\u6267\u884C\uFF1Asiluzan-tso account reauth -m Google --id <entityId>";
121660
+ }
121661
+ return "\u6267\u884C siluzan-tso account auth -m Google \u5B8C\u6210 OAuth \u7ED1\u5B9A\u3002";
121662
+ }
121652
121663
  function assertGoogleMediaCustomerId(raw) {
121653
121664
  const id = raw.trim();
121654
121665
  if (!id) {
@@ -121695,7 +121706,7 @@ function interpretCustomerAccessPermission(mediaCustomerId, httpStatus, rawBody)
121695
121706
  status: "reauth_required",
121696
121707
  accessible: false,
121697
121708
  message: "\u8D26\u6237\u5DF2\u7ED1\u5B9A\u4F46 Google OAuth \u4E0D\u53EF\u7528\uFF0C\u9700\u91CD\u65B0\u6388\u6743\u3002",
121698
- hint: "list-accounts --json-out \u53D6 ma.entityId \u540E\u6267\u884C\uFF1Asiluzan-tso account reauth -m Google --id <entityId>"
121709
+ hint: hintGoogleOAuth("reauth")
121699
121710
  };
121700
121711
  }
121701
121712
  return {
@@ -121713,7 +121724,7 @@ function interpretCustomerAccessPermission(mediaCustomerId, httpStatus, rawBody)
121713
121724
  status: "google_not_bound",
121714
121725
  accessible: false,
121715
121726
  message: "\u5F53\u524D\u4E1D\u8DEF\u8D5E\u8D26\u53F7\u672A\u7ED1\u5B9A Google \u5A92\u4F53\u6388\u6743\u3002",
121716
- hint: "\u6267\u884C siluzan-tso account auth -m Google \u5B8C\u6210 OAuth \u7ED1\u5B9A\u3002"
121727
+ hint: hintGoogleOAuth("auth")
121717
121728
  };
121718
121729
  }
121719
121730
  return {
@@ -121801,9 +121812,13 @@ Google \u8D26\u6237\u8BBF\u95EE\u6743\u9650\u6821\u9A8C ${mediaCustomerId}`);
121801
121812
  }
121802
121813
 
121803
121814
  // src/commands/account-manage/share.ts
121815
+ init_dist();
121804
121816
  init_auth();
121805
121817
  init_cli_json_snapshot();
121806
121818
  init_cli_table();
121819
+ function normalizeShareLookupPhone(input) {
121820
+ return normalizeChinaPhone(input.trim());
121821
+ }
121807
121822
  async function runAccountDelink(opts) {
121808
121823
  if (!opts.id && (!opts.ids || opts.ids.length === 0)) {
121809
121824
  console.error("\n\u274C \u8BF7\u901A\u8FC7 --id \u6216 --ids \u63D0\u4F9B\u8981\u65AD\u5F00\u5173\u8054\u7684\u8D26\u6237 entityId\n");
@@ -121860,13 +121875,24 @@ async function runAccountShare(opts) {
121860
121875
  console.error("\n\u274C \u65E0\u6CD5\u63A8\u5BFC\u4E3B API \u5730\u5740\uFF0C\u8BF7\u68C0\u67E5 apiBaseUrl \u914D\u7F6E\n");
121861
121876
  process.exit(1);
121862
121877
  }
121878
+ const phone = normalizeShareLookupPhone(opts.phone);
121879
+ if (!isValidChinaPhone(phone)) {
121880
+ console.error(
121881
+ `
121882
+ \u274C \u624B\u673A\u53F7\u683C\u5F0F\u65E0\u6548\uFF1A${opts.phone}
121883
+ SimpleAccountInfo \u987B\u4F20\u5E26\u56FD\u5BB6\u7801\u7684\u53F7\u7801\uFF08\u4E2D\u56FD\u5927\u9646\u9ED8\u8BA4 +86\uFF09\u3002
121884
+ \u793A\u4F8B\uFF1A--phone 18379752858 \u6216 --phone +8618379752858\uFF08\u5DF2\u6709\u56FD\u5BB6\u7801\u65F6\u52FF\u518D\u8865\uFF09
121885
+ `
121886
+ );
121887
+ process.exit(1);
121888
+ }
121863
121889
  let userId;
121864
121890
  try {
121865
- const lookupUrl = `${config.mainApiUrl}/query/account/SimpleAccountInfo?phone=${encodeURIComponent(opts.phone)}`;
121891
+ const lookupUrl = `${config.mainApiUrl}/query/account/SimpleAccountInfo?phone=${encodeURIComponent(phone)}`;
121866
121892
  const users = await apiFetch2(lookupUrl, config, {}, opts.verbose);
121867
121893
  if (!Array.isArray(users) || users.length === 0) {
121868
121894
  console.error(`
121869
- \u274C \u672A\u627E\u5230\u624B\u673A\u53F7 ${opts.phone} \u5BF9\u5E94\u7684\u4E1D\u8DEF\u8D5E\u8D26\u53F7\uFF0C\u8BF7\u786E\u8BA4\u8BE5\u7528\u6237\u5DF2\u5B8C\u6210\u6CE8\u518C
121895
+ \u274C \u672A\u627E\u5230\u624B\u673A\u53F7 ${phone} \u5BF9\u5E94\u7684\u4E1D\u8DEF\u8D5E\u8D26\u53F7\uFF0C\u8BF7\u786E\u8BA4\u8BE5\u7528\u6237\u5DF2\u5B8C\u6210\u6CE8\u518C
121870
121896
  `);
121871
121897
  process.exit(1);
121872
121898
  }
@@ -121892,7 +121918,7 @@ async function runAccountShare(opts) {
121892
121918
  process.exit(1);
121893
121919
  }
121894
121920
  console.log(`
121895
- \u2705 \u8D26\u6237\u5DF2\u6210\u529F\u5206\u4EAB\u7ED9\u624B\u673A\u53F7 ${opts.phone} \u7684\u7528\u6237\uFF08AccountId: ${userId}\uFF09
121921
+ \u2705 \u8D26\u6237\u5DF2\u6210\u529F\u5206\u4EAB\u7ED9\u624B\u673A\u53F7 ${phone} \u7684\u7528\u6237\uFF08AccountId: ${userId}\uFF09
121896
121922
  `);
121897
121923
  }
121898
121924
  async function runAccountUnshare(opts) {
@@ -121965,13 +121991,16 @@ async function runAccountShareDetail(opts) {
121965
121991
  }
121966
121992
 
121967
121993
  // src/commands/account-manage/oauth.ts
121968
- init_auth();
121969
121994
  init_dist();
121995
+ init_auth();
121970
121996
  function toApiMediaType(media) {
121971
121997
  return media === "Meta" ? "FacebookAds" : media;
121972
121998
  }
121973
121999
  var tryOpenBrowser = tryOpenHttpsUrlInBrowser;
121974
122000
  async function runAccountAuth(opts) {
122001
+ if (blockMediaAccountOAuthInAgentEnv("account auth")) {
122002
+ process.exit(1);
122003
+ }
121975
122004
  const config = loadConfig(opts.token);
121976
122005
  const apiMediaType = toApiMediaType(opts.media);
121977
122006
  const webUrl = deriveWebUrl(config.apiBaseUrl);
@@ -122003,6 +122032,9 @@ async function runAccountAuth(opts) {
122003
122032
  });
122004
122033
  }
122005
122034
  async function runAccountReauth(opts) {
122035
+ if (blockMediaAccountOAuthInAgentEnv("account reauth")) {
122036
+ process.exit(1);
122037
+ }
122006
122038
  if (!opts.id && (!opts.ids || opts.ids.length === 0)) {
122007
122039
  console.error(
122008
122040
  "\n\u274C \u91CD\u65B0\u6388\u6743\u987B\u6307\u5B9A\u8981\u89E3\u7ED1\u7684\u8D26\u6237 entityId\uFF1A--id <entityId> \u6216 --ids id1,id2\n entityId \u6765\u81EA list-accounts --json-out \u7684 ma.entityId\uFF08\u4E0D\u662F mediaCustomerId\uFF09\n"
@@ -122818,7 +122850,10 @@ function register23(program2) {
122818
122850
  verbose: opts.verbose
122819
122851
  });
122820
122852
  });
122821
- accountCmd.command("share").description("\u5C06 Google \u8D26\u6237\u5206\u4EAB\u7ED9\u6307\u5B9A\u624B\u673A\u53F7\u7528\u6237\uFF08\u8BE5\u7528\u6237\u9700\u5DF2\u6CE8\u518C\u4E1D\u8DEF\u8D5E\uFF09").requiredOption("--id <entityId>", "\u8D26\u6237 entityId\uFF08\u6765\u81EA list-accounts \u7684 ma.entityId \u5B57\u6BB5\uFF09").requiredOption("--phone <phone>", "\u88AB\u5206\u4EAB\u4EBA\u7684\u4E1D\u8DEF\u8D5E\u6CE8\u518C\u624B\u673A\u53F7").option("-t, --token <token>", "Auth Token").option("--verbose", "\u8BE6\u7EC6\u9519\u8BEF\u4FE1\u606F", false).action(async (opts) => {
122853
+ accountCmd.command("share").description("\u5C06 Google \u8D26\u6237\u5206\u4EAB\u7ED9\u6307\u5B9A\u624B\u673A\u53F7\u7528\u6237\uFF08\u8BE5\u7528\u6237\u9700\u5DF2\u6CE8\u518C\u4E1D\u8DEF\u8D5E\uFF09").requiredOption("--id <entityId>", "\u8D26\u6237 entityId\uFF08\u6765\u81EA list-accounts \u7684 ma.entityId \u5B57\u6BB5\uFF09").requiredOption(
122854
+ "--phone <phone>",
122855
+ "\u88AB\u5206\u4EAB\u4EBA\u624B\u673A\u53F7\uFF08\u5927\u9646 11 \u4F4D\u4F1A\u81EA\u52A8\u8865 +86\uFF1B\u5DF2\u5E26 +86/+861\u2026 \u5219\u539F\u6837\u4F7F\u7528\uFF0C\u4E0D\u91CD\u590D\u62FC\u63A5\uFF09"
122856
+ ).option("-t, --token <token>", "Auth Token").option("--verbose", "\u8BE6\u7EC6\u9519\u8BEF\u4FE1\u606F", false).action(async (opts) => {
122822
122857
  await runAccountShare({
122823
122858
  token: opts.token,
122824
122859
  id: opts.id,
@@ -1,5 +1,5 @@
1
1
  {
2
2
  "slug": "siluzan-tso",
3
- "version": "1.1.37-beta.10",
4
- "publishedAt": 1784255895813
3
+ "version": "1.1.37-beta.12",
4
+ "publishedAt": 1784276742609
5
5
  }
@@ -28,7 +28,8 @@ siluzan-tso list-accounts [选项]
28
28
 
29
29
  | 用户意图 | 推荐命令(一步) | 脚本读落盘 JSON |
30
30
  | ----------------------------- | ----------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------- |
31
- | 列出全部某媒体账户 | `list-accounts -m <媒体> --page-size 999 --json-out <dir>` | `items[]`(`ma.mediaCustomerId`、`ma.mediaCustomerName`、`ma.currencyCode`、`ma.mediaAccountState` 等) |
31
+ | 列出全部某媒体账户 | `list-accounts -m <媒体> --page-size 999 --json-out <dir>` | `items[]`(`ma.mediaCustomerId`、`ma.mediaCustomerName`、`ma.currencyCode`、`ma.invalidOAuthToken` 等) |
32
+ | 哪些账户 OAuth / 授权失效 | 同上(或 `-s invalid`);表格看「授权状态」列 | **`ma.invalidOAuthToken === true`**(勿用审核状态 / `mediaAccountState`) |
32
33
  | 有多少个账户 | 同上 | **`total`**(无需翻页;`itemCount < total` 时说明 page-size 不够大) |
33
34
  | 只查某一个户 | `list-accounts -m <媒体> -k <id或名称> --json-out <dir>` | 无需大 page-size |
34
35
  | **Meta 全部账户 + 余额/消耗** | **`accounts-digest -m MetaAd --json-out <dir>`**(一步;内部翻页+分批) | `accounts-digest-metaad.json` → `data.items[]`(含 `balance`、`spend`) |
@@ -66,13 +67,17 @@ siluzan-tso list-accounts -m Google --page 2 --page-size 999 --json-out ./snap-p
66
67
 
67
68
  **输出字段说明:**
68
69
 
69
- | 字段 | 说明 |
70
- | ----------------- | -------------------------------------------------------------------------------------------------------------------------------- |
71
- | `entityId` | 丝路赞内部 ID,`delink`/`share`、**`account-active-bills`** 等操作使用此 ID(**不是** `mediaCustomerId`) |
72
- | `mediaCustomerId` | 媒体平台账户数字 ID(Google Customer ID 等) |
73
- | `currencyCode` | 账户主币种:`CNY`(人民币)或 `USD`(美金)等;**表格有「币种」列**;报告/Excel 须与此一致,见 `references/accounts/currency.md` |
74
- | `name` | 账户名称 |
75
- | `status` | 账户状态 |
70
+ | 字段 / JSON 路径 | 说明 |
71
+ | ----------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------- |
72
+ | `ma.entityId` | 丝路赞内部 ID,`delink`/`share`/`reauth`、**`account-active-bills`** 等操作使用此 ID(**不是** `mediaCustomerId`) |
73
+ | `ma.mediaCustomerId` | 媒体平台账户数字 ID(Google Customer ID 等) |
74
+ | `ma.currencyCode` | 账户主币种:`CNY` / `USD` 等;**表格有「币种」列**;报告/Excel 须与此一致,见 `references/accounts/currency.md` |
75
+ | `ma.mediaCustomerName` | 账户名称(表格「账户名称」) |
76
+ | `ma.mediaAccountState`| 平台开户/审核态(如 Approved / Linked);**不是** OAuth 是否可用 |
77
+ | **`ma.invalidOAuthToken`** | **OAuth 是否失效**:`true`=失效,`false`=正常。**表格必有「授权状态」列**(✅ 正常 / ⚠️ 失效),与此字段一一对应;判失效、筛 `-s invalid`、走 `reauth` 均看它 |
78
+ | `ma.TTADInfo.status` 等 | 媒体侧投放/审核细态(TikTok 表格「审核状态」等);**勿**当成 OAuth 授权状态 |
79
+
80
+ > **Agent**:用户问「哪些授权失效 / OAuth 状态」时,读盘看 `items[].ma.invalidOAuthToken`,表格看「授权状态」列;**不要**用 `mediaAccountState` 或审核状态列代替。
76
81
 
77
82
  ---
78
83
 
@@ -330,12 +335,6 @@ siluzan-tso account check-access -a 4256317784 --json-out ./snap-access
330
335
 
331
336
  ---
332
337
 
333
- ### auth — 添加媒体平台 OAuth 授权(首次绑定)
334
-
335
- 在浏览器中打开对应媒体的 OAuth 授权页面,授权后账户自动绑定到丝路赞。对应网页 **「添加授权」**。
336
-
337
- > **OAuth 已失效**(`invalidOAuthToken=true`)时**不要**用本命令,须走下方 **`reauth`**(重新授权必须先解绑)。
338
-
339
338
  ```bash
340
339
  siluzan-tso account auth -m <媒体类型>
341
340
  ```
@@ -344,7 +343,7 @@ siluzan-tso account auth -m <媒体类型>
344
343
  | -------------------- | ------------------------------------------------------------------------ |
345
344
  | `-m, --media <type>` | 媒体类型(必填):`Google \| TikTok \| Meta \| Yandex \| BingV2 \| Kwai` |
346
345
 
347
- **示例:**
346
+ **示例(仅本地 / 非 Siluzan Agent CLI):**
348
347
 
349
348
  ```bash
350
349
  # 首次授权 Google Ads 账户
@@ -357,9 +356,9 @@ siluzan-tso account auth -m TikTok
357
356
  siluzan-tso account auth -m Meta
358
357
  ```
359
358
 
360
- > CLI 会自动在系统默认浏览器中打开授权页;无法打开时输出 URL 供手动粘贴。授权完成后会跳回丝路赞,账户立即生效。
359
+ > CLI 会自动在系统默认浏览器中打开授权页;无法打开时输出 URL 供手动粘贴。授权完成后会跳回丝路赞 TSO 绑定页,账户立即生效。
361
360
  >
362
- > **Agent 硬约束(auth / reauth 共通)**:CLI stdout 会打印完整 `https://…` OAuth 链接(Agent 沙箱不会自动开浏览器)。**必须把该 URL 原样贴进给用户的回复**,禁止只说「链接已生成 / 我这边还有链接」却不贴出;用户无法从工具日志自行翻找。
361
+ > **非 Agent 环境**若仍用手跑 CLIstdout 打印的完整 `https://…` OAuth 链接须原样贴给用户(沙箱不会自动开浏览器)。
363
362
 
364
363
  ---
365
364
 
@@ -367,6 +366,8 @@ siluzan-tso account auth -m Meta
367
366
 
368
367
  OAuth 失效时恢复授权。对齐 TSO 网页 **「重新授权」**:程序会先 **delink** 断开关联,再跳转媒体 OAuth。**禁止**对失效账户跳过解绑直接用 `account auth`。
369
368
 
369
+ > **Siluzan Agent**:同 `auth`——**禁止**执行;须走 **connectors / 平台授权工具**。CLI 拦截时不会先解绑。
370
+
370
371
  ```bash
371
372
  siluzan-tso account reauth -m <媒体类型> --id <entityId>
372
373
  siluzan-tso account reauth -m Google --ids <id1,id2>
@@ -378,7 +379,7 @@ siluzan-tso account reauth -m Google --ids <id1,id2>
378
379
  | `--id <entityId>` | 单个账户 `entityId`(来自 `list-accounts` 的 `ma.entityId`) |
379
380
  | `--ids <id1,id2>` | 批量 `entityId`,逗号分隔(与 `--id` 二选一) |
380
381
 
381
- **示例:**
382
+ **示例(仅本地 / 非 Siluzan Agent CLI):**
382
383
 
383
384
  ```bash
384
385
  # 1. 查失效账户的 entityId
@@ -391,13 +392,13 @@ siluzan-tso account reauth -m BingV2 --id <entityId> --commit "重新授权 Bing
391
392
  siluzan-tso list-accounts -m BingV2 -k <mediaCustomerId>
392
393
  ```
393
394
 
394
- **执行后 Agent 必须:**
395
+ **本地 CLI 执行后须:**
395
396
 
396
397
  1. 从 CLI 输出中提取 OAuth URL(含 `login.microsoftonline.com` / Google 等),**原样发给用户**并说明「请在浏览器打开完成授权」。
397
398
  2. 说明:步骤 1 已 delink,账户可能暂时从 `list-accounts` 消失;用户完成授权前无法拉数。
398
399
  3. 若用户之后才说要绑定回来、且当时未贴链接:再跑 **`account auth -m <媒体>`**(勿再 `reauth`——已无 entityId),把**新**链接贴出。勿声称「还有刚才的链接」却不粘贴。
399
400
 
400
- > 手动两步等价于 `reauth`:`account delink --id …` → `account auth -m …`(须用户确认解绑风险)。
401
+ > 手动两步等价于 `reauth`:`account delink --id …` → `account auth -m …`(须用户确认解绑风险;**Agent 环境仍勿用**)。
401
402
 
402
403
  ---
403
404
 
@@ -460,6 +461,13 @@ siluzan-tso account mcc-unbind --customers <mediaCustomerId> --mcc <MCC客户ID>
460
461
 
461
462
  将 Google 广告账户分享给指定手机号用户(手机号必须已在丝路赞注册)。
462
463
 
464
+ 查找被分享人走主站 `GET /query/account/SimpleAccountInfo?phone=…`(须带国家码;与网页一致)。
465
+
466
+ | 选项 | 说明 |
467
+ | ----------------- | -------------------------------------------------------------------------------------------- |
468
+ | `--id <entityId>` | 账户 `entityId` |
469
+ | `--phone <phone>` | 被分享人手机号:**裸 11 位默认补 `+86`**;已是 `+86…` / `86…` **不再重复拼接**(勿写成 `++86`) |
470
+
463
471
  ```bash
464
472
  siluzan-tso account share --id <entityId> --phone <手机号>
465
473
  ```
@@ -467,7 +475,11 @@ siluzan-tso account share --id <entityId> --phone <手机号>
467
475
  **示例:**
468
476
 
469
477
  ```bash
478
+ # 11 位本地号 → CLI 查询时自动变为 +8613800138000
470
479
  siluzan-tso account share --id abc123def456 --phone 13800138000
480
+
481
+ # 已带国家码:原样查询,不重复加 +86
482
+ siluzan-tso account share --id abc123def456 --phone +8618379752858
471
483
  ```
472
484
 
473
485
  ---
@@ -156,7 +156,7 @@
156
156
  - **触发**:分享/取消分享、解绑、OAuth 重授权、Google MCC 绑定/解绑、TikTok BC 绑定/解绑、Meta BM 绑定、TikTok 关闭账户、Google 被封提现、Google 邮箱授权管理。
157
157
  - **必读**:`references/accounts/accounts.md`(各 `account` 子命令参数与 ID 口径)。
158
158
  - **步骤(按场景)**:
159
- - **分享**:`list-accounts --json-out` 取 `entityId` → `account share --id <entityId> --phone <手机号>`;查 `account share-detail --customer-id <mediaCustomerId>`;取消 `account unshare --id <entityId> --account-id <userId>`。
159
+ - **分享**:`list-accounts --json-out` 取 `entityId` → `account share --id <entityId> --phone <手机号>`(`--phone` 裸 11 位补 `+86`,已有国家码则不补;见 `accounts.md` § share);查 `account share-detail --customer-id <mediaCustomerId>`;取消 `account unshare --id <entityId> --account-id <userId>`。
160
160
  - **解绑**:`account delink --id <entityId>` / `--ids id1,id2`。
161
161
  - **OAuth 重授权**:`invalidOAuthToken=true` → `list-accounts --json-out` 取 `ma.entityId` → **`account reauth -m <媒体> --id <entityId>`**(内置先 delink 再 OAuth,对齐网页「重新授权」)→ `list-accounts` 验证。**禁止**对失效账户直接用 `account auth`(首次「添加授权」专用)。
162
162
  - **首次 OAuth 添加授权**:`account auth -m <媒体>`(无需先 delink)。
@@ -9,7 +9,7 @@ $ErrorActionPreference = 'Stop'
9
9
  # -- Package info (injected at build time) ------------------------------------
10
10
  $PKG_NAME = 'siluzan-tso-cli'
11
11
  # PKG_VERSION 锁定到与本脚本同批构建产物一致的版本,避免与 dist/skill 错位
12
- $PKG_VERSION = '1.1.37-beta.10'
12
+ $PKG_VERSION = '1.1.37-beta.12'
13
13
  $CLI_BIN = 'siluzan-tso'
14
14
  $SKILL_LABEL = 'Siluzan TSO'
15
15
  $INSTALL_CMD = 'npm install -g siluzan-tso-cli@beta'
@@ -9,7 +9,7 @@ set -euo pipefail
9
9
  # -- Package info (injected at build time) ------------------------------------
10
10
  readonly PKG_NAME="siluzan-tso-cli"
11
11
  # PKG_VERSION 锁定到与本脚本同批构建产物一致的版本,避免与 dist/skill 错位
12
- readonly PKG_VERSION="1.1.37-beta.10"
12
+ readonly PKG_VERSION="1.1.37-beta.12"
13
13
  readonly CLI_BIN="siluzan-tso"
14
14
  readonly SKILL_LABEL="Siluzan TSO"
15
15
  readonly INSTALL_CMD="npm install -g siluzan-tso-cli@beta"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "siluzan-tso-cli",
3
- "version": "1.1.37-beta.10",
3
+ "version": "1.1.37-beta.12",
4
4
  "description": "Siluzan 广告账户管理 CLI — 查询账户、余额、消耗数据,管理绑定关系与充值。",
5
5
  "keywords": [
6
6
  "ad-account",