siluzan-tso-cli 1.1.29-beta.14 → 1.1.29-beta.15
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 +1 -1
- package/dist/index.js +51 -39
- package/dist/skill/_meta.json +2 -2
- package/dist/skill/assets/campaign-create-template.md +0 -4
- package/dist/skill/references/core/agent-conventions.md +0 -9
- package/dist/skill/references/google-ads/google-ads-campaign-plan.md +0 -19
- package/dist/skill/references/google-ads/rules/google-ads-keyword-taxonomy.md +0 -16
- package/dist/skill/scripts/install.ps1 +1 -1
- package/dist/skill/scripts/install.sh +1 -1
- package/package.json +1 -1
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.29-beta.
|
|
54
|
+
> **注意**:当前为测试版(1.1.29-beta.15),供内部测试使用。正式发布后安装命令将改为 `npm install -g siluzan-tso-cli`。
|
|
55
55
|
|
|
56
56
|
| 助手 | 建议 `--ai` |
|
|
57
57
|
| ----------------------- | ------------------------------------ |
|
package/dist/index.js
CHANGED
|
@@ -105394,6 +105394,18 @@ async function fetchAllAccountPages(media, pageSize, maxPages, config, verbose)
|
|
|
105394
105394
|
}
|
|
105395
105395
|
|
|
105396
105396
|
// src/commands/balance-scan/run.ts
|
|
105397
|
+
function balanceScanChunkSize(media) {
|
|
105398
|
+
switch (media) {
|
|
105399
|
+
case "BingV2":
|
|
105400
|
+
case "TikTok":
|
|
105401
|
+
case "Yandex":
|
|
105402
|
+
return 10;
|
|
105403
|
+
case "Kwai":
|
|
105404
|
+
return 20;
|
|
105405
|
+
default:
|
|
105406
|
+
return 100;
|
|
105407
|
+
}
|
|
105408
|
+
}
|
|
105397
105409
|
async function runBalanceScan(opts) {
|
|
105398
105410
|
let config = loadConfig(opts.token);
|
|
105399
105411
|
if (opts.refreshDp) {
|
|
@@ -105452,59 +105464,54 @@ async function runBalanceScan(opts) {
|
|
|
105452
105464
|
let balanceMap = /* @__PURE__ */ new Map();
|
|
105453
105465
|
let overviewMap = /* @__PURE__ */ new Map();
|
|
105454
105466
|
if (validIds.length > 0) {
|
|
105455
|
-
const
|
|
105467
|
+
const chunkSize = balanceScanChunkSize(media);
|
|
105456
105468
|
const chunks = [];
|
|
105457
|
-
for (let i = 0; i < validIds.length; i +=
|
|
105469
|
+
for (let i = 0; i < validIds.length; i += chunkSize) {
|
|
105470
|
+
chunks.push(validIds.slice(i, i + chunkSize));
|
|
105471
|
+
}
|
|
105458
105472
|
process.stderr.write(
|
|
105459
|
-
`\u23F3 [balance-scan] \u6709\u6548\u8D26\u6237 ${validIds.length} \u4E2A\uFF0C\u5206 ${chunks.length} \u6279\
|
|
105473
|
+
`\u23F3 [balance-scan] \u6709\u6548\u8D26\u6237 ${validIds.length} \u4E2A\uFF0C\u5206 ${chunks.length} \u6279\uFF08\u6BCF\u6279 \u2264${chunkSize} \u6237\uFF09\uFF1B\u6309 Web \u8D26\u6237\u5217\u8868\u53E3\u5F84\u4E32\u884C\u62C9\u53D6\u6D88\u8017 \u2192 \u4F59\u989D\uFF08\u5355\u8BF7\u6C42\u6700\u957F\u7EA6 10 \u5206\u949F\uFF09\u3002
|
|
105460
105474
|
`
|
|
105461
105475
|
);
|
|
105462
|
-
|
|
105476
|
+
for (let chunkIdx = 0; chunkIdx < chunks.length; chunkIdx++) {
|
|
105477
|
+
const ids = chunks[chunkIdx];
|
|
105463
105478
|
process.stderr.write(
|
|
105464
|
-
` \
|
|
105479
|
+
` \u2192 [\u8FD17\u65E5\u6D88\u8017] \u7B2C ${chunkIdx + 1}/${chunks.length} \u6279\u8BF7\u6C42\u4E2D\uFF08${ids.length} \u6237\uFF09\u2026
|
|
105465
105480
|
`
|
|
105466
105481
|
);
|
|
105467
|
-
|
|
105468
|
-
|
|
105482
|
+
const overviewChunk = await fetchOverviewMap(
|
|
105483
|
+
media,
|
|
105484
|
+
ids,
|
|
105485
|
+
config,
|
|
105486
|
+
void 0,
|
|
105487
|
+
void 0,
|
|
105488
|
+
opts.verbose
|
|
105489
|
+
);
|
|
105469
105490
|
process.stderr.write(
|
|
105470
|
-
` \u2713 [\u8FD17\u65E5\u6D88\u8017] \u7B2C ${
|
|
105491
|
+
` \u2713 [\u8FD17\u65E5\u6D88\u8017] \u7B2C ${chunkIdx + 1}/${chunks.length} \u6279\u5B8C\u6210\uFF08${ids.length} \u6237 \u2192 ${overviewChunk.size} \u6761\uFF09
|
|
105471
105492
|
`
|
|
105472
105493
|
);
|
|
105473
|
-
|
|
105474
|
-
|
|
105475
|
-
|
|
105476
|
-
chunks.map((ids, chunkIdx) => {
|
|
105477
|
-
process.stderr.write(
|
|
105478
|
-
` \u2192 [\u4F59\u989D] \u7B2C ${chunkIdx + 1}/${chunks.length} \u6279\u8BF7\u6C42\u4E2D\uFF08${ids.length} \u6237\uFF09\u2026
|
|
105494
|
+
for (const [k, v] of overviewChunk) overviewMap.set(k, v);
|
|
105495
|
+
process.stderr.write(
|
|
105496
|
+
` \u2192 [\u4F59\u989D] \u7B2C ${chunkIdx + 1}/${chunks.length} \u6279\u8BF7\u6C42\u4E2D\uFF08${ids.length} \u6237\uFF09\u2026
|
|
105479
105497
|
`
|
|
105480
|
-
|
|
105481
|
-
|
|
105482
|
-
|
|
105483
|
-
|
|
105484
|
-
|
|
105485
|
-
|
|
105486
|
-
|
|
105487
|
-
|
|
105488
|
-
)
|
|
105489
|
-
|
|
105490
|
-
chunks.
|
|
105491
|
-
process.stderr.write(
|
|
105492
|
-
` \u2192 [\u8FD17\u65E5\u6D88\u8017] \u7B2C ${chunkIdx + 1}/${chunks.length} \u6279\u8BF7\u6C42\u4E2D\uFF08${ids.length} \u6237\uFF09\u2026
|
|
105498
|
+
);
|
|
105499
|
+
const balanceChunk = await fetchBalanceMap(
|
|
105500
|
+
media,
|
|
105501
|
+
ids,
|
|
105502
|
+
config,
|
|
105503
|
+
void 0,
|
|
105504
|
+
void 0,
|
|
105505
|
+
opts.verbose
|
|
105506
|
+
);
|
|
105507
|
+
process.stderr.write(
|
|
105508
|
+
` \u2713 [\u4F59\u989D] \u7B2C ${chunkIdx + 1}/${chunks.length} \u6279\u5B8C\u6210\uFF08${ids.length} \u6237 \u2192 ${balanceChunk.size} \u6761\uFF09
|
|
105493
105509
|
`
|
|
105494
|
-
|
|
105495
|
-
|
|
105496
|
-
|
|
105497
|
-
logOverviewChunk(chunkIdx, ids, m);
|
|
105498
|
-
return m;
|
|
105499
|
-
}
|
|
105500
|
-
);
|
|
105501
|
-
})
|
|
105502
|
-
)
|
|
105503
|
-
]);
|
|
105510
|
+
);
|
|
105511
|
+
for (const [k, v] of balanceChunk) balanceMap.set(k, v);
|
|
105512
|
+
}
|
|
105504
105513
|
process.stderr.write(`\u23F3 [balance-scan] \u4F59\u989D\u4E0E\u6D88\u8017\u5DF2\u9F50\uFF0C\u6B63\u5728\u6309\u9608\u503C\u7B5B\u9009\u2026
|
|
105505
105514
|
`);
|
|
105506
|
-
for (const m of bMaps) for (const [k, v] of m) balanceMap.set(k, v);
|
|
105507
|
-
for (const m of oMaps) for (const [k, v] of m) overviewMap.set(k, v);
|
|
105508
105515
|
}
|
|
105509
105516
|
const evaluated = [];
|
|
105510
105517
|
for (const item of allItems) {
|
|
@@ -105561,6 +105568,7 @@ async function runBalanceScan(opts) {
|
|
|
105561
105568
|
},
|
|
105562
105569
|
pageSize,
|
|
105563
105570
|
maxPages,
|
|
105571
|
+
batchChunkSize: validIds.length > 0 ? balanceScanChunkSize(media) : null,
|
|
105564
105572
|
totalReported: total ?? null,
|
|
105565
105573
|
generatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
105566
105574
|
};
|
|
@@ -105636,6 +105644,9 @@ function register9(program2) {
|
|
|
105636
105644
|
).requiredOption(
|
|
105637
105645
|
"-m, --media <type>",
|
|
105638
105646
|
"\u5A92\u4F53\u7C7B\u578B\uFF1AGoogle | TikTok | Yandex | BingV2 | Kwai\uFF08MetaAd \u63A5\u53E3\u672A\u5F00\u653E\u4F59\u989D\u67E5\u8BE2\uFF09"
|
|
105647
|
+
).option(
|
|
105648
|
+
"-a, --accounts <ids>",
|
|
105649
|
+
"\u6307\u5B9A mediaCustomerId\uFF08\u9017\u53F7\u5206\u9694\uFF09\uFF1B\u8DF3\u8FC7\u6E05\u5355\u7FFB\u9875\uFF0C\u62C9\u53D6\u540E\u5168\u90E8\u8F93\u51FA\uFF08\u4E0D\u6309\u9608\u503C\u8FC7\u6EE4\uFF09"
|
|
105639
105650
|
).option(
|
|
105640
105651
|
"--threshold-days <n>",
|
|
105641
105652
|
"\u5269\u4F59\u7EED\u822A\u5929\u6570\u9608\u503C\uFF08\u9ED8\u8BA4 7\uFF0C\u6309\u8FD1 7 \u65E5\u65E5\u5747\u6D88\u8017\u4F30\u7B97\uFF09",
|
|
@@ -105661,6 +105672,7 @@ function register9(program2) {
|
|
|
105661
105672
|
await runBalanceScan({
|
|
105662
105673
|
token: opts.token,
|
|
105663
105674
|
media: opts.media,
|
|
105675
|
+
accounts: opts.accounts,
|
|
105664
105676
|
thresholdDays: opts.thresholdDays,
|
|
105665
105677
|
minBalance: opts.minBalance,
|
|
105666
105678
|
minDailySpend: opts.minDailySpend,
|
package/dist/skill/_meta.json
CHANGED
|
@@ -247,11 +247,7 @@ siluzan-tso ad batch diff --batch-id <taskId> --config-file ./campaign.json --js
|
|
|
247
247
|
| 基础 | `customerName` / `campaign` 非空;`Budget > 0`;地理/语言至少 1 项 |
|
|
248
248
|
| 网络 | `TargetPartnerSearchNetwork` 须 false;不可同时关闭 Google 搜索与搜索网络 |
|
|
249
249
|
| RSA / 关键词 / 附加信息 | 标题 **15** 条、描述 **4** 条(须写满);字符上限、词面非空;RSA `Path1`/`Path2` 必填;SITELINK 行长度限制 |
|
|
250
|
-
<<<<<<< HEAD
|
|
251
250
|
| 否词误填 | `KeywordsForBatchJob` 含常见否词词根或与 `NegativeKeywordsForBatchJob` 重复 → **warnings**(不阻断,须 Agent 修正后再 create) |
|
|
252
251
|
| 实务 | 日期格式与先后、出价策略与配套字段一致 |
|
|
253
|
-
=======
|
|
254
|
-
| 实务 | 日期格式与先后、出价策略与配套字段一致 |
|
|
255
|
-
>>>>>>> b58a64bcff40d4987fd54f6ad3e0b79061bf833c
|
|
256
252
|
|
|
257
253
|
`ad campaign-validate` 通过不保证 BatchJob 成功(例如仅写 `DestinationUrl` 未写 `Finalurl` 时 validate 仍可能 ✅)。异步结果用 `ad batch get` 轮询;`HasFailed` / 部分失败时用 `ad batch diff` 对照 JSON 补缺,系列级失败时改 JSON 重提,勿在半成品上反复整包创建。写操作须 `--commit`,见 `references/google-ads/google-ads.md` § ad campaign-create。
|
|
@@ -23,7 +23,6 @@
|
|
|
23
23
|
|
|
24
24
|
### Skill 内 Read 路径约定
|
|
25
25
|
|
|
26
|
-
<<<<<<< HEAD
|
|
27
26
|
| 类型 | 正确路径(相对 Skill 根目录) | 说明 |
|
|
28
27
|
| ---- | ----------------------------- | ---- |
|
|
29
28
|
| 命令 reference | `references/<域>/<文件>.md` | 如 `references/analytics/account-analytics.md` |
|
|
@@ -31,14 +30,6 @@
|
|
|
31
30
|
| JSON 契约模板(结构) | `assets/*-template.json`、`assets/*.schema.json` 等 | **先 Read**;如 `assets/campaign-create-template.json` |
|
|
32
31
|
| 契约说明 / 规则 | `assets/<文件>.md` | 与上表 JSON **成对** Read;如 `assets/campaign-create-template.md` |
|
|
33
32
|
| HTML 终稿模板 | `report-templates/*.html` | 由 CLI `render` 使用,Agent 通常只 Read 对应 `.md` 纲要 |
|
|
34
|
-
=======
|
|
35
|
-
| 类型 | 正确路径(相对 Skill 根目录) | 说明 |
|
|
36
|
-
| ---------------- | --------------------------------------- | -------------------------------------------------------- |
|
|
37
|
-
| 命令 reference | `references/<域>/<文件>.md` | 如 `references/analytics/account-analytics.md` |
|
|
38
|
-
| 报告纲要 | `references/report-templates/<文件>.md` | 如 `references/report-templates/google-period-report.md` |
|
|
39
|
-
| JSON 契约 / 规则 | `assets/<文件>.md` | 如 `assets/website-diagnosis-rules.md` |
|
|
40
|
-
| HTML 终稿模板 | `report-templates/*.html` | 由 CLI `render` 使用,Agent 通常只 Read 对应 `.md` 纲要 |
|
|
41
|
-
>>>>>>> b58a64bcff40d4987fd54f6ad3e0b79061bf833c
|
|
42
33
|
|
|
43
34
|
路由表若写 `analytics/…` 或 `report-templates/…` 而无 `references/` 前缀,**Read 时仍须加上 `references/`**(`assets/`、`report-templates/*.html` 除外)。
|
|
44
35
|
|
|
@@ -21,7 +21,6 @@
|
|
|
21
21
|
|
|
22
22
|
## 标准流水线
|
|
23
23
|
|
|
24
|
-
<<<<<<< HEAD
|
|
25
24
|
| 步 | 动作 | 文档/命令 |
|
|
26
25
|
|----|------|-----------|
|
|
27
26
|
| 1 | `list-accounts` 锁定 `account` / `customerName` / 币种 | `references/accounts/currency.md` |
|
|
@@ -36,20 +35,6 @@
|
|
|
36
35
|
| 10 | 输出所有失败的内容与原因,并询问用户是否需要修改后单独添加到系列中如果用户要求是则读取 `references\google-ads/google-ads.md` 来获取对应缺失部分的创建命令 |
|
|
37
36
|
|
|
38
37
|
|
|
39
|
-
=======
|
|
40
|
-
| 步 | 动作 | 文档/命令 |
|
|
41
|
-
| --- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ | ---------------------------------------------------------------------- |
|
|
42
|
-
| 1 | `list-accounts` 锁定 `account` / `customerName` / 币种 | `references/accounts/currency.md` |
|
|
43
|
-
| 2 | 可选 `rag query`;`keyword` / `keyword geo-list` 拓词 | `references/analytics/keyword-planner-workflows.md` |
|
|
44
|
-
| 3 | 按分层规则写入 `KeywordsForBatchJob`(Exact/Phrase/Broad) | `google-ads/rules/google-ads-keyword-taxonomy.md`(参考,非 CLI 强制) |
|
|
45
|
-
| 4 | 填 `campaign`(预算/出价/地域/否词≥20/RSA/附加信息) | `assets/campaign-create-template.md` |
|
|
46
|
-
| 5 | **`ad campaign-validate --config-file <json>`**(失败只改 JSON;超长见下文「超长人工确认」) | 下文「校验」 |
|
|
47
|
-
| 6 | 输出:**JSON 代码块** → **Markdown**(`google-ads-launch-plan-template.md` 正文)→ 待确认 | — |
|
|
48
|
-
| 7 | 用户确认后 **`ad campaign-create`** | `google-ads/google-ads.md` |
|
|
49
|
-
| 8 | 每隔5s 获取创建结果 | `ad batch get --id <taskId> --config-file ./campaign.json` |
|
|
50
|
-
| 9 | 创建失败根据失败原因修改json重新走创建流程,部分成功/成功/部分失败:都调用来做最后一步调整 `ad batch diff --batch-id <taskId> --config-file ./campaign.json` | |
|
|
51
|
-
| 10 | 输出所有失败的内容与原因,并询问用户是否需要修改后单独添加到系列中如果用户要求是则读取 `references\google-ads/google-ads.md` 来获取对应缺失部分的创建命令 |
|
|
52
|
-
>>>>>>> b58a64bcff40d4987fd54f6ad3e0b79061bf833c
|
|
53
38
|
|
|
54
39
|
多系列:每系列一个 JSON;可选 `campaign-manifest.json`(`role: brand|competitor|generic`)仅作文件组织参考。
|
|
55
40
|
|
|
@@ -66,11 +51,7 @@
|
|
|
66
51
|
| `google-ads/rules/sensitive-industries.md` | 敏感行业(若相关) |
|
|
67
52
|
| `google-ads/rules/google-ads-launch-plan-template.md` | 用户可见 Markdown 结构与 RSA/否词表 |
|
|
68
53
|
| `google-ads/rules/google-ads-creative-optimization.md` | RSA 创意主题;`campaign-validate` 强制 **15** 标题 + **4** 描述 |
|
|
69
|
-
<<<<<<< HEAD
|
|
70
54
|
| **`assets/campaign-create-template.json`** + `assets/campaign-create-template.md` | JSON 结构(先 Read `.json`)+ 字段说明 |
|
|
71
|
-
=======
|
|
72
|
-
| `assets/campaign-create-template.md` | JSON 字段契约 |
|
|
73
|
-
>>>>>>> b58a64bcff40d4987fd54f6ad3e0b79061bf833c
|
|
74
55
|
|
|
75
56
|
### 按需(触及时再读)
|
|
76
57
|
|
|
@@ -7,7 +7,6 @@
|
|
|
7
7
|
|
|
8
8
|
## 结构数量(每广告系列 / 每广告组)
|
|
9
9
|
|
|
10
|
-
<<<<<<< HEAD
|
|
11
10
|
| 模块 | 规则 | 建议数量 | 示例 |
|
|
12
11
|
|------|------|----------|------|
|
|
13
12
|
| Campaign | 按产品线拆分 | 3–10 个系列(多文件 + `campaign-manifest.json`) | Payment Gateway / CRM |
|
|
@@ -31,21 +30,6 @@
|
|
|
31
30
|
| 品牌系列 | 独立 Campaign | manifest `role: brand` | company crm |
|
|
32
31
|
| 竞品系列 | 独立 Campaign | manifest `role: competitor` | stripe alternative |
|
|
33
32
|
| Search Terms | 运营节奏 | 每周检查 | `ad search-terms` |
|
|
34
|
-
=======
|
|
35
|
-
| 模块 | 规则 | 建议数量 | 示例 |
|
|
36
|
-
| ------------ | ------------------ | ------------------------------------------------ | ----------------------- |
|
|
37
|
-
| Campaign | 按产品线拆分 | 3–10 个系列(多文件 + `campaign-manifest.json`) | Payment Gateway / CRM |
|
|
38
|
-
| Ad Group | 一个搜索意图一组 | 每组 5–20 个词 | Payment API Integration |
|
|
39
|
-
| 核心词 | 高商业意图 | 每组 **5–15** | payment api pricing |
|
|
40
|
-
| 长尾词 | 场景明确的长 query | 每组 **10–25** | crm for manufacturing |
|
|
41
|
-
| Exact Match | 核心高转化 | 每组 **2–8** 条 | [stripe alternative] |
|
|
42
|
-
| Phrase Match | 主流量 | 每组 **3–10** 条 | "payment solution" |
|
|
43
|
-
| Broad Match | 少量测试 | 每组 **1–3** 条 | payment platform |
|
|
44
|
-
| 否定关键词 | 基础否词库 | 系列级建议 **≥20** | free / jobs / tutorial |
|
|
45
|
-
| 品牌系列 | 独立 Campaign | manifest `role: brand` | company crm |
|
|
46
|
-
| 竞品系列 | 独立 Campaign | manifest `role: competitor` | stripe alternative |
|
|
47
|
-
| Search Terms | 运营节奏 | 每周检查 | `ad search-terms` |
|
|
48
|
-
>>>>>>> b58a64bcff40d4987fd54f6ad3e0b79061bf833c
|
|
49
33
|
|
|
50
34
|
### 初始匹配类型占比(按组内词条数)
|
|
51
35
|
|
|
@@ -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.29-beta.
|
|
12
|
+
$PKG_VERSION = '1.1.29-beta.15'
|
|
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.29-beta.
|
|
12
|
+
readonly PKG_VERSION="1.1.29-beta.15"
|
|
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"
|