siluzan-tso-cli 1.1.58-beta.5 → 1.1.59-beta.1

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.58-beta.5),供内部测试使用。正式发布后安装命令将改为 `npm install -g siluzan-tso-cli`。
54
+ > **注意**:当前为测试版(1.1.59-beta.1),供内部测试使用。正式发布后安装命令将改为 `npm install -g siluzan-tso-cli`。
55
55
 
56
56
  | 助手 | 建议 `--ai` |
57
57
  | ----------------------- | ------------------------------------ |
package/dist/index.js CHANGED
@@ -129123,7 +129123,8 @@ function annotateKeywordSuggestWithAccountPresence(items3, accountNormSet) {
129123
129123
  // src/commands/keyword-geo.ts
129124
129124
  var KNOWN_GEO_LABELS = {
129125
129125
  2840: "\u7F8E\u56FD",
129126
- 2826: "\u4E2D\u56FD"
129126
+ 2156: "\u4E2D\u56FD",
129127
+ 2826: "\u82F1\u56FD"
129127
129128
  };
129128
129129
  function geoLabel(id) {
129129
129130
  const name2 = KNOWN_GEO_LABELS[id];
@@ -129336,7 +129337,7 @@ Google Ads \u56FD\u5BB6/\u5730\u533A\u5E38\u91CF\uFF08\u5171 ${n} \u6761\uFF09
129336
129337
  ]
129337
129338
  );
129338
129339
  console.log(
129339
- '\n\u62D3\u8BCD\u65F6\u6307\u5B9A\u5730\u533A\uFF1Asiluzan-tso keyword -k "\u79CD\u5B50" --geo <id>\n \u4F8B\uFF1A\u7F8E\u56FD=2840\uFF0C\u4E2D\u56FD=2826\n \u591A\u4E2A --geo \u4E3A\u6C47\u603B\u6570\u636E\uFF1B\u5206\u5E02\u573A\u5BF9\u6BD4\u8BF7\u591A\u6B21\u8C03\u7528\u3001\u6BCF\u6B21\u53EA\u4F20\u4E00\u4E2A id\n'
129340
+ '\n\u62D3\u8BCD\u65F6\u6307\u5B9A\u5730\u533A\uFF1Asiluzan-tso keyword -k "\u79CD\u5B50" --geo <id>\n \u4F8B\uFF1A\u7F8E\u56FD=2840\uFF0C\u4E2D\u56FD=2156\uFF0C\u82F1\u56FD=2826\n \u591A\u4E2A --geo \u4E3A\u6C47\u603B\u6570\u636E\uFF1B\u5206\u5E02\u573A\u5BF9\u6BD4\u8BF7\u591A\u6B21\u8C03\u7528\u3001\u6BCF\u6B21\u53EA\u4F20\u4E00\u4E2A id\n'
129340
129341
  );
129341
129342
  }
129342
129343
  async function runKeywordSuggest(opts) {
@@ -129428,6 +129429,13 @@ async function runKeywordSuggest(opts) {
129428
129429
  return !excludes.some((exc) => kw.includes(exc));
129429
129430
  });
129430
129431
  }
