siluzan-tso-cli 1.1.39-beta.1 → 1.1.39-beta.3

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.39-beta.1),供内部测试使用。正式发布后安装命令将改为 `npm install -g siluzan-tso-cli`。
54
+ > **注意**:当前为测试版(1.1.39-beta.3),供内部测试使用。正式发布后安装命令将改为 `npm install -g siluzan-tso-cli`。
55
55
 
56
56
  | 助手 | 建议 `--ai` |
57
57
  | ----------------------- | ------------------------------------ |
package/dist/index.js CHANGED
@@ -3218,6 +3218,16 @@ function getResolvedWriteAuditCommit() {
3218
3218
  const env = process.env.SILUZAN_AUDIT_NOTE?.trim() ?? "";
3219
3219
  return env !== "" ? truncateCommit(env) : "";
3220
3220
  }
3221
+ function isWriteAuditCommitRequiredSatisfied() {
3222
+ if (isSiluzanAgentEnv()) return true;
3223
+ return getResolvedWriteAuditCommit() !== "";
3224
+ }
3225
+ function resolveWriteAuditCommitForRecord() {
3226
+ const c = getResolvedWriteAuditCommit();
3227
+ if (c !== "") return c;
3228
+ if (isSiluzanAgentEnv()) return WRITE_AUDIT_AGENT_AUTO_COMMIT;
3229
+ return "";
3230
+ }
3221
3231
  function getWriteAuditRunId() {
3222
3232
  const r = process.env.SILUZAN_AUDIT_RUN_ID?.trim();
3223
3233
  return r !== void 0 && r !== "" ? r : void 0;
@@ -3805,7 +3815,7 @@ async function issueApiKeyWithPhoneCode(opts) {
3805
3815
  });
3806
3816
  return apiKey;
3807
3817
  }
