@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 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
@@ -1,6 +1,6 @@
1
1
  {
2
- "generatedAt": "2026-07-22T12:34:00.265Z",
3
- "cliVersion": "0.2.21",
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",
@@ -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;AA0pED,OAAO,EAAE,OAAO,EAAE,CAAC"}
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, draft, commentType, thread:{subreddit,postTitle,...}, brandContext?:{brandKey|campaignId}, rewrite?, stage?, attempt? }")
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, title, body, subreddit, subredditRules?, brandContext?:{brandKey|campaignId}, rewrite?, stage?, attempt? }")
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");