dsh-archive-nudge
Verifieddsh-archive-nudge · v0.2.1 · MIT · Web UI
DeepSeek Harness plugin: a small archive-box icon next to sidebar session titles marks sessions that are worth archiving (idle too long, or the agent says the work is done). Reminds only, never archives for you.
Install
dsh plugin add dsh-archive-nudge Confirm the layer applied with dsh --profile default --dump-config — see the install guide.
Source
Tags
Creators
Readme
dsh-archive-nudge
English(README.md,随包附带) | 简体中文
一个 DeepSeek Harness 插件:在侧栏会话标题旁边挂一个小小的归档箱图标, 告诉你「这个会话大概已经办完了」——不用一个个点开,扫一眼就知道哪些会话可以归档。
只提醒,不替你归档:不弹窗、不点开会话、不改任何会话状态。 鼠标停上去看一句话理由。
截图
示意图只放在仓库里(docs/screenshot.png,源文件 docs/mockup.html):闲置的会话是灰色小箱子,
AI 判定的会话是琥珀色小箱子,悬停卡片重复那句理由。它是示意图 —— 会话标题是编的,不是真实截图 ——
也不在 npm 包里,所以这里不内嵌。
为什么要有它
会话列表越攒越长,慢慢就烂掉了。哪些会话是死的,你心里其实有数, 但要再找出来就得一路往下翻。这个插件只回答一个问题:这一条办完了没?
什么时候会出现
| 触发 | 判定 | 长相 |
|---|---|---|
| 闲置太久 | 最后一次活动早于 idleHours(默认 144 小时 = 6 天) |
灰色、半透明;悬停写「这个会话已经闲置 6 天,可以归档了」 |
| AI 自己判断 | AI 调用 mark_session_archivable 工具 |
琥珀色;悬停显示 AI 给的那句话 |
两个条件都只在这个会话行处于 idle(没有在跑、没有待审批)时才显示 —— 那个位置本来就是状态点的地方,归档行更是整格留空,所以永远不会打架。
鼠标停在该行上,悬停卡片里会把判定理由再写一遍:闲置了多久、生效阈值是多少小时; 如果是 AI 标记,还会写标记的时间与它给的理由。
「上下文快满」「轮数 / 花费多少」这两类信号没有单独实现:会话列表只拿得到 「闲置时长 / 标题 / 是否在跑」,要算 token 与轮数得把每条会话都激活一遍,代价太大。 AI 那一路本来就看得到自己的上下文用量,所以让它自己在那个时刻调用工具即可。
配置
只有一个文件:
%DSH_HOME%/archive-nudge/marks.json
(%DSH_HOME% 默认是 ~/.dsh。)
{
"config": { "idleHours": 144, "allowArchiveApi": false },
"marks": {
"<sessionId>": { "at": 1792775972791, "reason": "目标已交付,剩下的属于新任务" }
}
}
| 键 | 默认 | 含义 |
|---|---|---|
idleHours |
144 |
闲置多少小时出现灰色标记。0 = 只要一闲置就提示(自检图标时好用)。改完一分钟内生效 —— 侧栏每分钟拉一次。 |
allowArchiveApi |
false |
可选归档接口的总闸。也接受 true / 1 / "true"。 |
144是配合「autoArchiveDays = 7自动归档」这类插件取的:灰标提前一天亮起, 意思是「明天这条就没了」。不装那种插件的话,24~48更合适。marks里超过 30 天的条目会在下次读到时自动丢掉。- 写盘是原子写(先写临时文件再 rename),多窗口同时写也不会写出半个 JSON; 读到损坏的 JSON 会当空库处理,不会崩。
设置页
设置 → 可归档提醒 可以不用碰文件:
- 改
idleHours(离开输入框即保存,一分钟内生效); - 看所有 AI 标记(哪个会话、什么理由、什么时候标的);
- 单条清除或全部清除 —— 侧栏图标马上跟着消失。
设置页读写的是下面那两条写接口,所以 marks.json 仍然是唯一真相,手改也照样认。
同目录下还有 %DSH_HOME%/archive-nudge/nudge.log:一份操作日志,
超过 256 KB 滚动成 nudge.log.1(只留一份,不会无限长)。
日志里值得看的几行:boot: host half loaded …(确认新代码到底加载没有)、
tools available/unavailable、deny loopback …、batch archive …。
安装
# 从 npm 装(推荐 —— 这就是发布出去的包)
dsh plugin add --profile <profile> [email protected]
# 从 GitHub 装(只在你对这个仓库有访问权时可用 —— 仓库是私有的)
dsh plugin add --profile <profile> github:yuyu13251/dsh-archive-nudge#v0.2.1
手工安装(CLI 用不了的时候,比如桌面端独占着 profile):
- 把发布包解开(开发时直接复制这个仓库也行)放到
<DSH profile>/node_modules/dsh-archive-nudge,软链接 / junction 也可以, - 在 profile 的
package.json里把包名加进dsh.profile.bundles, - 重启 DSH(只改了浏览器半边的话,刷新一下页面就够)。
要求:DSH 0.2.x 的 Web 界面 + Node.js >= 22。插件没有运行时依赖,只用 Node 内置模块。
卸载
- 删掉
<DSH profile>/node_modules/dsh-archive-nudge, - 从 profile 的
package.json里去掉dsh.profile.bundles里的对应条目 (若当初是当依赖装的,再删dependencies里的那条), - 刷新页面 / 重启 DSH,
- 可选:删掉
%DSH_HOME%/archive-nudge/(标记与日志)。
隐私
- 数据全在本机:
%DSH_HOME%/archive-nudge/marks.json—— 会话 id + 一句话理由;%DSH_HOME%/archive-nudge/nudge.log—— 操作日志。
- 没有遥测、没有对外请求,也不读会话正文。插件从不打开会话的聊天数据。
- 所有写接口(
/config、/marks/clear和可选的归档接口)只接受本机请求; 归档接口默认关闭,否则返回403/503。 GET /marks与GET /config是只读、无门槛的(远端 Web UI 也要能读)。 换句话说:别把端口暴露到公网。会话 id 和你写的理由不算机密, 但也不适合对外转发。
HTTP 接口
给折腾的人和本机其他工具用:
| 路由 | 方法 | 门槛 | 用途 |
|---|---|---|---|
/dsh-archive-nudge/marks |
GET | 无(只读) | { ok, config, marks } |
/dsh-archive-nudge/config |
GET | 无(只读) | { ok, config } |
/dsh-archive-nudge/config |
POST | 仅本机 | {"idleHours": 12} 或 {"allowArchiveApi": true} |
/dsh-archive-nudge/marks/clear |
POST | 仅本机 | {"sessionIds": ["…"]} 或 {"all": true} |
/dsh-archive-nudge/archive |
POST | 本机 + allowArchiveApi + workspaceRegistry |
{"sessionIds": ["…"]} |
/dsh-archive-nudge/unarchive |
POST | 同上三道门 | {"sessionIds": ["…"]} |
归档接口走宿主的 workspaceRegistry.archiveSession / unarchiveSession,
所以有活动工作的会话会被宿主拒绝,并按 id 逐条返回 —— 一条失败不会炸掉整批。
归档成功时,插件会顺手把这个会话的「可归档」标记一起收掉(响应里的 marksCleared)。
增删路由要重启 DSH 才会注册;改配置值不用。
工具
mark_session_archivable { reason: string, clear?: boolean }
reason 会原样显示在侧栏图标的悬停提示里;clear: true 撤回这个会话的标记。
一个会话只留一条标记,重复调用只用最新理由。
兼容性与已知边界
- 面向 DSH 0.2.x 的 Web 界面,依赖公开插槽
sidebar.session.row.leading。 - 升级 DSH 后如果图标消失,先在浏览器控制台看
window.__archiveNudge还在不在 —— 它也没了说明浏览器半边没加载上,多半是插槽名字变了。 - 宿主半边只硬依赖
webServer。tools缺席 = 工具没注册;workspaceRegistry缺席 = 归档接口回503。这两种情况下侧栏提醒照常工作。 workspaceRegistry是异步加载的:它晚到也没关系,归档接口会自动开始能用,不用重启。- 界面文案有英文和简体中文两套。浏览器半边走 DSH 的
ctx.locale.register()注册 (设置页、悬停卡片、标签都跟随界面语言);宿主半边只有工具描述、工具回话与报错提示, 那边没有 locale 服务,按DSH_LOCALE/LANG选语言。
开发自检
npm run check # 等价于 node tools/check.mjs
npm test # 等价于 node --test "test/**/*.test.mjs"
check 把仓库里的 .js / .mjs 逐个过 node --check(只解析语法,不执行任何代码),
再确认 package.json 是合法 JSON。test 跑单测:数据层容错(缺文件 / 坏 JSON / 过期标记 /
原子写)、回环围栏与每条路由、工具、浏览器半边三处 slot、中英字典键对齐、闲置判定。
两者都不需要装依赖,Node 22+ 上直接能跑。
CI 用同两条命令,Node 22 与 24 各跑一遍(.github/workflows/check.yml)。
第三方声明
lib/index.js 里的回环信任围栏(loopback guard)改写移植自
@linxin666/dsh-session-archive
的 shared/host/loopback.ts,该包采用 Apache License 2.0。详见随包附带的 NOTICE 与 LICENSE-Apache-2.0.txt。其余代码为原创。
许可证
MIT —— 见随包附带的 LICENSE。