@geoly-ai/social-hub-cli 0.3.43 → 0.3.45
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 +23 -0
- package/dist/cli-error-channels.test.js +40 -0
- package/dist/cli-error-channels.test.js.map +1 -1
- package/dist/client.d.ts +7 -1
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +19 -2
- package/dist/client.js.map +1 -1
- package/dist/cmd-manifest.json +12 -2
- package/dist/cmd-manifest.test.js +13 -0
- package/dist/cmd-manifest.test.js.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +17 -3
- package/dist/index.js.map +1 -1
- package/dist/output.d.ts +12 -0
- package/dist/output.d.ts.map +1 -1
- package/dist/output.js +42 -0
- package/dist/output.js.map +1 -1
- package/dist/permissions-gates-restrictions.d.ts +10 -0
- package/dist/permissions-gates-restrictions.d.ts.map +1 -0
- package/dist/permissions-gates-restrictions.js +53 -0
- package/dist/permissions-gates-restrictions.js.map +1 -0
- package/dist/permissions-gates-restrictions.test.d.ts +2 -0
- package/dist/permissions-gates-restrictions.test.d.ts.map +1 -0
- package/dist/permissions-gates-restrictions.test.js +37 -0
- package/dist/permissions-gates-restrictions.test.js.map +1 -0
- package/dist/permissions.d.ts.map +1 -1
- package/dist/permissions.js +2 -0
- package/dist/permissions.js.map +1 -1
- package/dist/register-restrictions.d.ts +64 -0
- package/dist/register-restrictions.d.ts.map +1 -0
- package/dist/register-restrictions.js +431 -0
- package/dist/register-restrictions.js.map +1 -0
- package/dist/register-restrictions.test.d.ts +2 -0
- package/dist/register-restrictions.test.d.ts.map +1 -0
- package/dist/register-restrictions.test.js +315 -0
- package/dist/register-restrictions.test.js.map +1 -0
- package/package.json +3 -3
- package/skills/integrity.json +26 -25
- package/skills/manifest.json +2 -2
- package/skills/reddit-answers-research/SKILL.md +1 -1
- package/skills/reddit-matrix.lock.json +5 -5
- package/skills/reddit-phase-brief/references/phase4-brief-workflow.md +2 -2
- package/skills/reddit-phase-research/references/phase01-research.md +2 -2
- package/skills/reddit-strategy-shared/references/version-manifest.md +2 -2
- package/skills/reddit-voc-volume/SKILL.md +35 -28
- package/skills/reddit-voc-volume/matrix-contract.md +1 -1
- package/skills/reddit-voc-volume/references/arctic-shift.md +8 -7
- package/skills/reddit-voc-volume/references/browser-fallback.md +9 -4
- package/skills/reddit-voc-volume/requirements.txt +3 -1
- package/skills/reddit-voc-volume/scripts/reddit_voc_volume.py +3 -20
- package/skills/reddit-voc-volume/services/firecrawl/examples/o1_web_crawler/o1_web_crawler.py +152 -152
- package/skills/reddit-voc-volume/tests/test_links_fallback.py +87 -0
- package/skills/social-hub-admin/SKILL.md +33 -0
- package/skills/social-hub-calendar-directives/SKILL.md +14 -1
- package/skills/social-hub-calendar-jobs/SKILL.md +14 -0
- package/skills/social-hub-cli/SKILL.md +2 -0
- package/skills/social-hub-content-classification/SKILL.md +4 -0
- package/skills/social-hub-graph-compliance/SKILL.md +42 -0
- package/skills/social-hub-intelligence/SKILL.md +24 -1
- package/skills/social-hub-openclaw-context/SKILL.md +21 -16
- package/skills/social-hub-ops-runtime/SKILL.md +44 -0
- package/skills/social-hub-publishing/SKILL.md +12 -0
- package/skills/social-hub-scrape/SKILL.md +18 -16
|
@@ -129,22 +129,27 @@ social-hub query subreddit-candidates -t <team-id> --account A1 --action browse
|
|
|
129
129
|
|
|
130
130
|
**响应要点**(`subreddit-candidates`):
|
|
131
131
|
|
|
132
|
-
| 字段 | 说明
|
|
133
|
-
| ----------------------------------------- |
|
|
134
|
-
| `items[].source` | `system_pool`、`persona.*`、`brand.binding`;`fallback_team_pool` 仅表示是否用系统池补足
|
|
135
|
-
| `items[].sourceScope` | `system`(全局 catalog)或 `account`(人设/品牌展开)
|
|
136
|
-
| `items[].poolKind` | `pet` / `common` / `industry` / `brand` / `direct` / `other`
|
|
137
|
-
| `systemPools.expandedByKind` | 系统级 pet/common/industry/brand 汇总(选板前先看)
|
|
138
|
-
| `items[].subreddit` | 可直接消费的 `r/Subreddit` 格式
|
|
139
|
-
| `items[].selectionWeight` | 加权随机用;**禁止直接取 `items[0]`**
|
|
140
|
-
| `items[].cooldownUntil` | 未过期时禁止 `comment`/`reply`
|
|
141
|
-
| `items[].allowedActions` | 当前动作允许的操作
|
|
142
|
-
| `personaPools.expandedByKind` | 按来源汇总:`direct` / `common` / `industry` / `pet` / `brand` 的 `r/...` 列表
|
|
143
|
-
| `personaPools.expandedPools[].subreddits` | 每个 pool ref 展开后的具体板块(可多条)
|
|
144
|
-
| `personaPools.brandPools` | 账号品牌绑定及对应 `brand_pools.*` ref 展开结果
|
|
145
|
-
| `personaPools.unresolvedRefs` | alias 表无法解析的 ref;正常 seed 后 P01-P57 的 `starter/advanced/pet_pool` 不应出现
|
|
146
|
-
| `fallback.reason` | 如 `candidate_pool_exhausted` 须在 Agent 回执说明
|
|
147
|
-
| `exhaustion.reason` | **`items` 为空时是哪一类空** —— 用它判「要不要惊动人」,见下
|
|
132
|
+
| 字段 | 说明 |
|
|
133
|
+
| ----------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
134
|
+
| `items[].source` | `system_pool`、`persona.*`、`brand.binding`;`fallback_team_pool` 仅表示是否用系统池补足 |
|
|
135
|
+
| `items[].sourceScope` | `system`(全局 catalog)或 `account`(人设/品牌展开) |
|
|
136
|
+
| `items[].poolKind` | `pet` / `common` / `industry` / `brand` / `direct` / `other` |
|
|
137
|
+
| `systemPools.expandedByKind` | 系统级 pet/common/industry/brand 汇总(选板前先看) |
|
|
138
|
+
| `items[].subreddit` | 可直接消费的 `r/Subreddit` 格式 |
|
|
139
|
+
| `items[].selectionWeight` | 加权随机用;**禁止直接取 `items[0]`** |
|
|
140
|
+
| `items[].cooldownUntil` | 未过期时禁止 `comment`/`reply` |
|
|
141
|
+
| `items[].allowedActions` | 当前动作允许的操作 |
|
|
142
|
+
| `personaPools.expandedByKind` | 按来源汇总:`direct` / `common` / `industry` / `pet` / `brand` 的 `r/...` 列表 |
|
|
143
|
+
| `personaPools.expandedPools[].subreddits` | 每个 pool ref 展开后的具体板块(可多条) |
|
|
144
|
+
| `personaPools.brandPools` | 账号品牌绑定及对应 `brand_pools.*` ref 展开结果 |
|
|
145
|
+
| `personaPools.unresolvedRefs` | alias 表无法解析的 ref;正常 seed 后 P01-P57 的 `starter/advanced/pet_pool` 不应出现 |
|
|
146
|
+
| `fallback.reason` | 如 `candidate_pool_exhausted` 须在 Agent 回执说明 |
|
|
147
|
+
| `exhaustion.reason` | **`items` 为空时是哪一类空** —— 用它判「要不要惊动人」,见下 |
|
|
148
|
+
| `selectionLimit` / `returned` | 本次生效的 limit(含默认值)与实际返回条数(= `items.length`) |
|
|
149
|
+
| `truncated` | **有候选被截掉了**。分档配额 / limit 造成的:调大 `--limit` 或收窄 `--industry`/`--tier`;单 key 行数上限(500)造成的:上游固定帽,调 limit 补不全,只能收窄 industry 或找人处理。评论动作下配额阶段尚未过冷却/affinity,可能偏多报 |
|
|
150
|
+
|
|
151
|
+
`account-pools` 同样返回 `selectionLimit` / `returned` / `truncated`(口径一致,不带 `exhaustion`)。
|
|
152
|
+
⛔ `truncated: false` 只说明「没被截断」,**不**说明池子够用。
|
|
148
153
|
|
|
149
154
|
### `items: []` 到底是哪一类空(`exhaustion`)
|
|
150
155
|
|
|
@@ -70,6 +70,50 @@ social-hub ops skip -t <team-id> --job <jobId> --agent "$AGENT" --reason manual_
|
|
|
70
70
|
|
|
71
71
|
Hub 能保证:client 不能预置/篡改服务端字段、官方 worker executor 只收到冻结内容、complete 校验 hash/generation/pair、未 claim/错 holder/旧 generation 的 complete 被拒。**Hub 挡不住**:拿到 Reddit 会话的 agent 主动忽略 `executionContent`、自行输入别的正文,或用另一 token 重读草稿。真·强制依赖 agent(OpenClaw)遵守本契约——Hub 侧是「冻结 + 校验 + 审计漂移」,不是对平台写动作的物理拦截。
|
|
72
72
|
|
|
73
|
+
## 🔴 板块受限拦截(409 `JOB_BLOCKED` / `TARGET_BLOCKED`)
|
|
74
|
+
|
|
75
|
+
板块被系统级限制(整板 banned / private / quarantined / unavailable)或该账号在该板块有生效
|
|
76
|
+
sanction / bot_bouncer 名单时,Hub **在服务端拦住执行**,并把 job 置为终态 `blocked`
|
|
77
|
+
(`lastError` 形如 `target_blocked:<source>:<id>`)。你会看到的形状(HTTP **409**,AppError 信封):
|
|
78
|
+
|
|
79
|
+
```json
|
|
80
|
+
{
|
|
81
|
+
"error": {
|
|
82
|
+
"code": "CONFLICT",
|
|
83
|
+
"message": "…",
|
|
84
|
+
"details": {
|
|
85
|
+
"code": "JOB_BLOCKED",
|
|
86
|
+
"reason": "target_blocked",
|
|
87
|
+
"source": "restriction",
|
|
88
|
+
"id": "<uuid>",
|
|
89
|
+
"kind": "banned",
|
|
90
|
+
"subreddit": "adhdliving"
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
**识别方式:只看 `error.details.code`(`JOB_BLOCKED` / `TARGET_BLOCKED`)或 `details.reason === "target_blocked"`,
|
|
97
|
+
不要匹配 `message`**(措辞随时会改)。CLI 命中时 stderr 直接输出上面这段 JSON(含 `details`),退出码 1;
|
|
98
|
+
SDK 用 `getSubredditRestrictionBlock(err)`。
|
|
99
|
+
|
|
100
|
+
| 调用 | 受限时的行为 |
|
|
101
|
+
| ------------------------------------ | ------------------------------------------------------------------------------------------------- |
|
|
102
|
+
| `ops claim-next` | **永远不会**返回 blocked job;没有可领的就照旧 `no_claimable_job` |
|
|
103
|
+
| `ops heartbeat` | 409 `JOB_BLOCKED` —— 这一单已被拦 |
|
|
104
|
+
| `ops complete`(job 在排队时就被拦) | 409 `JOB_BLOCKED`(没有合法执行,没什么可回执的) |
|
|
105
|
+
| `ops complete`(领到后才被拦) | 只留一条 blocked 回执 + permalink 存档,**不会**把 job 改成 succeeded、不会标 published、不会重发 |
|
|
106
|
+
| `ops fail` / `ops skip` | 对已 blocked 的 job 是 **200 no-op**(不改状态) |
|
|
107
|
+
|
|
108
|
+
**agent 停止规则(必须遵守):**
|
|
109
|
+
|
|
110
|
+
1. 命中即**本轮跳过这个目标**:停止对该 job 的一切后续动作(不续租、不发帖、不评论)。
|
|
111
|
+
2. **不重试**:重试只会拿到同一个 409。解除路径看 `details.source`:`restriction` 只有 admin `restrictions revoke`;`sanction`(团队/账号级)由有权限的人把该 sanction 改为 lifted;`blocklist` 由 admin 维护(不是 agent 的事)。
|
|
112
|
+
3. **不要再 `fail` / `skip` 重报**(它们是 no-op,只会制造噪音),也不要把它当 Hub 故障告警。
|
|
113
|
+
4. 已被拦的 job 是永久终态:解封后也**不会**自动恢复,需要人重新排期(新建 job)。
|
|
114
|
+
5. 动手前可以先自查:`social-hub restrictions check -t <team-id> --subreddit <name> --account <accountId>`,
|
|
115
|
+
返回 `allowed:false` 就直接跳过(用法见 `social-hub-graph-compliance`)。
|
|
116
|
+
|
|
73
117
|
## `--reason` 枚举(仅允许下列值)
|
|
74
118
|
|
|
75
119
|
`ip_drift`, `env_start_timeout`, `login_expired`, `wrong_account_logged_in`, `reddit_connection_failed`, `rte_failed`, `subreddit_banned`, `bot_bouncer_blocked`, `rule_blocked`, `manual_intervention_required`, `unknown`
|
|
@@ -86,6 +86,18 @@ social-hub plans create -t <team-id> -j '{"brandId":"<uuid>","name":"Week 1","en
|
|
|
86
86
|
social-hub plans cancel -t <team-id> --plan <uuid> # 破坏性:先 list 确认 plan id
|
|
87
87
|
```
|
|
88
88
|
|
|
89
|
+
## 🔴 板块受限(409 `TARGET_BLOCKED`)
|
|
90
|
+
|
|
91
|
+
目标板块受系统级限制(整板 banned / private / quarantined / unavailable,待复核与逾期未复核的同样拦),
|
|
92
|
+
或该账号在该板块有生效 sanction / bot_bouncer 名单时:
|
|
93
|
+
|
|
94
|
+
- `drafts create` / `drafts update` **显式**把 subreddit 设为受限板块 → 409;改投别的板块、清空、读取都放行。
|
|
95
|
+
- `plans create`、建排期 / 改期 / job 创建 → 409。
|
|
96
|
+
- 形状:`error.code = "CONFLICT"`,`error.details = { code: "TARGET_BLOCKED", reason: "target_blocked", source, id, kind?, subreddit }`。
|
|
97
|
+
**按 `error.details.code` 识别,不要匹配 message;不要重试**——换板块或跳过。解除路径看 `details.source`:`restriction` 只有 admin `restrictions revoke`;`sanction`(团队/账号级)由有权限的人把该 sanction 改为 lifted;`blocklist` 由 admin 维护。
|
|
98
|
+
- 事前自查:`social-hub restrictions check -t <team-id> --subreddit <name> [--account <accountId>]`(见 `social-hub-graph-compliance`)。
|
|
99
|
+
- 执行侧(ops heartbeat / complete)的受限语义与停止规则见 `social-hub-ops-runtime`。
|
|
100
|
+
|
|
89
101
|
## 日历与任务
|
|
90
102
|
|
|
91
103
|
调度列表与 patch 见 **`social-hub-calendar-jobs`**(本 skill 不重复展开 jobs 全量命令)。
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: social-hub-scrape
|
|
3
3
|
description: >-
|
|
4
|
-
通用网页抓取:HTML/普通网页经自托管 Firecrawl 返回 markdown/html/rawHtml/links
|
|
5
|
-
Reddit
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
4
|
+
通用网页抓取:HTML/普通网页经自托管 Firecrawl 返回 markdown/html/rawHtml/links。
|
|
5
|
+
⛔ Reddit 不要用本端点:.json 直连已被 Reddit 全面拦截(2026-09-18 实测住宅代理同样 403),
|
|
6
|
+
本端点对 Reddit 的两条路径(.json 直连、Firecrawl 渲染)都取不到数据,要 Reddit 数据走
|
|
7
|
+
social-hub-intelligence 的采集链路。用户要抓某个非 Reddit 网页、取证、拉页面正文/链接,
|
|
8
|
+
或说 social-hub scrape 时使用;不用于绕过登录墙/验证码,也不做全站爬取。
|
|
9
9
|
metadata:
|
|
10
10
|
cliVersion: ">=0.0.12"
|
|
11
11
|
---
|
|
@@ -14,7 +14,11 @@ metadata:
|
|
|
14
14
|
|
|
15
15
|
> **前置条件:** 先读 [`../social-hub-shared/SKILL.md`](../social-hub-shared/SKILL.md),完成 `auth login`。
|
|
16
16
|
|
|
17
|
-
**按你给的 URL 抓**,不套系统内部的 Reddit
|
|
17
|
+
**按你给的 URL 抓**,不套系统内部的 Reddit 采集逻辑。适合临时取证、抓任意公开页面正文/链接。端点分流:**Reddit 主机 + `.json`(或 `--reddit-json`)→ API 内直连 curl_cffi**,**其余 HTML/普通网页 → Firecrawl**。
|
|
18
|
+
|
|
19
|
+
> 🔴 **Reddit 这条路现在是死的,别用本端点核实 Reddit 内容。** 2026-09-01 与 2026-09-18 两次实测:`.json` + 住宅代理 → `outcome: blocked`(403);Firecrawl `html`/`rawHtml` 渲染单帖页与板块列表页 → `outcome: captcha`;`old.reddit.com` 同样 captcha。API 侧只有这两条路,都被拦着。
|
|
20
|
+
> **要 Reddit 数据走 worker 侧采集**(`social-hub-intelligence`):那边另有 Reddit OAuth、`REDDIT_FIRECRAWL_FALLBACK_ENABLED` 渲染兜底与 `.json` 封禁熔断器,实测仍有产量。
|
|
21
|
+
> ⚠️ 「这次抓到了」不能推出「这个通道可用」——成败取决于出口 IP 当时的状态。
|
|
18
22
|
|
|
19
23
|
## 命令
|
|
20
24
|
|
|
@@ -25,13 +29,9 @@ social-hub scrape url "https://example.com/article"
|
|
|
25
29
|
# 指定输出格式(markdown|html|rawHtml|links,逗号分隔)
|
|
26
30
|
social-hub scrape url "https://example.com" -f markdown,links
|
|
27
31
|
|
|
28
|
-
# Reddit
|
|
29
|
-
social-hub scrape url "https://www.reddit.com/r/espresso/about.json" --reddit-json
|
|
30
|
-
social-hub scrape url "https://www.reddit.com/r/espresso
|
|
31
|
-
social-hub scrape url "https://www.reddit.com/search.json?q=plaud&sort=new"
|
|
32
|
-
|
|
33
|
-
# 抓 Reddit 页面正文(HTML,经 Firecrawl 渲染)
|
|
34
|
-
social-hub scrape url "https://www.reddit.com/r/espresso"
|
|
32
|
+
# ⛔ Reddit(.json 直连与 HTML 渲染都已被拦,实测取不到,保留仅为说明分流规则)
|
|
33
|
+
# social-hub scrape url "https://www.reddit.com/r/espresso/about.json" --reddit-json
|
|
34
|
+
# social-hub scrape url "https://www.reddit.com/r/espresso"
|
|
35
35
|
|
|
36
36
|
# 超时(毫秒,1000-60000)
|
|
37
37
|
social-hub scrape url "https://example.com" --timeout 20000
|
|
@@ -42,8 +42,9 @@ social-hub scrape status
|
|
|
42
42
|
|
|
43
43
|
## 边界与约束
|
|
44
44
|
|
|
45
|
-
- **HTML/普通网页需先部署 Firecrawl**(`docker/docker-compose.firecrawl.yml`)并给 API 配 `FIRECRAWL_BASE_URL`;未配时抓 HTML
|
|
46
|
-
-
|
|
45
|
+
- **HTML/普通网页需先部署 Firecrawl**(`docker/docker-compose.firecrawl.yml`)并给 API 配 `FIRECRAWL_BASE_URL`;未配时抓 HTML 报「未配置」。
|
|
46
|
+
- **Reddit:两条路径当前都不可用**(见上方红字)。`.json` 直连不依赖 Firecrawl、靠 API 内 curl_cffi + `REDDIT_HTTP_PROXY`,但住宅代理也已被 403;换代理后是否恢复要实测,不要假设。
|
|
47
|
+
- **分流规则**:Reddit 主机 + (`--reddit-json` 或 URL 以 `.json` 结尾)→ 直连 curl_cffi;其余 → Firecrawl。⚠️ 分流规则照旧,但 Reddit 这一侧当前取不到数据(见上方红字)。
|
|
47
48
|
- **权限 `scrape.create`**(运维/合规向;client 角色无权)。
|
|
48
49
|
- **SSRF 防护**:仅 http/https,拒绝私网/环回/云 metadata 地址(含 IPv6 私网段、DNS rebinding、重定向落地复检);可配 `SCRAPE_ALLOWED_HOSTS` 域名白名单收窄可抓范围。
|
|
49
50
|
- **并发受控**:API 侧非阻塞信号量(`SCRAPE_MAX_CONCURRENCY`,默认 4),满载返回 **429**,需重试。
|
|
@@ -52,4 +53,5 @@ social-hub scrape status
|
|
|
52
53
|
## 与其它 skill 的分工
|
|
53
54
|
|
|
54
55
|
- 要跑**系统内部**的 Reddit 情报/VOC 采集(watchlists、hot-posts、insights、fetch-by-\*,落库 + 聚合)→ `social-hub-intelligence`。
|
|
55
|
-
- 本 skill 是**通用/临时抓取**:给什么 URL 抓什么(
|
|
56
|
+
- 本 skill 是**通用/临时抓取**:给什么 URL 抓什么(HTML + 普通网页),输出原始内容而非系统结构化情报。
|
|
57
|
+
- **Reddit 取证不要用本 skill**:`reddit-voc-volume` 自 v2.12.28 起已不打 reddit.com `.json`,历史帖子/评论走 Arctic Shift 归档,渲染页证据走 Hub / Firecrawl。
|