siluzan-tso-cli 1.1.36-beta.1 → 1.1.36-beta.2
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 +72 -11
- package/dist/skill/_meta.json +2 -2
- package/dist/skill/references/analytics/account-analytics.md +13 -1
- package/dist/skill/references/core/agent-conventions.md +5 -0
- package/dist/skill/references/report-templates/bing-period-report.md +20 -2
- package/dist/skill/report-templates/bing-period-report.md +20 -2
- 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.36-beta.
|
|
54
|
+
> **注意**:当前为测试版(1.1.36-beta.2),供内部测试使用。正式发布后安装命令将改为 `npm install -g siluzan-tso-cli`。
|
|
55
55
|
|
|
56
56
|
| 助手 | 建议 `--ai` |
|
|
57
57
|
| ----------------------- | ------------------------------------ |
|
package/dist/index.js
CHANGED
|
@@ -106735,7 +106735,7 @@ async function writeReportAnalysisSnapshot(params) {
|
|
|
106735
106735
|
);
|
|
106736
106736
|
await fs8.writeFile(
|
|
106737
106737
|
path12.join(absDir, outlineFileName),
|
|
106738
|
-
`${formatOutlineFileBody(fileName, params.payload)}
|
|
106738
|
+
`${formatOutlineFileBody(fileName, params.payload, params.outlineExtraHints)}
|
|
106739
106739
|
`,
|
|
106740
106740
|
"utf8"
|
|
106741
106741
|
);
|
|
@@ -127807,6 +127807,55 @@ function syncOverviewBalanceFields(record) {
|
|
|
127807
127807
|
return out;
|
|
127808
127808
|
}
|
|
127809
127809
|
|
|
127810
|
+
// src/commands/bing-analysis/normalize-bing-rates.ts
|
|
127811
|
+
var RATE_FIELD_NAMES2 = /* @__PURE__ */ new Set(["ctr", "conversionRate"]);
|
|
127812
|
+
var BING_RATE_BEARING_SECTIONS = /* @__PURE__ */ new Set([
|
|
127813
|
+
"overview",
|
|
127814
|
+
"device",
|
|
127815
|
+
"geographic",
|
|
127816
|
+
"age-audience",
|
|
127817
|
+
"gender-audience",
|
|
127818
|
+
"audience-merged",
|
|
127819
|
+
"campaigns",
|
|
127820
|
+
"ad-groups",
|
|
127821
|
+
"ads",
|
|
127822
|
+
"keywords",
|
|
127823
|
+
"search-terms"
|
|
127824
|
+
]);
|
|
127825
|
+
function divIfFiniteNumber2(v) {
|
|
127826
|
+
return typeof v === "number" && Number.isFinite(v) ? v / 100 : v;
|
|
127827
|
+
}
|
|
127828
|
+
function divideRatesInPlace2(value, seen) {
|
|
127829
|
+
if (value === null || typeof value !== "object") return;
|
|
127830
|
+
if (seen.has(value)) return;
|
|
127831
|
+
seen.add(value);
|
|
127832
|
+
if (Array.isArray(value)) {
|
|
127833
|
+
for (const item of value) divideRatesInPlace2(item, seen);
|
|
127834
|
+
return;
|
|
127835
|
+
}
|
|
127836
|
+
const obj = value;
|
|
127837
|
+
for (const k of Object.keys(obj)) {
|
|
127838
|
+
if (RATE_FIELD_NAMES2.has(k)) {
|
|
127839
|
+
obj[k] = divIfFiniteNumber2(obj[k]);
|
|
127840
|
+
} else {
|
|
127841
|
+
divideRatesInPlace2(obj[k], seen);
|
|
127842
|
+
}
|
|
127843
|
+
}
|
|
127844
|
+
}
|
|
127845
|
+
function normalizeBingRateScales(payload, section) {
|
|
127846
|
+
if (!BING_RATE_BEARING_SECTIONS.has(section)) return payload;
|
|
127847
|
+
divideRatesInPlace2(payload, /* @__PURE__ */ new WeakSet());
|
|
127848
|
+
return payload;
|
|
127849
|
+
}
|
|
127850
|
+
var BING_RATE_NORMALIZED_OUTLINE_HINTS = [
|
|
127851
|
+
"// \u6982\u7387\u5B57\u6BB5\uFF1A`ctr` / `conversionRate` \u5DF2\u7531 bing-analysis CLI \u4ECE\u7F51\u5173\u767E\u5206\u6570\u523B\u5EA6\u5F52\u4E00\u4E3A **0~1 \u5C0F\u6570**\uFF08\u5982 `0.0074` = 0.74%\uFF09\u3002",
|
|
127852
|
+
"// \u5199\u300Cx%\u300D\u6587\u6848\uFF1A`(v * 100).toFixed(2) + '%'`\uFF1B**\u7981\u6B62**\u518D \xF7100\uFF0C\u4E5F**\u7981\u6B62**\u628A JSON \u6570\u503C\u5F53\u300C\u5DF2\u662F\u767E\u5206\u6570\u300D\u76F4\u63A5\u52A0 `%`\uFF08\u4F1A \xD7100 \u9519\u8BEF\uFF0C\u5982 0.74% \u663E\u793A\u6210 74%\uFF09\u3002"
|
|
127853
|
+
];
|
|
127854
|
+
function buildBingOutlineHints(section) {
|
|
127855
|
+
if (!BING_RATE_BEARING_SECTIONS.has(section)) return void 0;
|
|
127856
|
+
return BING_RATE_NORMALIZED_OUTLINE_HINTS;
|
|
127857
|
+
}
|
|
127858
|
+
|
|
127810
127859
|
// src/commands/bing-analysis/fetch.ts
|
|
127811
127860
|
var BING_KEYWORD_LIMIT_DEFAULT = 100;
|
|
127812
127861
|
function stripLocalDate(d) {
|
|
@@ -127919,7 +127968,10 @@ async function fetchBingOverviewPayload(config, id, startDate, endDate, verbose)
|
|
|
127919
127968
|
endDate,
|
|
127920
127969
|
verbose
|
|
127921
127970
|
);
|
|
127922
|
-
return
|
|
127971
|
+
return normalizeBingSectionPayload(
|
|
127972
|
+
syncOverviewBalanceFields(withPrevious),
|
|
127973
|
+
"overview"
|
|
127974
|
+
);
|
|
127923
127975
|
}
|
|
127924
127976
|
async function enrichBingOverviewPreviousPeriod(config, accountId, record, startDate, endDate, verbose) {
|
|
127925
127977
|
if (!isBingPeriodBlockEmpty(record.previousPeriod)) {
|
|
@@ -127963,13 +128015,16 @@ async function fetchBingAudienceMergedPayload(config, id, startDate, endDate, ve
|
|
|
127963
128015
|
fetchBingJson(config, ageUrl, verbose),
|
|
127964
128016
|
fetchBingJson(config, genderUrl, verbose)
|
|
127965
128017
|
]);
|
|
127966
|
-
return
|
|
127967
|
-
|
|
127968
|
-
|
|
127969
|
-
|
|
127970
|
-
|
|
127971
|
-
|
|
127972
|
-
|
|
128018
|
+
return normalizeBingSectionPayload(
|
|
128019
|
+
{
|
|
128020
|
+
mergedParts: ["AgeAudienceData", "GenderAudienceData"],
|
|
128021
|
+
startDate,
|
|
128022
|
+
endDate,
|
|
128023
|
+
account: id,
|
|
128024
|
+
data: { ageAudience: ageData, genderAudience: genderData }
|
|
128025
|
+
},
|
|
128026
|
+
"audience-merged"
|
|
128027
|
+
);
|
|
127973
128028
|
}
|
|
127974
128029
|
async function fetchBingSectionPayload(def, opts, config, id) {
|
|
127975
128030
|
const { startDate, endDate } = resolveBingDateRange(opts.start, opts.end);
|
|
@@ -127986,7 +128041,12 @@ async function fetchBingSectionPayload(def, opts, config, id) {
|
|
|
127986
128041
|
params.set("orderByCost", "true");
|
|
127987
128042
|
}
|
|
127988
128043
|
const url = reportingUrl(config, id, def.segment, params.toString());
|
|
127989
|
-
|
|
128044
|
+
const raw = await fetchBingJson(config, url, verbose);
|
|
128045
|
+
return normalizeBingRateScales(raw, def.name);
|
|
128046
|
+
}
|
|
128047
|
+
function normalizeBingSectionPayload(payload, section) {
|
|
128048
|
+
if (payload === null || typeof payload !== "object") return payload;
|
|
128049
|
+
return normalizeBingRateScales(payload, section);
|
|
127990
128050
|
}
|
|
127991
128051
|
function endpointHintForBingSection(def) {
|
|
127992
128052
|
return `GET \u2026/BingV2/{id}/${def.segment}`;
|
|
@@ -128045,7 +128105,8 @@ async function runAllBingSections(opts) {
|
|
|
128045
128105
|
accountId: id,
|
|
128046
128106
|
dateRange: { start: startDate, end: endDate },
|
|
128047
128107
|
payload,
|
|
128048
|
-
cliVersion
|
|
128108
|
+
cliVersion,
|
|
128109
|
+
outlineExtraHints: buildBingOutlineHints(def.name)
|
|
128049
128110
|
});
|
|
128050
128111
|
return {
|
|
128051
128112
|
section: def.name,
|
package/dist/skill/_meta.json
CHANGED
|
@@ -319,7 +319,7 @@ siluzan-tso tiktok-analysis -a 1234567890 --start 2026-03-01 --end 2026-03-31 \
|
|
|
319
319
|
|
|
320
320
|
## Bing(BingV2)账户分析
|
|
321
321
|
|
|
322
|
-
> **日期限制**:Bing 报表不能包含今天或昨天。省略时 CLI 默认截至前天的近 7
|
|
322
|
+
> **日期限制**:Bing 报表不能包含今天或昨天。省略时 CLI 默认截至前天的近 7 天。用户要**已结束的完整自然月**(如「6月份」)→ `--start` 当月 1 日、`--end` 当月最后一天(6 月 = `06-30`,**禁止**减 1 天),见 `report-templates/bing-period-report.md` §日期规则。
|
|
323
323
|
|
|
324
324
|
与 `google-analysis` / `facebook-analysis` 同架构:`bing-analysis -a … --json-out …`(省略子命令名默认执行 `run`,批量拉取全部维度或 `--sections` 指定子集)。
|
|
325
325
|
|
|
@@ -343,6 +343,18 @@ siluzan-tso bing-analysis -a <mediaCustomerId> --start 2026-03-01 --end 2026-03-
|
|
|
343
343
|
|
|
344
344
|
报告模板:`report-templates/bing-period-report.md`(**每个 section 须写「分析」**;**余额**:`overview` section 落盘 JSON 常自动校正 0 快照,读 `balance`/`remainingAccountBudget` 或 `balance` 命令;**环比**:网关 `previousPeriod` 常空,CLI 二次拉上一周期回填)。
|
|
345
345
|
|
|
346
|
+
### 点击率 / 转化率口径(必读)
|
|
347
|
+
|
|
348
|
+
Bing 的 `ctr` / `conversionRate` 为 0~1 小数**(`0.007434` = 0.74%),与 Google `schemaVersion ≥ 2` 一致。
|
|
349
|
+
|
|
350
|
+
| 场景 | 正确写法 | 错误写法 |
|
|
351
|
+
| ---- | -------- | -------- |
|
|
352
|
+
| 报告 HTML 展示 | `(ctr * 100).toFixed(2) + '%'` | `ctr.toFixed(2) + '%'`(会显示 74% 而非 0.74%) |
|
|
353
|
+
| Excel 0~1 列 | 直接写 JSON 数值 | 再 ÷100 |
|
|
354
|
+
| 脚本校验 | `clicks / impressions` 与 `ctr` 应一致(允许四舍五入) | 心算或凭印象 |
|
|
355
|
+
|
|
356
|
+
各 `overview-*.outline.txt` 等文件头部含 `//` 硬提示,Agent **须先读 outline** 再写报告。
|
|
357
|
+
|
|
346
358
|
---
|
|
347
359
|
|
|
348
360
|
## 报告模板
|
|
@@ -149,6 +149,11 @@
|
|
|
149
149
|
| Google 关键词/系列分析 | `now - 30d` ~ `now - 1d` |
|
|
150
150
|
| MetaAd 账户分析 | 不得默认,必须问 |
|
|
151
151
|
|
|
152
|
+
**完整自然月口径**(用户说「X 月 / X月份 / 月报」且该月已结束,或上表「月报」默认):
|
|
153
|
+
|
|
154
|
+
- `--start` = 当月 1 日,`--end` = 当月最后一天(6 月 → `06-01` ~ `06-30`,**禁止** `06-29`)。
|
|
155
|
+
- **Bing** `bing-analysis`:「不能含今天/昨天」仅当区间碰到**执行日**的今天/昨天时才需把结束日压到前天;**已结束的历史自然月必须用该月最后一天**,细则见 `report-templates/bing-period-report.md` §日期规则。交付前核对 `overview` 的 `activeDays` = 该月日历天数。
|
|
156
|
+
|
|
152
157
|
---
|
|
153
158
|
|
|
154
159
|
## 六、币种与金额
|
|
@@ -12,7 +12,25 @@
|
|
|
12
12
|
|
|
13
13
|
- Bing 接口**无法**拉取过新的数据;时间范围内**任意一天**若为**今天**或**昨天**,请求会失败。
|
|
14
14
|
- **CLI**:`--start` / `--end` 须**同传或同省略**;省略时默认**截至前天**的近 7 天(与 `bing-analysis` 实现一致)。
|
|
15
|
-
-
|
|
15
|
+
- **自选区间且靠近当前日期**时,结束日须 ≤ **前天**(仅当区间会碰到今天/昨天才需要压到前天;**不是**把历史自然月最后一天减 1 天)。
|
|
16
|
+
|
|
17
|
+
### 用户说「X 月 / X月份 / 月报」(已结束的完整自然月)
|
|
18
|
+
|
|
19
|
+
用户指定某一月份(如「6月份报告」「6月 Bing 月报」)且该月**已结束**时:
|
|
20
|
+
|
|
21
|
+
| 项 | 规则 |
|
|
22
|
+
| --- | --- |
|
|
23
|
+
| `--start` | 当月 **1 日**(如 `2026-06-01`) |
|
|
24
|
+
| `--end` | 当月**最后一天**(如 6 月 → `2026-06-30`,**禁止**写成 `06-29`) |
|
|
25
|
+
| 报告首行 | `统计区间:YYYY-MM-01 ~ YYYY-MM-<末>` |
|
|
26
|
+
|
|
27
|
+
示例(7 月 8 日要 6 月报告):
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
siluzan-tso bing-analysis -a <id> --start 2026-06-01 --end 2026-06-30 --json-out ./snap-bing
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
**禁止**因「Bing 不能含今天/昨天」而对**已结束的历史自然月**把 `--end` 减 1 天——该限制只针对区间内的日历日是否等于**执行当天的今天或昨天**;6 月 30 日在 7 月 8 日拉数完全合法。拉数后核对 `overview` 落盘里的 `activeDays` 应等于该月日历天数(6 月 = 30)。
|
|
16
34
|
|
|
17
35
|
---
|
|
18
36
|
|
|
@@ -35,7 +53,7 @@ siluzan-tso bing-analysis -a <mediaCustomerId> --start <S> --end <E> \
|
|
|
35
53
|
|
|
36
54
|
- 写脚本前先读各 `bing-*-<id>.outline.txt`,再读 `.json`(见 `references/core/agent-conventions.md` §三)。
|
|
37
55
|
- TopN、排序、汇总均在脚本内完成,禁止心算。
|
|
38
|
-
- 金额字段已为**元**;`ctr` / `conversionRate`
|
|
56
|
+
- 金额字段已为**元**;`ctr` / `conversionRate` 等:**`bing-analysis` 落盘前已从网关百分数刻度归一为 0~1 小数**(如 `0.0074` = 0.74%),展示百分比用 `(v * 100).toFixed(2) + '%'`;**禁止**把 JSON 数值当「已是百分数」直接加 `%`(会重复 ×100,如 0.74% 显示成 74%)。
|
|
39
57
|
|
|
40
58
|
---
|
|
41
59
|
|
|
@@ -12,7 +12,25 @@
|
|
|
12
12
|
|
|
13
13
|
- Bing 接口**无法**拉取过新的数据;时间范围内**任意一天**若为**今天**或**昨天**,请求会失败。
|
|
14
14
|
- **CLI**:`--start` / `--end` 须**同传或同省略**;省略时默认**截至前天**的近 7 天(与 `bing-analysis` 实现一致)。
|
|
15
|
-
-
|
|
15
|
+
- **自选区间且靠近当前日期**时,结束日须 ≤ **前天**(仅当区间会碰到今天/昨天才需要压到前天;**不是**把历史自然月最后一天减 1 天)。
|
|
16
|
+
|
|
17
|
+
### 用户说「X 月 / X月份 / 月报」(已结束的完整自然月)
|
|
18
|
+
|
|
19
|
+
用户指定某一月份(如「6月份报告」「6月 Bing 月报」)且该月**已结束**时:
|
|
20
|
+
|
|
21
|
+
| 项 | 规则 |
|
|
22
|
+
| --- | --- |
|
|
23
|
+
| `--start` | 当月 **1 日**(如 `2026-06-01`) |
|
|
24
|
+
| `--end` | 当月**最后一天**(如 6 月 → `2026-06-30`,**禁止**写成 `06-29`) |
|
|
25
|
+
| 报告首行 | `统计区间:YYYY-MM-01 ~ YYYY-MM-<末>` |
|
|
26
|
+
|
|
27
|
+
示例(7 月 8 日要 6 月报告):
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
siluzan-tso bing-analysis -a <id> --start 2026-06-01 --end 2026-06-30 --json-out ./snap-bing
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
**禁止**因「Bing 不能含今天/昨天」而对**已结束的历史自然月**把 `--end` 减 1 天——该限制只针对区间内的日历日是否等于**执行当天的今天或昨天**;6 月 30 日在 7 月 8 日拉数完全合法。拉数后核对 `overview` 落盘里的 `activeDays` 应等于该月日历天数(6 月 = 30)。
|
|
16
34
|
|
|
17
35
|
---
|
|
18
36
|
|
|
@@ -35,7 +53,7 @@ siluzan-tso bing-analysis -a <mediaCustomerId> --start <S> --end <E> \
|
|
|
35
53
|
|
|
36
54
|
- 写脚本前先读各 `bing-*-<id>.outline.txt`,再读 `.json`(见 `references/core/agent-conventions.md` §三)。
|
|
37
55
|
- TopN、排序、汇总均在脚本内完成,禁止心算。
|
|
38
|
-
- 金额字段已为**元**;`ctr` / `conversionRate`
|
|
56
|
+
- 金额字段已为**元**;`ctr` / `conversionRate` 等:**`bing-analysis` 落盘前已从网关百分数刻度归一为 0~1 小数**(如 `0.0074` = 0.74%),展示百分比用 `(v * 100).toFixed(2) + '%'`;**禁止**把 JSON 数值当「已是百分数」直接加 `%`(会重复 ×100,如 0.74% 显示成 74%)。
|
|
39
57
|
|
|
40
58
|
---
|
|
41
59
|
|
|
@@ -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.36-beta.
|
|
12
|
+
$PKG_VERSION = '1.1.36-beta.2'
|
|
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.36-beta.
|
|
12
|
+
readonly PKG_VERSION="1.1.36-beta.2"
|
|
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"
|