ilink-hub-bridge:本地 CLI 后端
ilink-hub-bridge 是一个独立进程:对每条用户文本消息按 YAML 配置执行本机命令,把 stdout 作为回复发回微信。与 Recursive / OpenClaw 一样,通过 Hub 暴露的 iLink 兼容 API(getupdates / sendmessage)通信。
连接 Hub 的方式(任选)
- 零交互(默认,本机最省事):不传
--token、且凭证路径尚不存在时,进程会自行调用 Hub 已有的POST /hub/register(与任何其他客户端相同),按local-<hostname>-<配置名>生成稳定客户端名(例如local-MacBook-ilink-claude)、拿到vhub_…后写入~/.ilink-hub/bridge-credentials.json。同名重启会复用 Hub 上的同一客户端,不会在/list里堆积local-<uuid>。终端会打印已向 Hub 自动注册客户端「…」,按提示在微信发/use <名称>即可。若 Hub 配置了ILINK_ADMIN_TOKEN,请在本机同一环境导出该变量,否则注册会 401。可用--register-name/ILINKHUB_BRIDGE_REGISTER_NAME覆盖默认名。
凭证文件已存在但损坏或 token 为空时:为避免静默覆盖扫码配对结果,默认不会再自动注册;请删文件、改用WEIXIN_TOKEN/--pair,或显式加--force-register(会先删该路径再自动注册)。 - 扫码配对:加
--pair(或你希望用手机确认时),走 Hub 通用配对流程;凭证仍写入上述 JSON。
Token 校验(v0.1.13+):Hub 在 getupdates / sendmessage 会拒绝未注册的 vhub_… token(HTTP 401)。Bridge 启动时会探测凭证是否仍被当前 Hub 接受;若本地 JSON 里的 token 已失效,会自动删除凭证并重新 POST /hub/register(除非你用 WEIXIN_TOKEN / --token 显式指定)。运行中若 Hub 撤销 token,bridge 也会同样自动重注册。
3. 显式 Token:自行 ilink-hub register 或拷贝 vhub_…,通过 --token / WEIXIN_TOKEN 传入。
Hub 侧不区分调用方是不是 bridge:只看到普通的「注册客户端」与「长轮询下游」。
不会在「连不上 Hub」时自动改走扫码或注册:自动 POST /hub/register 失败会直接报错(连接错误时会提示检查 URL / 远程 Hub / WEIXIN_TOKEN / 待 Hub 就绪后再用 --pair)。需要扫码时请自行加 --pair。
与是否本机安装 ilink-hub 无关:只要 WEIXIN_BASE_URL 指向任意可达的 Hub(同事机器、内网服务器、公网域名均可),只装 bridge 即可;本机不必安装或启动 ilink-hub。
Hub 不执行你的 CLI,仍只做 iLink 代理;命令执行只发生在运行 bridge 的机器上。
想先跑通再读细节?
先跟做 5 分钟上手(echo 链路);要接 Claude Code / Cursor / Codex 等本地 CLI,请看 使用指引。字段说明仍以本页为准。
适用场景
| 场景 | 说明 |
|---|---|
| 快速验证 Hub / Token / 路由 | 用 echo 或脚本确认消息能到本机 |
| 接 Claude Code、Codex、Gemini CLI 等 | 把 command / args 换成官方 CLI,用占位符塞入用户问题 |
| 与 Recursive / OpenClaw 并存 | 多注册一个 --name,用 /use 切换活跃后端 |
架构关系
flowchart LR
WX[微信用户]
ILINK[微信 iLink]
HUB[iLink Hub]
B[ilink-hub-bridge]
CLI[本机进程]
WX <--> ILINK
ILINK <--> HUB
HUB <-->|getupdates / sendmessage| B
B --> CLI与 什么是 iLink Hub? 中的多后端模型一致:bridge 只是又一个虚拟 Token 客户端。
获取程序
| 方式 | 说明 |
|---|---|
| Homebrew(macOS) | brew install ilink-hub 同时安装 ilink-hub 与 ilink-hub-bridge(见 安装) |
| 源码构建 | 仓库根目录 cargo build --release --bin ilink-hub-bridge |
| cargo install | cargo install ilink-hub(与 Hub 同属 crates.io 上的同一个包;默认会安装包内声明的多个二进制,含 ilink-hub-bridge;若只要 bridge 可加 --bin ilink-hub-bridge) |
| Release 预编译 | Releases 中的 ilink-hub-bridge-* 资产 |
前置条件
- Hub 已运行并完成微信侧绑定(见 快速开始)。
- 本机第一次跑 bridge:可不扫码;进程会自动
POST /hub/register并保存凭证(见上文)。若 Hub 开了管理 Token,请配置ILINK_ADMIN_TOKEN。 - 若 Hub 上已有多个客户端,在微信中 切换路由:按启动时终端提示的
/use <名称>。 - 运行 bridge 的机器能访问 Hub 的 HTTP 端口。
最小启动示例
若已准备好 ilink-hub-bridge.yaml(调试可用 echo 示例;真实 CLI 见 使用指引):
方式 A:自动注册(不传 token,无凭证文件时)
export WEIXIN_BASE_URL=http://127.0.0.1:8765
# 若 Hub 设置了 ILINK_ADMIN_TOKEN:
# export ILINK_ADMIN_TOKEN=……
ilink-hub-bridge --config ./ilink-hub-bridge.yaml首次运行成功后,凭证保存在 ~/.ilink-hub/bridge-credentials.json(可用 ILINKHUB_BRIDGE_CREDS 改路径)。再次启动会直接读文件。
方式 B:扫码配对
export WEIXIN_BASE_URL=http://127.0.0.1:8765
ilink-hub-bridge --pair --config ./ilink-hub-bridge.yaml方式 C:显式虚拟 Token
export WEIXIN_BASE_URL=http://127.0.0.1:8765
export WEIXIN_TOKEN=vhub_xxxxxxxx
ilink-hub-bridge --config ./ilink-hub-bridge.yaml命令行参数
| 参数 | 环境变量 | 说明 |
|---|---|---|
--hub-url | WEIXIN_BASE_URL | Hub 根 URL(无路径后缀) |
--token | WEIXIN_TOKEN | 可选;省略则尝试读本地凭证、自动注册或 --pair 扫码 |
--cred-file | ILINKHUB_BRIDGE_CREDS | 凭证 JSON 路径,默认 ~/.ilink-hub/bridge-credentials.json |
--pair | — | 忽略已存凭证,强制走 Hub 扫码配对 |
--force-register | — | 凭证文件存在但无效时:删除该文件后重新走自动 /hub/register(默认在这种情况下会报错而不覆盖) |
--register-name | ILINKHUB_BRIDGE_REGISTER_NAME | 自动注册时使用的客户端名(可选;默认 local-<hostname>-<config-stem>) |
--config | — | YAML 路径,默认 ./ilink-hub-bridge.yaml |
| (环境) | ILINK_ADMIN_TOKEN | Hub 若要求管理端鉴权注册,需与 Hub 相同,供自动注册请求携带 |
| (环境) | ILINKHUB_BRIDGE_DUMP_MSG | 设为 1 / true / yes 时,每条入站消息在 stderr 打印完整 WeixinMessage JSON,并逐项打印 item_list[*].extra(用于查看 iLink 嵌在 item 里的扩展字段,如引用信息是否落在 extra) |
调试:查看入站消息的 extra(引用回复等)
Hub 下发给 bridge 的体与 WeixinMessage 一致:MessageItem 里除 type / text_item 外的字段会 serde flatten 进 extra。
export ILINKHUB_BRIDGE_DUMP_MSG=1
ilink-hub-bridge --config ./ilink-hub-bridge.yaml微信里发一条引用机器人消息的回复,看终端 stderr:
- 若引用元数据在
item_list某元素的extra里,会单独打印出来。 - 若上游把引用放在 消息顶层、而
WeixinMessage没有对应字段,则在进 Hub 反序列化时已被丢弃,这里也看不到(需要抓 Hub 收到上游后的原始 JSON 才能确认)。
配置:单 Profile 与多 Profile
单 Profile(默认,与旧版兼容)
根级一个 command(必填)及下表字段即可;不要同时写顶层 profiles,否则会被识别为多 Profile 格式。
多 Profile(单进程、按前缀路由)
顶层包含 profiles 与 routing。每个 profile 拥有一套与单文件相同的执行字段(command、args、timeout_secs 等);根级可写 skip_bot_messages / require_text / send_error_reply,对所有 profile 生效。
| 字段 | 说明 |
|---|---|
profiles | map:profile 名 → 该 profile 的执行配置(command 必填等,字段同下表) |
routing.default_profile | 未命中任何前缀时使用的 profile 名 |
routing.strategy | fixed:始终用 default_profile;prefix:按 prefix_rules 匹配(先匹配先生效,较长前缀请写在列表前面) |
routing.prefix_rules | 仅 strategy: prefix 时需要非空;每项 prefix + profile;命中后 去掉前缀 的余文作为 / stdin |
完整示例:multi-profile.example.yaml。
Profile 目录(manager 模式,每个文件一个 workspace)
如果你希望 bridge profile 像插件一样自由增删,可以使用 manager 模式:
ilink-hub-bridge manager默认目录:
| 用途 | 路径 |
|---|---|
| profile YAML | ~/.ilink-hub-bridge/profiles/*.yaml / *.yml |
| 每个 profile 的凭证 | ~/.ilink-hub-bridge/credentials/<profile>.json |
每个 YAML 文件仍然使用现有 bridge YAML 格式,不需要新增字段。manager 会按文件名派生 workspace / register name,例如:
~/.ilink-hub-bridge/profiles/claude-work.yaml → workspace: claude-work
~/.ilink-hub-bridge/profiles/codex-demo.yml → workspace: codex-demomanager 只做进程管理:它会为每个有效 YAML 启动一个真实的 ilink-hub-bridge --config ... 子进程,并使用独立 --cred-file 和 --register-name。子进程异常退出后会退避重启;文件被修改会重启对应子进程;文件被删除会停止对应子进程。
可选参数:
| 参数 | 说明 |
|---|---|
--profiles-dir <dir> | 覆盖 profile 目录 |
--credentials-dir <dir> | 覆盖每个 profile 的凭证目录 |
--scan-interval-secs <n> | 扫描目录间隔,默认 5 秒 |
--restart-backoff-secs <n> | 子进程退出后的最小重启间隔,默认 5 秒 |
--max-restart-backoff-secs <n> | 子进程反复退出时的指数退避上限,默认 60 秒 |
--force-register | 透传给每个子 bridge,用于清理损坏凭证后重新注册 |
注意:manager 模式会忽略 --token / WEIXIN_TOKEN、--cred-file、--register-name 和 --pair,避免多个 profile 意外共享同一个 workspace 身份。Hub 如开启管理鉴权,仍可通过 ILINK_ADMIN_TOKEN 让每个子 bridge 自动注册。
配置字段(单 Profile 根级,或 profiles.<name> 内)
| 字段 | 类型 | 默认 | 说明 |
|---|---|---|---|
command | string | (必填) | 可执行文件名或绝对路径 |
args | string 数组 | [] | 参数;支持占位符(见下) |
stdin | none / message | none | message 时将用户消息全文以 UTF-8 写入子进程 stdin |
cwd | string | 不设置 | 子进程工作目录。可与 CLI 一样使用下方占位符(例如按 分目录;目录需已存在或由你的脚本创建) |
env | map | {} | 额外环境变量(值支持占位符) |
timeout_secs | number | 1800 | 单条消息等待子进程的最长时间(秒) |
max_reply_chars | number | 8000 | 回复按 Unicode 字符数 截断上限 |
truncation_suffix | string | …(输出已截断) | 超长时在末尾追加的提示 |
skip_bot_messages | bool | true | 忽略 message_type == 2(机器人侧消息),避免回路 |
require_text | bool | true | 无文本时是否仍触发 CLI;true 则忽略纯图片/语音等 |
send_error_reply | bool | true | CLI 非零退出或超时时,是否向用户发简短错误说明 |
include_stderr_in_reply | bool | false | 成功时是否把 stderr 拼在 stdout 后面一并发出 |
cli_session_first_line_prefix | string | 不设置 | 若 stdout 首行以该前缀开头,则去掉前缀后的整行余下部分视为 CLI 会话 id,会随 sendmessage 的 ilink_cli_session_id 上报 Hub;首行之后的正文作为发给微信的回复。用于让 CLI 把会话 id 与正文分开发(见下) |
占位符
在 args、cwd 与各 env 值中,bridge 仅替换以下两项(其余字符串保持字面量):
| 占位符 | 含义 |
|---|---|
| 当前用户消息的文本(多 Profile 的 prefix 模式下为去掉匹配前缀后的余文) |
| 与下行 JSON 字段 ilink_hub_session_id 一致:由 Hub 按虚拟线程(vctx)记录——来自 bridge 上一次成功回复里上报的 ilink_cli_session_id(CLI 产生、bridge 透传)。若该线程尚未上报过,则为空字符串。不是 Hub 用微信 session_id 或 context_token 推导出来的值。 |
闭环:CLI 在 stdout 首行(配合 cli_session_first_line_prefix)或通过你自建的侧车文件等方式,把 CLI 侧的会话标识交给 bridge → sendmessage 带 ilink_cli_session_id → Hub 写入映射 → 下次同线程用户消息在 getupdates 里带上 ilink_hub_session_id → 传给 CLI(例如 claude --resume 由你在 YAML/脚本里组合)。context_token 仍由 Hub 下发、sendmessage 回包必须与之一致,但不作为占位符暴露。
Hub 在 getupdates 下发的 JSON 里会带 ilink_hub_session_id;用 ILINKHUB_BRIDGE_DUMP_MSG=1 可在 stderr 看到完整消息体。
args 以 JSON/YAML 数组 传给进程,不经过 shell,可避免常见注入;请勿自行拼 sh -c 再把用户原文塞进去。
安全警告:注入风险
不要在配置中将 作为 shell -c 参数的一部分(例如 command: bash, args: ["-c", "echo "])。这样做会导致严重的 shell 命令行注入安全漏洞。 如果需要将用户消息作为输入,推荐使用 stdin: message 模式,将消息内容通过标准输入(stdin)安全地传递给子进程:
profiles:
my-command:
command: /usr/local/bin/my-script
stdin: message安全
Bridge 与 Hub 管理员权限无关:任何能向该微信会话发消息的人,都可能触发你配置的命令。请控制 Hub 暴露范围,并阅读 安全建议。
与桌面版(Tauri)的关系
当前 桌面路线图 中的壳主要嵌入 Hub;后续可在应用内一键拉起 bridge 子进程并写入配置,无需修改 iLink 协议。
更多示例
仓库内维护的示例(复制后按本机修改 cwd、认证方式与各 CLI 的 flag):
- multi-profile.example.yaml — 单进程多 Profile(
prefix路由示例) - claude-code.example.yaml — Claude Code(
claude -p) - claude-code.profiles.example.yaml — 多 Profile +
env中注入的示例 - cursor-agent.example.yaml — Cursor Agent(
agent -p) - codex.example.yaml — OpenAI Codex(
codex exec)
串联说明(多 CLI、多凭证路径、/use 切换)见 使用指引。各工具子命令以官方 --help 为准,模板中的 flag 可能随版本变化。
与「配置 AI 客户端」文档的关系
Bridge 不是 Recursive 插件,而是独立二进制;配置方式见 配置 AI 客户端 — 与 wechatbot Echo 并列说明。
常见问题
见 FAQ 中与 bridge 相关的条目。
最后更新:2026-06-08
