siluzan-tso-cli 1.1.39-beta.3 → 1.1.39-beta.4
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 +130 -41
- package/dist/skill/_meta.json +2 -2
- package/dist/skill/references/google-ads/google-ads-read.md +16 -2
- package/dist/skill/references/google-ads/google-ads-write.md +38 -1
- package/dist/skill/references/report-templates/google-period-report.md +1 -1
- package/dist/skill/report-templates/google-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.39-beta.
|
|
54
|
+
> **注意**:当前为测试版(1.1.39-beta.4),供内部测试使用。正式发布后安装命令将改为 `npm install -g siluzan-tso-cli`。
|
|
55
55
|
|
|
56
56
|
| 助手 | 建议 `--ai` |
|
|
57
57
|
| ----------------------- | ------------------------------------ |
|
package/dist/index.js
CHANGED
|
@@ -4171,7 +4171,9 @@ function isTsoArgvExemptFromWriteCommit(argv) {
|
|
|
4171
4171
|
function ensureWriteCommitForMutatingHttp() {
|
|
4172
4172
|
if (isTsoArgvExemptFromWriteCommit(process.argv.slice(2))) return;
|
|
4173
4173
|
if (isWriteAuditCommitRequiredSatisfied()) return;
|
|
4174
|
-
console.error(
|
|
4174
|
+
console.error(
|
|
4175
|
+
'\n\u274C \u5199\u64CD\u4F5C\u5FC5\u987B\u63D0\u4F9B\u8BF4\u660E\uFF08commit\uFF09\uFF1A\u8BF7\u5728\u547D\u4EE4\u672B\u5C3E\u52A0 --commit "\u7B80\u77ED\u8BF4\u660E"\n \u793A\u4F8B\uFF1Asiluzan-tso ad ad-create -a <id> \u2026 --commit "\u5728\u7EC4 X \u4E0B\u521B\u5EFA RSA \u5E76\u7A0D\u540E\u6682\u505C"\n'
|
|
4176
|
+
);
|
|
4175
4177
|
process.exit(1);
|
|
4176
4178
|
}
|
|
4177
4179
|
async function withWriteAudit(params, execute) {
|
|
@@ -112425,32 +112427,28 @@ async function resolveCampaignCustomerName(cfg, config, verbose) {
|
|
|
112425
112427
|
|
|
112426
112428
|
// src/commands/ad/campaign.ts
|
|
112427
112429
|
function formatGoogleCampaignListStatus(row) {
|
|
112428
|
-
let result = "-";
|
|
112429
112430
|
const raw = row.statusV2;
|
|
112430
|
-
if (raw == null || String(raw).trim() === "") return
|
|
112431
|
-
const
|
|
112431
|
+
if (raw == null || String(raw).trim() === "") return "-";
|
|
112432
|
+
const statusLabel = String(raw);
|
|
112433
|
+
const statusKey = statusLabel.toUpperCase();
|
|
112434
|
+
if (statusKey === "REMOVED") {
|
|
112435
|
+
return `${statusLabel}\xB7\u5DF2\u5220\u9664`;
|
|
112436
|
+
}
|
|
112432
112437
|
const start = parseCampaignTimeMs(row.startTime);
|
|
112433
112438
|
const end = parseCampaignTimeMs(row.endTime);
|
|
112434
|
-
if (start == null || end == null) return
|
|
112439
|
+
if (start == null || end == null) return statusLabel;
|
|
112435
112440
|
const now = Date.now();
|
|
112436
|
-
|
|
112437
|
-
|
|
112438
|
-
|
|
112439
|
-
|
|
112440
|
-
|
|
112441
|
-
|
|
112442
|
-
|
|
112443
|
-
|
|
112444
|
-
|
|
112445
|
-
|
|
112446
|
-
|
|
112447
|
-
} else if (now > end) {
|
|
112448
|
-
result = "\u5DF2\u7ED3\u675F\u4F7F\u7528";
|
|
112449
|
-
} else if (now < start) {
|
|
112450
|
-
result = "\u672A\u6295\u653E";
|
|
112451
|
-
}
|
|
112452
|
-
}
|
|
112453
|
-
return result;
|
|
112441
|
+
let schedule = "-";
|
|
112442
|
+
if (now < start) {
|
|
112443
|
+
schedule = "\u672A\u6295\u653E";
|
|
112444
|
+
} else if (now > end) {
|
|
112445
|
+
schedule = "\u6295\u653E\u671F\u5DF2\u7ED3\u675F";
|
|
112446
|
+
} else if (statusKey === "PAUSED") {
|
|
112447
|
+
schedule = "\u5DF2\u6682\u505C";
|
|
112448
|
+
} else if (statusKey === "ENABLED") {
|
|
112449
|
+
schedule = "\u6709\u6548";
|
|
112450
|
+
}
|
|
112451
|
+
return `${statusLabel}\xB7${schedule}`;
|
|
112454
112452
|
}
|
|
112455
112453
|
function parseCampaignTimeMs(v) {
|
|
112456
112454
|
if (v == null || v === "") return null;
|
|
@@ -113158,6 +113156,77 @@ init_auth();
|
|
|
113158
113156
|
init_cli_json_snapshot();
|
|
113159
113157
|
init_strip_legacy_google_fields();
|
|
113160
113158
|
init_cli_table();
|
|
113159
|
+
|
|
113160
|
+
// src/commands/ad/rsa-cli-validate.ts
|
|
113161
|
+
var AD_CLI_MIN_HEADLINES = 3;
|
|
113162
|
+
var AD_CLI_MAX_HEADLINES = 15;
|
|
113163
|
+
var AD_CLI_MIN_DESCRIPTIONS = 2;
|
|
113164
|
+
var AD_CLI_MAX_DESCRIPTIONS = 4;
|
|
113165
|
+
var AD_CLI_HEADLINE_MAX_CHARS = 30;
|
|
113166
|
+
var AD_CLI_DESCRIPTION_MAX_CHARS = 90;
|
|
113167
|
+
var AD_CLI_PATH_MAX_CHARS = 15;
|
|
113168
|
+
function validateRsaCliCopy(input) {
|
|
113169
|
+
const errors = [];
|
|
113170
|
+
if (input.headlines) {
|
|
113171
|
+
const hs = input.headlines.map((s) => s.trim()).filter(Boolean);
|
|
113172
|
+
if (hs.length < AD_CLI_MIN_HEADLINES) {
|
|
113173
|
+
errors.push(`--headlines \u81F3\u5C11 ${AD_CLI_MIN_HEADLINES} \u6761\uFF0C\u5F53\u524D ${hs.length} \u6761`);
|
|
113174
|
+
} else if (hs.length > AD_CLI_MAX_HEADLINES) {
|
|
113175
|
+
errors.push(`--headlines \u6700\u591A ${AD_CLI_MAX_HEADLINES} \u6761\uFF0C\u5F53\u524D ${hs.length} \u6761`);
|
|
113176
|
+
}
|
|
113177
|
+
for (let i = 0; i < hs.length; i++) {
|
|
113178
|
+
const len = calcGoogleCharLength(hs[i]);
|
|
113179
|
+
if (len > AD_CLI_HEADLINE_MAX_CHARS) {
|
|
113180
|
+
errors.push(
|
|
113181
|
+
`--headlines[${i}] \u8D85\u8FC7 ${AD_CLI_HEADLINE_MAX_CHARS} \u5B57\u7B26\uFF08\u5F53\u524D ${len}\uFF0CCJK \u8BA1 2\uFF09\uFF1A${JSON.stringify(hs[i])}`
|
|
113182
|
+
);
|
|
113183
|
+
}
|
|
113184
|
+
}
|
|
113185
|
+
}
|
|
113186
|
+
if (input.descriptions) {
|
|
113187
|
+
const ds = input.descriptions.map((s) => s.trim()).filter(Boolean);
|
|
113188
|
+
if (ds.length < AD_CLI_MIN_DESCRIPTIONS) {
|
|
113189
|
+
errors.push(`--descriptions \u81F3\u5C11 ${AD_CLI_MIN_DESCRIPTIONS} \u6761\uFF0C\u5F53\u524D ${ds.length} \u6761`);
|
|
113190
|
+
} else if (ds.length > AD_CLI_MAX_DESCRIPTIONS) {
|
|
113191
|
+
errors.push(`--descriptions \u6700\u591A ${AD_CLI_MAX_DESCRIPTIONS} \u6761\uFF0C\u5F53\u524D ${ds.length} \u6761`);
|
|
113192
|
+
}
|
|
113193
|
+
for (let i = 0; i < ds.length; i++) {
|
|
113194
|
+
const len = calcGoogleCharLength(ds[i]);
|
|
113195
|
+
if (len > AD_CLI_DESCRIPTION_MAX_CHARS) {
|
|
113196
|
+
errors.push(
|
|
113197
|
+
`--descriptions[${i}] \u8D85\u8FC7 ${AD_CLI_DESCRIPTION_MAX_CHARS} \u5B57\u7B26\uFF08\u5F53\u524D ${len}\uFF0CCJK \u8BA1 2\uFF09\uFF1A${JSON.stringify(ds[i])}`
|
|
113198
|
+
);
|
|
113199
|
+
}
|
|
113200
|
+
}
|
|
113201
|
+
}
|
|
113202
|
+
for (const [label, value] of [
|
|
113203
|
+
["--path1", input.path1],
|
|
113204
|
+
["--path2", input.path2]
|
|
113205
|
+
]) {
|
|
113206
|
+
if (value === void 0) continue;
|
|
113207
|
+
const len = calcGoogleCharLength(value);
|
|
113208
|
+
if (len > AD_CLI_PATH_MAX_CHARS) {
|
|
113209
|
+
errors.push(
|
|
113210
|
+
`${label} \u8D85\u8FC7 ${AD_CLI_PATH_MAX_CHARS} \u5B57\u7B26\uFF08\u5F53\u524D ${len}\uFF0CCJK \u8BA1 2\uFF09\uFF1A${JSON.stringify(value)}`
|
|
113211
|
+
);
|
|
113212
|
+
}
|
|
113213
|
+
}
|
|
113214
|
+
return errors;
|
|
113215
|
+
}
|
|
113216
|
+
function formatRsaCliValidationError(errors) {
|
|
113217
|
+
const lines = [
|
|
113218
|
+
"",
|
|
113219
|
+
"\u274C RSA \u6587\u6848\u6821\u9A8C\u5931\u8D25\uFF08\u672A\u8C03\u7528 API\uFF09\uFF1A",
|
|
113220
|
+
...errors.map((e) => ` - ${e}`),
|
|
113221
|
+
"",
|
|
113222
|
+
" \u89C4\u5219\uFF1A\u6807\u9898 3\u201315 \u6761\u3001\u6BCF\u6761 \u226430 Google \u5B57\u7B26\uFF1B\u63CF\u8FF0 2\u20134 \u6761\u3001\u6BCF\u6761 \u226490\uFF1Bpath \u226415\u3002CJK/\u5168\u89D2\u6309 2 \u8BA1\u3002",
|
|
113223
|
+
" \u8BF7\u7F29\u77ED\u8D85\u957F\u6761\u76EE\u6216\u5220\u6389\u591A\u4F59\u63CF\u8FF0\u540E\u91CD\u8BD5\uFF08\u52FF\u628A\u8D85\u957F\u6587\u6848\u539F\u6837\u518D\u63D0\u4EA4\uFF09\u3002",
|
|
113224
|
+
""
|
|
113225
|
+
];
|
|
113226
|
+
return lines.join("\n");
|
|
113227
|
+
}
|
|
113228
|
+
|
|
113229
|
+
// src/commands/ad/ad-creative.ts
|
|
113161
113230
|
async function runAdList(opts) {
|
|
113162
113231
|
const config = loadConfig(opts.token);
|
|
113163
113232
|
const googleApiUrl = requireGoogleApi(config);
|
|
@@ -113237,12 +113306,14 @@ async function runAdList(opts) {
|
|
|
113237
113306
|
async function runAdCreate(opts) {
|
|
113238
113307
|
const config = loadConfig(opts.token);
|
|
113239
113308
|
const googleApiUrl = requireGoogleApi(config);
|
|
113240
|
-
|
|
113241
|
-
|
|
113242
|
-
|
|
113243
|
-
|
|
113244
|
-
|
|
113245
|
-
|
|
113309
|
+
const rsaErrors = validateRsaCliCopy({
|
|
113310
|
+
headlines: opts.headlines,
|
|
113311
|
+
descriptions: opts.descriptions,
|
|
113312
|
+
path1: opts.path1,
|
|
113313
|
+
path2: opts.path2
|
|
113314
|
+
});
|
|
113315
|
+
if (rsaErrors.length > 0) {
|
|
113316
|
+
console.error(formatRsaCliValidationError(rsaErrors));
|
|
113246
113317
|
process.exit(1);
|
|
113247
113318
|
}
|
|
113248
113319
|
const [h1, h2, h3, ...moreHeadlines] = opts.headlines;
|
|
@@ -113367,12 +113438,14 @@ async function runAdEdit(opts) {
|
|
|
113367
113438
|
);
|
|
113368
113439
|
process.exit(1);
|
|
113369
113440
|
}
|
|
113370
|
-
|
|
113371
|
-
|
|
113372
|
-
|
|
113373
|
-
|
|
113374
|
-
|
|
113375
|
-
|
|
113441
|
+
const rsaErrors = validateRsaCliCopy({
|
|
113442
|
+
headlines: opts.headlines,
|
|
113443
|
+
descriptions: opts.descriptions,
|
|
113444
|
+
path1: opts.path1,
|
|
113445
|
+
path2: opts.path2
|
|
113446
|
+
});
|
|
113447
|
+
if (rsaErrors.length > 0) {
|
|
113448
|
+
console.error(formatRsaCliValidationError(rsaErrors));
|
|
113376
113449
|
process.exit(1);
|
|
113377
113450
|
}
|
|
113378
113451
|
const params = new URLSearchParams();
|
|
@@ -119651,7 +119724,7 @@ function register20(program2) {
|
|
|
119651
119724
|
});
|
|
119652
119725
|
}
|
|
119653
119726
|
);
|
|
119654
|
-
adCmd.command("campaigns").description("\u67E5\u8BE2\u5E7F\u544A\u7CFB\u5217\u5217\u8868\uFF08\u65E5\u671F\u9ED8\u8BA4\u8FD1 30 \u5929\uFF09").requiredOption("-a, --account <id>", "Google \u8D26\u6237 mediaCustomerId").option("--start <date>", "\u5F00\u59CB\u65E5\u671F YYYY-MM-DD\uFF08\u9ED8\u8BA4 30 \u5929\u524D\uFF09").option("--end <date>", "\u7ED3\u675F\u65E5\u671F YYYY-MM-DD\uFF08\u9ED8\u8BA4\u4ECA\u5929\uFF09").option("-t, --token <token>", "Auth Token").option(
|
|
119727
|
+
adCmd.command("campaigns").alias("campaign-list").description("\u67E5\u8BE2\u5E7F\u544A\u7CFB\u5217\u5217\u8868\uFF08\u65E5\u671F\u9ED8\u8BA4\u8FD1 30 \u5929\uFF1B\u522B\u540D campaign-list\uFF09").requiredOption("-a, --account <id>", "Google \u8D26\u6237 mediaCustomerId").option("--start <date>", "\u5F00\u59CB\u65E5\u671F YYYY-MM-DD\uFF08\u9ED8\u8BA4 30 \u5929\u524D\uFF09").option("--end <date>", "\u7ED3\u675F\u65E5\u671F YYYY-MM-DD\uFF08\u9ED8\u8BA4\u4ECA\u5929\uFF09").option("-t, --token <token>", "Auth Token").option(
|
|
119655
119728
|
"--json-out <path>",
|
|
119656
119729
|
"\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",
|
|
119657
119730
|
void 0
|
|
@@ -119667,7 +119740,7 @@ function register20(program2) {
|
|
|
119667
119740
|
});
|
|
119668
119741
|
}
|
|
119669
119742
|
);
|
|
119670
|
-
adCmd.command("groups").description("\u67E5\u8BE2\u5E7F\u544A\u7EC4\u5217\u8868\uFF08\u65E5\u671F\u9ED8\u8BA4\u8FD1 30 \u5929\uFF09").requiredOption("-a, --account <id>", "Google \u8D26\u6237 mediaCustomerId").option("--start <date>", "\u5F00\u59CB\u65E5\u671F YYYY-MM-DD\uFF08\u9ED8\u8BA4 30 \u5929\u524D\uFF09").option("--end <date>", "\u7ED3\u675F\u65E5\u671F YYYY-MM-DD\uFF08\u9ED8\u8BA4\u4ECA\u5929\uFF09").option("-t, --token <token>", "Auth Token").option(
|
|
119743
|
+
adCmd.command("groups").alias("group-list").description("\u67E5\u8BE2\u5E7F\u544A\u7EC4\u5217\u8868\uFF08\u65E5\u671F\u9ED8\u8BA4\u8FD1 30 \u5929\uFF1B\u522B\u540D group-list\uFF09").requiredOption("-a, --account <id>", "Google \u8D26\u6237 mediaCustomerId").option("--start <date>", "\u5F00\u59CB\u65E5\u671F YYYY-MM-DD\uFF08\u9ED8\u8BA4 30 \u5929\u524D\uFF09").option("--end <date>", "\u7ED3\u675F\u65E5\u671F YYYY-MM-DD\uFF08\u9ED8\u8BA4\u4ECA\u5929\uFF09").option("-t, --token <token>", "Auth Token").option(
|
|
119671
119744
|
"--json-out <path>",
|
|
119672
119745
|
"\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",
|
|
119673
119746
|
void 0
|
|
@@ -119683,7 +119756,7 @@ function register20(program2) {
|
|
|
119683
119756
|
});
|
|
119684
119757
|
}
|
|
119685
119758
|
);
|
|
119686
|
-
adCmd.command("list").description("\u67E5\u8BE2\u5E7F\u544A\uFF08\u521B\u610F\uFF09\u5217\u8868\uFF08\u65E5\u671F\u9ED8\u8BA4\u8FD1 30 \u5929\uFF09").requiredOption("-a, --account <id>", "Google \u8D26\u6237 mediaCustomerId").option("--start <date>", "\u5F00\u59CB\u65E5\u671F YYYY-MM-DD\uFF08\u9ED8\u8BA4 30 \u5929\u524D\uFF09").option("--end <date>", "\u7ED3\u675F\u65E5\u671F YYYY-MM-DD\uFF08\u9ED8\u8BA4\u4ECA\u5929\uFF09").option("--include-deleted", "\u5305\u542B\u5DF2\u5220\u9664\u7684\u5E7F\u544A\uFF08\u7F51\u5173 readDeleted=true\uFF09", false).option("-t, --token <token>", "Auth Token").option(
|
|
119759
|
+
adCmd.command("list").alias("ad-list").description("\u67E5\u8BE2\u5E7F\u544A\uFF08\u521B\u610F\uFF09\u5217\u8868\uFF08\u65E5\u671F\u9ED8\u8BA4\u8FD1 30 \u5929\uFF1B\u522B\u540D ad-list\uFF09").requiredOption("-a, --account <id>", "Google \u8D26\u6237 mediaCustomerId").option("--start <date>", "\u5F00\u59CB\u65E5\u671F YYYY-MM-DD\uFF08\u9ED8\u8BA4 30 \u5929\u524D\uFF09").option("--end <date>", "\u7ED3\u675F\u65E5\u671F YYYY-MM-DD\uFF08\u9ED8\u8BA4\u4ECA\u5929\uFF09").option("--include-deleted", "\u5305\u542B\u5DF2\u5220\u9664\u7684\u5E7F\u544A\uFF08\u7F51\u5173 readDeleted=true\uFF09", false).option("-t, --token <token>", "Auth Token").option(
|
|
119687
119760
|
"--json-out <path>",
|
|
119688
119761
|
"\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",
|
|
119689
119762
|
void 0
|
|
@@ -119700,7 +119773,7 @@ function register20(program2) {
|
|
|
119700
119773
|
});
|
|
119701
119774
|
}
|
|
119702
119775
|
);
|
|
119703
|
-
adCmd.command("keywords").description("\u67E5\u8BE2\u5173\u952E\u8BCD\u5217\u8868\uFF08--negative \u67E5\u8BE2\u5426\u5B9A\u5173\u952E\u8BCD\uFF1B\u65E5\u671F\u9ED8\u8BA4\u8FD1 30 \u5929\uFF09").requiredOption("-a, --account <id>", "Google \u8D26\u6237 mediaCustomerId").option("--negative", "\u67E5\u8BE2\u5426\u5B9A\u5173\u952E\u8BCD", false).option("--start <date>", "\u5F00\u59CB\u65E5\u671F\uFF08YYYY-MM-DD\uFF0C\u9ED8\u8BA4 30 \u5929\u524D\uFF09").option("--end <date>", "\u7ED3\u675F\u65E5\u671F\uFF08YYYY-MM-DD\uFF0C\u9ED8\u8BA4\u4ECA\u5929\uFF09").option("-t, --token <token>", "Auth Token").option(
|
|
119776
|
+
adCmd.command("keywords").alias("keyword-list").description("\u67E5\u8BE2\u5173\u952E\u8BCD\u5217\u8868\uFF08--negative \u67E5\u8BE2\u5426\u5B9A\u5173\u952E\u8BCD\uFF1B\u65E5\u671F\u9ED8\u8BA4\u8FD1 30 \u5929\uFF1B\u522B\u540D keyword-list\uFF09").requiredOption("-a, --account <id>", "Google \u8D26\u6237 mediaCustomerId").option("--negative", "\u67E5\u8BE2\u5426\u5B9A\u5173\u952E\u8BCD", false).option("--start <date>", "\u5F00\u59CB\u65E5\u671F\uFF08YYYY-MM-DD\uFF0C\u9ED8\u8BA4 30 \u5929\u524D\uFF09").option("--end <date>", "\u7ED3\u675F\u65E5\u671F\uFF08YYYY-MM-DD\uFF0C\u9ED8\u8BA4\u4ECA\u5929\uFF09").option("-t, --token <token>", "Auth Token").option(
|
|
119704
119777
|
"--json-out <path>",
|
|
119705
119778
|
"\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",
|
|
119706
119779
|
void 0
|
|
@@ -119793,7 +119866,7 @@ function register20(program2) {
|
|
|
119793
119866
|
}
|
|
119794
119867
|
);
|
|
119795
119868
|
adCmd.command("ad-create").description(
|
|
119796
|
-
"\u521B\u5EFA\u81EA\u9002\u5E94\u641C\u7D22\u5E7F\u544A\uFF08\u5FC5\u4F20\uFF1A-a / --adgroup-id / --adgroup-name / --final-url / --headlines / --descriptions\uFF09"
|
|
119869
|
+
"\u521B\u5EFA\u81EA\u9002\u5E94\u641C\u7D22\u5E7F\u544A\uFF08\u5FC5\u4F20\uFF1A-a / --adgroup-id / --adgroup-name / --final-url / --headlines / --descriptions\uFF1B\u63D0\u4EA4\u524D\u672C\u5730\u6821\u9A8C\uFF1A\u6807\u98983\u201315\u6761\u226430\u5B57\u3001\u63CF\u8FF02\u20134\u6761\u226490\u5B57\uFF0CCJK\xD72\uFF09"
|
|
119797
119870
|
).requiredOption("-a, --account <id>", "Google \u8D26\u6237 mediaCustomerId\uFF08\u5FC5\u4F20\uFF09").requiredOption("--adgroup-id <id>", "\u76EE\u6807\u5E7F\u544A\u7EC4 ID\uFF08\u5FC5\u4F20\uFF0C\u6765\u81EA ad groups\uFF09").requiredOption("--adgroup-name <name>", "\u76EE\u6807\u5E7F\u544A\u7EC4\u540D\u79F0\uFF08\u5FC5\u4F20\uFF0C\u4E0E adgroup-id \u5BF9\u5E94\uFF09").requiredOption("--final-url <url>", "\u6700\u7EC8\u5230\u8FBE\u7F51\u5740\uFF08\u5FC5\u4F20\uFF09").requiredOption(
|
|
119798
119871
|
"--headlines <h1,h2,h3,...>",
|
|
119799
119872
|
"\u6807\u9898\u5217\u8868\uFF0C\u9017\u53F7\u5206\u9694\uFF0C\u81F3\u5C11 3 \u4E2A\uFF08\u5FC5\u4F20\uFF0C\u6700\u591A 15 \u4E2A\uFF0C\u6BCF\u4E2A \u226430 \u5B57\u7B26\uFF09",
|
|
@@ -132246,14 +132319,30 @@ init_version();
|
|
|
132246
132319
|
init_cli_json_snapshot();
|
|
132247
132320
|
|
|
132248
132321
|
// src/utils/agent-compat-argv.ts
|
|
132322
|
+
function jsonOutMissingPath(args) {
|
|
132323
|
+
for (let i = 0; i < args.length; i++) {
|
|
132324
|
+
const a = args[i];
|
|
132325
|
+
if (a === "--json-out") {
|
|
132326
|
+
const next = args[i + 1];
|
|
132327
|
+
return next == null || next.startsWith("-");
|
|
132328
|
+
}
|
|
132329
|
+
if (a.startsWith("--json-out=")) {
|
|
132330
|
+
return a.slice("--json-out=".length).trim() === "";
|
|
132331
|
+
}
|
|
132332
|
+
}
|
|
132333
|
+
return false;
|
|
132334
|
+
}
|
|
132249
132335
|
function agentCompatFatalMessage(argv) {
|
|
132250
132336
|
const args = argv.slice(2);
|
|
132251
132337
|
if (args.includes("--period") || args.some((a) => a.startsWith("--period="))) {
|
|
132252
132338
|
return "\n\u274C \u6CA1\u6709 --period \u9009\u9879\u3002\u8BF7\u7528 --start/--end\uFF08\u6216\u517C\u5BB9\u522B\u540D --start-date/--end-date\uFF09\u6307\u5B9A YYYY-MM-DD \u533A\u95F4\u3002\n";
|
|
132253
132339
|
}
|
|
132340
|
+
if (jsonOutMissingPath(args)) {
|
|
132341
|
+
return "\n\u274C `--json-out` \u5FC5\u987B\u5E26\u8DEF\u5F84\uFF08\u76EE\u5F55\u6216 *.json \u6587\u4EF6\uFF09\uFF0CJSON \u843D\u76D8\u800C\u975E\u6253\u5370\u5230 stdout\uFF0C\u4E0D\u80FD\u7BA1\u9053\u7ED9 python/jq\u3002\n \u793A\u4F8B\uFF1Asiluzan-tso ad campaigns -a <id> --json-out ./snap\n \u7136\u540E\u7528 node/python \u8BFB ./snap \u4E0B writtenFiles\uFF08\u89C1 stdout \u6458\u8981\u7684 absoluteSnapshotDir\uFF09\u3002\n";
|
|
132342
|
+
}
|
|
132254
132343
|
const cmd = args[0];
|
|
132255
132344
|
if (cmd === "google-ads") {
|
|
132256
|
-
return "\n\u274C \u6CA1\u6709 `google-ads` \u547D\u540D\u7A7A\u95F4\u3002\u8BF7\u6539\u7528\uFF1A\n - \u8D26\u6237\u5206\u6790\u62C9\u6570\uFF1Asiluzan-tso google-analysis \u2026\n - \u5E7F\u544A\u7CFB\u5217/\u7EC4/\u5173\u952E\u8BCD
|
|
132345
|
+
return "\n\u274C \u6CA1\u6709 `google-ads` \u547D\u540D\u7A7A\u95F4\u3002\u8BF7\u6539\u7528\uFF1A\n - \u8D26\u6237\u5206\u6790\u62C9\u6570\uFF1Asiluzan-tso google-analysis \u2026\n - \u5E7F\u544A\u7CFB\u5217/\u7EC4/\u521B\u610F/\u5173\u952E\u8BCD\uFF1Asiluzan-tso ad campaigns|groups|list|keywords \u2026\n \uFF08\u6CA1\u6709 campaign-list\uFF1B\u5217\u8868\u547D\u4EE4\u662F campaigns / groups / list / keywords\uFF09\n - \u5E7F\u544A\u8BCA\u65AD\u62A5\u544A\uFF1Asiluzan-tso google-ads-diagnosis \u2026\n";
|
|
132257
132346
|
}
|
|
132258
132347
|
if (cmd === "list" && (args.length === 1 || args[1]?.startsWith("-"))) {
|
|
132259
132348
|
return "\n\u274C \u6CA1\u6709\u9876\u5C42 `list` \u547D\u4EE4\u3002\u67E5\u8BE2\u5E7F\u544A\u8D26\u6237\u5217\u8868\u8BF7\u7528\uFF1A\n siluzan-tso list-accounts [-m Google] [-k <id\u6216\u5173\u952E\u5B57>] --json-out <dir>\n";
|
package/dist/skill/_meta.json
CHANGED
|
@@ -42,7 +42,12 @@
|
|
|
42
42
|
siluzan-tso ad campaigns -a <accountId> [--start <YYYY-MM-DD>] [--end <YYYY-MM-DD>] [--json-out ./snap]
|
|
43
43
|
```
|
|
44
44
|
|
|
45
|
-
落盘 JSON 中 **`budget` 为日预算**(主币种「元」,CLI 已 ÷100),另有 `
|
|
45
|
+
落盘 JSON 中 **`budget` 为日预算**(主币种「元」,CLI 已 ÷100),另有 **`statusV2`**(`Enabled`/`Paused`/`Removed`)与 **`statusDisplay`**(`{statusV2}·日程文案`,如 `Enabled·有效`、`Enabled·投放期已结束`、`Removed·已删除`)。
|
|
46
|
+
|
|
47
|
+
> **消歧**:`statusDisplay` 含「投放期已结束」**不是**系列已删除——以 **`statusV2`** 为准;仅 `Removed` 才不可在其下新建组/广告。日程结束仍可 `ad-create`(是否投放另看预算与系列开关)。
|
|
48
|
+
|
|
49
|
+
命令名:列表是 **`ad campaigns`**(兼容别名 `campaign-list`),**没有** `google-ads` 命名空间。`--json-out` **必须带路径**(落盘,勿管道 stdout)。
|
|
50
|
+
|
|
46
51
|
带 `--start` / `--end` 时,同行的 **`spend` / `impressions` / `clicks` / `conversions` 为该闭区间合计**(**不是**日消耗)。
|
|
47
52
|
与日预算比较「是否超预算」时,**必须** `start=end=统计日`;多日窗口须先 ÷ 天数或改用 `balance-scan.dailySpend` / `overview.averageDailyCost` 再谈「日均」。
|
|
48
53
|
|
|
@@ -135,6 +140,8 @@ siluzan-tso ad list -a <accountId> [--start/--end <date>] [--include-deleted] [-
|
|
|
135
140
|
|
|
136
141
|
### 创建(RSA)
|
|
137
142
|
|
|
143
|
+
写操作细节与 `--commit` 见 `google-ads-write.md`(**ad ad-create**)。CLI **提交前本地校验**字数/条数,超限直接失败、不打 API。
|
|
144
|
+
|
|
138
145
|
```bash
|
|
139
146
|
siluzan-tso ad ad-create \
|
|
140
147
|
-a <accountId> \
|
|
@@ -143,10 +150,17 @@ siluzan-tso ad ad-create \
|
|
|
143
150
|
--headlines "标题1,标题2,标题3" \
|
|
144
151
|
--descriptions "描述1,描述2" \
|
|
145
152
|
[--path1 <≤15字符>] [--path2 <≤15字符>] \
|
|
153
|
+
--commit "创建 RSA …" \
|
|
146
154
|
[--json-out <path>]
|
|
147
155
|
```
|
|
148
156
|
|
|
149
|
-
|
|
157
|
+
| 字段 | 数量 | 每条上限(Google 字符宽,CJK×2) |
|
|
158
|
+
| ---- | ---- | -------------------------------- |
|
|
159
|
+
| `--headlines` | **3–15** | **≤30** |
|
|
160
|
+
| `--descriptions` | **2–4** | **≤90** |
|
|
161
|
+
| `--path1`/`--path2` | 可选 | **≤15** |
|
|
162
|
+
|
|
163
|
+
提交前用脚本 `len`/CJK×2 自检;**禁止**一次塞入 >4 条描述。创建后暂停:`ad ad-status … --status Paused --commit "…"`。
|
|
150
164
|
|
|
151
165
|
### 启停 / 删除
|
|
152
166
|
|
|
@@ -7,11 +7,20 @@
|
|
|
7
7
|
|
|
8
8
|
- 新建搜索系列 / PMax
|
|
9
9
|
- campaign-validate / campaign-create / campaign-edit
|
|
10
|
-
-
|
|
10
|
+
- **ad ad-create(RSA)** / ad-edit / 组/关键词写操作
|
|
11
11
|
- extension / device-bid
|
|
12
12
|
|
|
13
13
|
---
|
|
14
14
|
|
|
15
|
+
## 写操作硬纪律(Agent 易踩)
|
|
16
|
+
|
|
17
|
+
- **必须** `--commit "…"`;漏了会直接失败。
|
|
18
|
+
- 列表命令:`ad campaigns` / `ad groups` / `ad list` / `ad keywords`(**没有** `google-ads`、没有必用 `campaign-list`;`campaign-list` 仅为 `campaigns` 别名)。
|
|
19
|
+
- `--json-out <path>`:**路径必填**,JSON 落盘;禁止 `--json-out` 裸用或管道 stdout。
|
|
20
|
+
- 系列 `statusDisplay` 含「投放期已结束」≠ 已删除;以 JSON **`statusV2`** 为准(见 `google-ads-read.md`)。
|
|
21
|
+
|
|
22
|
+
---
|
|
23
|
+
|
|
15
24
|
## 金额单位(全局重要)
|
|
16
25
|
|
|
17
26
|
> **所有 CLI 金额参数均按「主币种金额」传入**(如 `1.5` = ¥1.50 / $1.50);CLI 写入网关前对「分」字段 ×100(含 `ad keyword-edit --max-cpc` → `maxCPC`)。
|
|
@@ -240,6 +249,34 @@ siluzan-tso ad adgroup-rename -a <accountId> --id <adGroupId> --name <新名称>
|
|
|
240
249
|
|
|
241
250
|
---
|
|
242
251
|
|
|
252
|
+
## ad ad-create — 创建自适应搜索广告(RSA)
|
|
253
|
+
|
|
254
|
+
在已有广告组下新增 RSA。提交前 CLI **本地校验**字数/条数(超限不打 API)。
|
|
255
|
+
|
|
256
|
+
```bash
|
|
257
|
+
siluzan-tso ad ad-create \
|
|
258
|
+
-a <accountId> \
|
|
259
|
+
--adgroup-id <adGroupId> --adgroup-name <adGroupName> \
|
|
260
|
+
--final-url <https://...> \
|
|
261
|
+
--headlines "H1,H2,H3,..." \
|
|
262
|
+
--descriptions "D1,D2[,D3,D4]" \
|
|
263
|
+
[--path1 <p1>] [--path2 <p2>] \
|
|
264
|
+
--commit "在 <组名> 下创建 RSA …" \
|
|
265
|
+
[--json-out <path>]
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
| 约束 | 值 |
|
|
269
|
+
| ---- | -- |
|
|
270
|
+
| headlines | **3–15** 条,每条 **≤30** Google 字符(CJK×2) |
|
|
271
|
+
| descriptions | **2–4** 条,每条 **≤90** Google 字符(CJK×2) |
|
|
272
|
+
| path1/path2 | 可选,各 **≤15** |
|
|
273
|
+
|
|
274
|
+
创建后暂停:`ad ad-status -a <accountId> --id <adId> --status Paused --commit "创建后暂停"`。若列表找不到新广告,给 `ad-status` / `ad list` 加宽 `--start`/`--end`。
|
|
275
|
+
|
|
276
|
+
文案合规见 `rules/google-ads-compliance-copy.md`。
|
|
277
|
+
|
|
278
|
+
---
|
|
279
|
+
|
|
243
280
|
## ad ad-edit — 广告创意编辑
|
|
244
281
|
|
|
245
282
|
先用 `ad list --json-out ./snap` 取得完整 JSON,再只修改传入字段,未改字段从列表原值带回。
|
|
@@ -120,4 +120,4 @@ siluzan-tso google-analysis -a <id> --start <s> --end <e> --json-out ./snap-goog
|
|
|
120
120
|
| 直接展示 `row.campaignStatusDisplay` | 读 `campaignStatus` 后自行 `MAP[s] \|\| '已移除'`(`Enabled` 未命中键时会全变「已移除」) |
|
|
121
121
|
| 需要英文枚举时读 `campaignStatus` 或 `campaignStatusV2`,展示前 `.upper()` 再映射 | 用 `stats` / `list-accounts` 的账户 `status` 充当系列状态 |
|
|
122
122
|
|
|
123
|
-
原始枚举为 PascalCase(`Enabled`),与 `ad campaigns` 的 `statusDisplay
|
|
123
|
+
原始枚举为 PascalCase(`Enabled`),与 `ad campaigns` 的 `statusDisplay`(如 `Enabled·有效` / `Enabled·投放期已结束`)口径不同;周期报告「状态」列统一用 **`campaignStatusDisplay`**。
|
|
@@ -120,4 +120,4 @@ siluzan-tso google-analysis -a <id> --start <s> --end <e> --json-out ./snap-goog
|
|
|
120
120
|
| 直接展示 `row.campaignStatusDisplay` | 读 `campaignStatus` 后自行 `MAP[s] \|\| '已移除'`(`Enabled` 未命中键时会全变「已移除」) |
|
|
121
121
|
| 需要英文枚举时读 `campaignStatus` 或 `campaignStatusV2`,展示前 `.upper()` 再映射 | 用 `stats` / `list-accounts` 的账户 `status` 充当系列状态 |
|
|
122
122
|
|
|
123
|
-
原始枚举为 PascalCase(`Enabled`),与 `ad campaigns` 的 `statusDisplay
|
|
123
|
+
原始枚举为 PascalCase(`Enabled`),与 `ad campaigns` 的 `statusDisplay`(如 `Enabled·有效` / `Enabled·投放期已结束`)口径不同;周期报告「状态」列统一用 **`campaignStatusDisplay`**。
|
|
@@ -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.39-beta.
|
|
12
|
+
$PKG_VERSION = '1.1.39-beta.4'
|
|
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.39-beta.
|
|
12
|
+
readonly PKG_VERSION="1.1.39-beta.4"
|
|
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"
|