siluzan-tso-cli 1.1.14-beta.2 → 1.1.14-beta.4

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 (104) hide show
  1. package/README.md +1 -3
  2. package/assets/siluzan-ads/references/hosted-automation-user-catalog.md +38 -0
  3. package/dist/index.js +131 -1
  4. package/dist/skill/SKILL.md +40 -28
  5. package/dist/skill/_meta.json +2 -2
  6. package/dist/skill/references/account-analytics.md +48 -2
  7. package/dist/skill/references/accounts.md +3 -3
  8. package/dist/skill/references/google-ads.md +66 -66
  9. package/dist/skill/references/hosted-automation-monitoring-json.md +94 -0
  10. package/dist/skill/references/hosted-automation-optimize-ab-winner.md +69 -0
  11. package/dist/skill/references/hosted-automation-optimize-index.md +32 -0
  12. package/dist/skill/references/hosted-automation-optimize-scale.md +90 -0
  13. package/dist/skill/references/hosted-automation-optimize-weak-downbid.md +94 -0
  14. package/dist/skill/references/hosted-automation-scenarios.md +23 -0
  15. package/dist/skill/references/hosted-automation-self-control.md +212 -0
  16. package/dist/skill/references/hosted-automation-user-catalog.md +38 -0
  17. package/dist/skill/references/open-account-google-ui.md +0 -6
  18. package/dist/skill/references/workflows.md +14 -1
  19. package/dist/skill/report-templates/google-account-diagnosis-report.md +1 -1
  20. package/dist/skill/report-templates/google-period-report.md +1 -0
  21. package/eval/cases/accounts-entityid-vs-mediaccustomerid.scenario.json +23 -0
  22. package/eval/cases/accounts-mcc-bind-inquiry.scenario.json +12 -0
  23. package/eval/cases/accounts-single-balance-not-bulk.scenario.json +23 -0
  24. package/eval/cases/budget-display-not-raw-micros.scenario.json +17 -0
  25. package/eval/cases/clue-meta-leads-json.scenario.json +23 -0
  26. package/eval/cases/clue-tiktok-leads-json.scenario.json +20 -0
  27. package/eval/cases/destructive-account-delink-needs-confirm.scenario.json +15 -0
  28. package/eval/cases/destructive-forewarning-delete-needs-confirm.scenario.json +15 -0
  29. package/eval/cases/destructive-invoice-apply-needs-confirm.scenario.json +15 -0
  30. package/eval/cases/destructive-unshare-needs-confirm.scenario.json +9 -0
  31. package/eval/cases/finance-invoice-info-list.scenario.json +17 -0
  32. package/eval/cases/forewarning-list-google.scenario.json +20 -0
  33. package/eval/cases/google-ads-no-structural-without-confirm.scenario.json +12 -0
  34. package/eval/cases/google-analysis-keywords-route.scenario.json +23 -0
  35. package/eval/cases/hosted-sop-cpa-spike-downbid.scenario.json +14 -0
  36. package/eval/cases/hosted-sop-daily-budget-circuit-breaker.scenario.json +13 -0
  37. package/eval/cases/hosted-sop-empty-spend-pause-p1.scenario.json +14 -0
  38. package/eval/cases/human-p1-multiturn.scenario.json +17 -0
  39. package/eval/cases/meta-single-balance-not-bulk.scenario.json +26 -0
  40. package/eval/cases/open-account-bing-noninteractive.scenario.json +13 -0
  41. package/eval/cases/open-account-google-noninteractive.scenario.json +12 -0
  42. package/eval/cases/open-account-tiktok-license-file.scenario.json +12 -0
  43. package/eval/cases/optimize-list-by-account.scenario.json +17 -0
  44. package/eval/cases/p1-single-account-profile.scenario.json +20 -0
  45. package/eval/cases/p2-balance-scan-bulk.scenario.json +18 -0
  46. package/eval/cases/p3-accounts-digest.scenario.json +20 -0
  47. package/eval/cases/p4-period-report-window.scenario.json +17 -0
  48. package/eval/cases/report-list-google.scenario.json +20 -0
  49. package/eval/cases/report-push-list-google.scenario.json +20 -0
  50. package/eval/cases/reporting-vs-account-analytics-routing.scenario.json +13 -0
  51. package/eval/cases/setup-login-or-env.scenario.json +12 -0
  52. package/eval/cases/setup-siluzan-data-permission-env.scenario.json +19 -0
  53. package/eval/cases/skill-async-poll-guidance.scenario.json +9 -0
  54. package/eval/cases/skill-optimize-vs-google-ads-distinction.scenario.json +13 -0
  55. package/eval/cases/tiktok-bc-bind-inquiry.scenario.json +12 -0
  56. package/eval/cases/time-range-must-ask.scenario.json +16 -0
  57. package/eval/cases/time-range-user-delegates-default.scenario.json +17 -0
  58. package/eval/cases/tips-json-filtering.scenario.json +12 -0
  59. package/eval/cases/tips-large-json-pagination.scenario.json +19 -0
  60. package/eval/cases/uj-ad-bluetooth-keywords-exclude-cheap-free.scenario.json +9 -0
  61. package/eval/cases/uj-ad-keywords-camping-tent-outdoor-plan.scenario.json +9 -0
  62. package/eval/cases/uj-ad-outdoor-campgear-search-plan.scenario.json +12 -0
  63. package/eval/cases/uj-analytics-30d-pdf-campaign-device-geo.scenario.json +29 -0
  64. package/eval/cases/uj-analytics-compare-google-tiktok-last-month-roi.scenario.json +17 -0
  65. package/eval/cases/uj-analytics-google-weekly-trends-campaigns-keywords.scenario.json +20 -0
  66. package/eval/cases/uj-analytics-report-push-weekly-email.scenario.json +12 -0
  67. package/eval/cases/uj-finance-invoice-records-this-month.scenario.json +20 -0
  68. package/eval/cases/uj-life-newbie-siluzan-google-end-to-end.scenario.json +13 -0
  69. package/eval/cases/uj-ops-google-accounts-list-normal.scenario.json +23 -0
  70. package/eval/cases/uj-ops-google-yesterday-spend-conversions.scenario.json +23 -0
  71. package/eval/cases/uj-ops-open-google-b2c-usd-shenzhen.scenario.json +13 -0
  72. package/eval/cases/uj-ops-pause-worst-adgroup-confirm.scenario.json +12 -0
  73. package/eval/cases/uj-ops-tiktok-leads-last-week.scenario.json +23 -0
  74. package/eval/cases/uj-patrol-all-media-balance-stats-forewarning.scenario.json +9 -0
  75. package/eval/cases/uj-patrol-cpc-spike-adgroups-over-15.scenario.json +18 -0
  76. package/eval/cases/uj-patrol-forewarning-create-daily-cap-3000.scenario.json +12 -0
  77. package/eval/cases/uj-patrol-forewarning-trigger-records.scenario.json +23 -0
  78. package/eval/cases/uj-patrol-google-balances-low.scenario.json +20 -0
  79. package/eval/cases/uj-roi-full-google-account-diagnosis.scenario.json +9 -0
  80. package/eval/cases/uj-roi-keywords-high-cpa-low-cvr-triage.scenario.json +9 -0
  81. package/eval/cases/uj-roi-optimize-records-then-execute-cautiously.scenario.json +20 -0
  82. package/eval/cases/uj-roi-search-terms-add-negative-keywords.scenario.json +23 -0
  83. package/eval/stub-fixtures/accounts-digest.json +33 -0
  84. package/eval/stub-fixtures/ad-campaigns.json +14 -0
  85. package/eval/stub-fixtures/balance-meta.json +6 -0
  86. package/eval/stub-fixtures/balance-scan.json +21 -0
  87. package/eval/stub-fixtures/balance.json +6 -0
  88. package/eval/stub-fixtures/clue-meta.json +7 -0
  89. package/eval/stub-fixtures/clue-tiktok.json +7 -0
  90. package/eval/stub-fixtures/forewarning-create-ok.json +1 -0
  91. package/eval/stub-fixtures/forewarning-records.json +7 -0
  92. package/eval/stub-fixtures/generic-ok.json +1 -0
  93. package/eval/stub-fixtures/google-analysis-search-terms.json +10 -0
  94. package/eval/stub-fixtures/google-analysis.json +7 -0
  95. package/eval/stub-fixtures/invoice-billable.json +7 -0
  96. package/eval/stub-fixtures/invoice-info-list.json +13 -0
  97. package/eval/stub-fixtures/invoice-list.json +10 -0
  98. package/eval/stub-fixtures/list-accounts.json +13 -0
  99. package/eval/stub-fixtures/optimize-list.json +7 -0
  100. package/eval/stub-fixtures/report-push-list.json +7 -0
  101. package/eval/stub-fixtures/stats.json +9 -0
  102. package/package.json +7 -2
  103. package/scripts/postinstall.mjs +27 -2
  104. package/dist/skill/references/open-account-by-media.md +0 -61
