Merge pull request #46 from Panniantong/migrate-bird-to-xreach

feat: 迁移 Twitter 后端 bird → xreach CLI
This commit is contained in:
Pnant
2026-02-27 15:21:25 +08:00
committed by GitHub
11 changed files with 155 additions and 170 deletions
+9 -9
View File
@@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
"""Twitter/X — check if bird CLI is available."""
"""Twitter/X — check if xreach CLI is available."""
import shutil
import subprocess
@@ -9,7 +9,7 @@ from .base import Channel
class TwitterChannel(Channel):
name = "twitter"
description = "Twitter/X 推文"
backends = ["bird CLI"]
backends = ["xreach CLI"]
tier = 1
def can_handle(self, url: str) -> bool:
@@ -18,21 +18,21 @@ class TwitterChannel(Channel):
return "x.com" in d or "twitter.com" in d
def check(self, config=None):
bird = shutil.which("bird") or shutil.which("birdx")
if not bird:
xreach = shutil.which("xreach")
if not xreach:
return "warn", (
"bird CLI 未安装。搜索可通过 Exa 替代。安装:\n"
" npm install -g @steipete/bird"
"xreach CLI 未安装。搜索可通过 Exa 替代。安装:\n"
" npm install -g xreach-cli"
)
try:
r = subprocess.run(
[bird, "whoami"], capture_output=True, text=True, timeout=10
[xreach, "auth", "check"], capture_output=True, text=True, timeout=10
)
if r.returncode == 0:
return "ok", "完整可用(读取、搜索推文)"
return "warn", (
"bird CLI 已安装但未配置 Cookie。运行:\n"
"xreach CLI 已安装但未配置 Cookie。运行:\n"
" agent-reach configure twitter-cookies \"auth_token=xxx; ct0=yyy\""
)
except Exception:
return "warn", "bird CLI 已安装但连接失败"
return "warn", "xreach CLI 已安装但连接失败"
+17 -17
View File
@@ -387,24 +387,24 @@ def _install_system_deps():
except Exception:
print(" ⚠️ Node.js install failed. Try: apt install nodejs npm, or nvm install 22, or download from https://nodejs.org")
# ── bird CLI (for Twitter search) ──
if shutil.which("bird") or shutil.which("birdx"):
print("bird CLI already installed")
# ── xreach CLI (for Twitter search) ──
if shutil.which("xreach"):
print("xreach CLI already installed")
else:
if shutil.which("npm"):
try:
subprocess.run(
["npm", "install", "-g", "@steipete/bird"],
["npm", "install", "-g", "xreach-cli"],
capture_output=True, text=True, timeout=120,
)
if shutil.which("bird"):
print("bird CLI installed (Twitter search + timeline)")
if shutil.which("xreach"):
print("xreach CLI installed (Twitter search + timeline)")
else:
print("bird CLI install failed (optional — Twitter reading still works via Jina)")
print("xreach CLI install failed (optional — Twitter reading still works via Jina)")
except Exception:
print("bird CLI install failed (optional — Twitter reading still works via Jina)")
print("xreach CLI install failed (optional — Twitter reading still works via Jina)")
else:
print("bird CLI requires Node.js (optional — Twitter reading still works via Jina)")
print("xreach CLI requires Node.js (optional — Twitter reading still works via Jina)")
# ── undici (proxy support for Node.js fetch) ──
if shutil.which("npm"):
@@ -417,7 +417,7 @@ def _install_system_deps():
subprocess.run(["npm", "install", "-g", "undici"], capture_output=True, text=True, timeout=60)
print(" ✅ undici installed (Node.js proxy support)")
except Exception:
print(" ⬜ undici install failed (optional — bird may not work behind proxies)")
print(" ⬜ undici install failed (optional — xreach may not work behind proxies)")
def _install_system_deps_safe():
@@ -429,7 +429,7 @@ def _install_system_deps_safe():
deps = [
("gh", ["gh"], "GitHub CLI", "https://cli.github.com — or: apt install gh / brew install gh"),
("node", ["node", "npm"], "Node.js", "https://nodejs.org — or: apt install nodejs npm"),
("bird", ["bird", "birdx"], "bird CLI (Twitter)", "npm install -g @steipete/bird"),
("xreach", ["xreach"], "xreach CLI (Twitter)", "npm install -g xreach-cli"),
]
missing = []
@@ -459,7 +459,7 @@ def _install_system_deps_dryrun():
checks = [
("gh CLI", ["gh"], "apt install gh / brew install gh"),
("Node.js", ["node"], "curl NodeSource setup | bash + apt install nodejs"),
("bird CLI", ["bird", "birdx"], "npm install -g @steipete/bird"),
("xreach CLI", ["xreach"], "npm install -g xreach-cli"),
]
for label, binaries, method in checks:
@@ -690,16 +690,16 @@ def _cmd_configure(args):
print("Testing Twitter access...", end=" ")
try:
import subprocess
bird = shutil.which("bird") or shutil.which("birdx")
if not bird:
print("⚠️ bird CLI not installed. Run: npm install -g @steipete/bird")
xreach = shutil.which("xreach")
if not xreach:
print("⚠️ xreach CLI not installed. Run: npm install -g xreach-cli")
else:
import os
env = os.environ.copy()
env["AUTH_TOKEN"] = auth_token
env["CT0"] = ct0
result = subprocess.run(
[bird, "search", "test", "-n", "1"],
[xreach, "search", "test", "-n", "1"],
capture_output=True, text=True, timeout=15,
env=env,
)
@@ -823,7 +823,7 @@ def _cmd_uninstall(args):
print()
print("Optional: remove tools installed by Agent Reach:")
print(" npm uninstall -g mcporter")
print(" npm uninstall -g @steipete/bird")
print(" npm uninstall -g xreach-cli")
print(" npm uninstall -g undici")
+1 -1
View File
@@ -22,7 +22,7 @@ class Config:
FEATURE_REQUIREMENTS = {
"exa_search": ["exa_api_key"],
"reddit_proxy": ["reddit_proxy"],
"twitter_bird": ["twitter_auth_token", "twitter_ct0"],
"twitter_xreach": ["twitter_auth_token", "twitter_ct0"],
"groq_whisper": ["groq_api_key"],
"github_token": ["github_token"],
}
+1 -1
View File
@@ -3,7 +3,7 @@
AgentReach — installer, doctor, and configuration tool.
Agent Reach helps AI agents install and configure upstream platform tools
(bird CLI, yt-dlp, mcporter, gh CLI, etc.). After installation, agents
(xreach CLI, yt-dlp, mcporter, gh CLI, etc.). After installation, agents
call the upstream tools directly — no wrapper layer needed.
Usage:
+56 -46
View File
@@ -1,67 +1,77 @@
# Twitter 高级功能配置指南(bird CLI
# Twitter 高级功能配置指南(xreach CLI
## 功能说明
基础 Twitter 功能(搜索+读单条推文)无需配置,开箱即用。
Twitter 基础阅读通过 Jina Reader 免费可用,无需配置。
高级功能需要 bird CLI
- 查看用户时间线
- 深度搜索(更精确、更多结果)
- 读取完整线程(thread
- 查看关注列表推文
高级功能需要 xreach CLI
bird 是免费开源工具(npm 包 @steipete/bird),但需要你的 Twitter 账号 cookie。
- 搜索推文(`xreach search`
- 读取完整推文和对话链(`xreach tweet``xreach thread`
- 用户时间线(`xreach tweets`
## Agent 可自动完成的步骤
xreach 是免费开源工具(npm 包 xreach-cli),但需要你的 Twitter 账号 cookie。
## 快速配置
1. 检查 xreach 是否安装:
1. 检查 bird 是否安装:
```bash
which bird && echo "installed" || echo "not installed"
which xreach && echo "installed" || echo "not installed"
```
2. 安装 bird
2. 安装 xreach
```bash
npm install -g @steipete/bird
npm install -g xreach-cli
```
3. 测试(需要先配置 cookie
3. 测试是否配置好
```bash
AUTH_TOKEN="xxx" CT0="yyy" bird search "test" -n 1
AUTH_TOKEN="xxx" CT0="yyy" xreach search "test" -n 1
```
4. 用 agent-reach 配置 cookie推荐)
## 获取 CookieCookie-Editor 方式,推荐)
1. 安装 [Cookie-Editor](https://cookie-editor.com/) 浏览器扩展
2. 登录 x.com
3. 点击 Cookie-Editor 图标 → Export → 复制全部
4. 运行配置命令:
```bash
agent-reach configure twitter-cookies "auth_token=xxx; ct0=yyy"
agent-reach configure twitter-cookies "粘贴的 cookie JSON"
```
## 需要用户手动做的步骤
这会自动提取 `auth_token``ct0`,并写入环境变量。
请告诉用户:
## 手动设置 Cookie
> Twitter 高级功能需要你的 Twitter 账号 cookie(完全免费)。
>
> **最简单的方式:**
> 1. 安装 Chrome 插件 [Cookie-Editor](https://chromewebstore.google.com/detail/cookie-editor/hlkenndednhfkekhgcdicdfddnkalmdm)
> 2. 打开 https://x.com 并确保已登录
> 3. 点击 Cookie-Editor 插件图标 → Export → Header String
> 4. 把导出的内容发给我
>
> **手动方式:**
> 1. 用 Chrome 打开 https://x.com 并确保你已登录
> 2. 按 **F12** 打开开发者工具(Mac 按 Cmd+Option+I
> 3. 点击顶部的 **Application**(应用)标签
> 4. 左侧找到 **Cookies** → **https://x.com**
> 5. 在列表中找到以下两个值,双击复制:
> - **auth_token** — 一串字母数字
> - **ct0** — 一串字母数字
> 6. 把这两个值发给我
>
> ⚠️ 这些 cookie 让我能以你的身份读取推文(只读)。我不会发推、点赞或做任何操作。
> ⚠️ cookie 大约 1-3 个月会过期,届时需要重新导出。
如果你已经知道 `auth_token``ct0`
## Agent 收到 cookie 后的操作
1. 安装 xreach(如果没装):`npm install -g xreach-cli`
1. 安装 bird(如果没装):`npm install -g @steipete/bird`
2. 配置 cookie`agent-reach configure twitter-cookies "粘贴的内容"`
3. 测试:运行 `agent-reach doctor` 确认 Twitter 状态
4. 反馈:"✅ Twitter 高级功能已开启!现在可以搜索推文、查看时间线了。"
5. 如果失败:"❌ Cookie 无效或已过期,请重新导出。"
2. 设置环境变量:
```bash
export AUTH_TOKEN="你的auth_token"
export CT0="你的ct0"
```
3. 测试:
```bash
xreach search "test" --auth-token "$AUTH_TOKEN" --ct0 "$CT0" -n 1
```
## 代理配置
> xreach CLI 内置代理支持,通过 `--proxy` 参数传入:
```bash
xreach search "test" --auth-token "$AUTH_TOKEN" --ct0 "$CT0" --proxy "http://user:pass@host:port"
```
也支持代理轮换文件:
```bash
xreach search "test" --auth-token "$AUTH_TOKEN" --ct0 "$CT0" --proxy-file proxies.txt
```
+1 -1
View File
@@ -5,7 +5,7 @@ Agent Reach MCP Server — expose doctor/status as MCP tool.
Run: python -m agent_reach.integrations.mcp_server
Agent Reach is an installer + doctor tool. For actual reading/searching,
agents should call upstream tools directly (bird, yt-dlp, mcporter, etc.).
agents should call upstream tools directly (xreach, yt-dlp, mcporter, etc.).
"""
import asyncio
+6 -6
View File
@@ -23,7 +23,7 @@ agent-reach install --env=auto
agent-reach doctor
```
`install` auto-detects your environment and installs core dependencies (Node.js, mcporter, bird CLI, gh CLI, yt-dlp, feedparser). Run `doctor` to see what's active.
`install` auto-detects your environment and installs core dependencies (Node.js, mcporter, xreach CLI, gh CLI, yt-dlp, feedparser). Run `doctor` to see what's active.
## Management
@@ -78,17 +78,17 @@ When a user asks to configure/enable any channel:
After `agent-reach install`, call the upstream tools directly. No need for `agent-reach read` or `agent-reach search`.
### Twitter/X (bird CLI)
### Twitter/X (xreach CLI)
```bash
# Search tweets
bird search "query" --json -n 10
xreach search "query" --json -n 10
# Read a specific tweet
bird read https://x.com/user/status/123 --json
xreach tweet https://x.com/user/status/123 --json
# Read a user's timeline
bird timeline @username --json -n 20
xreach tweets @username --json -n 20
```
### YouTube (yt-dlp)
@@ -248,7 +248,7 @@ for e in d.entries[:5]:
### Twitter "fetch failed"
bird CLI uses Node.js native `fetch()`, which doesn't respect `HTTP_PROXY`. Solutions:
xreach CLI uses Node.js `undici`, which doesn't respect `HTTP_PROXY`. Solutions:
1. Ensure `undici` is installed: `npm install -g undici`
2. Configure proxy: `agent-reach configure proxy http://user:pass@ip:port`
3. If still failing, use transparent proxy (Clash TUN, Proxifier)