hermeschat-pair
v1.2.1
Published
One-command pair tool for the HermesChat iOS app. Auto-starts the bundled FastAPI server, registers an access-code QR, and runs the relay bridge as a daemon. Cross-platform (macOS / Linux / Windows).
Downloads
2,339
Maintainers
Readme
hermeschat-pair
One-command pair tool for the HermesChat iOS app. Generates a QR code, starts a local Hermes backend, and bridges the app to it through a relay you operate yourself — no Python / pip / certificate setup required on the user's side.
Breaking change in 1.2.0: this tool no longer ships with a built-in public relay. You must self-host your own registry / relay and point this tool to it. Deployment scripts: ship with the iOS app distribution.
Install
npm install -g hermeschat-pairTo upgrade:
npm install -g hermeschat-pair@latest
hermeschat-pair --stop
hermeschat-pairUse
export HERMESCHAT_REGISTRY_URL=https://relay.yourdomain.com
hermeschat-pairWithout HERMESCHAT_REGISTRY_URL (or the --server flag), the tool exits
with instructions to set it.
That's it. The tool will:
- Start the bundled Hermes backend on
127.0.0.1:8765(if nothing is already listening there). - Wait until
http://127.0.0.1:8765/api/healthis ready. - Open a WebSocket to the HermesChat cloud relay.
- Print an ASCII QR code in your terminal and write
hermeschat_pair.pngin the current directory. - Launch a detached background daemon so it keeps running after you close the terminal.
The QR code is only shown after the local API is healthy. If the local backend
cannot start or another process is using the port without serving /api/health,
the tool exits with a clear error instead of generating a QR code that would
pair but fail later in the app.
Open the HermesChat iOS app → My tab → + → Scan QR. Done.
Commands
| Command | What it does |
|------------------------------|-------------------------------------------|
| hermeschat-pair | Generate QR, start server + daemon |
| hermeschat-pair --status | Is the daemon / backend running? |
| hermeschat-pair --stop | Stop both the daemon and the backend |
| hermeschat-pair --refresh-code | Rotate only the access code (paired devices keep working) |
| hermeschat-pair --reset | Rotate the bridge identity (unpairs all clients) |
| hermeschat-pair --foreground | Run the bridge in the foreground (debug) |
| hermeschat-pair --json | Print the QR payload as JSON and exit |
| hermeschat-pair --no-server | Don't auto-start the bundled backend |
| hermeschat-pair --port 8765 | Use a different local Hermes port |
| hermeschat-pair --local | LAN-only direct mode (bypass registry/relay) |
| hermeschat-pair --install | (macOS) install launchd LaunchAgent for boot auto-start |
| hermeschat-pair --uninstall | (macOS) uninstall launchd LaunchAgent |
| hermeschat-pair --service-status | (macOS) show LaunchAgent status |
Config, logs and pid files live in ~/.hermeschat/.
Troubleshooting
Local API is not ready
Since 0.1.1, hermeschat-pair blocks QR generation until the local Hermes API
passes /api/health. If startup fails, run:
hermeschat-pair --status
tail -n 120 ~/.hermeschat/server.logThen retry:
hermeschat-pair --stop
hermeschat-pairPort 8765 is occupied
If you already run a compatible Hermes backend on another port, start the pair tool with that port:
hermeschat-pair --port 8000Only scan the fresh QR code printed by that command.
Boot auto-start (macOS launchd)
hermeschat-pair 默认启动一个前台 daemon(~/.hermeschat/bridge.pid),机器重启后不会
自动恢复。如果你希望开机自动拉起 bridge,从 1.0.0 起新增了 launchd 集成:
# 1) 先确保已经配对(生成过 QR、bridgeId 已写入 ~/.hermeschat/bridge.json)
hermeschat-pair
# 2) 注册 LaunchAgent(写入 ~/Library/LaunchAgents/ai.hermeschat.bridge.plist 并 launchctl load)
hermeschat-pair --install
# 3) 检查状态
hermeschat-pair --service-status
# ● launchd 服务运行中 pid=12345
# label : ai.hermeschat.bridge
# plist : ~/Library/LaunchAgents/ai.hermeschat.bridge.plist
# 4) 卸载(停止 + 删 plist)
hermeschat-pair --uninstall注意事项:
- 仅 macOS:Linux / Windows 用户请走
hermeschat-pair --foreground+ systemd / supervisord / pm2 自管。 - 安装前必须先配对成功,否则 daemon 启动后会因为缺凭据立即退出(
KeepAlive会反复重启)。 - launchd 入口走的是
node bin/hermeschat-pair.js --__bridge_run,它读~/.hermeschat/bridge.json, 不会重新生成 QR;如果你--reset过,需要重启 LaunchAgent:launchctl kickstart -k gui/$UID/ai.hermeschat.bridge。 - 日志:
~/.hermeschat/service.log(stdout)+~/.hermeschat/service-error.log(stderr)。 - 升级 npm 包后建议重新执行
--install(plist 里node路径会指向新版 nvm/Volta 节点)。
Hermes Gateway 自动唤醒
HermesChat App 的聊天能力依赖 Hermes Gateway (127.0.0.1:8642),由 Hermes Agent 提供。使用本 App 的前提是已安装 hermes-agent。
但 Gateway 可能因为下列原因没有在跑:
- 从未手动
start过(粉丝装了手动版没装服务) - launchd / systemd 服务崩了
KeepAlive没续上 - 机器重启后 plist 没 load
从 0.1.3 起,hermeschat-pair 启动时会主动拉起 Gateway,按顺序尝试:
launchctl kickstart -k gui/<uid>/ai.hermes.gateway(macOS LaunchAgent)- 直接 spawn
~/.hermes/hermes-agent/venv/bin/python -m hermes_cli.main gateway run - PATH 里的
hermes gateway start
终端输出会明确告诉你当前状态:
✓ Hermes Gateway 在线 (127.0.0.1:8642) ← 一切正常
✓ Hermes Gateway 已拉起 (via launchd) ← 自动唤醒成功
⚠ Hermes Gateway 未运行,自动拉起失败。… ← 需手工处理(打印具体命令)如果自动拉起失败,终端会打印手工命令(hermes gateway start / launchctl kickstart ... / 直接用 venv python 启动)。
Release notes
1.0.0 — Phase 4 LAN direct mode + Phase 7 launchd auto-start
Stable feature parity with Clawket-style migration plan: 这是 0.x → 1.x 的稳定版,
全量对齐 HermesChat_迁移方案_Clawket风格连接.md。
新增能力:
--local真路径:探测 LAN IP → 探测 8765 → 已跑 FastAPI 主路径直接调POST /api/local-bridge/register-token注册 10min 临时 token;未跑则启动 fallbackbridge-local.jsws server。输出hermes-localQR{mode, url, token, expiresAt}。--install/--uninstall/--service-status:macOS launchd LaunchAgent 集成(ai.hermeschat.bridge),开机自启 bridge daemon。详见 README "Boot auto-start" 章节。HERMESCHAT_REGISTRY_URL环境变量:运行时覆盖默认https://relay.example.com,方便 本地开发 / 自建 registry 联调,无需重打 npm 包。- Relay
/v1/internal/hermes/bridge-status端点:供 relay worker 在握手阶段 轻量探测 bridge 是否已注册(200 +{hasBridge, online},未知 bridge 不抛 404)。 - iOS 配套:
HermesPairingParser.swift统一识别 4 种 QR(v=1 老协议、v=2 hp/hc/cp、 hermes-local);LocalBridgeClient.swift同 WiFi 直连 LAN ws,零云依赖。
兼容性:
- 0.3.x 老 QR 仍可识别(向后兼容)。
- 1.0.0 npm 包升级后强烈建议重新执行
--install,plist 里 node 路径会指向新版。 - 服务端
server/main.py必须包含 1.0.0 的local_ws.py(含 token 注册端点)才能配合--local主路径;否则 cli 会自动 fallback 到内置 bridge-local.js。
0.3.2 — Binary body passthrough (fix file uploads in Relay mode)
修复 Relay 模式下 iOS App「上传失败:暂不支持文件上传」。0.3.1 envelope 协议
要求 body 是 UTF-8 字符串,二进制数据(multipart 文件上传、PNG/PDF 等)会被
String(data:encoding:.utf8) 拒绝或 round-trip 损坏,所以 iOS 端干脆抛 501。
0.3.2 协议层扩展:iOS(>= 配套版本)对二进制 body 自动 base64 编码并加
bodyBase64: true 标志;bridge 端识别此标志后用 Buffer.from(s, 'base64')
解码再 HTTP 透传到本地 8765 server,二进制完整 round-trip。
向后兼容:纯文本 body(JSON 聊天请求等)行为不变,老 iOS 客户端继续工作。
Upgrade:
hermeschat-pair --stop
npm install -g hermeschat-pair@latest
hermeschat-pair0.3.1 — Restored local-server passthrough
修复 0.3.0 在真机上聊天报 HTTP 502: missing base_url in envelope.body 的问题。
0.3.0 沿用了 0.2.x 的"npm-pair 内置 LLM 代理"模式,与迁移设计文档原意相反
(文档要求 /api/chat → 透传到 mac 本地 8765 server,由 server 自己持有
provider/key 路由)。0.3.1 把 bridge 改回透传模式,与 0.1.x 行为对齐。
前置条件:mac 上必须有 HermesChat FastAPI server 监听 127.0.0.1:8765。
启动方式(任选其一):
cd <HermesChat 仓库> && python -m server.main # 直接跑
# 或保持你之前的启动方式,例如 launchd / pm2 / systemd 等你可以通过 HERMESCHAT_LOCAL_HOST / HERMESCHAT_LOCAL_PORT 环境变量
让 npm-pair 透传到其它地址。bridge 启动时会探测一次本地 server,不可达
会打印明显的中文提示但仍保持 relay 连接。
协议未变:v=2 QR 配对流程、registry verify、Keychain client_secret 存储 全部不动。iOS 0.3.0 客户端直接配 0.3.1 bridge。
Upgrade:
hermeschat-pair --stop
npm install -g hermeschat-pair@latest --registry=https://registry.npmjs.org/
hermeschat-pair现有 ~/.hermeschat/config.json 不需要迁移;老 QR 仍然有效。
0.3.0 — Registry-driven pairing (v=2 protocol)
Why bump 0.1.x → 0.3.0? This release is a security-critical rewrite of the pairing handshake. The QR code no longer contains a long-term secret.
- New v=2 QR payload (
{v:2,k:"hp",g,a,s,u,n}):g=bridgeId(24-hex, registered with the registry on first run)a=accessCode(32-hex, one-time, 10-min expiry)s=registryUrl(https://relay.example.com)u=relayWssUrl(wss://relay.example.com/ws/app)
- After scanning, the iOS app calls
POST /v1/pair/verifyonce to exchange the access code for a long-termclient_secret, which is stored in the iOS Keychain. The QR can then be safely deleted / regenerated; an attacker who later sees a screenshot cannot use it (access code is single-use and expired). - The bridge authenticates to the relay with a
relay_secret(registry-issued, rotated independently ofclient_secret). The iOS app authenticates withclient_secret. They are independent secrets — rotating one does not affect the other. hermeschat-pair --refresh-codeissues a fresh access code (existing paired devices keep working — only the QR rotates).hermeschat-pair --resetrotates the entire bridge identity (kicks all paired iOS clients).- Old v=1 QR codes (with
bridgeSecretdirectly in the QR) are no longer generated. The relay still accepts old paired clients during a transition window so existing users keep working until they re-pair.
Upgrade: npm install -g hermeschat-pair@latest --registry=https://registry.npmjs.org/
followed by hermeschat-pair --stop && hermeschat-pair. Old ~/.hermeschat/config.json
is auto-migrated; users will see a fresh v=2 QR.
0.1.4
- 新增 Gateway 远程控制端点:
POST /api/gateway/restart?action=restart|start|stop, 让 HermesChat App 可以一键重启 / 启动 / 停止 Hermes Gateway。 - 服务端按平台优先级尝试:
launchctl kickstart(macOS) →systemctl --user(Linux) →~/.hermes/hermes-agent/venv/bin/python -m hermes_cli.main gateway run兜底,逻辑与 CLIgateway-ensurer.js保持一致。 - 失败时返回
attempted步骤列表 +gateway.log末尾 4KB,方便 App 端排错。
0.1.3
- 重大修复:App 对话报 "HTTP 500"。问题本质是用户机器上 Hermes Gateway
(127.0.0.1:8642) 没在跑,但
hermeschat-pair之前不会主动拉起它。 - 新增 Gateway 自动唤醒 (
src/gateway-ensurer.js):launchd kickstart → venv 直启 →hermes gateway start,逐级尝试。 - 新增
GET /api/gateway/health返回gateway/direct/none后端状态; App 端据此显示 banner。 - App 端删除了错误的 "HTTP 500" 字符串误判逻辑。
- Server 端
/api/chat在 Gateway 不可用时返回200 + SSE error而非裸 500; 如用户额外配了AI_API_KEY还能兜底直连 LLM(纯保险丝)。 - PyInstaller 构建显式安装
httpx,避免极端情况下运行时缺依赖。
0.1.2
- Removed npm install-time platform blocking so Windows, macOS, and Linux users can install the pair tool.
- On platforms without a bundled
hermes-server, the tool now tries to reuse an already-running Hermes-compatible API. - Added automatic probing of common local ports such as
8765,8000,7860,3000,8080, and11434. - If a healthy API is found, the bridge uses that port and still prints a normal QR code.
- If no healthy API is found, the tool fails before QR generation and explains that the current platform has no bundled backend binary yet.
0.1.1
- Added a startup health check against
127.0.0.1:8765/api/health. - QR generation now waits for the local backend to become ready.
- The bridge daemon also verifies the local API before connecting to the relay.
--statusnow distinguishesserver ready,server unhealthy, andserver not listening.- This prevents successful-looking pairings that later fail with bridge
ECONNREFUSED 127.0.0.1:8765errors in the iOS app.
Platform support
hermeschat-pair is a pure-JavaScript pairing / relay bridge and runs on
Windows, macOS, and Linux. It assumes a Hermes-compatible API is already
running locally (typically installed via hermes-agent) and will probe common
ports 8765, 8000, 7860, 3000, 8080, 11434 to find it. If none is
healthy, the tool exits with an explicit message instead of generating a QR
that would fail in the app.
License
MIT
