Reddit API requires a non-empty User-Agent header per its API rules.
Without it, the JSON endpoint returns 403 even when Reddit is reachable,
causing doctor to falsely report the channel as unavailable.
Changes:
- Add _reddit_reachable() helper that probes Reddit JSON API with UA
- doctor check() now distinguishes 'actually unreachable' from 'no proxy'
- Users on home IPs get 'ok' when Reddit is reachable; warn only on real failure
Fixes#168
- Replace brittle '"status": "ok"' string match with proper JSON parsing
in _mcporter_status_ok(). Handles Windows BOM, CRLF line endings, and
whitespace variations that caused false negatives on Windows + mcporter 0.7.3.
- Fallback to normalised string matching for backward compatibility.
- Extend config-get timeout to 15 s and list timeout to 30 s on Windows
(unchanged on Linux/macOS: 5 s / 10 s).
Fixes#159
* feat(channels): add V2EX support via public API
V2EX provides a public JSON API that requires no authentication.
This PR adds:
- agent_reach/channels/v2ex.py: V2EXChannel (tier=0, zero-config)
- can_handle() matches v2ex.com URLs
- check() verifies API reachability via urllib (no extra deps)
- Register V2EXChannel in channels/__init__.py
- SKILL.md: add V2EX section with curl examples for hot topics,
node browsing, topic detail, replies, and user info
- tests/test_channels.py: URL matching + mocked ok/warn check tests
V2EX API endpoints used:
GET /api/v2/topics/hot — hot topics
GET /api/topics/show.json — node topics / topic detail
GET /api/replies/show.json — topic replies
GET /api/members/show.json — user info
* feat(channels): expand V2EX channel with data-fetching methods
Add get_hot_topics, get_node_topics, get_topic, get_user, and search
methods to V2EXChannel using stdlib urllib only (no new dependencies).
Update unit tests and SKILL.md with Python call examples.
* feat(v2ex): add data fetching methods to V2EXChannel
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>
xreach-cli v0.3.2 added:
- extractTweetText() preferring note_tweet.text for long tweets
- X Article URL support (/article/ path)
Previously, doctor reported 'ok' even when the user had v0.3.0/v0.3.1
installed, silently failing to read longform tweets. Now check() reads
`xreach --version` and returns a warn with upgrade instructions if the
version is below 0.3.2.
Closes#126
Co-authored-by: neo_minion1 <minion@openclaw.ai>
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>
- 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
- wechat channel now supports both search and read
- Search: miku_ai (sogou weixin search) → article list with URLs
- Read: camoufox (stealth Firefox) → full Markdown content
- Doctor shows granular status (search only / read only / both)
- SKILL.md updated with search + read workflow examples
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>
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
- Detect ARM64 architecture and auto-add --platform linux/amd64 to
docker run hints in doctor/check output
- Add ARM64 FAQ section to setup guide with two options:
Rosetta emulation (--platform linux/amd64) or build from source
- Closes#44
- Twitter _read_jina now detects unusable X.com responses (JS-required pages)
and shows a friendly error instead of garbage HTML
- CLI read command now shows user-friendly messages for invalid URLs
and connection errors instead of raw HTTP exception traces