@bulolo/hermes-link
v0.3.8
Published
Provides full client API, multi-device auth and conversation management for Hermes Agent, with LAN and internet connectivity.
Maintainers
Readme
hermes-link
Hermes Agent 本地接入层
为 Hermes Agent 提供完整的客户端 API、多设备鉴权与对话管理,支持局域网 / 公网直连。
简体中文 | English
如果这个项目对你有帮助,请点击右上角 ⭐ Star 支持一下,这是对开发者最大的鼓励!
概述
Hermes Link 是一个运行在本机的后台 HTTP 服务,默认监听 http://0.0.0.0:18642。客户端(App / 浏览器)通过公网或局域网直接访问,对话、文件、指令均在本地处理,数据不经过外部服务器。
所有 API 请求分为两类:
- 无需鉴权:
/pair、/api/v1/bootstrap - 需要 Bearer Token:其余接口均需
Authorization: Bearer hlat_xxx,通过配对流程获取
为什么需要 HermesLink?
Hermes Agent 内置了一个 API Server(端口 8642),但它只有 12 个接口:
| 功能 | Hermes API Server :8642 | HermesLink :18642 |
|------|:---:|:---:|
| 接口数量 | 12 | 97 |
| Agent 执行 / 事件流 | ✓ | ✓(代理转发) |
| 模型列表 / 定时任务 | ✓ | ✓(代理转发) |
| 认证 | 单一共享 Key | 设备独立 Token,可单独吊销 |
| 设备配对 | — | ✓ 二维码 / 多设备管理 |
| 对话存储 | — | ✓ 本地历史 + 附件 |
| Profile & Memory 管理 | — | ✓ 多 Profile、记忆、权限、工具开关 |
| 使用统计 | — | ✓ Token 用量按日期 / 模型 / Profile |
| 工具调用审批 | — | ✓ Approve / deny 流程 |
| 更新管理 / 开机自启 | — | ✓ |
如何选择
- 只需本机脚本 / 受信任内部服务直连 → 直接用 Hermes API Server(8642)
- 开发移动 App 或多设备接入 → 需要 HermesLink(18642)
- 需要对话历史 / Profile / 统计等完整功能 → 需要 HermesLink(18642)
工作原理
客户端(浏览器 / App)
│
└──→ hermeslink (本机, 端口 18642)
│
├── 鉴权 / 设备管理 / 对话存储 / Profile & Memory ← HermesLink 自身处理(~87 个接口)
│
└──→ Hermes Agent API Server (127.0.0.1:8642) ← 仅 runs / models / cron jobs(~10 个接口)绝大多数功能由 HermesLink 独立完成,不依赖 API Server。API Server 未运行时,认证、配对、对话查询、Profile 管理等接口仍可正常使用,仅 Agent 执行、模型列表、定时任务不可用。所有数据均存储在本机,不经过外部服务器。
环境要求
1. Node.js >= 20.0.0
node --version # 需要 >= v20.0.0如未安装,推荐通过 nvm 安装:
nvm install 20
nvm use 202. 启动 Hermes Agent API Server
Hermes Link 通过 127.0.0.1:8642 与本机的 Hermes Agent API Server 通信。
如果 Hermes Agent API Server 未运行,对话、Profiles 等功能将无法使用,但认证、配对、设备管理、日志等基础接口仍可正常工作。
在 ~/.hermes/.env 中添加以下配置以启用 API Server:
API_SERVER_ENABLED=true
API_SERVER_KEY=your-secret-key
API_SERVER_HOST=0.0.0.0
API_SERVER_CORS_ORIGINS=*
GATEWAY_ALLOW_ALL_USERS=true| 配置项 | 说明 |
|--------|------|
| API_SERVER_ENABLED | 设为 true 开启 API Server |
| API_SERVER_KEY | 认证密钥,替换为强随机字符串 openssl rand -hex 32 |
| API_SERVER_HOST | 监听地址,0.0.0.0 允许本机所有网卡 |
| API_SERVER_CORS_ORIGINS | CORS 来源,本地调试可设为 * |
配置完成后启动:
hermes gateway stop
hermes gateway start
或者
hermes gateway restart验证是否就绪:
curl -s http://127.0.0.1:8642/v1/health如缺失或版本过旧:
hermes update安装
npm 包地址:https://www.npmjs.com/package/@bulolo/hermes-link
npm install -g @bulolo/hermes-link@latest --registry=https://registry.npmjs.org
安装后如果终端找不到
hermeslink命令,说明 npm 全局 bin 目录不在 PATH 中,运行以下命令添加:export PATH="$(npm prefix -g)/bin:$PATH"也可以直接用完整路径调用:
$(npm prefix -g)/bin/hermeslink
快速开始
# 1. 启动后台服务
hermeslink start
# 2. 生成配对页面(浏览器打开完成配对)
hermeslink pair
# 3. 查看状态
hermeslink status
# 4. 查看日志
hermeslink logs配对流程
方式一:App 扫码配对(标准流程)
二维码内容是一段 JSON,App 解析后获取连接所需的全部信息:
{
"kind": "hermes_link_pairing",
"version": 1,
"link_id": "link_xxx",
"display_name": "Hermes Link",
"session_id": "ps_xxx",
"code": "xxx",
"preferred_urls": ["http://192.168.1.10:18642", "http://127.0.0.1:18642"]
}App 拿到上述信息后:
1. 取 preferred_urls[0] 作为服务地址(优先局域网 IP)
2. POST {baseUrl}/api/v1/pairing/claim
Body: { "session_id": "...", "claim_token": "<code 字段的值>" }
3. 响应中获得 access_token 和 refresh_token
4. 后续 API 请求携带 Authorization: Bearer <access_token>方式二:浏览器配对
hermeslink pair
# 在浏览器打开终端输出的 Pairing page URL
# 点击"在此设备上配对",页面直接显示 access_token 和 refresh_token方式三:命令行脚本(适合自动化)
# 1. 获取 connect_token
CONNECT_TOKEN=$(hermeslink pair 2>&1 | grep "Connect token:" | awk '{print $NF}')
# 2. 用 connect_token 换 access_token
curl -s -X POST http://localhost:18642/api/v1/auth/device-session \
-H "Authorization: Bearer $CONNECT_TOKEN" \
-H "Content-Type: application/json" \
-d '{"device_label":"my-script","device_platform":"cli"}'Token 有效期:access_token 2 小时,refresh_token 90 天。access_token 过期后用 refresh_token 换新,无需重新配对。
命令一览
| 命令 | 说明 |
|------|------|
| hermeslink start | 启动后台守护进程 |
| hermeslink stop | 停止守护进程 |
| hermeslink restart | 重启守护进程 |
| hermeslink status | 查看运行状态 |
| hermeslink pair | 生成配对 URL 和二维码 |
| hermeslink config get | 查看当前配置 |
| hermeslink config set <key> <value> | 修改配置 |
| hermeslink autostart on | 开机自启(同 enable)|
| hermeslink autostart off | 关闭自启(同 disable)|
| hermeslink logs | 查看 Link 日志 |
| hermeslink logs --gateway | 查看 Hermes 网关日志 |
| hermeslink logs -n 100 | 查看最近 100 条日志 |
| hermeslink version | 查看版本号 |
配置
hermeslink config set port 18642 # 修改监听端口(默认 18642)
hermeslink config set lan-host 192.168.1.10 # 手动指定局域网 IP(默认自动检测)
hermeslink config set language zh-CN # 语言:auto / en / zh-CN
hermeslink config set log-level debug # 日志级别:debug / info / warn / error配置文件位于 ~/.hermeslink/config.json。
API 参考
服务默认监听 http://0.0.0.0:18642。所有需要鉴权的接口均使用 Bearer Token(hlat_ 前缀)。
交互式 Swagger 文档:http://localhost:18642/api/docs
Token 说明
| Token | 前缀 | 有效期 | 用途 |
|-------|------|--------|------|
| Connect Token | 无前缀(base64url)| 5 分钟,一次性 | 兑换 access_token |
| Access Token | hlat_ | 2 小时 | 所有 API 请求 |
| Refresh Token | hlrt_ | 90 天 | 刷新 access_token |
无需鉴权
| 方法 | 路径 | 说明 |
|------|------|------|
| GET | /pair | 配对网页(浏览器打开) |
| GET | /api/v1/bootstrap | 服务基础信息,含 link_id、版本、能力 |
认证 / 设备
所有以下接口需要 Header:Authorization: Bearer hlat_xxx
| 方法 | 路径 | 说明 |
|------|------|------|
| GET | /api/v1/auth/me | 当前 Token 信息及设备信息 |
| POST | /api/v1/auth/device-session | 用 connect_token 换取 access/refresh token |
| POST | /api/v1/auth/refresh | 用 refresh_token 换新 access_token |
| POST | /api/v1/auth/logout | 撤销 refresh_token |
POST /api/v1/auth/device-session 的 Authorization 头需放 connect_token(不是 hlat_),Body:
{
"device_label": "我的设备",
"device_platform": "ios|android|web|cli",
"device_model": "可选,设备型号"
}响应:
{
"ok": true,
"device": { "device_id": "dev_xxx", "label": "我的设备", "platform": "ios" },
"access_token": { "token": "hlat_xxx", "expires_at": "2026-05-08T13:00:00Z" },
"refresh_token": { "token": "hlrt_xxx", "expires_at": "2026-08-06T12:00:00Z" }
}POST /api/v1/auth/refresh Body:
{ "refresh_token": "hlrt_xxx" }配对
| 方法 | 路径 | 说明 |
|------|------|------|
| GET | /api/v1/pairing/session | 查询配对会话状态(含 claimed 字段) |
| POST | /api/v1/pairing/claim | App 端用来完成配对 |
GET /api/v1/pairing/session 查询参数:?session_id=ps_xxx
POST /api/v1/pairing/claim Body:
{
"session_id": "ps_xxx",
"claim_token": "connect_token值",
"device_label": "My App",
"device_platform": "ios"
}系统状态
| 方法 | 路径 | 说明 |
|------|------|------|
| GET | /api/v1/status | 服务整体状态(版本、设备数、profiles 数量等) |
| GET | /api/v1/logs | 最近日志(?source=link\|gateway&limit=50) |
设备列表
| 方法 | 路径 | 说明 |
|------|------|------|
| GET | /api/v1/devices | 列出所有已配对设备 |
| PATCH | /api/v1/devices/:deviceId | 重命名设备({"label":"新名字"}) |
| DELETE | /api/v1/devices/:deviceId | 撤销设备(吊销 token) |
| DELETE | /api/v1/devices/:deviceId/app-listing | 从列表中隐藏已撤销设备 |
对话(Conversations)
活跃对话
| 方法 | 路径 | 说明 |
|------|------|------|
| GET | /api/v1/conversations | 列出活跃对话(?limit=20&cursor=xxx) |
| GET | /api/v1/conversations/search | 搜索活跃对话(?q=关键词) |
| POST | /api/v1/conversations | 新建对话 |
| DELETE | /api/v1/conversations | 批量删除对话({"conversation_ids":["conv_xxx"]}) |
| DELETE | /api/v1/conversations/:id | 删除单个对话 |
| GET | /api/v1/conversations/:id/messages | 获取对话消息列表(含 runtime 上下文信息) |
| POST | /api/v1/conversations/:id/messages | 发送消息 |
| GET | /api/v1/conversations/:id/events | SSE 实时事件流 |
| GET | /api/v1/conversations/events | 所有对话事件流(SSE) |
| PATCH | /api/v1/conversations/:id/title | 重命名对话({"title":"新标题"}) |
| PATCH | /api/v1/conversations/:id/model | 切换模型({"model_id":"xxx"}) |
| PATCH | /api/v1/conversations/:id/profile | 切换 profile |
| POST | /api/v1/conversations/:id/ack | 确认已读 |
| POST | /api/v1/conversations/:id/runs/:runId/cancel | 取消对话内的某次执行 |
| POST | /api/v1/conversations/:id/approvals/:approvalId/approve | 审批工具调用(允许,{"scope":"once\|session\|always"}) |
| POST | /api/v1/conversations/:id/approvals/:approvalId/deny | 审批工具调用(拒绝) |
| POST | /api/v1/conversations/:id/blobs | 上传附件 |
| GET | /api/v1/conversations/:id/blobs/:blobId | 下载附件 |
| DELETE | /api/v1/conversations/:id/blobs/:blobId | 删除附件 |
归档对话
| 方法 | 路径 | 说明 |
|------|------|------|
| GET | /api/v1/conversations/archived | 列出已归档对话(?limit=20&cursor=xxx) |
| GET | /api/v1/conversations/archived/search | 搜索已归档对话(?q=关键词) |
| POST | /api/v1/conversations/:id/archive | 归档对话(发送新消息时自动恢复为活跃) |
| POST | /api/v1/conversations/:id/unarchive | 取消归档 |
批量清理计划
| 方法 | 路径 | 说明 |
|------|------|------|
| POST | /api/v1/conversations/clear-plans | 创建批量删除计划({"target_status":"active\|archived"}) |
| GET | /api/v1/conversations/clear-plans/:planId | 查询计划状态 |
| POST | /api/v1/conversations/clear-plans/:planId/execute | 执行计划(批量删除) |
批量归档计划
| 方法 | 路径 | 说明 |
|------|------|------|
| POST | /api/v1/conversations/archive-plans | 创建批量归档计划({"exclude_conversation_ids":[]}) |
| GET | /api/v1/conversations/archive-plans/:planId | 查询计划状态 |
| POST | /api/v1/conversations/archive-plans/:planId/execute | 执行计划(批量归档) |
响应结构说明
ConversationSummary(对话列表每项):
{
"id": "conv_xxx",
"title": "对话标题",
"created_at": "2026-05-09T00:00:00.000Z",
"updated_at": "2026-05-09T00:00:00.000Z",
"last_event_seq": 12,
"usage": { "input_tokens": 100, "output_tokens": 200, "total_tokens": 300, "updated_at": "..." },
"profile": { "uid": "prof_xxx", "name": "default", "display_name": "default", "avatar_url": null },
"last_message": { "id": "msg_xxx", "role": "assistant", "content_preview": "消息摘要..." }
}GET /api/v1/conversations/:id/messages 响应新增 runtime 字段:
{
"ok": true,
"messages": [...],
"last_event_seq": 12,
"runtime": {
"profile": { "name": "default", "display_name": "default", "avatar_url": null },
"model": { "id": "claude-3-5-sonnet", "provider": "anthropic", "context_window": 200000 },
"context": { "input_tokens": 100, "output_tokens": 200, "total_tokens": 300, "usage_percent": 0, "source": "estimated" }
},
"page": { "limit": 50, "has_more_before": false, "has_more_after": false, "oldest_message_id": "...", "newest_message_id": "..." }
}LinkMessage(消息对象):
{
"id": "msg_xxx",
"schema_version": 1,
"conversation_id": "conv_xxx",
"role": "user|assistant|tool|system",
"status": "queued|streaming|completed|failed|cancelled",
"created_at": "...",
"updated_at": "...",
"sender": { "id": "app_user", "type": "human|agent|system|tool", "display_name": "Me" },
"parts": [{ "type": "text", "text": "消息内容" }],
"attachments": [],
"blocks": [],
"agent_events": [],
"approvals": []
}DELETE /api/v1/conversations/:id 响应新增字段:
{
"ok": true,
"conversation_id": "conv_xxx",
"hermes_deleted": false,
"deleted_at": "2026-05-09T00:00:00.000Z"
}统计
| 方法 | 路径 | 说明 |
|------|------|------|
| GET | /api/v1/statistics | 全局使用统计(?profile=xxx&profile_uid=xxx) |
| GET | /api/v1/statistics/usage | Token 用量统计(?days=7&from=2026-05-01&to=2026-05-08&model=xxx&profile=xxx) |
GET /api/v1/statistics 响应:
{
"ok": true,
"statistics": {
"conversations": { "total": 10, "active": 8, "archived": 1, "deleted": 1 },
"tokens": { "input_tokens": 5000, "output_tokens": 8000, "total_tokens": 13000 },
"messages": { "total": 120 },
"runs": { "total": 50 },
"models": { "total": 0 },
"profiles": { "total": 0 },
"skills": { "total": 0 },
"tools": { "total": 0 }
}
}模型(Models)
| 方法 | 路径 | 说明 |
|------|------|------|
| GET | /api/v1/models | 列出可用模型(来自 Hermes API Server,OpenAI 兼容格式) |
| GET | /api/v1/model-configs | 列出全局模型配置 |
| POST | /api/v1/model-configs | 新增全局模型配置 |
| PATCH | /api/v1/model-configs/defaults | 更新默认模型配置 |
| DELETE | /api/v1/model-configs | 删除全局模型配置 |
Profiles
| 方法 | 路径 | 说明 |
|------|------|------|
| GET | /api/v1/profiles | 列出所有 Profile 名称 |
| POST | /api/v1/profiles | 创建新 Profile(异步,返回 202) |
| PATCH | /api/v1/profiles/:name | 重命名({"name":"new-name"})或更新元数据 |
| DELETE | /api/v1/profiles/:name | 删除 Profile |
| GET | /api/v1/profiles/catalog | 完整目录(包含各 Profile 的 capabilities、permissions、modelConfigs)|
| GET | /api/v1/profile-creation/status | 查询创建进度 |
| GET | /api/v1/profile-creation/events | 创建进度 SSE 流 |
| GET | /api/v1/profiles/:name/status | Profile 状态(存在性、API Key 配置等) |
| GET | /api/v1/profiles/:name/statistics | Profile 的对话统计 |
| GET | /api/v1/profiles/:name/skills | 列出 Profile Skills(?include_disabled=true)|
| PATCH | /api/v1/profiles/:name/skills/:skillName | 启用/禁用 Skill({"enabled":true}) |
| GET | /api/v1/profiles/:name/memory | 查看记忆(USER.md + MEMORY.md) |
| POST | /api/v1/profiles/:name/memory/entries | 新增记忆条目({"target":"memory","content":"..."}) |
| PATCH | /api/v1/profiles/:name/memory/entries | 替换记忆条目({"target":"memory","match":"旧内容","content":"新内容"})|
| DELETE | /api/v1/profiles/:name/memory/entries | 删除记忆条目({"target":"memory","match":"匹配内容"})|
| DELETE | /api/v1/profiles/:name/memory | 重置记忆({"target":"memory\|user\|all"})|
| PATCH | /api/v1/profiles/:name/memory/settings | 更新记忆 Provider 设置 |
| PATCH | /api/v1/profiles/:name/memory/provider | 切换记忆 Provider({"provider":"built-in"})|
| GET | /api/v1/profiles/:name/permissions | 查看权限配置 |
| PATCH | /api/v1/profiles/:name/permissions | 更新权限配置 |
| GET | /api/v1/profiles/:name/tool-configs/:toolKey | 查看工具配置(toolKey:web / image_gen / stt / tts / messaging / homeassistant / rl)|
| PATCH | /api/v1/profiles/:name/tool-configs/:toolKey | 更新工具配置(同上 toolKey)|
| GET | /api/v1/profiles/:name/model-configs | 列出 Profile 的模型配置 |
| POST | /api/v1/profiles/:name/model-configs | 新增 Profile 的模型配置 |
| PATCH | /api/v1/profiles/:name/model-configs/defaults | 更新 Profile 默认模型 |
| DELETE | /api/v1/profiles/:name/model-configs | 删除 Profile 的模型配置 |
记忆 target 字段:"memory"(Agent 笔记,MEMORY.md)或 "user"(用户信息,USER.md)。
Cron Jobs(定时任务)
| 方法 | 路径 | 说明 |
|------|------|------|
| GET | /api/v1/cron-jobs | 汇总列出所有 Profile 的定时任务 |
| GET | /api/v1/profiles/:name/cron-jobs | 列出指定 Profile 的定时任务 |
| POST | /api/v1/profiles/:name/cron-jobs | 创建定时任务 |
| GET | /api/v1/profiles/:name/cron-jobs/:jobId | 查看定时任务详情 |
| PATCH | /api/v1/profiles/:name/cron-jobs/:jobId | 更新定时任务 |
| DELETE | /api/v1/profiles/:name/cron-jobs/:jobId | 删除定时任务 |
| POST | /api/v1/profiles/:name/cron-jobs/:jobId/pause | 暂停定时任务 |
| POST | /api/v1/profiles/:name/cron-jobs/:jobId/resume | 恢复定时任务 |
| POST | /api/v1/profiles/:name/cron-jobs/:jobId/run | 立即执行定时任务 |
Runs(执行任务)
| 方法 | 路径 | 说明 |
|------|------|------|
| POST | /api/v1/runs | 向 Hermes Agent 提交执行任务(返回 202) |
| GET | /api/v1/runs/:runId/events | 订阅执行事件流(SSE 代理) |
| POST | /api/v1/runs/:runId/cancel | 取消执行任务 |
POST /api/v1/runs Body:
{
"input": "请帮我整理 ~/Downloads 目录",
"profile": "default",
"instructions": "可选的系统指令",
"session_id": "可选的会话 ID",
"conversation_history": []
}响应(202):
{
"run_id": "run_xxx",
"fallback": false
}更新管理(Updates)
Hermes Agent 更新
| 方法 | 路径 | 说明 |
|------|------|------|
| GET | /api/v1/hermes/update-check | 检查 Hermes Agent 是否有新版本 |
| GET | /api/v1/hermes/update/status | 查询 Hermes 更新进度 |
| POST | /api/v1/hermes/update | 触发 Hermes Agent 更新 |
| GET | /api/v1/hermes/update/events | 更新进度 SSE 流 |
Link 自身更新
| 方法 | 路径 | 说明 |
|------|------|------|
| GET | /api/v1/link/update-check | 检查 Link 是否有新版本 |
| GET | /api/v1/link/update/status | 查询 Link 更新进度 |
| POST | /api/v1/link/update | 触发 Link 自更新({"version":"0.3.0"})|
| GET | /api/v1/link/update/events | 更新进度 SSE 流 |
系统(System)
| 方法 | 路径 | 说明 |
|------|------|------|
| GET | /api/v1/system/status | 系统详情(版本、自启状态、网络环境)|
| GET | /api/v1/system/version | 仅返回 Link 版本号 |
| POST | /api/v1/system/autostart/enable | 开启开机自启 |
| POST | /api/v1/system/autostart/disable | 关闭开机自启 |
| GET | /api/v1/system/logs | 最近 Link 日志 |
| GET | /api/v1/system/logs/gateway | 最近 Gateway 日志 |
| GET | /api/v1/system/updates | 查询可用更新(Hermes + Link 汇总)|
| POST | /api/v1/system/updates/dismiss | 忽略当前可用更新提示 |
错误响应格式
所有错误均返回:
{
"ok": false,
"error": {
"code": "error_code",
"message": "Human readable message"
}
}常见错误码:
| code | HTTP | 说明 |
|------|------|------|
| auth_required | 401 | 未提供 Authorization |
| device_access_token_invalid | 401 | access_token 已过期或无效 |
| auth_invalid | 401 | connect_token 无效或已用过 |
| pairing_session_not_found | 404 | 配对会话不存在 |
| pairing_session_expired | 404 | 配对会话已过期 |
| pairing_claim_mismatch | 409 | 配对 token 不匹配 |
| link_not_paired | 409 | 服务尚未分配 link_id |
调用示例
全流程脚本
#!/bin/bash
BASE="http://localhost:18642"
# Step 1: 生成配对 token
CONNECT=$(hermeslink pair 2>&1 | grep "Connect token:" | awk '{print $NF}')
echo "Connect token: $CONNECT"
# Step 2: 兑换 access_token 和 refresh_token
RESP=$(curl -s -X POST "$BASE/api/v1/auth/device-session" \
-H "Authorization: Bearer $CONNECT" \
-H "Content-Type: application/json" \
-d '{"device_label":"my-script","device_platform":"cli"}')
ACCESS=$(echo $RESP | python3 -c "import json,sys; print(json.load(sys.stdin)['access_token']['token'])")
REFRESH=$(echo $RESP | python3 -c "import json,sys; print(json.load(sys.stdin)['refresh_token']['token'])")
echo "Access: $ACCESS"
echo "Refresh: $REFRESH"
# Step 3: 查询状态
curl -s "$BASE/api/v1/status" -H "Authorization: Bearer $ACCESS" | python3 -m json.tool刷新 Token
curl -s -X POST http://localhost:18642/api/v1/auth/refresh \
-H "Content-Type: application/json" \
-d "{\"refresh_token\":\"$REFRESH\"}"查询设备列表
curl -s http://localhost:18642/api/v1/devices \
-H "Authorization: Bearer $ACCESS"查询对话列表
curl -s "http://localhost:18642/api/v1/conversations?limit=10" \
-H "Authorization: Bearer $ACCESS"开机自启
- macOS:通过 launchd(
~/Library/LaunchAgents/com.hermes.link.plist) - Linux:通过 systemd 用户服务或 XDG autostart
- Windows:通过 Startup 文件夹
hermeslink autostart on
hermeslink autostart off运行时文件
所有文件存储于 ~/.hermeslink/:
| 路径 | 说明 |
|------|------|
| config.json | 用户配置 |
| identity.json | 设备身份(ed25519 密钥对 + link_id)|
| credentials.json | 已配对设备的访问令牌 |
| app-connect-tokens.json | 待使用的配对 token(5 分钟有效)|
| conversations/ | 对话数据 |
| blobs/ | 文件附件 |
| pairing/ | 配对会话 |
| link.db | SQLite 数据库(统计信息)|
| logs/ | 日志文件 |
卸载 npm 包不会删除此目录,重新安装后仍可复用同一 link_id。
环境变量
| 变量 | 说明 |
|------|------|
| HERMESLINK_HOME | 覆盖运行时目录(默认 ~/.hermeslink)|
| HERMESLINK_LOG_LEVEL | 覆盖日志级别 |
| HERMESLINK_LANG | 覆盖语言(en / zh-CN)|
| HERMES_BIN | hermes 二进制路径(默认 hermes)|
| HERMESLINK_LISTEN_HOST | HTTP 监听地址(默认 0.0.0.0)|
开发调试
# 安装依赖
npm install
# 启动开发服务器 — 监听源码变化,自动编译并重启 daemon
npm run dev
# 生产构建
npm run build
# TypeScript 类型检查
npm run check服务运行后可访问 http://localhost:18642/api/v1/bootstrap 验证是否正常。
交互式 API 文档(Swagger UI):http://localhost:18642/api/docs
License
MIT
