siluzan-cso-cli 1.1.28 → 1.1.29-beta.10

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
@@ -46,7 +46,7 @@
46
46
  在**用户的目标项目根目录**执行(根据用户使用的助手选择 `--ai`):
47
47
 
48
48
  ```bash
49
- npm install -g siluzan-cso-cli
49
+ npm install -g siluzan-cso-cli@beta
50
50
  siluzan-cso init --ai cursor # 写入 Cursor(默认)
51
51
  siluzan-cso init --ai cursor,claude # 同时写入多个平台
52
52
  siluzan-cso init --ai all # 写入所有支持的平台
@@ -54,6 +54,7 @@ siluzan-cso init -d /path/to/skills # 写入自定义目录
54
54
  siluzan-cso init --force # 强制覆盖已存在文件
55
55
  ```
56
56
 
57
+ > **注意**:当前为测试版(1.1.29-beta.10),供内部测试使用。正式发布后安装命令将改为 `npm install -g siluzan-cso-cli`。
57
58
 
58
59
  | 助手 | 建议 `--ai` |
59
60
  | ----------------------- | ------------------------------------ |
package/dist/index.js CHANGED
@@ -2610,6 +2610,9 @@ function pickStr(obj, key) {
2610
2610
  const v = obj[key];
2611
2611
  return typeof v === "string" && v.trim() ? v.trim() : void 0;
2612
2612
  }
2613
+ function pickPhone(data) {
2614
+ return pickStr(data, "phone") ?? pickStr(data, "mobile") ?? pickStr(data, "phoneNumber") ?? pickStr(data, "mobilePhone");
2615
+ }
2613
2616
  function pickCompanyId(data) {
2614
2617
  const direct = pickStr(data, "companyId") ?? pickStr(data, "companyID") ?? pickStr(data, "CompanyId");
2615
2618
  if (direct) return direct;
@@ -2626,10 +2629,11 @@ function parseMeResponse(text) {
2626
2629
  const data = json?.data && typeof json.data === "object" ? json.data : json;
2627
2630
  const id = pickStr(data, "entityId") ?? pickStr(data, "id") ?? pickStr(data, "userId") ?? pickStr(data, "accountId");
2628
2631
  const email = pickStr(data, "email");
2629
- const username = pickStr(data, "userName") ?? pickStr(data, "username") ?? pickStr(data, "name") ?? pickStr(data, "phone");
2632
+ const phone = pickPhone(data);
2633
+ const username = pickStr(data, "userName") ?? pickStr(data, "username") ?? pickStr(data, "name") ?? phone;
2630
2634
  const companyId = pickCompanyId(data);
2631
- if (!id && !email && !username && !companyId) return null;
2632
- return { id, email, username, companyId };
2635
+ if (!id && !email && !username && !phone && !companyId) return null;
2636
+ return { id, email, username, phone, companyId };
2633
2637
  } catch {
2634
2638
  return null;
2635
2639
  }
@@ -2654,6 +2658,7 @@ async function fetchSiluzanCurrentUser(apiBase, config) {
2654
2658
  entityId: parsed.id,
2655
2659
  email: parsed.email,
2656
2660
  username: parsed.username,
2661
+ phone: parsed.phone,
2657
2662
  companyId: parsed.companyId
2658
2663
  };
2659
2664
  } catch {
@@ -2878,11 +2883,11 @@ import { Command } from "commander";
2878
2883
  import { Option } from "commander";
2879
2884
 
2880
2885
  // src/config/defaults.ts
2881
- var BUILD_ENV = "production";
2882
- var DEFAULT_API_BASE = "https://api.siluzan.com";
2883
- var DEFAULT_CSO_BASE = "https://cso.siluzan.com";
2884
- var DEFAULT_WEB_BASE = "https://www.siluzan.com";
2885
- var DEFAULT_AGENT_BASE = "https://agent.mysiluzan.com";
2886
+ var BUILD_ENV = "test";
2887
+ var DEFAULT_API_BASE = "https://api-ci.siluzan.com";
2888
+ var DEFAULT_CSO_BASE = "https://cso-ci.siluzan.com";
2889
+ var DEFAULT_WEB_BASE = "https://www-ci.siluzan.com";
2890
+ var DEFAULT_AGENT_BASE = "https://agent-ci.mysiluzan.com";
2886
2891
 
2887
2892
  // src/commands/init.ts
2888
2893
  import * as fs4 from "fs/promises";
@@ -5091,7 +5096,7 @@ async function runUpload(options) {
5091
5096
  }
5092
5097
  }
5093
5098
 
5094
- // src/commands/validate-content.ts
5099
+ // src/commands/workflow/validate.ts
5095
5100
  import * as fs9 from "fs";
5096
5101
  import * as path9 from "path";
5097
5102
  var CJK_REGEX = /[\u3400-\u4dbf\u4e00-\u9fff\uf900-\ufaff]/g;
@@ -5206,9 +5211,9 @@ function resolveContent(options) {
5206
5211
  if (piped.length > 0) return { raw: piped, sourceLabel: "stdin" };
5207
5212
  }
5208
5213
  console.error("\n\u274C \u672A\u63D0\u4F9B\u5F85\u6821\u9A8C\u6587\u6848\u3002\u8BF7\u7528\u4EE5\u4E0B\u4EFB\u4E00\u65B9\u5F0F\u4F20\u5165\uFF08\u5BBF\u4E3B\u65E0\u6587\u4EF6\u5DE5\u5177\u65F6\u7528\u540E\u4E24\u79CD\uFF09\uFF1A");
