siluzan-tso-cli 1.1.46-beta.5 → 1.1.46-beta.6
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 +37 -8
- package/dist/skill/_meta.json +2 -2
- package/dist/skill/references/analytics/account-analytics.md +1 -1
- package/dist/skill/references/report-templates/yandex-period-report.md +1 -1
- package/dist/skill/report-templates/yandex-period-report.html +12 -1
- package/dist/skill/report-templates/yandex-period-report.md +1 -1
- 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.46-beta.
|
|
54
|
+
> **注意**:当前为测试版(1.1.46-beta.6),供内部测试使用。正式发布后安装命令将改为 `npm install -g siluzan-tso-cli`。
|
|
55
55
|
|
|
56
56
|
| 助手 | 建议 `--ai` |
|
|
57
57
|
| ----------------------- | ------------------------------------ |
|
package/dist/index.js
CHANGED
|
@@ -132169,7 +132169,14 @@ function parseLocalYmd(ymd) {
|
|
|
132169
132169
|
return /* @__PURE__ */ new Date(NaN);
|
|
132170
132170
|
}
|
|
132171
132171
|
const [y, m, day] = parts;
|
|
132172
|
-
|
|
132172
|
+
if (m < 1 || m > 12 || day < 1 || day > 31) {
|
|
132173
|
+
return /* @__PURE__ */ new Date(NaN);
|
|
132174
|
+
}
|
|
132175
|
+
const d = new Date(y, m - 1, day);
|
|
132176
|
+
if (d.getFullYear() !== y || d.getMonth() !== m - 1 || d.getDate() !== day) {
|
|
132177
|
+
return /* @__PURE__ */ new Date(NaN);
|
|
132178
|
+
}
|
|
132179
|
+
return d;
|
|
132173
132180
|
}
|
|
132174
132181
|
function formatLocalYmd(d) {
|
|
132175
132182
|
const y = d.getFullYear();
|
|
@@ -134371,7 +134378,14 @@ function parseLocalYmd2(ymd) {
|
|
|
134371
134378
|
return /* @__PURE__ */ new Date(NaN);
|
|
134372
134379
|
}
|
|
134373
134380
|
const [y, m, day] = parts;
|
|
134374
|
-
|
|
134381
|
+
if (m < 1 || m > 12 || day < 1 || day > 31) {
|
|
134382
|
+
return /* @__PURE__ */ new Date(NaN);
|
|
134383
|
+
}
|
|
134384
|
+
const d = new Date(y, m - 1, day);
|
|
134385
|
+
if (d.getFullYear() !== y || d.getMonth() !== m - 1 || d.getDate() !== day) {
|
|
134386
|
+
return /* @__PURE__ */ new Date(NaN);
|
|
134387
|
+
}
|
|
134388
|
+
return d;
|
|
134375
134389
|
}
|
|
134376
134390
|
function formatLocalYmd2(d) {
|
|
134377
134391
|
const y = d.getFullYear();
|
|
@@ -134502,6 +134516,11 @@ function num10(value) {
|
|
|
134502
134516
|
function round25(value) {
|
|
134503
134517
|
return value == null ? void 0 : Math.round(value * 100) / 100;
|
|
134504
134518
|
}
|
|
134519
|
+
function normalizeYandexRoi(value) {
|
|
134520
|
+
if (typeof value !== "number" && typeof value !== "string") return void 0;
|
|
134521
|
+
const r = num10(value);
|
|
134522
|
+
return r === -1 ? void 0 : r;
|
|
134523
|
+
}
|
|
134505
134524
|
function asItems(payload) {
|
|
134506
134525
|
const obj = asRecord26(payload);
|
|
134507
134526
|
if (!obj) return [];
|
|
@@ -134523,7 +134542,7 @@ function pickMetrics2(row, extras = []) {
|
|
|
134523
134542
|
averageCpc: num10(row.averageCpc) ?? (clicks > 0 ? round25(spend / clicks) : void 0),
|
|
134524
134543
|
conversionRate: num10(row.conversionRate) ?? (clicks > 0 ? conversions / clicks : void 0),
|
|
134525
134544
|
costPerConversion: num10(row.costPerConversion) ?? (conversions > 0 ? round25(spend / conversions) : void 0),
|
|
134526
|
-
roi:
|
|
134545
|
+
roi: normalizeYandexRoi(row.roi)
|
|
134527
134546
|
};
|
|
134528
134547
|
for (const f of extras) {
|
|
134529
134548
|
if (row[f] !== void 0 && row[f] !== null) out[f] = row[f];
|
|
@@ -134568,8 +134587,14 @@ function parseYmd2(value) {
|
|
|
134568
134587
|
const s = normalizeYandexDailyDate(value);
|
|
134569
134588
|
const m = /^(\d{4})-(\d{2})-(\d{2})$/.exec(s);
|
|
134570
134589
|
if (!m) return null;
|
|
134571
|
-
const
|
|
134572
|
-
|
|
134590
|
+
const y = Number(m[1]);
|
|
134591
|
+
const month = Number(m[2]);
|
|
134592
|
+
const day = Number(m[3]);
|
|
134593
|
+
const d = new Date(y, month - 1, day);
|
|
134594
|
+
if (Number.isNaN(d.getTime()) || d.getFullYear() !== y || d.getMonth() !== month - 1 || d.getDate() !== day) {
|
|
134595
|
+
return null;
|
|
134596
|
+
}
|
|
134597
|
+
return d;
|
|
134573
134598
|
}
|
|
134574
134599
|
function formatYmd2(d) {
|
|
134575
134600
|
const y = d.getFullYear();
|
|
@@ -134648,9 +134673,12 @@ var YANDEX_DAILY_OUTLINE_HINTS = [
|
|
|
134648
134673
|
"// `items[].date` \u5DF2\u89C4\u8303\u4E3A YYYY-MM-DD\u3002\u63A5\u53E3\u53EF\u80FD\u8FD4\u56DE ISO \u65F6\u95F4\u6233\uFF08\u5982 2026-07-01T00:00:00+00:00\uFF09\uFF0CCLI \u5DF2\u622A\u65AD\uFF1B\u7981\u6B62\u518D\u62FC\u63A5 T00:00:00Z\uFF0C\u5426\u5219 new Date() \u4F1A Invalid Date\uFF0C\u5468\u6807\u7B7E\u53D8\u6210 NaN\u3002",
|
|
134649
134674
|
"// \u5468\u8D8B\u52BF\u8BFB\u672C\u6587\u4EF6 `weekly[]`\uFF08ISO \u5468\u4E00~\u5468\u65E5\uFF1B`days` \u4E3A\u6709\u6570\u636E\u7684\u5929\u6570\uFF09\u3002\u7981\u6B62\u81EA\u884C\u6309 date \u805A\u5468\u3002"
|
|
134650
134675
|
];
|
|
134676
|
+
var YANDEX_ROI_OUTLINE_HINTS = [
|
|
134677
|
+
"// `roi` = (Revenue-Spend)/Spend\uFF0C\u5DF2\u662F\u500D\u6570\uFF083.72 \u2248 \u5229\u6DA6 372%\uFF09\uFF0C\u4E0D\u662F 0~1\u3002\u7981\u6B62\u518D \xD7100\u3002\u65E0\u6536\u76CA\u65F6\u5E38\u4E3A -1\uFF0C\u6309\u7F3A\u5931\u5904\u7406\u3002"
|
|
134678
|
+
];
|
|
134651
134679
|
function buildYandexOutlineHints(section) {
|
|
134652
|
-
if (section === "daily") return YANDEX_DAILY_OUTLINE_HINTS;
|
|
134653
|
-
return
|
|
134680
|
+
if (section === "daily") return [...YANDEX_DAILY_OUTLINE_HINTS, ...YANDEX_ROI_OUTLINE_HINTS];
|
|
134681
|
+
return YANDEX_ROI_OUTLINE_HINTS;
|
|
134654
134682
|
}
|
|
134655
134683
|
function mapDailyRows(payload) {
|
|
134656
134684
|
return asItems(payload).map((r) => {
|
|
@@ -134737,7 +134765,8 @@ async function mergeYandexAnalysisSnapshotIntoReport(payload, snapshotDir) {
|
|
|
134737
134765
|
kpis.costPerConversion = round25(num10(totals.costPerConversion));
|
|
134738
134766
|
}
|
|
134739
134767
|
if (num10(totals.conversionRate) != null) kpis.conversionRate = num10(totals.conversionRate);
|
|
134740
|
-
|
|
134768
|
+
const overviewRoi = normalizeYandexRoi(totals.roi);
|
|
134769
|
+
if (overviewRoi != null) kpis.roi = overviewRoi;
|
|
134741
134770
|
}
|
|
134742
134771
|
if (overview) {
|
|
134743
134772
|
if (num10(overview.balance) != null) kpis.balance = round25(num10(overview.balance));
|
package/dist/skill/_meta.json
CHANGED
|
@@ -442,7 +442,7 @@ siluzan-tso bing-analysis run -a <mediaCustomerId> --json-out ./snap --sections
|
|
|
442
442
|
>
|
|
443
443
|
> **账户 ID**:Yandex Client-Login / mediaCustomerId(如 `porg-xxx`,与 `list-accounts -m Yandex` 一致),**不是**纯数字。
|
|
444
444
|
>
|
|
445
|
-
> **金额**:已从 micros 转为账户币种小数(`/1e6`)。`ctr` / `conversionRate` 为 **0~1 小数**(先读 outline
|
|
445
|
+
> **金额**:已从 micros 转为账户币种小数(`/1e6`)。`ctr` / `conversionRate` 为 **0~1 小数**(先读 outline)。`roi` 为 **(收益-消耗)/消耗** 倍数,禁止再 ×100。
|
|
446
446
|
|
|
447
447
|
与 `bing-analysis` 同架构:`yandex-analysis -a … --json-out …`(省略子命令名默认执行 `run`);周期报告默认 **HTML**:`yandex-analysis render`(见 `report-templates/yandex-period-report.md`)。用户要 Excel → `yandex-period-report-excel.md`(Agent 脚本,无 excel 子命令)。
|
|
448
448
|
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
| `geo` | `{ …, items: GeoRow[] }` | → `tables.geo[]` |
|
|
20
20
|
| `devices` | `{ …, items: DeviceRow[] }` | → `tables.devices[]` |
|
|
21
21
|
|
|
22
|
-
> 金额已为账户币种小数;`ctr` / `conversionRate` 为 **0~1
|
|
22
|
+
> 金额已为账户币种小数;`ctr` / `conversionRate` 为 **0~1 小数**。`roi` 为 **(收益-消耗)/消耗** 的倍数(如 `3.72` 表示利润约 372%),**不是** 0~1,禁止再 ×100;无收益时常为 `-1`(按缺失)。写叙事前先读各维 `*.outline.txt`。
|
|
23
23
|
|
|
24
24
|
---
|
|
25
25
|
|
|
@@ -492,6 +492,17 @@
|
|
|
492
492
|
return (n * 100).toFixed(2) + "%";
|
|
493
493
|
}
|
|
494
494
|
|
|
495
|
+
/**
|
|
496
|
+
* 后端 roi = (Revenue - Spend) / Spend,已是倍数(如 3.72 = 372% 利润),
|
|
497
|
+
* **不是** CTR 那种 0~1。禁止走 pct(),否则 371.96 会显示成 37195.98%。
|
|
498
|
+
* 无收益时网关算成 -1,展示为 —。
|
|
499
|
+
*/
|
|
500
|
+
function fmtRoi(v) {
|
|
501
|
+
const n = toNum(v);
|
|
502
|
+
if (n === undefined || n === -1) return "—";
|
|
503
|
+
return n.toFixed(2) + "%";
|
|
504
|
+
}
|
|
505
|
+
|
|
495
506
|
function num2(v) {
|
|
496
507
|
const n = toNum(v);
|
|
497
508
|
return n === undefined ? "—" : n.toFixed(2);
|
|
@@ -1158,7 +1169,7 @@
|
|
|
1158
1169
|
'</td><td class="num">' +
|
|
1159
1170
|
money(r.costPerConversion, currency) +
|
|
1160
1171
|
'</td><td class="num">' +
|
|
1161
|
-
|
|
1172
|
+
fmtRoi(r.roi) +
|
|
1162
1173
|
'</td><td class="num">' +
|
|
1163
1174
|
pct(r.ctr) +
|
|
1164
1175
|
"</td><td>" +
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
| `geo` | `{ …, items: GeoRow[] }` | → `tables.geo[]` |
|
|
20
20
|
| `devices` | `{ …, items: DeviceRow[] }` | → `tables.devices[]` |
|
|
21
21
|
|
|
22
|
-
> 金额已为账户币种小数;`ctr` / `conversionRate` 为 **0~1
|
|
22
|
+
> 金额已为账户币种小数;`ctr` / `conversionRate` 为 **0~1 小数**。`roi` 为 **(收益-消耗)/消耗** 的倍数(如 `3.72` 表示利润约 372%),**不是** 0~1,禁止再 ×100;无收益时常为 `-1`(按缺失)。写叙事前先读各维 `*.outline.txt`。
|
|
23
23
|
|
|
24
24
|
---
|
|
25
25
|
|
|
@@ -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.46-beta.
|
|
12
|
+
$PKG_VERSION = '1.1.46-beta.6'
|
|
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.46-beta.
|
|
12
|
+
readonly PKG_VERSION="1.1.46-beta.6"
|
|
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"
|