siluzan-tso-cli 1.1.39-beta.3 → 1.1.39

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 CHANGED
@@ -43,7 +43,7 @@ HTML 报告模板外部资源:**ECharts** 统一使用 `https://staticpn.siluz
43
43
  在**用户的目标项目根目录**执行(根据用户使用的助手选择 `--ai`):
44
44
 
45
45
  ```bash
46
- npm install -g siluzan-tso-cli@beta
46
+ npm install -g siluzan-tso-cli
47
47
  siluzan-tso init --ai cursor # 写入 Cursor(默认)
48
48
  siluzan-tso init --ai cursor,claude # 同时写入多个平台
49
49
  siluzan-tso init --ai all # 写入所有支持的平台
@@ -51,7 +51,6 @@ siluzan-tso init -d /path/to/skills # 写入自定义目录
51
51
  siluzan-tso init --force # 强制覆盖已存在文件
52
52
  ```
53
53
 
54
- > **注意**:当前为测试版(1.1.39-beta.3),供内部测试使用。正式发布后安装命令将改为 `npm install -g siluzan-tso-cli`。
55
54
 
56
55
  | 助手 | 建议 `--ai` |
57
56
  | ----------------------- | ------------------------------------ |
package/dist/index.js CHANGED
@@ -3937,7 +3937,7 @@ var DEFAULT_API_BASE;
3937
3937
  var init_defaults = __esm({
3938
3938
  "src/config/defaults.ts"() {
3939
3939
  "use strict";
3940
- DEFAULT_API_BASE = "https://tso-api-ci.siluzan.com";
3940
+ DEFAULT_API_BASE = "https://tso-api.siluzan.com";
3941
3941
  }
3942
3942
  });
3943
3943
 
@@ -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('\n\u274C \u5199\u64CD\u4F5C\u5FC5\u987B\u63D0\u4F9B\u8BF4\u660E\uFF08commit\uFF09\uFF1A\u8BF7\u4F7F\u7528 --commit "\u2026"');
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 result;
112431
- const statusV2 = String(raw).toUpperCase();
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 result;
112439
+ if (start == null || end == null) return statusLabel;
112435
112440
  const now = Date.now();
112436
- if (statusV2 === "PAUSED") {
112437
- if (now > start && now < end) {
112438
- result = "\u5DF2\u6682\u505C";
112439
- } else if (now > end) {
112440
- result = "\u5DF2\u7ED3\u675F\u4F7F\u7528";
112441
- } else if (now < start) {
112442
- result = "\u672A\u6295\u653E";
112443
- }
112444
- } else if (statusV2 === "ENABLED") {
112445
- if (now > start && now < end) {
112446
- result = "\u6709\u6548";
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
- if (opts.headlines.length < 3) {
113241
- console.error("\n\u274C \u6807\u9898\uFF08--headlines\uFF09\u81F3\u5C11\u9700\u8981 3 \u4E2A\n");
113242
- process.exit(1);
113243
- }
113244
- if (opts.descriptions.length < 2) {
113245
- console.error("\n\u274C \u63CF\u8FF0\uFF08--descriptions\uFF09\u81F3\u5C11\u9700\u8981 2 \u4E2A\n");
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
- if (opts.headlines && opts.headlines.length < 3) {
113371
- console.error("\n\u274C --headlines \u81F3\u5C11\u9700\u8981 3 \u4E2A\n");
113372
- process.exit(1);
113373
- }
113374
- if (opts.descriptions && opts.descriptions.length < 2) {
113375
- console.error("\n\u274C --descriptions \u81F3\u5C11\u9700\u8981 2 \u4E2A\n");
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 CRUD\uFF1Asiluzan-tso ad \u2026\n - \u5E7F\u544A\u8BCA\u65AD\u62A5\u544A\uFF1Asiluzan-tso google-ads-diagnosis \u2026\n";
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";
@@ -1,5 +1,5 @@
1
1
  {
2
2
  "slug": "siluzan-tso",
3
- "version": "1.1.39-beta.3",
4
- "publishedAt": 1785132603059
3
+ "version": "1.1.39",
4
+ "publishedAt": 1785141614907
5
5
  }
@@ -164,7 +164,7 @@ siluzan-tso account-history --start 2026-03-01 --end 2026-03-31 --json-out ./sna
164
164
  | 状态 | 含义 | 下一步操作 |
165
165
  | ---------- | -------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
166
166
  | `Pending` | 审核中 | 等待,可反复运行此命令轮询;审核周期因媒体而异 |
167
- | `Approved` | 审核通过 | 运行 `list-accounts -m <媒体>` 确认账户已出现;引导用户充值激活(`config show` 取 `webUrl`,按 `finance.md` 打开对应媒体充值页;例如 Google 为 `https://www-ci.siluzan.com/v3/foreign_trade/tso/recharge/pay?mediaType=Google`;Kwai、Yandex 当前没有对应充值界面) |
167
+ | `Approved` | 审核通过 | 运行 `list-accounts -m <媒体>` 确认账户已出现;引导用户充值激活(`config show` 取 `webUrl`,按 `finance.md` 打开对应媒体充值页;例如 Google 为 `https://www.siluzan.com/v3/foreign_trade/tso/recharge/pay?mediaType=Google`;Kwai、Yandex 当前没有对应充值界面) |
168
168
  | `Rejected` | 被拒 | 查看 `--json-out` 落盘中的 `reason` 字段了解拒绝原因;修改资料后重新提交;若原因不明,引导用户联系丝路赞客服 |