package/README.md CHANGED
@@ -19,8 +19,6 @@
19
19
  | 项目 | 说明 |
20
20
  | --------------- | --------------------------------------------------------------- |
21
21
  | API Key / Token | 存储在 `~/.siluzan/config.json`,用于所有 API 调用鉴权 |
22
- | TSO API | `tso-api.siluzan.com`(生产)/ `tso-api-ci.siluzan.com`(测试) |
23
- | Google API 网关 | `googleapi.mysiluzan.com` / `googleapi-ci.mysiluzan.com` |
24
22
  | 前端页面 | `www.siluzan.com`(充值、激活等浏览器操作) |
25
23
  | 错误追踪 | `o605862.ingest.us.sentry.io`(匿名崩溃日志) |
26
24
  | 版本检查 | `registry.npmjs.org` |
@@ -53,7 +51,7 @@ siluzan-tso init -d /path/to/skills # 写入自定义目录
53
51
  siluzan-tso init --force # 强制覆盖已存在文件
54
52
  ```
55
53
 
56
- > **注意**:当前为测试版(1.1.14-beta.2),供内部测试使用。正式发布后安装命令将改为 `npm install -g siluzan-tso-cli`。
54
+ > **注意**:当前为测试版(1.1.14-beta.4),供内部测试使用。正式发布后安装命令将改为 `npm install -g siluzan-tso-cli`。
57
55
 
58
56
  | 助手 | 建议 `--ai` |
59
57
  | ----------------------- | ------------------------------------ |
@@ -0,0 +1,38 @@
1
+ # 自动化场景用户向目录
2
+
3
+ 这是skill的一些结合Agent客户端可完成的自动化功能,你可以给用户介绍下面的这些内容
4
+
5
+ ## 预算 & ROI 控制引擎
6
+
7
+ 三条均为 **Google 宿主编排 + siluzan-tso** 路径;IF/定时/通知在宿主,命令与 JSON 以详规为准。
8
+
9
+ | 提醒名称 | 系统在后台默默帮你做什么?(自动动作) | 文档(references) |
10
+ | ------------------- | ------------------------------------- | ------------------ |
11
+ | 1. 单日预算熔断 | 当日系列 **花费**相对**日预算**达到设定比例(如 ≥110%,可配 110%–120% 抗延迟)时,**暂停 Campaign**;恢复需人工加预算后再启用。 | [场景 1 · 单日预算熔断](hosted-automation-self-control.md) · [`google-ads.md`](google-ads.md)(`ad campaigns`、`ad campaign-status`、预算口径) · [`tips.md`](tips.md)(`--json`) |
12
+ | 2. CPA 飙升自动降价 | 滑动时间窗内 **转化数**达置信阈值且 **实际 CPA** 高于 **目标 CPA×飙升比例** 时,在 **Campaign / Ad Group** 上**下调** tCPA 或 eCPC 等**出价上限**(具体策略依账户)。 | [场景 2 · CPA 飙升自动降价](hosted-automation-self-control.md) · [`hosted-automation-optimize-weak-downbid.md`](hosted-automation-optimize-weak-downbid.md)(组/创意侧降价关停,可与宿主组合) · [`google-ads.md`](google-ads.md)(`campaign-edit`、`adgroup-edit`) · [`account-analytics.md`](account-analytics.md)(窗口粒度不足时的报表拉数) |
13
+ | 3. 连续空耗自动暂停 | **当日**累计 **花费 ≥ 目标 CPA×N** 且 **转化为 0** 时,**暂停**广告组或创意;宿主发 **P1** 且文案含 **「空耗熔断」**。 | [场景 3 · 连续空耗自动暂停](hosted-automation-self-control.md) · [`google-ads.md`](google-ads.md)(`ad groups`、`ad list`、`adgroup-status`、`ad-status`) · [`hosted-automation-monitoring-json.md`](hosted-automation-monitoring-json.md)(JSON 键名勿套用 Google Ads API 官方名) |
14
+
15
+ **总索引**:[`hosted-automation-scenarios.md`](hosted-automation-scenarios.md) · **自控全文**:[`hosted-automation-self-control.md`](hosted-automation-self-control.md) · **金额硬规范**(展示用 `*Display` 等):[`SKILL.md`](../SKILL.md)「金额与货币单位硬约束」。
16
+
17
+ ## 异常监控与报警系统
18
+
19
+ 编排(定时、HTTP 探活、通知)在宿主;**读哪些 JSON 字段、用什么命令** 以 **[`hosted-automation-monitoring-json.md`](hosted-automation-monitoring-json.md)** 为准(键名以当次 `--json` 为准,勿套用 Google Ads API 官方字段名解析本 CLI 输出)。
20
+
21
+ | 功能名称 | 监控层级 / 说明 | CLI 检查入口(`--json`) |
22
+ | ----------------- | --------------- | ------------------------ |
23
+ | 1. 账户被封禁 | 账户级;与 Google `CustomerStatus` 及 `list-accounts` 的字段映射**暂不写进本 skill**,由宿主约定。 | `list-accounts`、`balance` 等见 [`accounts.md`](accounts.md) |
24
+ | 2. 落地页死链强停 | URL 不可用或跳错页时暂停关联创意,避免无效消耗。 | **`google-analysis final-urls`**;或 **`ad list`** / **`google-analysis ads`** 取落地页字段后由宿主 HTTP 校验 |
25
+ | 3. 广告素材拒审 | 创意政策状态异常时告警或配合工单。 | **`ad list`** / **`google-analysis ads`**:`policyApprovalStatusV2`、`approvalStatusDetails` 等(见 **[`google-ads.md`](google-ads.md)**) |
26
+ | 4. 花费异动监控 | 系列或账户维度花费相对历史异常波动。 | **`google-analysis campaign-hour`**:按 `campaignId` + `date` + `hour` 看 **`spend`** |
27
+ | 5. 余额枯竭预警 | 余额过低或按日均推算续航不足。 | **`balance-scan`**(`balance`、`remainingDays`、`hitReason`、`meta`)或 **`balance`** / **`google-analysis overview`**(`remainingAccountBudget`、`averageDailyCost` 等) |
28
+
29
+ ## 自动优化
30
+
31
+ 编排与阈值在宿主;**命令、JSON 键名、聚合与写后复核** 见 **[`hosted-automation-optimize-index.md`](hosted-automation-optimize-index.md)**(及链出的三份 SOP)。
32
+
33
+ | 功能名称 | 说明 | SOP |
34
+ | ----------------------- | ---- | ----- |
35
+ | 1. 表现差广告降价/关停 | 组/创意:CTR、CPA、转化等触达后 **下调 `targetCpa` 或 `Paused`**。 | [`hosted-automation-optimize-weak-downbid.md`](hosted-automation-optimize-weak-downbid.md) |
36
+ | 2. 高转化广告提价扩量 | 系列/组:ROAS 代理、预算丢失份额等触达后 **提预算 / 上调目标 CPA**。 | [`hosted-automation-optimize-scale.md`](hosted-automation-optimize-scale.md) |
37
+ | 3. A/B 测试自动决出胜者 | 同组多创意:聚合后比 **CVPI / all conv** 等,**停输家**。 | [`hosted-automation-optimize-ab-winner.md`](hosted-automation-optimize-ab-winner.md) |
38
+ | 4. 异动根因自动排查建议 | 诊断报告与归因:用 `account-analytics`、报告模板等,见 [`account-analytics.md`](account-analytics.md) 与 `report-templates/`。 | (未单独拆 SOP,沿用分析文档) |
package/dist/index.js CHANGED
@@ -5184,6 +5184,12 @@ var SECTIONS = [
5184
5184
  dateMode: "range",
5185
5185
  path: (id) => `/reporting/media-account/${id}/CampaignSectionData`
5186
5186
  },
5187
+ {
5188
+ name: "campaign-hour",
5189
+ description: "\u7CFB\u5217\u6309\u5C0F\u65F6 campaign-hour\uFF08Query\uFF1AstartDate\u3001endDate\uFF09",
5190
+ dateMode: "range",
5191
+ path: (id) => `/reporting/media-account/${id}/campaign-hour`
5192
+ },
5187
5193
  {
5188
5194
  name: "ads",
5189
5195
  description: "\u5E7F\u544A\u7EA7\u5217\u8868 admanagement/v2/list",
@@ -5319,6 +5325,55 @@ async function fetchJson(config, pathWithQuery, verbose) {
5319
5325
  const url = `${config.googleApiUrl}${pathWithQuery}`;
5320
5326
  return apiFetch2(url, config, {}, verbose);
5321
5327
  }
5328
+ function assertNever(x, ctx) {
5329
+ throw new Error(`${ctx}\uFF1A\u672A\u5904\u7406\u7684\u5206\u652F ${String(x)}`);
5330
+ }
5331
+ async function fetchGoogleAnalysisSectionJson(config, fullPath, verbose, name) {
5332
+ switch (name) {
5333
+ case "overview":
5334
+ return fetchJson(config, fullPath, verbose);
5335
+ case "keywords":
5336
+ return fetchJson(config, fullPath, verbose);
5337
+ case "search-terms":
5338
+ return fetchJson(config, fullPath, verbose);
5339
+ case "campaigns":
5340
+ return fetchJson(config, fullPath, verbose);
5341
+ case "campaign-hour":
5342
+ return fetchJson(config, fullPath, verbose);
5343
+ case "ads":
5344
+ return fetchJson(config, fullPath, verbose);
5345
+ case "extensions":
5346
+ return fetchJson(config, fullPath, verbose);
5347
+ case "devices":
5348
+ return fetchJson(config, fullPath, verbose);
5349
+ case "geographic":
5350
+ return fetchJson(config, fullPath, verbose);
5351
+ case "audience":
5352
+ return fetchJson(config, fullPath, verbose);
5353
+ case "asset-images":
5354
+ return fetchJson(config, fullPath, verbose);
5355
+ case "videos":
5356
+ return fetchJson(config, fullPath, verbose);
5357
+ case "resource-counts":
5358
+ return fetchJson(config, fullPath, verbose);
5359
+ case "conversion-actions":
5360
+ return fetchJson(config, fullPath, verbose);
5361
+ case "daily-metrics":
5362
+ return fetchJson(config, fullPath, verbose);
5363
+ case "gold-account":
5364
+ return fetchJson(config, fullPath, verbose);
5365
+ case "ads-index":
5366
+ return fetchJson(config, fullPath, verbose);
5367
+ case "final-urls":
5368
+ return fetchJson(config, fullPath, verbose);
5369
+ case "dimension-summary":
5370
+ return fetchJson(config, fullPath, verbose);
5371
+ case "campaign-types":
5372
+ return fetchJson(config, fullPath, verbose);
5373
+ default:
5374
+ return assertNever(name, "google-analysis");
5375
+ }
5376
+ }
5322
5377
  function summarizeHuman(section, data) {
5323
5378
  if (data === null || data === void 0) return "\u65E0\u6570\u636E";
5324
5379
  if (Array.isArray(data)) return `\u6570\u7EC4\uFF0C\u5171 ${data.length} \u6761`;
@@ -5389,7 +5444,12 @@ async function runOneSection(def, opts) {
5389
5444
  );
5390
5445
  return;
5391
5446
  }
5392
- const data = await fetchJson(config, fullPath, !!opts.verbose);
5447
+ const data = await fetchGoogleAnalysisSectionJson(
5448
+ config,
5449
+ fullPath,
5450
+ !!opts.verbose,
5451
+ def.name
5452
+ );
5393
5453
  if (opts.json) {
5394
5454
  console.log(JSON.stringify(stripLegacyGoogleFieldsIfV2Present(data), null, 2));
5395
5455
  return;
@@ -8044,6 +8104,53 @@ async function runAdGroupRename(opts) {
8044
8104
  \u2705 \u5E7F\u544A\u7EC4 ${opts.id} \u5DF2\u6539\u540D\u4E3A\u300C${opts.name}\u300D
8045
8105
  `);
