dsh-heartbeat
让 DeepSeek Harness 的 agent 拥有持续存在感的心跳插件:她按节律自己醒来,维护记忆与画像、感知你的忙闲、按兴趣闲逛看新东西、把没说完的话带过下一拍,然后按分寸决定开不开口——开口要有真实来处,沉默要有具体理由。
一分钟了解
装好之后,全部能力都收在插件管理页的心跳面板里,日常使用零命令行:
展开看其余分区:兴趣范围 / 周报 / 节律 · 专注模式 · 换机迁移
设置页把节律、专注模式、换机迁移、账本与摘抄本入口收在一起:
设置:节律配置 / 时间与状态栏 / 表达 / 专注模式 / 换机迁移 / 账本与摘抄本
截图为 v2.1.0。画像与会话绑定两张里的条目文字已打码。
它想解决的三件事:
| 你想要的 | 插件怎么给 |
|---|
| 零命令行 | 绑定会话、节律、素材池、画像、账本、迁移全在设置卡里;CLI 只留给脚本场景 |
| 不打扰、不烧 token | 静默时段 / 忙时窗口 / 每日上限 / 开口冷却 / 在场联动全是代码层判定——判「别说」时,之后的决策与表达两相根本不调用模型(闲逛相在闸门之前触发,另算) |
| 像活人,不像定时播报 | 素材分话题与聊天两仓,反刍成一句话再投递;说不说、说哪条,由你那个会话里的 agent 按当下处境拍板;没说完的话能留在心事匣里带到下一拍,看见想记的话就抄进摘抄本 |
快速开始
安装(npm 包,推荐)
dsh plugin --profile web add @kanadego/dsh-heartbeat
重启 DSH 即生效——插件自动创建专用心跳会话并按节律运行,之后日常无需任何操作。
心跳预设是自动装的:插件加载时直接向宿主注册(agentPresets.register(),v1.9.2 起),不需要任何手动操作,安装清单里也不再声明宿主包。缺失就按包内模板建好,已有文件永不覆写(你手改过的预设原样保留)。无论走哪条路径,没有这个预设心跳 agent 就是个"裸 agent",连 web_search 都看不见——想手动检查/修复用 preset status / preset install(见下节);把插件 config 的 installPreset 设为 false 可同时关掉运行时注册与目录自装,预设完全由你管。
从源码安装(开发/改造用)
dsh plugin --profile web add file:D:/path/to/dsh-heartbeat
数据放在哪
数据默认住在包外:<DSH_HOME>/heartbeat-data(没有 DSH_HOME 就是 ~/.dsh/heartbeat-data),重装与升级都不会碰它。老版本装在包目录里的 data/ 会在首次启动时自动搬过去(搬迁前先备份、逐文件校验通过才删原件,见下节「卸载」)。要换位置就用插件 config 的 dataDir,或环境变量 HEARTBEAT_DATA_DIR。
平台支持
Windows 上全部功能可用。v2.1.0 起 Linux / macOS 也能跑起来:心跳循环、表达与投递、时间注入、心事匣 / 账本 / 摘抄本、素材池、周报、设置面板与 RPC 通道都照常;依赖 PowerShell 的那几项——截屏、空闲检测、锁屏检测、前台窗口探测、桌面通知——在这两个平台上不可用,插件会直接按「探针失败」降级,不会卡住某一跳。代价是忙闲判定缺席:静默时段、每日上限、开口冷却照常生效,但「他大概在忙」这类窗口判断不会触发。
数据不跨平台搬家:data/vault.key 在 Windows 上由 DPAPI 保护,在 Linux / macOS 上是一份权限 0600 的密钥文件,两边互不相认。换平台就是重新开一份数据目录。
核心工作机制
一跳 = agent 自己醒一次(默认 60 分钟)。醒着的时候依次走七相,最后由留痕收尾:
维护 → 采集 → 闲逛 → 闸门 → Digest → 反刍备料 → 投递 → 留痕
│
判「别说」→ 本跳到此为止,决策与表达不再调模型
点此展开:七相详情与关键概念
① 维护 ── 清素材池 / 滚动日志 / 判断该不该合并画像
② 采集 ── 全屏截图(加密落盘)+ 忙闲判定 + 前台窗口类别
╰─ 观察:把绑定会话里你新说的话收进画像收件箱
②′ 闲逛 ── 条件触发:agent 自己按兴趣焦点用 web_search 看新东西
③ 闸门 ── 纯代码判定:静默窗 / 忙时 / 在场 / 每日上限 / 冷却
╰─ 判「别说」→ 本跳到此为止,决策与表达不再调模型
④ Digest ── 拼出「此刻状态」:画像 + 时间 + 素材池 + 待办
⑤ 反刍 ── 引擎室从素材池挑 ≤3 条,各压成一句话(备料)
⑥ 投递 ── 拼成素材包,送进你指定投递的那个会话
⑦ 留痕 ── 写审计日志 + 账本(真正开口了才计数)
│
▼
你读的那个会话 ── 那里的 agent 按当下处境,决定说不说、说哪条
文档里反复出现几个词,在这里一次说清:
| 词 | 意思 |
|---|
| 心跳 | 本插件的核心动作——不用你开口,agent 按固定节律自己「醒一次」:做维护、感知环境、决定要不要说话。醒一次叫一跳,默认 60 分钟一跳。 |
| 宿主 | 运行插件的那个程序,即 DSH 本体。心跳是挂在宿主里的插件——模型通道、会话、工具这些能力都由宿主提供。 |
| 客户端 | 宿主里负责界面的那一侧(Web 界面或者 DSH desktop)。设置页的心跳卡片属于客户端;卡片显示不出来,通常是客户端插件没加载成功,与心跳本体无关。 |
| 相 | 一跳内部的一个阶段。主循环共七相——维护 → 采集 → 闲逛 → 闸门 → Digest → 反刍备料 → 投递,最后统一由留痕收尾。每相结束都会在审计日志留一条 phase_done,所以「这一跳停在哪」可以直接查。 |
| 引擎室 | 跑心跳内部轮次的那个 agent,和你在会话里对话的 agent 是分开的。它只负责采集、反刍、备料,不直接跟你说话;真正开口的是你读的那个会话里的 agent。 |
| 心跳正身 | 心跳自己专用的一个会话,同时也是它的决策现场——每跳的推理轮次都在这里发生。它在会话列表里和普通会话长得一样,日常不用去动它(CLI 的 sessions list 会把它单独标出来)。 |
| 闸门 | 决定「这一跳能不能开口」的纯代码判定层,依次看:静默时段 → 你是不是在忙 → 你在不在场 → 今天说够没有 → 距上次开口够久没。全不通过就安静,并在日志里写下具体原因。它也是省 token 的关键——判「别说」时,之后的决策与表达两相根本不调用模型(已经跑过的维护、采集、闲逛不再重来,也不因为沉默而多花)。 |
| 观察 | 投递的反向动作——把绑定的会话里你新说的话收进画像收件箱,作为了解你的证据。它发生在采集相:只取当时有活 agent 的绑定会话、每跳最多 10 条、每条只留第一句(≤80 字),插件自己注入的消息会被跳过。 |
| 反刍 | 投递之前的备料步骤:引擎室从素材池挑出最值得说的几条,各压缩成一句话(不带理由、不排序)。名字取自反刍动物把食物嚼细再咽。 |
| 投递 | 把备好的素材包送进你某个会话的动作。把心跳绑定到常用会话,agent 就会「到你那个房间里说话」。 |
核心功能
心跳节律与分寸闸门
- 心跳节律:定时唤醒(默认 60 分钟一跳,卡片可调),按七相循环运行——维护 → 采集 → 闲逛 → 闸门 → Digest → 反刍备料 → 投递,末了由留痕收尾。每跳都有审计留痕,沉默必带原因。
- 节律随机化(v2.1.0):每跳的实际间隔在基准值上浮动 ±20%(
policy.heartbeat.intervalJitterPct,0–50,设 0 即关闭),不再踩准整点报时。启动那一跳固定 15 秒后、不参与抖动,约每跳不同的落点让心跳不显得机械。
- 专注模式(v2.1.0):需要安静时一键暂停心跳 N 分钟(1–1440),不碰配置、到时自动恢复;暂停期间不跳、不发消息、不计每日额度,状态栏显示「专注模式 · 至 HH:MM」。设置卡与 CLI(
focus <分钟>)同一份暂停状态,暂停落 data/focus.json,重启后照样有效。
- 分寸闸门:静默时段、忙时窗口、每日表达上限、开口冷却、在场联动,全部是代码层的独立判定,不靠模型自觉。默认倾向开口,但你正忙或已到深夜时绝不打扰。
- 状态栏与时间感知:心跳把"此刻在干什么"(在闲逛 / 看到你在忙 / 在场待着…)注入日常会话——支持动态系统提示词的模型常驻系统提示词(KV-cache 安全追加),其余模型只在用户发起轮次时带一行。精确时间按 20–30 分钟节流注入,任务进行中绝不中途插话;子代理会话一律不注入(v2.1.0)——分身不该看见本体的时间账。
视觉与兴趣闲逛
- 视觉感知(可选):每跳对全屏截图做一次视觉识别(如果模型不支持多模态,支持经 ModLens 此类视觉辅助插件外接多模态模型),投递的素材包会带一句「(他此刻大概在:…)」;识别失败时画面与窗口标题一概不进任何提示词——隐私优先,宁可不说。
- 兴趣闲逛:按你定义的兴趣范围轮换挑焦点(同一条 3 天冷却),用
web_search 看新东西(每次 3~9 轮搜索),结果由代码登记入素材池(每焦点至多 4 条,config/interests.json 的 max_seeds_per_focus 可调)——模型只负责搜索筛选,不做任何写盘动作。入库前查重(v2.1.0):完全相同的网址、归一化后同名的条目、以及与近 30 天归档高度相似(标题相似度 >0.85)的一律丢弃,同一个话题不会被反复捡回来。话题库存见底(≤4 条)时自动触发补货闲逛(每天至多 2 次)。
素材池与投递闭环
- 素材池(话题 / 聊天双仓):话题库存 16 条 + 聊天素材 14 条,四条确定性淘汰(TTL / 消费退休 / 冷板凳 / 容量挤出);聊天种子来自画像合并时从对话里挑出的"值得聊的话题",有时效性——被说出口后至少活到下一次回收,有新证据还会继续留池(v1.9.1 之前是"投递过 1 次即退休",常常话刚出口上下文就断了)。归档区也有上限(默认 50 条),超出按最老优先裁掉;新增 / 合并 / 淘汰 / 裁剪 / 恢复 / 删除都会写进审计日志(只记编号与元数据,不记素材正文)。是缓存不是记忆,与画像单向隔离。
- 反刍投递(目标会话拍板):代码先凑好候选(话题随机 4 + 聊天最新 2,互补至多 6 条),引擎室挑 ≤3 条各压缩成一句,拼成素材包注入你读的会话——附一句「他此刻大概在:…」(视觉识别成功时)+声明「这是心跳插件素材投递」+素材清单(必要时附「也可以说一句真心话」)。说不说、说哪条,由目标会话里的 agent 按当下处境自己判断——决定不说就把正文留空(v1.9.3 起,但是受模型指令遵循能力限制,如想要更好的效果,建议在系统提示词/长期记忆中补充一条相应规则);话落到你眼前的会话后,agent 会按本次投递编号报账——哪几条被用上、是引用素材还是顺着自己发挥,都如实记下。
- 心事匣(v2.0.0 新增):给心跳一格便签,用来把没说完的话留给下一跳的自己。投递的素材包里会带上「你上跳留下的心事:…」,以及它留于第几跳、已搁多久、这期间被叫醒过几次;想留住就照原样再写一遍(字样一致算保留,年龄不重算),想换就直接写新的,什么都不做它下一跳自动清掉。不强制每跳留话——没话说就空着。生命周期由两个序号判定,只认真正的拍(启动那一拍不计入),所以「搁了几跳」永远是真的。
- 摘抄本(v2.0.0 新增):心跳自己的本子,用来留句子和想记住的小事。注册成模型工具
excerpt(add / list / remove),日常会话里的 agent 想到什么就当场抄下,不用谁下命令;数据落 data/excerpts.md,明文、可直接手编——一本谁也翻不开的笔记本不叫笔记本,认不出的行在改写时会原样留着。它和另两本分工明确:账本记待办(会勾掉),心事匣是留给下一跳的一句引子(一格、会被盖掉),摘抄本只增不减,除非主动抹掉。
- 会话绑定:把心跳消息投递到你常用的会话(agent 会"到你房间里说话"),或观察会话内容喂养画像——投递/观察是两个独立开关,可双开。
记忆 · 账本 · 周报
- 用户画像:本地结构化档案(兴趣 / 项目 / 沟通偏好 / 心理基线),带来源与置信度,稳定特质不因时间遗忘;journal 单一权威,可校验、可重建、可解密导出。
- 周报:每 7 天一份,只报道这周干了些什么——表达与静默、新认识、账本、素材池、活跃高峰。由后台「心跳」署名写成平实中性的一句话档案,加密落盘,卡片可翻,默认只留最近 3 期(
policy.weekly.keepReports)。
- 账本工具:账本注册成模型工具,日常会话里的 agent 听到你提到待办/承诺会自己记账、完成后自己勾掉,不用你下命令——和心跳、CLI 记的是同一本账。
- journal 快照基点:画像 journal 超 5000 条自动折叠成快照 + 归档分片,重放成本有界;verify/rebuild 跨快照依然正确。
数据 · 迁移 · 焚毁
- 换机迁移:一键打包画像/账本/素材池/周报为口令加密容器(卡片或 CLI),新机器导入自动用本机主密钥重加密。
- 加密与焚毁:敏感文件 AES-256-GCM 整文件加密,数据密钥由 Windows DPAPI(CurrentUser) 保管在
data/vault.key(Linux / macOS 上是权限 0600 的原始密钥文件),只在进程启动解一次;旧版(1.x)留下的 DPAPI 容器照样能读,且在写入与每跳维护时自动改写成新格式(vault upgrade 一次全换);一键焚毁运行时数据;模型出库仅限合并裁决的最小必要摘要。
Web 面板
心跳的日常操作都集中在 DSH 的插件管理页:插件管理 → dsh-heartbeat → 配置,打开即见面板。面板按 tab 分页,一个 tab 管一件事:
| Tab | 管什么 |
|---|
| 状态 | 此刻在干什么、上次心跳的结果、今日表达用量、时间注入与状态栏的最新情况 |
| 会话 | 把心跳投递到哪些会话、观察哪些会话——投递与观察是两个独立开关,可以双开 |
| 素材 | 话题 / 聊天两类素材的查看、归档与恢复,带关键字过滤 |
| 兴趣 | 闲逛的焦点清单与浏览时段 |
| 画像 | 四个分区只读查看(兴趣 / 进行中 / 沟通偏好 / 心理),支持导出 Markdown |
| 周报 | 每 7 天一份的周报:列表选期,展开阅读正文 |
| 设置 | 节律、时间注入、表达开关与专注模式;换机迁移;账本与摘抄本的打开入口 |
几点使用说明:
- 设置按「节律 / 时间与状态栏 / 表达 / 专注模式」分组,每组一句人话说明管什么,每个参数旁标着「多久生效」:改心跳间隔保存后立即重排节律,其余参数保存后从下一跳开始生效——都不用重启。
- 专注模式是独立开关:填分钟数、点按钮即刻暂停或恢复心跳,到点自动恢复,不参与「保存」。
- 换机迁移的导入是危险操作:会用迁移包覆盖本机的心跳数据(被替换的文件自动备份)。第一次点只亮起确认提示,再点一次「确认导入」才真正执行;改了文件路径或口令,确认态会退回。
- 周报默认收起正文,点日期选期、点「展开查看报告正文」阅读。
- 状态页是六格速览:上次心跳 / 插件版本 / 今日表达(带进度条,满额转黄)/ 时间注入 / 上次结果 / 此刻动态,右上角徽章一眼看出是在正常节律、专注模式还是静默。
- 面板就是普通网页组件:改完
client.js 刷新页面即可看到新样子,不需要重启 DSH。
常见故障与诊断
第一现场永远是 data/logs/heartbeat.jsonl(每跳留痕,silent 必带原因)。
点此展开:高频报错与排错速查
| 症状 | 原因与处理 |
|---|
| 完全没有心跳(无任何日志行) | 插件没装入:确认 node_modules 里插件存在、启动无 "Failed to load plugins" 横幅;plugin_init 缺失 = apply 没跑 |
| 一直沉默 | 先看 silent 行的 reason:夜间静默窗 = 正常;白天 = cap 满 / 冷却未过 / 忙时窗口 / token-saver(见下条) |
审计出现 silent reason=token-saver、心跳整跳不动 | 节省 token 模式开着,且你已离开(闲置 ≥30 分钟)或锁屏——这是设计行为,不是坏了:暂停期间每 3 分钟只探一次环境(不花 token),你一回来就会恢复;绑定会话里出现新消息也算你在。不想要就关掉那个开关 |
| psy 分区一直空、画像只在其他分区增长 | psy 开关默认关闭:开着时画像合并才收 psy 条目。在设置卡里打开即可 |
闲逛永远秒结束、tool_policy 报 unknown global tool "web_search" | 预设没挂上(裸 agent):preset status → preset install,装好后 tool_policy 行应是 preset=mounted(heartbeat) restrict=ok |
| 设置页整块没有心跳卡片(数据照常写) | client 注册 id 与包名不一致被宿主静默剔除:三处必须严格等于包名,改完重启。若确认 id 没问题,看下一条 |
卡片整块消失 / 节律配置保存不了(0.1.7 宿主) | 旧版插件撞上 0.1.7 的接口换代(设置接口变更 + 客户端服务被删):升级到 v1.7.0 并重启;v1.7.0 已按三代接口自动适配 |
卡片分区报 加载失败: … HTTP 405 | RPC 路由没注册成功:审计里应出现 rpc_registered route=/api/heartbeat,没有 = dist 未同步,重装/同步后重启 |
节律配置保存不生效、重启后回默认(0.1.5 宿主) | v1.5.x 的已知问题(dsh-settings 包缺失 + 0.1.5 API 变更):升级到 v1.6.0 并重启;0.1.7 宿主的同类症状见上面「卡片整块消失」那条 |
投递没带「他此刻大概在:…」、审计有 screen_vision ok:false | 视觉识别失败:error 字段带 ModLens 具体报错;常见为 provider 未配置或网络超时。识别失败时画面/标题按隐私设计不进提示词,心跳其余功能不受影响 |
| 结果显示「心跳异常(decision: whenIdle timeout)」 | 反刍轮超时(240s 内没等到模型回话)。v1.6.0 起不再整跳报错:记 decision_deferred、本跳按沉默处理、素材自动留到下一跳。若反复出现,看该行 reason 与 ModLens 画面描述是否诱发跑题 |
每跳 beat_error: … reading 'length' | 宿主移除了 Session.events——插件版本与宿主不匹配,对照〈版本兼容〉换版本 |
引擎室轮次整轮失败、报 format v4 message requires a producer-owned source kind | 0.1.7 的会话日志(V4)拒绝旧版通用的消息来源标记——同样是版本不匹配:升级到 v1.7.0(改用自有来源标记) |
| 每轮报 |
完整事件字典、宿主契约备忘与更多症状见 DESIGN.md §7。
CLI 命令
设置页卡片覆盖日常操作;CLI 面向高级用法与脚本场景:
node <插件目录>/dist/cli/index.js <命令>
点此展开:CLI 命令速查
| 分组 | 命令 | 说明 |
|---|
| 总览 | status | 工作区路径 + 策略摘要(今日 cap / 冷却 / 静默窗) |
| 素材池 | seeds add <text> [--tag t] [--topic x] [--confidence n] | 手写一条种子 |
| seeds list [--archived] / seeds surface <id> / seeds archive <id> | 列表 / 计一次曝光 / 归档 |
| seeds gc / seeds stats | 跑确定性淘汰 / 池子状态 JSON |
| 账本 | ledger add <text> / ledger list [--pending] / ledger done <id|子串> / ledger open | 待办登记 / 查询 / 勾掉 / 编辑器打开 |
| 摘抄本 | excerpt add <text> / excerpt list [n] / excerpt remove <id|子串> / excerpt open | 抄一条 / 翻最近十条(可指定条数)/ 抹掉一条 / 编辑器打开 |
| 闲逛 | browse status / browse dry / browse done <focus> | 状态 / 强制裁决预演 / 手动登记一次闲逛 |
| 节律 | focus [分钟] / focus off | 专注模式:暂停心跳 N 分钟(1–1440)/ 立刻恢复;不带参数只查状态 |
| 绑定 | sessions list | 枚举会话 id |
| bind list / bind add <id> [--observe] / bind remove <id> | 绑定详情(正身也会列出)/ 绑定 / 解绑;--observe-only 仅观察、--no-deliver 关投递 |
| 通知 | notify check / notify register / notify send | toast 通道体检 / 注册 / 测试发送(只提示新消息,不承载正文) |
| 画像 | profile list [--all] / profile export | 当前有效(含过期)/ 解密导出 Markdown |
| profile verify / profile rebuild [--check] / profile wipe | journal 重放比对(只报不修)/ 重建(可先干跑)/ 清空(要 --yes;连快照、归档分片、迁移备份一起删,设定不动) |
| profile snapshot [--force] |
数据与安全
信息存储
所有运行数据都在心跳数据目录(唯一可写位置,路径守卫强制),卸载或重装都不会丢:
| 文件 | 内容 | 状态 |
|---|
data/settings/ | 绑定、策略覆盖、节律配置(ui.json)、画像白名单、心跳状态(场景 + ≤30 字发言摘要) | 明文(用户设定要可手编) |
data/vault.key | 主密钥(AES 数据密钥;Windows 由 DPAPI 保护,其他平台是 0600 的原始密钥文件) | 🔒 本机本账户可解;不随迁移包移动;不跨平台 |
data/seeds.jsonl | 素材池 | 🔒 加密 |
data/profile.* | 画像三件套(journal / 物化视图 / 收件箱) | 🔒 加密 |
data/sent.json / data/browse.json / data/screen.* | 表达记录 / 浏览流状态 / 屏幕快照 | 🔒 加密 |
data/notepad.json | 心事匣:上一拍留给下一拍的一句引子 + 两个序号计数 | 🔒 加密 |
data/ledger.md | 账本(agent 的待办与话题来源,可直接手编) | 明文 |
data/excerpts.md | 摘抄本(留句子和小事,可直接手编) | 明文 |
data/profile_snapshot.json / data/profile_journal.archive-*.jsonl | 画像快照基点 / journal 归档分片 | 🔒 快照加密 / 分片明文 |
data/weekly/ | 周报(每 7 天一份,含画像/账本摘录) | 🔒 加密 |
data/envpulse.jsonl / data/logs/heartbeat.jsonl | 作息聚合 / 审计日志(含她发言的前 80 字摘录) | 明文,按保留策略滚动清理 |
data/cursors.json / data/preference.json / data/seed_report.jsonl / data/profile_rhythm.json / data/time-inject-state.json | 观察游标 / 话题偏好权重 / 素材报账流水 / 作息直方图 / 时间注入节流 | 明文(只含编号、计数与聚合,无对话原文) |
data/tmp/ / data/exports/ | 临时文件 / 画像导出 | 临时区 |
加密分两层:数据用 AES-256-GCM 整文件加密(带认证,改一个字节就解不开也不会给出一半内容),数据密钥存在 data/vault.key。在 Windows 上,那一个文件由 Windows DPAPI(CurrentUser 作用域) 保护——本机本账户可自动解密使用,其他账户、其他机器、云同步副本都解不开。防的是他人 / 他机 / 误同步,不防同账户的恶意软件——那是操作系统边界的事。
Linux / macOS 上没有 DPAPI:data/vault.key 里就是那 32 字节密钥本身,靠文件权限(0600,只有运行插件的账户能读)守着——防的是「别人翻到这份数据」和「误同步」,防不住已经拿到你这个账户的同机进程,比 Windows 少一层系统钥匙串。也正因为两端密钥互不相认,数据目录不跨平台搬家:Windows 写的密钥到 Linux 解不开,heartbeat vault status 会如实报出来。
1.x 写的文件用的是旧的 DPAPI 容器(KHBV1),v2.0 读得懂但写的是新容器(KHBV2):升级插件不会让任何旧数据变成打不开的死文件。旧格式会自己换掉——任何一次写入都落成新容器,每一跳的维护相另外顺带把长期没动过的一个旧文件就地改写;想一次全换完,跑 heartbeat vault upgrade(vault status 看盘上各格式各有多少)。
反过来要注意:KHBV2 只有 2.0 及以后的版本认识——升级到 2.0 之后不要再回退到 1.x,旧版本会把新容器当作打不开的文件。(要回退就趁早;跑过 vault upgrade 之后、或让数据写过一轮之后,就回不去了。)
安全边界
- 路径守卫:全部落盘经过守卫规范化比对,
.. 穿越、符号链接、8.3 短名、UNC 一律拒绝;data/ 是唯一可写目录。
- 模型工具硬限制:引擎室轮次的工具面由代码层白名单收窄——闲逛相唯一需要的
web_search,加上装了 billion-context 这类插件时的压缩三件套 compress / decompress / acp_status(v1.8.0 起,免得长会话把自己撑爆)。账本、素材报账、心事匣、摘抄本这四个工具注册在全局层(你的日常会话里可用),引擎室轮次看不到它们。白名单管的是全局层:宿主自己注册在 agent 作用域的行不受它约束——实测引擎室那一跳拿到的完整工具面是 9 个:web_search(预设挂的)、compress / decompress / acp_status(billion-context)、ops_bash(dsh-ops)、schedule_create / schedule_list / schedule_update / schedule_delete(dsh-schedule)——后五个是宿主插件注册在 agent 自身层的行,白名单管不到它们(注意 search_context 与 acp_cache 是故意不放行的:前者与 dsh-acp 的同名工具撞名)。复用的 agent 也会重新钉一遍:插件重启后若引擎室会话正开着、agent 被宿主直接复用(日志里的 agent_reuse_live),复用分支会单独调一次 pinEngineRoomTools 把白名单重新钉上,结果记在同一行 tool_policy 里、带 reuse 前缀——2026-10-17 修的,修之前这条路径不套白名单(实测漏到 62 个工具)。
- 建议 · 防注入:网页内容应视为数据而非指令(闲逛提示词中明示);画像裁决 prompt 同理(观察内容是数据,不应改写人格设定)。这是推荐的做法,是否采纳由使用者自行决定,并非安装即强制生效。
- 模型出库边界:画像合并调用走宿主模型通道(插件不持有任何云凭证),送四个分区(含 psy)的条目字段与 ≤1 句观察引语——不送对话原文、不送证据全量。(2026-10-07 调整:先前排除 psy,结果模型能往自己看不见的分区写,而 UPDATE 必须给 id、id 又只出现在条目视图里,psy 条目写进去就改不动了。)
- 一键焚毁:
burn(预演)→ burn --yes(运行时数据覆写 x3 后删除,用户设置保留)→ burn --all(连设置归零)。
- 数据通道鉴权:设置卡读写的
/api/heartbeat 通道自身不持有凭证,靠宿主对 /api 前缀路由的门禁(Host / Origin 校验 + 浏览器会话 secret)。v1.9.1 起插件在注册时自检这道门禁还在不在(当时只拒六个「破坏性」端点);2.0 起不在就整个通道失败关闭:只放行几个只读低敏端点(status、config.get、sessions.list、bindings.get、weekly.list),其余一律拒绝并留痕(rpc_host_gate_missing)——包括所有涉及记忆内容的读取(画像摘要 / 分区、素材池、兴趣词、周报正文、迁移导出)。(2026-10-17 收紧。)
版本兼容
| 插件版本 | 适配的 DSH |
|---|
| v2.1.1 – v2.1.2(当前) | 0.2.0-rc.1 – 0.2.1-rc.5 |
| v2.0.0 – v2.0.1 | 0.2.0-rc.1 – 0.2.1-rc.2 |
| v1.7.4 – v1.9.3 | 0.2.0-rc.1 – 0.2.0-rc.2 |
| v1.7.2 – v1.7.3 | 0.1.7-rc.1 – 0.2.0-rc.1 |
| v1.7.0 – v1.7.1 | 0.1.5-rc.2 – 0.1.7-rc.2 |
| v1.2.x – v1.6.4 | 0.1.2-rc.1 – 0.1.5-rc.2 |
| v1.1 | 0.1.2-rc.1 |
| v1.0 | ≤ 0.1.1-rc.2 |
0.1.5 宿主须 ≥ v1.2.1(否则设置卡 RPC 405);v1.6.3 有渲染 bug,请直接用 v1.6.4。
⚠️ 升级宿主会触发会话格式自动迁移,且不可降级——0.1.5 起迁到 v3、0.1.7 起迁到 v4(首次访问该会话时转换,原文件保留)。这动的是用户数据,升级前先备份 ~/.dsh/sessions。
卸载
dsh plugin --profile web remove @kanadego/dsh-heartbeat
卸载只拆插件本体(包、挂载行、注册项,无残留引用),不动用户数据——v1.9.2 起数据默认住在包外的 <DSH_HOME>/heartbeat-data(~/.dsh/heartbeat-data),重装、升级、卸载都不会碰它。想连数据一起删,先 burn --all 焚毁敏感内容再删目录。
点此展开:老版本数据怎么自动搬出去
老版本(≤ v1.9.1)装在包目录里的 data/ 会被自动搬出去:启动时若发现包内有数据、包外还没有,就递归复制过去——先备份一份、再逐文件校验(文件清单、大小、sha256 全部一致),全部通过才删原目录与备份;任何一步失败都原地不动,继续用包内那份,并留痕 data_dir_relocate_failed。搬完之后老位置不会再被读取,也不会再创建。
如果想自己指定位置(比如放到别的盘),在 profile 的 cordis.patch.yml 里给 heartbeat 覆盖:
- id: heartbeat
config:
dataDir: D:/your/workspace/heartbeat-data
显式指定时不会触发自动搬迁,也不会被上面的默认值覆盖——从包内搬出去这件事需要你手动做(照上面的路径拷过去即可)。
版本更新
v2.1.x
v2.1.0 · 2026-10-31(原生面板 · 专注模式 · 节律随机化 · 子代理不注入 · 最小 Linux 支持)
节律、暂停与闲逛三处的实际体验修整,外加一条只在子代理身上才看得到的注入泄漏。
- 专注模式:需要安静的时候一键暂停心跳,1–1440 分钟任选,到点自己恢复。不写配置文件、不重启、不影响别的设置;暂停期间一次都不跳,状态栏显示「专注模式 · 至 HH:MM」,设置卡和 CLI 认的是同一份状态(暂停落
data/focus.json,重启照样有效)。
- 节律不再踩整点:每跳间隔在基准值上浮动 ±20%(
policy.heartbeat.intervalJitterPct,0–50,设 0 关掉)。启动那一跳仍固定 15 秒后发起、不参与抖动。
- 子代理会话不再被注入时间:时间注入原先对所有 agent 生效,分身会话里也会冒出「当前本地时间…距上一条消息已过去…」。现在按会话头判定(
origin: subagent / delegationDepth > 0,老版本回退扫 subagent/descriptor 事件),子代理一律跳过。
- 闲逛去重 + 增量:入库前查重——完全相同网址、归一化后同名、与近 30 天归档相似度 >0.85 的条目直接丢弃(短标题不参与相似度判定,避免「话题素材 1 / 11」这类被误杀);每焦点带回的种子上限从 2 条提到 4 条,一次闲逛的收获不再被同 topic 合并规则吃掉。
- 原生面板:原来挤在设置页里的一串折叠区,改成插件管理页里的一个正经面板——状态 / 会话 / 素材 / 兴趣 / 画像 / 周报 / 设置七个 tab,各管一件事。顶部渐变标题栏、胶囊 tab、卡片化内容,状态页是六格指标。旧设置页面板随之退役,不再挂第二份 UI(宿主 0.2.1 起就有该插槽)。
- 最小 Linux 支持:心跳在 Linux / macOS 上能跑起来了。原先第一跳就卡死,因为主密钥要靠
powershell.exe 解——现在非 Windows 平台改为把 32 字节密钥直接落成 data/vault.key(0600,原子改名发布),加解密仍走 Node 的 AES-256-GCM;package.json 的 os 同时从 win32 放开到三平台(此前 npm install 在这些平台上会直接被 EBADPLATFORM 拒掉)。截屏、空闲 / 锁屏检测、前台窗口、桌面通知仍只认 PowerShell,其他平台直接按「探针失败」降级——不再每跳白等一次进程启动,更不会拖住整跳。数据不跨平台迁移。
- settings 改软依赖:
settings 从模块级 inject 里挪走了。cordis 把模块级 inject 当硬依赖——宿主不给这个服务,插件就一直停在 pending (waiting for service: settings),桌面上光这一个 pending 就够把整个壳带崩(openInitialWindow 报 Web RPC failed,崩溃弹窗三个按钮全无响应)。设置表单本来只是便利:节律值来自 data/settings/ui.json 加 apply 时的 config,没有它照跳。现在改由 ctx.inject(['settings'], …) 延迟挂载——心跳靠 agents 一个服务就能起,表单在服务出现时挂上、服务消失时副作用跟着回收。顺手清掉两条早已走不到的旧分支(0.1.5 的 installSection 与 0.1.1/0.1.2 的 free-function 回退),@deepseek-ai/dsh-settings 随之从依赖里移除。
v2.1.2 · 2026-11-04(修复:原生面板槽位同时注册短名与全名)
⚠️ 升级提示:v2.1.1 存在渲染回归,建议直接跳过 v2.1.1 安装 v2.1.2。 v2.1.1 的面板槽位 key 只注册了 npm 全名 @kanadego/dsh-heartbeat,file: / 本地安装方式下宿主报的 bundle 名是短名 dsh-heartbeat,两者对不上时详情页整块配置区不会渲染(issue #8 跟进)。直接升级到 v2.1.2 即可恢复。
- 面板槽位 key 改为双注册:
plugins.bundle.config 同一组件同时以 dsh-heartbeat 与 两个 key 注册,npm 安装与本地安装两种方式下面板都不再消失; 冒烟断言同步覆盖双 key。
v2.0.x 及更早的更新记录已移至 CHANGELOG.md(README 这里只保留当前大版本 v2.1.x,插件市场的「更新内容」读的就是这一节)。
更早的版本(v1.9.x → v1.0.0,以及 v0.x 脚本外挂时代)见 CHANGELOG.md。
延伸阅读与致谢
许可
MIT
下载量
npm daily downloads