169
169
 
170
170
  ---
@@ -472,7 +472,7 @@ siluzan-tso account email-deauth -c <mediaCustomerId> --invitation-id <id> --res
472
472
 
473
473
  | 功能 | 媒体 | 网页路径 |
474
474
  | --------------------------------------- | ------ | ------------------------------------------------- |
475
- | **账户激活**(邀请他人激活 / 充值激活) | Google | `https://www-ci.siluzan.com/v3/foreign_trade/tso/manageAccounts` |
475
+ | **账户激活**(邀请他人激活 / 充值激活) | Google | `https://www.siluzan.com/v3/foreign_trade/tso/manageAccounts` |
476
476
 
477
477
  **Agent 建议话术**:
478
478
 
@@ -481,5 +481,5 @@ siluzan-tso account email-deauth -c <mediaCustomerId> --invitation-id <id> --res
481
481
  siluzan-tso config show # 查看 webUrl 字段
482
482
 
483
483
  # 账户激活(Google)→ 引导至账户管理页
484
- # https://www-ci.siluzan.com/v3/foreign_trade/tso/manageAccounts
484
+ # https://www.siluzan.com/v3/foreign_trade/tso/manageAccounts
485
485
  ```
@@ -127,7 +127,7 @@ siluzan-tso config show
127
127
 
128
128
  ### 充值页链接(按媒体 × 类型)
129
129
 
130
- 链接模式:`https://www-ci.siluzan.com/v3/foreign_trade/tso/recharge/<page>?mediaType=<mediaType>`;丝路赞钱包:`https://www-ci.siluzan.com/v3/foreign_trade/tso/recharge/siluzanWallet`(无媒体参数)。
130
+ 链接模式:`https://www.siluzan.com/v3/foreign_trade/tso/recharge/<page>?mediaType=<mediaType>`;丝路赞钱包:`https://www.siluzan.com/v3/foreign_trade/tso/recharge/siluzanWallet`(无媒体参数)。
131
131
 
132
132
  | 充值类型 | `<page>` | 支持媒体(`mediaType` 参数) |
133
133
  | ------------------------- | --------------------- | ------------------------------------------- |
@@ -1,6 +1,6 @@
1
1
  # 各媒体开户
2
2
 
3
- > 网页链接:`https://www-ci.siluzan.com/v3/foreign_trade/tso/accountOpeningHistory?tso=%2Fv3umijs%2Ftso%2FaccountOpeningHistory`
3
+ > 网页链接:`https://www.siluzan.com/v3/foreign_trade/tso/accountOpeningHistory?tso=%2Fv3umijs%2Ftso%2FaccountOpeningHistory`
4
4
  > 多命令串联见 `references/core/workflows.md` § 流程一。
