@mzzsfy/dsh-session-manager 0.9.3 → 0.9.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -3
- package/cordis.patch.yml +5 -4
- package/package.json +10 -3
- package/src/client.js +811 -811
- package/src/core.mjs +271 -262
- package/src/index.js +15 -1
- package/test/client-toast.test.mjs +6 -6
- package/test/core.test.mjs +14 -0
- package/test/index.test.mjs +35 -1
package/README.md
CHANGED
|
@@ -9,7 +9,7 @@ DeepSeek Harness 会话生命周期管理插件:自动归档 + 归档面板 +
|
|
|
9
9
|
- 自动归档:host 半区对超期会话走官方 `workspace.archiveSession` 通道,三个触发源共用同一评估与门闩:新会话创建(`session/created`,按该会话所属工作区限定)、settings 就绪后的启动补扫(全量,清掉停机期间积压)、每日周期轮(全量,经宿主 timer 服务固定短 tick + 到期判断)。幂等:已归档会话不参与评估。阈值 `autoArchiveDays` 默认 7,`0` 关闭;周期间隔 `autoArchiveIntervalHours` 默认 24,`0` 关闭周期轮,变更经周期 tick 对账(关闭即时暂停、重启用最迟下个 tick 生效、缩短经锚定钳制前移,最长等新间隔而非等满旧周期)。评估筛选:createdAt 纯内存预筛 + 已归档跳过 + stat 后活跃度判定,locate 缺失(第三方后端)与产物不可读的会话一律跳过,宁可漏归档不可误归档。经 settings 命名空间 `session-manager` 注册(schema 拒绝负数与非整数)。timer 为软依赖:宿主定时服务不可用时仅周期轮停用,面板顶部提示,插件其余能力不受影响。
|
|
10
10
|
- 自动归档配置:归档面板「已删除」区下方的配置行,阈值天数与检查周期小时数两个数字输入,失焦或 Enter 单字段即时提交,非法输入前端拦截不发请求,服务端失败回读生效值回滚;读写经本插件 `GET/POST /api/session-manager/auto-archive`(POST 部分更新,仅接受出现且为非负整数的字段,空字段拒绝),值存宿主 settings 与评估逻辑同源,`0` = 关闭,GET 返回含默认回退的当前生效值。配置行的行为说明经原生 `title` 悬停展示(设置侧栏为滚动容器,CSS 气泡会被 overflow 裁剪,故不做自绘气泡),文案由源码契约测试锁定。
|
|
11
11
|
- 归档面板:设置页「会话归档」分区,数据为 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 测试锁定。行内支持取消归档与删除。
|
|
12
|
-
- 归档与操作通知:host 归档动作经 `workspace.follow` 的 `archived` 增量帧到达 client
|
|
12
|
+
- 归档与操作通知:host 归档动作经 `workspace.follow` 的 `archived` 增量帧到达 client,集合差分得到新增会话,经公共依赖 `@mzzsfy/dsh-common-tools`(toast 组件)顶部居中显示带会话标题的文案:单个显示如「会话「修复登录页」已归档」,多个显示「有 N 个会话已归档:标题1、标题2」(N 恒为真实总数),标题数超过 `TOAST_MAX_TITLES` 只列前 `TOAST_MAX_TITLES` 个并以「 等」收尾,标题缺失、空白或行不存在回退会话 id;host 侧逐会话归档成功时写一条 info 日志(含会话 id)。面板操作(恢复 / 删除 / 重新挂载等)的成功与失败反馈同样经该依赖展示,失败提示常驻待确认。dsh-common-tools 为普通 npm 依赖由本插件 dependencies 声明随装(表层 manifest 不再单列,装载经 dsh fallback 沿 bundles 依赖闭包补链),其宿主占位条目由本插件 cordis.patch.yml 代挂。
|
|
13
13
|
- 删除:仅对已归档会话生效(运行中守卫先于执行,执行前 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 重删的残留收尾)时跳过处置与台账、仅解除列表关联,提示「产物已不存在,已完成列表清理」;两者皆无的缺失可能是新建会话尚未落盘,直接拒绝以防剥离活会话。
|
|
14
14
|
- 已删除分区与重挂载:面板「已删除」区列出台账条目(标题 / 原位置 / 删除时间)。OS 回收站条目:用户在系统回收站将会话文件夹还原到原位置后点「重新挂载」;**回收区暂存条目(heldPath)重挂载自动把产物从回收区移回原位置再挂载**,无需手工搬移。挂载经官方 `workspace.attachSession` 并清除台账;「移除记录」幂等清除单条。系统回收站的还原动作始终由用户在回收站完成,插件不驱动系统回收站。
|
|
15
15
|
|
|
@@ -60,13 +60,14 @@ DeepSeek Harness 会话生命周期管理插件:自动归档 + 归档面板 +
|
|
|
60
60
|
## 已知取舍
|
|
61
61
|
|
|
62
62
|
- 取消归档:官方 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 无原子原语可用,属已知取舍。
|
|
63
|
+
- 取消归档宽限:取消归档后 10 分钟内自动归档评估对该会话短路(进程内宽限标记),防「恢复→补扫/周期轮」竞态把刚恢复的会话立刻重新归档;宽限仅本进程内存态,宿主重启即失效。
|
|
63
64
|
- 删除:成功路径在 detach 后同样从归档集合移除该 id(域与快照同步),清理失败响应 partial 提示;detach 失败时不清理归档集合,保留归档资格供重试。删除后 `session.list` 的会话行按官方语义仅在宿主发出 `session/disposed`(经 `api-session/removed`)时移除;官方 `SessionStore` 无按 id dispose 的公开 API,本进程内打开过的会话被删除后,其列表行会以「未分组」形式残留,直至宿主重启(重启后 live 记录清空,持久层扫描因产物缺失自然不再列出)。残留行仍可再次执行删除:产物缺失路径即为此设计,完成列表关联清理并提示。重挂载复用该语义:删除后会话行短暂残留在 client 会话模型,「已删除」区标题在重连前显示原标题,重连后回退会话 id。
|
|
64
65
|
- 已删除台账:独立 storage domain `session_manager`(global 单列表),非 workspace 域、非审计层——存在意义仅为重挂载定位产物原位置。trash 成功即记录(位于 detach 前),台账失败仅降级重挂载便利,不回滚删除;同 id 再次删除替换旧条目。台账读改写经进程内互斥链串行化(并发删除不再有丢更新窗口),条目上限 200、超出裁最旧,防无界增长写放大。台账不随产物还原自动清除,以「重新挂载」或「移除记录」收尾;清空回收站后的残留条目无恢复价值,应手动移除。
|
|
65
66
|
- 评估的活跃时间:JSONL 后端以产物 mtime 作为最近活跃代理,updatedAt = max(createdAt, mtime);非 JSONL 后端退化为 createdAt。评估两级筛选:先用 createdAt 纯内存预筛(mtime 只会增大 updatedAt,createdAt 未超期必不超期),仅对预筛存活者做产物 stat / blank 探测,活跃会话零 IO。空白判定:live 会话 seq=0,冷会话以 JSONL 产物「仅 header 一行」判定,locate 不可用的后端按非空白处理。评估整体带超时兜底(宿主服务挂起时门闩必然复位,不会永久停摆);单会话归档失败仅告警不中断整轮。
|
|
66
67
|
- 无批量操作、无正文内容搜索(归档库仅标题子串检索)、无会话详情预览。
|
|
67
68
|
- 归档库的组织与检索:分组键为行投影的工作区标题,同名标题的不同工作区在库视图合并为一组(行投影不含工作区 id,不为分组扩展投影公共形态);搜索仅匹配标题,不做正文全文检索(正文搜索属后续独立任务);分页粒度 100 为统一常量(`ARCHIVE_PAGE_SIZE`),搜索命中与组内展开共用同一分页机制,主列表固定首页不翻页;视图切换、展开与搜索状态均为面板内存态,离开设置页即复位,不做持久化。
|
|
68
69
|
- 自动归档评估门闩:评估进行中其他触发源(含周期轮与 session/created)的新触发直接丢弃,不做排队;漏掉的会话由下一次触发兜底,启动补扫与每日周期轮保证了积压会话最迟一个周期内归档。产物不可读(mtime 探测失败)的会话视为已删除,不参与归档,防止删除后的会话被重新归档复活。subagent 内部会话(`origin: 'subagent'`)永不参与归档:官方主列表即以 origin 排除 subagent(归档集合仅服务用户会话),误归档只产出无 title 回退 cwd 名的不可辨认面板行与无意义通知。timer 软依赖:宿主定时服务缺失或调用失败时周期轮停用,设置页显示降级提示(session/created 触发与启动补扫不受影响);timer 服务晚于插件激活时周期轮自动补武装。
|
|
69
|
-
- 归档提示以「连续两个 ready 快照」为差分启用条件:基线首装(启动与重连)不提示存量,重连基线携带的离期新增仍会提示。通知展示经公共依赖 `@mzzsfy/dsh-
|
|
70
|
+
- 归档提示以「连续两个 ready 快照」为差分启用条件:基线首装(启动与重连)不提示存量,重连基线携带的离期新增仍会提示。通知展示经公共依赖 `@mzzsfy/dsh-common-tools`(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)。
|
|
70
71
|
- 重挂载的并发窗口:attachSession 后、台账清除前进程中断,残留条目重挂载时因官方 attachSession 幂等(已在 sessionIds 中则跳过校验直写)无副作用,再次点按或「移除记录」即可收尾。台账域打开失败时已删除 / 重挂载 / forget 以 400 拒绝;删除路由走 partial 降级(其余步骤照常,提示「已移入回收站,但重挂载记录失败」),不做无台账中断——产物进回收站后中断删除只会造成状态不一致。
|
|
71
72
|
- 测试基建:trash 与回收区搬移/移回为进程级 OS 副作用出口,经 `executor`(trashPath / moveToQuarantine / restoreFromQuarantine)注册表注入,删除全流程(OS 回收站成败 / 回收区降级 / 台账成败 / 归档清理 / 重挂载移回)有路由层覆盖。EXDEV 分支经 fs 注入桩测试(真实跨设备场景难以在测试中稳定构造)。
|
|
72
73
|
- 删除降级的已知取舍:系统回收站**任意**失败(不限命令缺失,含 dbus 不可用、权限拒绝)都触发回收区降级——按错误类别区分收益低、降级后仍可还原;回收区目录 `~/.dsh/trash/session-manager` 不自动清理(与系统回收站同责,由用户清空),重挂载移回成功后暂存条目随台账清除,但已移回前的重复暂存或用户手工干预可能留下孤儿目录,空间占用以回收区目录大小为准;跨设备搬移回退 `cp + rm`,中断窗口内两侧各有部分数据时以重试补齐(cp 幂等覆盖、rm force)。
|
|
@@ -89,4 +90,4 @@ node scripts/dev-link.mjs dsh-session-manager # 仓库根执行:归一 profile
|
|
|
89
90
|
|
|
90
91
|
## dsh 版本兼容
|
|
91
92
|
|
|
92
|
-
|
|
93
|
+
按仓库动态窗口验证(scripts/compat/window.mjs),不预置任何固定版本槽:主测 = 渠道 dist-tag 最新 rc,完全适配口径;基线 = npm latest,不崩溃底线口径;主测与基线同版时收敛单槽。兼容面以窗口实测为准,不逐版本承诺。逐轮实测结论见 `docs/兼容性测试/逐包测试进度.md` 与本包 `兼容性测试.md`。
|
package/cordis.patch.yml
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
# session-manager 打包补丁:将自动归档 + 归档面板 + 回收站删除插件以单条目
|
|
2
2
|
# 注入 profile 根。由 `dsh plugin add @mzzsfy/dsh-session-manager` 应用;
|
|
3
3
|
# 行 id 指向本插件宿主半区,其 /api/session-manager/* 路由服务设置页中的浏览器半区。
|
|
4
|
-
# dsh-
|
|
5
|
-
#
|
|
4
|
+
# dsh-common-tools 行代挂公共依赖的宿主占位(该包无自带 patch,作为普通依赖随各
|
|
5
|
+
# 消费插件装载,其 client 由此进入客户端模块表供 external require);条目 id 带本
|
|
6
6
|
# 插件前缀避免多消费插件同时安装时树内 id 冲突,name 才是模块表的包解析键。
|
|
7
|
+
# 其 host 半区(setupCommonTools)由各消费插件在自己的 apply 里执行,不经此条目。
|
|
7
8
|
|
|
8
9
|
- insert:
|
|
9
10
|
- id: session-manager
|
|
10
11
|
name: '@mzzsfy/dsh-session-manager'
|
|
11
|
-
- id: session-manager-dsh-
|
|
12
|
-
name: '@mzzsfy/dsh-
|
|
12
|
+
- id: session-manager-dsh-common-tools
|
|
13
|
+
name: '@mzzsfy/dsh-common-tools'
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mzzsfy/dsh-session-manager",
|
|
3
3
|
"description": "会话自动归档与管理:超期自动归档、归档面板、删除进系统回收站、还原后一键重挂载",
|
|
4
|
-
"version": "0.9.
|
|
4
|
+
"version": "0.9.5",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "src/index.js",
|
|
7
7
|
"exports": {
|
|
@@ -16,8 +16,15 @@
|
|
|
16
16
|
"client": {
|
|
17
17
|
"platform": "web",
|
|
18
18
|
"external": [
|
|
19
|
-
"@mzzsfy/dsh-
|
|
19
|
+
"@mzzsfy/dsh-common-tools/client"
|
|
20
20
|
]
|
|
21
|
+
},
|
|
22
|
+
"compatibility": {
|
|
23
|
+
"dshReleases": {
|
|
24
|
+
"0.2.0-rc.1": "unknown",
|
|
25
|
+
"0.2.0-rc.2": "compatible",
|
|
26
|
+
"0.2.1-alpha.1": "unknown"
|
|
27
|
+
}
|
|
21
28
|
}
|
|
22
29
|
},
|
|
23
30
|
"scripts": {
|
|
@@ -33,7 +40,7 @@
|
|
|
33
40
|
"node": ">=22"
|
|
34
41
|
},
|
|
35
42
|
"dependencies": {
|
|
36
|
-
"@mzzsfy/dsh-
|
|
43
|
+
"@mzzsfy/dsh-common-tools": "^0.2.0"
|
|
37
44
|
},
|
|
38
45
|
"peerDependencies": {
|
|
39
46
|
"@deepseek-ai/dsh-settings": ">=0.1.2-alpha.2",
|