@geoly-ai/social-hub-cli 0.2.21 → 0.2.23
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/CHANGELOG.md +14 -0
- package/dist/cmd-manifest.json +20 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +174 -2
- package/dist/index.js.map +1 -1
- package/dist/index.test.js +20 -0
- package/dist/index.test.js.map +1 -1
- package/package.json +3 -3
- package/skills/manifest.json +1 -1
- package/skills/social-hub-content-review/SKILL.md +23 -5
- package/skills/social-hub-post-review/SKILL.md +23 -4
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,20 @@ All notable changes to `@geoly-ai/social-hub-cli` are documented in this file.
|
|
|
4
4
|
|
|
5
5
|
Release workflow: `pnpm release:cli` → `pnpm publish:cli`.
|
|
6
6
|
|
|
7
|
+
## [0.2.23] - 2026-07-24
|
|
8
|
+
|
|
9
|
+
审核门 v1.5 文档面:content/post review accountId 可选(ContentOnly/AccountBound 双模式)+审核 skill 文档更新
|
|
10
|
+
|
|
11
|
+
### Documentation
|
|
12
|
+
|
|
13
|
+
- v1.5 文档面 —— accountId 可选 + ContentOnly/AccountBound 双模式
|
|
14
|
+
|
|
15
|
+
## [0.2.22] - 2026-07-23
|
|
16
|
+
|
|
17
|
+
### Added
|
|
18
|
+
|
|
19
|
+
- Trigger P1-D3 —— 四眼 registry 管理面 CLI 命令(social-hub)
|
|
20
|
+
|
|
7
21
|
## [0.2.21] - 2026-07-22
|
|
8
22
|
|
|
9
23
|
### Added
|
package/dist/cmd-manifest.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
|
-
"generatedAt": "2026-07-
|
|
3
|
-
"cliVersion": "0.2.
|
|
2
|
+
"generatedAt": "2026-07-24T12:32:09.933Z",
|
|
3
|
+
"cliVersion": "0.2.23",
|
|
4
4
|
"commands": [
|
|
5
5
|
"accounts",
|
|
6
6
|
"accounts brand-bindings",
|
|
@@ -67,6 +67,24 @@
|
|
|
67
67
|
"brand-fit",
|
|
68
68
|
"brand-fit migrate",
|
|
69
69
|
"brand-fit show",
|
|
70
|
+
"brand-fit-registry",
|
|
71
|
+
"brand-fit-registry avoid-contexts",
|
|
72
|
+
"brand-fit-registry avoid-contexts list",
|
|
73
|
+
"brand-fit-registry avoid-contexts show",
|
|
74
|
+
"brand-fit-registry proposals",
|
|
75
|
+
"brand-fit-registry proposals apply",
|
|
76
|
+
"brand-fit-registry proposals approve",
|
|
77
|
+
"brand-fit-registry proposals cancel",
|
|
78
|
+
"brand-fit-registry proposals list",
|
|
79
|
+
"brand-fit-registry proposals propose",
|
|
80
|
+
"brand-fit-registry proposals reject",
|
|
81
|
+
"brand-fit-registry proposals show",
|
|
82
|
+
"brand-fit-registry rule-signals",
|
|
83
|
+
"brand-fit-registry rule-signals list",
|
|
84
|
+
"brand-fit-registry rule-signals show",
|
|
85
|
+
"brand-fit-registry triggers",
|
|
86
|
+
"brand-fit-registry triggers list",
|
|
87
|
+
"brand-fit-registry triggers show",
|
|
70
88
|
"brand-members",
|
|
71
89
|
"brand-members create",
|
|
72
90
|
"brand-members list",
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AA2BpC,QAAA,MAAM,OAAO,SAAgB,CAAC;AAiqD9B,8DAA8D;AAC9D,wBAAgB,4BAA4B,CAC1C,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC5B,MAAM,GAAG,IAAI,CAOf;AAs+BD,MAAM,MAAM,gBAAgB,GAAG;IAC7B,QAAQ,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IAC1D,mBAAmB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACjE,CAAC;AAQF,wBAAsB,qBAAqB,CACzC,MAAM,EAAE,gBAAgB,EACxB,MAAM,EAAE;IACN,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC/B,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACtC,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,OAAO,CAAC;IACf,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CACvC,GACA,OAAO,CAAC;IAAE,QAAQ,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAAE,CAAC,CAkJnE;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AA2BpC,QAAA,MAAM,OAAO,SAAgB,CAAC;AAiqD9B,8DAA8D;AAC9D,wBAAgB,4BAA4B,CAC1C,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC5B,MAAM,GAAG,IAAI,CAOf;AAs+BD,MAAM,MAAM,gBAAgB,GAAG;IAC7B,QAAQ,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IAC1D,mBAAmB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACjE,CAAC;AAQF,wBAAsB,qBAAqB,CACzC,MAAM,EAAE,gBAAgB,EACxB,MAAM,EAAE;IACN,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC/B,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACtC,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,OAAO,CAAC;IACf,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CACvC,GACA,OAAO,CAAC;IAAE,QAAQ,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAAE,CAAC,CAkJnE;AA+1ED,OAAO,EAAE,OAAO,EAAE,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -462,7 +462,7 @@ content
|
|
|
462
462
|
.command("review")
|
|
463
463
|
.description("POST /content-review — 评论发布前独立 LLM 复审+优化(层③);degraded 时降级本地自审")
|
|
464
464
|
.option("-t, --team <teamId>", "Team UUID(缺省用当前 context)")
|
|
465
|
-
.requiredOption("-j, --json <json>", "{ accountId
|
|
465
|
+
.requiredOption("-j, --json <json>", "{ accountId?, draft, commentType, thread:{subreddit,postTitle,...}, brandContext?:{brandKey|campaignId}, rewrite?, stage?, attempt? } (omit accountId for persona-less ContentOnly review)")
|
|
466
466
|
.option("--brand-context <json>", '品牌上下文 { "brandKey":"..." } 或 { "campaignId":"..." }(§0.3;便捷参数,覆盖 -j 里的 brandContext)')
|
|
467
467
|
.action(async (opts) => {
|
|
468
468
|
let body;
|
|
@@ -489,7 +489,7 @@ content
|
|
|
489
489
|
.command("post-review")
|
|
490
490
|
.description("POST /post-review — 帖子(title+body)发布前独立 LLM 审核(七维,独立模型 key);仅审帖子正文,评论审核用 content review")
|
|
491
491
|
.option("-t, --team <teamId>", "Team UUID(缺省用当前 context)")
|
|
492
|
-
.requiredOption("-j, --json <json>", "{ accountId
|
|
492
|
+
.requiredOption("-j, --json <json>", "{ accountId?, title, body, subreddit, subredditRules?, brandContext?:{brandKey|campaignId}, rewrite?, stage?, attempt? } (omit accountId for persona-less ContentOnly review)")
|
|
493
493
|
.option("--brand-context <json>", '品牌上下文 { "brandKey":"..." } 或 { "campaignId":"..." }(便捷参数,覆盖 -j 里的 brandContext)')
|
|
494
494
|
.action(async (opts) => {
|
|
495
495
|
let body;
|
|
@@ -3774,6 +3774,178 @@ brandRegistry
|
|
|
3774
3774
|
cursor: opts.cursor,
|
|
3775
3775
|
}), null, 2));
|
|
3776
3776
|
});
|
|
3777
|
+
// ── Trigger 注册表四眼管理面(P1-D3)——只提案/审批/执行,不提供直写命令 ──────────────
|
|
3778
|
+
const bfRegistry = program
|
|
3779
|
+
.command("brand-fit-registry")
|
|
3780
|
+
.description("Trigger 注册表四眼管理面:trigger/avoid/rule_signal 的 create/update/scope/mandate/retire 全走 propose→approve→apply(无直写命令)");
|
|
3781
|
+
const out = (v) => console.log(JSON.stringify(v, null, 2));
|
|
3782
|
+
/** apply 的 stale 友好提示(不解析 message,靠 SDK RegistryProposalSdkError.isStale)。 */
|
|
3783
|
+
function handleProposalError(err) {
|
|
3784
|
+
const e = err;
|
|
3785
|
+
if (e && e.isStale) {
|
|
3786
|
+
console.error(`proposal 已过时(staleCode=${e.staleCode}):目标已变更,请 show 最新状态后重新 propose`);
|
|
3787
|
+
}
|
|
3788
|
+
else if (e && e.code) {
|
|
3789
|
+
console.error(`${e.code}: ${e.message ?? ""}`);
|
|
3790
|
+
}
|
|
3791
|
+
else {
|
|
3792
|
+
console.error(e?.message ?? String(err));
|
|
3793
|
+
}
|
|
3794
|
+
process.exit(1);
|
|
3795
|
+
}
|
|
3796
|
+
const bfrProposals = bfRegistry
|
|
3797
|
+
.command("proposals")
|
|
3798
|
+
.description("四眼提案(propose/approve/reject/cancel/apply/list/show)");
|
|
3799
|
+
bfrProposals
|
|
3800
|
+
.command("propose")
|
|
3801
|
+
.description("提交一个 registry 变更提案(RegistryProposalInput)")
|
|
3802
|
+
.requiredOption("--input <json>", 'RegistryProposalInput JSON,如 {"type":"trigger.create","triggerKey":"...","matchDefinition":{...},"scopeMode":"global"}')
|
|
3803
|
+
.requiredOption("--idempotency-key <key>", "幂等键(同 proposer 同 key 返既有)")
|
|
3804
|
+
.option("--expires-at <iso>", "过期时间 ISO(可选,须晚于当前)")
|
|
3805
|
+
.action(async (opts) => {
|
|
3806
|
+
let input;
|
|
3807
|
+
try {
|
|
3808
|
+
input = JSON.parse(opts.input);
|
|
3809
|
+
}
|
|
3810
|
+
catch {
|
|
3811
|
+
console.error("Invalid --input JSON");
|
|
3812
|
+
process.exit(1);
|
|
3813
|
+
}
|
|
3814
|
+
try {
|
|
3815
|
+
out(await requireClient().proposeRegistryChange({
|
|
3816
|
+
input,
|
|
3817
|
+
idempotencyKey: opts.idempotencyKey,
|
|
3818
|
+
expiresAt: opts.expiresAt,
|
|
3819
|
+
}));
|
|
3820
|
+
}
|
|
3821
|
+
catch (err) {
|
|
3822
|
+
handleProposalError(err);
|
|
3823
|
+
}
|
|
3824
|
+
});
|
|
3825
|
+
bfrProposals
|
|
3826
|
+
.command("approve")
|
|
3827
|
+
.description("批准提案(四眼第二只眼;审批人须≠提案人)")
|
|
3828
|
+
.requiredOption("--id <id>", "proposal id")
|
|
3829
|
+
.option("--comment <text>", "审批备注")
|
|
3830
|
+
.action(async (opts) => {
|
|
3831
|
+
try {
|
|
3832
|
+
out(await requireClient().approveRegistryProposal(opts.id, {
|
|
3833
|
+
approvalComment: opts.comment,
|
|
3834
|
+
}));
|
|
3835
|
+
}
|
|
3836
|
+
catch (err) {
|
|
3837
|
+
handleProposalError(err);
|
|
3838
|
+
}
|
|
3839
|
+
});
|
|
3840
|
+
bfrProposals
|
|
3841
|
+
.command("reject")
|
|
3842
|
+
.description("拒绝提案")
|
|
3843
|
+
.requiredOption("--id <id>", "proposal id")
|
|
3844
|
+
.option("--reason <text>", "拒绝原因")
|
|
3845
|
+
.action(async (opts) => {
|
|
3846
|
+
try {
|
|
3847
|
+
out(await requireClient().rejectRegistryProposal(opts.id, {
|
|
3848
|
+
rejectionReason: opts.reason,
|
|
3849
|
+
}));
|
|
3850
|
+
}
|
|
3851
|
+
catch (err) {
|
|
3852
|
+
handleProposalError(err);
|
|
3853
|
+
}
|
|
3854
|
+
});
|
|
3855
|
+
bfrProposals
|
|
3856
|
+
.command("cancel")
|
|
3857
|
+
.description("取消提案(proposed 或 approved;apply 前)")
|
|
3858
|
+
.requiredOption("--id <id>", "proposal id")
|
|
3859
|
+
.action(async (opts) => {
|
|
3860
|
+
try {
|
|
3861
|
+
out(await requireClient().cancelRegistryProposal(opts.id));
|
|
3862
|
+
}
|
|
3863
|
+
catch (err) {
|
|
3864
|
+
handleProposalError(err);
|
|
3865
|
+
}
|
|
3866
|
+
});
|
|
3867
|
+
bfrProposals
|
|
3868
|
+
.command("apply")
|
|
3869
|
+
.description("执行已批准提案(stale→提示重新提案)")
|
|
3870
|
+
.requiredOption("--id <id>", "proposal id")
|
|
3871
|
+
.action(async (opts) => {
|
|
3872
|
+
try {
|
|
3873
|
+
out(await requireClient().applyRegistryProposal(opts.id));
|
|
3874
|
+
}
|
|
3875
|
+
catch (err) {
|
|
3876
|
+
handleProposalError(err);
|
|
3877
|
+
}
|
|
3878
|
+
});
|
|
3879
|
+
bfrProposals
|
|
3880
|
+
.command("list")
|
|
3881
|
+
.description("列出提案(可按 status 过滤)")
|
|
3882
|
+
.option("--status <status>", "proposed|approved|rejected|cancelled|applied|stale")
|
|
3883
|
+
.action(async (opts) => {
|
|
3884
|
+
out(await requireClient().listRegistryProposals({ status: opts.status }));
|
|
3885
|
+
});
|
|
3886
|
+
bfrProposals
|
|
3887
|
+
.command("show")
|
|
3888
|
+
.description("查看单个提案")
|
|
3889
|
+
.requiredOption("--id <id>", "proposal id")
|
|
3890
|
+
.action(async (opts) => {
|
|
3891
|
+
try {
|
|
3892
|
+
out(await requireClient().getRegistryProposal(opts.id));
|
|
3893
|
+
}
|
|
3894
|
+
catch (err) {
|
|
3895
|
+
handleProposalError(err);
|
|
3896
|
+
}
|
|
3897
|
+
});
|
|
3898
|
+
const bfrTriggers = bfRegistry
|
|
3899
|
+
.command("triggers")
|
|
3900
|
+
.description("trigger 注册表(只读;写走 proposals)");
|
|
3901
|
+
bfrTriggers
|
|
3902
|
+
.command("list")
|
|
3903
|
+
.action(async () => out(await requireClient().listBrandFitTriggers()));
|
|
3904
|
+
bfrTriggers
|
|
3905
|
+
.command("show")
|
|
3906
|
+
.requiredOption("--key <triggerKey>")
|
|
3907
|
+
.action(async (opts) => {
|
|
3908
|
+
try {
|
|
3909
|
+
out(await requireClient().getBrandFitTrigger(opts.key));
|
|
3910
|
+
}
|
|
3911
|
+
catch (err) {
|
|
3912
|
+
handleProposalError(err);
|
|
3913
|
+
}
|
|
3914
|
+
});
|
|
3915
|
+
const bfrAvoids = bfRegistry
|
|
3916
|
+
.command("avoid-contexts")
|
|
3917
|
+
.description("avoid_context 注册表(只读;写走 proposals)");
|
|
3918
|
+
bfrAvoids
|
|
3919
|
+
.command("list")
|
|
3920
|
+
.action(async () => out(await requireClient().listBrandFitAvoidContexts()));
|
|
3921
|
+
bfrAvoids
|
|
3922
|
+
.command("show")
|
|
3923
|
+
.requiredOption("--key <avoidKey>")
|
|
3924
|
+
.action(async (opts) => {
|
|
3925
|
+
try {
|
|
3926
|
+
out(await requireClient().getBrandFitAvoidContext(opts.key));
|
|
3927
|
+
}
|
|
3928
|
+
catch (err) {
|
|
3929
|
+
handleProposalError(err);
|
|
3930
|
+
}
|
|
3931
|
+
});
|
|
3932
|
+
const bfrSignals = bfRegistry
|
|
3933
|
+
.command("rule-signals")
|
|
3934
|
+
.description("rule_signal 注册表(只读;写走 proposals)");
|
|
3935
|
+
bfrSignals
|
|
3936
|
+
.command("list")
|
|
3937
|
+
.action(async () => out(await requireClient().listBrandFitRuleSignals()));
|
|
3938
|
+
bfrSignals
|
|
3939
|
+
.command("show")
|
|
3940
|
+
.requiredOption("--key <signalKey>")
|
|
3941
|
+
.action(async (opts) => {
|
|
3942
|
+
try {
|
|
3943
|
+
out(await requireClient().getBrandFitRuleSignal(opts.key));
|
|
3944
|
+
}
|
|
3945
|
+
catch (err) {
|
|
3946
|
+
handleProposalError(err);
|
|
3947
|
+
}
|
|
3948
|
+
});
|
|
3777
3949
|
const brandFit = program
|
|
3778
3950
|
.command("brand-fit")
|
|
3779
3951
|
.description("Persona Brand Fit 分级(persona×brand 正式关系):关系表查看 + 受控迁移 validate/apply");
|