@geoly-ai/social-hub-cli 0.2.23 → 0.2.24

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.
Files changed (53) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/dist/client.d.ts +21 -0
  3. package/dist/client.d.ts.map +1 -1
  4. package/dist/client.js +64 -1
  5. package/dist/client.js.map +1 -1
  6. package/dist/client.test.d.ts +2 -0
  7. package/dist/client.test.d.ts.map +1 -0
  8. package/dist/client.test.js +123 -0
  9. package/dist/client.test.js.map +1 -0
  10. package/dist/cmd-manifest.json +14 -2
  11. package/dist/cmd-manifest.test.js +4 -0
  12. package/dist/cmd-manifest.test.js.map +1 -1
  13. package/dist/index.d.ts.map +1 -1
  14. package/dist/index.js +2 -0
  15. package/dist/index.js.map +1 -1
  16. package/dist/permission-runner.d.ts +21 -4
  17. package/dist/permission-runner.d.ts.map +1 -1
  18. package/dist/permission-runner.js +36 -9
  19. package/dist/permission-runner.js.map +1 -1
  20. package/dist/permission-runner.test.js +76 -0
  21. package/dist/permission-runner.test.js.map +1 -1
  22. package/dist/permissions-gates-subreddit-style.d.ts +10 -0
  23. package/dist/permissions-gates-subreddit-style.d.ts.map +1 -0
  24. package/dist/permissions-gates-subreddit-style.js +66 -0
  25. package/dist/permissions-gates-subreddit-style.js.map +1 -0
  26. package/dist/permissions-gates-subreddit-style.test.d.ts +2 -0
  27. package/dist/permissions-gates-subreddit-style.test.d.ts.map +1 -0
  28. package/dist/permissions-gates-subreddit-style.test.js +44 -0
  29. package/dist/permissions-gates-subreddit-style.test.js.map +1 -0
  30. package/dist/permissions.d.ts +10 -0
  31. package/dist/permissions.d.ts.map +1 -1
  32. package/dist/permissions.js +9 -2
  33. package/dist/permissions.js.map +1 -1
  34. package/dist/register-extensions.d.ts.map +1 -1
  35. package/dist/register-extensions.js +1 -0
  36. package/dist/register-extensions.js.map +1 -1
  37. package/dist/register-subreddit-style-actions.test.d.ts +2 -0
  38. package/dist/register-subreddit-style-actions.test.d.ts.map +1 -0
  39. package/dist/register-subreddit-style-actions.test.js +295 -0
  40. package/dist/register-subreddit-style-actions.test.js.map +1 -0
  41. package/dist/register-subreddit-style.d.ts +57 -0
  42. package/dist/register-subreddit-style.d.ts.map +1 -0
  43. package/dist/register-subreddit-style.js +418 -0
  44. package/dist/register-subreddit-style.js.map +1 -0
  45. package/dist/register-subreddit-style.test.d.ts +2 -0
  46. package/dist/register-subreddit-style.test.d.ts.map +1 -0
  47. package/dist/register-subreddit-style.test.js +183 -0
  48. package/dist/register-subreddit-style.test.js.map +1 -0
  49. package/package.json +3 -3
  50. package/skills/README.md +1 -0
  51. package/skills/manifest.json +6 -1
  52. package/skills/social-hub-cli/SKILL.md +1 -0
  53. package/skills/social-hub-style-profiles/SKILL.md +126 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@geoly-ai/social-hub-cli",
3
- "version": "0.2.23",
3
+ "version": "0.2.24",
4
4
  "type": "module",
5
5
  "description": "social-hub CLI for Social Ops Hub",
6
6
  "repository": {
@@ -22,8 +22,8 @@
22
22
  },
23
23
  "dependencies": {
24
24
  "commander": "^12.1.0",
25
- "@geoly-ai/social-hub-sdk": "0.0.38",
26
- "@geoly-ai/social-hub-authz": "0.0.7"
25
+ "@geoly-ai/social-hub-authz": "0.0.7",
26
+ "@geoly-ai/social-hub-sdk": "0.0.38"
27
27
  },