8046
8106
  }
8107
+ async function runAdGroupEdit(opts) {
8108
+ const hasName = opts.name !== void 0 && opts.name.trim() !== "";
8109
+ const hasMax = opts.maxCPCAmount !== void 0;
8110
+ const hasTcpa = opts.targetCpaAmount !== void 0;
8111
+ if (!hasName && !hasMax && !hasTcpa) {
8112
+ console.error(
8113
+ "\n\u274C \u8BF7\u81F3\u5C11\u6307\u5B9A\u4E00\u9879\u4FEE\u6539\uFF1A--name / --max-cpc / --target-cpa\n"
8114
+ );
8115
+ process.exit(1);
8116
+ }
8117
+ if (hasMax && (!Number.isFinite(opts.maxCPCAmount) || opts.maxCPCAmount < 0)) {
8118
+ console.error("\n\u274C --max-cpc \u987B\u4E3A\u975E\u8D1F\u6570\u5B57\n");
8119
+ process.exit(1);
8120
+ }
8121
+ if (hasTcpa && (!Number.isFinite(opts.targetCpaAmount) || opts.targetCpaAmount < 0)) {
8122
+ console.error("\n\u274C --target-cpa \u987B\u4E3A\u975E\u8D1F\u6570\u5B57\n");
8123
+ process.exit(1);
8124
+ }
8125
+ const config = loadConfig(opts.token);
8126
+ const googleApiUrl = requireGoogleApi(config);
8127
+ const listUrl = adgroupListUrl(googleApiUrl, opts.account, opts.startDate, opts.endDate);
8128
+ let adgroup;
8129
+ try {
8130
+ adgroup = await findItemInList(listUrl, config, opts.id, opts.verbose);
8131
+ } catch (err) {
8132
+ console.error(`
8133
+ \u274C \u67E5\u8BE2\u5E7F\u544A\u7EC4\u5931\u8D25\uFF1A${err instanceof Error ? err.message : String(err)}
8134
+ `);
8135
+ process.exit(1);
8136
+ }
8137
+ const body = { ...adgroup };
8138
+ if (hasName) body["name"] = opts.name.trim();
8139
+ if (hasMax) body["maxCPCAmount"] = Math.round(opts.maxCPCAmount);
8140
+ if (hasTcpa) body["targetCpaAmount"] = Math.round(opts.targetCpaAmount);
8141
+ const putUrl = `${googleApiUrl}/adgroupnmanagement/adgroup/${opts.account}/${opts.id}`;
8142
+ try {
8143
+ await apiFetch2(putUrl, config, { method: "PUT", body: JSON.stringify(body) }, opts.verbose);
8144
+ } catch (err) {
8145
+ console.error(`
8146
+ \u274C \u7F16\u8F91\u5E7F\u544A\u7EC4\u5931\u8D25\uFF1A${err instanceof Error ? err.message : String(err)}
8147
+ `);
8148
+ process.exit(1);
8149
+ }
8150
+ console.log(`
8151
+ \u2705 \u5E7F\u544A\u7EC4 ${opts.id} \u5DF2\u66F4\u65B0
8152
+ `);
8153
+ }
8047
8154
  async function runAdEdit(opts) {
8048
8155
  const config = await ensureDataPermission(loadConfig(opts.token));
8049
8156
  const googleApiUrl = requireGoogleApi(config);
@@ -13310,6 +13417,29 @@ adCmd.command("adgroup-rename").description("\u4FEE\u6539\u5E7F\u544A\u7EC4\u540
13310
13417
  });
