The one-liner entry docs were untouched by the backend upgrade — new users
following "帮我安装 Agent Reach" would still get the old world. Now:
- docs/install.md: xiaohongshu section rewritten (desktop OpenCLI with the
one manual extension click / server xiaohongshu-mcp with QR + 150MB
first-run warning / legacy xhs-cli kept as fallback); Reddit section says
plainly there is no zero-config path; optional-channel menu gains OpenCLI;
upstream table matches the new routing with a doctor --json pointer
- docs/update.md: full rewrite — upgrade-only-what-exists tool refresh
(incl. npm update for OpenCLI/mcporter, pinned git source for rdt-cli),
one-time OpenCLI offer for desktops, skill sync now rides doctor's
auto-sync instead of an inline python blob, WeChat-era content removed
- check-update / watch: "update available" now leads with the one-liner
(帮我更新 Agent Reach:<update.md>) which updates package + tools + skill;
bare pip stays as the package-only alternative
- fix: version compare was `!=` — a local build AHEAD of the latest release
(installed from main during a release window) was told to "update" into a
downgrade; now semantic tuple compare with fallback (+4 tests)
- skill (zh+en): description gains a NOT-for boundary (fetch-only, no write
ops, defer to dedicated skills); new standing rule — after substantial
tasks run check-update and append a one-liner update hint to the wrap-up,
never interrupting or nagging
- SKILL_en.md restructured to the same three-layer skeleton as the Chinese
version (124-line body, shared references/) instead of a 263-line
everything-inline page
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- 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>
- backends becomes the ordered candidate list [OpenCLI, xiaohongshu-mcp,
xhs-cli]; probing order makes the desktop/server split automatic:
OpenCLI never probes alive headless, so servers fall through to
xiaohongshu-mcp; first fully-usable candidate wins, fixable (warn)
candidates only win when nothing is fully usable
- xiaohongshu-mcp probing: HTTP reachability of localhost:18060
(proxy-bypassed) + mcporter config presence; guides through
`mcporter config add` when half-wired
- opencli backend: treat a sleeping extension service worker as ready —
verified live that `daemon status` reports disconnected while any real
command wakes it; disambiguate "sleeping" vs "never installed" via the
Chrome Extensions directory on disk (fixes active_backend flapping
between OpenCLI and xhs-cli across doctor runs)
- install: desktop installs OpenCLI; server prints the xiaohongshu-mcp
guide (binary to ~/.agent-reach/tools/, QR login, mcporter add);
xhs-cli is no longer installed by default (upstream unmaintained since
2026-03) but existing installs keep working as the last candidate
- skill/references/social.md: xiaohongshu section rewritten as three
backend command groups keyed off `doctor --json` active_backend,
including the 120s-timeout and login-first caveats for the mcp path
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- new agent_reach/backends/opencli.py: probes install + daemon/extension
state via `opencli daemon status` (pure query — `opencli doctor`
auto-starts the daemon, a side effect health checks must avoid)
- `agent-reach install --channels opencli`: npm install + Chrome Web
Store guide (extension install cannot be automated — Chrome security
model — so we print the one-click path)
- server env skips OpenCLI (rides a real desktop Chrome session)
- channels will adopt it as a backend candidate in follow-up PRs
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- backends is now an ordered candidate list (first = preferred); channels
report the backend actually serving via active_backend, surfaced in the
doctor text report and --json
- new agent_reach/probe.py really executes upstream commands and tells
apart missing / broken (stale venv shebang after a system Python
upgrade) / timeout, with a reinstall prescription for broken installs
- all 13 channels migrated off which()-only checks: fixes bilibili
false-positive "bili-cli 可用" on broken shims, misleading xiaohongshu
"连接失败", rdt OSError crashing doctor, mcporter breakage masquerading
as "未配置"
- twitter: 15s probe + 1 retry (flaky 10s timeout), broken twitter-cli
now falls back to bird instead of aborting the check
- doctor survives per-channel exceptions; config supports per-channel
backend override (<channel>_backend / <CHANNEL>_BACKEND env)
- fix skill install/uninstall crash on symlinked skill dirs (the
"[Errno None] None" warning from shutil.rmtree on a symlink)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Routes the two credential-writing call sites (xfetch session sync, no-Docker XHS cookie fallback) through the same atomic os.open(..., 0o600) pattern Config.save() already uses, closing a TOCTOU window where credential files were briefly world-readable (CWE-732). Also hardens _sync_bird_env() with shlex.quote against a shell-injection breakout in the sourceable env file — verified exploitable on the pre-fix code. Maintainer follow-up: scoped the injection-probe test markers to tmp_path so they can't poison reruns. 107 tests pass.
The ok/warn/off symbols had no explanation for non-technical users;
--json gives agents and scripts a machine-readable health check.
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
All three had rotted past honest usability:
- Douyin's upstream (yzfly/douyin-mcp-server) is archived and required a
4-step manual local-server setup nobody could complete
- Weibo depended on an unmaintained personal fork (mcp-server-weibo)
- WeChat full-article reading was increasingly blocked by anti-bot
(#339) while doctor still advertised it as zero-config
Removes the channel files, installers, skill routing/trigger entries,
reference sections and README rows (zh+en). Honest counts: 13 platforms,
6 zero-config. They can return when maintained upstreams exist.
Follows the v1.4.0 precedent of removing Discord/Toutiao (#234).
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Extracted from #318 (the UTF-8/doctor core, minus the env-wrapper feature):
- new agent_reach/utils/process.py: utf8_subprocess_env() +
mcporter_utf8_env_args() — Windows GBK consoles otherwise corrupt
Chinese output from mcporter/MCP child processes
- weibo/douyin/linkedin checks and weibo install/registration now pass
the UTF-8 env (and register the MCP server with --env PYTHONUTF8=1)
- youtube: extract _has_js_runtime_config() with an OSError guard so an
unreadable yt-dlp config can't crash doctor
- test_skill_command: open SKILL.md with explicit utf-8 (Windows GBK
default broke these tests)
Co-authored-by: chidao <2980933590@qq.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Adds agent_reach/transcribe.py (download → compress → chunk → transcribe with provider fallback, fully mocked tests). Maintainer follow-up on the branch: wired an agent-reach transcribe CLI subcommand + skill docs so agents can actually invoke it, added the missing configure openai-key branch the error hint referenced, removed two dead static methods. 103 tests pass; wheel-gate clean.
PyPI still only has rdt-cli 0.4.1 while the doctor hint required >=0.4.2, so the suggested install command always failed. Installs from the upstream GitHub repo pinned to the 0.4.2 commit instead, and syncs all four docs that still taught the PyPI path. Verified locally: clean-venv install from the pinned source yields rdt 0.4.2 and rdt status works. 86 tests pass. Fixes#294.
- WebChannel.read(): reads any URL via Jina Reader (r.jina.ai), returns Markdown
- _install_skill(): add fallback from importlib.resources to Path(__file__) for editable installs
- Explicit UTF-8 encoding on all file read/write operations
Inspired by PR #215, implemented correctly (Jina instead of raw requests).
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Base install now only sets up lightweight zero-config channels (Web, YouTube,
GitHub, RSS, Exa, V2EX, Bilibili basic). Optional channels (Twitter, Weibo,
WeChat, Xiaoyuzhou, XiaoHongShu, Reddit, Bilibili full, Douyin, LinkedIn)
are installed on demand via --channels flag.
- Add --channels param to install subcommand
- Extract twitter/xhs/reddit/bili into independent install functions
- Remove heavy deps (weibo/xiaoyuzhou/wechat/twitter-cli/xhs-cli) from
default _install_system_deps() and _install_mcporter()
- Cookie import only triggers when cookie-needing channels are selected
- Doctor output: inactive optional channels summarized in one line
- install.md: two-step flow (basics → ask user which channels)
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Reddit: Exa crawling had chronic CRAWL_LIVECRAWL_TIMEOUT issues.
rdt-cli (304 stars, public-clis) works without login — search, read
full posts, and comments all verified. Massive improvement.
Bilibili: add bili-cli (590 stars) as optional enhanced backend for
hot/rank/search/feed. yt-dlp remains for video metadata + subtitles.
Also fix UA string (was "agent-reach/1.0", now proper browser UA).
75 tests passing.
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Reddit blocks nearly all non-browser access at IP level (including ISP proxies).
Switch Reddit channel to use Exa exclusively:
- Search: web_search_exa with includeDomains: ["reddit.com"]
- Read: crawling_exa for full post + comments
- check() now verifies Exa availability instead of probing Reddit API
- tier changed from 1 (needs config) to 0 (zero config)
- Removed reddit_proxy from config, CLI, and setup guide
- Updated all docs (README, README_en, install.md, SKILL.md, references)
- Fixed xreach→bird references in references/social.md
Fixes#218, Fixes#222, Fixes#221
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Add 'agent-reach skill --install/--uninstall' command for explicit skill management
- Make 'agent-reach doctor' auto-install skill if not present (fixes#154)
- Add format_xhs_result() to strip bloated XHS JSON to essential fields (fixes#134)
- Add 'agent-reach format xhs' CLI command (pipe mcporter output to clean it)
- Update SKILL.md with XHS formatter usage tip
- Add tests for both features (11 new tests, 73/73 total pass)
Co-authored-by: Panniantong <panniantong@users.noreply.github.com>
* feat: use rich text formatting for doctor UI
* fix: remove unrelated cli formatting changes
* fix: keep cli diff focused on doctor rich output
---------
Co-authored-by: Yuki9814 <Yuki9814@users.noreply.github.com>
- Replace xreach CLI with bird (@steipete/bird) as Twitter/X backend
- bird uses AUTH_TOKEN/CT0 env vars (simpler than xreach's session.json)
- Accept both 'bird' and 'birdx' binary names
- Remove version detection logic (bird v0.8.0 is the baseline)
- Write credentials.env to ~/.config/bird/ for easy sourcing
- Keep xfetch session.json sync for backward compatibility
- Update SKILL.md commands: bird search/read/user-tweets/thread
- Update install/uninstall to use npm @steipete/bird
- All 52 tests pass
- Change fallback cookie path from relative 'cookies.json' to absolute
'/app/cookies.json' so docker cp works correctly when COOKIES_PATH env
var is not set in older container images
- Also fix except branch to use the same absolute fallback
- Auto-restart container after writing cookies so the upstream MCP
reloads them from disk without requiring manual intervention
Fixes#175
Upstream bzd6661/wechat-article-for-ai has a bug where Tag.new_tag
is None in BS4 4.12+. Our fork fixes this.
Co-authored-by: Panniantong <panniantong@users.noreply.github.com>
Config class writes YAML (config.yaml), but xiaoyuzhou.py, cli.py, and
transcribe.sh were hardcoded to read config.json (JSON format). Users who
configured groq-key via 'agent-reach configure' would not have their key
detected because the wrong file was being read.
Fixes#128 (related to config loading)
Co-authored-by: Panniantong <panniantong@users.noreply.github.com>
Fixes#128
Two bugs:
1. doctor warn message said 'agent-reach configure groq-api-key' but the
actual CLI arg is 'groq-key' (see cli.py:75 choices list and :993 handler).
Same typo existed in cli.py _install_xiaoyuzhou_deps() output.
2. check() had a logic flaw: the inner 'if not has_key' was nested inside
'if not os.environ.get(...)', so when GROQ_API_KEY env var was absent but
config.json read succeeded, the outer condition never triggered the warning.
Refactored to a flat has_key variable — cleaner and correct.
Verified: 36/36 tests pass, manual unit tests confirm warn uses 'groq-key'
and ok is returned when groq_api_key is present in config.json.
Co-authored-by: 小白(Agent) <neo@agent-reach.dev>
Both _install_weibo_deps() and _install_xiaoyuzhou_deps() use
shutil.which() but didn't import shutil, causing NameError during
agent-reach install.
Co-authored-by: Panniantong <panniantong@users.noreply.github.com>
- Weibo now auto-installs during 'agent-reach install' (no login needed)
- Uses Panniantong/mcp-server-weibo fork with visitor passport auth fix
- Works from overseas servers without proxy or cookies
- Updated README (CN/EN), install.md, and channel check to point to fork
- 10 tools: trending, search content/users/topics, profile, feeds, comments
Co-authored-by: Panniantong <panniantong@users.noreply.github.com>
- YouTube: warn when only Node.js is installed but yt-dlp config file
is missing (previously returned "ok" incorrectly)
- Douyin: use `mcporter list` instead of calling with a hardcoded
invalid share URL that always fails
- cli: replace bare `except:` with `except Exception:` in
`_detect_environment` to avoid catching KeyboardInterrupt/SystemExit
- cli: fix unclosed file handle for cloud VM detection
- config: use `os.open()` with 0o600 mode to eliminate permission
race window when saving credentials
Adds a proper way for AI agents to import XiaoHongShu cookies into
the xiaohongshu-mcp Docker container. Previously agents had no clear
command to use, leading to confusion loops (issue #108).
Supports two input formats:
- Cookie-Editor JSON export (array of cookie objects)
- Header String format (key1=val1; key2=val2; ...)
The command:
1. Parses and validates the cookie input
2. Finds the running xiaohongshu-mcp container
3. Reads COOKIES_PATH from container env
4. Writes cookies via docker cp
5. Verifies login status via mcporter
Also updates install.md with the new command.
Closes#108
Co-authored-by: Panniantong <panniantong@users.noreply.github.com>
The isatty() check skipped UTF-8 wrapping when agent-reach was called
as a subprocess by AI agents (non-TTY). On Windows with GBK encoding,
any remaining non-ASCII chars would crash with UnicodeEncodeError.
Now UTF-8 wrapping applies in all environments on Windows.
Closes#95
Co-authored-by: Panniantong <panniantong@users.noreply.github.com>
- Remove all decorative emoji (👁️🔍📦🍪💡🔧📥🧩🛡️📡💻🤖⭐🙏🆕ℹ️) from cli.py and doctor.py
- Replace ⚠️ with [!] and ❌ with [X] (ASCII-safe status markers)
- Replace ⬜ with -- (ASCII-safe)
- Keep ✅ only for final success confirmations
- Fixes Windows GBK encoding crash during 'agent-reach install' (issue #95)
Closes#95
A friendly, non-intrusive message after successful installation
asking users to star the repo.
Co-authored-by: Panniantong <panniantong@users.noreply.github.com>
* feat: auto-install WeChat article tools during agent-reach install
WeChat (微信公众号) deps are now auto-installed during 'agent-reach install':
- Python packages: camoufox[geoip], markdownify, beautifulsoup4, httpx, miku_ai
- Tool repo: wechat-article-for-ai cloned to ~/.agent-reach/tools/
No login or configuration needed — works out of the box like YouTube/RSS.
Updated README tables to reflect zero-config status.
Also covers safe mode and dry-run.
* feat: auto-install WeChat + add channel-setup reference to SKILL.md
1. WeChat auto-install during 'agent-reach install':
- pip install camoufox[geoip], markdownify, bs4, httpx, miku_ai
- clone wechat-article-for-ai to ~/.agent-reach/tools/
- covers safe mode and dry-run
- README tables: WeChat → zero-config
2. SKILL.md improvements:
- Added 'configure' triggers to description
- Added references/channel-setup.md with install steps for all
login-required platforms (Twitter, XHS, Douyin, LinkedIn, Boss)
- Principle: user only provides cookies, agent does everything else
* simplify: point to install.md URL instead of bundled reference
No need to maintain a separate channel-setup.md. Just tell agents
to fetch install.md when they need setup instructions.
---------
Co-authored-by: Panniantong <panniantong@users.noreply.github.com>
Two subprocess.run(["npm", ...]) calls in undici installation were
using bare command name, which fails on Windows where npm is
installed as npm.cmd. Now resolves full path via shutil.which()
first, consistent with all other subprocess calls.
Co-authored-by: Panniantong <panniantong@users.noreply.github.com>
Problem: After installing Agent Reach, agents may clone repos, create
files, or write output into the workspace directory, gradually polluting
the user's project. Over time this degrades the agent experience.
Fix:
- SKILL.md: add Workspace Rules section — never create files in workspace
- install.md: add Directory Rules table, explicit boundary about workspace
- install.md: all git clone commands now target ~/.agent-reach/tools/
- update.md: add workspace warning
- cli.py: install creates ~/.agent-reach/tools/ directory
All agent-facing docs now enforce: /tmp for temp, ~/.agent-reach/ for
persistent data, workspace stays untouched.
Co-authored-by: Panniantong <panniantong@users.noreply.github.com>
- Replace text=True with encoding='utf-8', errors='replace' in all
subprocess.run calls (channels + cli.py) to fix GBK decode errors
on Chinese Windows systems
- Use shutil.which() resolved paths in channel subprocess calls to
handle Windows .cmd wrappers (npm global installs)
Co-authored-by: Panniantong <panniantong@users.noreply.github.com>
- Remove dead '# ── read ──' placeholder comment in cli.py
- Reword SKILL.md to make it explicit that agent-reach is an
installer/config tool, not a content fetcher
- Addresses confusion from issue #58
Co-authored-by: Panniantong <panniantong@users.noreply.github.com>
When running 'agent-reach configure twitter-cookies', credentials are now
automatically written to ~/.config/xfetch/session.json so that 'xreach auth
check' works without manual intervention.
Preserves existing session.json fields if the file already exists.
Falls back gracefully if the sync fails (still saves to agent-reach config).
Fixes#50
yt-dlp now requires an external JS runtime (deno or Node.js) for YouTube.
Since agent-reach already installs Node.js, we configure yt-dlp to use it:
1. cli.py: install writes '--js-runtimes node' to ~/.config/yt-dlp/config
2. youtube.py: doctor checks JS runtime availability and config
3. SKILL.md: updated YouTube section with accurate troubleshooting
Bilibili note: 412 errors are IP-based (needs proxy), not cookie-related.
Fixes#47