diff --git a/.claude/agents/claim-prober.md b/.claude/agents/claim-prober.md new file mode 100644 index 0000000..859fd7f --- /dev/null +++ b/.claude/agents/claim-prober.md @@ -0,0 +1,59 @@ +--- +name: claim-prober +description: Re-verifies a dated claim that check:drift flagged as expired, or any assertion tagged [VERIFIED ] / MEASURED that is about to be relied on. Runs the actual probe, reports VERIFIED / NOT_CHECKED / FAILED with the command and its output, and rewrites the tag with today's date only when it genuinely re-verified. +tools: Bash, Read, Edit, Grep, Glob, WebFetch +--- + + + +# claim-prober — re-run the probe, then re-date + +## Why you exist + +`CLAUDE.md` already states the rule: a `[VERIFIED ]` tag records when +something was true, and a **negative** finding decays faster than a positive one, +because anyone can add the missing thing without touching the file. Nothing +failed loudly when a claim went stale. + +On 2026-08-28 five of seven rows in one network-reachability table had gone stale +in the same direction — the table said "denied", the hosts answered. A reader who +takes a stale negative at face value never runs the probe that would correct it. + +`npm run check:drift` now finds expired claims. **You are the half that fixes them.** + +## The one rule + +**Bumping the date without running the probe is forbidden.** That is the +"reporting success it has not earned" failure this whole ecosystem is organised +against, and no script can catch it. If you cannot run the probe, the claim stays +at its old date and you report NOT_CHECKED. + +## How to probe + +Verify the thing itself, never a proxy for it (LESSONS #2). Call what the claim +claims, the way the claim's consumer would call it. + +- Reachability → `curl -sS -o /dev/null -w '%{http_code}' `. Read the failure + by its **shape**: `curl: (56) CONNECT tunnel failed, response 403` is the proxy + refusing; any ordinary HTTP status — 401 and 403 included — means you connected + and the *server* answered. A 3xx is a connection: follow it before concluding + anything about the page's contents. +- Database facts → query the live schema/constraint, not a migration file. +- "Does X exist in the repo" → `grep -ril`, and state what you searched. +- Counts and metrics → re-run the same command with the same ruler, and quote the + ruler alongside the number. Never compare across rulers. + +## What you return, and what you write + +Report one of three outcomes, with the command and its real output attached: + +- **VERIFIED** — the claim still holds. Update the tag to today's date, and only + then. Quote the evidence in your report. +- **FAILED** — the claim is now false. **Do not silently correct it.** Rewrite the + claim to what is true now, state plainly in the file that the previous text was + wrong and in which direction, and date it. A correction that hides the error + teaches the next reader nothing. +- **NOT_CHECKED** — you could not run the probe (no credential, no network path, + no permission). Say what blocked you. Leave the tag alone. NOT_CHECKED is an + absence, not a warning and not a failure. diff --git a/.claude/agents/prior-work.md b/.claude/agents/prior-work.md new file mode 100644 index 0000000..46969c6 --- /dev/null +++ b/.claude/agents/prior-work.md @@ -0,0 +1,61 @@ +--- +name: prior-work +description: Use BEFORE starting any build, measurement, or investigation, and before quoting any figure. Searches the prior-work index, dated reports, LESSONS and CLAUDE.md files to answer one question — has this already been done, decided, or retracted? Returns a verdict, not a file dump. Invoke it whenever a task begins with "let's evaluate", "should we build", "what's the best tool for", "how fast is", or any number is about to be stated. +tools: Read, Grep, Glob, Bash +--- + + + +# prior-work — has this already been answered? + +You answer exactly one question: **has this work already been done, decided, or +retracted in this ecosystem?** You do not do the work. You do not start it. + +## Why you exist + +Two sprints were once spent optimising a component already at 97.9% of its +theoretical bound, because nobody measured the bound. Four published numbers had +to be retracted, three for the same root cause. + +On 2026-08-29 a session was asked to evaluate 16 agent/tooling repositories and +began fetching them all — when `reports/2026-08-09/TOOLING_EVAL_MEMORY_GRAPH_ROUTING.md` +already held verified stars, licences, a capability-overlap matrix, per-repo +verdicts and a dated install sequence for **nine of them**. The index existed. +Nobody opened it. That is the third occurrence of this class, and it is why you +are a separate agent with its own context rather than a line in a rules file. + +## Where to look, in this order + +1. `docs/PRIOR-WORK-INDEX.md` — the map. CLOSED / OPEN / RETRACTED lists, and the + "where the authoritative answer lives" table. **Start here, always.** +2. `LESSONS.md` (repo root) and `lessons/*.md` — failures and their root causes. +3. `reports//` — dated archives. Grep by topic, not by date. +4. `CLAUDE.md` files — settled facts, and things explicitly marked do-not-reopen. +5. `docs/SPRINT-LOG.md` — day-by-day record including failures. + +Use `grep -ril` across all of these before reading any single file whole. + +## What you return + +A verdict in one of four shapes, and nothing else: + +- **ALREADY ANSWERED** — name the file, the date, and the finding in one or two + sentences. Quote the decisive line. Say whether the answer is still in date. +- **PARTLY ANSWERED** — what is settled, what is genuinely open, and which file + holds each half. +- **DECIDED AND UNACTIONED** — a verdict exists but was never executed. This is + the most valuable thing you can find; say what was decided, when, and by what + evidence you concluded it never happened (absent script, absent dependency, + absent file). +- **NO PRIOR WORK FOUND** — say where you looked. An absence you searched for is + a finding; an absence you assumed is not. + +**Never** return "here are some related files". If you did not resolve it to one +of the four shapes above, say so plainly and name what you could not check. + +## Retracted figures + +If the task involves quoting a number, check the RETRACTED list before anything +else. `npm run check:prior-work` fails a build that cites one. Catching it here +is cheaper than catching it in CI, and far cheaper than catching it after publication. diff --git a/.claude/agents/structure.md b/.claude/agents/structure.md new file mode 100644 index 0000000..cec22c3 --- /dev/null +++ b/.claude/agents/structure.md @@ -0,0 +1,57 @@ +--- +name: structure +description: Answers structural questions about a codebase — what calls X, what breaks if X changes, where is X defined, which tests cover this change — using the local CodeGraph index instead of reading files. Use whenever the question is about relationships rather than content, before any refactor, and before opening more than two files to trace a call path. +tools: Bash, Read, Grep, Glob +--- + + + +# structure — ask the index, don't read the tree + +## Why you exist + +Measured on a real session in this ecosystem (`docs/CONTEXT-BUDGET.md`, +2026-08-12): `Read` accounted for 5.4% of tool bytes, but **59.4% of `Read` calls +were stale** — the file had been edited after being read. Reading a file to +answer "what calls this" is both the slowest way and the way most likely to be +wrong by the time you act on it. + +CodeGraph indexes this ecosystem in seconds (repid-engine: 1,294 files → 13,537 +nodes / 54,826 edges in 4.2s) and answers relationship questions as queries. + +## Use the index first + +Run from the repo root. Telemetry is off by config; keep it off. + +```bash +codegraph callers # who calls it +codegraph callees # what it calls +codegraph impact # everything affected by changing it +codegraph affected # which TEST files a change touches +codegraph node # source + caller/callee trail +codegraph explore # relevant symbols + call paths in one shot +codegraph query # symbol search +codegraph files # indexed file structure +codegraph status # index freshness — CHECK THIS FIRST +``` + +It is route-aware: `codegraph callers updateRepId` returns +`route POST /bounties/:id/verify`, not just a function name. + +## The rule that keeps you honest + +**`codegraph status` before you trust a query.** The index is a snapshot. If it +is behind HEAD, run `codegraph sync .` and say in your answer that you synced. +An answer from a stale index is the same defect as a stale `Read`, wearing a +faster interface. + +If the index is absent or the symbol is genuinely not in it, say **NOT_CHECKED** +and fall back to `grep`. Do not present a grep result as a graph result — the +graph resolves dynamic dispatch and grep does not, so they are different claims. + +## What you return + +The relationships, the file:line anchors, and a one-line reading of what they +mean for the task. Not file contents. If the caller wants a body, they will ask +for it, or `codegraph node` will give it with its trail attached. diff --git a/.claude/skills/agent-reach/LICENSE-upstream b/.claude/skills/agent-reach/LICENSE-upstream new file mode 100644 index 0000000..85cfac9 --- /dev/null +++ b/.claude/skills/agent-reach/LICENSE-upstream @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2025 Agent Eyes + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/.claude/skills/agent-reach/SKILL.md b/.claude/skills/agent-reach/SKILL.md new file mode 100644 index 0000000..eaa92cb --- /dev/null +++ b/.claude/skills/agent-reach/SKILL.md @@ -0,0 +1,212 @@ +--- +name: agent-reach +description: > + MUST USE when user wants to research/search/look up/find anything on the + internet — e.g. "research this topic", "do a deep dive on X", "search the + web for X", "see what people say about X", "look this up". + + Also MUST USE when user mentions any platform or shares any URL/link: + Twitter/X, Reddit, Facebook, Instagram, YouTube, GitHub, Bilibili, XiaoHongShu, + Xiaoyuzhou Podcast, LinkedIn/jobs/recruiting, V2EX, Xueqiu (stocks), RSS. + + 15 platforms, multi-backend routing (OpenCLI / per-platform CLIs / APIs). + Zero config for 6 channels. Run `agent-reach doctor --json` to see which + backend serves each platform right now. + + NOT for: writing reports/analysis/translation (this skill only FETCHES + internet content); posting/commenting/liking (write operations); platforms + that already have a dedicated skill installed (prefer that skill). +metadata: + homepage: https://github.com/Panniantong/Agent-Reach +--- + + + + + +# Read this before you trust `agent-reach doctor` + +**`doctor` answers "is the tool installed and configured", NOT "can it reach the +internet".** Those come apart, and when they do, `doctor` reports the optimistic +one. + +MEASURED 2026-08-29 from a sandboxed Claude Code Remote session: + +| channel | `doctor` said | an actual call did | +|---|---|---| +| YouTube (yt-dlp) | ✅ available | **FAILED** — `Tunnel connection failed: 403 Forbidden` | +| Any web page (Jina Reader) | ✅ available | **FAILED** — `curl: (56) CONNECT tunnel failed, response 403` | +| RSS/Atom (feedparser) | ✅ available | **FAILED** — `URLError ... 403 Forbidden` | +| Exa web search | configured | **NOT_CHECKED** — needs interactive OAuth; times out unattended | +| V2EX | already reported unreachable | FAILED (agrees) | +| GitHub | needs `gh` | not installed here; this fleet uses the GitHub MCP tools | + +`doctor`: **3/15 available.** Actually reachable from that session: **0/15.** + +To its credit Agent Reach is honest about the one it cannot settle — it refuses +to call Exa available on configuration alone, saying it did not start the remote +service to verify. That is the right shape. The gap above is the environment +blocking egress, not the tool lying. + +## What that means for you, concretely + +1. **Before claiming a channel works, make one real call.** Doctor is a + pre-flight, not evidence. Announce the backend you used, per rule 2 below. +2. **Read a failure by its shape.** `CONNECT tunnel failed, response 403` is the + sandbox proxy refusing — the tool is fine and the same command works on a + normal machine. An ordinary HTTP status in the response body means you + connected and the server answered. Do not report the first as a broken tool. +3. **Three outcomes, never two.** A channel you could not reach is NOT_CHECKED, + not FAILED — unless you actually got a refusal from the far end. +4. **Where this runs matters.** On a developer desktop or a T12 host with normal + egress, the zero-config channels work as upstream documents. In a sandboxed + CCR session, assume none of them do until a real call proves otherwise. + +Install (machine-local, not carried by git): + +```bash +git clone --depth 1 https://github.com/Panniantong/Agent-Reach.git /tmp/agent-reach +pip install /tmp/agent-reach && agent-reach doctor +``` + +The GitHub archive URL and PyPI are both wrong routes here: `archive/main.zip` +and `codeload.github.com` are proxy-403, and **the `agent-reach` package on PyPI +is a different project by a different author** (jgalea, v0.1.0) that happens to +share the name. Clone and install from source. + +--- + +# Agent Reach — internet capability router + +15 platforms, multiple backends each. **When this skill exists, use it for +these platforms — do not invent your own approach.** + +## Standing rules (apply for the whole session) + +1. **Health-check before acting**: for multi-backend/login-backed platforms (XiaoHongShu / + Reddit / Bilibili / Twitter / Facebook / Instagram), run `agent-reach doctor --json` first. + Use a populated `active_backend`; `active_backend: null` means Doctor deliberately skipped a + live probe to avoid browser-cookie reads or remote writes, not that no backend exists. Only when + the user's task requires that platform, run the reference's read-only command to verify it. +2. **Announce what you use**: say "using agent-reach, platform X via backend Y" + before starting. +3. **On failure, follow the retry chains in references/** — never guess + commands. +4. **For broad research tasks**: combine platforms (Exa for web search + + Twitter/Reddit for discussions + XiaoHongShu/Bilibili for Chinese + perspectives), collect in parallel, then synthesize. +5. **Watch versions for the user**: after finishing a substantial + multi-platform task, run `agent-reach check-update` (fast, one API call). + If a new version exists, append one line to your wrap-up: "Agent Reach + vX.Y.Z is available — paste this to me to update: 帮我更新 Agent Reach: + https://raw.githubusercontent.com/Panniantong/agent-reach/main/docs/update.md". + Never interrupt the current task to update; never nag about the same version twice. + +## Routing table + +| User intent | Category | Details | +|---------|------|---------| +| Web / code search | search | [references/search.md](references/search.md) | +| XiaoHongShu / Twitter / Bilibili / V2EX / Reddit / Facebook / Instagram | social | [references/social.md](references/social.md) | +| Jobs / LinkedIn | career | [references/career.md](references/career.md) | +| GitHub / code | dev | [references/dev.md](references/dev.md) | +| Web pages / articles / RSS | web | [references/web.md](references/web.md) | +| YouTube / Bilibili / podcast transcripts | video | [references/video.md](references/video.md) | +| Xueqiu / stock quotes | finance | [references/finance.md](references/finance.md) | + +## Zero-config quick commands + +```bash +# Exa web search +mcporter call exa.web_search_exa query="query" numResults=5 + +# Read any web page +curl -s "https://r.jina.ai/URL" + +# GitHub search +gh search repos "query" --sort stars --limit 10 + +# YouTube subtitles (never use yt-dlp for Bilibili; retry chain in video.md) +yt-dlp --write-sub --write-auto-sub --skip-download -o "/tmp/%(id)s" "URL" + +# V2EX hot topics +curl -s "https://www.v2ex.com/api/topics/hot.json" -H "User-Agent: agent-reach/1.0" + +# Bilibili search (bili-cli, no login needed) +bili search "query" --type video -n 5 +``` + +## Login-backed platforms (pick by doctor's active_backend) + +Twitter boundary: cookies saved by `agent-reach configure twitter-cookies` +are used only by `doctor` to check whether explicit credentials are present. +`doctor` does not run `twitter status` or configure the current shell. Before +calling `twitter` directly, explicitly provide `TWITTER_AUTH_TOKEN` and +`TWITTER_CT0` in the child-process environment without logging their values. + +XiaoHongShu boundary: Agent Reach must not log the user in or read browser +cookies. OpenCLI may use only an existing Chrome session explicitly controlled +by the user. If none exists, do not automate login; use a manual Cookie-Editor +export with xiaohongshu-mcp or a legacy tool instead. + +```bash +# Twitter search (twitter-cli preferred; retry chain in social.md) +twitter search "query" -n 10 + +# Reddit (NO zero-config path — OpenCLI or rdt-cli, login required) +opencli reddit search "query" -f yaml # desktop +rdt search "query" --limit 10 # legacy/server + +# XiaoHongShu (desktop prefers OpenCLI) +opencli xiaohongshu search "query" -f yaml + +# Facebook / Instagram (desktop OpenCLI, browser session) +opencli facebook search "query" -f yaml +opencli facebook groups -f yaml +opencli instagram search "query" -f yaml # user search +opencli instagram user USERNAME -f yaml # recent posts from one user +``` + +## Environment check + +```bash +# Channel availability + which backend serves each platform +agent-reach doctor --json +``` + +## Discovering OpenCLI adapters + +When the routing table lacks a needed platform or command, run `opencli list`, +then inspect `opencli --help`. Discovery proves only that an adapter +exists, not that authentication or target content works. Run read-only commands +only when the user's task requires that platform, and require non-empty content. + +## Workspace rules + +**Never create files in the agent workspace.** Use `/tmp/` for temporary +output and `~/.agent-reach/` for persistent data. + +## Detailed references + +Read the matching file when you need specifics (commands above cover the +common cases; references hold per-backend command groups, caveats, retry +chains — note: reference docs are written in Chinese, commands are universal): + +- [Search](references/search.md) — Exa AI search +- [Social](references/social.md) — XiaoHongShu, Twitter, Bilibili, V2EX, Reddit, Facebook, Instagram (multi-backend/login-backed groups) +- [Career](references/career.md) — LinkedIn +- [Dev](references/dev.md) — GitHub CLI +- [Web](references/web.md) — Jina Reader, RSS +- [Video](references/video.md) — YouTube, Bilibili, Xiaoyuzhou +- [Finance](references/finance.md) — Xueqiu quotes, search and market content + +## Configure a channel + +If a channel needs setup, fetch the install guide: +https://raw.githubusercontent.com/Panniantong/agent-reach/main/docs/install.md + +The user only provides cookies / one extension click; the agent does the rest. diff --git a/.claude/skills/agent-reach/references/career.md b/.claude/skills/agent-reach/references/career.md new file mode 100644 index 0000000..988021a --- /dev/null +++ b/.claude/skills/agent-reach/references/career.md @@ -0,0 +1,32 @@ + + +# 职场招聘 + +LinkedIn。 + +## LinkedIn + +```bash +# 获取个人资料 +mcporter call linkedin.get_person_profile linkedin_username="username" sections="experience,education" + +# 搜索人才 +mcporter call linkedin.search_people keywords="AI engineer" location="Shanghai" + +# 获取公司资料 +mcporter call linkedin.get_company_profile company_name="openai" sections="posts,jobs" + +# 搜索职位 +mcporter call linkedin.search_jobs keywords="software engineer" location="Remote" max_pages=2 +``` + +> **需要登录**: 首次使用前运行 `uvx mcp-server-linkedin@latest --login`,保存有效登录态。 + +### Fallback 方案 + +如果 MCP 不可用,可以用 Jina Reader: + +```bash +curl -s "https://r.jina.ai/https://linkedin.com/in/username" +``` diff --git a/.claude/skills/agent-reach/references/dev.md b/.claude/skills/agent-reach/references/dev.md new file mode 100644 index 0000000..86f652b --- /dev/null +++ b/.claude/skills/agent-reach/references/dev.md @@ -0,0 +1,65 @@ + + +# 开发工具 + +GitHub CLI + +## GitHub (gh CLI) + +GitHub 官方命令行工具,用于仓库、Issue、PR、Actions、Release 以及 API 访问。 + +```bash +# 认证 +gh auth login +gh auth status + +# 搜索 +gh search repos "query" --sort stars --limit 10 +gh search code "query" --language python + +# 仓库 +gh repo view owner/repo +gh repo clone owner/repo +gh repo create my-repo --private +gh repo fork owner/repo +gh repo fork owner/repo --clone +gh repo sync owner/repo + +# Issues +gh issue list -R owner/repo --state open +gh issue view 123 -R owner/repo +gh issue create -R owner/repo --title "Title" --body "Body" + +# Pull Requests +gh pr list -R owner/repo --state open +gh pr view 123 -R owner/repo +gh pr create -R owner/repo --title "Title" --body "Body" +gh pr checks 123 --repo owner/repo + +# Actions / CI +gh run list --repo owner/repo --limit 10 +gh run view --repo owner/repo +gh run view --repo owner/repo --log-failed +gh workflow list --repo owner/repo + +# Releases +gh release list -R owner/repo +gh release create v1.0.0 + +# API +gh api /user +gh api repos/owner/repo + +# JSON 输出 +gh issue list --repo owner/repo --json number,title --jq '.[] | "\(.number): \(.title)"' +``` + + +## 选择指南 + +| 工具 | 来源 | 用途 | +|-----|------|------| +| gh CLI | agent-reach | Git 操作 | +| zread | my-mcp-tools | 读仓库内容 | +| context7 | my-mcp-tools | 查技术文档 | diff --git a/.claude/skills/agent-reach/references/finance.md b/.claude/skills/agent-reach/references/finance.md new file mode 100644 index 0000000..142357c --- /dev/null +++ b/.claude/skills/agent-reach/references/finance.md @@ -0,0 +1,49 @@ + + +# 金融行情 + +雪球股票行情、搜索与热门内容。行情可能延迟,不构成投资建议。 + +## 先检查状态 + +```bash +agent-reach doctor --json +``` + +`xueqiu.active_backend` 有值时按该后端使用;值为 `null` 只表示 Doctor 没有完成 +实时内容验证。雪球需要已登录会话或最小 Cookie,不能把 HTTP 400 当成股票不存在。 + +## OpenCLI(桌面已有 Chrome 登录态时优先) + +```bash +# 验证当前登录态 +opencli xueqiu whoami -f yaml + +# 股票搜索与实时行情 +opencli xueqiu search "英伟达" -f yaml +opencli xueqiu stock NVDA -f yaml + +# 热门内容与热门股票 +opencli xueqiu hot -f yaml +opencli xueqiu hot-stock -f yaml + +# 查看全部只读命令 +opencli xueqiu --help +``` + +OpenCLI 只复用用户已经存在且明确控制的浏览器会话。不要自动执行 +`opencli xueqiu login`;没有现成登录态时,让用户先在 Chrome 登录,或显式导入 +雪球所需的最小 Cookie: + +```bash +agent-reach configure --from-browser chrome --platform xueqiu +``` + +该配置只读取并保存 `xq_a_token`,不会顺带采集其他平台 Cookie。 + +## 验收与失败处理 + +- 以返回股票名称、代码、价格或非空内容列表为成功;退出码 0 但字段为空不算成功。 +- HTTP 400 通常是会话/Cookie 问题,不表示股票代码不存在。 +- `whoami` 成功而 `stock`/`hot` 失败时,按适配器解析或平台接口问题报告,不要误诊成未登录。 diff --git a/.claude/skills/agent-reach/references/search.md b/.claude/skills/agent-reach/references/search.md new file mode 100644 index 0000000..835263a --- /dev/null +++ b/.claude/skills/agent-reach/references/search.md @@ -0,0 +1,39 @@ + + +# 搜索工具 + +Exa AI 搜索引擎。 + +## Exa AI 搜索 + +高质量 AI 搜索引擎,适合查找技术文档、官方示例和相关网页。 + +```bash +mcporter call exa.web_search_exa query="query" numResults=5 +mcporter call exa.web_search_exa query="library API code example" numResults=5 +``` + +### 使用场景 + +| 场景 | 参数 | +|-----|------| +| 网页搜索 | `web_search_exa(query: "...", numResults: 5)` | +| 技术/代码资料 | `web_search_exa(query: "框架名 API 示例", numResults: 5)` | + +> Exa MCP 的 `get_code_context_exa` 已弃用且默认不注册。代码问题也使用 +> `web_search_exa`;需要精确搜索仓库内容时,改用 `dev.md` 中的 GitHub 搜索。 + +### 特点 + +- 擅长英文内容和技术文档 +- 可通过查询词定位官方文档和代码示例 +- 结果质量高 + +## 与其他搜索工具对比 + +| 工具 | 来源 | 适用场景 | +|-----|------|---------| +| Exa | agent-reach | 英文/技术/代码搜索 | +| 智谱搜索 | my-mcp-tools | 中文搜索 | +| GitHub 搜索 | agent-reach (dev.md) | 仓库/代码搜索 | diff --git a/.claude/skills/agent-reach/references/social.md b/.claude/skills/agent-reach/references/social.md new file mode 100644 index 0000000..35e6a80 --- /dev/null +++ b/.claude/skills/agent-reach/references/social.md @@ -0,0 +1,304 @@ + + +# 社交媒体 & 社区 + +小红书、Twitter/X、B站、V2EX、Reddit、Facebook、Instagram。 + +## 小红书 / XiaoHongShu(多后端) + +小红书有三个后端,**先跑 `agent-reach doctor --json` 看 xiaohongshu 的 `active_backend` 是哪个**,再用对应命令组。 + +### 后端 A:OpenCLI(桌面首选) + +```bash +# 搜索笔记 +opencli xiaohongshu search "query" -f yaml + +# 读笔记正文+互动数据(用搜索结果里的完整 URL,含 xsec_token) +opencli xiaohongshu note "NOTE_URL" -f yaml + +# 评论(支持楼中楼) +opencli xiaohongshu comments NOTE_ID -f yaml + +# 首页推荐 feed +opencli xiaohongshu feed -f yaml + +# 用户主页公开笔记 +opencli xiaohongshu user USER_ID -f yaml +``` + +> 要求 Chrome 打开且装了 OpenCLI 扩展。OpenCLI 只使用用户已经存在且明确控制 +> 的 Chrome 会话;Agent Reach 不替用户登录,也不读取浏览器 Cookie。 +> `agent-reach configure xhs-cookies` 不会把 Cookie 注入 OpenCLI。 +> 如果没有现成会话,不要自动登录;改走后端 B/C,并按对应的 +> Cookie-Editor 手工导出流程配置。 + +### 后端 B:xiaohongshu-mcp(服务器场景) + +```bash +# 认证前先让用户用 Cookie-Editor 手工导出,再显式导入 +agent-reach configure xhs-cookies + +# 只读检查当前状态 +mcporter call xiaohongshu.check_login_status --timeout 120000 + +# 搜索 +mcporter call xiaohongshu.search_feeds keyword="query" --timeout 120000 + +# 笔记详情+评论(feed_id 和 xsec_token 从搜索结果取) +mcporter call xiaohongshu.get_feed_detail feed_id="..." xsec_token="..." --timeout 120000 +``` + +> 首次调用会自动下载约 150MB 无头浏览器,务必带 `--timeout 120000`。 +> 认证只走 Cookie-Editor 手工导出;导入后先运行 `check_login_status`。 +> 该显式命令会保存/导入用户提供的 xiaohongshu.com 同域 Cookie 集,用户应 +> 确认范围;非 xiaohongshu.com 域 Cookie 会被忽略。 + +### 后端 C:xhs-cli(存量备选,上游 2026-03 起停更) + +```bash +xhs search "query" # 搜索 +xhs read NOTE_ID_OR_URL # 读笔记(必须用搜索结果中的 URL/ID,不能裸 note_id) +xhs comments NOTE_ID_OR_URL # 评论 +xhs hot # 热门 +xhs feed # 推荐 +``` + +> 已知不稳定:`xhs user` / `xhs user-posts` / `xhs favorites` 可能返回 API error(上游停更无人修)。新装用户建议直接走后端 A/B。 + +### 通用注意事项 + +> **认证边界**: Agent Reach 不得替用户执行小红书登录,也不得读取浏览器 +> Cookie。OpenCLI 只能使用用户已有且明确控制的 Chrome 会话; +> xiaohongshu-mcp / 存量工具使用 Cookie-Editor 手工导出。 +> +> **xsec_token 限制**: 小红书强制 xsec_token 机制,**不能直接用裸 note_id 去读**。正确流程:先搜索/feed 拿结果,再用结果中的完整 URL/ID 去读。三个后端都一样。 +> +> **频率控制**: 高频请求(批量搜索、深翻评论)会触发验证码,平台限制无法绕过。每次操作间隔 2-3 秒。 +> +> **写操作(发帖/评论/点赞)**: 建议只读。xhs-cli v0.6.x 写操作可能因签名问题返回 406。 + +## Twitter/X (twitter-cli) + +### 认证前置条件 + +`agent-reach configure twitter-cookies` 通过隐藏输入保存的 Cookie 只供 +`agent-reach doctor` 检查显式凭据是否齐全。`doctor` 不执行上游 +`twitter status`,也不会设置当前 Shell。运行下面任何 `twitter` 命令前, +必须在同一个 Shell 或子进程环境中显式提供: + +```bash +export TWITTER_AUTH_TOKEN="..." +export TWITTER_CT0="..." +``` + +### 稳定命令 + +```bash +# 首页时间线(最稳定) +twitter feed -n 20 + +# 读取单条推文(含回复) +twitter tweet URL_OR_ID + +# 读取长文 / X Article +twitter article URL_OR_ID + +# 用户时间线 +twitter user-posts @username -n 20 + +# 用户资料 +twitter user @username +``` + +### 可能不稳定的命令 + +```bash +# 搜索推文(Twitter 频繁改 GraphQL 端点,可能 404) +twitter search "query" -n 10 + +# likes(2024 年后只能看自己的,平台限制) +twitter likes +``` + +### search 失败时的重试链(按序执行,成功即停) + +1. 直接重试一次(偶发失败常见):`twitter search "query" -n 10` +2. 升级后再试:`pipx upgrade twitter-cli && twitter search "query" -n 10` +3. 换 OpenCLI 备选(桌面,复用浏览器登录态):`opencli twitter search "query" -f yaml` +4. 都不行就改用 `twitter feed` / `twitter user-posts @somebody` 等稳定命令绕路 + +### 重要注意事项 + +> **安装**: `pipx install twitter-cli`(确保 v0.8.5+) +> +> **认证**: 只用 Cookie-Editor 手工导出,再显式设置环境变量 +> `TWITTER_AUTH_TOKEN` + `TWITTER_CT0`;不要依赖自动浏览器读取。 +> +> **IP 风控**: 不要在 VPS/数据中心 IP 上频繁调用,尤其是 followers/following,有封号风险。使用住宅代理或本地环境。 +> +> **OpenCLI 备选**: 桌面装了 OpenCLI 的话,`opencli twitter search/article/user-posts -f yaml` 全套可用(浏览器登录态,无需 cookie 环境变量)。 +> +> **输出格式**: 建议用 `--yaml` 或 `--json` 获得结构化输出,对 AI agent 更友好。 + +## B站 / Bilibili + +> ⚠️ **不要用 yt-dlp 读 B站**(风控已全面 412 拦截,实测无解)。用 bili-cli / OpenCLI。 + +```bash +# 搜索 / 热门 / 视频详情(bili-cli,只读无需登录) +bili search "query" --type video -n 5 +bili hot -n 10 +bili video BVxxx + +# 字幕(OpenCLI,需桌面 Chrome) +opencli bilibili subtitle BVxxx +``` + +> 详细命令(音频转写、API 直连兜底)见 [references/video.md](video.md)。 + +## V2EX (公开 API) + +无需认证,直接调用公开 API。 + +### 热门主题 + +```bash +curl -s "https://www.v2ex.com/api/topics/hot.json" -H "User-Agent: agent-reach/1.0" +``` + +### 节点主题 + +```bash +# node_name 如: python, tech, jobs, qna, programmers +curl -s "https://www.v2ex.com/api/topics/show.json?node_name=python&page=1" -H "User-Agent: agent-reach/1.0" +``` + +### 主题详情 + +```bash +# topic_id 从 URL 获取,如 https://www.v2ex.com/t/1234567 +curl -s "https://www.v2ex.com/api/topics/show.json?id=TOPIC_ID" -H "User-Agent: agent-reach/1.0" +``` + +### 主题回复 + +```bash +curl -s "https://www.v2ex.com/api/replies/show.json?topic_id=TOPIC_ID&page=1" -H "User-Agent: agent-reach/1.0" +``` + +### 用户信息 + +```bash +curl -s "https://www.v2ex.com/api/members/show.json?username=USERNAME" -H "User-Agent: agent-reach/1.0" +``` + +### Python 调用示例 + +```python +from agent_reach.channels.v2ex import V2EXChannel + +ch = V2EXChannel() + +# 获取热门帖子 +topics = ch.get_hot_topics(limit=10) +for t in topics: + print(f"[{t['node_title']}] {t['title']} ({t['replies']} 回复)") + +# 获取节点帖子 +node_topics = ch.get_node_topics("python", limit=5) + +# 获取帖子详情 + 回复 +topic = ch.get_topic(1234567) +print(topic["title"], "—", topic["author"]) + +# 获取用户信息 +user = ch.get_user("Livid") +``` + +> **节点列表**: https://www.v2ex.com/planes + +## Reddit(多后端,必须登录态) + +**Reddit 没有零配置路径**:匿名 `.json` 端点已被封(403),官方 API 自 2025-11 起人工审批基本不批。两个后端都靠登录态,先跑 `agent-reach doctor --json` 看 reddit 的 `active_backend`。中国大陆访问需代理。 + +### 后端 A:OpenCLI(桌面首选,复用浏览器登录态) + +```bash +# 搜索帖子 +opencli reddit search "query" -f yaml + +# 读帖子全文 + 评论 +opencli reddit read POST_ID -f yaml + +# 浏览 subreddit / 热门 / Popular +opencli reddit subreddit LocalLLaMA -f yaml +opencli reddit hot -f yaml +opencli reddit popular -f yaml + +# subreddit 元信息(订阅数、简介) +opencli reddit subreddit-info LocalLLaMA -f yaml +``` + +> 要求 Chrome 打开且浏览器里登录过 reddit.com。 + +### 后端 B:rdt-cli(存量/服务器备选,上游 2026-03 起停更) + +```bash +rdt search "query" --limit 10 # 搜索帖子 +rdt read POST_ID # 读帖子全文 + 评论 +rdt sub python --limit 20 # 浏览 subreddit +rdt popular --limit 10 # 浏览热门 +rdt all --limit 10 # 浏览 /r/all +``` + +> **安装**: `pipx install 'git+https://github.com/public-clis/rdt-cli.git'`(PyPI 版本落后,需从 GitHub 装 v0.4.2+)。先 `rdt login` 才能搜索和阅读(服务器无浏览器时手动写 Cookie,见 doctor 提示)。 +> 建议使用 `--yaml` 输出,对 AI agent 更友好。 + +### 高级选项:官方 API + PRAW(仅限已有凭证的用户) + +2025-11 前注册过 Reddit script app(持有 client_id/client_secret)的用户可以用 PRAW 走官方 API(100 QPM 免费)。新申请需人工审批且个人项目基本不批,**不要推荐新用户走这条路**。 + +## Facebook(OpenCLI,必须登录态) + +Facebook 走 OpenCLI,复用用户 Chrome 里的 facebook.com 登录态。先跑 `agent-reach doctor --json` 看 facebook 的 `active_backend`,正常应为 `OpenCLI`。不要推荐 Jina/Exa/Graph API 作为默认路径。 + +```bash +# 搜索用户 / 主页 / 帖子 +opencli facebook search "query" -f yaml + +# 用户或主页信息 +opencli facebook profile zuck -f yaml + +# 当前账号 News Feed +opencli facebook feed --limit 10 -f yaml + +# 当前账号可见的群组列表/最近动态 +opencli facebook groups --limit 20 -f yaml +``` + +> 要求 Chrome 打开且装了 OpenCLI 扩展,并已登录 facebook.com。Facebook Groups 当前只承诺读取当前账号可见的群组列表/最近动态,不承诺任意群帖子和评论 API。 + +## Instagram(OpenCLI,必须登录态) + +Instagram 走 OpenCLI,复用用户 Chrome 里的 instagram.com 登录态。先跑 `agent-reach doctor --json` 看 instagram 的 `active_backend`,正常应为 `OpenCLI`。不要默认恢复 instaloader;历史上 cookies/401/429 不稳定。 + +```bash +# 搜索用户(不是全站帖子关键词搜索) +opencli instagram search "query" -f yaml + +# 用户 Profile +opencli instagram profile nasa -f yaml + +# 用户最近帖子 +opencli instagram user nasa --limit 12 -f yaml + +# Explore / Discover +opencli instagram explore --limit 20 -f yaml + +# 当前账号收藏 +opencli instagram saved --limit 20 -f yaml +``` + +> 要求 Chrome 打开且装了 OpenCLI 扩展,并已登录 instagram.com。`instagram search` 是用户搜索;读帖子需要先确定 username,再用 `instagram user USERNAME`。若出现 429 / login required,先让用户在 Chrome 里重新登录并降低频率。 diff --git a/.claude/skills/agent-reach/references/video.md b/.claude/skills/agent-reach/references/video.md new file mode 100644 index 0000000..c6fa9ec --- /dev/null +++ b/.claude/skills/agent-reach/references/video.md @@ -0,0 +1,151 @@ + + +# 视频/播客 + +YouTube、B站、小宇宙播客的字幕和转录。 + +## YouTube (yt-dlp) + +### 获取视频元数据 + +```bash +yt-dlp --dump-json "URL" +``` + +### 下载字幕 + +```bash +# 下载字幕 (不下载视频) +yt-dlp --write-sub --write-auto-sub --sub-lang "zh-Hans,zh,en" --skip-download -o "/tmp/%(id)s" "URL" + +# 然后读取 .vtt 文件 +cat /tmp/VIDEO_ID.*.vtt +``` + +### 获取评论 + +```bash +# 提取评论(best-effort,不保证完整) +yt-dlp --write-comments --skip-download --write-info-json \ + --extractor-args "youtube:max_comments=20" \ + -o "/tmp/%(id)s" "URL" +# 评论在 .info.json 的 comments 字段中 +``` + +### 搜索视频 + +```bash +yt-dlp --dump-json "ytsearch5:query" +``` + +> **字幕注意**: 手动上传的字幕提取可靠;自动生成字幕可能存在行间重复,需后处理。 +> **评论注意**: `--write-comments` 基于网页抓取(非 YouTube Data API),部分评论可能丢失。 + +### 字幕失败时的重试链(按序执行,拿到实质内容即停) + +`doctor` 只确认 yt-dlp 本体与 JS runtime 能执行,不会请求具体视频;因此 +`active_backend: yt-dlp` 不等于目标视频的字幕已经通过实时验证。 + +1. 先用上面的 `yt-dlp --write-sub --write-auto-sub` 命令。 +2. 若出现 bot 校验、字幕响应为空或没有生成字幕文件,且 OpenCLI 已连接: + `opencli youtube transcript "URL" -f yaml`。 +3. OpenCLI 若返回 `Caption URL returned empty response`,最多重试 3 次;这是带 + 过期时间的字幕 URL 偶发失效,不能把空响应当成“视频没有字幕”。 +4. 仍失败或视频本来就没有字幕:`agent-reach transcribe "URL"` 下载音频转写。 + +成功标准是实际得到非空字幕/转录内容,不是命令退出码或 `doctor` 的版本探测结果。 + +### 无字幕兜底:Whisper 音频转写 + +```bash +# 视频没有字幕时的兜底:下载音频并用 Whisper 转写(Groq 免费 key 即可) +agent-reach transcribe "https://www.youtube.com/watch?v=VIDEO_ID" +agent-reach transcribe ./local_audio.mp3 -o /tmp/transcript.txt +``` + +> `agent-reach transcribe` 只接收公开 http(s) URL 或本地音频文件。用 `ytsearch5:` 搜索时,先从 yt-dlp 结果里选出具体视频 URL,再转写。 +> 需要先配置 key:`agent-reach configure groq-key`(隐藏输入;免费,console.groq.com) +> 或 `agent-reach configure openai-key`。默认 auto 模式只使用第一个已配置服务商 +>(优先 Groq,否则 OpenAI),失败即停止,不会把音频自动发给另一家。 +> `--allow-provider-fallback` 会显式授权跨服务商降级;同一音频内容可能被 Groq 和 +> OpenAI 分别处理,并可能产生 OpenAI 费用,只应在确认内容可分享给两家后使用。 + +## B站 / Bilibili(bili-cli 为主,OpenCLI 补字幕) + +> ⚠️ **不要用 yt-dlp 读 B站**:B站风控已全面 412 拦截 yt-dlp(实测最新版、直连/代理/带 Cookie 全部无效)。yt-dlp 只用于 YouTube。 + +### 视频详情/搜索/热门/排行 (bili-cli,只读无需登录) + +```bash +# 视频详情(标题/UP主/时长/播放互动数据/字幕可用性) +bili video BVxxx + +# 搜索视频 +bili search "query" --type video -n 5 + +# 热门视频 / 排行榜 +bili hot -n 10 +bili rank -n 10 + +# 下载音频并切分为 ASR-ready WAV(无字幕时配合 agent-reach transcribe 转写) +bili audio BVxxx +``` + +### 字幕 (OpenCLI,需要桌面 Chrome) + +```bash +# 字幕逐句带时间轴 +opencli bilibili subtitle BVxxx + +# OpenCLI 也能搜索/读视频元数据(备选) +opencli bilibili search "query" -f yaml +opencli bilibili video BVxxx -f yaml +``` + +### 零配置兜底:搜索 API 直连 + +```bash +UA="Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36" +curl -s -c /tmp/bili_ck.txt -o /dev/null -A "$UA" "https://www.bilibili.com/" +curl -s -b /tmp/bili_ck.txt -A "$UA" -e "https://www.bilibili.com/" \ + "https://api.bilibili.com/x/web-interface/search/all/v2?keyword=QUERY&page=1" +``` + +> **安装 bili-cli**: `pipx install bilibili-cli`(上游 2026-03 起停更但实测健康;只读场景无需登录,`bili login` 扫码可解锁动态/收藏等个人功能)。 + +## 小宇宙播客 / Xiaoyuzhou Podcast + +### 转录单集播客(可选 --polish 增强标点) + +```bash +# 输出 Markdown 文件到 /tmp/。--polish 让 Llama 3.3 70B 给文稿补中文标点+合理分段 +~/.agent-reach/tools/xiaoyuzhou/transcribe.sh --polish "https://www.xiaoyuzhoufm.com/episode/EPISODE_ID" +``` + +> 转写 prompt 已要求 Whisper 输出中文标点;若标点效果仍不理想,可加 `--polish` 用 Groq 上免费的 Llama 3.3 70B 补标点+合理分段(9 分钟播客约多 ~7 秒)。每次转写多一轮 LLM 调用,按需使用。 + +### 前置要求 + +1. **ffmpeg**: `brew install ffmpeg` +2. **Groq API Key** (免费): https://console.groq.com/keys +3. **配置 Key**: `agent-reach configure groq-key`(隐藏输入) +4. **首次运行**: `agent-reach install --env=auto --system --channels=xiaoyuzhou`(需用户明确授权) + +### 检查状态 + +```bash +agent-reach doctor +``` + +> 输出 Markdown 文件默认保存到 `/tmp/`。 + +## 选择指南 + +| 场景 | 推荐工具 | +|-----|---------| +| YouTube 字幕 | yt-dlp;失败时 OpenCLI(最多 3 次)→ agent-reach transcribe | +| B站视频详情/搜索 | bili-cli | +| B站字幕 | opencli bilibili subtitle | +| 播客转录 | 小宇宙 transcribe.sh | +| 无字幕音视频 | agent-reach transcribe(B站音频先 `bili audio`) | diff --git a/.claude/skills/agent-reach/references/web.md b/.claude/skills/agent-reach/references/web.md new file mode 100644 index 0000000..b7e8967 --- /dev/null +++ b/.claude/skills/agent-reach/references/web.md @@ -0,0 +1,53 @@ + + +# 网页阅读 + +通用网页、RSS。 + +## 通用网页 (Jina Reader) + +```bash +# 读取任意网页内容 +curl -s "https://r.jina.ai/URL" + +# 示例 +curl -s "https://r.jina.ai/https://example.com/article" +``` + +**适用场景**: 大多数网页可以直接用 Jina Reader 读取。 + +## Web Reader (MCP) + +```bash +# 读取网页内容 (Markdown 格式) +mcporter call web-reader.webReader url="https://example.com" + +# 保留图片 +mcporter call web-reader.webReader url="https://example.com" retain_images=true + +# 纯文本格式 +mcporter call web-reader.webReader url="https://example.com" return_format="text" +``` + +**适用场景**: 需要更精确控制输出格式时使用。 + +## RSS (feedparser) + +```python +python3 -c " +import feedparser +for e in feedparser.parse('FEED_URL').entries[:5]: + print(f'{e.title} — {e.link}') +" +``` + +**适用场景**: 订阅博客、新闻源、播客等 RSS feed。 + +## 选择指南 + +| 场景 | 推荐工具 | +|-----|---------| +| 通用网页 | Jina Reader (`curl r.jina.ai`) | +| 需要图片/格式控制 | web-reader MCP | +| RSS 订阅 | feedparser | diff --git a/README.md b/README.md index 745c57f..dad7c7c 100644 --- a/README.md +++ b/README.md @@ -70,7 +70,9 @@ Real on-chain ERC-8004 activity from a production agent fleet. Every number is v | `trinity-orch` | `6705` | `trinity-mel` | `6710` | | `trinity-nexus` | `6711` | `trinity-hdm` | `6712` | -- **70 lifetime on-chain reputation writes** from the agent economy — real production activity, not synthetic backfill (verified 2026-07-08 via `/api/v1/observability/onchain-stats`). Gas per write: ~134,661. **Honest currency note:** writes paused after **2026-06-22** and **resumed 2026-07-08** as the settlement path was re-wired; cadence is still being restored. The reputation *history* on-chain remains fully verifiable — treat the count as a dated snapshot, not a fixed constant. +- **92 lifetime on-chain reputation writes** from the agent economy — real production activity, not synthetic backfill (re-measured **2026-08-29** against `erc8004_reputation_writes`; the previous published figure of 70 was a 2026-07-08 snapshot and is superseded, not withdrawn). Gas per write: ~134,661. Most recent write: [`0xdaf4863b…`](https://sepolia.basescan.org/tx/0xdaf4863bf3c21d156d5d38c4c5c9e46288c4b6cf61c439c0bccd086fdd21ac73) at 2026-08-29 12:01:34 UTC — the minter re-reads the receipt from Base Sepolia (`status 0x1`, sent to the ReputationRegistry) and exits non-zero rather than record an unverified write, so every row here was confirmed against the chain and not against our own database. + **Honest currency note — there have been two pauses, and the second is the more instructive.** The first ran **2026-06-22 → 2026-07-08** while the settlement path was re-wired. The second ran **2026-08-17 → 2026-08-29**: an upstream provider retired the model our peer-validation step called, so every validator returned an error — and the aggregation counted an unreachable validator as a score of **zero** rather than as *not measured*. The result was a confident failing verdict about work nobody had assessed, which disputed twelve consecutive runs. Both halves are fixed: the model is configuration rather than a literal, and a validator that does not answer is now excluded from the aggregate instead of counted against the provider. + We publish the gap rather than the average. The reputation *history* on-chain remains fully verifiable — treat the count as a dated snapshot, not a fixed constant, and treat live cadence as something to re-probe rather than assume. - **Epoch-1 reset:** RepID was reset to a neutral **1,000 baseline** for a clean start. Core agents now range **~1,000–1,520** (ESTABLISHED tier) as they re-earn from a level field.