5209
- console.error(" 1) \u6587\u4EF6\uFF1A siluzan-cso validate-content -f draft.md --max 800");
5210
- console.error(' 2) \u7BA1\u9053\uFF1A echo "\u6587\u6848\u5185\u5BB9" | siluzan-cso validate-content --max 800');
5211
- console.error(' 3) \u884C\u5185\u6587\u672C\uFF1Asiluzan-cso validate-content --text "\u6587\u6848\u5185\u5BB9" --max 800');
5214
+ console.error(" 1) \u6587\u4EF6\uFF1A siluzan-cso workflow validate -f draft.md --max 800");
5215
+ console.error(' 2) \u7BA1\u9053\uFF1A echo "\u6587\u6848\u5185\u5BB9" | siluzan-cso workflow validate --max 800');
5216
+ console.error(' 3) \u884C\u5185\u6587\u672C\uFF1Asiluzan-cso workflow validate --text "\u6587\u6848\u5185\u5BB9" --max 800');
5212
5217
  process.exit(1);
5213
5218
  }
5214
5219
  async function runValidateContent(options) {
@@ -5287,6 +5292,111 @@ async function runValidateContent(options) {
5287
5292
  }
5288
5293
  }
5289
5294
 
5295
+ // src/commands/workflow/load-libraries.ts
5296
+ import * as fs10 from "fs";
5297
+ import * as path10 from "path";
5298
+ var REMOTE_BASE = "https://staticpn.siluzan.com/assets/chat/thrju_sofn";
5299
+ var WECHAT_PACK_PATH = "packs/wechat";
5300
+ var LIB_FILES = [
5301
+ { label: "\u6D41\u91CF\u56E0\u5B50\u5E93", file: "umferdarthattasafn.md" },
5302
+ { label: "\u4EA7\u54C1\u8D44\u4EA7\u5E93", file: "vorueignasafn.md" },
5303
+ { label: "\u70F9\u8C03\u65B9\u6CD5\u5E93", file: "matreidsluadferdasafn.md" }
5304
+ ];
5305
+ function isWechatPlatform(platform) {
5306
+ return /公众号|微信|wechat/i.test(platform);
5307
+ }
5308
+ async function downloadText(url) {
5309
+ const res = await rawRequest(url, { headers: { Accept: "text/plain,text/markdown,*/*" } });
5310
+ if (res.status < 200 || res.status >= 300) {
5311
+ throw new Error(`HTTP ${res.status} \u2014 ${url}`);
5312
+ }
5313
+ if (res.text.trim().length === 0) {
5314
+ throw new Error(`\u8FDC\u7AEF\u6587\u4EF6\u4E3A\u7A7A \u2014 ${url}`);
5315
+ }
5316
+ return res.text;
5317
+ }
5318
+ async function fetchAllFrom(base) {
5319
+ return Promise.all(LIB_FILES.map((lib) => downloadText(`${base}/${lib.file}`)));
5320
+ }
5321
+ function combineLibraries(contents) {
5322
+ return LIB_FILES.map((lib, i) => `# ${lib.label}
5323
+
5324
+ ${contents[i].trim()}
5325
+ `).join("\n---\n\n");
5326
+ }
5327
+ async function runLoadLibraries(options) {
5328
+ const platform = options.platform.trim();
5329
+ if (!platform) {
5330
+ console.error("\n\u274C \u7F3A\u5C11\u5E73\u53F0\u53C2\u6570\uFF0C\u8BF7\u7528 --platform <\u5E73\u53F0> \u6307\u5B9A\uFF08\u5982\u300C\u516C\u4F17\u53F7\u300D\u300C\u6296\u97F3\u300D\uFF09");
5331
+ process.exit(1);
5332
+ }
5333
+ const useWechat = isWechatPlatform(platform);
5334
+ let contents;
5335
+ let sourceUsed;
5336
+ try {
5337
+ if (useWechat) {
5338
+ try {
5339
+ contents = await fetchAllFrom(`${REMOTE_BASE}/${WECHAT_PACK_PATH}`);
5340
+ sourceUsed = "wechat-pack";
5341
+ } catch (e) {
5342
+ if (options.verbose) {
5343
+ console.error(`
5344
+ \u26A0\uFE0F \u516C\u4F17\u53F7\u8D5B\u9053\u5305\u62C9\u53D6\u5931\u8D25\uFF0C\u56DE\u9000\u5168\u5C40\u9ED8\u8BA4\u4E09\u5E93\uFF1A${e.message}`);
5345
+ }
5346
+ contents = await fetchAllFrom(REMOTE_BASE);
5347
+ sourceUsed = "global-default";
5348
+ }
5349
+ } else {
5350
+ contents = await fetchAllFrom(REMOTE_BASE);
5351
+ sourceUsed = "global-default";
5352
+ }
5353
+ } catch (e) {
5354
+ console.error(`
5355
+ \u274C \u4E09\u5E93\u62C9\u53D6\u5931\u8D25\uFF1A${e.message}`);
5356
+ if (options.verbose) console.error(e.stack ?? "");
5357
+ process.exit(1);
5358
+ }
5359
+ const combined = combineLibraries(contents);
5360
+ let outPath;
5361
+ try {
5362
+ if (options.out) {
5363
+ outPath = path10.resolve(options.out);
5364
+ fs10.mkdirSync(path10.dirname(outPath), { recursive: true });
5365
+ } else {
5366
+ const cacheDir = path10.join(SILUZAN_DIR, "content-library", ".cache");
5367
+ fs10.mkdirSync(cacheDir, { recursive: true });
5368
+ outPath = path10.join(cacheDir, `three-lib-${sourceUsed}-${Date.now()}.md`);
5369
+ }
5370
+ fs10.writeFileSync(outPath, combined, "utf8");
5371
+ } catch (e) {
5372
+ console.error(`
5373
+ \u274C \u5199\u5165\u5408\u5E76\u6587\u4EF6\u5931\u8D25\uFF1A${e.message}`);
5374
+ process.exit(1);
5375
+ }
5376
+ if (options.json) {
5377
+ console.log(
5378
+ JSON.stringify(
5379
+ {
5380
+ platform,
5381
+ source: sourceUsed,
5382
+ libraries: LIB_FILES.map((l) => l.label),
5383
+ file: outPath,
5384
+ bytes: Buffer.byteLength(combined, "utf8")
5385
+ },
5386
+ null,
5387
+ 2
5388
+ )
5389
+ );
5390
+ return;
5391
+ }
5392
+ console.log(`
5393
+ \u2705 \u4E09\u5E93\u5DF2\u5408\u5E76\u5199\u5165\u5355\u4E2A\u4E34\u65F6\u6587\u4EF6`);
5394
+ console.log(` \u5E73\u53F0\uFF1A${platform}`);
5395
+ console.log(` \u6765\u6E90\uFF1A${sourceUsed === "wechat-pack" ? "\u516C\u4F17\u53F7\u4E13\u5C5E\u8D5B\u9053\u5305" : "\u5168\u5C40\u9ED8\u8BA4\u4E09\u5E93"}`);
5396
+ console.log(` \u542B\u5E93\uFF1A${LIB_FILES.map((l) => l.label).join(" / ")}`);
5397
+ console.log(` \u6587\u4EF6\uFF1A${outPath}`);
5398
+ }
5399
+
5290
5400
  // src/commands/report/_shared.ts