13311
13418
  }
13312
13419
  );
13420
+ adCmd.command("adgroup-edit").description("\u7F16\u8F91\u5E7F\u544A\u7EC4\uFF08\u540D\u79F0\u3001\u6700\u9AD8 CPC\u3001\u7EC4\u7EA7\u76EE\u6807 CPA\uFF1B\u81F3\u5C11\u4F20\u4E00\u9879\uFF1B\u4E0E\u7F51\u5173 PUT \u4E00\u81F4\uFF09").requiredOption("-a, --account <id>", "Google \u8D26\u6237 mediaCustomerId").requiredOption("--id <adgroupId>", "\u5E7F\u544A\u7EC4 ID").option("--name <name>", "\u65B0\u540D\u79F0").option(
13421
+ "--max-cpc <n>",
13422
+ "\u6700\u9AD8 CPC\uFF0C\u4E0E ad groups --json \u7684 maxCPCAmount \u540C\u53E3\u5F84\uFF08\u4E3B\u5E01\u79CD\u91D1\u989D\xD7100\uFF0C\u89C1 references/google-ads.md\uFF09",
13423
+ parseFloat
13424
+ ).option(
13425
+ "--target-cpa <n>",
13426
+ "\u7EC4\u7EA7\u76EE\u6807 CPA\uFF0C\u4E0E ad groups --json \u7684 targetCpaAmount \u540C\u53E3\u5F84\uFF08\xD7100 \u5206\u5355\u4F4D\uFF09",
13427
+ parseFloat
13428
+ ).option("--start <date>", "\u5217\u8868\u67E5\u8BE2\u8D77\u59CB\u65E5\u671F YYYY-MM-DD").option("--end <date>", "\u5217\u8868\u67E5\u8BE2\u7ED3\u675F\u65E5\u671F YYYY-MM-DD").option("-t, --token <token>", "Auth Token").option("--verbose", "\u8BE6\u7EC6\u9519\u8BEF\u4FE1\u606F", false).action(
13429
+ async (opts) => {
13430
+ await runAdGroupEdit({
13431
+ token: opts.token,
13432
+ account: opts.account,
13433
+ id: opts.id,
13434
+ name: opts.name,
13435
+ maxCPCAmount: opts.maxCpc,
13436
+ targetCpaAmount: opts.targetCpa,
13437
+ startDate: opts.start,
13438
+ endDate: opts.end,
13439
+ verbose: opts.verbose
13440
+ });
13441
+ }
13442
+ );
13313
13443
  adCmd.command("ad-edit").description(
13314
13444
  "\u7F16\u8F91\u81EA\u9002\u5E94\u641C\u7D22\u5E7F\u544A\uFF08RESPONSIVE_SEARCH_AD\uFF09\uFF1A\u6807\u9898/\u63CF\u8FF0/\u843D\u5730\u9875/\u8DEF\u5F84/\u72B6\u6001\uFF1B\u4E0E\u7F51\u9875 PUT admanagement/campaign \u884C\u4E3A\u4E00\u81F4"
13315
13445
  ).requiredOption("-a, --account <id>", "Google \u8D26\u6237 mediaCustomerId").requiredOption("--id <adId>", "\u5E7F\u544A ID").option(
@@ -50,11 +50,13 @@ allowed-tools: Bash(siluzan-tso:*) Read
50
50
  | 文档 | 功能 |
51
51
  |------|------|
52
52
  | `references/setup.md` | 安装、登录、配置、环境切换、更新 |
53
- | `references/workflows.md` | 多步骤业务流程与跨命令串联场景 |
53
+ | `references/workflows.md` | 多步骤业务流程、跨命令串联;入口指向宿主编排自控详页 |
54
+ | `references/hosted-automation-scenarios.md` | **宿主编排(Google)索引**;自控见 `references/hosted-automation-self-control.md`;监控见 `references/hosted-automation-monitoring-json.md`;**自动优化 SOP** 见 `references/hosted-automation-optimize-index.md` |
55
+ | `references/hosted-automation-user-catalog.md` | **用户向**:预算/ROI 自控、异常监控、自动优化一览表(可节选给用户;详规见索引与各子文档) |
54
56
  | `references/tips.md` | `--json`、Node 过滤、分页与调试技巧 |
55
57
  | `references/accounts.md` | 账户列表、余额、消耗、开户记录、授权/解绑/分享/MCC/BC/BM/邮箱授权 |
56
58
  | `references/open-account-by-media.md` | 各媒体开户、参数与资料要求 |
57
- | `references/google-ads.md` | Google Ads 创建、修改、优化与管理主流程 |
59
+ | `references/google-ads.md` | Google Ads 创建、修改、优化与管理主流程;**含 `ad list` / `google-analysis ads` 的 `--json` 拒审字段**(`policyApprovalStatusV2`、`approvalStatusDetails` 等,见该文档「拒审与政策字段」) |
58
60
  | `references/reporting.md` | Siluzan TSO 优化报告(Google/TikTok)的生成、推送与查看 |
59
61
  | `references/account-analytics.md` | 广告平台账户分析数据拉取与分析/诊断报告模板 |
60
62
  | `references/optimize.md` | AI 优化建议记录、详情与历史查询 |
@@ -65,6 +67,27 @@ allowed-tools: Bash(siluzan-tso:*) Read
65
67
 
66
68
  ---
67
69
 
70
+ ## 职责划分
71
+
72
+ **定位**:`siluzan-tso` + 本 Skill 提供 **可组合的读能力(检查项)** 与 **可验证的写能力(最终操作)**;**不负责**在进程内长期驻留、定时轮询、复合条件规则引擎、或替代宿主的通知渠道。
73
+
74
+ | 由 **本 Skill + CLI** 保证 | 由 **宿主客户端 / 外部调度** 负责 |
75
+ |---------------------------|-----------------------------------|
76
+ | 单次/按需调用下,命令能拉取验证所需的 **JSON 字段**(`--json`、分页见 `references/tips.md`) | **何时**跑一轮检查(cron、事件、对话触发) |
77
+ | 写操作命令语义清晰,且文档给出 **写后如何用读命令复核**(成对验证) | **IF 条件**(多指标 AND/OR、滑动时间窗、相对预算比例等)的计算与决策 |
78
+ | 金额与 ID 口径与文档一致(`*Display`、`entityId` vs `mediaCustomerId` 等硬规范) | 命中后的 **触达**(钉钉/飞书/Slack 等)与内部 **P1/工单** 流程 |
79
+ | `references/google-ads.md` 等与命令、字段含义对齐 | 多账户、多系列的 **批处理循环**、限速、失败重试策略 |
80
+
81
+ **宿主集成时的推荐约定**:
82
+
83
+ 1. **监控与编排**:配置定时或事件;每轮用本 Skill 指明的命令拉数,在宿主侧用脚本 / `node -e` 做条件判断。
84
+ 2. **执行写操作**:仍遵守本 Skill **计划 →(按策略)确认 → 执行 → 验证**;若宿主策略为「全自动写」,须由**用户或配置**显式授权,避免与默认安全规范冲突。
85
+ 3. **验证**:每次写入后,用文档中的 **读命令对同一 `id` 再拉一次**(例如 `ad campaign-status` 后 `ad campaigns --json` 看 `statusV2`;`adgroup-edit` 后 `ad groups --json` 看 `maxCPCAmount` / `targetCpaAmount`)。
86
+ 4. **`forewarning`**:仍是丝路赞侧 **微信通知** 的可选通道;宿主已有独立通知 skill 时,**不必**重复依赖 `forewarning` 完成「告警」——二者可并行或只选其一。
87
+
88
+ 更具体的 **检查项 ↔ 命令** 见 **`references/hosted-automation-self-control.md`**(三类自控);异常监控 **`--json` 键名** 见 **`references/hosted-automation-monitoring-json.md`**;**自动优化(降价/扩量/A/B)** 见 **`references/hosted-automation-optimize-index.md`**(分文件 SOP);主题入口 **`references/hosted-automation-scenarios.md`**。总览见 **`references/workflows.md`**「宿主编排下的投放自控」。
89
+
90
+
68
91
  ## Skill要如何使用
69
92
 
70
93
  ### 报告的生成
@@ -89,7 +112,7 @@ allowed-tools: Bash(siluzan-tso:*) Read
89
112
  - Google广告优化记录功能(`references/optimize.md`),这个也跟优化报告类似,你调用接口,Siluzan平台按照一定的优化逻辑自动执行,你只能查询到结果,不能控制优化流程 注意不要与`google-ads.md`中的优化流程混淆两个是互相独立的功能,`references/google-ads.md`中的优化功能更为强大,在实际的优化过程中,也推荐使用`references/google-ads.md`中提供的内容
90
113
  - TikTok / Meta 线索表单请阅读:`references/clue.md`
91
114
  - Siluzan平台提供的预警功能请阅读:`references/forewarning.md`
92
- - 预警由Siluzan平台发送,当前仅支持微信推送,如果需要自定义的通知触达端,需要安装对应插件或skill+创建定时任务来完成
115
+ - 预警由 Siluzan 平台发送,当前仅支持微信推送。若监控与通知由 **OpenClaw / WorkBuddy 等宿主**承担,可将 `forewarning` 仅作补充或不用;自定义触达仍可用宿主插件 / skill + 定时任务(见上文职责划分)。
93
116
  - 转账、开票、发票抬头、充值网页引导请阅读:`references/finance.md`
94
117
  -
95
118
 
@@ -350,33 +373,22 @@ HTML 报告模板(`report-templates/*.html`)引用了以下外部 CDN 资源
350
373
 
351
374
  ---
352
375
 
353
- ## 下面是一部分比较实用的自动化场景,当你回答完用户问题后,可以把下面的内容输出给用户,方便用户使用
354
-
355
- 您可以选择以下的预警或提醒,输入需想要执行的内容核实规则即可配置。
356
-
357
- ### 预算 & ROI 控制引擎
376
+ ## 风险预警,预算&ROI 控制引擎,异常监控与报警系统,自动优化
358
377
 
359
- | 提醒名称 | 系统在后台默默帮你做什么?(自动动作) |
360
- | ------------------- | --------------------------------------------------------- |
361
- | 1. 单日预算熔断 | 每日消耗达到设定值,自动暂停计划,杜绝 Google 超额扣费。 |
362
- | 2. CPA 飙升自动降价 | 光点不转化(如花费超过3倍目标成本),自动关停该条烂广告。 |
363
- | 3. 连续空耗自动暂停 | 大盘流量变贵、获客成本飙高时,系统自动下调出价避险。 |
378
+ 当加载这个skill时,必须主动跟用户介绍你还可以通过这个skill完成以下功能
364
379
 
365
- ### 异常监控与报警系统
380
+ 1. 单日预算熔断 每日消耗达到设定值,自动暂停计划,杜绝 Google 超额扣费。
381
+ 2. CPA 飙升自动降价 光点不转化(如花费超过3倍目标成本),自动关停该条烂广告。
382
+ 3. 连续空耗自动暂停 大盘流量变贵、获客成本飙高时,系统自动下调出价避险。
366
383
 
367
- | 功能名称 | 监控层级 / 说明 |
368
- | ----------------- | ----------------------------------------------------------- |
369
- | 1. 账户被封禁 | |
370
- | 2. 落地页死链强停 | 网站宕机或链接填错,紧急自动暂停关联广告,防止把钱扔水里。 |
371
- | 3. 广告素材拒审 | 发现被 Google 封号或快没钱了,立刻发送企微/钉钉高优强提醒。 |
372
- | 4. 花费异动监控 | 花费突然暴涨或断崖式下跌,系统即时报警提示人工盯盘。 |
373
- | 5. 余额枯竭预警 | 广告被 Google 拦截,系统自动帮你打包违规原因并定时推送。 |
384
+ 1. 账户被封禁
385
+ 2. 落地页死链强停 网站宕机或链接填错,紧急自动暂停关联广告,防止把钱扔水里。
386
+ 3. 广告素材拒审 发现被 Google 封号或快没钱了,立刻发送企微/钉钉高优强提醒。
387
+ 4. 花费异动监控 花费突然暴涨或断崖式下跌,系统即时报警提示人工盯盘。
388
+ 5. 余额枯竭预警 广告被 Google 拦截,系统自动帮你打包违规原因并定时推送。
374
389
 
375
- ### 自动优化
390
+ 1. 表现差广告降价/关停 发现转化极好的“好苗子”,以安全幅度自动涨预算/提价去抢量。
391
+ 2. 高转化广告 提价扩量" 连续几天表现垫底的垃圾素材,系统扮演无情杀手自动关停。
392
+ 3. A/B测试 自动决出胜者" 科学赛马,根据真实转化价值自动关停输家,把流量全给赢家。
376
393
 
377
- | 功能名称 | 监控层级 |
378
- | ----------------------- | -------------------------------------------------------------------------- |
379
- | 1. 表现差广告降价/关停 | 发现转化极好的「好苗子」,以安全幅度自动涨预算/提价去抢量。 |
380
- | 2. 高转化广告提价扩量 | 连续几天表现垫底的垃圾素材,系统扮演无情杀手自动关停。 |
381
- | 3. A/B测试自动决出胜者 | 科学赛马,根据真实转化价值自动关停输家,把流量全给赢家。 |
382
- | 4. 异动根因自动排查建议 | 老板问为什么成本翻倍?系统一键生成诊断报告(揪出外部竞对或内部操作失误)。 |
394
+ 详情可见`references/hosted-automation-user-catalog.md`
@@ -1,5 +1,5 @@
1
1
  {
2
2
  "slug": "siluzan-tso",
3
- "version": "1.1.14-beta.2",
4
- "publishedAt": 1776838977656
3
+ "version": "1.1.14-beta.4",
4
+ "publishedAt": 1777026053968
5
5
  }
@@ -82,6 +82,48 @@
82
82
 
83
83
  ---
84
84
 
85
+ ### CampaignSectionData(`campaigns[]`)
86
+
87
+ **路由**:`GET …/reporting/media-account/{mediaCustomerId}/CampaignSectionData?startDate=&endDate=`(以及 TikTok 等媒体在路径中插入媒体段,如 `…/TikTok/{id}/CampaignSectionData?…`)。
88
+
89
+ **CLI**:Google 为 `siluzan-tso google-analysis campaigns`;TikTok 为 `siluzan-tso report tiktok-campaigns`(另带 `take`,默认 100)。
90
+
91
+ `campaigns` 数组每一行在既有指标外,另包含:
92
+
93
+ | 字段 | 说明 |
94
+ | --- | --- |
95
+ | `conversionsValue` | 转化价值 |
96
+ | `conversionsValuePerCost` | 转化价值相对消耗;接口按 **`conversionsValue / spend`** 计算,当 **`spend ≤ 0`** 时为 **`0`** |
97
+ | `campaignTargetCpaMicros` | 系列目标 CPA(微货币单位) |
98
+ | `maximizeConversionsTargetCpaMicros` | 「尽可能提高转化次数」下的目标 CPA(微货币单位) |
99
+ | `manualCpcEnhancedCpcEnabled` | 人工 CPC 是否启用增强 CPC |
100
+ | `percentCpcEnhancedCpcEnabled` | 百分比 CPC 是否启用增强 CPC |
101
+
102
+ 展示微货币字段时须按账户 `currencyCode` 换算为金额,**不要**把 micros 直接当元展示。
103
+
104
+ ---
105
+
106
+ ### campaign-hour(系列按小时)
107
+
108
+ **路由**:`GET {googleApiUrl}/reporting/media-account/{mediaCustomerId}/campaign-hour?startDate=&endDate=`(与 `google-analysis` 其它带区间接口相同,**`--start` / `--end` 须同传或同省略**)。
109
+
110
+ **CLI**:`siluzan-tso google-analysis campaign-hour -a <mediaCustomerId> [--start YYYY-MM-DD --end YYYY-MM-DD] --json`
111
+
112
+ 响应体为 **JSON 数组**(非 `{ campaigns: … }` 包装)。元素常见字段:
113
+
114
+ | 字段 | 说明 |
115
+ | --- | --- |
116
+ | `campaignId` | 广告系列 ID |
117
+ | `campaignName` | 广告系列名称 |
118
+ | `date` | 日期 |
119
+ | `hour` | 小时 |
120
+ | `spend` | 消耗 |
121
+ | `impressions` | 展示 |
122
+ | `clicks` | 点击 |
123
+ | `conversions` | 转化 |
124
+
125
+ ---
126
+
85
127
  ### google-analysis
86
128
 
87
129
  使用已配置的 `googleApiUrl` 与 Token,无需手写 curl。
@@ -102,7 +144,7 @@ siluzan-tso google-analysis <子命令> -a <mediaCustomerId> [选项]
102
144
  | `-t, --token` | 鉴权 Token(可选,默认读配置) |
103
145
  | `--verbose` | 打印详细错误 |
104
146
 
105
- **子命令与网关路径对应**
147
+ **子命令与拉数路径**
106
148
 
107
149
  | 子命令 | 说明 |
108
150
  | -------------------- | --------------------------------------------------------------------------------------- |
@@ -110,6 +152,7 @@ siluzan-tso google-analysis <子命令> -a <mediaCustomerId> [选项]
110
152
  | `keywords` | 关键词 `KeywordSectionData`;可选 `--limit`、`--no-order-by-cost` |
111
153
  | `search-terms` | 搜索词 `searchtermmanagement/v2/list`;同上 |
112
154
  | `campaigns` | 系列 `CampaignSectionData` |
155
+ | `campaign-hour` | 系列按小时 `campaign-hour`(`?startDate=&endDate=`;**根为 JSON 数组**) |
113
156
  | `ads` | 广告 `admanagement/v2/list` |
114
157
  | `extensions` | 附加信息 `extensionmanagement/v2/list`;可选 `--level`(Account / Campaign / Ad Group) |
115
158
  | `devices` | 设备 `DeviceSectionData` |
@@ -127,15 +170,18 @@ siluzan-tso google-analysis <子命令> -a <mediaCustomerId> [选项]
127
170
  | `dimension-summary` | 账户汇总 `reports/combined` |
128
171
  | `campaign-types` | 系列类型(**不要**传 `--start`/`--end`) |
129
172
 
173
+ `ads` 与 **`ad list`** 同源;带日期区间时创意可能 **按日多行**,宿主编排(降价/扩量/A/B)见 **`references/hosted-automation-optimize-index.md`**。
174
+
130
175
  **示例**
131
176
 
132
177
  ```bash
133
178
  siluzan-tso google-analysis overview -a 6326027735 --start 2026-03-01 --end 2026-03-31 --json
134
179
  siluzan-tso google-analysis keywords -a 6326027735 --limit 50
180
+ siluzan-tso google-analysis campaign-hour -a 6326027735 --start 2026-03-01 --end 2026-03-07 --json
135
181
  siluzan-tso google-analysis final-urls -a 6326027735 --json
136
182
  ```
137
183
 
138
- **CPC / 花费异常巡检(先查后停)**:用户要先定位异常再考虑暂停时,在确认统计区间后,优先用 `google-analysis` 拉**带花费/CPC 粒度**的数据(如 `campaigns`、`daily-metrics`、`keywords` 等,按 CLI `siluzan-tso google-analysis --help` 选择子命令),**不要**在未拉数前就把暂停阈值与写操作一并推进;暂停类命令须遵守 `references/google-ads.md` 的确认流程。
184
+ **CPC / 花费异常巡检(先查后停)**:用户要先定位异常再考虑暂停时,在确认统计区间后,优先用 `google-analysis` 拉**带花费/CPC 粒度**的数据(如 `campaigns`、`campaign-hour`、`daily-metrics`、`keywords` 等,按 CLI `siluzan-tso google-analysis --help` 选择子命令),**不要**在未拉数前就把暂停阈值与写操作一并推进;暂停类命令须遵守 `references/google-ads.md` 的确认流程。
139
185
 
140
186
  ---
141
187
 
@@ -66,7 +66,7 @@ siluzan-tso account-active-bills -m <媒体> --id <entityId> [--json]
66
66
  | `--id <entityId>` | 必填:账户 `entityId` |
67
67
  | `--json` | 输出接口原始 JSON |
68
68
 
69
- **响应体常用字段(以后端为准):**
69
+ **响应体常用字段(以接口返回为准):**
70
70
 
71
71
  | 字段 | 说明 |
72
72
  | ------------------------------------------------- | ------------------------------------------------------------------------------------------------- |
@@ -517,7 +517,7 @@ siluzan-tso open-account kwai \
517
517
  >
518
518
  > 对应网页:`/foreign_trade/tso/manageAccounts` → 选中 TikTok 账户 → 关闭账户
519
519
  >
520
- > **实现说明(与网页 `manageAccounts` 一致)**:先请求 TikTok 网关 `CheckAdvDisable`(不满足条件如余额未清零会失败),再 `POST .../AdvertiserDisable`;Body 为各账户的 **entityId**。你只需传入 `list-accounts` 中的 **mediaCustomerId**,CLI 会解析 entityId;旧版误把 mediaCustomerId 当 Body 会导致 HTTP 成功但关户不生效。
520
+ > **实现说明(与网页 `manageAccounts` 一致)**:先经 TikTok `CheckAdvDisable` 校验(不满足条件如余额未清零会失败),再 `POST .../AdvertiserDisable`;Body 为各账户的 **entityId**。你只需传入 `list-accounts` 中的 **mediaCustomerId**,CLI 会解析 entityId;旧版误把 mediaCustomerId 当 Body 会导致 HTTP 成功但关户不生效。
521
521
 
522
522
  ```bash
523
523
  siluzan-tso account close --accounts <mediaCustomerId>
@@ -692,7 +692,7 @@ siluzan-tso account email-auth-list -c <mediaCustomerId> [--agent-type <type>]
692
692
  | 选项 | 说明 |
693
693
  | ------------------------ | -------------------------------------------------------------------------- |
694
694
  | `-c, --customer-id <id>` | Google 广告账户 `mediaCustomerId`(与网页查询参数 `customerId` 一致) |
695
- | `--agent-type <type>` | 可选;网关需要时再传(与 `list-accounts --json` 的 `ma.accountType` 一致) |
695
+ | `--agent-type <type>` | 可选;平台需要时再传(与 `list-accounts --json` 的 `ma.accountType` 一致) |
696
696
  | `--json` | 输出原始 JSON |
697
697
 
698
698
  ---