SKILL.md (per the skill-writing guide):
- description rewritten trigger-first: 调研/全网调研/帮我调研/research lead
the text (the owner's own phrasing "去全网调研" previously had NO matching
trigger word — the exact undertrigger the guide warns about); platform
keywords front-loaded against the 1536-char truncation
- standing rules added: probe `doctor --json` active_backend before acting
on multi-backend platforms, announce which skill/backend is in use,
follow the documented retry chains, compose multi-platform research
- quick commands updated to the new reality: bili-cli for bilibili search,
Reddit/xiaohongshu moved to a "login-backed platforms" section
- SKILL_en.md: same description surgery + the actively harmful stale
advice removed (anonymous reddit .json curl, yt-dlp for bilibili)
README / README_en:
- tagline gains the capability-layer subline: backends are chosen,
installed and health-checked for us to swap — the user never notices
- "设计理念" reframed from scaffolding to capability layer (selection /
install / doctor / routing); channels diagram now shows ordered backend
lists; selection table split into primary + fallback columns with the
live-test rationale per row
- platform table: honest rows for bilibili (bili-cli, yt-dlp retired),
Reddit (no zero-config path), xiaohongshu (OpenCLI / mcp / legacy)
Version 1.5.0 across pyproject / __init__ / CLAUDE.md / test fixture.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
bilibili:
- live-verified 2026-06: bilibili 412-blocks yt-dlp in every
configuration (latest version, direct, proxied, warmed cookies) while
bili-cli works fine without login — so yt-dlp no longer serves this
channel (it remains the YouTube backend)
- backends = [bili-cli, OpenCLI, B站搜索 API]: bili-cli covers
search/hot/rank/video-detail/audio, OpenCLI adds subtitles through the
browser session, the search API is the zero-dependency fallback
- when a broken candidate is bypassed by a working fallback, its
reinstall prescription is appended to the winning message instead of
being swallowed
- skill docs (social.md + video.md): "do NOT use yt-dlp for bilibili"
warning, bili-cli/OpenCLI command groups, curl fallback recipe,
B站 audio transcription path via `bili audio` + agent-reach transcribe
twitter:
- OpenCLI joins as the middle candidate [twitter-cli, OpenCLI, bird]
- social.md: explicit 4-step search retry chain (retry → upgrade →
OpenCLI → stable-command detour)
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.
Adds a punctuation-aware Whisper prompt and an optional --polish step (free Llama 3.3 70B on Groq) for Chinese podcast transcripts. Maintainer follow-up on the branch: replaced ASCII quotes that bash swallowed inside the prompt (hexdump-verified), added the same prompt to the 429-retry call, and documented --polish as optional. bash -n passes.
Rewrites the skill description with platform aliases (zh+en) and action triggers so agents reliably auto-invoke the skill. Maintainer follow-up on the branch: removed nonexistent skill_view tool reference, dropped finance category (no references/finance.md), updated the EN-locale test assertion to the new description. YAML validated, 85 tests pass. Fixes#316.
Four small correctness fixes found while live-testing community PRs:
- SKILL.md taught agents 'twitter search --limit 10' but twitter-cli
v0.8.5 has no --limit (real flag is -n/--max) — every agent following
the skill got a usage error
- transcribe_xiaoyuzhou.sh audio regex only matched lowercase .m4a/.mp3;
current episodes serve uppercase .MP3 (verified on a live episode) —
add /i flag
- reddit.py declared tier=0 (zero-config) while its own docstring says
Reddit requires login since 2024 — set tier=1 to match reality (tier
is doctor display metadata only)
- docs/README_en.md referenced the retired 'bird' CLI name once
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
CRITICAL FIX: update.md was telling agents to uninstall bird CLI,
which broke users who had working bird installations. Now:
- twitter.py: prefers twitter-cli, falls back to bird/birdx if installed
- update.md: removed "clean up deprecated tools" step entirely
- Added explicit rule: "Never uninstall any existing tools the user already has"
- Tests cover twitter-cli primary + bird fallback + preference order
78 tests passing.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Based on investigation of public-clis/twitter-cli 47 issues:
- search may 404 when Twitter changes GraphQL endpoints
- followers command has account ban risk on datacenter IPs
- Cookie auto-extraction fragile (macOS Keychain, Windows DPAPI)
- Recommend Cookie-Editor export + env vars over auto-extraction
- Ensure v0.8.5+ for Windows pipe fix
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Based on upstream issue investigation:
- Reddit (rdt-cli): ensure v0.4.2+, note login-required features
- B站: 412 is overseas-IP + no-cookie, add bili-cli commands
- YouTube: --write-comments is best-effort, auto-subs may duplicate
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Based on investigation of jackwener/xiaohongshu-cli issues:
- xsec_token: can't read by bare note_id, must search/feed first
- Rate limiting: high-freq requests trigger CAPTCHA
- v0.6.4: user/user-posts/favorites may return API error
- POST operations: may 406 due to signature issues in v0.6.x
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- 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>
Discord only returns server metadata (no messages without Bot Token),
not useful enough. Toutiao search was fragile (HTML scraping). Both
can be revisited when better upstream tools appear.
75 tests passing.
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
miku_ai (Sogou WeChat search) has been unmaintained for 20 months.
Exa can search AND read WeChat articles via mp.weixin.qq.com domain
filtering — verified: search returns articles, crawling returns full text.
Jina Reader fails on WeChat (CAPTCHA block).
- wechat.py: check() now detects Exa (primary) + Camoufox (optional)
- tier downgraded from 2 to 0 (Exa is zero-config)
- skill/references/web.md: updated WeChat commands to use Exa
- 104 tests passing
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
browser_cookie3 has been unmaintained for 15+ months and breaks with
newer browser versions. rookiepy (Rust-based, 345 stars, updated 2026-01)
is now the preferred cookie extraction backend.
- xueqiu.py: try rookiepy first, fallback to browser_cookie3
- cookie_extract.py: same priority order, compatible API wrapper
- Remove bird CLI credential sync (bird repo deleted)
- 104 tests passing
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Zero-config channel (tier=0). Uses Discord Invite API to read public
server info (no auth), and Exa via mcporter for content search.
Tested: discord.gg/python returns 419K members, description, channel.
104 tests passing.
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Zero-config channel (tier=0). Searches so.toutiao.com by scraping
embedded JSON from script tags. Fixes URL extraction order from PR #207
(article_url is the primary field, not display.info.url). Adds read()
via Jina Reader. 89 tests passing.
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
- Clarify that localhost:18060 root may return 404 (MCP is at /mcp)
- Recommend Cookie-Editor export over QR scan login
- Note that Docker container QR login is unreliable and cookies
don't auto-share to MCP service
Fixes#220
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>
The Xueqiu stock API requires a login session token (xq_a_token) that
is generated by Xueqiu's frontend JavaScript and cannot be obtained by
simply visiting the homepage. This caused persistent HTTP 400 (error
code 400016) for all users.
Changes:
- _ensure_cookies(): add three-level priority — config file (saved by
--from-browser) → live Chrome cookies via browser_cookie3 → homepage
fallback. The homepage-only approach only ever got acw_tc (anti-DDoS
token), never xq_a_token.
- _get_json(): switch User-Agent from "agent-reach/1.0" to a real Chrome
UA, and add Referer: https://xueqiu.com/ to all API requests.
- get_hot_posts(): replace the defunct /statuses/hot/listV3.json endpoint
(returns empty body) with the v4 public timeline endpoint; correctly
parse item.data as a JSON string to extract author, text, and likes.
- cookie_extract.py: add Xueqiu to PLATFORM_SPECS and configure_from_browser
so that `agent-reach configure --from-browser chrome` now also saves
Xueqiu cookies (only when xq_a_token is present).
- check(): improve error message to direct users to --from-browser instead
of suggesting a proxy.
- Fix urllib.parse.quote usage (was using urllib.request.quote).
- Update tier and backends description to reflect cookie requirement.
- Add 2 new tests: cookie loading from config, Referer/UA header verification.
- Update docs: README, install guide, troubleshooting, SKILL.md, CHANGELOG.
- 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: add Xueqiu (雪球) channel for stock quotes and community posts
Add a Tier 0 (zero-config) channel for Xueqiu, China's popular stock
market and investment community platform. Uses auto-generated session
cookies via http.cookiejar — no login required.
Supported methods:
- get_stock_quote(symbol) — real-time quotes (A/HK/US markets)
- search_stock(query) — search by name or code
- get_hot_posts(limit) — trending community posts
- get_hot_stocks(limit, stock_type) — popular stocks leaderboard
Inspired by https://github.com/jackwener/opencli xueqiu implementation.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: add Xueqiu to README platform tables, remove stale Instagram ref
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---------
Co-authored-by: fernando_jacob <f.jacob1996@gmail.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>