liangmianya/dsh-synapse
liangmianya/dsh-synapseDeepSeek Harness 的可视化非线性对话工作区:把会话、追问与分支变成可浏览、可拖拽的对话地图。
DeepSeek Harness 会话生命周期管理插件:自动归档 + 归档面板 + 归档删除 + 回收站还原重挂载。
历史输入浮层、插话撤回与对话分叉已迁至独立插件 dsh-context-manager(会话上下文管理);工作区文件夹运行标记见 dsh-turn-notify。
workspace.archiveSession 通道,三个触发源共用同一评估与门闩:新会话创建(session/created,按该会话所属工作区限定)、settings 就绪后的启动补扫(全量,清掉停机期间积压)、每日周期轮(全量,经宿主 timer 服务固定短 tick + 到期判断)。幂等:已归档会话不参与评估。阈值 autoArchiveDays 默认 7,0 关闭;周期间隔 autoArchiveIntervalHours 默认 24,0 关闭周期轮,变更经周期 tick 对账(关闭即时暂停、重启用最迟下个 tick 生效、缩短经锚定钳制前移,最长等新间隔而非等满旧周期)。评估筛选:createdAt 纯内存预筛 + 已归档跳过 + stat 后活跃度判定,locate 缺失(第三方后端)与产物不可读的会话一律跳过,宁可漏归档不可误归档。经 settings 命名空间 session-manager 注册(schema 拒绝负数与非整数)。timer 为软依赖:宿主定时服务不可用时仅周期轮停用,面板顶部提示,插件其余能力不受影响。GET/POST /api/session-manager/auto-archive(POST 部分更新,仅接受出现且为非负整数的字段,空字段拒绝),值存宿主 settings 与评估逻辑同源,0 = 关闭,GET 返回含默认回退的当前生效值。配置行的行为说明经原生 title 悬停展示(设置侧栏为滚动容器,CSS 气泡会被 overflow 裁剪,故不做自绘气泡),文案由源码契约测试锁定。session.list 行 ∩ workspaces.follow 归档快照的交集,按更新时间倒序;主列表只展开最近 ARCHIVE_PAGE_SIZE(100)条,列表尾部「按工作区浏览」按钮直接进入二级视图查看全部(主列表不翻页,防归档集合无限增长拖垮渲染)。二级视图:无搜索词时按工作区分组(组间按组内最新活跃倒序,分组默认收起,展开即见组内首页并可继续翻页,workspace 假值并入「未分组」组);输入搜索词后平铺展示标题命中(不区分大小写子串,标题缺失回退会话 id 天然可搜)的全部归档会话并显示匹配计数,同样分页。行内标题前显示所属工作区徽标——映射优先走 workspace 账本(sessionIds,与官方 dsh-client-ui-workspace 的 workspaceBySession 同构),cwd 命中某登记工作区路径时回退该工作区标题(较官方「cwd basename 直接回退」收紧,防未登记目录名冒充工作区),均未命中显示「未分组」;工作区 title 缺失回退路径末段。镜像函数 client 与 core 双实现由 parity 测试锁定。行内支持取消归档与删除。workspace.follow 的 archived 增量帧到达 client,集合差分得到新增会话,经公共依赖 @mzzsfy/dsh-change-bus(toast 组件)顶部居中显示带会话标题的文案:单个显示如「会话「修复登录页」已归档」,多个显示「有 N 个会话已归档:标题1、标题2」(N 恒为真实总数),标题数超过 TOAST_MAX_TITLES 只列前 TOAST_MAX_TITLES 个并以「 等」收尾,标题缺失、空白或行不存在回退会话 id;host 侧逐会话归档成功时写一条 info 日志(含会话 id)。面板操作(恢复 / 删除 / 重新挂载等)的成功与失败反馈同样经该依赖展示,失败提示常驻待确认。dsh-change-bus 为普通 npm 依赖由本插件 dependencies 声明随装(表层 manifest 不再单列,装载经 dsh fallback 沿 bundles 依赖闭包补链),其宿主占位条目由本插件 cordis.patch.yml 代挂。~/.dsh/trash/session-manager,rename 搬移,跨设备 EXDEV 回退复制),仍可经重挂载移回,不做无暂存的永久删除;双失败才会话保留并拒绝。处置成功即写入已删除台账(独立 storage domain session_manager,读改写经进程内互斥链串行化且单次操作带超时兜底,条目上限 200 裁最旧),记录会话 id、产物原位置与回收区条目的暂存路径;响应附处置模式(os / quarantine),面板成功文案随之区分。产物目录已缺失的会话,仅当已归档或台账有记录(同 id 重删的残留收尾)时跳过处置与台账、仅解除列表关联,提示「产物已不存在,已完成列表清理」;两者皆无的缺失可能是新建会话尚未落盘,直接拒绝以防剥离活会话。workspace.attachSession 并清除台账;「移除记录」幂等清除单条。系统回收站的还原动作始终由用户在回收站完成,插件不驱动系统回收站。删除移入系统回收站的是会话产物目录,「原位置」形如 C:\Users\.dsh\sessions----\(工作区目录名由宿主对 cwd 做编码,非裸路径;目录内是 session.jsonl.zstd 日志)。辨认以面板「已删除」区记录的原位置为准,无需理解编码规则。
插件回收区条目(环境无系统回收站时降级产生):产物暂存于 ~/.dsh/trash/session-manager,无需手工搬移——直接点「重新挂载」,插件自动把产物移回原位置后挂载。
0.1.3 版本删除的条目回收的是日志文件 session.jsonl.zstd 而非目录:还原该文件即可(目录本身未被移除),还原后同样走「重新挂载」。还原步骤(系统回收站操作):
.dsh\sessions)或名称(会话 id)定位目录 → 右键「还原」。gio trash --restore。还原后回到面板「已删除」区点「重新挂载」:会话经官方通道挂回工作区,重新出现在会话列表。注意事项:
失败点 · 表现 locate 返回 undefined(SQLite 等后端) · 拒绝执行,提示后端不支持,无副作用 产物目录已缺失(且已归档或台账有记录) · 跳过归档资格 / 回收 / 台账,仅 detach 与归档清理,提示「产物已不存在,已完成列表清理」;清理半失败转 partial 并聚合失败点,重试即补全 产物目录已缺失(未归档且无台账记录) · 拒绝执行(可能是新建会话尚未落盘,剥离活会话属破坏性误删),无副作用 trash 失败、回收区搬移成功 · 降级为插件回收区暂存(容器无 gio / dbus 等场景),台账记录暂存路径,响应 mode=quarantine;原始回收站错误落服务端日志;重挂载时自动移回原位置 trash 失败、回收区搬移也失败 · 整体中止,提示系统回收站与插件回收区均不可用(携回收区错误),目录与台账未动,可重试 trash 成功、detach 失败 · 视为已删除,提示「已移入回收站,但移除列表记录失败」;还原前重试将走产物缺失路径完成列表清理(台账保留),或还原后走「已删除」区重挂载 trash 成功、归档清理失败 · 已删除但归档集合残留,提示「已移入回收站,但移除归档记录失败」;经取消归档重试清理(幂等) trash 成功、台账写入失败 · 已删除,提示「已移入回收站,但重挂载记录失败」,其余步骤照常完成 重挂载、产物未还原(OS 回收站条目) · 拒绝,提示先到系统回收站还原,无副作用 重挂载、回收区暂存已缺失(原位置亦无产物) · 拒绝,提示暂存缺失无法找回,无副作用 重挂载、台账域打开失败 · 入口即拒绝(移回依据不可得,不做静默跳过),无副作用 重挂载、无匹配工作区 · 拒绝,提示未找到会话所属工作区,无副作用 重挂载、attachSession 失败 · 拒绝并透出原始错误,台账保留供重试 重挂载、挂载后台账清除失败 · 挂载已生效,提示 partial「已重新挂载,但清除台账记录失败」,经「移除记录」收尾 trash 执行期间会话恢复运行 · 回收已完成,响应附警告「回收期间会话恢复运行」并落服务端日志;建议检查会话状态(agent 写入已断裂) 台账操作超时(存储域挂起) · 单次读改写超 10s 按失败降级(同「台账写入失败」),互斥链不死锁,后续操作可重试;超时写操作后台落盘仍安全(幂等语义)
多个失败点并发时按 detach > 归档清理 > 台账的优先级聚合透出:前两者的 partial 消息末尾追加「,且重挂载记录失败」。
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 无原子原语可用,属已知取舍。session.list 的会话行按官方语义仅在宿主发出 session/disposed(经 api-session/removed)时移除;官方 SessionStore 无按 id dispose 的公开 API,本进程内打开过的会话被删除后,其列表行会以「未分组」形式残留,直至宿主重启(重启后 live 记录清空,持久层扫描因产物缺失自然不再列出)。残留行仍可再次执行删除:产物缺失路径即为此设计,完成列表关联清理并提示。重挂载复用该语义:删除后会话行短暂残留在 client 会话模型,「已删除」区标题在重连前显示原标题,重连后回退会话 id。session_manager(global 单列表),非 workspace 域、非审计层——存在意义仅为重挂载定位产物原位置。trash 成功即记录(位于 detach 前),台账失败仅降级重挂载便利,不回滚删除;同 id 再次删除替换旧条目。台账读改写经进程内互斥链串行化(并发删除不再有丢更新窗口),条目上限 200、超出裁最旧,防无界增长写放大。台账不随产物还原自动清除,以「重新挂载」或「移除记录」收尾;清空回收站后的残留条目无恢复价值,应手动移除。ARCHIVE_PAGE_SIZE),搜索命中与组内展开共用同一分页机制,主列表固定首页不翻页;视图切换、展开与搜索状态均为面板内存态,离开设置页即复位,不做持久化。origin: 'subagent')永不参与归档:官方主列表即以 origin 排除 subagent(归档集合仅服务用户会话),误归档只产出无 title 回退 cwd 名的不可辨认面板行与无意义通知。timer 软依赖:宿主定时服务缺失或调用失败时周期轮停用,设置页显示降级提示(session/created 触发与启动补扫不受影响);timer 服务晚于插件激活时周期轮自动补武装。@mzzsfy/dsh-change-bus(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)。executor(trashPath / moveToQuarantine / restoreFromQuarantine)注册表注入,删除全流程(OS 回收站成败 / 回收区降级 / 台账成败 / 归档清理 / 重挂载移回)有路由层覆盖。EXDEV 分支经 fs 注入桩测试(真实跨设备场景难以在测试中稳定构造)。~/.dsh/trash/session-manager 不自动清理(与系统回收站同责,由用户清空),重挂载移回成功后暂存条目随台账清除,但已移回前的重复暂存或用户手工干预可能留下孤儿目录,空间占用以回收区目录大小为准;跨设备搬移回退 cp + rm,中断窗口内两侧各有部分数据时以重试补齐(cp 幂等覆盖、rm force)。npm test纯逻辑层(评估状态机 / 删除资格与失败矩阵 / 面板投影 / 归档差分 / 空白判定 / 回收站命令构造)以 node --test 覆盖,无外部依赖。路由层测试依赖 peer 包可解析,仓库根未安装依赖时自动 skip,npm install 后激活。Windows 真实回收站执行测试仅在本平台执行,其余平台自动 skip。周期评估测试经 mock.timers 接管 setInterval 与 Date(显式传 now:接管后虚拟时钟从 epoch 起算,夹具时间戳会全成「未来」),timer 服务以 makeCtx 桩模拟激活与缺失两种形态。
node scripts/dev-link.mjs dsh-session-manager # 仓库根执行:归一 profile 依赖行 + 挂 junction工作副本以 junction 挂进 profile,改代码保存即热重载(host 半区)或刷新页面生效(client 半区),无需发版;规约与全仓归一见仓库根 node scripts/dev-link.mjs all。
按仓库动态窗口验证(scripts/compat/window.mjs),不预置任何固定版本槽:主测 = 渠道 dist-tag 最新 rc,完全适配口径;基线 = npm latest,不崩溃底线口径;主测与基线同版时收敛单槽。兼容面以窗口实测为准,不逐版本承诺。逐轮实测结论见 docs/兼容性测试/逐包测试进度.md 与本包 兼容性测试.md。