3808
- var import_semver, SILUZAN_DIR, CONFIG_FILE, inProcessLockChain, ALLOWED_HOSTNAME_SUFFIXES, EXACT_ID_FIELD_NAMES, DEFAULT_TIMEOUT_MS, MAX_RESPONSE_BYTES, httpsAgent, httpAgent, PERF_PREFIX, DEFAULT_DETAIL_MAX, VERBOSE_DETAIL_MAX, ASCII_TABLE_CHARS, CLI_SNAPSHOT_MANIFEST_FILE, SCHEMA_VERSION, FALLBACK_FIELD_GUIDE_REFS, _cliPackage, _resolveCliVersion, _fieldGuideRefs, OUTLINE_AGENT_HINT, TS_LIKE_ARRAY_SAMPLE_MAX, MAX_INVOCATION_CHARS, currentInvocation, MAX_COMMIT_CHARS, cliCommitOverride, WRITE_AUDIT_SCHEMA_VERSION, MUTATING, BEIJING_TZ, AUDIT_LOG_FILENAME_RE, DEFAULT_MAX_FILE_MB, MIN_SEGMENT_BYTES, MAX_SEGMENT_BYTES, DEFAULT_RETENTION_DAYS, MIN_RETENTION_DAYS, MAX_RETENTION_DAYS, PRUNE_THROTTLE_MS, lastPruneAtMs, MAX_BODY_CHARS, MAX_ERROR_CHARS, DEFAULT_FIND_AUDIT_MAX_DAYS, MAX_SNAPSHOT_FILE_BYTES, API_KEY_SERVICE_VALUES;
3818
+ var import_semver, SILUZAN_DIR, CONFIG_FILE, inProcessLockChain, ALLOWED_HOSTNAME_SUFFIXES, EXACT_ID_FIELD_NAMES, DEFAULT_TIMEOUT_MS, MAX_RESPONSE_BYTES, httpsAgent, httpAgent, PERF_PREFIX, DEFAULT_DETAIL_MAX, VERBOSE_DETAIL_MAX, ASCII_TABLE_CHARS, CLI_SNAPSHOT_MANIFEST_FILE, SCHEMA_VERSION, FALLBACK_FIELD_GUIDE_REFS, _cliPackage, _resolveCliVersion, _fieldGuideRefs, OUTLINE_AGENT_HINT, TS_LIKE_ARRAY_SAMPLE_MAX, MAX_INVOCATION_CHARS, currentInvocation, MAX_COMMIT_CHARS, WRITE_AUDIT_AGENT_AUTO_COMMIT, cliCommitOverride, WRITE_AUDIT_SCHEMA_VERSION, MUTATING, BEIJING_TZ, AUDIT_LOG_FILENAME_RE, DEFAULT_MAX_FILE_MB, MIN_SEGMENT_BYTES, MAX_SEGMENT_BYTES, DEFAULT_RETENTION_DAYS, MIN_RETENTION_DAYS, MAX_RETENTION_DAYS, PRUNE_THROTTLE_MS, lastPruneAtMs, MAX_BODY_CHARS, MAX_ERROR_CHARS, DEFAULT_FIND_AUDIT_MAX_DAYS, MAX_SNAPSHOT_FILE_BYTES, API_KEY_SERVICE_VALUES;
3809
3819
  var init_dist = __esm({
3810
3820
  "../common/dist/index.js"() {
3811
3821
  "use strict";
@@ -3897,6 +3907,7 @@ var init_dist = __esm({
3897
3907
  TS_LIKE_ARRAY_SAMPLE_MAX = 8;
3898
3908
  MAX_INVOCATION_CHARS = 4e3;
3899
3909
  MAX_COMMIT_CHARS = 2e3;
3910
+ WRITE_AUDIT_AGENT_AUTO_COMMIT = "agent:auto";
3900
3911
  WRITE_AUDIT_SCHEMA_VERSION = 2;
3901
3912
  MUTATING = /* @__PURE__ */ new Set(["POST", "PUT", "PATCH", "DELETE"]);
3902
3913
  BEIJING_TZ = "Asia/Shanghai";
@@ -4159,15 +4170,14 @@ function isTsoArgvExemptFromWriteCommit(argv) {
4159
4170
  }
4160
4171
  function ensureWriteCommitForMutatingHttp() {
4161
4172
  if (isTsoArgvExemptFromWriteCommit(process.argv.slice(2))) return;
4162
- const c = getResolvedWriteAuditCommit();
4163
- if (c !== "") return;
4173
+ if (isWriteAuditCommitRequiredSatisfied()) return;
4164
4174
  console.error('\n\u274C \u5199\u64CD\u4F5C\u5FC5\u987B\u63D0\u4F9B\u8BF4\u660E\uFF08commit\uFF09\uFF1A\u8BF7\u4F7F\u7528 --commit "\u2026"');
4165
4175
  process.exit(1);
4166
4176
  }
4167
4177
  async function withWriteAudit(params, execute) {
4168
4178
  ensureWriteCommitForMutatingHttp();
4169
4179
  const auditId = randomUUID();
4170
- const commit = getResolvedWriteAuditCommit();
4180
+ const commit = resolveWriteAuditCommitForRecord();
4171
4181
  const runId = getWriteAuditRunId();
4172
4182
  const snap = await tryWritePreSnapshot({
4173
4183
  namespace: TSO_WRITE_AUDIT_NS,
@@ -5407,6 +5417,40 @@ var init_accounts_digest2 = __esm({
5407
5417
  }
5408
5418
  });
5409
5419
 
5420
+ // src/commands/google-analysis/daily-metrics-range.ts
5421
+ function pad2(n) {
5422
+ return String(n).padStart(2, "0");
5423
+ }
5424
+ function formatChinaOffsetDateTime(d) {
5425
+ const sh = new Date(d.getTime() + CHINA_OFFSET_MS);
5426
+ return `${sh.getUTCFullYear()}-${pad2(sh.getUTCMonth() + 1)}-${pad2(sh.getUTCDate())}T${pad2(sh.getUTCHours())}:${pad2(sh.getUTCMinutes())}:${pad2(sh.getUTCSeconds())}+08:00`;
5427
+ }
5428
+ function defaultChinaDateRange(now = /* @__PURE__ */ new Date()) {
5429
+ const chinaNow = new Date(now.getTime() + CHINA_OFFSET_MS);
5430
+ chinaNow.setUTCDate(chinaNow.getUTCDate() - 1);
5431
+ const endY = chinaNow.getUTCFullYear();
5432
+ const endM = chinaNow.getUTCMonth();
5433
+ const endD = chinaNow.getUTCDate();
5434
+ const startChina = new Date(Date.UTC(endY, endM, endD - 6));
5435
+ const endChina = new Date(Date.UTC(endY, endM, endD));
5436
+ const fmt2 = (utcCal) => `${utcCal.getUTCFullYear()}-${pad2(utcCal.getUTCMonth() + 1)}-${pad2(utcCal.getUTCDate())}`;
5437
+ return { startDate: fmt2(startChina), endDate: fmt2(endChina) };
5438
+ }
5439
+ function resolveDailyMetricsQueryTimes(startDate, endDate, now = /* @__PURE__ */ new Date()) {
5440
+ const startInstant = `${startDate}T00:00:00+08:00`;
5441
+ const endOfDay = /* @__PURE__ */ new Date(`${endDate}T23:59:59+08:00`);
5442
+ const endInstant = endOfDay.getTime() > now.getTime() ? formatChinaOffsetDateTime(now) : formatChinaOffsetDateTime(endOfDay);
5443
+ return { startInstant, endInstant };
5444
+ }
5445
+ var CHINA_OFFSET_MS, resolveChinaQueryTimes;
5446
+ var init_daily_metrics_range = __esm({
5447
+ "src/commands/google-analysis/daily-metrics-range.ts"() {
5448
+ "use strict";
5449
+ CHINA_OFFSET_MS = 8 * 36e5;
5450
+ resolveChinaQueryTimes = resolveDailyMetricsQueryTimes;
5451
+ }
5452
+ });
5453
+
5410
5454
  // src/commands/google-analysis/wrap-snapshot-envelope.ts
5411
5455
  function coerceToRowArray(value) {
5412
5456
  if (Array.isArray(value)) return value;
@@ -101788,49 +101832,20 @@ var init_translate_fields = __esm({
101788
101832
  }
101789
101833
  });
101790
101834
 
101791
- // src/commands/google-analysis/daily-metrics-range.ts
101792
- function pad2(n) {
101793
- return String(n).padStart(2, "0");
101794
- }
101795
- function formatChinaOffsetDateTime(d) {
101796
- const sh = new Date(d.getTime() + CHINA_OFFSET_MS);
101797
- return `${sh.getUTCFullYear()}-${pad2(sh.getUTCMonth() + 1)}-${pad2(sh.getUTCDate())}T${pad2(sh.getUTCHours())}:${pad2(sh.getUTCMinutes())}:${pad2(sh.getUTCSeconds())}+08:00`;
101798
- }
101799
- function resolveDailyMetricsQueryTimes(startDate, endDate, now = /* @__PURE__ */ new Date()) {
101800
- const startInstant = `${startDate}T00:00:00+08:00`;
101801
- const endOfDay = /* @__PURE__ */ new Date(`${endDate}T23:59:59+08:00`);
101802
- const endInstant = endOfDay.getTime() > now.getTime() ? formatChinaOffsetDateTime(now) : formatChinaOffsetDateTime(endOfDay);
101803
- return { startInstant, endInstant };
101804
- }
101805
- var CHINA_OFFSET_MS;
101806
- var init_daily_metrics_range = __esm({
101807
- "src/commands/google-analysis/daily-metrics-range.ts"() {
101808
- "use strict";
101809
- CHINA_OFFSET_MS = 8 * 36e5;
101810
- }
101811
- });
101812
-
101813
101835
  // src/commands/google-analysis/fetch.ts
101814
- function defaultDateRange3() {
101815
- const end = /* @__PURE__ */ new Date();
101816
- end.setDate(end.getDate() - 1);
101817
- const start = new Date(end);
101818
- start.setDate(start.getDate() - 6);
101819
- const fmt2 = (d) => d.toISOString().slice(0, 10);
101820
- return { startDate: fmt2(start), endDate: fmt2(end) };
101821
- }
101822
101836
  function resolveDateRange(start, end) {
101823
101837
  if (start && end) return { startDate: start, endDate: end };
101824
- if (!start && !end) return defaultDateRange3();
101825
- console.error("\n\u274C --start \u4E0E --end \u987B\u540C\u65F6\u4F20\u5165\uFF0C\u6216\u540C\u65F6\u7701\u7565\u4EE5\u4F7F\u7528\u9ED8\u8BA4\u8FD1 7 \u5929\uFF08\u622A\u81F3\u6628\u5929\uFF09\u3002\n");
101838
+ if (!start && !end) return defaultChinaDateRange();
101839
+ console.error("\n\u274C --start \u4E0E --end \u987B\u540C\u65F6\u4F20\u5165\uFF0C\u6216\u540C\u65F6\u7701\u7565\u4EE5\u4F7F\u7528\u9ED8\u8BA4\u8FD1 7 \u5929\uFF08\u622A\u81F3\u6628\u5929\uFF0CUTC+8\uFF09\u3002\n");
101826
101840
  process.exit(1);
101827
101841
  }
101828
101842
  function buildSearchParams(def, start, end, extras) {
101829
101843
  const params = new URLSearchParams();
101830
101844
  if (def.dateMode === "range") {
101831
101845
  const { startDate, endDate } = resolveDateRange(start, end);
101832
- params.set("startDate", startDate);
101833
- params.set("endDate", endDate);
101846
+ const { startInstant, endInstant } = resolveChinaQueryTimes(startDate, endDate);
101847
+ params.set("startDate", startInstant);
101848
+ params.set("endDate", endInstant);
101834
101849
  }
101835
101850
  const merged = { ...def.defaultQuery };
101836
101851
  for (const [k, v] of Object.entries(extras)) {
@@ -101990,7 +102005,8 @@ async function fetchSectionPayload(def, opts, config, id, http2) {
101990
102005
  }
101991
102006
  if (def.name === "materials") {
101992
102007
  const { startDate, endDate } = resolveDateRange(opts.start, opts.end);
101993
- const q = `?${new URLSearchParams({ startDate, endDate }).toString()}`;
102008
+ const { startInstant, endInstant } = resolveChinaQueryTimes(startDate, endDate);
102009
+ const q = `?${new URLSearchParams({ startDate: startInstant, endDate: endInstant }).toString()}`;
101994
102010
  const videoPath = `/reporting/media-account/${id}/Videos${q}`;
101995
102011
  const imagePath = `/reporting/media-account/${id}/CampaignAssetView${q}`;
101996
102012
  const verbose = !!opts.verbose;
@@ -103994,8 +104010,11 @@ function registerRunCommand() {
103994
104010
  "\u7ED3\u679C\u843D\u76D8\u76EE\u5F55\uFF1B\u6BCF\u7EF4\u5EA6\u4E00\u4E2A <section>-<accountId>.json\uFF0C\u4E0E manifest-<accountId>.json \u540C\u7EA7"
103995
104011
  ).option("-t, --token <token>", "Auth Token").option(
103996
104012
  "--start <date>",
103997
- "\u5F00\u59CB\u65E5\u671F YYYY-MM-DD\uFF08range \u7C7B\u7EF4\u5EA6\u751F\u6548\uFF1B\u7701\u7565=\u8FD1 7 \u5929\u622A\u81F3\u6628\u5929\uFF1B\u4E0E --end \u540C\u4F20\u6216\u540C\u7701\uFF09"
103998
- ).option("--end <date>", "\u7ED3\u675F\u65E5\u671F YYYY-MM-DD").option("--start-date <date>", "\u540C --start\uFF08\u6587\u6863/Playbook \u517C\u5BB9\u522B\u540D\uFF09").option("--end-date <date>", "\u540C --end\uFF08\u6587\u6863/Playbook \u517C\u5BB9\u522B\u540D\uFF09").option(
104013
+ "\u5F00\u59CB\u65E5\u671F YYYY-MM-DD\uFF08\u6309 UTC+8 \u65E5\u5386\u65E5\uFF1Brange \u7C7B\u7EF4\u5EA6\u4F1A\u8F6C\u6210 \u2026T00:00:00+08:00 \u518D\u8BF7\u6C42\uFF1B\u7701\u7565=\u8FD1 7 \u5929\u622A\u81F3\u6628\u5929\uFF1B\u4E0E --end \u540C\u4F20\u6216\u540C\u7701\uFF09"
104014
+ ).option(
104015
+ "--end <date>",
104016
+ "\u7ED3\u675F\u65E5\u671F YYYY-MM-DD\uFF08\u6309 UTC+8\uFF1B\u8F6C\u6210 \u2026T23:59:59+08:00\uFF0C\u542B\u4ECA\u5929\u65F6\u622A\u5230\u5F53\u524D\u65F6\u523B\uFF09"
104017
+ ).option("--start-date <date>", "\u540C --start\uFF08\u6587\u6863/Playbook \u517C\u5BB9\u522B\u540D\uFF09").option("--end-date <date>", "\u540C --end\uFF08\u6587\u6863/Playbook \u517C\u5BB9\u522B\u540D\uFF09").option(
103999
104018
  "--sections <list>",
104000
104019
  "\u4EC5\u6267\u884C\u6307\u5B9A\u7EF4\u5EA6\uFF08\u9017\u53F7\u5206\u9694\uFF09\uFF0C\u5982 overview,keywords,ads\uFF1B\u7701\u7565=\u5168\u90E8 25 \u4E2A"
104001
104020
  ).option(
@@ -107039,18 +107058,14 @@ init_auth();
107039
107058
  init_cli_json_snapshot();
107040
107059
  init_cli_table();
107041
107060
  init_balance();
107061
+ init_daily_metrics_range();
107042
107062
  init_media_account_lookup();
107043
107063
  init_media_customer_id();
107044
107064
  var VALID_MEDIA_TYPES3 = ["Google", "TikTok", "Yandex", "MetaAd", "BingV2", "Kwai"];
107045
107065
  var MAX_BY_DAY_SPAN = 366;
107046
107066
  var DATE_RE = /^\d{4}-\d{2}-\d{2}$/;
107047
- function defaultDateRange2() {
107048
- const end = /* @__PURE__ */ new Date();
107049
- end.setDate(end.getDate() - 1);
107050
- const start = new Date(end);
107051
- start.setDate(start.getDate() - 6);
107052
- const fmt2 = (d) => d.toISOString().slice(0, 10);
107053
- return { startDate: fmt2(start), endDate: fmt2(end) };
107067
+ function defaultDateRange2(now = /* @__PURE__ */ new Date()) {
107068
+ return defaultChinaDateRange(now);
107054
107069
  }
107055
107070
  function eachDateInclusive(startDate, endDate) {
107056
107071
  if (!DATE_RE.test(startDate) || !DATE_RE.test(endDate)) {
@@ -107082,7 +107097,12 @@ async function fetchStatsWindow(media, ids, config, startDate, endDate, verbose)
107082
107097
  const isGoogle = media === "Google";
107083
107098
  const isMetaAd = media === "MetaAd";
107084
107099
  if (isGoogle) {
107085
- const params = new URLSearchParams({ startDate, endDate, mediaCustomerIds: ids.join("|") });
107100
+ const { startInstant, endInstant } = resolveDailyMetricsQueryTimes(startDate, endDate);
107101
+ const params = new URLSearchParams({
107102
+ startDate: startInstant,
107103
+ endDate: endInstant,
107104
+ mediaCustomerIds: ids.join("|")
107105
+ });
107086
107106
  const url = `${config.apiBaseUrl}/report/media-account/google/account-spend-overview?${params.toString()}`;
107087
107107
  const raw = await apiFetch2(url, config, {}, verbose);
107088
107108
  return parseGoogleAccountSpendOverviewRows(raw).map((row) => ({
@@ -107287,7 +107307,7 @@ ${opts.media} \u6295\u653E\u6570\u636E\uFF08${rangeLabel}\uFF09\uFF08\u7B2C 1 \u
107287
107307
  }
107288
107308
  function register11(program2) {
107289
107309
  program2.command("stats").description(
107290
- "\u67E5\u8BE2\u5E7F\u544A\u6D88\u8017\u3001\u70B9\u51FB\u3001\u8F6C\u5316\u7B49\u6295\u653E\u6570\u636E\uFF08\u9ED8\u8BA4\u8FD1 7 \u5929\u533A\u95F4\u5408\u8BA1\uFF0C\u4E0D\u542B\u4ECA\u5929\uFF1B\u8981\u6309\u65E5\u660E\u7EC6\u52A0 --by-day\uFF09"
107310
+ "\u67E5\u8BE2\u5E7F\u544A\u6D88\u8017\u3001\u70B9\u51FB\u3001\u8F6C\u5316\u7B49\u6295\u653E\u6570\u636E\uFF08\u9ED8\u8BA4\u8FD1 7 \u5929\u533A\u95F4\u5408\u8BA1\uFF0C\u4E0D\u542B\u4ECA\u5929\uFF0C\u65E5\u5386\u6309 UTC+8\uFF1B\u8981\u6309\u65E5\u660E\u7EC6\u52A0 --by-day\uFF09"
107291
107311
  ).requiredOption(
107292
107312
  "-m, --media <type>",
107293
107313
  "\u5A92\u4F53\u7C7B\u578B\uFF1AGoogle | TikTok | Yandex | MetaAd | BingV2 | Kwai"
@@ -1,5 +1,5 @@
1
1
  {
2
2
  "slug": "siluzan-tso",
3
- "version": "1.1.39-beta.1",
4
- "publishedAt": 1784775605661
3
+ "version": "1.1.39-beta.3",
4
+ "publishedAt": 1785132603059
5
5
  }
@@ -152,9 +152,8 @@ siluzan-tso accounts-digest -m Google --start 2026-07-20 --end 2026-07-20 \
152
152
  ## stats — 查询投放消耗数据
153
153
 
154
154
  > **数据时效性**:
155
- > - **Google**:走 `account-spend-overview`(2026-05 起),后端按日期窗口分流——
156
- > - 窗口完全在历史 → `database` 模式:含余额、状态、币种、账户名、当期展点消等完整字段;
157
- > - 窗口包含今天 → `googleCombined` 模式:只返回实时聚合的展点消(**没有**余额/状态/币种/账户名)。
155
+ > - **Google**:走 `account-spend-overview`;`--start` / `--end` 日历日按 **UTC+8** 转为 `YYYY-MM-DDTHH:mm:ss+08:00` 再请求(起 00:00:00、止 23:59:59,含今天时 end 截到当前时刻)。勿传裸 `YYYY-MM-DD`(易被当成 UTC 切窗)。
156
+ > - 窗口完全在历史 → `database` 模式;窗口含今天 → `googleCombined` 模式(仅实时消耗,无余额/状态/币种/账户名)。
158
157
  > - **TikTok / Yandex / BingV2 / Kwai**:走旧版 `accountsoverview`,每日凌晨同步昨天数据,**不能查今天**。判断这几家的「今天/当天/今日消耗」仍需走 `google-analysis(-batch) --sections overview`(仅 Google)。
159
158
  > - 完整时效性表见 `references/analytics/account-analytics.md` 顶部。
160
159
 
@@ -23,10 +23,10 @@
23
23
 
24
24
  | 命令 / 接口 | 时效性 | 能否查"今天" | 典型用途 |
25
25
  | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------- | ------------------------------------------------------ |
26
- | `google-analysis --sections overview`(Google 网关 `OverviewSectionData`) | **实时** | ✅ 可查当天 | 当天/今日消耗、当天高消耗账号排行 |
26
+ | `google-analysis --sections overview`(Google 网关 `OverviewSectionData`) | **实时**;请求起止按 **UTC+8** 墙钟 | ✅ 可查当天 | 当天/今日消耗、当天高消耗账号排行 |
27
27
  | `google-analysis --sections campaign-types`(`types-summary`) | **实时** | ✅ 可查当天 | 当天系列类型分布 |
28
- | `google-analysis` 其他维度(`campaigns` / `keywords` / `devices` / ...) | 实时(受 Google Ads API 同步延迟影响) | 可查当天,但当天可能尚未结算 | 周期分析、报告 |
29
- | `stats -m Google` / `balance-scan -m Google` / `accounts-digest -m Google` / `list-accounts -m Google` 合并消耗(TSO `account-spend-overview`,2026-05 起) | **后端自动分流**:窗口完全在历史 → `database` 模式(含余额/状态/币种/账户名 + 当期消耗);窗口含今天 → `googleCombined` 模式(仅实时消耗,无余额/状态/币种/账户名) | ✅ 可查当天(含今天时切实时聚合) | 历史回溯、巡检、余额续航估算;含今天时也能给出实时消耗 |
28
+ | `google-analysis` 其他 range 维度(`campaigns` / `keywords` / `devices` / `geographic` / `daily-metrics` / …) | 实时(受 Google Ads API 同步延迟影响);**一律东八区起止时刻**(与 `stats` 同) | 可查当天,但当天可能尚未结算 | 周期分析、报告 |
29
+ | `stats -m Google` / `balance-scan -m Google` / `accounts-digest -m Google` / `list-accounts -m Google` 合并消耗(TSO `account-spend-overview`,2026-05 起) | **后端自动分流**:窗口完全在历史 → `database`;含今天 → `googleCombined`。**`stats` 请求起止按 UTC+8 墙钟**(`…T00:00:00+08:00` ~ `…T23:59:59+08:00`) | ✅ 可查当天(含今天时切实时聚合) | 历史回溯、巡检、周报 KPI、余额续航估算 |
30
30
  | `stats` / `balance-scan` / `accounts-digest` / `list-accounts` 的 **TikTok / Yandex / BingV2 / Kwai / MetaAd** 合并消耗(TSO `accountsoverview`;MetaAd OAuth 户走 `FacebookAds` 段) | **每日同步昨天** | ❌ 查今天会全为 0 | 历史回溯、巡检、余额续航估算(口径为"截至昨天") |
31
31
  | `balance`(`GetMediaAccountInfo`) | 实时 | — | 仅当前余额,不反映消耗 |
32
32
 
@@ -102,7 +102,7 @@ siluzan-tso google-analysis -a <id> --exclude materials,gold-account --json-out
102
102
  | `--json-out <dir>` | 必填;每维一个 `<section>-<accountId>.json` + `manifest-<accountId>.json` |
103
103
  | `--sections <list>` | 仅执行指定维度(逗号分隔);省略=全部 25 个 |
104
104
  | `--exclude <list>` | 排除指定维度;与 `--sections` 可叠加 |
105
- | `--start` / `--end` | 统计区间(YYYY-MM-DD);省略=近 7 天截至昨天;`final-urls`/`campaign-types` 自动忽略 |
105
+ | `--start` / `--end` | 统计区间(YYYY-MM-DD,按 **UTC+8** 日历日);CLI 转成 `…T00:00:00+08:00` ~ `…T23:59:59+08:00` 再请求;省略=近 7 天截至昨天;`final-urls`/`campaign-types` 自动忽略 |
106
106
  | `--concurrency <n>` | 并发数,默认 5,上限 16 |
107
107
  | `--limit <n>` | 透传给 `keywords`/`search-terms`(默认 **0**=不封顶;`orderByCost=true`) |
108
108
  | `--level <lvl>` | 透传给 `extensions`(Account/Campaign/Ad Group) |
@@ -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.39-beta.1'
12
+ $PKG_VERSION = '1.1.39-beta.3'
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.39-beta.1"
12
+ readonly PKG_VERSION="1.1.39-beta.3"
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.39-beta.1",
3
+ "version": "1.1.39-beta.3",
4
4
  "description": "Siluzan 广告账户管理 CLI — 查询账户、余额、消耗数据,管理绑定关系与充值。",
5
5
  "keywords": [
6
6
  "ad-account",