{"_id":"@dsh-pulse/dsh-hermes-bridge","name":"@dsh-pulse/dsh-hermes-bridge","dist-tags":{"latest":"0.1.0"},"versions":{"0.1.0":{"name":"@dsh-pulse/dsh-hermes-bridge","version":"0.1.0","description":"DSH ↔ WeChat bridge: inbound dispatch (WeChat → DSH agent, persistent per-cwd session pool) + outbound push (task progress → WeChat via hermes send, zero-LLM). 微信 ↔ DSH 双向桥：入站调度 + 出站推送，常驻会话复用。","type":"module","main":"lib/index.js","keywords":["deepseek-harness","dsh-plugin","wechat","hermes-agent","notify","bridge","cordis","ai-agent"],"repository":{"type":"git","url":"git+https://github.com/dsh-pulse/dsh-hermes-bridge.git"},"homepage":"https://github.com/dsh-pulse/dsh-hermes-bridge#readme","bugs":{"url":"https://github.com/dsh-pulse/dsh-hermes-bridge/issues"},"dsh":{"bundle":{"patch":"./cordis.yml"}},"license":"MIT","peerDependencies":{"@deepseek-ai/cordis":"^4.0.1"},"publishConfig":{"access":"public"},"_id":"@dsh-pulse/dsh-hermes-bridge@0.1.0","gitHead":"620c1573c61d1c1979ca8ed9291a20ccba601e88","_nodeVersion":"22.23.1","_npmVersion":"10.9.8","dist":{"integrity":"sha512-V8byXXdj3FgDzjttFB8iUCF7TMDkCZ3+RG7Z+QbbR84Nw/Kcy5nK4/2qwhYN/tyuRhbzux9xos/k2+7Qz73D0g==","shasum":"0998af82757a130f926ced832d559f4e07da46c6","tarball":"https://registry.npmjs.org/@dsh-pulse/dsh-hermes-bridge/-/dsh-hermes-bridge-0.1.0.tgz","fileCount":7,"unpackedSize":59854,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIHBa1xx01sqT2fljXMRvbiicy5JRxvcH1QOLyHOmjhx1AiEAh13jxMNpeXM8wVlIkVhg+gt4iNeIJh3lR6SQMrJDvL4="}]},"_npmUser":{"name":"dsh-daily","email":"1872895@qq.com"},"directories":{},"maintainers":[{"name":"dsh-daily","email":"1872895@qq.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/dsh-hermes-bridge_0.1.0_1787041213787_0.13823801220983056"},"_hasShrinkwrap":false}},"time":{"created":"2026-08-18T08:20:12.985Z","0.1.0":"2026-08-18T08:20:13.964Z","modified":"2026-08-18T08:20:14.641Z"},"maintainers":[{"name":"dsh-daily","email":"1872895@qq.com"}],"description":"DSH ↔ WeChat bridge: inbound dispatch (WeChat → DSH agent, persistent per-cwd session pool) + outbound push (task progress → WeChat via hermes send, zero-LLM). 微信 ↔ DSH 双向桥：入站调度 + 出站推送，常驻会话复用。","homepage":"https://github.com/dsh-pulse/dsh-hermes-bridge#readme","keywords":["deepseek-harness","dsh-plugin","wechat","hermes-agent","notify","bridge","cordis","ai-agent"],"repository":{"type":"git","url":"git+https://github.com/dsh-pulse/dsh-hermes-bridge.git"},"bugs":{"url":"https://github.com/dsh-pulse/dsh-hermes-bridge/issues"},"license":"MIT","readme":"# dsh-hermes-bridge\n\nDSH ↔ 微信双向桥插件：**入站调度（微信消息 → DSH agent 执行）+ 出站推送（任务进度/结果 → 微信）**，微信通道由 [Hermes](https://github.com/) gateway 承载。出站走 `hermes send` 零 LLM 消耗；按工作目录复用常驻会话，比一次性 headless 调用省 15–20× token。\n\n> **⚠️ 使用前必读——环境假设。** 本插件是基于**开发者本人的一套特定环境**开发验证的（见「环境假设」章节）。DSH 与 Hermes 的部署方式千奇百怪，本插件**无法**开箱即用于所有环境。请先逐条核对假设并适配你的配置，再期望它跑起来。\n\n## 为什么做（Why）\n\n「微信 → Hermes skill → `dsh --profile headless`」的单向手工链路能用，但每次冷启动烧 token、消息间丢失会话上下文、长任务跑完无法主动通知。本插件把这条链路产品化为 DSH 一等公民插件：\n\n- **会话复用**：agent 按工作目录常驻（`ctx.agents.create/resume + followup`），后续消息续接同一会话。\n- **自动回推**：每个任务推送 `接单 → 开跑 → 完成/失败`，带结构化 `改动/验证/遗留`。\n- **零 LLM 出站**：通知走 `hermes send`（iLink REST），不发模型请求；bot-token 平台无需 gateway 在线。\n- **Web UI 可见**：任务经 `ctx.jobs` 登记（无 job controller 时优雅降级）。\n\n## 工作方式（How it works）\n\n```\n微信 ──▶ Hermes gateway ──▶ dsh-run.sh（bridge 优先）──▶ POST 127.0.0.1:8643/v1/tasks\n                                                          │\n                                                          ▼\n                                          常驻会话池（按 cwd）\n                                                          │\n                                      DSH agent（全工具集, followup + whenIdle）\n                                                          │\n微信 ◀── hermes send ◀── 结构化结果回推 ◀──────────────────┘\n```\n\n入站：Hermes（或任意 HTTP 客户端）POST 任务到插件回环端点；插件分发给按 cwd 常驻的 agent 会话，并通过 `hermes send` 回推进度。bridge 不可用时，脚本自动回退一次性 `dsh --profile headless`。\n\n## 环境假设（务必逐条核对）\n\n本插件在**一台特定机器**上开发验证（部署细节见 `DEVELOPMENT.zh-CN.md`）。你的环境必然不同，请逐项适配：\n\n| 假设 | 本项目取值 | 你需适配的 |\n|---|---|---|\n| DSH 版本 | `0.1.0-rc.7`（Node ≥ 22） | `ctx.agents`/`ctx.agentPresets`/session API 是 **rc 阶段快照**——DSH 升级可能破坏兼容。钉住你运行的 rc 版本，或改代码。 |\n| DSH profile | **web profile**（常驻宿主，`dsh web` 保活插件） | 纯 headless 部署需自行保活插件（其 HTTP 回环必须长驻）。 |\n| DSH 模型配置 | `provider: tokenrhythm / model: deepseek-v4-flash-0731`（取自 `~/.dsh/settings.yaml` 的 `agent-default-model`） | `provider`/`model` 指向**你的**默认模型。persona 模板报 `{{model}} has no value` = 缺 `model`。 |\n| Hermes 安装 | venv 在 `~/.hermes/hermes-agent/venv/bin/hermes`，服务 `hermes-gateway.service`（用户 systemd） | `hermesBin` 配置指向你的 hermes CLI；服务名/端口可能不同。 |\n| 微信通道 | iLink 个人 bot 通道（`ilinkai.weixin.qq.com`，经 Hermes 接入） | 你的通道可能是 Telegram/Discord/Slack 等。**出站**只需 `hermes send --to <平台>:<目标>`——改 `pushTarget` 即可；**入站**触发（Hermes skill / hook）随通道而异。 |\n| `hermes send` 目标 | 经 `hermes send --list` 实测 | 自己跑 `hermes send --list`；chat id 是环境相关的。 |\n| HTTP 回环 | `127.0.0.1:8643` | 端口冲突改 `port`；host 硬编码回环（安全）。 |\n| 会话持久化 | `~/.dsh/sessions`（按用户） | 若你的 `DSH_HOME` 不同，resume 路径随之变化。 |\n\n**已知限制（非 bug）：**\n\n- **微信限流**：iLink 通道对 `sendmessage` 限频（`ret=-2` → 30s 冷却，Hermes 已处理）。推送突发会被丢弃/排队。保持推送频率低（插件每任务状态推一次，正常够用）。\n- **宿主无认证层**：`dsh web` 本身无认证（设计如此）。只跑回环，勿对外暴露。\n- **rc 阶段 API 漂移**：DSH 任何升级都需回归（见 `DEVELOPMENT.zh-CN.md` 需复验清单）。\n\n## 安装\n\n从 GitHub 分发（npm 发布暂缓，包名已预留 `@dsh-pulse/dsh-hermes-bridge`）：\n\n```bash\ngit clone https://github.com/dsh-pulse/dsh-hermes-bridge.git\ncd dsh-hermes-bridge && npm install   # 缺 peer 依赖时补装\n\n# 在 web profile patch 注册\ncat >> ~/.dsh/profiles/web/cordis.patch.yml <<'EOF'\n- insert:\n    - id: hermes-bridge\n      name: 'file:/绝对路径/dsh-hermes-bridge/lib/index.js'\n      config:\n        port: 8643\n        authToken: '${env.DSH_BRIDGE_TOKEN}'   # 必填——缺了插件拒绝激活\n        pushTarget: 'weixin:<chat_id>'          # 必填\n        hermesBin: '/path/to/hermes'            # 可选，默认 'hermes'\n        workspaceRoots: ['/path/to/workspace']  # 可选 cwd 白名单\nEOF\n```\n\n需要 `@deepseek-ai/cordis`（peer 依赖）——DSH 自带。插件面向 **web profile**（常驻宿主）设计，勿装进 headless。\n\n## 配置（Config schema）\n\n| key | 类型 | 默认 | 说明 |\n|---|---|---|---|\n| `port` | number | `8643` | 回环监听端口（host 硬编码 `127.0.0.1`） |\n| `authToken` | string | — | **必填**；每个请求校验 Bearer（恒定时间比较） |\n| `pushTarget` | string | — | **必填**；如 `weixin:<chat_id>`——由 `hermes send` 解析 |\n| `hermesBin` | string | `hermes` | hermes CLI 路径 |\n| `retries` | number | `1` | 出站推送重试次数 |\n| `maxTextLen` | number | `1500` | 推送文本截断 |\n| `preset` | string | `standard` | 会话 setup 挂载的 agent preset |\n| `provider` / `model` | string | dsh 默认 | agent 模型（对齐你的 `agent-default-model`） |\n| `workspaceRoots` | string[] | `[]` | cwd 白名单（realpath 前缀校验；空 = 不限制） |\n| `maxAgents` | number | `3` | 常驻会话上限（LRU 淘汰） |\n| `maxQueue` | number | `8` | 任务队列上限（满则 429） |\n| `taskTtlMs` | number | `86400000` | 已完成任务保留时长（24h） |\n\n## API（所有端点需 `Authorization: Bearer <token>`）\n\n| 端点 | 说明 |\n|---|---|\n| `POST /v1/tasks` | 入站任务 `{task, context?, cwd?, sessionId?, title?}` → `202 {taskId}` |\n| `GET /v1/tasks/:id` | 任务状态 + 结构化结果（`changes/verification/leftovers`） |\n| `POST /v1/tasks/:id/cancel` | 取消（queued → 立即 failed；running → 标记意图） |\n| `POST /v1/notify` | 纯推送 `{text}`（不经 agent） |\n| `GET /v1/health` | 存活检查 |\n\n回推消息（每状态一条，不刷屏）：\n\n```\n📥 已接单 br-xxxxxxxx\n🔧 开跑 br-xxxxxxxx\n✅ br-xxxxxxxx（6m12s）\n改动：…\n验证：…\n遗留：…\n```\n\n## 安全\n\n- **仅回环**：`server.listen(port, '127.0.0.1')`——host 硬编码，要暴露需改源码。\n- **必填认证**：`authToken` 必填，缺了拒绝激活。token 只存在于 profile patch（600 权限）或 env，绝不写进代码。\n- **cwd 白名单**：配置 `workspaceRoots` 后，白名单外路径在入站与 `executeTask` 内均被拒（`403`）。\n- **零 shell**：子进程一律 `spawn(args[])`——任务文本永不过 shell。\n- **出站脱敏**：推送前剥掉 `sk-`/`sk_tr_`/`ghp_` token 模式与 credentials 路径。\n\n> ⚠️ 本插件执行任意 DSH agent 工作（全工具权限）。只喂可信指令（微信侧纪律由你的 Hermes skill 层维持），且永不把 HTTP 端口暴露到回环之外。\n\n## 常见问题\n\n| 现象 | 原因 / 解决 |\n|---|---|\n| `prompt variable \"{{model}}\" has no value` | 缺 `agentOptions.model`——设置 `model`（对齐你的 `agent-default-model`）。 |\n| 任务报 `done` 但结果为空 | 看会话日志里 `turn/end` 的 `reason.kind == \"error\"`——插件现已把这类标为 `failed`；核对模型/provider。 |\n| `hermes send` 报 `Could not resolve target` | 跑 `hermes send --list`，把准确目标写进 `pushTarget`。 |\n| 端口 `EADDRINUSE` | 另一实例占用——改 `port`，或改代码后重启宿主一次（ESM 模块缓存）。 |\n| 微信推送丢失/排队 | iLink 限流（`ret=-2`，30s 冷却）——保持推送频率低。 |\n| Hermes 仍走 headless 不走 bridge | 插件经 `dsh-run.sh` 调用，该脚本**内部先试 bridge**（失败才回退）。若你的 skill 调别的脚本，指向 `dsh-run.sh`。见 `DEVELOPMENT.zh-CN.md`。 |\n\n## 开发文档\n\n见 **`DEVELOPMENT.zh-CN.md`**（中文）/ **`DEVELOPMENT.md`**（英文）——架构决策、踩坑与解决、测试策略、DSH 升级后需复验清单。\n\n## License\n\nMIT\n","readmeFilename":"README.zh-CN.md","_rev":"1-78c58b40efb300996e00e0968104c2ee"}