DeepSeek Harness 插件

mzzsfy/dsh-plugin#dsh-session-manager

Star 数 ★ 0 下载量(近 30 天) 1,910 分类 会话与消息 收录于 2026-09-18 npm @mzzsfy/dsh-session-manager

会话管理:超期会话自动归档(阈值可配),归档面板支持取消归档,删除移入系统回收站可还原。

安装

# npm 包(预构建)

dsh plugin --profile web add @mzzsfy/dsh-session-manager

# GitHub 源码(首次需按提示配置 allowBuilds 构建授权后重试)

dsh plugin --profile web add github:mzzsfy/dsh-plugin#path:/packages/dsh-session-manager

装任何插件都等于在你的机器上跑第三方代码,权限和你本人一样大——能读你的文件、用你的凭据、访问网络,工具审批管不到它。GitHub 来源的插件还会在安装时执行构建脚本——pnpm 默认拦截,所以安装可能停在 ERR_PNPM_GIT_DEP_PREPARE_NOT_ALLOWEDERR_PNPM_IGNORED_BUILDS;dsh 会打印出需要添加的确切键名,把它加进该 profile 的 pnpm-workspace.yamlallowBuilds 下,重跑一次即可装上。放行构建本身就是一次信任判断:请只安装可信来源,并尽量锁定 commit(github:owner/repo#sha)。

README

DeepSeek Harness 会话生命周期管理插件:自动归档 + 归档面板 + 归档删除 + 回收站还原重挂载。

历史输入浮层、插话撤回与对话分叉已迁至独立插件 dsh-context-manager(会话上下文管理);工作区文件夹运行标记见 dsh-turn-notify

功能

  • 自动归档:host 半区对超期会话走官方 workspace.archiveSession 通道,三个触发源共用同一评估与门闩:新会话创建(session/created,按该会话所属工作区限定)、settings 就绪后的启动补扫(全量,清掉停机期间积压)、每日周期轮(全量,经宿主 timer 服务固定短 tick + 到期判断)。幂等:已归档会话不参与评估。阈值 autoArchiveDays 默认 7,0 关闭;周期间隔 autoArchiveIntervalHours 默认 24,0 关闭周期轮,变更经周期 tick 对账(关闭即时暂停、重启用最迟下个 tick 生效、缩短经锚定钳制前移,最长等新间隔而非等满旧周期)。评估筛选:createdAt 纯内存预筛 + 已归档跳过 + stat 后活跃度判定,locate 缺失(第三方后端)与产物不可读的会话一律跳过,宁可漏归档不可误归档。经 settings 命名空间 session-manager 注册(schema 拒绝负数与非整数)。timer 为软依赖:宿主定时服务不可用时仅周期轮停用,面板顶部提示,插件其余能力不受影响。
  • 自动归档配置:归档面板「已删除」区下方的配置行,阈值天数与检查周期小时数两个数字输入,失焦或 Enter 单字段即时提交,非法输入前端拦截不发请求,服务端失败回读生效值回滚;读写经本插件 GET/POST /api/session-manager/auto-archive(POST 部分更新,仅接受出现且为非负整数的字段,空字段拒绝),值存宿主 settings 与评估逻辑同源,0 = 关闭,GET 返回含默认回退的当前生效值。配置行的行为说明经原生 title 悬停展示(设置侧栏为滚动容器,CSS 气泡会被 overflow 裁剪,故不做自绘气泡),文案由源码契约测试锁定。
  • 归档面板:设置页「会话归档」分区,数据为 client 侧 session.list 行 ∩ workspaces.follow 归档快照的交集,按更新时间倒序;主列表只展开最近 ARCHIVE_PAGE_SIZE(100)条,列表尾部「按工作区浏览」按钮直接进入二级视图查看全部(主列表不翻页,防归档集合无限增长拖垮渲染)。二级视图:无搜索词时按工作区分组(组间按组内最新活跃倒序,分组默认收起,展开即见组内首页并可继续翻页,workspace 假值并入「未分组」组);输入搜索词后平铺展示标题命中(不区分大小写子串,标题缺失回退会话 id 天然可搜)的全部归档会话并显示匹配计数,同样分页。行内标题前显示所属工作区徽标——映射优先走 workspace 账本(sessionIds,与官方 dsh-client-ui-workspace 的 workspaceBySession 同构),cwd 命中某登记工作区路径时回退该工作区标题(较官方「cwd basename 直接回退」收紧,防未登记目录名冒充工作区),均未命中显示「未分组」;工作区 title 缺失回退路径末段。镜像函数 client 与 core 双实现由 parity 测试锁定。行内支持取消归档与删除。
  • 归档与操作通知:host 归档动作经 workspace.followarchived 增量帧到达 client,集合差分得到新增会话,经公共通知依赖 @mzzsfy/dsh-toast 顶部居中显示带会话标题的文案:单个显示如「会话「修复登录页」已归档」,多个显示「有 N 个会话已归档:标题1、标题2」(N 恒为真实总数),标题数超过 TOAST_MAX_TITLES 只列前 TOAST_MAX_TITLES 个并以「 等」收尾,标题缺失、空白或行不存在回退会话 id;host 侧逐会话归档成功时写一条 info 日志(含会话 id)。面板操作(恢复 / 删除 / 重新挂载等)的成功与失败反馈同样经该依赖展示,失败提示常驻待确认。dsh-toast 为普通 npm 依赖由本插件 dependencies 声明随装(表层 manifest 不再单列,装载经 dsh fallback 沿 bundles 依赖闭包补链),其宿主占位条目由本插件 cordis.patch.yml 代挂。
  • 删除:仅对已归档会话生效(运行中守卫先于执行,执行前 TOCTOU 复检,运行中的会话不可删除;OS 回收存在数百 ms 异步窗口,复检通过后仍可能恢复运行——此时回收已完成,响应附警告并落服务端日志)。三次确认:击「删除」展示标题 / 日志体积(产物已缺失时以「产物已丢失」替代体积)→ 行内「移入回收站」确认 → 弹窗强提示(说明删除会影响其他插件的工作、若无特殊需求请不要删除,携会话标题,确认后才发请求)。确认后按 locate → 处置 → 台账 → detach → 归档清理单序执行;同 id 并发删除仅首个生效,其余以「正在删除中」拒绝。处置两级:优先移入系统回收站(Windows PowerShell VisualBasic / macOS Finder / Linux gio;Windows 路径经环境变量传入 PowerShell,含空格或特殊字符的路径安全);系统回收站不可用的环境(Docker 容器无 gio / dbus 等)自动降级为插件回收区(~/.dsh/trash/session-manager,rename 搬移,跨设备 EXDEV 回退复制),仍可经重挂载移回,不做无暂存的永久删除;双失败才会话保留并拒绝。处置成功即写入已删除台账(独立 storage domain session_manager,读改写经进程内互斥链串行化且单次操作带超时兜底,条目上限 200 裁最旧),记录会话 id、产物原位置与回收区条目的暂存路径;响应附处置模式(os / quarantine),面板成功文案随之区分。产物目录已缺失的会话,仅当已归档或台账有记录(同 id 重删的残留收尾)时跳过处置与台账、仅解除列表关联,提示「产物已不存在,已完成列表清理」;两者皆无的缺失可能是新建会话尚未落盘,直接拒绝以防剥离活会话。
  • 已删除分区与重挂载:面板「已删除」区列出台账条目(标题 / 原位置 / 删除时间)。OS 回收站条目:用户在系统回收站将会话文件夹还原到原位置后点「重新挂载」;回收区暂存条目(heldPath)重挂载自动把产物从回收区移回原位置再挂载,无需手工搬移。挂载经官方 workspace.attachSession 并清除台账;「移除记录」幂等清除单条。系统回收站的还原动作始终由用户在回收站完成,插件不驱动系统回收站。

回收站还原与重新挂载

删除移入系统回收站的是会话产物目录,「原位置」形如 C:\Users\<你>\.dsh\sessions\--<工作区路径编码>--\<会话id>\(工作区目录名由宿主对 cwd 做编码,非裸路径;目录内是 session.jsonl.zstd 日志)。辨认以面板「已删除」区记录的原位置为准,无需理解编码规则。

插件回收区条目(环境无系统回收站时降级产生):产物暂存于 ~/.dsh/trash/session-manager,无需手工搬移——直接点「重新挂载」,插件自动把产物移回原位置后挂载。

0.1.3 版本删除的条目回收的是日志文件 session.jsonl.zstd 而非目录:还原该文件即可(目录本身未被移除),还原后同样走「重新挂载」。

还原步骤(系统回收站操作):

  • Windows:打开桌面「回收站」→ 按「原位置」列(含 .dsh\sessions\)或名称(会话 id)定位目录 → 右键「还原」。
  • macOS:打开 Finder「废纸篓」→ 选中会话目录 → 右键「放回原处」。
  • Linux(GNOME Files):打开「回收站」→ 右键「还原」;命令行 gio trash --restore

还原后回到面板「已删除」区点「重新挂载」:会话经官方通道挂回工作区,重新出现在会话列表。注意事项:

  • 未还原(持久层读不到产物)时重挂载直接拒绝,提示先还原。
  • 还原后重挂载提示「未找到会话所属工作区」:插件按会话 cwd 匹配工作区失败,通常是原工作区目录已删除或更名。
  • 清空回收站后产物永久丢失,台账条目仅剩记录价值,应「移除记录」。
  • 只还原产物而不重挂载:数据在磁盘上,但会话不会自动回到工作区列表(删除时已 detach)。

失败矩阵

失败点 表现
locate 返回 undefined(SQLite 等后端) 拒绝执行,提示后端不支持,无副作用
产物目录已缺失(且已归档或台账有记录) 跳过归档资格 / 回收 / 台账,仅 detach 与归档清理,提示「产物已不存在,已完成列表清理」;清理半失败转 partial 并聚合失败点,重试即补全
产物目录已缺失(未归档且无台账记录) 拒绝执行(可能是新建会话尚未落盘,剥离活会话属破坏性误删),无副作用
trash 失败、回收区搬移成功 降级为插件回收区暂存(容器无 gio / dbus 等场景),台账记录暂存路径,响应 mode=quarantine;原始回收站错误落服务端日志;重挂载时自动移回原位置
trash 失败、回收区搬移也失败 整体中止,提示系统回收站与插件回收区均不可用(携回收区错误),目录与台账未动,可重试
trash 成功、detach 失败 视为已删除,提示「已移入回收站,但移除列表记录失败」;还原前重试将走产物缺失路径完成列表清理(台账保留),或还原后走「已删除」区重挂载
trash 成功、归档清理失败 已删除但归档集合残留,提示「已移入回收站,但移除归档记录失败」;经取消归档重试清理(幂等)
trash 成功、台账写入失败 已删除,提示「已移入回收站,但重挂载记录失败」,其余步骤照常完成
重挂载、产物未还原(OS 回收站条目) 拒绝,提示先到系统回收站还原,无副作用
重挂载、回收区暂存已缺失(原位置亦无产物) 拒绝,提示暂存缺失无法找回,无副作用
重挂载、台账域打开失败 入口即拒绝(移回依据不可得,不做静默跳过),无副作用
重挂载、无匹配工作区 拒绝,提示未找到会话所属工作区,无副作用
重挂载、attachSession 失败 拒绝并透出原始错误,台账保留供重试
重挂载、挂载后台账清除失败 挂载已生效,提示 partial「已重新挂载,但清除台账记录失败」,经「移除记录」收尾
trash 执行期间会话恢复运行 回收已完成,响应附警告「回收期间会话恢复运行」并落服务端日志;建议检查会话状态(agent 写入已断裂)
台账操作超时(存储域挂起) 单次读改写超 10s 按失败降级(同「台账写入失败」),互斥链不死锁,后续操作可重试;超时写操作后台落盘仍安全(幂等语义)

多个失败点并发时按 detach > 归档清理 > 台账的优先级聚合透出:前两者的 partial 消息末尾追加「,且重挂载记录失败」。

已知取舍

  • 取消归档:官方 workspace registry 明确归档为 one-way,无移除 API。本插件经 storageDomain.get('workspace') 的 global 句柄直写 archivedSessionIds(写入经 domain/changed 驱动 follow 帧),并把注册表进程内快照 registry.state 同步为写后值——注册表只在自身写路径同步该快照,不同步则其后续全量写回与 workspace.list 重连基线会复活刚移除的 id,官方归档的幂等判定也会因旧快照静默跳过(即早期版本「取消归档后列表不消失 / 二次归档不出现」的根因)。合并 durable 与快照取并集后再移除:可自愈历史失同步与清理半失败(经取消归档重试即补全),代价是快照中的陈旧 id 会在任一次清理时随全量写回重新落盘,可经再次取消归档清除。registry.state 为上游内部字段,缺失即路由报错 loud fail(注册表未就绪或上游形态变更)。域 global 仅支持整体写回,读改写窗口若与注册表两阶段变更交错,理论上可回退其 pendingMutation/workspaceIds 中间态,下次启动校验将 loud fail;同理,恢复操作与进行中的自动归档评估并发时,评估携带的旧快照整包写回也可能复活刚移除的 id,再次恢复即可清除——窗口极窄且域 API 无原子原语可用,属已知取舍。
  • 删除:成功路径在 detach 后同样从归档集合移除该 id(域与快照同步),清理失败响应 partial 提示;detach 失败时不清理归档集合,保留归档资格供重试。删除后 session.list 的会话行按官方语义仅在宿主发出 session/disposed(经 api-session/removed)时移除;官方 SessionStore 无按 id dispose 的公开 API,本进程内打开过的会话被删除后,其列表行会以「未分组」形式残留,直至宿主重启(重启后 live 记录清空,持久层扫描因产物缺失自然不再列出)。残留行仍可再次执行删除:产物缺失路径即为此设计,完成列表关联清理并提示。重挂载复用该语义:删除后会话行短暂残留在 client 会话模型,「已删除」区标题在重连前显示原标题,重连后回退会话 id。
  • 已删除台账:独立 storage domain session_manager(global 单列表),非 workspace 域、非审计层——存在意义仅为重挂载定位产物原位置。trash 成功即记录(位于 detach 前),台账失败仅降级重挂载便利,不回滚删除;同 id 再次删除替换旧条目。台账读改写经进程内互斥链串行化(并发删除不再有丢更新窗口),条目上限 200、超出裁最旧,防无界增长写放大。台账不随产物还原自动清除,以「重新挂载」或「移除记录」收尾;清空回收站后的残留条目无恢复价值,应手动移除。
  • 评估的活跃时间:JSONL 后端以产物 mtime 作为最近活跃代理,updatedAt = max(createdAt, mtime);非 JSONL 后端退化为 createdAt。评估两级筛选:先用 createdAt 纯内存预筛(mtime 只会增大 updatedAt,createdAt 未超期必不超期),仅对预筛存活者做产物 stat / blank 探测,活跃会话零 IO。空白判定:live 会话 seq=0,冷会话以 JSONL 产物「仅 header 一行」判定,locate 不可用的后端按非空白处理。评估整体带超时兜底(宿主服务挂起时门闩必然复位,不会永久停摆);单会话归档失败仅告警不中断整轮。
  • 无批量操作、无正文内容搜索(归档库仅标题子串检索)、无会话详情预览。
  • 归档库的组织与检索:分组键为行投影的工作区标题,同名标题的不同工作区在库视图合并为一组(行投影不含工作区 id,不为分组扩展投影公共形态);搜索仅匹配标题,不做正文全文检索(正文搜索属后续独立任务);分页粒度 100 为统一常量(ARCHIVE_PAGE_SIZE),搜索命中与组内展开共用同一分页机制,主列表固定首页不翻页;视图切换、展开与搜索状态均为面板内存态,离开设置页即复位,不做持久化。
  • 自动归档评估门闩:评估进行中其他触发源(含周期轮与 session/created)的新触发直接丢弃,不做排队;漏掉的会话由下一次触发兜底,启动补扫与每日周期轮保证了积压会话最迟一个周期内归档。产物不可读(mtime 探测失败)的会话视为已删除,不参与归档,防止删除后的会话被重新归档复活。subagent 内部会话(origin: 'subagent')永不参与归档:官方主列表即以 origin 排除 subagent(归档集合仅服务用户会话),误归档只产出无 title 回退 cwd 名的不可辨认面板行与无意义通知。timer 软依赖:宿主定时服务缺失或调用失败时周期轮停用,设置页显示降级提示(session/created 触发与启动补扫不受影响);timer 服务晚于插件激活时周期轮自动补武装。
  • 归档提示以「连续两个 ready 快照」为差分启用条件:基线首装(启动与重连)不提示存量,重连基线携带的离期新增仍会提示。通知展示经公共依赖 @mzzsfy/dsh-toast(external require),本包不再自带通知 UI。client.js 为单文件自包含格式,守卫逻辑与 core.mjs 各存一份镜像,修改需两处同步(projectRows / archiveToastStep / projectDeletedRows / pageArchiveRows / groupArchiveRowsByWorkspace / filterArchiveRows 同规);test/parity.test.mjs 对各组镜像做行为级对照并锁定 client 侧确认态文案与 host MESSAGES 同值。client 已删除列表加载失败时保留旧数据并 console.warn,不渲染成「无记录」。路由错误响应:业务错误原样透传中文文案,系统级错误(带 fs 错误码,message 内嵌绝对路径)收敛为固定文案并落服务端日志。header 查找走 ctx 级 TTL 缓存(归档/删除/重挂载路由不每次全量扫描 listSessions)。
  • 重挂载的并发窗口:attachSession 后、台账清除前进程中断,残留条目重挂载时因官方 attachSession 幂等(已在 sessionIds 中则跳过校验直写)无副作用,再次点按或「移除记录」即可收尾。台账域打开失败时已删除 / 重挂载 / forget 以 400 拒绝;删除路由走 partial 降级(其余步骤照常,提示「已移入回收站,但重挂载记录失败」),不做无台账中断——产物进回收站后中断删除只会造成状态不一致。
  • 测试基建:trash 与回收区搬移/移回为进程级 OS 副作用出口,经 executor(trashPath / moveToQuarantine / restoreFromQuarantine)注册表注入,删除全流程(OS 回收站成败 / 回收区降级 / 台账成败 / 归档清理 / 重挂载移回)有路由层覆盖。EXDEV 分支经 fs 注入桩测试(真实跨设备场景难以在测试中稳定构造)。
  • 删除降级的已知取舍:系统回收站任意失败(不限命令缺失,含 dbus 不可用、权限拒绝)都触发回收区降级——按错误类别区分收益低、降级后仍可还原;回收区目录 ~/.dsh/trash/session-manager 不自动清理(与系统回收站同责,由用户清空),重挂载移回成功后暂存条目随台账清除,但已移回前的重复暂存或用户手工干预可能留下孤儿目录,空间占用以回收区目录大小为准;跨设备搬移回退 cp + rm,中断窗口内两侧各有部分数据时以重试补齐(cp 幂等覆盖、rm force)。

验证

npm test

纯逻辑层(评估状态机 / 删除资格与失败矩阵 / 面板投影 / 归档差分 / 空白判定 / 回收站命令构造)以 node --test 覆盖,无外部依赖。路由层测试依赖 peer 包可解析,仓库根未安装依赖时自动 skip,npm install 后激活。Windows 真实回收站执行测试仅在本平台执行,其余平台自动 skip。周期评估测试经 mock.timers 接管 setIntervalDate(显式传 now:接管后虚拟时钟从 epoch 起算,夹具时间戳会全成「未来」),timer 服务以 makeCtx 桩模拟激活与缺失两种形态。

开发安装(仓库工作副本直挂,不经 npm 发布)

node scripts/dev-link.mjs dsh-session-manager   # 仓库根执行:归一 profile 依赖行 + 挂 junction

工作副本以 junction 挂进 profile,改代码保存即热重载(host 半区)或刷新页面生效(client 半区),无需发版;规约与全仓归一见仓库根 node scripts/dev-link.mjs all

dsh 版本兼容

三版本全部通过:会话树渲染、归档入口、激活 live、diagnostics 0 findings。

内容来自项目 README(GitHub)↗

链接

同类插件

查看整个分类 →

社区评论

评论公开保存在 GitHub Discussions。加载评论会连接 GitHub 和 Giscus;发表内容需要 GitHub 账号。