siluzan-tso-cli 1.1.30-beta.5 → 1.1.30-beta.7
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 +282 -74
- package/dist/skill/SKILL.md +34 -34
- package/dist/skill/_meta.json +2 -2
- package/dist/skill/assets/campaign-create-template.md +1 -1
- package/dist/skill/references/README.md +35 -35
- package/dist/skill/references/accounts/accounts.md +10 -7
- package/dist/skill/references/accounts/currency.md +2 -2
- package/dist/skill/references/accounts/open-account-google-ui.md +1 -1
- package/dist/skill/references/analytics/account-analytics.md +2 -2
- package/dist/skill/references/analytics/keyword-planner-workflows.md +3 -3
- package/dist/skill/references/analytics/rag.md +4 -4
- package/dist/skill/references/analytics/website-diagnosis-guide.md +1 -1
- package/dist/skill/references/core/agent-conventions.md +4 -4
- package/dist/skill/references/core/playbooks.md +11 -11
- package/dist/skill/references/core/subagent-orchestration.md +5 -5
- package/dist/skill/references/core/tips.md +1 -1
- package/dist/skill/references/core/workflows.md +25 -25
- package/dist/skill/references/google-ads/google-ads-campaign-plan.md +18 -18
- package/dist/skill/references/google-ads/google-ads.md +4 -4
- package/dist/skill/references/google-ads/rules/README.md +1 -1
- package/dist/skill/references/operations/hosted-automation-monitoring-json.md +4 -4
- package/dist/skill/references/operations/hosted-automation-optimize-ab-winner.md +2 -2
- package/dist/skill/references/operations/hosted-automation-optimize-index.md +5 -5
- package/dist/skill/references/operations/hosted-automation-optimize-scale.md +1 -1
- package/dist/skill/references/operations/hosted-automation-optimize-weak-downbid.md +5 -5
- package/dist/skill/references/operations/hosted-automation-scenarios.md +4 -4
- package/dist/skill/references/operations/hosted-automation-self-control.md +7 -7
- package/dist/skill/references/operations/hosted-automation-user-catalog.md +12 -12
- package/dist/skill/references/report-templates/google-inquiry-analysis.md +2 -2
- package/dist/skill/references/report-templates/google-period-report-excel.md +3 -3
- package/dist/skill/report-templates/google-inquiry-analysis.md +2 -2
- package/dist/skill/report-templates/google-period-report-excel.md +3 -3
- package/dist/skill/report-templates/website-diagnosis-report.html +0 -25
- 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.30-beta.
|
|
54
|
+
> **注意**:当前为测试版(1.1.30-beta.7),供内部测试使用。正式发布后安装命令将改为 `npm install -g siluzan-tso-cli`。
|
|
55
55
|
|
|
56
56
|
| 助手 | 建议 `--ai` |
|
|
57
57
|
| ----------------------- | ------------------------------------ |
|
package/dist/index.js
CHANGED
|
@@ -4170,11 +4170,27 @@ function defaultDateRange() {
|
|
|
4170
4170
|
start.setDate(start.getDate() - 6);
|
|
4171
4171
|
return { startDate: fmt(start), endDate: fmt(end) };
|
|
4172
4172
|
}
|
|
4173
|
+
function resolveAccountOverviewMediaRoute(cliMedia, accountMediaAccountType) {
|
|
4174
|
+
if (cliMedia === "MetaAd" && accountMediaAccountType === "FacebookAds") {
|
|
4175
|
+
return "FacebookAds";
|
|
4176
|
+
}
|
|
4177
|
+
return cliMedia;
|
|
4178
|
+
}
|
|
4179
|
+
function groupAccountIdsByOverviewRoute(cliMedia, accountIds, accountMediaTypes) {
|
|
4180
|
+
const groups = /* @__PURE__ */ new Map();
|
|
4181
|
+
for (const id of accountIds) {
|
|
4182
|
+
const route = resolveAccountOverviewMediaRoute(cliMedia, accountMediaTypes?.get(id));
|
|
4183
|
+
const list = groups.get(route) ?? [];
|
|
4184
|
+
list.push(id);
|
|
4185
|
+
groups.set(route, list);
|
|
4186
|
+
}
|
|
4187
|
+
return groups;
|
|
4188
|
+
}
|
|
4173
4189
|
async function fetchBalanceMap(media, accountIds, config, startDate, endDate, verbose) {
|
|
4174
4190
|
const result = /* @__PURE__ */ new Map();
|
|
4175
|
-
if (accountIds.length === 0
|
|
4191
|
+
if (accountIds.length === 0) return result;
|
|
4176
4192
|
try {
|
|
4177
|
-
if (["Google", "Yandex", "TikTok", "BingV2"].includes(media)) {
|
|
4193
|
+
if (["Google", "Yandex", "TikTok", "BingV2", "MetaAd"].includes(media)) {
|
|
4178
4194
|
const params = new URLSearchParams({ ids: accountIds.join("|") });
|
|
4179
4195
|
const url = `${config.apiBaseUrl}/query/media-account/${media}/GetMediaAccountInfo?${params}`;
|
|
4180
4196
|
const raw = await apiFetch2(
|
|
@@ -4284,39 +4300,87 @@ function parseGoogleAccountSpendOverviewRows(raw) {
|
|
|
4284
4300
|
const items = Array.isArray(r.items) ? r.items : [];
|
|
4285
4301
|
return items.map(fromDbItem).filter((row) => row !== null);
|
|
4286
4302
|
}
|
|
4287
|
-
async function fetchOverviewMap(
|
|
4303
|
+
async function fetchOverviewMap(route, accountIds, config, startDate, endDate, verbose) {
|
|
4288
4304
|
const result = /* @__PURE__ */ new Map();
|
|
4289
|
-
if (accountIds.length === 0
|
|
4305
|
+
if (accountIds.length === 0) return result;
|
|
4290
4306
|
const range = defaultDateRange();
|
|
4291
4307
|
const start = startDate ?? range.startDate;
|
|
4292
4308
|
const end = endDate ?? range.endDate;
|
|
4293
4309
|
try {
|
|
4294
|
-
if (
|
|
4295
|
-
const
|
|
4310
|
+
if (route === "Google") {
|
|
4311
|
+
const params = new URLSearchParams({
|
|
4296
4312
|
startDate: start,
|
|
4297
4313
|
endDate: end,
|
|
4298
4314
|
mediaCustomerIds: accountIds.join("|")
|
|
4299
4315
|
});
|
|
4300
|
-
const
|
|
4301
|
-
const
|
|
4302
|
-
const rows = parseGoogleAccountSpendOverviewRows(
|
|
4316
|
+
const url = `${config.apiBaseUrl}/report/media-account/google/account-spend-overview?${params}`;
|
|
4317
|
+
const raw = await apiFetch2(url, config, {}, verbose);
|
|
4318
|
+
const rows = parseGoogleAccountSpendOverviewRows(raw);
|
|
4303
4319
|
for (const row of rows) {
|
|
4304
4320
|
result.set(row.mediaAccountId, row);
|
|
4305
4321
|
}
|
|
4306
4322
|
return result;
|
|
4307
4323
|
}
|
|
4308
|
-
const
|
|
4309
|
-
|
|
4310
|
-
|
|
4311
|
-
|
|
4312
|
-
|
|
4313
|
-
|
|
4314
|
-
|
|
4315
|
-
|
|
4316
|
-
|
|
4317
|
-
|
|
4318
|
-
|
|
4319
|
-
|
|
4324
|
+
const fetchLegacyBatch = async (ids) => {
|
|
4325
|
+
const batch = /* @__PURE__ */ new Map();
|
|
4326
|
+
const params = new URLSearchParams({
|
|
4327
|
+
period: "true",
|
|
4328
|
+
startDate: start,
|
|
4329
|
+
endDate: end,
|
|
4330
|
+
mediaCustomerIds: ids.join(",")
|
|
4331
|
+
});
|
|
4332
|
+
const url = `${config.apiBaseUrl}/report/media-account/${route}/accountsoverview?${params}`;
|
|
4333
|
+
const raw = await apiFetch2(url, config, {}, verbose);
|
|
4334
|
+
const items = Array.isArray(raw) ? raw : [];
|
|
4335
|
+
for (const item of items) {
|
|
4336
|
+
if (item.mediaAccountId != null) {
|
|
4337
|
+
batch.set(String(item.mediaAccountId), item);
|
|
4338
|
+
}
|
|
4339
|
+
}
|
|
4340
|
+
return batch;
|
|
4341
|
+
};
|
|
4342
|
+
const mergeOverview = (batch) => {
|
|
4343
|
+
for (const [k, v] of batch) result.set(k, v);
|
|
4344
|
+
};
|
|
4345
|
+
if (accountIds.length === 1) {
|
|
4346
|
+
mergeOverview(await fetchLegacyBatch(accountIds));
|
|
4347
|
+
return result;
|
|
4348
|
+
}
|
|
4349
|
+
try {
|
|
4350
|
+
const batch = await fetchLegacyBatch(accountIds);
|
|
4351
|
+
mergeOverview(batch);
|
|
4352
|
+
if (batch.size === 0) {
|
|
4353
|
+
for (const id of accountIds) {
|
|
4354
|
+
try {
|
|
4355
|
+
mergeOverview(await fetchLegacyBatch([id]));
|
|
4356
|
+
} catch (singleErr) {
|
|
4357
|
+
if (verbose) {
|
|
4358
|
+
process.stderr.write(
|
|
4359
|
+
`[fetchOverviewMap] \u9010\u6237\u91CD\u8BD5\u5931\u8D25 ${id}\uFF1A${singleErr instanceof Error ? singleErr.message : String(singleErr)}
|
|
4360
|
+
`
|
|
4361
|
+
);
|
|
4362
|
+
}
|
|
4363
|
+
}
|
|
4364
|
+
}
|
|
4365
|
+
}
|
|
4366
|
+
} catch (err) {
|
|
4367
|
+
if (verbose) {
|
|
4368
|
+
process.stderr.write(
|
|
4369
|
+
`[fetchOverviewMap] \u6279\u91CF\u5F02\u5E38\uFF0C\u9010\u6237\u91CD\u8BD5\uFF1A${err instanceof Error ? err.message : String(err)}
|
|
4370
|
+
`
|
|
4371
|
+
);
|
|
4372
|
+
}
|
|
4373
|
+
for (const id of accountIds) {
|
|
4374
|
+
try {
|
|
4375
|
+
mergeOverview(await fetchLegacyBatch([id]));
|
|
4376
|
+
} catch (singleErr) {
|
|
4377
|
+
if (verbose) {
|
|
4378
|
+
process.stderr.write(
|
|
4379
|
+
`[fetchOverviewMap] \u9010\u6237\u91CD\u8BD5\u5931\u8D25 ${id}\uFF1A${singleErr instanceof Error ? singleErr.message : String(singleErr)}
|
|
4380
|
+
`
|
|
4381
|
+
);
|
|
4382
|
+
}
|
|
4383
|
+
}
|
|
4320
4384
|
}
|
|
4321
4385
|
}
|
|
4322
4386
|
} catch (err) {
|
|
@@ -4339,7 +4403,8 @@ var init_balance = __esm({
|
|
|
4339
4403
|
"Yandex",
|
|
4340
4404
|
"TikTok",
|
|
4341
4405
|
"BingV2",
|
|
4342
|
-
"Kwai"
|
|
4406
|
+
"Kwai",
|
|
4407
|
+
"MetaAd"
|
|
4343
4408
|
];
|
|
4344
4409
|
}
|
|
4345
4410
|
});
|
|
@@ -4373,16 +4438,25 @@ async function fetchBalanceAndOverviewSequential(opts) {
|
|
|
4373
4438
|
const ids = chunks[chunkIdx];
|
|
4374
4439
|
const oneBased = chunkIdx + 1;
|
|
4375
4440
|
opts.onChunkStart?.(oneBased, chunks.length, ids);
|
|
4376
|
-
const
|
|
4441
|
+
const routeGroups = groupAccountIdsByOverviewRoute(
|
|
4377
4442
|
media,
|
|
4378
4443
|
ids,
|
|
4379
|
-
|
|
4380
|
-
startDate,
|
|
4381
|
-
endDate,
|
|
4382
|
-
verbose
|
|
4444
|
+
opts.accountMediaTypes
|
|
4383
4445
|
);
|
|
4384
|
-
|
|
4385
|
-
for (const [
|
|
4446
|
+
let chunkOverviewSize = 0;
|
|
4447
|
+
for (const [route, routeIds] of routeGroups) {
|
|
4448
|
+
const overviewChunk = await fetchOverviewMap(
|
|
4449
|
+
route,
|
|
4450
|
+
routeIds,
|
|
4451
|
+
config,
|
|
4452
|
+
startDate,
|
|
4453
|
+
endDate,
|
|
4454
|
+
verbose
|
|
4455
|
+
);
|
|
4456
|
+
chunkOverviewSize += overviewChunk.size;
|
|
4457
|
+
for (const [k, v] of overviewChunk) overviewMap.set(k, v);
|
|
4458
|
+
}
|
|
4459
|
+
opts.onOverviewDone?.(oneBased, chunks.length, ids, chunkOverviewSize);
|
|
4386
4460
|
const balanceChunk = await fetchBalanceMap(
|
|
4387
4461
|
media,
|
|
4388
4462
|
ids,
|
|
@@ -4403,6 +4477,143 @@ var init_media_account_batch = __esm({
|
|
|
4403
4477
|
}
|
|
4404
4478
|
});
|
|
4405
4479
|
|
|
4480
|
+
// src/utils/media-account-lookup.ts
|
|
4481
|
+
function pickMediaCustomerName(items, mediaCustomerId) {
|
|
4482
|
+
const list = Array.isArray(items) ? items : [];
|
|
4483
|
+
const target = mediaCustomerId.trim();
|
|
4484
|
+
for (const item of list) {
|
|
4485
|
+
const cid = String(item.ma?.mediaCustomerId ?? "");
|
|
4486
|
+
if (cid === target) {
|
|
4487
|
+
const name2 = String(item.ma?.mediaCustomerName ?? "").trim();
|
|
4488
|
+
return name2 || null;
|
|
4489
|
+
}
|
|
4490
|
+
}
|
|
4491
|
+
return null;
|
|
4492
|
+
}
|
|
4493
|
+
function metaAccountIdDigits(raw) {
|
|
4494
|
+
const t = raw.trim();
|
|
4495
|
+
if (t.startsWith("act_")) return t.slice(4);
|
|
4496
|
+
return t;
|
|
4497
|
+
}
|
|
4498
|
+
function idsMatch(a, b) {
|
|
4499
|
+
return metaAccountIdDigits(a) === metaAccountIdDigits(b);
|
|
4500
|
+
}
|
|
4501
|
+
async function lookupFromMediaAccountQuery(apiBaseUrl, config, mediaType, mediaCustomerId, verbose) {
|
|
4502
|
+
const params = new URLSearchParams({
|
|
4503
|
+
MediaType: mediaType,
|
|
4504
|
+
mediaAccountState: "Approved,Linked",
|
|
4505
|
+
pageNo: "1",
|
|
4506
|
+
pageSize: "20",
|
|
4507
|
+
mediaCustomerId: mediaCustomerId.trim()
|
|
4508
|
+
});
|
|
4509
|
+
const data = await apiFetch2(
|
|
4510
|
+
`${apiBaseUrl}/query/media-account/?${params}`,
|
|
4511
|
+
config,
|
|
4512
|
+
{},
|
|
4513
|
+
verbose
|
|
4514
|
+
);
|
|
4515
|
+
return pickMediaCustomerName(data, mediaCustomerId);
|
|
4516
|
+
}
|
|
4517
|
+
async function lookupMediaCustomerName(apiBaseUrl, config, mediaType, mediaCustomerId, verbose = false) {
|
|
4518
|
+
const id = mediaCustomerId.trim();
|
|
4519
|
+
if (!id) return null;
|
|
4520
|
+
if (mediaType === "Google" || mediaType === "Yandex") {
|
|
4521
|
+
return lookupFromMediaAccountQuery(apiBaseUrl, config, mediaType, id, verbose);
|
|
4522
|
+
}
|
|
4523
|
+
return null;
|
|
4524
|
+
}
|
|
4525
|
+
async function lookupMetaMediaAccountTypes(config, accountIds, verbose = false) {
|
|
4526
|
+
const result = /* @__PURE__ */ new Map();
|
|
4527
|
+
const pending = new Set(accountIds.map((id) => id.trim()).filter(Boolean));
|
|
4528
|
+
if (pending.size === 0) return result;
|
|
4529
|
+
const CHUNK = 50;
|
|
4530
|
+
const ids = [...pending];
|
|
4531
|
+
for (let i = 0; i < ids.length; i += CHUNK) {
|
|
4532
|
+
const chunk = ids.slice(i, i + CHUNK);
|
|
4533
|
+
const params = new URLSearchParams({
|
|
4534
|
+
MediaTypes: "MetaAd|FacebookAds",
|
|
4535
|
+
advStatus: "",
|
|
4536
|
+
mediaAccountState: "Approved,Linked",
|
|
4537
|
+
isForce: "false",
|
|
4538
|
+
pageNum: "1",
|
|
4539
|
+
pageSize: String(Math.max(20, chunk.length)),
|
|
4540
|
+
mediaCustomerIds: chunk.join(",")
|
|
4541
|
+
});
|
|
4542
|
+
try {
|
|
4543
|
+
const data = await apiFetch2(
|
|
4544
|
+
`${config.apiBaseUrl}/query/media-account/SearchMediaAcountByCriteria?${params}`,
|
|
4545
|
+
config,
|
|
4546
|
+
{},
|
|
4547
|
+
verbose
|
|
4548
|
+
);
|
|
4549
|
+
for (const item of data?.mas ?? []) {
|
|
4550
|
+
const ma = item.ma ?? {};
|
|
4551
|
+
const cid = String(ma.mediaCustomerId ?? "");
|
|
4552
|
+
const typ = String(ma.mediaAccountType ?? "").trim();
|
|
4553
|
+
if (!cid || !typ) continue;
|
|
4554
|
+
for (const inputId of chunk) {
|
|
4555
|
+
if (idsMatch(inputId, cid)) {
|
|
4556
|
+
result.set(inputId, typ);
|
|
4557
|
+
pending.delete(inputId);
|
|
4558
|
+
}
|
|
4559
|
+
}
|
|
4560
|
+
}
|
|
4561
|
+
} catch {
|
|
4562
|
+
}
|
|
4563
|
+
}
|
|
4564
|
+
for (const inputId of [...pending]) {
|
|
4565
|
+
for (const idCandidate of [inputId, `act_${metaAccountIdDigits(inputId)}`]) {
|
|
4566
|
+
const params = new URLSearchParams({
|
|
4567
|
+
MediaTypes: "MetaAd|FacebookAds",
|
|
4568
|
+
advStatus: "",
|
|
4569
|
+
mediaAccountState: "Approved,Linked",
|
|
4570
|
+
isForce: "false",
|
|
4571
|
+
pageNum: "1",
|
|
4572
|
+
pageSize: "20",
|
|
4573
|
+
mediaCustomerIds: idCandidate
|
|
4574
|
+
});
|
|
4575
|
+
try {
|
|
4576
|
+
const data = await apiFetch2(
|
|
4577
|
+
`${config.apiBaseUrl}/query/media-account/SearchMediaAcountByCriteria?${params}`,
|
|
4578
|
+
config,
|
|
4579
|
+
{},
|
|
4580
|
+
verbose
|
|
4581
|
+
);
|
|
4582
|
+
for (const item of data?.mas ?? []) {
|
|
4583
|
+
const ma = item.ma ?? {};
|
|
4584
|
+
const cid = String(ma.mediaCustomerId ?? "");
|
|
4585
|
+
if (idsMatch(inputId, cid)) {
|
|
4586
|
+
result.set(inputId, String(ma.mediaAccountType ?? "FacebookAds"));
|
|
4587
|
+
pending.delete(inputId);
|
|
4588
|
+
break;
|
|
4589
|
+
}
|
|
4590
|
+
}
|
|
4591
|
+
} catch {
|
|
4592
|
+
}
|
|
4593
|
+
if (!pending.has(inputId)) break;
|
|
4594
|
+
}
|
|
4595
|
+
if (!result.has(inputId)) {
|
|
4596
|
+
result.set(inputId, "FacebookAds");
|
|
4597
|
+
}
|
|
4598
|
+
}
|
|
4599
|
+
return result;
|
|
4600
|
+
}
|
|
4601
|
+
function buildAccountMediaTypesMap(items) {
|
|
4602
|
+
const map = /* @__PURE__ */ new Map();
|
|
4603
|
+
for (const item of items) {
|
|
4604
|
+
const id = item.ma?.mediaCustomerId;
|
|
4605
|
+
const typ = item.ma?.mediaAccountType;
|
|
4606
|
+
if (id && typ) map.set(String(id), String(typ));
|
|
4607
|
+
}
|
|
4608
|
+
return map;
|
|
4609
|
+
}
|
|
4610
|
+
var init_media_account_lookup = __esm({
|
|
4611
|
+
"src/utils/media-account-lookup.ts"() {
|
|
4612
|
+
"use strict";
|
|
4613
|
+
init_auth();
|
|
4614
|
+
}
|
|
4615
|
+
});
|
|
4616
|
+
|
|
4406
4617
|
// src/commands/accounts-digest/list-fetch.ts
|
|
4407
4618
|
async function fetchAccountsByMedia(media, config, opts) {
|
|
4408
4619
|
const cfg = DIGEST_PLATFORM_CONFIG[media];
|
|
@@ -4491,6 +4702,17 @@ var init_list_fetch = __esm({
|
|
|
4491
4702
|
isForce: false
|
|
4492
4703
|
},
|
|
4493
4704
|
responseType: "mas"
|
|
4705
|
+
},
|
|
4706
|
+
MetaAd: {
|
|
4707
|
+
path: "/query/media-account/SearchMediaAcountByCriteria",
|
|
4708
|
+
pageParam: "pageNum",
|
|
4709
|
+
fixedParams: {
|
|
4710
|
+
MediaTypes: "MetaAd|FacebookAds",
|
|
4711
|
+
advStatus: "",
|
|
4712
|
+
mediaAccountState: "Approved,Linked",
|
|
4713
|
+
isForce: false
|
|
4714
|
+
},
|
|
4715
|
+
responseType: "mas"
|
|
4494
4716
|
}
|
|
4495
4717
|
};
|
|
4496
4718
|
}
|
|
@@ -4509,7 +4731,7 @@ async function runAccountsDigest(opts) {
|
|
|
4509
4731
|
console.error(
|
|
4510
4732
|
`
|
|
4511
4733
|
\u274C accounts-digest \u6682\u4E0D\u652F\u6301\u5A92\u4F53\uFF1A${opts.media}
|
|
4512
|
-
\u53EF\u9009\uFF1A${BALANCE_SUPPORTED_MEDIA.join(" | ")}
|
|
4734
|
+
\u53EF\u9009\uFF1A${BALANCE_SUPPORTED_MEDIA.join(" | ")}
|
|
4513
4735
|
`
|
|
4514
4736
|
);
|
|
4515
4737
|
process.exit(1);
|
|
@@ -4523,12 +4745,16 @@ async function runAccountsDigest(opts) {
|
|
|
4523
4745
|
let accountsList;
|
|
4524
4746
|
let scannedFromList = false;
|
|
4525
4747
|
if (filterSet.size > 0) {
|
|
4748
|
+
let mediaTypes = /* @__PURE__ */ new Map();
|
|
4749
|
+
if (media === "MetaAd") {
|
|
4750
|
+
mediaTypes = await lookupMetaMediaAccountTypes(config, filterIds, opts.verbose);
|
|
4751
|
+
}
|
|
4526
4752
|
accountsList = filterIds.map((id) => ({
|
|
4527
4753
|
ma: {
|
|
4528
4754
|
entityId: "",
|
|
4529
4755
|
mediaCustomerId: id,
|
|
4530
4756
|
mediaCustomerName: null,
|
|
4531
|
-
mediaAccountType: media,
|
|
4757
|
+
mediaAccountType: mediaTypes.get(id) ?? media,
|
|
4532
4758
|
invalidOAuthToken: false
|
|
4533
4759
|
},
|
|
4534
4760
|
accepted: true,
|
|
@@ -4566,6 +4792,7 @@ async function runAccountsDigest(opts) {
|
|
|
4566
4792
|
startDate: opts.startDate,
|
|
4567
4793
|
endDate: opts.endDate,
|
|
4568
4794
|
verbose: opts.verbose,
|
|
4795
|
+
accountMediaTypes: buildAccountMediaTypesMap(accountsList),
|
|
4569
4796
|
onChunkStart: (chunkIdx, totalChunks, ids) => {
|
|
4570
4797
|
process.stderr.write(
|
|
4571
4798
|
` \u2192 [\u6D88\u8017] \u7B2C ${chunkIdx}/${totalChunks} \u6279\uFF08${ids.length} \u6237\uFF09\u2026
|
|
@@ -4725,6 +4952,7 @@ var init_run = __esm({
|
|
|
4725
4952
|
init_cli_table();
|
|
4726
4953
|
init_currency_display();
|
|
4727
4954
|
init_media_account_batch();
|
|
4955
|
+
init_media_account_lookup();
|
|
4728
4956
|
init_list_fetch();
|
|
4729
4957
|
}
|
|
4730
4958
|
});
|
|
@@ -4735,7 +4963,7 @@ function register10(program2) {
|
|
|
4735
4963
|
"\u591A\u8D26\u6237\u6295\u653E\u753B\u50CF\uFF1A\u4E00\u6761\u547D\u4EE4\u62FF\u9F50\u6D88\u8017/\u70B9\u51FB/\u8F6C\u5316/\u4F59\u989D/\u6D3E\u751F\u6307\u6807\uFF08CTR/CPC/CPA\uFF09\uFF0C\u66FF\u4EE3 AI \u9010\u8D26\u6237 `list-accounts` + `stats` \u7684\u7F16\u6392\u3002\u5178\u578B\u573A\u666F\uFF1A\u300C\u8FD9 10 \u4E2A\u8D26\u6237\uFF08\u6216\u67D0\u5A92\u4F53\u5168\u90E8\u8D26\u6237\uFF09\u5E2E\u6211\u6574\u7406\u4E00\u4E0B\u300D\u3002"
|
|
4736
4964
|
).requiredOption(
|
|
4737
4965
|
"-m, --media <type>",
|
|
4738
|
-
"\u5A92\u4F53\u7C7B\u578B\uFF1AGoogle | TikTok | Yandex | BingV2 | Kwai
|
|
4966
|
+
"\u5A92\u4F53\u7C7B\u578B\uFF1AGoogle | TikTok | Yandex | MetaAd | BingV2 | Kwai"
|
|
4739
4967
|
).option(
|
|
4740
4968
|
"-a, --accounts <ids>",
|
|
4741
4969
|
"\u6307\u5B9A\u8D26\u6237 mediaCustomerId\uFF0C\u9017\u53F7\u5206\u9694\uFF1B\u7559\u7A7A\u5219\u626B\u63CF\u8BE5\u5A92\u4F53\u4E0B\u5168\u90E8\u8D26\u6237"
|
|
@@ -105320,6 +105548,7 @@ init_balance();
|
|
|
105320
105548
|
init_cli_table();
|
|
105321
105549
|
init_currency_display();
|
|
105322
105550
|
init_media_account_batch();
|
|
105551
|
+
init_media_account_lookup();
|
|
105323
105552
|
|
|
105324
105553
|
// src/commands/balance-scan/list-fetch.ts
|
|
105325
105554
|
init_auth();
|
|
@@ -105369,6 +105598,17 @@ var SCAN_PLATFORM_CONFIG = {
|
|
|
105369
105598
|
isForce: false
|
|
105370
105599
|
},
|
|
105371
105600
|
responseType: "mas"
|
|
105601
|
+
},
|
|
105602
|
+
MetaAd: {
|
|
105603
|
+
path: "/query/media-account/SearchMediaAcountByCriteria",
|
|
105604
|
+
pageParam: "pageNum",
|
|
105605
|
+
fixedParams: {
|
|
105606
|
+
MediaTypes: "MetaAd|FacebookAds",
|
|
105607
|
+
advStatus: "",
|
|
105608
|
+
mediaAccountState: "Approved,Linked",
|
|
105609
|
+
isForce: false
|
|
105610
|
+
},
|
|
105611
|
+
responseType: "mas"
|
|
105372
105612
|
}
|
|
105373
105613
|
};
|
|
105374
105614
|
async function fetchOnePage(media, page, pageSize, config, verbose) {
|
|
@@ -105472,7 +105712,7 @@ async function runBalanceScan(opts) {
|
|
|
105472
105712
|
console.error(
|
|
105473
105713
|
`
|
|
105474
105714
|
\u274C balance scan \u6682\u4E0D\u652F\u6301\u5A92\u4F53\uFF1A${opts.media}
|
|
105475
|
-
\u53EF\u9009\uFF1A${BALANCE_SUPPORTED_MEDIA.join(" | ")}
|
|
105715
|
+
\u53EF\u9009\uFF1A${BALANCE_SUPPORTED_MEDIA.join(" | ")}
|
|
105476
105716
|
`
|
|
105477
105717
|
);
|
|
105478
105718
|
process.exit(1);
|
|
@@ -105489,12 +105729,16 @@ async function runBalanceScan(opts) {
|
|
|
105489
105729
|
let allItems;
|
|
105490
105730
|
let total;
|
|
105491
105731
|
if (isSubset) {
|
|
105732
|
+
let mediaTypes = /* @__PURE__ */ new Map();
|
|
105733
|
+
if (media === "MetaAd") {
|
|
105734
|
+
mediaTypes = await lookupMetaMediaAccountTypes(config, filterIds, opts.verbose);
|
|
105735
|
+
}
|
|
105492
105736
|
allItems = filterIds.map((id) => ({
|
|
105493
105737
|
ma: {
|
|
105494
105738
|
entityId: "",
|
|
105495
105739
|
mediaCustomerId: id,
|
|
105496
105740
|
mediaCustomerName: null,
|
|
105497
|
-
mediaAccountType: media,
|
|
105741
|
+
mediaAccountType: mediaTypes.get(id) ?? media,
|
|
105498
105742
|
invalidOAuthToken: false
|
|
105499
105743
|
},
|
|
105500
105744
|
accepted: true,
|
|
@@ -105532,6 +105776,7 @@ async function runBalanceScan(opts) {
|
|
|
105532
105776
|
accountIds: validIds,
|
|
105533
105777
|
config,
|
|
105534
105778
|
verbose: opts.verbose,
|
|
105779
|
+
accountMediaTypes: buildAccountMediaTypesMap(allItems),
|
|
105535
105780
|
onChunkStart: (chunkIdx, totalChunks, ids) => {
|
|
105536
105781
|
process.stderr.write(
|
|
105537
105782
|
` \u2192 [\u8FD17\u65E5\u6D88\u8017] \u7B2C ${chunkIdx}/${totalChunks} \u6279\u8BF7\u6C42\u4E2D\uFF08${ids.length} \u6237\uFF09\u2026
|
|
@@ -105691,7 +105936,7 @@ function register9(program2) {
|
|
|
105691
105936
|
"\u4E00\u952E\u626B\u63CF\u67D0\u5A92\u4F53\u4E0B\u6240\u6709\u8D26\u6237\u7684\u4F59\u989D\uFF0C\u7B5B\u51FA\u7EED\u822A\u5929\u6570\u4E0D\u8DB3\u7684\u8D26\u6237\u3002\u66FF\u4EE3\u5FAA\u73AF\u8C03\u7528 balance \u7684\u4F20\u7EDF\u505A\u6CD5\uFF0C\u5178\u578B\u573A\u666F\uFF1A\u300C\u5E2E\u6211\u627E\u51FA 117 \u4E2A Bing \u8D26\u6237\u91CC\u4F59\u989D\u4E0D\u8DB3 7 \u5929\u7684\u300D\u3002"
|
|
105692
105937
|
).requiredOption(
|
|
105693
105938
|
"-m, --media <type>",
|
|
105694
|
-
"\u5A92\u4F53\u7C7B\u578B\uFF1AGoogle | TikTok | Yandex | BingV2 | Kwai
|
|
105939
|
+
"\u5A92\u4F53\u7C7B\u578B\uFF1AGoogle | TikTok | Yandex | MetaAd | BingV2 | Kwai"
|
|
105695
105940
|
).option(
|
|
105696
105941
|
"-a, --accounts <ids>",
|
|
105697
105942
|
"\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"
|
|
@@ -111664,46 +111909,8 @@ function tryLoadCampaignCreateConfig(configFile) {
|
|
|
111664
111909
|
return stripMetaKeys(raw);
|
|
111665
111910
|
}
|
|
111666
111911
|
|
|
111667
|
-
// src/utils/media-account-lookup.ts
|
|
111668
|
-
init_auth();
|
|
111669
|
-
function pickMediaCustomerName(items, mediaCustomerId) {
|
|
111670
|
-
const list = Array.isArray(items) ? items : [];
|
|
111671
|
-
const target = mediaCustomerId.trim();
|
|
111672
|
-
for (const item of list) {
|
|
111673
|
-
const cid = String(item.ma?.mediaCustomerId ?? "");
|
|
111674
|
-
if (cid === target) {
|
|
111675
|
-
const name2 = String(item.ma?.mediaCustomerName ?? "").trim();
|
|
111676
|
-
return name2 || null;
|
|
111677
|
-
}
|
|
111678
|
-
}
|
|
111679
|
-
return null;
|
|
111680
|
-
}
|
|
111681
|
-
async function lookupFromMediaAccountQuery(apiBaseUrl, config, mediaType, mediaCustomerId, verbose) {
|
|
111682
|
-
const params = new URLSearchParams({
|
|
111683
|
-
MediaType: mediaType,
|
|
111684
|
-
mediaAccountState: "Approved,Linked",
|
|
111685
|
-
pageNo: "1",
|
|
111686
|
-
pageSize: "20",
|
|
111687
|
-
mediaCustomerId: mediaCustomerId.trim()
|
|
111688
|
-
});
|
|
111689
|
-
const data = await apiFetch2(
|
|
111690
|
-
`${apiBaseUrl}/query/media-account/?${params}`,
|
|
111691
|
-
config,
|
|
111692
|
-
{},
|
|
111693
|
-
verbose
|
|
111694
|
-
);
|
|
111695
|
-
return pickMediaCustomerName(data, mediaCustomerId);
|
|
111696
|
-
}
|
|
111697
|
-
async function lookupMediaCustomerName(apiBaseUrl, config, mediaType, mediaCustomerId, verbose = false) {
|
|
111698
|
-
const id = mediaCustomerId.trim();
|
|
111699
|
-
if (!id) return null;
|
|
111700
|
-
if (mediaType === "Google" || mediaType === "Yandex") {
|
|
111701
|
-
return lookupFromMediaAccountQuery(apiBaseUrl, config, mediaType, id, verbose);
|
|
111702
|
-
}
|
|
111703
|
-
return null;
|
|
111704
|
-
}
|
|
111705
|
-
|
|
111706
111912
|
// src/commands/ad/campaign-customer-name.ts
|
|
111913
|
+
init_media_account_lookup();
|
|
111707
111914
|
var CampaignCustomerNameResolveError = class extends Error {
|
|
111708
111915
|
constructor(accountId) {
|
|
111709
111916
|
super(
|
|
@@ -113932,6 +114139,7 @@ async function runAdGeoSetBid(opts) {
|
|
|
113932
114139
|
|
|
113933
114140
|
// src/commands/ad/ai-creation.ts
|
|
113934
114141
|
init_auth();
|
|
114142
|
+
init_media_account_lookup();
|
|
113935
114143
|
init_cli_json_snapshot();
|
|
113936
114144
|
init_cli_table();
|
|
113937
114145
|
|
package/dist/skill/SKILL.md
CHANGED
|
@@ -65,55 +65,55 @@ siluzan-tso -h # 查看帮助
|
|
|
65
65
|
|
|
66
66
|
| 用户意图(关键词) | 工作流 | 必读文档 |
|
|
67
67
|
| ------------------ | ------ | -------- |
|
|
68
|
-
| 账户列表 / 有哪些 / 有多少 / 列出全部某媒体 | W1 | `accounts/accounts.md`(§ list-accounts 意图速查) |
|
|
69
|
-
| 单户实时余额 | W1 | `accounts/accounts.md`(balance) |
|
|
70
|
-
| 多账户余额 / 续航不足预警 | **P2** | `accounts/accounts.md`(balance-scan) |
|
|
71
|
-
| 单户消耗 / 投放数据 | W1 / **P1** | `accounts/accounts.md`(stats) |
|
|
72
|
-
| 多账户消耗/对比汇总 | **P3** | `accounts/accounts.md`(accounts-digest) |
|
|
73
|
-
| 激活/充值账单明细 | W1 | `accounts/accounts.md`(account-active-bills) |
|
|
74
|
-
| 开户(六大媒体)/ 开户进度 | W2 | `accounts/open-account-by-media.md`(**首次须列全必填项**;Google 加 `accounts/open-account-google-ui.md`) |
|
|
75
|
-
| 账户权限:分享/取消/解绑/重授权/MCC/BC/BM/关闭/提现/邮箱授权 | W9 | `accounts/accounts.md`(account 子命令) |
|
|
76
|
-
| 充值 / 钱包 | W8 | `accounts/finance.md`(recharge 引导网页) |
|
|
77
|
-
| 转账记录 / 账户间转账 | W8 | `accounts/finance.md`(transfer) |
|
|
78
|
-
| 发票 / 开票 / 发票抬头 | W8 | `accounts/finance.md`(invoice / invoice-info) |
|
|
79
|
-
| 审计 / 误操作恢复 | — | `accounts/write-audit-restore.md` |
|
|
68
|
+
| 账户列表 / 有哪些 / 有多少 / 列出全部某媒体 | W1 | `references/accounts/accounts.md`(§ list-accounts 意图速查) |
|
|
69
|
+
| 单户实时余额 | W1 | `references/accounts/accounts.md`(balance) |
|
|
70
|
+
| 多账户余额 / 续航不足预警 | **P2** | `references/accounts/accounts.md`(balance-scan) |
|
|
71
|
+
| 单户消耗 / 投放数据 | W1 / **P1** | `references/accounts/accounts.md`(stats) |
|
|
72
|
+
| 多账户消耗/对比汇总 | **P3** | `references/accounts/accounts.md`(accounts-digest) |
|
|
73
|
+
| 激活/充值账单明细 | W1 | `references/accounts/accounts.md`(account-active-bills) |
|
|
74
|
+
| 开户(六大媒体)/ 开户进度 | W2 | `references/accounts/open-account-by-media.md`(**首次须列全必填项**;Google 加 `references/accounts/open-account-google-ui.md`) |
|
|
75
|
+
| 账户权限:分享/取消/解绑/重授权/MCC/BC/BM/关闭/提现/邮箱授权 | W9 | `references/accounts/accounts.md`(account 子命令) |
|
|
76
|
+
| 充值 / 钱包 | W8 | `references/accounts/finance.md`(recharge 引导网页) |
|
|
77
|
+
| 转账记录 / 账户间转账 | W8 | `references/accounts/finance.md`(transfer) |
|
|
78
|
+
| 发票 / 开票 / 发票抬头 | W8 | `references/accounts/finance.md`(invoice / invoice-info) |
|
|
79
|
+
| 审计 / 误操作恢复 | — | `references/accounts/write-audit-restore.md` |
|
|
80
80
|
|
|
81
81
|
### Google 广告投放
|
|
82
82
|
|
|
83
83
|
| 用户意图(关键词) | 工作流 | 必读文档 |
|
|
84
84
|
| ------------------ | ------ | -------- |
|
|
85
|
-
| 新建搜索系列 / 出投放方案 / **根据官网·网站·URL 生成 Google 搜索广告** / 搜索广告文案·关键词·**表格** / 写搜索广告计划 | **W3** | `google-ads/google-ads-campaign-plan.md` + **`assets/campaign-create-template.json`**(结构真相源,先 Read)+ `assets/campaign-create-template.md`(字段说明);表格交付读 `google-ads/rules/google-ads-launch-plan-template.md`。**≠ P8 网站诊断 / ≠ P9 市场分析 / ≠ W5 仅拓词** |
|
|
86
|
-
| 广告系列/组/广告/关键词 CRUD / 拒审 | W3 | `google-ads/google-ads.md` |
|
|
87
|
-
| PMax 系列 | W3 | **`assets/pmax-create-template.json`**(先 Read)+ `assets/pmax-create-template.md` + `google-ads/pmax-api.md` |
|
|
88
|
-
| AI 智投草稿 list/get/update/publish | W4 | `google-ads/google-ads.md`(§ ad batch) |
|
|
89
|
-
| 拓词 / keyword / 关键词规划 | W5 | `analytics/keyword-planner-workflows.md`(客户背景先 `analytics/rag.md`) |
|
|
90
|
-
| AI 广告优化记录 / 建议 | W6 | `operations/optimize.md` |
|
|
91
|
-
| 优化/合规 SOP | W3 / W6 | `google-ads/rules/README.md` |
|
|
85
|
+
| 新建搜索系列 / 出投放方案 / **根据官网·网站·URL 生成 Google 搜索广告** / 搜索广告文案·关键词·**表格** / 写搜索广告计划 | **W3** | `references/google-ads/google-ads-campaign-plan.md` + **`assets/campaign-create-template.json`**(结构真相源,先 Read)+ `assets/campaign-create-template.md`(字段说明);表格交付读 `references/google-ads/rules/google-ads-launch-plan-template.md`。**≠ P8 网站诊断 / ≠ P9 市场分析 / ≠ W5 仅拓词** |
|
|
86
|
+
| 广告系列/组/广告/关键词 CRUD / 拒审 | W3 | `references/google-ads/google-ads.md` |
|
|
87
|
+
| PMax 系列 | W3 | **`assets/pmax-create-template.json`**(先 Read)+ `assets/pmax-create-template.md` + `references/google-ads/pmax-api.md` |
|
|
88
|
+
| AI 智投草稿 list/get/update/publish | W4 | `references/google-ads/google-ads.md`(§ ad batch) |
|
|
89
|
+
| 拓词 / keyword / 关键词规划 | W5 | `references/analytics/keyword-planner-workflows.md`(客户背景先 `references/analytics/rag.md`) |
|
|
90
|
+
| AI 广告优化记录 / 建议 | W6 | `references/operations/optimize.md` |
|
|
91
|
+
| 优化/合规 SOP | W3 / W6 | `references/google-ads/rules/README.md` |
|
|
92
92
|
|
|
93
93
|
### 分析与报告(CLI 拉数 + Agent 撰稿)
|
|
94
94
|
|
|
95
95
|
| 用户意图(关键词) | 工作流 | 必读文档 |
|
|
96
96
|
| ------------------ | ------ | -------- |
|
|
97
|
-
| 单账户投放画像 / **Google 广告账户诊断** / 账户健康检查 / 投放诊断报告 / 账户体检(**含账户 ID**) | **P1** | `analytics/account-analytics.md`;完整 HTML 诊断加 `references/report-templates/google-ads-diagnosis.md` |
|
|
98
|
-
| Google 账户 **周期** / **月度** / **季度** 报告 / 月报(**非** OKKI / **非** 询盘 / **非** 强调健康诊断) | **P4** | `references/report-templates/google-period-report.md` + `analytics/account-analytics.md`;要 **Excel** 加 `references/report-templates/google-period-report-excel.md` |
|
|
99
|
-
| Meta/Facebook 周期或诊断报告 | **P4-FB** | `references/report-templates/meta-period-report.md` + `assets/meta-period-report-rules.md` + `analytics/facebook-analysis-guide.md`;要 Excel 加 `references/report-templates/meta-period-report-excel.md` |
|
|
100
|
-
| TikTok / Bing 周期报告 | **P4** | `analytics/account-analytics.md`(report tiktok-*/bing-*)+ 对应 `references/report-templates/*-period-report.md` |
|
|
101
|
-
| 多账户 × 多维度批处理 | **P5** | `analytics/google-analysis-batch.md` + `analytics/account-analytics.md` |
|
|
97
|
+
| 单账户投放画像 / **Google 广告账户诊断** / 账户健康检查 / 投放诊断报告 / 账户体检(**含账户 ID**) | **P1** | `references/analytics/account-analytics.md`;完整 HTML 诊断加 `references/report-templates/google-ads-diagnosis.md` |
|
|
98
|
+
| Google 账户 **周期** / **月度** / **季度** 报告 / 月报(**非** OKKI / **非** 询盘 / **非** 强调健康诊断) | **P4** | `references/report-templates/google-period-report.md` + `references/analytics/account-analytics.md`;要 **Excel** 加 `references/report-templates/google-period-report-excel.md` |
|
|
99
|
+
| Meta/Facebook 周期或诊断报告 | **P4-FB** | `references/report-templates/meta-period-report.md` + `assets/meta-period-report-rules.md` + `references/analytics/facebook-analysis-guide.md`;要 Excel 加 `references/report-templates/meta-period-report-excel.md` |
|
|
100
|
+
| TikTok / Bing 周期报告 | **P4** | `references/analytics/account-analytics.md`(report tiktok-*/bing-*)+ 对应 `references/report-templates/*-period-report.md` |
|
|
101
|
+
| 多账户 × 多维度批处理 | **P5** | `references/analytics/google-analysis-batch.md` + `references/analytics/account-analytics.md` |
|
|
102
102
|
| OKKI 周报 | **P6** | `references/report-templates/okki-weekly-google-client.md`(全文) |
|
|
103
|
-
| Google 询盘分析 | **P7** | `references/report-templates/google-inquiry-analysis.md`(全文)+ `analytics/geo-continents.json` |
|
|
104
|
-
| 网站诊断 / **网站诊断·检测·监测报告** / 落地页报告 / 网站质量评分 / 官网体检(**要 URL**) | **P8** | `analytics/website-diagnosis-guide.md` + `assets/website-diagnosis-rules.md`(**必须先** `website-diagnosis collect` + `render`,**默认交付 HTML**;**≠ P9 ≠ W3**) |
|
|
105
|
-
| 市场分析 / **行业分析** / **行业分析报告** / 市场调查 / 生成 **XX 行业** 报告(如电商)/ 战略市场报告 / KA 市场报告 | **P9** | `analytics/market-analysis-guide.md` + `assets/market-analysis-rules.md`(**必须先** `market-analysis collect` + `render`,**默认交付 HTML**;**禁止**纯 WebSearch 交 Markdown 终稿;**≠ P8**) |
|
|
106
|
-
| TSO 平台优化报告:列表/生成/推送 | W7 | `analytics/reporting.md` |
|
|
107
|
-
| RAG 知识库检索 | W5 | `analytics/rag.md` |
|
|
103
|
+
| Google 询盘分析 | **P7** | `references/report-templates/google-inquiry-analysis.md`(全文)+ `references/analytics/geo-continents.json` |
|
|
104
|
+
| 网站诊断 / **网站诊断·检测·监测报告** / 落地页报告 / 网站质量评分 / 官网体检(**要 URL**) | **P8** | `references/analytics/website-diagnosis-guide.md` + `assets/website-diagnosis-rules.md`(**必须先** `website-diagnosis collect` + `render`,**默认交付 HTML**;**≠ P9 ≠ W3**) |
|
|
105
|
+
| 市场分析 / **行业分析** / **行业分析报告** / 市场调查 / 生成 **XX 行业** 报告(如电商)/ 战略市场报告 / KA 市场报告 | **P9** | `references/analytics/market-analysis-guide.md` + `assets/market-analysis-rules.md`(**必须先** `market-analysis collect` + `render`,**默认交付 HTML**;**禁止**纯 WebSearch 交 Markdown 终稿;**≠ P8**) |
|
|
106
|
+
| TSO 平台优化报告:列表/生成/推送 | W7 | `references/analytics/reporting.md` |
|
|
107
|
+
| RAG 知识库检索 | W5 | `references/analytics/rag.md` |
|
|
108
108
|
|
|
109
109
|
### 工具与运营
|
|
110
110
|
|
|
111
111
|
| 用户意图(关键词) | 工作流 | 必读文档 |
|
|
112
112
|
| ------------------ | ------ | -------- |
|
|
113
|
-
| 智能预警:创建/查询/启停/触发记录 | W10 | `operations/forewarning.md` |
|
|
114
|
-
| TikTok / Meta 线索表单 | W11 | `operations/clue.md` |
|
|
115
|
-
| 日/周巡检 | W12 | `core/workflows.md`(W12)+ `accounts/accounts.md` |
|
|
116
|
-
| 宿主编排 / 投放自控 / 异常监控 / 自动优化 | — | `operations/hosted-automation-user-catalog.md`(索引)→ `operations/hosted-automation-*.md` |
|
|
113
|
+
| 智能预警:创建/查询/启停/触发记录 | W10 | `references/operations/forewarning.md` |
|
|
114
|
+
| TikTok / Meta 线索表单 | W11 | `references/operations/clue.md` |
|
|
115
|
+
| 日/周巡检 | W12 | `references/core/workflows.md`(W12)+ `references/accounts/accounts.md` |
|
|
116
|
+
| 宿主编排 / 投放自控 / 异常监控 / 自动优化 | — | `references/operations/hosted-automation-user-catalog.md`(索引)→ `operations/hosted-automation-*.md` |
|
|
117
117
|
|
|
118
118
|
---
|
|
119
119
|
|
|
@@ -132,4 +132,4 @@ siluzan-tso -h # 查看帮助
|
|
|
132
132
|
| 金额、ID、字段口径一致 | 触达(钉钉/飞书)与工单 |
|
|
133
133
|
| references 与命令对齐 | 批处理循环、限速、重试;**可选** subagent 并行 |
|
|
134
134
|
|
|
135
|
-
详见 `operations/hosted-automation-self-control.md`、`operations/hosted-automation-monitoring-json.md`、`operations/hosted-automation-optimize-index.md`。
|
|
135
|
+
详见 `references/operations/hosted-automation-self-control.md`、`references/operations/hosted-automation-monitoring-json.md`、`references/operations/hosted-automation-optimize-index.md`。
|
package/dist/skill/_meta.json
CHANGED
|
@@ -37,7 +37,7 @@ JSON 模板:同目录 [`campaign-create-template.json`](campaign-create-templa
|
|
|
37
37
|
|
|
38
38
|
| 命令 | 支持 `--json-out`? | 推荐用法 |
|
|
39
39
|
| -------------------------------- | :-----------------: | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
40
|
-
| `ad campaign-validate` | **是** | **推荐** `--json-out ./snap-campaign`(落盘 `ad-campaign-validate-<account>.json`,含 `lengthViolations`);。人读:`--config-file` 即可;词面规范化:`--write-normalized`。超长勿自动截断,见 `google-ads/google-ads-campaign-plan.md` § 超长人工确认 |
|
|
40
|
+
| `ad campaign-validate` | **是** | **推荐** `--json-out ./snap-campaign`(落盘 `ad-campaign-validate-<account>.json`,含 `lengthViolations`);。人读:`--config-file` 即可;词面规范化:`--write-normalized`。超长勿自动截断,见 `references/google-ads/google-ads-campaign-plan.md` § 超长人工确认 |
|
|
41
41
|
| `ad campaign-create` | **是** | 落盘任务响应:`--json-out ./snap-campaign`; |
|
|
42
42
|
| `ad batch get` / `ad batch diff` | **是** | 轮询与 diff 结果落盘,见 `references/core/tips.md` |
|
|
43
43
|
|