5291
5401
  var DEFAULT_METHOD = "Day";
5292
5402
  var DEFAULT_WORKS_ORDER = "play";
@@ -5604,8 +5714,8 @@ function printMarkdownFetch(runtime, includeModules, sections) {
5604
5714
  }
5605
5715
 
5606
5716
  // src/commands/report/commands.ts
5607
- import * as fs10 from "fs";
5608
- import * as path10 from "path";
5717
+ import * as fs11 from "fs";
5718
+ import * as path11 from "path";
5609
5719
  async function runReportFetch(options) {
5610
5720
  const runtime = buildRuntime(options);
5611
5721
  const includeModules = parseModules(options.include);
@@ -5789,7 +5899,7 @@ function defaultDownloadPath(recordId) {
5789
5899
  const now = /* @__PURE__ */ new Date();
5790
5900
  const pad = (n) => String(n).padStart(2, "0");
5791
5901
  const name = `operations-report-${recordId}-${now.getFullYear()}${pad(now.getMonth() + 1)}${pad(now.getDate())}-${pad(now.getHours())}${pad(now.getMinutes())}${pad(now.getSeconds())}.pdf`;
5792
- return path10.resolve(process.cwd(), name);
5902
+ return path11.resolve(process.cwd(), name);
5793
5903
  }
5794
5904
  async function downloadFile(url, output) {
5795
5905
  const res = await fetch(url);
@@ -5797,7 +5907,7 @@ async function downloadFile(url, output) {
5797
5907
  throw new Error(`\u4E0B\u8F7D\u5931\u8D25\uFF0CHTTP ${res.status}`);
5798
5908
  }
5799
5909
  const buffer = Buffer.from(await res.arrayBuffer());
5800
- fs10.writeFileSync(output, buffer);
5910
+ fs11.writeFileSync(output, buffer);
5801
5911
  }
5802
5912
  async function runReportDownload(options) {
5803
5913
  if (!options.id) {
@@ -5817,7 +5927,7 @@ async function runReportDownload(options) {
5817
5927
  const msg = error.message;
5818
5928
  exitWithError(`\u83B7\u53D6\u4E0B\u8F7D\u5730\u5740\u5931\u8D25\uFF1A${msg}`);
5819
5929
  }
5820
- const output = path10.resolve(options.output ? options.output : defaultDownloadPath(options.id));
5930
+ const output = path11.resolve(options.output ? options.output : defaultDownloadPath(options.id));
5821
5931
  try {
5822
5932
  await downloadFile(pdfUrl, output);
5823
5933
  } catch (error) {
@@ -6048,8 +6158,8 @@ async function requestPlanning(config, endpoint, init = {}, verbose = false) {
6048
6158
  }
6049
6159
 
6050
6160
  // src/commands/planning/commands.ts
6051
- import * as fs11 from "fs";
6052
- import * as path11 from "path";
6161
+ import * as fs12 from "fs";
6162
+ import * as path12 from "path";
6053
6163
  async function runPlanningEnterprises(options) {
6054
6164
  const config = loadConfig(options.token);
6055
6165
  const verbose = Boolean(options.verbose);
@@ -6177,7 +6287,7 @@ async function watchPlanTask(config, taskId, maxWaitMs, onProgress) {
6177
6287
  const url = `${baseUrl}/api/plans/tasks/${encodeURIComponent(taskId)}/progress`;
6178
6288
  const controller = new AbortController();
6179
6289
  let finished = false;
6180
- return new Promise((resolve7, reject) => {
6290
+ return new Promise((resolve8, reject) => {
6181
6291
  const settle = (fn) => {
6182
6292
  if (finished) return;
6183
6293
  finished = true;
@@ -6224,7 +6334,7 @@ async function watchPlanTask(config, taskId, maxWaitMs, onProgress) {
6224
6334
  }
6225
6335
  onProgress?.(event);
6226
6336
  if (event.status === "completed") {
6227
- settle(() => resolve7(event.plan ?? null));
6337
+ settle(() => resolve8(event.plan ?? null));
6228
6338
  return;
6229
6339
  }
6230
6340
  if (event.status === "failed" || event.status === "cancelled") {
@@ -6555,13 +6665,13 @@ function inferEnterpriseNameFromPlan(plan) {
6555
6665
  }
6556
6666
  async function loadPlanFromSource(options, config) {
6557
6667
  if (options.input) {
6558
- const inputPath = path11.resolve(options.input);
6559
- if (!fs11.existsSync(inputPath)) {
6668
+ const inputPath = path12.resolve(options.input);
6669
+ if (!fs12.existsSync(inputPath)) {
6560
6670
  exitWithError2(`\u8F93\u5165\u6587\u4EF6\u4E0D\u5B58\u5728\uFF1A${inputPath}`);
6561
6671
  }
6562
6672
  let raw = "";
6563
6673
  try {
6564
- raw = fs11.readFileSync(inputPath, "utf-8");
6674
+ raw = fs12.readFileSync(inputPath, "utf-8");
6565
6675
  } catch (error) {
6566
6676
  exitWithError2(`\u8BFB\u53D6\u8F93\u5165\u6587\u4EF6\u5931\u8D25\uFF1A${error.message}`);
6567
6677
  }
@@ -6595,9 +6705,9 @@ async function runPlanningExportTxt(options) {
6595
6705
  const defaultName = sanitizeFilename(
6596
6706
  `\u5185\u5BB9\u9009\u9898\u65B9\u5411\u89C4\u5212_${enterpriseName}_${plan.yearMonth ?? "unknown"}.txt`
6597
6707
  );
6598
- const outputPath = path11.resolve(options.output ? options.output : defaultName);
6708
+ const outputPath = path12.resolve(options.output ? options.output : defaultName);
6599
6709
  try {
6600
- fs11.writeFileSync(outputPath, text, "utf-8");
6710
+ fs12.writeFileSync(outputPath, text, "utf-8");
6601
6711
  } catch (error) {
6602
6712
  exitWithError2(`\u5199\u5165\u5BFC\u51FA\u6587\u4EF6\u5931\u8D25\uFF1A${error.message}`);
6603
6713
  }
@@ -7094,8 +7204,8 @@ async function runAuthorize(opts) {
7094
7204
  }
7095
7205
 
7096
7206
  // src/commands/persona.ts
7097
- import fs12 from "fs";
7098
- import path12 from "path";
7207
+ import fs13 from "fs";
7208
+ import path13 from "path";
7099
7209
  var MAX_PERSONA_NAME = 60;
7100
7210
  function unwrapGetPersonas(raw) {
7101
7211
  if (!raw || typeof raw !== "object") return null;
@@ -7167,6 +7277,9 @@ async function runPersonaList(options) {
7167
7277
  const includeStyleGuide = options.includeStyleGuide !== false;
7168
7278
  const results = list.map((p) => projectPersonaForJson(p, includeStyleGuide));
7169
7279
  console.log(JSON.stringify({ results, totalResultCount: total }, null, 2));
7280
+ if (!options.name && !options.id) {
7281
+ console.log("\n\u4EBA\u8BBE\u5217\u8868\u5DF2\u8F93\u51FA\u3002\u8BF7\u6CE8\u610F\uFF1A\u5982\u9700\u4E3A\u7528\u6237\u5199\u6587\u6848\uFF0C\u8BF7\u52A1\u5FC5\u8BE2\u95EE\u7528\u6237\u9009\u62E9\u5177\u4F53\u7684\u4EBA\u8BBE\uFF0C\u5207\u52FF\u9ED8\u8BA4\u6216\u64C5\u81EA\u66FF\u7528\u6237\u51B3\u5B9A\u3002");
7282
+ }
7170
7283
  return;
7171
7284
  }
7172
7285
  if (list.length === 0) {
@@ -7195,18 +7308,21 @@ ${hint}`);
7195
7308
  }));
7196
7309
  const tableOpts2 = options.unicode ? { plain: false } : void 0;
7197
7310
  printCliTable(rows, columns, tableOpts2);
7311
+ if (!options.name && !options.id) {
7312
+ console.log("\n\u63D0\u793A\uFF1A\u4EBA\u8BBE\u5217\u8868\u5DF2\u8F93\u51FA\u3002\u8BF7\u6CE8\u610F\uFF1A\u5982\u9700\u4E3A\u7528\u6237\u5199\u6587\u6848\uFF0C\u8BF7\u52A1\u5FC5\u8BE2\u95EE\u7528\u6237\u9009\u62E9\u5177\u4F53\u7684\u4EBA\u8BBE\uFF0C\u5207\u52FF\u9ED8\u8BA4\u6216\u64C5\u81EA\u66FF\u7528\u6237\u51B3\u5B9A\u3002");
7313
+ }
7198
7314
  console.log("\n\u63D0\u793A\uFF1A\u5B8C\u6574 styleGuide\uFF08Markdown\uFF09\u8BF7\u4F7F\u7528 --json \u67E5\u770B\u6BCF\u6761\u8BB0\u5F55\u7684 styleGuide \u5B57\u6BB5\u3002");
7199
7315
  }
7200
7316
  function readStyleGuideFromFile(filePath) {
7201
- const resolved = path12.resolve(process.cwd(), filePath);
7202
- if (!fs12.existsSync(resolved)) {
7317
+ const resolved = path13.resolve(process.cwd(), filePath);
7318
+ if (!fs13.existsSync(resolved)) {
7203
7319
  throw new Error(`styleGuide \u6587\u4EF6\u4E0D\u5B58\u5728\uFF1A${resolved}`);
7204
7320
  }
7205
- const stat = fs12.statSync(resolved);
7321
+ const stat = fs13.statSync(resolved);
7206
7322
  if (!stat.isFile()) {
7207
7323
  throw new Error(`styleGuide \u6587\u4EF6\u8DEF\u5F84\u4E0D\u662F\u666E\u901A\u6587\u4EF6\uFF1A${resolved}`);
7208
7324
  }
7209
- return fs12.readFileSync(resolved, "utf-8");
7325
+ return fs13.readFileSync(resolved, "utf-8");
7210
7326
  }
7211
7327
  function unwrapAddPersona(raw) {
7212
7328
  if (!raw || typeof raw !== "object") return null;
@@ -7741,7 +7857,7 @@ async function runRagList(options) {
7741
7857
  }
7742
7858
 
7743
7859
  // src/commands/config.ts
7744
- import * as fs13 from "fs";
7860
+ import * as fs14 from "fs";
7745
7861
  function cmdConfigShow() {
7746
7862
  const shared = readSharedConfig();
7747
7863
  const envApiKey = process.env.SILUZAN_API_KEY;
@@ -8089,7 +8205,8 @@ function registerCsoCommands(program2) {
8089
8205
  });
8090
8206
  }
8091
8207
  );
8092
- program2.command("validate-content").description(
8208
+ const workflowCmd = program2.command("workflow").description("\u5185\u5BB9\u521B\u4F5C\u5DE5\u4F5C\u6D41\u76F8\u5173\u547D\u4EE4\uFF1A\u6587\u6848\u6821\u9A8C\u7B49");
8209
+ workflowCmd.command("validate").description(
8093
8210
  "\u6821\u9A8C\u6587\u6848\uFF1A\u7EDF\u8BA1\u5B57\u6570\uFF08\u6C49\u5B57/\u5B57\u7B26/\u5355\u8BCD\uFF09\uFF0C\u6309 --min/--max \u68C0\u67E5\u5B57\u6570\u9650\u5236\uFF0C\u5E76\u68C0\u67E5\u4E09\u5E93\u7F16\u7801/\u6EAF\u6E90\u7B49\u5185\u90E8\u5185\u5BB9\u662F\u5426\u6CC4\u6F0F\u5230\u6210\u7A3F\u3002\u6587\u6848\u6765\u6E90\u652F\u6301 -f \u6587\u4EF6\u3001--text \u884C\u5185\u6587\u672C\u3001\u6216 stdin \u7BA1\u9053\uFF08\u5BBF\u4E3B\u65E0\u6587\u4EF6\u5DE5\u5177\u65F6\u7528\u540E\u4E24\u79CD\uFF09"
8094
8211
  ).option("-f, --file <path>", "\u5F85\u6821\u9A8C\u7684\u6587\u6848\u6587\u4EF6\u8DEF\u5F84\uFF08.md / .txt\uFF09\uFF1B\u4E0E --text / stdin \u4E09\u9009\u4E00").option(
8095
8212
  "--text <content>",
@@ -8114,6 +8231,16 @@ function registerCsoCommands(program2) {
8114
8231
  });
8115
8232
  }
8116
8233
  );
8234
+ workflowCmd.command("load-libraries").description(
8235
+ "\u6309\u5E73\u53F0\u52A0\u8F7D\u5185\u7F6E\u9ED8\u8BA4\u4E09\u5E93\uFF08\u6D41\u91CF\u56E0\u5B50/\u4EA7\u54C1\u8D44\u4EA7/\u70F9\u8C03\u65B9\u6CD5\uFF09\uFF0C\u5C06\u4E09\u4E2A\u6587\u4EF6\u5185\u5BB9\u5408\u5E76\u5199\u5165\u5355\u4E2A\u4E34\u65F6\u6587\u4EF6\u3002\u5E73\u53F0\u542B\u300C\u516C\u4F17\u53F7\u300D\u65F6\u4F18\u5148\u53D6\u4E13\u5C5E\u8D5B\u9053\u5305\uFF0C\u53D6\u4E0D\u5230\u56DE\u9000\u5168\u5C40\u9ED8\u8BA4\u3002"
8236
+ ).requiredOption("--platform <platform>", "\u5E73\u53F0 / \u6E20\u9053\uFF08\u5982\u300C\u516C\u4F17\u53F7\u300D\u300C\u6296\u97F3\u300D\u300CYouTube\u300D\uFF09").option("-o, --out <path>", "\u5408\u5E76\u8F93\u51FA\u6587\u4EF6\u8DEF\u5F84\uFF1B\u7F3A\u7701\u5199\u5165 ~/.siluzan/content-library/.cache/").option("--json", "\u4EE5 JSON \u8F93\u51FA\u7ED3\u679C\uFF08\u9002\u5408\u811A\u672C/\u81EA\u52A8\u5316\uFF09", false).option("--verbose", "\u663E\u793A\u8BE6\u7EC6\u9519\u8BEF\u4FE1\u606F", false).action(async (opts) => {
8237
+ await runLoadLibraries({
8238
+ platform: opts.platform,
8239
+ out: opts.out,
8240
+ json: opts.json,
8241
+ verbose: opts.verbose
8242
+ });
8243
+ });
8117
8244
  program2.command("publish").description("\u6309 JSON \u914D\u7F6E\u6587\u4EF6\u63D0\u4EA4\u53D1\u5E03\u4EFB\u52A1\u5230 CSO").requiredOption("-c, --config <path>", "\u53D1\u5E03\u914D\u7F6E\u6587\u4EF6\u8DEF\u5F84\uFF08JSON\uFF09").option("-t, --token <token>", "Token\uFF08\u53EF\u9009\uFF1B\u4F18\u5148\u4E8E ~/.siluzan/config.json\uFF09").option("--dry-run", "\u4EC5\u9884\u89C8\u8BF7\u6C42\u4F53\uFF0C\u4E0D\u5B9E\u9645\u63D0\u4EA4", false).option("--verbose", "\u663E\u793A\u5B8C\u6574\u8BF7\u6C42\u4F53\u53CA\u8BE6\u7EC6\u9519\u8BEF\uFF08\u542B\u654F\u611F\u5B57\u6BB5\uFF0C\u9ED8\u8BA4\u8131\u654F\uFF09", false).action(
8118
8245
  async (opts) => {
8119
8246
  await runPublish({
@@ -64,7 +64,7 @@ Windows 注意:部分 Agent 客户端通过 PowerShell / cmd 代执行命令
64
64
 
65
65
  - **只读**:查询媒体账号列表、账号分组、运营报表、发布任务状态、人设列表、RAG 知识库检索、AI 内容规划详情
66
66
  - **写入**(需用户确认):上传素材、提交发布任务、创建/更新账号分组、生成 AI 内容规划、站内信回复
67
- - **本地文件操作**:`extract-cover` 在本地截取视频帧并输出图片文件;`validate-content` 在本地校验文案文件(字数限制 / 内部内容泄漏);`init` 将 Skill 文件写入 AI 助手目录
67
+ - **本地文件操作**:`extract-cover` 在本地截取视频帧并输出图片文件;`workflow validate` 在本地校验文案文件(字数限制 / 内部内容泄漏);`init` 将 Skill 文件写入 AI 助手目录
68
68
 
69
69
  ---
70
70
 
@@ -89,26 +89,25 @@ Windows 注意:部分 Agent 客户端通过 PowerShell / cmd 代执行命令
89
89
 
90
90
  ## 命令索引
91
91
 
92
- | 命令 | 作用 | 详细文档 |
93
- | ---------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -------------------------------- |
94
- | `siluzan-cso login` / `siluzan-cso send-login-code` | 登录 / 配置凭据;手机号 + 验证码两段式登录 | `references/setup.md` |
95
- | `siluzan-cso config show/set/clear` | 查看 / 修改 / 清空本地配置 | `references/setup.md` |
96
- | `siluzan-cso init` | Skill 文件初始化(写入 AI 助手目录) | `references/setup.md` |
97
- | `siluzan-cso update` | 更新 CLI 版本并刷新 Skill 文件 | `references/setup.md` |
98
- | `siluzan-cso authorize --media-type <平台>` | 发起媒体账号 OAuth 授权 | `references/authorize.md` |
99
- | `siluzan-cso list-accounts` | 列出媒体账号,获取账号 ID / 数据总览 | `references/list-accounts.md` |
100
- | `siluzan-cso persona list` | 拉取 CSO 人设列表。**请先阅读详细文档,规范操作,避免误用。** | `references/persona.md` |
101
- | `siluzan-cso rag list` | 列出知识库文件夹;`--rag-only` 仅已建索引;`--folder-id` 查指定文件夹下的子库 | `references/rag.md` |
102
- | `siluzan-cso rag query` | 知识库向量检索;**`--partition wiki` 或 `default`**(默认 `default`;写稿与须贴库作答时优先 **wiki**,不足再 **default**);`-q` 含空白时多词分检合并;`--folder-id` / `--tags` 见 `references/rag.md` | `references/rag.md` |
103
- | `siluzan-cso account-group list/create/add-accounts/remove-accounts/update/delete` | 账号分组管理 | `references/account-group.md` |
104
- | `siluzan-cso upload -f <file>` | 上传视频 / 图片到素材库 | `references/upload.md` |
105
- | `siluzan-cso extract-cover -f <video> -p <平台>` | 从视频截取封面帧 | `references/extract-cover.md` |
106
- | `siluzan-cso validate-content -f <file>` | 文案落盘后校验:字数统计 / 字数限制(`--min`/`--max`)/ 内部内容泄漏检查 | `references/validate-content.md` |
107
- | `siluzan-cso publish -c config.json` | 提交多平台发布任务 | `references/publish.md` |
108
- | `siluzan-cso task list/detail/item` | 查看任务状态 / 处理失败 / 重试 | `references/task.md` |
109
- | `siluzan-cso report fetch --media <平台>` | 运营报表(核心指标 / 视频排行 / 趋势) | `references/report.md` |
110
- | `siluzan-cso planning ...` | AI 内容规划:生成、监控、详情、导出 | `references/planning.md` |
111
- | —(网页端) | CSO web端全部页面 URL | `references/web-pages.md` |
92
+ | 命令 | 作用 | 详细文档 |
93
+ | ---------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ----------------------------- |
94
+ | `siluzan-cso login` / `siluzan-cso send-login-code` | 登录 / 配置凭据;手机号 + 验证码两段式登录 | `references/setup.md` |
95
+ | `siluzan-cso config show/set/clear` | 查看 / 修改 / 清空本地配置 | `references/setup.md` |
96
+ | `siluzan-cso init` | Skill 文件初始化(写入 AI 助手目录) | `references/setup.md` |
97
+ | `siluzan-cso update` | 更新 CLI 版本并刷新 Skill 文件 | `references/setup.md` |
98
+ | `siluzan-cso authorize --media-type <平台>` | 发起媒体账号 OAuth 授权 | `references/authorize.md` |
99
+ | `siluzan-cso list-accounts` | 列出媒体账号,获取账号 ID / 数据总览 | `references/list-accounts.md` |
100
+ | `siluzan-cso persona list` | 拉取 CSO 人设列表。**请先阅读详细文档,规范操作,避免误用。** | `references/persona.md` |
101
+ | `siluzan-cso rag list` | 列出知识库文件夹;`--rag-only` 仅已建索引;`--folder-id` 查指定文件夹下的子库 | `references/rag.md` |
102
+ | `siluzan-cso rag query` | 知识库向量检索;**`--partition wiki` 或 `default`**(默认 `default`;写稿与须贴库作答时优先 **wiki**,不足再 **default**);`-q` 含空白时多词分检合并;`--folder-id` / `--tags` 见 `references/rag.md` | `references/rag.md` |
103
+ | `siluzan-cso account-group list/create/add-accounts/remove-accounts/update/delete` | 账号分组管理 | `references/account-group.md` |
104
+ | `siluzan-cso upload -f <file>` | 上传视频 / 图片到素材库 | `references/upload.md` |
105
+ | `siluzan-cso extract-cover -f <video> -p <平台>` | 从视频截取封面帧 | `references/extract-cover.md` |
106
+ | `siluzan-cso publish -c config.json` | 提交多平台发布任务 | `references/publish.md` |
107
+ | `siluzan-cso task list/detail/item` | 查看任务状态 / 处理失败 / 重试 | `references/task.md` |
108
+ | `siluzan-cso report fetch --media <平台>` | 运营报表(核心指标 / 视频排行 / 趋势) | `references/report.md` |
109
+ | `siluzan-cso planning ...` | AI 内容规划:生成、监控、详情、导出 | `references/planning.md` |
110
+ | —(网页端) | CSO web端全部页面 URL | `references/web-pages.md` |
112
111
 
113
112
  ---
114
113
 
@@ -276,6 +275,6 @@ CLI 返回的时间字段(如 `*DateTime` / `*Time` / `createTime` / `publishT
276
275
 
277
276
  > 无对应 CLI 命令的模块,或需要引导用户在网页端查看数据时,查阅 `references/web-pages.md` 获取完整页面清单与链接。
278
277
 
279
- URL 格式:`https://www.siluzan.com/v3/foreign_trade/cso/{页面}`
278
+ URL 格式:`https://www-ci.siluzan.com/v3/foreign_trade/cso/{页面}`
280
279
 
281
280
  常用页面:`task`(任务管理)· `postVideo`(发布页)· `ManageAccounts`(账号管理)· `planning`(AI 内容规划)· `table`(绩效报表)· `Workdata`(作品数据)
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "slug": "siluzan-cso",
3
- "version": "1.1.28",
4
- "publishedAt": 1781171192245,
3
+ "version": "1.1.29-beta.10",
4
+ "publishedAt": 1781595320905,
5
5
  "homepage": "https://www.siluzan.com",
6
6
  "source": "https://dev.azure.com/jack4it/Sammamish/_git/siluzan-skill",
7
7
  "requiredBinaries": [
@@ -236,7 +236,7 @@ siluzan-cso publish -c publish-config.json
236
236
 
237
237
  > 查询发布状态、处理失败项 → 参见 `references/task.md`
238
238
 
239
- 前往 CSO 任务管理页面查看进度:`https://www.siluzan.com/v3/foreign_trade/cso/task`
239
+ 前往 CSO 任务管理页面查看进度:`https://www-ci.siluzan.com/v3/foreign_trade/cso/task`
240
240
 
241
241
  ---
242
242
 
@@ -1,6 +1,6 @@
1
1
  # rag:RAG 知识库检索
2
2
 
3
- 知识库管理页面在https://www.siluzan.com/knowledge-base/
3
+ 知识库管理页面在https://www-ci.siluzan.com/knowledge-base/
4
4
 
5
5
  用于写稿、产品知识问答、三库素材提取等场景;凡回答依赖「本企业已入库素材」且不应凭模型记忆编造时,优先走 RAG。
6
6
 
@@ -3,7 +3,7 @@
3
3
  ## 安装 CLI
4
4
 
5
5
  ```bash
6
- npm install -g siluzan-cso-cli
6
+ npm install -g siluzan-cso-cli@beta
7
7
  ```
8
8
 
9
9
  环境要求:Node.js 18+
@@ -46,7 +46,7 @@ siluzan-cso config set --token <Token> # 备用:设置 JWT Token
46
46
 
47
47
  > **⚠️ 不要使用 `config set --token <token>` 的方式。** 该方式会将 Token 明文写入 shell history(`~/.bash_history`、`~/.zsh_history`、PowerShell 历史),存在凭证泄露风险。推荐使用 `siluzan-cso login` 交互式输入。
48
48
 
49
- API Key 获取入口:`https://www.siluzan.com/v3/foreign_trade/settings/apiKeyManagement`
49
+ API Key 获取入口:`https://www-ci.siluzan.com/v3/foreign_trade/settings/apiKeyManagement`
50
50
 
51
51
  ### 通过手机号 + 验证码登录(对话式 AI 推荐)
52
52
 
@@ -123,8 +123,8 @@ siluzan-cso config show
123
123
 
124
124
  ```
125
125
  构建环境 : production
126
- apiBaseUrl : https://api.siluzan.com
127
- csoBaseUrl : https://cso.siluzan.com
126
+ apiBaseUrl : https://api-ci.siluzan.com
127
+ csoBaseUrl : https://cso-ci.siluzan.com
128
128
  apiKey : abcd****1234
129
129
  ```
130
130
 
@@ -1,4 +1,4 @@
1
- # validate-content — 文案校验(字数限制 + 内部内容泄漏)
1
+ # workflow validate — 文案校验(字数限制 + 内部内容泄漏)
2
2
 
3
3
  > 对文案做**本地**校验:统计字数、按字数限制检查上下限、并检查三库编码 / 溯源 / SOP 等内部骨架资产是否泄漏到成稿。
4
4
  > 纯本地操作,不调用任何接口、不需要鉴权。校验**通过 exit 0,不通过 exit 1**,便于在工作流中卡点。
@@ -9,16 +9,16 @@
9
9
 
10
10
  ```bash
11
11
  # 1) 文件(宿主有文件工具时最常用)
12
- siluzan-cso validate-content -f draft.md --max 800
12
+ siluzan-cso workflow validate -f draft.md --max 800
13
13
 
14
14
  # 2) 管道 / heredoc(推荐:长文不受命令行长度限制)
15
- cat <<'EOF' | siluzan-cso validate-content --max 800
15
+ cat <<'EOF' | siluzan-cso workflow validate --max 800
16
16
  这里是要校验的整篇文案……
17
17
  可以包含多行、markdown 等。
18
18
  EOF
19
19
 
20
20
  # 3) 行内文本(短文案;过长会受 shell 参数长度限制)
21
- siluzan-cso validate-content --text "这里是文案内容" --max 280
21
+ siluzan-cso workflow validate --text "这里是文案内容" --max 280
22
22
  ```
23
23
 
24
24
  > 三者都没提供且 stdin 非管道时,命令会报错并打印上述三种用法指引。
@@ -37,25 +37,25 @@ siluzan-cso validate-content --text "这里是文案内容" --max 280
37
37
 
38
38
  ```bash
39
39
  # 最简:只统计字数 + 默认泄漏检查
40
- siluzan-cso validate-content -f draft.md
40
+ siluzan-cso workflow validate -f draft.md
41
41
 
42
42
  # 字数上限 800(默认按「不含空白字符数」口径)
43
- siluzan-cso validate-content -f draft.md --max 800
43
+ siluzan-cso workflow validate -f draft.md --max 800
44
44
 
45
45
  # 字数区间 1500~3000,按汉字数统计
46
- siluzan-cso validate-content -f article.md --min 1500 --max 3000 --count-by cjk
46
+ siluzan-cso workflow validate -f article.md --min 1500 --max 3000 --count-by cjk
47
47
 
48
48
  # 去除 markdown 语法后再统计(更贴近用户感知的正文字数)
49
- siluzan-cso validate-content -f article.md --max 800 --strip-markdown
49
+ siluzan-cso workflow validate -f article.md --max 800 --strip-markdown
50
50
 
51
51
  # 关闭内部内容泄漏检查(仅看字数)
52
- siluzan-cso validate-content -f draft.md --max 280 --no-check-leak
52
+ siluzan-cso workflow validate -f draft.md --max 280 --no-check-leak
53
53
 
54
54
  # 追加自定义禁用词(命中即不通过)
55
- siluzan-cso validate-content -f draft.md --forbidden "竞品名,内部代号,占位符"
55
+ siluzan-cso workflow validate -f draft.md --forbidden "竞品名,内部代号,占位符"
56
56
 
57
57
  # 脚本/自动化:JSON 输出 + 退出码判定
58
- siluzan-cso validate-content -f draft.md --max 800 --json
58
+ siluzan-cso workflow validate -f draft.md --max 800 --json
59
59
  ```
60
60
 
61
61
  ---