129432
+ const beforeVolumeFilter = items3.length;
129433
+ items3 = filterByMinMonthlySearch(items3, opts.minMonthlySearch);
129434
+ if (opts.minMonthlySearch != null && opts.minMonthlySearch > 0 && items3.length !== beforeVolumeFilter) {
129435
+ console.error(
129436
+ ` [keyword] \u6708\u641C\u7D22\u91CF >= ${opts.minMonthlySearch}\uFF1A\u4FDD\u7559 ${items3.length} \u6761\uFF0C\u53BB\u6389 ${beforeVolumeFilter - items3.length} \u6761\uFF08\u7F3A\u641C\u7D22\u91CF\u89C6\u4E3A 0\uFF09`
129437
+ );
129438
+ }
129431
129439
  if (accountId) {
129432
129440
  try {
129433
129441
  const accountNormSet = await fetchAccountPositiveKeywordNormSet(
@@ -129565,6 +129573,23 @@ function microsItemToBidAmounts(item) {
129565
129573
  )
129566
129574
  };
129567
129575
  }
129576
+ function filterByMinMonthlySearch(items3, minMonthlySearch) {
129577
+ if (minMonthlySearch == null || !Number.isFinite(minMonthlySearch) || minMonthlySearch <= 0) {
129578
+ return items3;
129579
+ }
129580
+ return items3.filter((item) => {
129581
+ const volume = Number(item.montlySearch);
129582
+ return Number.isFinite(volume) && volume >= minMonthlySearch;
129583
+ });
129584
+ }
129585
+ function parseMinMonthlySearch(raw) {
129586
+ const value = Number(raw);
129587
+ if (!Number.isFinite(value) || value < 0) {
129588
+ console.error("\n\u274C --min-monthly-search \u5FC5\u987B\u662F\u5927\u4E8E\u7B49\u4E8E 0 \u7684\u6570\u5B57\u3002\n");
129589
+ process.exit(1);
129590
+ }
129591
+ return value;
129592
+ }
129568
129593
  function attachBaseCliOptions(cmd) {
129569
129594
  attachJsonOutOption(cmd);
129570
129595
  cmd.option("--verbose", "\u8F93\u51FA\u8BE6\u7EC6\u9519\u8BEF\u5806\u6808").option("--token <jwt>", "\u4E34\u65F6\u4F7F\u7528\u7684 JWT Token\uFF08\u8986\u76D6 ~/.siluzan/config.json\uFF09");
@@ -129583,7 +129608,10 @@ function register23(program2) {
129583
129608
  ).option(
129584
129609
  "--geo <ids>",
129585
129610
  "geoTargetConstant ID\uFF08\u5148 keyword geo-list\uFF1B\u4F8B 2840=\u7F8E\u56FD\uFF09\u3002\u591A\u4E2A ID \u4E3A\u6C47\u603B\u6307\u6807\uFF1B\u5206\u5E02\u573A\u987B\u591A\u6B21\u8C03\u7528\u3001\u6BCF\u6B21\u53EA\u4F20\u4E00\u4E2A"
129586
- ).option("--url <url>", "\u516C\u53F8/\u4EA7\u54C1\u7F51\u5740\uFF08\u586B\u5199\u540E\u89E6\u53D1\u7F51\u5740\u62D3\u8BCD\uFF1B\u4E0E --google-only \u4E92\u65A5\uFF09").option("--google-only", "\u4EC5 Google Keyword Planner\uFF0C\u4E0D\u53E0\u52A0\u7F51\u5740\u62D3\u8BCD").option("--include <words>", "\u7ED3\u679C\u5FC5\u987B\u5305\u542B\u7684\u8BCD\uFF0C\u9017\u53F7\u6216\u7A7A\u683C\u5206\u9694").option("--exclude <words>", "\u7ED3\u679C\u4E0D\u5305\u542B\u7684\u8BCD\uFF0C\u9017\u53F7\u6216\u7A7A\u683C\u5206\u9694").action(async (opts) => {
129611
+ ).option("--url <url>", "\u516C\u53F8/\u4EA7\u54C1\u7F51\u5740\uFF08\u586B\u5199\u540E\u89E6\u53D1\u7F51\u5740\u62D3\u8BCD\uFF1B\u4E0E --google-only \u4E92\u65A5\uFF09").option("--google-only", "\u4EC5 Google Keyword Planner\uFF0C\u4E0D\u53E0\u52A0\u7F51\u5740\u62D3\u8BCD").option("--include <words>", "\u7ED3\u679C\u5FC5\u987B\u5305\u542B\u7684\u8BCD\uFF0C\u9017\u53F7\u6216\u7A7A\u683C\u5206\u9694").option("--exclude <words>", "\u7ED3\u679C\u4E0D\u5305\u542B\u7684\u8BCD\uFF0C\u9017\u53F7\u6216\u7A7A\u683C\u5206\u9694").option(
129612
+ "--min-monthly-search <n>",
129613
+ "\u4E22\u6389\u6708\u641C\u7D22\u91CF\u4F4E\u4E8E\u8BE5\u503C\u7684\u8BCD\uFF1B\u7F3A\u641C\u7D22\u91CF\u89C6\u4E3A 0\u3002\u7528\u6237\u8981\u6709\u641C\u7D22\u70ED\u5EA6\u65F6\u7528 1"
129614
+ ).action(async (opts) => {
129587
129615
  await runKeywordSuggest({
129588
129616
  token: opts.token,
129589
129617
  account: opts.account,
@@ -129593,6 +129621,7 @@ function register23(program2) {
129593
129621
  include: opts.include,
129594
129622
  exclude: opts.exclude,
129595
129623
  googleOnly: opts.googleOnly,
129624
+ minMonthlySearch: opts.minMonthlySearch == null ? void 0 : parseMinMonthlySearch(opts.minMonthlySearch),
129596
129625
  jsonOut: opts.jsonOut,
129597
129626
  verbose: opts.verbose
129598
129627
  });
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: siluzan-tso
3
- description: 丝路赞 TSO 广告平台(Google/Bing/Yandex/TikTok/MetaAd),凡涉及丝路赞/TSO、投广告、出价预算、广告账户管理,或需要做行业分析/市场分析/行业分析报告(含「写一份 XX 行业报告」「电商/制造/医疗等行业报告」「市场调查/战略市场/KA 市场报告」「竞品/GTM/市场格局/行业趋势」等,无论是否提及丝路赞/广告/客户)须加载本 skill。【§零·最高优先】网址/域名/官网+诊断/检测/监测/评估/体检/报告/符合投放要求/能不能投(含「网络诊断」混说)→P8 website-diagnosis collect(禁纯WebFetch/肉眼看页),禁止P9/P1/W3、禁止A/B/C/D追问;细则见 intent-routing.md §零。【§零·B·次高优先】未命中§零时,行业/市场分析报告类话术→必走P9 market-analysis collect+render出HTML,禁止纯WebSearch/WebFetch在对话里写Markdown/HTML当终稿、禁止改走P8/P1/P4/W5/google-analysis;细则见 references/core/intent-routing.md §零·B。【§零·C·关键词规划】Google Ads/谷歌广告拓词、关键词规划/推荐、Keyword Planner、长尾关键词、月搜索量/搜索量、竞争度、核心词/种子词扩词(含「阅读网址/文章/页面后针对核心词出带搜索量词表」,无论是否提及丝路赞/TSO/账户)→必走W5 keyword -k … --google-only --json-out,禁止WebSearch/WebFetch编造搜索量当终稿;细则见 references/core/intent-routing.md §零·C。【报告/诊断消歧】其余报告类话术禁止默认某一CLI——行业/市场/战略/行业分析报告→P9 market-analysis(必走collect+render,禁止纯WebSearch代替);Google账户ID+健康诊断→P1 google-ads-diagnosis;只要周期数据/8维/花费转化汇总/Excel→P4;Google/谷歌广告月度报告、月总结与规划、季度报告、Q3汇总、Q4规划、季度汇报、投放季报、客户版、大族模板、下月规划→P10 google-quarterly;Meta/TikTok/Bing周期→P4/P4-FB;多账户对比→P3/P5;OKKI周报→P6;Google询盘→P7;官网+明确要搜索广告方案/campaign JSON→W3;Meta Instant Form 线索广告→W13;仅要词表+搜索量/竞争度→W5;平台优化报告列表/推送→W7;对象仍不清→Read intent-routing.md。【账户】列表/余额/消耗/激活账单(W1)、多账户余额预警 balance-scan(P2)、多户消耗汇总 accounts-digest(P3)、五大媒体开户与进度(W2)、分享/解绑/MCC/BC/BM/权限(W9)。【投放】**搭建仅 Google+Meta**:Google Search/PMax(W3,无 Display;含 CRUD/PMax/batch W4);Meta Instant Form(W13)。TikTok/Bing/Yandex **不能建广告**。另:拓词 W5、optimize W6。【财务】充值/钱包、转账记录、发票/开票/抬头(W8);写操作审计与 restore。【运营】智能预警 forewarning 创建/启停/记录(W10)、TikTok/Meta 线索 clue(W11)、日周巡检(W12)、宿主编排/投放自控/异常监控(hosted-automation)。【其他】RAG 知识库检索、Meta/Facebook 周期与诊断 HTML、Google/Meta 周期 Excel、多账户 google-analysis-batch。
3
+ description: 丝路赞 TSO 广告平台(Google/Bing/Yandex/TikTok/MetaAd),凡涉及丝路赞/TSO、投广告、出价预算、广告账户管理,或需要做行业分析/市场分析/行业分析报告(含「写一份 XX 行业报告」「电商/制造/医疗等行业报告」「市场调查/战略市场/KA 市场报告」「竞品/GTM/市场格局/行业趋势」等,无论是否提及丝路赞/广告/客户)须加载本 skill。【§零·最高优先】网址/域名/官网+诊断/检测/监测/评估/体检/报告/符合投放要求/能不能投(含「网络诊断」混说)→P8 website-diagnosis collect(禁纯WebFetch/肉眼看页),禁止P9/P1/W3、禁止A/B/C/D追问;细则见 intent-routing.md §零。【§零·B·次高优先】未命中§零时,行业/市场分析报告类话术→必走P9 market-analysis collect+render出HTML,禁止纯WebSearch/WebFetch在对话里写Markdown/HTML当终稿、禁止改走P8/P1/P4/W5/google-analysis;细则见 references/core/intent-routing.md §零·B。【§零·C·关键词规划】Google Ads/谷歌广告拓词、关键词规划/推荐、Keyword Planner、长尾关键词、月搜索量/搜索量、竞争度、核心词/种子词扩词(含「阅读网址/文章/页面后针对核心词出带搜索量词表」,无论是否提及丝路赞/TSO/账户)→必走W5,一次 keyword -k … --google-only --min-monthly-search,禁止分批洗词脚本,禁止WebSearch/WebFetch编造搜索量当终稿;细则见 references/core/intent-routing.md §零·C。【报告/诊断消歧】其余报告类话术禁止默认某一CLI——行业/市场/战略/行业分析报告→P9 market-analysis(必走collect+render,禁止纯WebSearch代替);Google账户ID+健康诊断→P1 google-ads-diagnosis;只要周期数据/8维/花费转化汇总/Excel→P4;Google/谷歌广告月度报告、月总结与规划、季度报告、Q3汇总、Q4规划、季度汇报、投放季报、客户版、大族模板、下月规划→P10 google-quarterly;Meta/TikTok/Bing周期→P4/P4-FB;多账户对比→P3/P5;OKKI周报→P6;Google询盘→P7;官网+明确要搜索广告方案/campaign JSON→W3;Meta Instant Form 线索广告→W13;仅要词表+搜索量/竞争度→W5;平台优化报告列表/推送→W7;对象仍不清→Read intent-routing.md。【账户】列表/余额/消耗/激活账单(W1)、多账户余额预警 balance-scan(P2)、多户消耗汇总 accounts-digest(P3)、五大媒体开户与进度(W2)、分享/解绑/MCC/BC/BM/权限(W9)。【投放】**搭建仅 Google+Meta**:Google Search/PMax(W3,无 Display;含 CRUD/PMax/batch W4);Meta Instant Form(W13)。TikTok/Bing/Yandex **不能建广告**。另:拓词 W5、optimize W6。【财务】充值/钱包、转账记录、发票/开票/抬头(W8);写操作审计与 restore。【运营】智能预警 forewarning 创建/启停/记录(W10)、TikTok/Meta 线索 clue(W11)、日周巡检(W12)、宿主编排/投放自控/异常监控(hosted-automation)。【其他】RAG 知识库检索、Meta/Facebook 周期与诊断 HTML、Google/Meta 周期 Excel、多账户 google-analysis-batch。
4
4
  license: MIT
5
5
  compatibility: 需要 Node.js 18+、已安装 siluzan-tso-cli,通过 send-login-code + login 或 config set 完成鉴权
6
6
  metadata:
@@ -1,5 +1,5 @@
1
1
  {
2
2
  "slug": "siluzan-tso",
3
- "version": "1.1.58-beta.5",
4
- "publishedAt": 1793009570139
3
+ "version": "1.1.59-beta.1",
4
+ "publishedAt": 1793084796757
5
5
  }
@@ -18,6 +18,19 @@
18
18
  > **拓词命令**读本文;**建户 JSON + validate + create** 读 `references/google-ads/google-ads-campaign-plan.md`。关键词数量规则:`references/google-ads/rules/google-ads-keyword-taxonomy.md`。
19
19
  > **数据口径**:`siluzan-tso keyword` 默认走 `keywordidea/google`(共享 MCC,出价 **USD**);传 **`-a <mediaCustomerId>`** 时走 `keywordrecommendation/recommend/{id}/google`,出价币种为 `list-accounts` 的 **`currencyCode`**(如 CNY)。可选 `--url` 叠加 **网址拓词**(`websitereco`)。与 **`google-analysis` 投放表现**不是同一套数据。
20
20
 
21
+ ## 一次拓词(默认)
22
+
23
+ 竞品词、产品词、核心词全部放进 **同一次** `-k`。用户要「有搜索热度」时加 `--min-monthly-search 1`(缺搜索量视为 0,会被丢掉)。用户给了具体下限(如约 3000)就用该下限。
24
+
25
+ ```bash
26
+ siluzan-tso keyword -k "scania truck,scania tipper,daf truck,daf tipper" -a 4460948284 --google-only --min-monthly-search 1
27
+ ```
28
+
29
+ - 命令打印的表就是交付物。不要为洗词、按品牌分桶、逐条查看 JSON 再写一轮 Python / Node。
30
+ - 用户没点名国家时 **不要** `--geo`,也 **不要** `keyword geo-list`。常见 ID 已写在下文,点名了国家再加 `--geo`。
31
+ - 某几个种子完全没有量时,只为这几个种子再补 **一次** `-k`。不要按品牌循环改脚本。
32
+ - 用户明确要 Excel 时才加 `--json-out`,并用 **一次** 脚本把已经滤好的 `items` 写成 xlsx,然后 `present_files`。不要边滤边改脚本。
33
+
21
34
  ---
22
35
 
23
36
  ## 路径选择(拓词前先定分支)
@@ -51,17 +64,17 @@
51
64
 
52
65
  1. 种子词仅来自:**用户已给出的词**、账户内 `google-analysis` 抽词、或(可选)**RAG 知识库**片段——**不要**再联网搜索补种子。
53
66
  2. ```bash
54
- siluzan-tso keyword -k "种子1,种子2,..." --google-only --json-out ./snap-kw
67
+ siluzan-tso keyword -k "种子1,种子2,..." --google-only --min-monthly-search 1
55
68
  ```
56
- (`--google-only` 即使误传 `--url` 也会忽略网址拓词。)
57
- 3. 词包说明首行标注:**数据来源:Google Keyword Planner(`keywordidea/google`)**;表格只列落盘 JSON 中有 `montlySearch` 等字段的词。
69
+ (`--google-only` 即使误传 `--url` 也会忽略网址拓词。命令打印的表就是交付物,不要再写脚本洗词。)
70
+ 3. 词包说明首行标注:**数据来源:Google Keyword Planner(`keywordidea/google`)**。用户要 Excel 时才加 `--json-out`,并只写一次导出脚本。
58
71
  4. 若 `source` 为 `"Cgy"` 的条目仍存在,须在说明中单独标注,勿称为 Google Planner 原生建议。
59
72
 
60
73
  ---
61
74
 
62
75
  ## 九类场景索引
63
76
 
64
- 洗词、分组、否词表、匹配策略等多依赖对 **`--json-out` 落盘 JSON** 的解析或 Agent 归纳;逐步命令见「场景编排」。
77
+ 月搜索量下限用 `--min-monthly-search`,不要再写脚本滤掉 0 搜索量。分组、否词、匹配策略仍可读落盘 JSON;逐步命令见「场景编排」。
65
78
 
66
79
  | # | 场景 | 编排 |
67
80
  | --- | ------------------------------------------------------------------------------- | ------------------------------------------------ |
@@ -69,7 +82,7 @@
69
82
  | 0 | **先 RAG 再拓词**:客户产品/行业背景 → 种子词与 `--url` | §0 |
70
83
  | 1 | 竞品网址 + 种子拓词:至少一个 `-k` + `--url`,落盘后去重/排序/截 Top N | §1 |
71
84
  | 2 | 多种子长尾:`-k "种子1,种子2,..."` | §2 |
72
- | 3 | 按规则洗词:月搜索量阈值、排除词根、排除类意图等 | §2(JSON) |
85
+ | 3 | 按规则洗词:月搜索量阈值用 `--min-monthly-search`;排除词根用 `--exclude` | §2 |
73
86
  | 4 | 账户关键词表现 + 市场侧指标:`google-analysis` keywords → 抽词 → 分批 `keyword` | §3 |
74
87
  | 5 | 搜索词 + 拓词:浪费流量 / 否词线索 | §4 |
75
88
  | 6 | 高商业意图粗筛:CPC、竞争度、搜索量 | §5 |
@@ -89,18 +102,15 @@
89
102
  **执行**:
90
103
 
91
104
  1. (可选)WebFetch 用户 URL,提取产品语境与同义词,**补充** `-k` 种子;**禁止**用文章臆测搜索量。
92
- 2. 将核心词 **分批**(每批 3–8 个)调用:
105
+ 2. 核心词放进 **同一次** `-k`。搜索量下限用 `--min-monthly-search`,不要分批,也不要再写脚本滤搜索量:
93
106
 
94
107
  ```bash
95
- siluzan-tso keyword -k "fish gelatin,porcine gelatin,..." --url "https://example.com/" --geo 2840 --google-only --json-out ./snap-kw-batch1
108
+ siluzan-tso keyword -k "fish gelatin,porcine gelatin,..." --google-only --min-monthly-search 1500
96
109
  ```
97
110
 
98
- - 目标市场未指定时默认 `--geo 2840`(美国)并在交付说明中写明;要其它市场先 `keyword geo-list`。
111
+ - 用户没点名国家时不要加 `--geo`,也不要先跑 `keyword geo-list`。点名了市场再用下文的常见 ID,例如美国 `--geo 2840`。
99
112
 
100
- 3. 脚本读各批 `items[]`:
101
- - 按 `montlySearch` 过滤(如 1500–6000 视为「约 3000」区间);
102
- - 按 `competition` / `competitionV2` 筛「中低」(LOW / MEDIUM 或数值阈值,以当次 outline 为准);
103
- - 每个核心词保留 Top N(用户指定如 30 条);不足时扩大 `-k` 变体或放宽阈值并在说明中标注。
113
+ 3. 竞争度「中低」看命令输出的 `competitionV2`(LOW / MEDIUM)。某个核心词一条都没有时,只为这个词再补一次 `-k`。用户指定了每个核心词保留 Top N 时,在这一次结果里截断并在说明里写明。
104
114
  4. 交付 Markdown/表格:**英文关键词 | 中文翻译 | 所属核心词 | 月搜索量 | 竞争度 | 目标市场**。目标市场用落盘 JSON 根上的 `targetMarket.label`(例如「美国(2840)」),表题写明 **月搜索量不是全球**。把 `targetMarket.note` 写进表头说明。首行仍注明 **Google Keyword Planner(`keywordidea/google`)**。用户拿官方规划师对数字时,先核对规划师选的是不是同一个国家;选「全球」或别的国家时数字本来就不会一致。
105
115
 
106
116
  **禁止**:纯 WebSearch/WebFetch 输出带「月搜索量」的终稿;禁止跳过 `keyword` CLI。
@@ -121,26 +131,26 @@ Google Keyword Planner 的搜索量/CPC 与**目标国家/地区**相关,**不
121
131
  siluzan-tso keyword -k "pipe" --geo 2840 --json-out ./snap-kw-us
122
132
  ```
123
133
 
124
- 常见 ID(与 `ad campaign-create --location-ids` 同源):美国 `2840`,中国 `2826`。
134
+ 常见 ID(以 `keyword geo-list` 为准):美国 `2840`,中国 `2156`,英国 `2826`。`2826` 不是中国。
125
135
 
126
136
  ### 多地区 `--geo`:返回汇总数据,无法按地区拆分
127
137
 
128
- `--geo` 可传多个 ID(逗号分隔,如 `--geo 2840,2826`),网关会把它们一并传给 `keywordidea/google?geoTargetConstantIds=...`。此时 Google Keyword Planner 返回的 `montlySearch`、CPC、竞争度等是**跨所传地区的汇总/合并口径**,**不是**「每个国家各一行」或 JSON 里带 `geoTargetConstantId` 分字段。
138
+ `--geo` 可传多个 ID(逗号分隔,如 `--geo 2840,2156`),网关会把它们一并传给 `keywordidea/google?geoTargetConstantIds=...`。此时 Google Keyword Planner 返回的 `montlySearch`、CPC、竞争度等是**跨所传地区的汇总/合并口径**,**不是**「每个国家各一行」或 JSON 里带 `geoTargetConstantId` 分字段。
129
139
 
130
140
  | 需求 | 做法 |
131
141
  | ----------------------------------- | ------------------------------------------------------------------------------------------------------------- |
132
- | 只要「美国+中国合在一起」的市场参考 | 一次调用:`--geo 2840,2826` |
142
+ | 只要「美国+中国合在一起」的市场参考 | 一次调用:`--geo 2840,2156` |
133
143
  | 要对比美国 vs 中国各自搜索量/CPC | **多次调用**,每次 `--geo` **只传一个** ID,分别 `--json-out` 到不同目录(如 `./snap-kw-us`、`./snap-kw-cn`) |
134
144
 
135
- **禁止**把 `--geo 2840,2826` 的单次落盘结果当成「美国一套、中国一套」两张表;报告里若写多市场对比,须注明数据来源为分次 `keyword` 调用。
145
+ **禁止**把 `--geo 2840,2156` 的单次落盘结果当成「美国一套、中国一套」两张表;报告里若写多市场对比,须注明数据来源为分次 `keyword` 调用。
136
146
 
137
147
  ```bash
138
148
  # 正确:分市场各查一次
139
149
  siluzan-tso keyword -k "pipe" --geo 2840 --json-out ./snap-kw-us
140
- siluzan-tso keyword -k "pipe" --geo 2826 --json-out ./snap-kw-cn
150
+ siluzan-tso keyword -k "pipe" --geo 2156 --json-out ./snap-kw-cn
141
151
 
142
152
  # 易误解:单次多 geo 只有汇总指标,无法在 items[] 内按国家拆开
143
- siluzan-tso keyword -k "pipe" --geo 2840,2826 --json-out ./snap-kw-merged
153
+ siluzan-tso keyword -k "pipe" --geo 2840,2156 --json-out ./snap-kw-merged
144
154
  ```
145
155
 
146
156
  ---
@@ -196,9 +206,9 @@ siluzan-tso keyword -k "structural adhesive,SG-200,curtain wall bonding" --url "
196
206
  ### 2)核心词长尾裂变 + 自定义过滤
197
207
 
198
208
  1. ```bash
199
- siluzan-tso keyword -k "种子1,种子2,..." [--include "<须含片段>"] [--exclude "<排除片段>"] --json-out ./snap-kw
209
+ siluzan-tso keyword -k "种子1,种子2,..." [--include "<须含片段>"] [--exclude "<排除片段>"] [--min-monthly-search <下限>] --google-only
200
210
  ```
201
- 2. 月搜索量阈值、排除求职/零售等意图:**对 JSON 中 `montlySearch`(字段名与网关一致)等做程序或 AI 过滤**;`--exclude` 仅做子串级粗滤。
211
+ 2. 月搜索量下限用 `--min-monthly-search`,排除求职/零售等词根用 `--exclude`。不要再写脚本把 `montlySearch` 滤一轮。
202
212
 
203
213
  ### 3)旧账户关键词 + 叠市场侧 CPC/热度
204
214
 
@@ -207,8 +217,8 @@ siluzan-tso keyword -k "structural adhesive,SG-200,curtain wall bonding" --url "
207
217
  1. 拉账户表现:
208
218
  `siluzan-tso google-analysis -a <mediaCustomerId> --sections keywords --start <S> --end <E> --json-out ./snap-ga`
209
219
  2. 从落盘 JSON 抽取关键词文案(字段路径以该次 **`keywords-*.outline.txt`** 为准)。
210
- 3. 分批调用(避免单次 body 过大):
211
- `siluzan-tso keyword -k "词A,词B,..." --json-out ./snap-kw-batchN`
220
+ 3. 抽出来的词放进 **同一次** `-k`(要有搜索热度时加 `--min-monthly-search 1`)。只有接口明确拒绝过长 body 时才拆成第二次,不要按品牌循环。
221
+ `siluzan-tso keyword -k "词A,词B,..." --google-only --min-monthly-search 1`
212
222
  4. 报告中**分栏说明**:左列为账户内指标(花费/转化等),右列为 `keyword` 返回的搜索量/CPC/竞争度(市场参考)。
213
223
 
214
224
  ### 4)搜索词辅助(浪费流量 / 否词线索)
@@ -238,7 +248,7 @@ siluzan-tso keyword -k "structural adhesive,SG-200,curtain wall bonding" --url "
238
248
  ## 单命令速查
239
249
 
240
250
  ```bash
241
- siluzan-tso keyword -k "<必填,逗号分隔多词>" [-a <mediaCustomerId>] [--geo <id[,id...]>] [--url <url>] [--google-only] [--include <words>] [--exclude <words>] [--json-out ./snap] [--json-out <dir>] [--verbose]
251
+ siluzan-tso keyword -k "<必填,逗号分隔多词>" [-a <mediaCustomerId>] [--geo <id[,id...]>] [--url <url>] [--google-only] [--min-monthly-search <n>] [--include <words>] [--exclude <words>] [--json-out ./snap] [--json-out <dir>] [--verbose]
242
252
  siluzan-tso keyword geo-list [--country-code <codes>] [--name-contains <text>] [--json-out ./snap] [--json-out <dir>]
243
253
  ```
244
254
 
@@ -246,6 +256,8 @@ siluzan-tso keyword geo-list [--country-code <codes>] [--name-contains <text>] [
246
256
 
247
257
  `--google-only`:只调 Google 推荐主接口(有 `-a` 为账户接口,无 `-a` 为 `keywordidea/google`),不叠加 `--url` 的网址拓词;**分支 B(仅 Google)必加**。
248
258
 
259
+ `--min-monthly-search`:丢掉 `montlySearch` 低于该值的行;字段缺失视为 0。用户要「有搜索热度」时传 `1`。
260
+
249
261
  **返回字段**(与后端 `Samm.Core.Service.KeywordRecommendation` 对齐):根级 **`targetMarket`**(`label` 是给用户看的目标市场,如「美国(2840)」;没传 `--geo` 时为「未限定国家」;`note` 说明搜索量不是全球)。根级与每条 **`bidAmountCurrency`**(无账户=`USD`;有账户=`list-accounts` 的 `currencyCode`);`averageCpc` / `lowTopOfPageBid` / `highTopOfPageBid`(微元 ÷1,000,000,**与 `bidAmountCurrency` 一致**)。另有 `keyword` / `montlySearch` / `monthlySearchVolumes` / `competition` / `competitionV2` / `source` 等;**有 `-a` 时**每条多 **`alreadyInAccount`**(`0` | `1`)。交给用户的表必须带 `targetMarket.label`,并写明不是全球。
250
262
 
251
263
  与只读账户关键词列表、否词 CRUD 的对照:查询见 **`google-ads-read.md`**,写入见 **`google-ads-write.md`**。
@@ -113,8 +113,8 @@
113
113
  ### C.2 命中后的 Agent 行为(强制)
114
114
 
115
115
  1. **直接定工作流 W5** → Read `workflows.md` W5 + `analytics/keyword-planner-workflows.md`。
116
- 2. **必走 CLI**:`siluzan-tso keyword -k "种子1,种子2,..." [--url "<落地页>"] [--geo <id>] --google-only --json-out ./snap-kw`(要官方 Planner 指标时 **必加 `--google-only`**;多核心词 **分批** `-k`,避免单次 body 过大)。
117
- 3. **网址/文章**:可用 WebFetch 读页面 **仅归纳种子词与产品语境**;**月搜索量 / 竞争度 / CPC 只能来自 `keyword` 落盘 JSON**(字段 `montlySearch`、`competition`/`competitionV2`、`averageCpc` 等),脚本过滤(如「约 3000 搜索量、竞争中低」)后再交付表格。
116
+ 2. **必走 CLI,一次 `-k`**:`siluzan-tso keyword -k "种子1,种子2,..." [--url "<落地页>"] [--geo <id>] --google-only [--min-monthly-search <下限>]`。要官方 Planner 指标时 **必加 `--google-only`**。用户要有搜索热度时 `--min-monthly-search 1`。用户没点名国家时不要 `--geo`,也不要 `keyword geo-list`。
117
+ 3. **网址/文章**:可用 WebFetch 读页面 **仅归纳种子词与产品语境**。**月搜索量 / 竞争度 / CPC 只能来自这次 `keyword` 命令的输出**(`montlySearch`、`competition`/`competitionV2`、`averageCpc`)。搜索量下限用 `--min-monthly-search`,不要再写脚本把同一批词滤好几轮。
118
118
  4. **交付列**(用户未指定时):英文关键词、中文翻译、所属核心词、月搜索量、竞争度、**目标市场**。目标市场抄落盘 JSON 的 `targetMarket.label`,表题写明 **不是全球**。表头注明 **数据来源:Google Keyword Planner(`keywordidea/google`)**。
119
119
 
120
120
  ### C.3 与 W3 / P8 / P9 区分
@@ -131,6 +131,8 @@
131
131
  - **禁止**跳过 `keyword`,用 WebSearch / 模型臆测 **月搜索量、竞争度** 充当终稿。
132
132
  - **禁止**因用户未提「丝路赞 / TSO / 账户 ID」就认为不适用本 skill。
133
133
  - **禁止**把「阅读文章归纳行业词」当作 Planner 指标来源(文章 → 种子;指标 → CLI)。
134
+ - **禁止**把种子拆成多批 `-k`,或为洗词反复写 Python / Node。某个种子没有量时只补一次。
135
+ - **禁止**在用户没点名国家时调用 `keyword geo-list` 或默认加上美国 `--geo 2840`。
134
136
 
135
137
  ### C.5 示例(全部 → W5,必走 `keyword` CLI)
136
138
 
@@ -118,8 +118,8 @@
118
118
  - **必读**:`references/analytics/keyword-planner-workflows.md`;客户/品牌背景先 `references/analytics/rag.md`。
119
119
  - **步骤**:
120
120
  1. (可选)WebFetch 读用户 URL/文章 **仅归纳种子词**;或 RAG:`rag list --rag-only --json-out ./snap` → `rag query … --json-out ./snap`。
121
- 2. 拓词(**必 `--google-only --json-out`**):`keyword -k "种子1,种子2,..." [--url "<落地页>"] [--geo <id>] --google-only --json-out ./snap-kw`;**多核心词分批** `-k`(每批 3–8 词),避免单次过大。
122
- 3. 脚本读落盘 `items`(`montlySearch`/`averageCpc`/`competition`,币种见 `bidAmountCurrency`)和根上的 **`targetMarket.label`** → 按用户阈值洗词(如搜索量≈3000、竞争中低)→ 去重/分组/截 Top N,标注 **数据来源:Google Keyword Planner**,并写明 **目标市场(不是全球)**。
121
+ 2. 拓词(**必 `--google-only`**,种子放进同一次 `-k`):`keyword -k "种子1,种子2,..." [--url "<落地页>"] [--geo <id>] --google-only [--min-monthly-search <下限>]`。用户要有搜索热度时下限用 `1`。用户没点名国家时不要 `--geo`,也不要 `keyword geo-list`。
122
+ 3. 命令打印的表就是交付物(含 `montlySearch` / `averageCpc` / `competition`)。不要再写脚本按品牌洗词。某个种子没有量时只为它再补一次 `-k`。标注 **数据来源:Google Keyword Planner**。传了 `--geo` 时写明 **目标市场(不是全球)**,抄 `targetMarket.label`。
123
123
  - **产物**:表格列含英文词、中文翻译、所属核心词、月搜索量、竞争度、**目标市场**(`targetMarket.label`,并写明不是全球)。指标**仅**来自 CLI;联网/文章语境与 Planner 指标**分列标注**;账户内 `google-analysis keywords` 表现**不可**与市场侧拓词合并。完整 campaign 见 **W3**。
124
124
 
125
125
  ---
@@ -249,7 +249,7 @@ siluzan-tso keyword -k <搜索词> [-a <mediaCustomerId>] [--geo <geoTargetConst
249
249
  siluzan-tso keyword geo-list [--country-code <US,CN,...>] [--name-contains <text>] [--json-out ./snap]
250
250
  ```
251
251
 
252
- `keyword --json-out` 的根字段 **`targetMarket.label`** 是这次搜索量所属的目标市场(如「美国(2840)」)。没传 `--geo` 时为「未限定国家」。交给用户的表要带上这个市场,并写明 **不是全球**。`--geo` 传多个 ID(如 `2840,2826`)时,返回的搜索量/CPC/竞争度为**跨所传地区的汇总数据**,响应中**无**按地区拆分的字段。若要分别查看各市场指标,须**多次调用**且每次 `--geo` **只传一个** ID(详见 **`references/analytics/keyword-planner-workflows.md`**「多地区 `--geo`」)。
252
+ `keyword --json-out` 的根字段 **`targetMarket.label`** 是这次搜索量所属的目标市场(如「美国(2840)」)。没传 `--geo` 时为「未限定国家」。交给用户的表要带上这个市场,并写明 **不是全球**。`--geo` 传多个 ID(如 `2840,2156`)时,返回的搜索量/CPC/竞争度为**跨所传地区的汇总数据**,响应中**无**按地区拆分的字段。若要分别查看各市场指标,须**多次调用**且每次 `--geo` **只传一个** ID(详见 **`references/analytics/keyword-planner-workflows.md`**「多地区 `--geo`」)。
253
253
 
254
254
  `--url` 触发网址拓词(`websitereco`)并合并进结果;与 `--google-only` 互斥(仅 Google Keyword Planner 时用后者)。`--include`/`--exclude` 为本地过滤。仅 Google、不联网搜索的 Agent 编排见 **`references/analytics/keyword-planner-workflows.md`**「分支 B」。
255
255
 
@@ -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.58-beta.5'
12
+ $PKG_VERSION = '1.1.59-beta.1'
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.58-beta.5"
12
+ readonly PKG_VERSION="1.1.59-beta.1"
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.58-beta.5",
3
+ "version": "1.1.59-beta.1",
4
4
  "description": "Siluzan 广告账户管理 CLI — 查询账户、余额、消耗数据,管理绑定关系与充值。",
5
5
  "keywords": [
6
6
  "ad-account",