28
28
  "devDependencies": {
29
29
  "@types/node": "^22.10.2",
package/skills/README.md CHANGED
@@ -126,6 +126,7 @@ pnpm skills:check
126
126
  | [social-hub-accounts](social-hub-accounts) | 账号 CRUD、browser-envs、personas |
127
127
  | [social-hub-posts](social-hub-posts) | Reddit 帖快照 CRUD、batch-upsert |
128
128
  | [social-hub-style-curator](social-hub-style-curator) | style-marks、curator、style-guide |
129
+ | [social-hub-style-profiles](social-hub-style-profiles) | 板块画像四眼、帖子标注 |
129
130
  | [social-hub-calendar-jobs](social-hub-calendar-jobs) | 日历与任务 |
130
131
  | [social-hub-publishing](social-hub-publishing) | 发布闭环 |
131
132
  | [social-hub-events-observability](social-hub-events-observability) | events、dashboard、audit、reports |
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 1,
3
3
  "package": "social-ops-hub",
4
- "cliVersion": "0.2.23",
4
+ "cliVersion": "0.2.24",
5
5
  "repository": "social-ops-hub",
6
6
  "publish": {
7
7
  "registry": "https://skill.sh",
@@ -44,6 +44,11 @@
44
44
  "path": "social-hub-style-curator",
45
45
  "description": "style-marks 审核/沉淀、curator run、accounts style-guide"
46
46
  },
47
+ {
48
+ "id": "social-hub-style-profiles",
49
+ "path": "social-hub-style-profiles",
50
+ "description": "板块画像四眼治理(style-profiles)与帖子标注(subreddit-annotations)"
51
+ },
47
52
  {
48
53
  "id": "social-hub-calendar-jobs",
49
54
  "path": "social-hub-calendar-jobs",
@@ -38,6 +38,7 @@ social-hub version --json
38
38
  | 社交账号 CRUD / browser-envs / personas | `social-hub-accounts` |
39
39
  | Reddit 帖快照 CRUD / batch-upsert | `social-hub-posts` |
40
40
  | style-marks / curator / style-guide | `social-hub-style-curator` |
41
+ | 板块画像四眼 / 帖子标注 | `social-hub-style-profiles` |
41
42
  | 日历 / scheduled jobs | `social-hub-calendar-jobs` |
42
43
  | 发布闭环(brand→report) | `social-hub-publishing` |
43
44
  | 评论发布前复审/优化(三层 gate 层③) | `social-hub-content-review` |
@@ -0,0 +1,126 @@
1
+ ---
2
+ name: social-hub-style-profiles
3
+ description: >-
4
+ Social Hub 板块画像/帖子标注:style-profiles list/get/active/propose/approve/reject/cancel/retire
5
+ (系统级四眼治理)与 subreddit-annotations list/upsert(团队维度人工标注)。
6
+ 用户要查/审板块风格画像、处理画像提案、给 Reddit 帖打 style_fit/brand_friendliness 标注时用本 skill。
7
+ 不用于账号级 style-marks/curator(用 social-hub-style-curator)、运营板块池 CRUD(用 social-hub-subreddit-pools)。
8
+ metadata:
9
+ cliVersion: ">=0.2.24"
10
+ ---
11
+
12
+ # social-hub-style-profiles
13
+
14
+ > **前置条件:** 先阅读 [`../social-hub-shared/SKILL.md`](../social-hub-shared/SKILL.md),
15
+ > 确认已 `auth login`(Device Code 的 CLI **user token**)并 `context use <team-id>`。
16
+
17
+ 板块画像(`subreddit_style_profiles`)是系统级共享知识库:worker 定时从板块热帖用 LLM 起草,
18
+ **恒以 `proposed` 入库**,必须人工四眼审批后 `approved` 才生效(供发帖/评论审核 enrich 引用)。
19
+ 帖子标注(`subreddit_post_annotations`)是 team 维度的人工研判(`style_fit` / `brand_friendliness`,1-5 分)。
20
+
21
+ ## 职责边界
22
+
23
+ | 做 | 不做 |
24
+ | -------------------------------------------------------- | ---------------------------------------------------------------------- |
25
+ | 画像读面 list/get/active、提案 propose、四眼审批流转 | 账号级风格资产(style-marks / curator run → social-hub-style-curator) |
26
+ | 帖子 style_fit / brand_friendliness 人工标注 list/upsert | 运营板块池 catalog/aliases/tier rules(→ social-hub-subreddit-pools) |
27
+
28
+ ## 关键约束(先读再操作)
29
+
30
+ - **写操作全部 user-only**:propose/approve/reject/cancel/retire/upsert 拒绝 API Key(CLI 本地先拒,API 侧同样 403)。
31
+ 必须用 `social-hub auth login` 拿到的 CLI token 执行。
32
+ - **角色**:画像写只 manager/admin;标注 supervisor 及以上可写、senior/internal 只读、client 恒拒。
33
+ - **四眼审批**:提案人本人不能 approve(409 `SELF_APPROVE`)——propose 和 approve 要换人操作。
34
+ - **If-Match 乐观锁**:approve/reject/cancel/retire 必须带 `If-Match: <rowVersion>`。
35
+ CLI 缺省自动 `GET` 一次取当前 `profile.rowVersion` 带上;也可 `--row-version <token>` 显式传(接受裸 token 或带引号 ETag)。
36
+ 自动 GET 只是便利,竞态保护在服务端锁内:409 `PROFILE_STALE` 表示已被他人变更,**重新 get 核对后再重试**(CLI 不会自动重试)。
37
+ - **cancel 仅提案人本人**(worker/LLM 起草的画像 `proposedByUserId` 为空,不可 cancel,由 manager/admin 用 `reject`)。
38
+
39
+ ## 画像读面
40
+
41
+ ```bash
42
+ social-hub style-profiles list [--subreddit <name>] [--scope global|brand] \
43
+ [--brand <uuid>] [--status proposed,approved] [-n 50] [--offset 0]
44
+ social-hub style-profiles get --id <profile-uuid> # 响应 profile.rowVersion = 写操作 If-Match 值
45
+ social-hub style-profiles active --subreddit <name> [--brand <uuid>]
46
+ ```
47
+
48
+ `active` 语义:传 `--brand` 优先返回该品牌的 approved override,无 override 回退 global;不传只查 global。
49
+ **没有生效画像是正常状态**,输出 `{ "profile": null, "versionToken": null }`,退出码 0。
50
+
51
+ ## 画像四眼工作流
52
+
53
+ ```bash
54
+ # 1) 提案人:起草新画像版本(恒 proposed 入库;profile 至少含 tone 或非空 stylePoints/taboos)
55
+ social-hub style-profiles propose -j '{
56
+ "scope": "global",
57
+ "subreddit": "bouldering",
58
+ "profile": {
59
+ "tone": "laid-back, supportive, anti-gatekeeping",
60
+ "stylePoints": ["share genuine progress stories", "beta questions welcome"],
61
+ "taboos": ["humble-bragging", "brand shilling"]
62
+ },
63
+ "summary": "r/bouldering 新手工友好社区画像"
64
+ }' --apply # scope=brand 时必须带 "brandId"
65
+
66
+ # 2) 另一位 manager/admin:审批(自动 GET 取 rowVersion;--dry-run 先看 status/版本/提案人)
67
+ social-hub style-profiles approve --id <profile-uuid> --dry-run
68
+ social-hub style-profiles approve --id <profile-uuid> --apply
69
+
70
+ # 审批人驳回(仅 proposed;落 retire_reason=rejected:<reason>)
71
+ social-hub style-profiles reject --id <profile-uuid> --reason "taboos 与实际版规不符" --apply
72
+
73
+ # 提案人本人撤回(仅 proposed 且本人;worker/LLM 提案请用 reject)
74
+ social-hub style-profiles cancel --id <profile-uuid> --reason "重新整理后再提" --apply
75
+
76
+ # 停用已生效画像(仅 approved)
77
+ social-hub style-profiles retire --id <profile-uuid> --reason "画像过时,等新版本" --apply
78
+ ```
79
+
80
+ 所有写命令都遵循 `--dry-run` 预览 / `--apply` 执行约定;dry-run 会展示将写入的摘要
81
+ (流转命令含自动取得的 `rowVersion` 与当前 `status/version/proposedByUserId`)。
82
+
83
+ ## 帖子标注(team 维度)
84
+
85
+ ```bash
86
+ social-hub subreddit-annotations list [-t <team-id>] [--subreddit <name>] \
87
+ [--permalink <url>] [--type style_fit|brand_friendliness] [--brand <uuid>] \
88
+ [--source llm|human] [-n 50] [--offset 0]
89
+
90
+ social-hub subreddit-annotations upsert [-t <team-id>] \
91
+ --subreddit bouldering \
92
+ --permalink "https://www.reddit.com/r/bouldering/comments/abc123/some_title/" \
93
+ --type style_fit --score 4 \
94
+ --label "tone-match" --note "高赞评论语气与画像一致" --apply
95
+
96
+ # brand_friendliness 必须带 --brand;style_fit 禁带 --brand
97
+ social-hub subreddit-annotations upsert -t <team-id> \
98
+ --subreddit bouldering --permalink "https://old.reddit.com/r/bouldering/comments/xyz789/t/" \
99
+ --type brand_friendliness --brand <brand-uuid> --score 2 \
100
+ --note "对品牌提及敏感,慎用" --apply
101
+ ```
102
+
103
+ - **list 返回本团队行+全局行**:响应里 `teamId=null` 是系统全局行,当前 team UUID 是团队行。
104
+ - **upsert 是 last-write-wins**:同源(`human`)同 identity(team+subreddit+permalink+type+brand)重复提交会覆盖既有标注,
105
+ 服务端同事务落 before/after 审计。`source` 由服务端固定 `human` 并绑定当前用户。
106
+ - **score 方向**:1=最差/敌意 … 5=最佳/友好。
107
+ - **permalink** 必须是 reddit.com 的 `/r/<sub>/comments/` 帖链接(https,www/old/np 等子域均可)。
108
+ - **`--scope global`**(默认 `team`)写系统共享知识库,另需 manager/admin 的画像治理权限,危险级升 admin。
109
+
110
+ ## API
111
+
112
+ - `GET/POST /v1/system/subreddit-style-profiles`(list / propose)
113
+ - `GET /v1/system/subreddit-style-profiles/active`、`GET .../:id`
114
+ - `POST /v1/system/subreddit-style-profiles/:id/approve|reject|cancel|retire`(If-Match 必填)
115
+ - `GET/POST /v1/teams/:teamId/subreddit-post-annotations`(list / upsert 走 `.../upsert`)
116
+
117
+ 权限资源:`subredditStyleProfile`(画像读写 + 全局标注的第二道 gate)、`subredditPostAnnotation`(标注读写)。
118
+
119
+ ## 常见排障
120
+
121
+ - `PROFILE_IF_MATCH_REQUIRED` / `PROFILE_IF_MATCH_INVALID`(400):写操作没带 If-Match。CLI 会自动 GET 带上;显式 `--row-version` 时检查 token 是否完整(`ssp:<id>:<status>:<updatedAtISO>`)。
122
+ - `PROFILE_STALE`(409):画像已被他人变更。重新 `style-profiles get --id <id>` 核对最新 `rowVersion` 与内容后再重试。
123
+ - `SELF_APPROVE`(409):四眼约束,提案人本人不能 approve,换另一位 manager/admin。
124
+ - `ILLEGAL_TRANSITION`(409):状态机不允许(如 reject 一个已 approved 的画像;cancel/reject 只接受 proposed,retire 只接受 approved)。
125
+ - `403 subreddit style profile management requires an authenticated user`:用了 API Key。改 `social-hub auth login` 的 CLI token。
126
+ - 标注 upsert 403 但角色看似够:API 要求 create+update 双动作;`--scope global` 另需 `subredditStyleProfile:update`(manager/admin)。