5
5
 
6
6
 
@@ -60,7 +60,7 @@ siluzan-tso open-account google-wizard
60
60
 
61
61
  ```bash
62
62
  siluzan-tso account-history -m Google
63
- # 审核通过后:config show → https://www-ci.siluzan.com/v3/foreign_trade/tso/recharge/pay?mediaType=Google
63
+ # 审核通过后:config show → https://www.siluzan.com/v3/foreign_trade/tso/recharge/pay?mediaType=Google
64
64
  ```
65
65
 
66
66
  ---
@@ -1,6 +1,6 @@
1
1
  # rag:知识库检索(TSO 广告投放辅助)
2
2
 
3
- 知识库管理页面在 https://www-ci.siluzan.com/knowledge-base/
3
+ 知识库管理页面在 https://www.siluzan.com/knowledge-base/
4
4
 
5
5
  为 **广告投放、账户分析、拓词、诊断报告** 等 TSO 业务提供**企业已入库**的产品、行业、客户背景事实依据。
6
6
 
@@ -190,9 +190,9 @@ siluzan-tso report push receive-emails -m Google [--json-out ./snap]
190
190
 
191
191
  | 媒体 | 报告类型 | URL 模板 |
192
192
  | ------ | ---------------- | ----------------------------------------------------------- |
193
- | Google | 日报(Daily) | `https://www-ci.siluzan.com/media-report/publish/{entityId}?culture=zh-CN` |
194
- | Google | 小时报(Hourly) | `https://www-ci.siluzan.com/media-report/hour/{entityId}?culture=zh-CN` |
195
- | TikTok | 日报 | `https://www-ci.siluzan.com/media-report/publish/{entityId}?culture=zh-CN` |
193
+ | Google | 日报(Daily) | `https://www.siluzan.com/media-report/publish/{entityId}?culture=zh-CN` |
194
+ | Google | 小时报(Hourly) | `https://www.siluzan.com/media-report/hour/{entityId}?culture=zh-CN` |
195
+ | TikTok | 日报 | `https://www.siluzan.com/media-report/publish/{entityId}?culture=zh-CN` |
196
196
 
197
197
  `entityId` 来自 `siluzan-tso report list --json-out ./snap` 中每条记录的 `entityId` 字段。
198
198
 
@@ -205,8 +205,8 @@ siluzan-tso report list -m Google --json-out ./snap
205
205
 
206
206
  # 第二步:查看 webUrl
207
207
  siluzan-tso config show
208
- # webUrl: https://www-ci.siluzan.com
208
+ # webUrl: https://www.siluzan.com
209
209
 
210
210
  # 第三步:拼接链接(Google 日报)
211
- # https://www-ci.siluzan.com/media-report/publish/rpt_abc123?culture=zh-CN
211
+ # https://www.siluzan.com/media-report/publish/rpt_abc123?culture=zh-CN
212
212
  ```
@@ -10,7 +10,7 @@
10
10
  ## 安装 CLI
11
11
 
12
12
  ```bash
13
- npm install -g siluzan-tso-cli@beta
13
+ npm install -g siluzan-tso-cli
14
14
  ```
15
15
 
16
16
  ---
@@ -63,7 +63,7 @@ siluzan-tso config set --api-key <Key> # 或 config 直接写入
63
63
  siluzan-tso config set --token <Token> # 备用:设置 JWT Token
64
64
  ```
65
65
 
66
- API Key 获取入口:`https://www-ci.siluzan.com/v3/foreign_trade/settings/apiKeyManagement`
66
+ API Key 获取入口:`https://www.siluzan.com/v3/foreign_trade/settings/apiKeyManagement`
67
67
 
68
68
  ```bash
69
69
  # 第 1 步:让用户报出手机号后,立刻发码(命令立即返回,不会等待输入)
@@ -126,9 +126,9 @@ siluzan-tso config show
126
126
 
127
127
  ```
128
128
  构建环境 : production
