feat(reddit): honest tiering — OpenCLI / rdt-cli, no zero-config path

- live-verified 2026-06: anonymous .json endpoints are 403-blocked (all
  variants) and the official API closed self-service registration in
  2025-11 — so the channel now says plainly: every Reddit backend needs
  a logged-in session, mainland China needs a proxy
- backends = [OpenCLI, rdt-cli]: OpenCLI rides the browser session
  (desktop preferred); rdt-cli stays for servers and existing installs
  (upstream unmaintained since 2026-03, noted in the ok message)
- install: desktop routes to OpenCLI, server installs rdt-cli from the
  pinned git source (split out as _install_rdt_cli)
- skill/references/social.md: Reddit section rewritten as two backend
  command groups + a PRAW note scoped to users who already hold
  pre-2025-11 credentials (explicitly not recommended for new users)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Pnant
2026-06-11 16:10:04 +08:00
parent 3e5f9df5b8
commit d7551bf19d
5 changed files with 156 additions and 38 deletions
+27 -4
View File
@@ -647,17 +647,36 @@ class TestXueqiuChannel:
class TestRedditChannel:
def test_reports_off_when_not_installed(self, monkeypatch):
"""多后端:OpenCLI > rdt-cli,没有零配置路径。"""
@staticmethod
def _isolate(monkeypatch, opencli=None):
"""隔离 OpenCLI 候选(None = 未安装),聚焦 rdt-cli 路径。"""
from agent_reach.channels.reddit import RedditChannel
monkeypatch.setattr(RedditChannel, "_check_opencli", lambda self: opencli)
def test_reports_off_when_nothing_installed(self, monkeypatch):
self._isolate(monkeypatch)
monkeypatch.setattr(shutil, "which", lambda _: None)
from agent_reach.channels.reddit import RedditChannel
status, msg = RedditChannel().check()
assert status == "off"
assert "rdt-cli" in msg
assert "public-clis/rdt-cli" in msg
# 诚实口径:明说没有零配置路径,推荐 OpenCLI + rdt git 源
assert "零配置" in msg
assert "opencli" in msg
assert "git+https://github.com/public-clis/rdt-cli.git" in msg
assert "rdt-cli>=0.4.2" not in msg
def test_opencli_ready_wins(self, monkeypatch):
self._isolate(monkeypatch, opencli=("ok", "OpenCLI 可用(复用浏览器登录态)"))
monkeypatch.setattr(shutil, "which", lambda _: None)
from agent_reach.channels.reddit import RedditChannel
ch = RedditChannel()
status, msg = ch.check()
assert status == "ok"
assert ch.active_backend == "OpenCLI"
def test_reports_ok_when_authenticated(self, monkeypatch):
self._isolate(monkeypatch)
monkeypatch.setattr(shutil, "which", lambda _: "/usr/local/bin/rdt")
fake_output = json.dumps({
"ok": True,
@@ -677,6 +696,7 @@ class TestRedditChannel:
assert ch.active_backend == "rdt-cli"
def test_reports_warn_when_not_authenticated(self, monkeypatch):
self._isolate(monkeypatch)
monkeypatch.setattr(shutil, "which", lambda _: "/usr/local/bin/rdt")
fake_output = json.dumps({
"ok": True,
@@ -701,6 +721,7 @@ class TestRedditChannel:
def test_reports_error_when_status_check_fails(self, monkeypatch):
"""rdt 非零退出且输出不可解析 → 工具异常(error),不再算 warn。"""
self._isolate(monkeypatch)
monkeypatch.setattr(shutil, "which", lambda _: "/usr/local/bin/rdt")
def fake_run(cmd, **kwargs):
@@ -716,6 +737,7 @@ class TestRedditChannel:
def test_reports_error_with_reinstall_hint_when_broken(self, monkeypatch):
"""which 命中但 exec 抛 FileNotFoundErrorvenv 断链)→ error + 重装处方。"""
self._isolate(monkeypatch)
monkeypatch.setattr(shutil, "which", lambda _: "/usr/local/bin/rdt")
def fake_run(cmd, **kwargs):
@@ -733,6 +755,7 @@ class TestRedditChannel:
def test_reports_error_with_reinstall_hint_on_exit_127(self, monkeypatch):
"""退出码 127(找到但跑不动)同样按断链处理。"""
self._isolate(monkeypatch)
monkeypatch.setattr(shutil, "which", lambda _: "/usr/local/bin/rdt")
def fake_run(cmd, **kwargs):
+18 -2
View File
@@ -60,7 +60,7 @@ class TestCLI:
assert auth_token == "token123"
assert ct0 == "ct0abc"
def test_install_reddit_deps_prefers_github_source(self, monkeypatch, capsys):
def test_install_rdt_cli_prefers_github_source(self, monkeypatch, capsys):
state = {"rdt_installed": False}
commands = []
@@ -79,12 +79,28 @@ class TestCLI:
monkeypatch.setattr(shutil, "which", fake_which)
monkeypatch.setattr(subprocess, "run", fake_run)
cli._install_reddit_deps()
cli._install_rdt_cli()
out = capsys.readouterr().out
assert commands == [["pipx", "install", cli._RDT_GIT_SOURCE]]
assert "✅ rdt-cli installed" in out
def test_install_reddit_deps_routes_by_environment(self, monkeypatch):
"""桌面 → OpenCLI;服务器 → rdt-cli(钉 git 源)。"""
calls = []
monkeypatch.setattr(cli, "_install_opencli_deps", lambda: calls.append("opencli"))
monkeypatch.setattr(cli, "_install_rdt_cli", lambda: calls.append("rdt"))
monkeypatch.setattr(shutil, "which", lambda _: None)
monkeypatch.setattr(cli, "_detect_environment", lambda: "local")
cli._install_reddit_deps()
assert calls == ["opencli"]
calls.clear()
monkeypatch.setattr(cli, "_detect_environment", lambda: "server")
cli._install_reddit_deps()
assert calls == ["rdt"]
class TestCheckUpdateRetry:
def test_retry_timeout_classification(self):