siluzan-cso-cli 1.1.29-beta.1 → 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 +1 -1
- package/dist/index.js +156 -29
- package/dist/skill/SKILL.md +20 -21
- package/dist/skill/_meta.json +2 -2
- package/dist/skill/references/validate-content.md +11 -11
- package/dist/skill/scripts/install.ps1 +1 -1
- package/dist/skill/scripts/install.sh +1 -1
- package/dist/skill/three-lib-content-workflow/collaboration.md +17 -15
- package/dist/skill/three-lib-content-workflow/content-writer.workflow.md +66 -68
- package/dist/skill/three-lib-content-workflow/persona-onboarding.md +29 -28
- package/dist/skill/three-lib-content-workflow/persona-reverse-sop.md +56 -118
- package/dist/skill/three-lib-content-workflow/persona-schema.md +87 -203
- package/dist/skill/three-lib-content-workflow/sop.md +109 -189
- package/package.json +1 -1
- package/dist/skill/three-lib-content-workflow/packs//345/205/254/344/274/227/345/217/267/347/210/206/346/254/276/overview.md +0 -167
- package/dist/skill/three-lib-content-workflow/packs//347/237/255/350/247/206/351/242/221/345/217/243/346/222/255/overview.md +0 -68
- package/dist/skill/three-lib-content-workflow/packs//347/237/255/350/247/206/351/242/221/345/217/243/346/222/255//345/217/243/346/222/255-sop.md +0 -246
package/README.md
CHANGED
|
@@ -54,7 +54,7 @@ siluzan-cso init -d /path/to/skills # 写入自定义目录
|
|
|
54
54
|
siluzan-cso init --force # 强制覆盖已存在文件
|
|
55
55
|
```
|
|
56
56
|
|
|
57
|
-
> **注意**:当前为测试版(1.1.29-beta.
|
|
57
|
+
> **注意**:当前为测试版(1.1.29-beta.10),供内部测试使用。正式发布后安装命令将改为 `npm install -g siluzan-cso-cli`。
|
|
58
58
|
|
|
59
59
|
| 助手 | 建议 `--ai` |
|
|
60
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
|
|
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 {
|
|
@@ -5091,7 +5096,7 @@ async function runUpload(options) {
|
|
|
5091
5096
|
}
|
|
5092
5097
|
}
|
|
5093
5098
|
|
|
5094
|
-
// src/commands/validate
|
|
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
|
|
5210
|
-
console.error(' 2) \u7BA1\u9053\uFF1A echo "\u6587\u6848\u5185\u5BB9" | siluzan-cso validate
|
|
5211
|
-
console.error(' 3) \u884C\u5185\u6587\u672C\uFF1Asiluzan-cso validate
|
|
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
|
|
5608
|
-
import * as
|
|
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
|
|
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
|
-
|
|
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 =
|
|
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
|
|
6052
|
-
import * as
|
|
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((
|
|
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(() =>
|
|
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 =
|
|
6559
|
-
if (!
|
|
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 =
|
|
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 =
|
|
6708
|
+
const outputPath = path12.resolve(options.output ? options.output : defaultName);
|
|
6599
6709
|
try {
|
|
6600
|
-
|
|
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
|
|
7098
|
-
import
|
|
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 =
|
|
7202
|
-
if (!
|
|
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 =
|
|
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
|
|
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
|
|
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("
|
|
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({
|
package/dist/skill/SKILL.md
CHANGED
|
@@ -64,7 +64,7 @@ Windows 注意:部分 Agent 客户端通过 PowerShell / cmd 代执行命令
|
|
|
64
64
|
|
|
65
65
|
- **只读**:查询媒体账号列表、账号分组、运营报表、发布任务状态、人设列表、RAG 知识库检索、AI 内容规划详情
|
|
66
66
|
- **写入**(需用户确认):上传素材、提交发布任务、创建/更新账号分组、生成 AI 内容规划、站内信回复
|
|
67
|
-
- **本地文件操作**:`extract-cover` 在本地截取视频帧并输出图片文件;`validate
|
|
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
|
|
107
|
-
| `siluzan-cso
|
|
108
|
-
| `siluzan-cso
|
|
109
|
-
| `siluzan-cso
|
|
110
|
-
|
|
|
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
|
|
package/dist/skill/_meta.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"slug": "siluzan-cso",
|
|
3
|
-
"version": "1.1.29-beta.
|
|
4
|
-
"publishedAt":
|
|
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": [
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# validate
|
|
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
|
|
12
|
+
siluzan-cso workflow validate -f draft.md --max 800
|
|
13
13
|
|
|
14
14
|
# 2) 管道 / heredoc(推荐:长文不受命令行长度限制)
|
|
15
|
-
cat <<'EOF' | siluzan-cso validate
|
|
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
|
|
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
|
|
40
|
+
siluzan-cso workflow validate -f draft.md
|
|
41
41
|
|
|
42
42
|
# 字数上限 800(默认按「不含空白字符数」口径)
|
|
43
|
-
siluzan-cso validate
|
|
43
|
+
siluzan-cso workflow validate -f draft.md --max 800
|
|
44
44
|
|
|
45
45
|
# 字数区间 1500~3000,按汉字数统计
|
|
46
|
-
siluzan-cso validate
|
|
46
|
+
siluzan-cso workflow validate -f article.md --min 1500 --max 3000 --count-by cjk
|
|
47
47
|
|
|
48
48
|
# 去除 markdown 语法后再统计(更贴近用户感知的正文字数)
|
|
49
|
-
siluzan-cso validate
|
|
49
|
+
siluzan-cso workflow validate -f article.md --max 800 --strip-markdown
|
|
50
50
|
|
|
51
51
|
# 关闭内部内容泄漏检查(仅看字数)
|
|
52
|
-
siluzan-cso validate
|
|
52
|
+
siluzan-cso workflow validate -f draft.md --max 280 --no-check-leak
|
|
53
53
|
|
|
54
54
|
# 追加自定义禁用词(命中即不通过)
|
|
55
|
-
siluzan-cso validate
|
|
55
|
+
siluzan-cso workflow validate -f draft.md --forbidden "竞品名,内部代号,占位符"
|
|
56
56
|
|
|
57
57
|
# 脚本/自动化:JSON 输出 + 退出码判定
|
|
58
|
-
siluzan-cso validate
|
|
58
|
+
siluzan-cso workflow validate -f draft.md --max 800 --json
|
|
59
59
|
```
|
|
60
60
|
|
|
61
61
|
---
|
|
@@ -9,7 +9,7 @@ $ErrorActionPreference = 'Stop'
|
|
|
9
9
|
# -- Package info (injected at build time) ------------------------------------
|
|
10
10
|
$PKG_NAME = 'siluzan-cso-cli'
|
|
11
11
|
# PKG_VERSION 锁定到与本脚本同批构建产物一致的版本,避免与 dist/skill 错位
|
|
12
|
-
$PKG_VERSION = '1.1.29-beta.
|
|
12
|
+
$PKG_VERSION = '1.1.29-beta.10'
|
|
13
13
|
$CLI_BIN = 'siluzan-cso'
|
|
14
14
|
$SKILL_LABEL = 'Siluzan CSO'
|
|
15
15
|
$INSTALL_CMD = 'npm install -g siluzan-cso-cli@beta'
|
|
@@ -9,7 +9,7 @@ set -euo pipefail
|
|
|
9
9
|
# -- Package info (injected at build time) ------------------------------------
|
|
10
10
|
readonly PKG_NAME="siluzan-cso-cli"
|
|
11
11
|
# PKG_VERSION 锁定到与本脚本同批构建产物一致的版本,避免与 dist/skill 错位
|
|
12
|
-
readonly PKG_VERSION="1.1.29-beta.
|
|
12
|
+
readonly PKG_VERSION="1.1.29-beta.10"
|
|
13
13
|
readonly CLI_BIN="siluzan-cso"
|
|
14
14
|
readonly SKILL_LABEL="Siluzan CSO"
|
|
15
15
|
readonly INSTALL_CMD="npm install -g siluzan-cso-cli@beta"
|
|
@@ -5,7 +5,9 @@
|
|
|
5
5
|
**人设是变量,三库是骨架。** 三库都不内置任何人设腔调。
|
|
6
6
|
- 人设卡通过用户注入,统一走 CSO 平台(详见 `persona-schema.md` 和 `persona-onboarding.md`)
|
|
7
7
|
- 三库提供通用结构 / 因子 / 方法
|
|
8
|
-
-
|
|
8
|
+
- 写稿时,人设卡(styleGuide 的 6 个章节)被注入到三库选出的结构里
|
|
9
|
+
|
|
10
|
+
> 人设 = styleGuide 的 6 个章节:`一句话定位` / `目标受众` / `内容 DNA`(开场惯用方式·标志性表达·口头禅·节奏·价值观锚点)/ `推荐用词` / `禁用表达 · 禁忌` / `<平台> 平台适配建议`。平台**没有**结构化字段,下面提到的"风格倾向 / 结构偏好 / 质检尺子"都从这些章节**推断**,推不出来用库内通用默认。
|
|
9
11
|
|
|
10
12
|
## 总原则
|
|
11
13
|
|
|
@@ -27,7 +29,7 @@
|
|
|
27
29
|
|
|
28
30
|
这是**选题和流量入口**。
|
|
29
31
|
|
|
30
|
-
|
|
32
|
+
从人设「一句话定位」+「目标受众」推断行业,决定挂哪些行业因子包。
|
|
31
33
|
|
|
32
34
|
### 2. 产品资产库:决定"写什么能长期有价值"
|
|
33
35
|
|
|
@@ -39,7 +41,7 @@
|
|
|
39
41
|
|
|
40
42
|
这是**内容背后的商业沉淀层**。
|
|
41
43
|
|
|
42
|
-
|
|
44
|
+
从人设「内容 DNA」+「一句话定位」推断风格倾向,过滤可用模板。
|
|
43
45
|
|
|
44
46
|
### 3. 烹调方法库:决定"怎么写最好看"
|
|
45
47
|
|
|
@@ -52,28 +54,28 @@
|
|
|
52
54
|
|
|
53
55
|
这是**表达和结构层**。
|
|
54
56
|
|
|
55
|
-
|
|
57
|
+
从人设「内容 DNA · 开场惯用方式 / 节奏」推断开头与推进偏好,选具体方法;推不出来用库内通用默认。
|
|
56
58
|
|
|
57
59
|
### 4. 人设卡:决定"以谁的口气说"
|
|
58
60
|
|
|
59
61
|
负责判断:
|
|
60
|
-
-
|
|
61
|
-
-
|
|
62
|
-
-
|
|
63
|
-
-
|
|
64
|
-
-
|
|
62
|
+
- 用什么句式 / 口头禅 / 比喻(「内容 DNA · 标志性表达 / 口头禅」)
|
|
63
|
+
- 用什么关键词(「推荐用词」)
|
|
64
|
+
- 用什么语气与节奏(「内容 DNA · 节奏」及整体口吻)
|
|
65
|
+
- 避开什么表达 / 话题(「禁用表达 / 禁忌」)
|
|
66
|
+
- 写完用什么尺子检查(从「价值观锚点」+「一句话定位」提炼,无则通用清单)
|
|
65
67
|
|
|
66
68
|
这是**腔调与边界层**。三库都不持有这些信息。人设卡即 CSO 平台的 styleGuide。
|
|
67
69
|
|
|
68
70
|
## 工作顺序
|
|
69
71
|
|
|
70
72
|
1. **先加载人设**(从 CSO 平台 `siluzan-cso persona list` 拉取;无人设则走 `persona-onboarding.md`)。
|
|
71
|
-
2.
|
|
72
|
-
3.
|
|
73
|
-
4.
|
|
74
|
-
5.
|
|
75
|
-
6.
|
|
76
|
-
7.
|
|
73
|
+
2. 从流量因子库挑题(从「一句话定位 / 目标受众」推断行业挂行业包)。
|
|
74
|
+
3. 从产品资产库找落点(从「内容 DNA / 一句话定位」推断风格倾向过滤模板)。
|
|
75
|
+
4. 从烹调方法库选结构(从「内容 DNA · 开场惯用方式 / 节奏」推断,无则通用默认)。
|
|
76
|
+
5. 最后生成文案,**腔调从人设卡注入**(「内容 DNA」+「推荐用词」,避「禁用表达 / 禁忌」)。
|
|
77
|
+
6. 质检(从「价值观锚点 / 一句话定位」提炼尺子,叠加通用清单)。
|
|
78
|
+
7. 写完反哺人设卡(把新句式/口头禅并入「内容 DNA」、新禁忌并入「禁用表达 / 禁忌」、新词并入「推荐用词」,平台模式下存为新版本)。
|
|
77
79
|
|
|
78
80
|
## 一句话总结
|
|
79
81
|
|