129
- apiBaseUrl : https://tso-api-ci.siluzan.com
130
- googleApiUrl : https://googleapi-ci.mysiluzan.com
131
- webUrl : https://www-ci.siluzan.com
129
+ apiBaseUrl : https://tso-api.siluzan.com
130
+ googleApiUrl : https://googleapi.mysiluzan.com
131
+ webUrl : https://www.siluzan.com
132
132
  apiKey : abcd****1234
133
133
  ```
134
134
 
@@ -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),另有 `statusDisplay`(状态文案)。
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
- `--headlines` 至少 3 条(≤30字符),`--descriptions` 至少 2 条(≤90字符)。**`--json-out`** 落盘返回网关响应(含 `id` 等字段),便于批量脚本拿到 adId 后续编辑/启停。
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,再只修改传入字段,未改字段从列表原值带回。
@@ -6,7 +6,7 @@
6
6
  siluzan-tso config show # 取 webUrl
7
7
  ```
8
8
 
9
- 首页地址:`https://www-ci.siluzan.com/v3/foreign_trade/tso/home`
9
+ 首页地址:`https://www.siluzan.com/v3/foreign_trade/tso/home`
10
10
 
11
11
  ---
12
12
 
@@ -25,7 +25,7 @@ siluzan-tso config show # 取 webUrl
25
25
 
26
26
  ## 推荐话术
27
27
 
28
- 1. **「和首页一样的总览」** → 打开 `https://www-ci.siluzan.com/v3/foreign_trade/tso/home`。
28
+ 1. **「和首页一样的总览」** → 打开 `https://www.siluzan.com/v3/foreign_trade/tso/home`。
29
29
  2. **「某个 Google 账户昨天花了多少」** → `list-accounts -m Google` + `stats -m Google -a <id>`。
30
30
  3. **「有待充值账户」** → 说明聚合数据在首页;CLI 可 `list-accounts` + `balance` 逐户排查,或引导充值页。
31
31
 
@@ -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`(有效/未投放/已结束使用)口径不同;周期报告「状态」列统一用 **`campaignStatusDisplay`**。
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`(有效/未投放/已结束使用)口径不同;周期报告「状态」列统一用 **`campaignStatusDisplay`**。
123
+ 原始枚举为 PascalCase(`Enabled`),与 `ad campaigns` 的 `statusDisplay`(如 `Enabled·有效` / `Enabled·投放期已结束`)口径不同;周期报告「状态」列统一用 **`campaignStatusDisplay`**。
@@ -9,11 +9,11 @@ $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.3'
12
+ $PKG_VERSION = '1.1.39'
13
13
  $CLI_BIN = 'siluzan-tso'
14
14
  $SKILL_LABEL = 'Siluzan TSO'
15
- $INSTALL_CMD = 'npm install -g siluzan-tso-cli@beta'
16
- $WEB_BASE = 'https://www-ci.siluzan.com'
15
+ $INSTALL_CMD = 'npm install -g siluzan-tso-cli'
16
+ $WEB_BASE = 'https://www.siluzan.com'
17
17
 
18
18
  # -- Constants ----------------------------------------------------------------
19
19
  $NODE_MAJOR_MIN = 18
@@ -9,11 +9,11 @@ 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.3"
12
+ readonly PKG_VERSION="1.1.39"
13
13
  readonly CLI_BIN="siluzan-tso"
14
14
  readonly SKILL_LABEL="Siluzan TSO"
15
- readonly INSTALL_CMD="npm install -g siluzan-tso-cli@beta"
16
- readonly WEB_BASE="https://www-ci.siluzan.com"
15
+ readonly INSTALL_CMD="npm install -g siluzan-tso-cli"
16
+ readonly WEB_BASE="https://www.siluzan.com"
17
17
 
18
18
  # -- Constants ----------------------------------------------------------------
19
19
  readonly NODE_MAJOR_MIN=18
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "siluzan-tso-cli",
3
- "version": "1.1.39-beta.3",
3
+ "version": "1.1.39",
4
4
  "description": "Siluzan 广告账户管理 CLI — 查询账户、余额、消耗数据,管理绑定关系与充值。",
5
5
  "keywords": [
6
6
  "ad-account",