siluzan-tso-cli 1.1.37-beta.12 → 1.1.37-beta.14
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 +197 -94
- package/dist/skill/AGENTS.md +18 -51
- package/dist/skill/SKILL.md +58 -69
- package/dist/skill/_meta.json +2 -2
- package/dist/skill/assets/campaign-create-template.md +1 -1
- package/dist/skill/references/README.md +14 -6
- package/dist/skill/references/accounts/accounts-balance-stats.md +167 -0
- package/dist/skill/references/accounts/accounts-list.md +170 -0
- package/dist/skill/references/accounts/accounts-permissions.md +481 -0
- package/dist/skill/references/accounts/accounts.md +18 -939
- package/dist/skill/references/accounts/currency.md +2 -2
- package/dist/skill/references/accounts/finance.md +11 -0
- package/dist/skill/references/accounts/open-account-by-media.md +16 -0
- package/dist/skill/references/accounts/open-account-google-ui.md +1 -1
- package/dist/skill/references/analytics/account-analytics.md +14 -0
- package/dist/skill/references/analytics/google-analysis-batch.md +16 -0
- package/dist/skill/references/analytics/keyword-planner-workflows.md +18 -4
- package/dist/skill/references/analytics/rag.md +1 -1
- package/dist/skill/references/analytics/reporting.md +1 -1
- package/dist/skill/references/analytics/website-diagnosis-guide.md +1 -1
- package/dist/skill/references/core/agent-conventions.md +46 -30
- package/dist/skill/references/core/intent-routing.md +18 -1
- package/dist/skill/references/core/playbooks.md +19 -10
- package/dist/skill/references/core/skill-authoring.md +35 -0
- package/dist/skill/references/core/tips.md +18 -4
- package/dist/skill/references/core/workflows.md +14 -14
- package/dist/skill/references/google-ads/google-ads-batch.md +66 -0
- package/dist/skill/references/google-ads/google-ads-campaign-plan.md +4 -4
- package/dist/skill/references/google-ads/google-ads-read.md +272 -0
- package/dist/skill/references/google-ads/google-ads-write.md +400 -0
- package/dist/skill/references/google-ads/google-ads.md +14 -659
- package/dist/skill/references/google-ads/rules/README.md +20 -18
- package/dist/skill/references/google-ads/rules/google-ads-account-audit-assets.md +284 -0
- package/dist/skill/references/google-ads/rules/google-ads-account-audit-quick.md +223 -0
- package/dist/skill/references/google-ads/rules/google-ads-account-audit-report.md +79 -0
- package/dist/skill/references/google-ads/rules/google-ads-account-audit-structure.md +123 -0
- package/dist/skill/references/google-ads/rules/google-ads-account-audit.md +31 -652
- package/dist/skill/references/google-ads/rules/google-ads-compliance-copy.md +201 -0
- package/dist/skill/references/google-ads/rules/google-ads-compliance-forbid.md +280 -0
- package/dist/skill/references/google-ads/rules/google-ads-compliance-ops.md +151 -0
- package/dist/skill/references/google-ads/rules/google-ads-compliance.md +24 -587
- package/dist/skill/references/google-ads/rules/google-ads-launch-plan-template.md +1 -1
- package/dist/skill/references/operations/hosted-automation-monitoring-json.md +1 -1
- package/dist/skill/references/operations/hosted-automation-optimize-index.md +1 -1
- package/dist/skill/references/operations/hosted-automation-optimize-scale.md +2 -2
- package/dist/skill/references/operations/hosted-automation-optimize-weak-downbid.md +1 -1
- package/dist/skill/references/operations/hosted-automation-scenarios.md +2 -2
- package/dist/skill/references/operations/hosted-automation-self-control.md +14 -2
- package/dist/skill/references/operations/hosted-automation-user-catalog.md +35 -27
- package/dist/skill/references/report-templates/README.md +1 -0
- package/dist/skill/references/report-templates/REPORT-WORKFLOW.md +3 -1
- package/dist/skill/references/report-templates/google-ads-diagnosis.md +23 -2
- package/dist/skill/references/report-templates/google-inquiry-analysis.md +18 -0
- package/dist/skill/references/report-templates/google-period-report-excel.md +2 -9
- package/dist/skill/references/report-templates/okki-weekly-google-client.md +14 -0
- package/dist/skill/references/report-templates/stats-daily-excel.md +10 -0
- package/dist/skill/report-templates/README.md +1 -0
- package/dist/skill/report-templates/REPORT-WORKFLOW.md +3 -1
- package/dist/skill/report-templates/google-ads-diagnosis.md +23 -2
- package/dist/skill/report-templates/google-inquiry-analysis.md +18 -0
- package/dist/skill/report-templates/google-period-report-excel.md +2 -9
- package/dist/skill/report-templates/okki-weekly-google-client.md +14 -0
- package/dist/skill/report-templates/stats-daily-excel.md +10 -0
- 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.37-beta.
|
|
54
|
+
> **注意**:当前为测试版(1.1.37-beta.14),供内部测试使用。正式发布后安装命令将改为 `npm install -g siluzan-tso-cli`。
|
|
55
55
|
|
|
56
56
|
| 助手 | 建议 `--ai` |
|
|
57
57
|
| ----------------------- | ------------------------------------ |
|
package/dist/index.js
CHANGED
|
@@ -4385,6 +4385,40 @@ var init_currency_display = __esm({
|
|
|
4385
4385
|
}
|
|
4386
4386
|
});
|
|
4387
4387
|
|
|
4388
|
+
// src/utils/media-customer-id.ts
|
|
4389
|
+
function stripMediaCustomerIdDecorators(raw) {
|
|
4390
|
+
return raw.trim().replace(/[\s-]+/g, "");
|
|
4391
|
+
}
|
|
4392
|
+
function looksLikeNumericMediaCustomerId(raw) {
|
|
4393
|
+
return /^\d+$/.test(stripMediaCustomerIdDecorators(raw));
|
|
4394
|
+
}
|
|
4395
|
+
function normalizeNumericMediaCustomerId(raw) {
|
|
4396
|
+
if (!looksLikeNumericMediaCustomerId(raw)) return null;
|
|
4397
|
+
return stripMediaCustomerIdDecorators(raw);
|
|
4398
|
+
}
|
|
4399
|
+
function parseNumericMediaCustomerIds(input) {
|
|
4400
|
+
if (!input || !input.trim()) return [];
|
|
4401
|
+
const seen = /* @__PURE__ */ new Set();
|
|
4402
|
+
const out = [];
|
|
4403
|
+
for (const raw of input.split(",")) {
|
|
4404
|
+
const piece = raw.trim();
|
|
4405
|
+
if (!piece) continue;
|
|
4406
|
+
const id = normalizeNumericMediaCustomerId(piece);
|
|
4407
|
+
if (!id) {
|
|
4408
|
+
throw new Error(`mediaCustomerId \u5FC5\u987B\u4E3A\u7EAF\u6570\u5B57\uFF08\u53EF\u542B\u8FDE\u5B57\u7B26\uFF09\uFF1A${piece}`);
|
|
4409
|
+
}
|
|
4410
|
+
if (seen.has(id)) continue;
|
|
4411
|
+
seen.add(id);
|
|
4412
|
+
out.push(id);
|
|
4413
|
+
}
|
|
4414
|
+
return out;
|
|
4415
|
+
}
|
|
4416
|
+
var init_media_customer_id = __esm({
|
|
4417
|
+
"src/utils/media-customer-id.ts"() {
|
|
4418
|
+
"use strict";
|
|
4419
|
+
}
|
|
4420
|
+
});
|
|
4421
|
+
|
|
4388
4422
|
// src/utils/balance.ts
|
|
4389
4423
|
function fmt(d) {
|
|
4390
4424
|
return d.toISOString().slice(0, 10);
|
|
@@ -103126,20 +103160,7 @@ function parseSections(input) {
|
|
|
103126
103160
|
return list;
|
|
103127
103161
|
}
|
|
103128
103162
|
function parseAccountIds(input) {
|
|
103129
|
-
|
|
103130
|
-
const seen = /* @__PURE__ */ new Set();
|
|
103131
|
-
const out = [];
|
|
103132
|
-
for (const raw of input.split(",")) {
|
|
103133
|
-
const id = raw.trim();
|
|
103134
|
-
if (!id) continue;
|
|
103135
|
-
if (!/^\d+$/.test(id)) {
|
|
103136
|
-
throw new Error(`mediaCustomerId \u5FC5\u987B\u4E3A\u7EAF\u6570\u5B57\uFF1A${id}`);
|
|
103137
|
-
}
|
|
103138
|
-
if (seen.has(id)) continue;
|
|
103139
|
-
seen.add(id);
|
|
103140
|
-
out.push(id);
|
|
103141
|
-
}
|
|
103142
|
-
return out;
|
|
103163
|
+
return parseNumericMediaCustomerIds(input);
|
|
103143
103164
|
}
|
|
103144
103165
|
function parseDeadline(s) {
|
|
103145
103166
|
if (!s) return void 0;
|
|
@@ -103644,6 +103665,7 @@ var init_google_analysis_batch = __esm({
|
|
|
103644
103665
|
init_google_analysis3();
|
|
103645
103666
|
init_balance();
|
|
103646
103667
|
init_version();
|
|
103668
|
+
init_media_customer_id();
|
|
103647
103669
|
DEFAULT_SECTIONS = ["campaigns", "geographic", "keywords"];
|
|
103648
103670
|
DEFAULT_ACCOUNT_CONCURRENCY = 4;
|
|
103649
103671
|
DEFAULT_SECTION_CONCURRENCY = 6;
|
|
@@ -103795,23 +103817,15 @@ function finiteOpt(n) {
|
|
|
103795
103817
|
return typeof n === "number" && Number.isFinite(n) ? n : void 0;
|
|
103796
103818
|
}
|
|
103797
103819
|
function parseAccountIdsForAnalysis(input) {
|
|
103798
|
-
|
|
103799
|
-
|
|
103800
|
-
|
|
103801
|
-
const
|
|
103802
|
-
|
|
103803
|
-
|
|
103804
|
-
console.error(`
|
|
103805
|
-
\u274C --account \u987B\u4E3A\u6570\u5B57 mediaCustomerId\uFF08\u4E0D\u5408\u6CD5\uFF1A${id}\uFF09\u3002
|
|
103820
|
+
try {
|
|
103821
|
+
return parseNumericMediaCustomerIds(input);
|
|
103822
|
+
} catch (err) {
|
|
103823
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
103824
|
+
console.error(`
|
|
103825
|
+
\u274C --account \u987B\u4E3A\u6570\u5B57 mediaCustomerId\uFF1A${message}
|
|
103806
103826
|
`);
|
|
103807
|
-
|
|
103808
|
-
}
|
|
103809
|
-
if (!seen.has(id)) {
|
|
103810
|
-
seen.add(id);
|
|
103811
|
-
out.push(id);
|
|
103812
|
-
}
|
|
103827
|
+
process.exit(1);
|
|
103813
103828
|
}
|
|
103814
|
-
return out;
|
|
103815
103829
|
}
|
|
103816
103830
|
async function runMultiAccountViaBatch(accountIds, opts) {
|
|
103817
103831
|
const targets = resolveSectionList(opts.sections, opts.exclude);
|
|
@@ -103997,6 +104011,7 @@ var init_register_cli = __esm({
|
|
|
103997
104011
|
init_auth();
|
|
103998
104012
|
init_google_analysis_snapshot();
|
|
103999
104013
|
init_version();
|
|
104014
|
+
init_media_customer_id();
|
|
104000
104015
|
init_http_retry();
|
|
104001
104016
|
init_sections();
|
|
104002
104017
|
init_fetch();
|
|
@@ -105963,6 +105978,7 @@ function wrapListJson(params) {
|
|
|
105963
105978
|
}
|
|
105964
105979
|
|
|
105965
105980
|
// src/commands/list-accounts/main.ts
|
|
105981
|
+
init_media_customer_id();
|
|
105966
105982
|
async function runListAccounts(opts) {
|
|
105967
105983
|
let config = loadConfig(opts.token);
|
|
105968
105984
|
if (opts.refreshDp) {
|
|
@@ -105993,9 +106009,9 @@ async function runListAccounts(opts) {
|
|
|
105993
106009
|
params.set("status", opts.status);
|
|
105994
106010
|
}
|
|
105995
106011
|
if (opts.keyword) {
|
|
105996
|
-
const
|
|
105997
|
-
if (
|
|
105998
|
-
params.set(platformCfg.idSearchParam,
|
|
106012
|
+
const numericId = normalizeNumericMediaCustomerId(opts.keyword);
|
|
106013
|
+
if (numericId) {
|
|
106014
|
+
params.set(platformCfg.idSearchParam, numericId);
|
|
105999
106015
|
} else {
|
|
106000
106016
|
params.set("mediaCustomerName", opts.keyword.trim());
|
|
106001
106017
|
}
|
|
@@ -106033,7 +106049,9 @@ async function runListAccounts(opts) {
|
|
|
106033
106049
|
}
|
|
106034
106050
|
} else {
|
|
106035
106051
|
const params = new URLSearchParams();
|
|
106036
|
-
if (opts.keyword)
|
|
106052
|
+
if (opts.keyword) {
|
|
106053
|
+
params.set("keyword", normalizeNumericMediaCustomerId(opts.keyword) ?? opts.keyword.trim());
|
|
106054
|
+
}
|
|
106037
106055
|
if (opts.status && opts.status !== "all") params.set("status", opts.status);
|
|
106038
106056
|
params.set("pageNo", String(page));
|
|
106039
106057
|
params.set("pageSize", String(pageSize));
|
|
@@ -106280,6 +106298,7 @@ init_auth();
|
|
|
106280
106298
|
init_cli_json_snapshot();
|
|
106281
106299
|
init_cli_table();
|
|
106282
106300
|
init_balance();
|
|
106301
|
+
init_media_customer_id();
|
|
106283
106302
|
var VALID_MEDIA_TYPES2 = ["Google", "TikTok", "Yandex", "MetaAd", "BingV2", "Kwai"];
|
|
106284
106303
|
async function runBalance(opts) {
|
|
106285
106304
|
const config = loadConfig(opts.token);
|
|
@@ -106316,7 +106335,7 @@ async function runBalance(opts) {
|
|
|
106316
106335
|
`);
|
|
106317
106336
|
process.exit(1);
|
|
106318
106337
|
}
|
|
106319
|
-
const accountIds = opts.accounts.split(",").map((id) => id.trim()).filter(Boolean);
|
|
106338
|
+
const accountIds = opts.accounts.split(",").map((id) => id.trim()).filter(Boolean).map((id) => normalizeNumericMediaCustomerId(id) ?? id);
|
|
106320
106339
|
if (accountIds.length === 0) {
|
|
106321
106340
|
console.error("\n\u274C \u8BF7\u901A\u8FC7 --accounts \u63D0\u4F9B\u81F3\u5C11\u4E00\u4E2A\u8D26\u6237 ID\uFF08\u591A\u4E2A\u7528\u9017\u53F7\u5206\u9694\uFF09\n");
|
|
106322
106341
|
process.exit(1);
|
|
@@ -106874,7 +106893,10 @@ init_cli_json_snapshot();
|
|
|
106874
106893
|
init_cli_table();
|
|
106875
106894
|
init_balance();
|
|
106876
106895
|
init_media_account_lookup();
|
|
106896
|
+
init_media_customer_id();
|
|
106877
106897
|
var VALID_MEDIA_TYPES3 = ["Google", "TikTok", "Yandex", "MetaAd", "BingV2", "Kwai"];
|
|
106898
|
+
var MAX_BY_DAY_SPAN = 366;
|
|
106899
|
+
var DATE_RE = /^\d{4}-\d{2}-\d{2}$/;
|
|
106878
106900
|
function defaultDateRange2() {
|
|
106879
106901
|
const end = /* @__PURE__ */ new Date();
|
|
106880
106902
|
end.setDate(end.getDate() - 1);
|
|
@@ -106883,6 +106905,77 @@ function defaultDateRange2() {
|
|
|
106883
106905
|
const fmt2 = (d) => d.toISOString().slice(0, 10);
|
|
106884
106906
|
return { startDate: fmt2(start), endDate: fmt2(end) };
|
|
106885
106907
|
}
|
|
106908
|
+
function eachDateInclusive(startDate, endDate) {
|
|
106909
|
+
if (!DATE_RE.test(startDate) || !DATE_RE.test(endDate)) {
|
|
106910
|
+
throw new Error(`\u65E5\u671F\u683C\u5F0F\u987B\u4E3A YYYY-MM-DD\uFF0C\u6536\u5230\uFF1A${startDate} ~ ${endDate}`);
|
|
106911
|
+
}
|
|
106912
|
+
const [ys, ms, ds] = startDate.split("-").map(Number);
|
|
106913
|
+
const [ye, me, de] = endDate.split("-").map(Number);
|
|
106914
|
+
const cur = new Date(Date.UTC(ys, ms - 1, ds));
|
|
106915
|
+
const end = new Date(Date.UTC(ye, me - 1, de));
|
|
106916
|
+
if (Number.isNaN(cur.getTime()) || Number.isNaN(end.getTime())) {
|
|
106917
|
+
throw new Error(`\u65E0\u6548\u65E5\u671F\uFF1A${startDate} ~ ${endDate}`);
|
|
106918
|
+
}
|
|
106919
|
+
if (cur > end) {
|
|
106920
|
+
throw new Error(`\u5F00\u59CB\u65E5\u671F\u4E0D\u80FD\u665A\u4E8E\u7ED3\u675F\u65E5\u671F\uFF1A${startDate} > ${endDate}`);
|
|
106921
|
+
}
|
|
106922
|
+
const out = [];
|
|
106923
|
+
while (cur <= end) {
|
|
106924
|
+
out.push(cur.toISOString().slice(0, 10));
|
|
106925
|
+
cur.setUTCDate(cur.getUTCDate() + 1);
|
|
106926
|
+
}
|
|
106927
|
+
if (out.length > MAX_BY_DAY_SPAN) {
|
|
106928
|
+
throw new Error(
|
|
106929
|
+
`--by-day \u8DE8\u5EA6\u6700\u591A ${MAX_BY_DAY_SPAN} \u5929\uFF08\u542B\u8D77\u6B62\uFF09\uFF0C\u5F53\u524D ${out.length} \u5929\uFF1B\u8BF7\u7F29\u5C0F\u533A\u95F4\u6216\u5206\u6BB5\u62C9\u53D6`
|
|
106930
|
+
);
|
|
106931
|
+
}
|
|
106932
|
+
return out;
|
|
106933
|
+
}
|
|
106934
|
+
async function fetchStatsWindow(media, ids, config, startDate, endDate, verbose) {
|
|
106935
|
+
const isGoogle = media === "Google";
|
|
106936
|
+
const isMetaAd = media === "MetaAd";
|
|
106937
|
+
if (isGoogle) {
|
|
106938
|
+
const params = new URLSearchParams({ startDate, endDate, mediaCustomerIds: ids.join("|") });
|
|
106939
|
+
const url = `${config.apiBaseUrl}/report/media-account/google/account-spend-overview?${params.toString()}`;
|
|
106940
|
+
const raw = await apiFetch2(url, config, {}, verbose);
|
|
106941
|
+
return parseGoogleAccountSpendOverviewRows(raw).map((row) => ({
|
|
106942
|
+
mediaAccountId: row.mediaAccountId,
|
|
106943
|
+
mediaCustomerName: row.mediaCustomerName,
|
|
106944
|
+
spend: row.spend,
|
|
106945
|
+
impressions: row.impressions,
|
|
106946
|
+
clicks: row.clicks,
|
|
106947
|
+
conversions: row.conversions,
|
|
106948
|
+
costPerClick: row.costPerClick,
|
|
106949
|
+
currencyCode: row.currencyCode,
|
|
106950
|
+
remainingAccountBudget: row.remainingAccountBudget,
|
|
106951
|
+
status: row.status
|
|
106952
|
+
}));
|
|
106953
|
+
}
|
|
106954
|
+
if (isMetaAd) {
|
|
106955
|
+
const accountMediaTypes = await lookupMetaMediaAccountTypes(config, ids, verbose);
|
|
106956
|
+
const items2 = [];
|
|
106957
|
+
for (const [route, routeIds] of groupAccountIdsByOverviewRoute(
|
|
106958
|
+
"MetaAd",
|
|
106959
|
+
ids,
|
|
106960
|
+
accountMediaTypes
|
|
106961
|
+
)) {
|
|
106962
|
+
const map2 = await fetchOverviewMap(route, routeIds, config, startDate, endDate, verbose);
|
|
106963
|
+
for (const item of map2.values()) {
|
|
106964
|
+
items2.push(item);
|
|
106965
|
+
}
|
|
106966
|
+
}
|
|
106967
|
+
return items2;
|
|
106968
|
+
}
|
|
106969
|
+
const map = await fetchOverviewMap(
|
|
106970
|
+
media,
|
|
106971
|
+
ids,
|
|
106972
|
+
config,
|
|
106973
|
+
startDate,
|
|
106974
|
+
endDate,
|
|
106975
|
+
verbose
|
|
106976
|
+
);
|
|
106977
|
+
return [...map.values()];
|
|
106978
|
+
}
|
|
106886
106979
|
async function runStats(opts) {
|
|
106887
106980
|
const config = loadConfig(opts.token);
|
|
106888
106981
|
if (!VALID_MEDIA_TYPES3.includes(opts.media)) {
|
|
@@ -106909,57 +107002,35 @@ async function runStats(opts) {
|
|
|
106909
107002
|
);
|
|
106910
107003
|
process.exit(1);
|
|
106911
107004
|
}
|
|
106912
|
-
const ids = opts.accounts.split(",").map((id) => id.trim()).filter(Boolean);
|
|
106913
|
-
const isGoogle = opts.media === "Google";
|
|
106914
|
-
const isMetaAd = opts.media === "MetaAd";
|
|
107005
|
+
const ids = opts.accounts.split(",").map((id) => id.trim()).filter(Boolean).map((id) => normalizeNumericMediaCustomerId(id) ?? id);
|
|
106915
107006
|
let items2;
|
|
106916
107007
|
try {
|
|
106917
|
-
if (
|
|
106918
|
-
const
|
|
106919
|
-
const url = `${config.apiBaseUrl}/report/media-account/google/account-spend-overview?${params.toString()}`;
|
|
106920
|
-
const raw = await apiFetch2(url, config, {}, opts.verbose);
|
|
106921
|
-
items2 = parseGoogleAccountSpendOverviewRows(raw).map((row) => ({
|
|
106922
|
-
mediaAccountId: row.mediaAccountId,
|
|
106923
|
-
mediaCustomerName: row.mediaCustomerName,
|
|
106924
|
-
spend: row.spend,
|
|
106925
|
-
impressions: row.impressions,
|
|
106926
|
-
clicks: row.clicks,
|
|
106927
|
-
conversions: row.conversions,
|
|
106928
|
-
costPerClick: row.costPerClick,
|
|
106929
|
-
currencyCode: row.currencyCode,
|
|
106930
|
-
remainingAccountBudget: row.remainingAccountBudget,
|
|
106931
|
-
status: row.status
|
|
106932
|
-
}));
|
|
106933
|
-
} else if (isMetaAd) {
|
|
106934
|
-
const accountMediaTypes = await lookupMetaMediaAccountTypes(config, ids, opts.verbose);
|
|
107008
|
+
if (opts.byDay) {
|
|
107009
|
+
const days = eachDateInclusive(startDate, endDate);
|
|
106935
107010
|
items2 = [];
|
|
106936
|
-
|
|
106937
|
-
|
|
106938
|
-
|
|
106939
|
-
|
|
106940
|
-
|
|
106941
|
-
|
|
106942
|
-
|
|
106943
|
-
|
|
107011
|
+
console.error(
|
|
107012
|
+
`\u23F3 [stats --by-day] ${opts.media} ${ids.length} \u6237 \xD7 ${days.length} \u5929\uFF08${startDate} ~ ${endDate}\uFF09\u2026`
|
|
107013
|
+
);
|
|
107014
|
+
for (let i = 0; i < days.length; i++) {
|
|
107015
|
+
const day = days[i];
|
|
107016
|
+
if (opts.verbose || days.length > 7) {
|
|
107017
|
+
console.error(` \u2192 [${i + 1}/${days.length}] ${day}`);
|
|
107018
|
+
}
|
|
107019
|
+
const dayItems = await fetchStatsWindow(
|
|
107020
|
+
opts.media,
|
|
107021
|
+
ids,
|
|
106944
107022
|
config,
|
|
106945
|
-
|
|
106946
|
-
|
|
107023
|
+
day,
|
|
107024
|
+
day,
|
|
106947
107025
|
opts.verbose
|
|
106948
107026
|
);
|
|
106949
|
-
for (const
|
|
106950
|
-
items2.push(
|
|
107027
|
+
for (const row of dayItems) {
|
|
107028
|
+
items2.push({ ...row, date: day });
|
|
106951
107029
|
}
|
|
106952
107030
|
}
|
|
107031
|
+
console.error(` \u2713 \u5B8C\u6210\uFF1A${items2.length} \u6761\u6309\u65E5\u884C`);
|
|
106953
107032
|
} else {
|
|
106954
|
-
|
|
106955
|
-
opts.media,
|
|
106956
|
-
ids,
|
|
106957
|
-
config,
|
|
106958
|
-
startDate,
|
|
106959
|
-
endDate,
|
|
106960
|
-
opts.verbose
|
|
106961
|
-
);
|
|
106962
|
-
items2 = [...map.values()];
|
|
107033
|
+
items2 = await fetchStatsWindow(opts.media, ids, config, startDate, endDate, opts.verbose);
|
|
106963
107034
|
}
|
|
106964
107035
|
} catch (err) {
|
|
106965
107036
|
const message = err instanceof Error ? err.message : String(err);
|
|
@@ -106978,17 +107049,18 @@ async function runStats(opts) {
|
|
|
106978
107049
|
process.exit(1);
|
|
106979
107050
|
}
|
|
106980
107051
|
const n = items2.length;
|
|
107052
|
+
const section = opts.byDay ? `stats-${opts.media}-by-day` : `stats-${opts.media}`;
|
|
106981
107053
|
const statsPayload = wrapListJson({ page: 1, pageSize: Math.max(n, 1), total: n, items: items2 });
|
|
106982
107054
|
if (await emitCliJsonOrSnapshot(opts, {
|
|
106983
|
-
section
|
|
107055
|
+
section,
|
|
106984
107056
|
commandLabel: "stats",
|
|
106985
|
-
commandHint: opts.media,
|
|
107057
|
+
commandHint: opts.byDay ? `${opts.media}-by-day` : opts.media,
|
|
106986
107058
|
payload: statsPayload,
|
|
106987
|
-
idSuffix: opts.media
|
|
107059
|
+
idSuffix: opts.byDay ? `${opts.media}-by-day` : opts.media
|
|
106988
107060
|
})) {
|
|
106989
107061
|
return;
|
|
106990
107062
|
}
|
|
106991
|
-
const rangeLabel = `${startDate} ~ ${endDate}`;
|
|
107063
|
+
const rangeLabel = opts.byDay ? `${startDate} ~ ${endDate}\uFF08\u6309\u65E5\uFF09` : `${startDate} ~ ${endDate}`;
|
|
106992
107064
|
if (items2.length === 0) {
|
|
106993
107065
|
console.log(`
|
|
106994
107066
|
${opts.media} \u6295\u653E\u6570\u636E\uFF08${rangeLabel}\uFF09\uFF08\u7B2C 1 \u9875\uFF0C\u672C\u9875 0 \u6761\uFF0C\u5171 0 \u6761\uFF09
|
|
@@ -107001,7 +107073,16 @@ ${opts.media} \u6295\u653E\u6570\u636E\uFF08${rangeLabel}\uFF09\uFF08\u7B2C 1 \u
|
|
|
107001
107073
|
${opts.media} \u6295\u653E\u6570\u636E\uFF08${rangeLabel}\uFF09\uFF08\u7B2C 1 \u9875\uFF0C\u672C\u9875 ${items2.length} \u6761\uFF0C\u5171 ${items2.length} \u6761\uFF09
|
|
107002
107074
|
`
|
|
107003
107075
|
);
|
|
107004
|
-
const cols = [
|
|
107076
|
+
const cols = opts.byDay ? [
|
|
107077
|
+
{ key: "date", header: "\u65E5\u671F" },
|
|
107078
|
+
{ key: "id", header: "\u8D26\u6237ID" },
|
|
107079
|
+
{ key: "name", header: "\u8D26\u6237\u540D\u79F0" },
|
|
107080
|
+
{ key: "spend", header: "\u6D88\u8017" },
|
|
107081
|
+
{ key: "impressions", header: "\u5C55\u793A\u6B21\u6570" },
|
|
107082
|
+
{ key: "clicks", header: "\u70B9\u51FB\u6B21\u6570" },
|
|
107083
|
+
{ key: "conversions", header: "\u8F6C\u5316\u6B21\u6570" },
|
|
107084
|
+
{ key: "cpc", header: "\u70B9\u51FB\u5747\u4EF7" }
|
|
107085
|
+
] : [
|
|
107005
107086
|
{ key: "id", header: "\u8D26\u6237ID" },
|
|
107006
107087
|
{ key: "name", header: "\u8D26\u6237\u540D\u79F0" },
|
|
107007
107088
|
{ key: "spend", header: "\u6D88\u8017" },
|
|
@@ -107019,7 +107100,7 @@ ${opts.media} \u6295\u653E\u6570\u636E\uFF08${rangeLabel}\uFF09\uFF08\u7B2C 1 \u
|
|
|
107019
107100
|
totalImpressions += item.impressions ?? 0;
|
|
107020
107101
|
totalClicks += item.clicks ?? 0;
|
|
107021
107102
|
totalConversions += item.conversions ?? 0;
|
|
107022
|
-
|
|
107103
|
+
const base = {
|
|
107023
107104
|
id: item.mediaAccountId ?? "",
|
|
107024
107105
|
name: item.mediaCustomerName ?? "",
|
|
107025
107106
|
spend: item.spend?.toFixed(2) ?? "0.00",
|
|
@@ -107028,27 +107109,45 @@ ${opts.media} \u6295\u653E\u6570\u636E\uFF08${rangeLabel}\uFF09\uFF08\u7B2C 1 \u
|
|
|
107028
107109
|
conversions: String(item.conversions ?? 0),
|
|
107029
107110
|
cpc: item.costPerClick?.toFixed(4) ?? "0.0000"
|
|
107030
107111
|
};
|
|
107112
|
+
return opts.byDay ? { date: item.date ?? "", ...base } : base;
|
|
107031
107113
|
});
|
|
107032
107114
|
if (items2.length > 1) {
|
|
107033
107115
|
const avgCpc = totalClicks > 0 ? (totalSpend / totalClicks).toFixed(4) : "0.0000";
|
|
107034
|
-
rows.push(
|
|
107035
|
-
|
|
107036
|
-
|
|
107037
|
-
|
|
107038
|
-
|
|
107039
|
-
|
|
107040
|
-
|
|
107041
|
-
|
|
107042
|
-
|
|
107116
|
+
rows.push(
|
|
107117
|
+
opts.byDay ? {
|
|
107118
|
+
date: "\u5408\u8BA1",
|
|
107119
|
+
id: "",
|
|
107120
|
+
name: "",
|
|
107121
|
+
spend: totalSpend.toFixed(2),
|
|
107122
|
+
impressions: String(totalImpressions),
|
|
107123
|
+
clicks: String(totalClicks),
|
|
107124
|
+
conversions: String(totalConversions),
|
|
107125
|
+
cpc: avgCpc
|
|
107126
|
+
} : {
|
|
107127
|
+
id: "\u5408\u8BA1",
|
|
107128
|
+
name: "",
|
|
107129
|
+
spend: totalSpend.toFixed(2),
|
|
107130
|
+
impressions: String(totalImpressions),
|
|
107131
|
+
clicks: String(totalClicks),
|
|
107132
|
+
conversions: String(totalConversions),
|
|
107133
|
+
cpc: avgCpc
|
|
107134
|
+
}
|
|
107135
|
+
);
|
|
107043
107136
|
}
|
|
107044
107137
|
printCliTable(rows, cols);
|
|
107045
107138
|
console.log();
|
|
107046
107139
|
}
|
|
107047
107140
|
function register11(program2) {
|
|
107048
|
-
program2.command("stats").description(
|
|
107141
|
+
program2.command("stats").description(
|
|
107142
|
+
"\u67E5\u8BE2\u5E7F\u544A\u6D88\u8017\u3001\u70B9\u51FB\u3001\u8F6C\u5316\u7B49\u6295\u653E\u6570\u636E\uFF08\u9ED8\u8BA4\u8FD1 7 \u5929\u533A\u95F4\u5408\u8BA1\uFF0C\u4E0D\u542B\u4ECA\u5929\uFF1B\u8981\u6309\u65E5\u660E\u7EC6\u52A0 --by-day\uFF09"
|
|
107143
|
+
).requiredOption(
|
|
107049
107144
|
"-m, --media <type>",
|
|
107050
107145
|
"\u5A92\u4F53\u7C7B\u578B\uFF1AGoogle | TikTok | Yandex | MetaAd | BingV2 | Kwai"
|
|
107051
|
-
).option("-a, --accounts <ids>", "\u8D26\u6237
|
|
107146
|
+
).option("-a, --accounts <ids>", "\u8D26\u6237 mediaCustomerId\uFF0C\u591A\u4E2A\u7528\u9017\u53F7\u5206\u9694\uFF08\u5FC5\u586B\uFF09").option("--start <date>", "\u5F00\u59CB\u65E5\u671F\uFF0C\u683C\u5F0F YYYY-MM-DD\uFF08\u9ED8\u8BA4 7 \u5929\u524D\uFF09").option("--end <date>", "\u7ED3\u675F\u65E5\u671F\uFF0C\u683C\u5F0F YYYY-MM-DD\uFF08\u9ED8\u8BA4\u6628\u5929\uFF09").option("--start-date <date>", "\u540C --start\uFF08\u6587\u6863/Playbook \u517C\u5BB9\u522B\u540D\uFF09").option("--end-date <date>", "\u540C --end\uFF08\u6587\u6863/Playbook \u517C\u5BB9\u522B\u540D\uFF09").option(
|
|
107147
|
+
"--by-day",
|
|
107148
|
+
"\u6309\u65E5\u660E\u7EC6\uFF1A\u5BF9\u533A\u95F4\u5185\u6BCF\u4E00\u5929\u5206\u522B\u62C9\u6570\uFF0Citems[] \u6BCF\u884C\u5E26 date\uFF1B\u5BFC\u51FA Excel/\u6309\u65E5\u8D8B\u52BF\u5FC5\u52A0\u3002\u9ED8\u8BA4\u4E0D\u52A0\u5219\u53EA\u8FD4\u56DE\u533A\u95F4\u5408\u8BA1\u4E00\u884C",
|
|
107149
|
+
false
|
|
107150
|
+
).option("-t, --token <token>", "Token\uFF08\u53EF\u9009\uFF1B\u4F18\u5148\u4E8E ~/.siluzan/config.json\uFF09").option(
|
|
107052
107151
|
"--json-out <path>",
|
|
107053
107152
|
"\u843D\u76D8\uFF08\u76EE\u5F55\u6216 *.json \u6587\u4EF6\u8DEF\u5F84\uFF09\u5E76\u66F4\u65B0 cli-manifest[-<\u67E5\u8BE2id>].json\uFF1B\u76EE\u5F55\u6A21\u5F0F\u6587\u4EF6\u540D\u4E3A `<section>[-<\u67E5\u8BE2id>].json`\uFF1Bstdout \u4E00\u884C\u6458\u8981 JSON\uFF0C\u542B outlineFile\uFF08TS \u5F0F\u7C7B\u578B\u5728 `*.outline.txt`\uFF09",
|
|
107054
107153
|
void 0
|
|
@@ -107060,6 +107159,7 @@ function register11(program2) {
|
|
|
107060
107159
|
accounts: opts.accounts,
|
|
107061
107160
|
startDate: opts.start ?? opts.startDate,
|
|
107062
107161
|
endDate: opts.end ?? opts.endDate,
|
|
107162
|
+
byDay: opts.byDay,
|
|
107063
107163
|
jsonOut: opts.jsonOut,
|
|
107064
107164
|
verbose: opts.verbose
|
|
107065
107165
|
});
|
|
@@ -131871,7 +131971,10 @@ configureCliJsonSnapshot({
|
|
|
131871
131971
|
fieldGuideRefs: [
|
|
131872
131972
|
"references/accounts/currency.md",
|
|
131873
131973
|
"references/core/tips.md",
|
|
131874
|
-
"references/accounts/accounts.md"
|
|
131974
|
+
"references/accounts/accounts.md",
|
|
131975
|
+
"references/accounts/accounts-list.md",
|
|
131976
|
+
"references/accounts/accounts-balance-stats.md",
|
|
131977
|
+
"references/accounts/accounts-permissions.md"
|
|
131875
131978
|
]
|
|
131876
131979
|
});
|
|
131877
131980
|
var program = new Command5();
|
package/dist/skill/AGENTS.md
CHANGED
|
@@ -1,61 +1,28 @@
|
|
|
1
1
|
# siluzan-tso — Agent 文档目录
|
|
2
2
|
|
|
3
|
-
>
|
|
3
|
+
> 运行时入口:`SKILL.md` → 按路由表 Read **leaf** 文档。维护时对齐 `references/core/skill-authoring.md`。
|
|
4
4
|
|
|
5
5
|
## 启动顺序
|
|
6
6
|
|
|
7
|
-
1. Read `SKILL.md
|
|
8
|
-
2.
|
|
9
|
-
3.
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
- 命令参数/字段口径 → 各域 `references/*.md`
|
|
13
|
-
4. **P5 / P6 / P7** 或长 CLI 输出:可选 Read `references/core/subagent-orchestration.md`(主 Agent 自行决定是否委派 subagent)
|
|
7
|
+
1. Read `SKILL.md` 路由表,锁定唯一工作流
|
|
8
|
+
2. 报告类模糊 → Read `references/core/intent-routing.md`
|
|
9
|
+
3. Read 路由行「必读文档」+ 对应 `playbooks.md` / `workflows.md` 卡片(**直接读 leaf**,不必先经 `accounts.md` 索引)
|
|
10
|
+
4. 写操作 / 报告交付 / 批量拉数 → Read `references/core/agent-conventions.md` 相关节
|
|
11
|
+
5. P5/P6/P7 或长 CLI:可选 `references/core/subagent-orchestration.md`
|
|
14
12
|
|
|
15
|
-
##
|
|
13
|
+
## 文档域
|
|
16
14
|
|
|
17
|
-
| 域
|
|
18
|
-
|
|
|
19
|
-
|
|
|
20
|
-
|
|
|
21
|
-
|
|
|
22
|
-
|
|
|
23
|
-
|
|
|
24
|
-
|
|
|
25
|
-
| **Templates** | `assets/`、`references/report-templates/`、`report-templates/*.html` | JSON 契约、报告纲要、HTML 样式 |
|
|
26
|
-
|
|
27
|
-
## 工作流目录
|
|
28
|
-
|
|
29
|
-
| 类别 | 文档 | 编号 |
|
|
30
|
-
| ------------- | ------------------------------ | ------ |
|
|
31
|
-
| 分析 / 报告类 | `references/core/playbooks.md` | P1–P9 |
|
|
32
|
-
| 操作 / 管理类 | `references/core/workflows.md` | W1–W12 |
|
|
33
|
-
|
|
34
|
-
专用报告模板(被工作流卡片引用):
|
|
35
|
-
|
|
36
|
-
| ID | 文档 |
|
|
37
|
-
| ----------------- | ----------------------------------------------------------------- |
|
|
38
|
-
| 网站诊断 | `references/report-templates/website-diagnosis-report.md` |
|
|
39
|
-
| 战略市场分析 | `references/report-templates/market-analysis-report.md` |
|
|
40
|
-
| Google 周期 Excel | `references/report-templates/google-period-report-excel.md`(P4) |
|
|
41
|
-
| OKKI 周报 | `references/report-templates/okki-weekly-google-client.md` |
|
|
42
|
-
| 询盘分析 | `references/report-templates/google-inquiry-analysis.md` |
|
|
15
|
+
| 域 | 路径 | 何时 Read |
|
|
16
|
+
| -- | ---- | --------- |
|
|
17
|
+
| Core | `references/core/` | 纪律、intent-routing、playbooks、workflows |
|
|
18
|
+
| Accounts | `references/accounts/` | `accounts-list` / `accounts-balance-stats` / `accounts-permissions`(`accounts.md` 仅索引) |
|
|
19
|
+
| Google Ads | `references/google-ads/` | `google-ads-read` / `write` / `batch`(索引:`google-ads.md`);`rules/` 先 README 再单文件 |
|
|
20
|
+
| Analytics | `references/analytics/` | 拉数、批处理、拓词、RAG |
|
|
21
|
+
| Operations | `references/operations/` | 预警、线索;自动化仅用户问起时 |
|
|
22
|
+
| Templates | `report-templates/*.md`、`assets/` | 报告纲要 / JSON 契约;**禁止** Read `*.html` |
|
|
43
23
|
|
|
44
24
|
## 维护
|
|
45
25
|
|
|
46
|
-
-
|
|
47
|
-
-
|
|
48
|
-
|
|
49
|
-
## CLI 代码域(与文档对齐)
|
|
50
|
-
|
|
51
|
-
| CLI 模块 | 文档域 |
|
|
52
|
-
| ----------------------------------------------------------------------- | ------------------------------------- |
|
|
53
|
-
| `src/commands/list-accounts/`、`accounts-digest/`、`balance-scan/` | accounts |
|
|
54
|
-
| `src/commands/open-account/`、`account-manage-register.ts` | accounts |
|
|
55
|
-
| `src/commands/ad/` | google-ads |
|
|
56
|
-
| `src/commands/google-analysis/`、`google-analysis-batch.ts` | analytics |
|
|
57
|
-
| `src/commands/facebook-analysis/`、`bing-analysis/`、`tiktok-analysis/` | analytics(架构对齐 google-analysis) |
|
|
58
|
-
| `src/commands/website-diagnosis/` | analytics(网站诊断) |
|
|
59
|
-
| `src/commands/market-analysis/` | analytics(战略市场分析) |
|
|
60
|
-
| `src/commands/report/` | analytics + report-templates |
|
|
61
|
-
| `src/commands/forewarning/`、`optimize/`、`clue.ts` | operations |
|
|
26
|
+
- 源码:`tso-cli/assets/siluzan-ads/`
|
|
27
|
+
- 纪律真相源:`references/core/agent-conventions.md`
|
|
28
|
+
- 规范:`references/core/skill-authoring.md`
|