dsh-session-mng 0.1.4 → 0.2.0
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/CHANGELOG.md +34 -0
- package/README.md +22 -8
- package/ROADMAP.md +12 -11
- package/client.js +1210 -319
- package/docs/01-design.md +49 -2
- package/docs/02-open-source-and-marketplace.md +16 -0
- package/docs/HANDOVER-2026-10-29.md +105 -0
- package/docs/PLAN-2026-10-29.md +245 -0
- package/docs/RELEASE-CHECKLIST-0.1.4.md +6 -5
- package/docs/RELEASE-CHECKLIST-0.2.0.md +76 -0
- package/lib/api.js +44 -11
- package/lib/catalog.js +773 -0
- package/lib/service.js +456 -0
- package/lib/state.js +46 -25
- package/lib/store-jsonl.js +76 -2
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,39 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.2.0 — 2026-10-29
|
|
4
|
+
|
|
5
|
+
### Added
|
|
6
|
+
|
|
7
|
+
- **Host 侧会话 catalog(零会话日志 IO)**:新增 `lib/catalog.js`,从宿主的 `workspaceRegistry.headers`(启动时已建好的全量 header 索引)与 `sessionProjectionCache`(title / `sessionListMetadata`)组装会话行,不再为总览调用 `sessionController.list()`、`sessionPersistence.list()` 或批量 `readTitleSnapshots()`。内部 seam 全部特性检测;缺失时自动回退到 0.1.x 的 `buildState` 慢路径(30 s TTL),接口形状不变。
|
|
8
|
+
- **`GET /overview`**:首屏只返回工作区计数/归档计数/空会话计数、totals、orphans、capabilities、limits,**不含任何会话行**;10000 条会话的合成基准约 10 ms、payload 约 1.3 KB。
|
|
9
|
+
- **`GET /sessions`**:按 `workspaceId` + `tab` + `query` + `sort` + `offset/limit`(≤50)分页;Host 端 branch-aware 排序(父行优先)+ `id` tie-break 保证分页稳定;对不在本页的分支返回 `parentStub`;页内只对 ≤50 条日志做一次 readdir+stat 取大小。
|
|
10
|
+
- **`GET /search`**:跨工作区的标题/路径/id/父标题搜索(与 0.1.3 的搜索口径一致),一次请求返回每个命中工作区的 `total` 与首屏一页,供客户端自动展开。
|
|
11
|
+
- **`GET /session` / `GET /blanks` / `GET /sizes`**:详情单行、空会话 id 列表、按工作区/全局大小统计;大小统计复用一次 `sessionPersistence.list()` 并做 60 s 进程内缓存。
|
|
12
|
+
- **客户端两段式加载**:首屏 `overview` → 展开工作区时取第一页 → 「加载更多」按 offset 追加;每工作区页缓存 + 行缓存,请求并发上限 3,切换筛选/排序/搜索时按 scope 失效。
|
|
13
|
+
- **老 Host 回退**:`GET /overview` 404 时一次性探测并回退到 `GET /state`(0.1.4 行为),旧 Host + 新 Client 仍可用;`GET /state` 本身保持不变。
|
|
14
|
+
- **配置项**:`sizesTtlMs`(默认 60000)、`sizeScanMax`(默认 20000)、`pageLimitMax`(默认 50)。
|
|
15
|
+
|
|
16
|
+
### Changed
|
|
17
|
+
|
|
18
|
+
- **列表默认每工作区 50 条改由 Host 分页**:客户端不再持有全量行;组头计数与「剩余 N 条」来自 Host 的 `total`,组大小异步取自 `/sizes`(未到达时显示「—」)。
|
|
19
|
+
- **搜索改为宿主搜索**:输入防抖 250 ms 后请求 `/search`,命中工作区自动展开;搜索期间仍锁定折叠与「展开全部/收起全部」。
|
|
20
|
+
- **选择语义收紧**:只允许选择已加载且已展开的行;切换 tab/工作区/搜索/排序/开关会清空选择;「全选当前列表」只作用于已加载可见行,并提示另有 N 条未加载;批量提交前再次过滤未加载 id(数据安全)。
|
|
21
|
+
- **分支跨页展示**:父会话不在本页时不再误报「来源父会话已不存在」——有 `parentStub` 时显示「↳ 来自:父标题」,仅 Host 确认父不存在时才显示原提示;`forkCount` 始终是全域名额。
|
|
22
|
+
- **详情页独立取数**:进入详情先用行缓存立即渲染,再由 `GET /session` 补齐;刷新不会再因为「不在当前列表数据里」把详情踢回列表。
|
|
23
|
+
- **刷新策略**:写操作与「刷新」按钮改为刷新 overview + 按已加载深度重取当前展开工作区的页,保留选择与滚动位置;窗口重新获得焦点时只静默刷新 overview,不再全量重取。
|
|
24
|
+
|
|
25
|
+
### Fixed
|
|
26
|
+
|
|
27
|
+
- **排序键相同时行序不稳定**:`updated/created/size/title` 四种排序全部补 `id` 升序 tie-break,分页切片不再重复/漏行。
|
|
28
|
+
- **切换排序不重置分页与选择裁剪**:`sort` 纳入分页 limit 重置与选择裁剪的依赖键,修掉 0.1.x 遗留的失效漏项。
|
|
29
|
+
- **空会话 / orphan / 计数在分页后失真**:tabs 计数、hiddenBlankCount、hiddenSubagents、orphan 横幅与两个空会话按钮全部改为读 overview / `/blanks`,不再由「已加载行」推算。
|
|
30
|
+
- **老 Host 回退丢失每工作区分页**:回退 `/state` 时仍按每组 50 条渲染 + 「加载更多」,不一次性铺满整组。
|
|
31
|
+
|
|
32
|
+
### Compatibility
|
|
33
|
+
|
|
34
|
+
- 实测宿主 DSH `0.2.1-rc.2` / `0.2.1-rc.3`;`GET /state` 保留,0.1.x 客户端不受影响。
|
|
35
|
+
- 快速路径依赖的两个宿主内存 seam(`workspaceRegistry.headers`、`sessionProjectionCache`)仍属版本敏感点,已全部特性检测并保留慢路径兜底。
|
|
36
|
+
|
|
3
37
|
## 0.1.4 — 2026-10-28
|
|
4
38
|
|
|
5
39
|
### Fixed
|
package/README.md
CHANGED
|
@@ -18,7 +18,8 @@
|
|
|
18
18
|
|
|
19
19
|
- **统一会话总览**:按工作区分组列出当前 profile 的全部会话(活跃 + 已归档)。显示标题、路径、会话 id、大小、最后活动时间、运行/已打开/已归档/已置顶/分支/子代理标记;支持搜索、工作区筛选、排序、刷新、批量选择。
|
|
20
20
|
- **分支会话默认显示**:从某条会话分出来的会话(fork)和主会话一样可见、可管理——缩进挂在父会话下方,父行显示「N 分支」,分支行标注「↳ 来自:父标题」;搜索父标题也能找到它。由委派产生的**子代理会话**仍默认隐藏(勾选「显示子代理会话」查看),总览行会提示「已隐藏 N 个子代理会话」。
|
|
21
|
-
-
|
|
21
|
+
- **按工作区分页(Host 侧)**:首屏只取工作区概览(会话数/归档数/空会话数/大小占位),展开工作区才按 50 条一页向宿主取行,「加载更多」继续追加;会话数 >100 时默认折叠工作区;搜索自动展开命中工作区。过滤工具栏和批量条整体吸顶。
|
|
22
|
+
- **万级会话可用**:Host 新增零会话日志 IO 的 catalog(复用宿主的 header 索引与投影缓存),10000 条会话首屏 overview 约 10 ms / 约 1.3 KB,单页 50 行约 9 ms;`GET /state` 保留给 0.1.x 客户端与回退路径。
|
|
22
23
|
- **选择跟随可见集**:切换筛选/折叠/搜索/刷新后,隐藏会话自动取消选择;`全选当前列表` 只作用于当前筛选与已展开的工作区。
|
|
23
24
|
- **空会话默认隐藏**:侧栏本来就不显示的 `blank` 会话,会话管理默认也不显示;勾选「显示空会话」才出现。提供「清理空会话(N)」快速清理已归档空会话。
|
|
24
25
|
- **删除范围模态确认**:范围内容在弹窗内独立滚动,底部勾选与确认/取消按钮固定可见;支持遮罩点击/Esc 取消。
|
|
@@ -73,17 +74,23 @@ Host 半是进程内模块:装完如果看不到页面,重启一次 dsh/应
|
|
|
73
74
|
|
|
74
75
|
```
|
|
75
76
|
Settings page (client.js)
|
|
76
|
-
│ GET /session-mng/api/
|
|
77
|
+
│ GET /session-mng/api/overview ← 首屏:只有计数,没有会话行
|
|
78
|
+
│ GET /session-mng/api/sessions?... ← 每个展开的工作区一页(≤50 行)
|
|
79
|
+
│ GET /session-mng/api/{search,session,blanks,sizes}
|
|
80
|
+
│ GET /session-mng/api/state ← 0.1.x 兼容 / 老 Host 回退
|
|
77
81
|
│ POST /session-mng/api/{preview,title/propose,title/apply,archive,unarchive,delete/preview,delete,move}
|
|
78
82
|
▼
|
|
79
83
|
Host route (lib/api.js) ──► service (lib/service.js)
|
|
80
|
-
├─
|
|
84
|
+
├─ catalog : workspaceRegistry.headers + sessionProjectionCache(零会话日志 IO;seam 缺失回退 buildState 慢路径)
|
|
85
|
+
├─ state : buildState 慢路径 / sessionController + sessionQuery + workspaceRegistry + sessionPersistence
|
|
81
86
|
├─ title : sessionQuery.readSurface → ctx.llm.stream → 确认后写 session/title 事件
|
|
82
87
|
├─ archive : workspaceRegistry.archiveSession / unarchiveSession
|
|
83
88
|
├─ move : 日志 header cwd 重写 + 目录迁移 + workspace 缓存对账(失败全回滚)
|
|
84
89
|
└─ delete : 删除范围预览 → 目录移入临时区 → 清理账本 → 删除(失败回滚)
|
|
85
90
|
```
|
|
86
91
|
|
|
92
|
+
- **首屏是概览、行是分页**:`overview` 只聚合内存索引;`sessions` 每页最多 50 行,排序/分支嵌套在 Host 完成后再切片,`id` tie-break 保证翻页稳定。
|
|
93
|
+
- **catalog 不落盘、不缓存会话**:行从宿主已有的 header 索引与投影缓存读取;归档/移动/删除/改标题后只失效大小快照与慢路径缓存,下一次请求自然重建。
|
|
87
94
|
- **标题是日志事件**:`session/title` 的 `source` 为 `user`,与官方重命名一致;已归档会话不需要恢复 Agent。
|
|
88
95
|
- **工作区归属是派生的**:由会话 header 的 `cwd` 决定。移动必须改写 header,只改账本无效。
|
|
89
96
|
- **不碰事件正文**:移动只重写日志第一个 frame(header),其余字节原样保留;移动后重新完整 replay 校验一次。
|
|
@@ -99,7 +106,7 @@ Host route (lib/api.js) ──► service (lib/service.js)
|
|
|
99
106
|
| 会话后端 | 移动/删除只支持本地 JSONL 后端(`sessionPersistence.locate`);其他后端仍可用总览/标题/归档/恢复 |
|
|
100
107
|
| 官方依赖 | 无 runtime 依赖;只使用 `ctx` 服务 |
|
|
101
108
|
| 已知限制 | 已打开(live)会话不能移动或彻底删除,重启 DSH 后重试;有子代理后代的会话不能单独移动;子代理会话默认隐藏(可勾选「显示子代理会话」查看);分支会话默认显示,但暂不能单独移动(需与父会话留在同一工作区);删除父会话不级联普通分支,分支会失去来源标识(显示「来源父会话已不存在」) |
|
|
102
|
-
| 规模限制 |
|
|
109
|
+
| 规模限制 | 首屏与分页行走 Host catalog,不拉全量行;单页上限 50。**大小**按需异步统计(`/sizes` 复用一次 `sessionPersistence.list()`,10000 条约数秒),首屏/分页不依赖它。依赖宿主的两个内存 seam(`workspaceRegistry.headers`、`sessionProjectionCache`),缺失时自动退回 0.1.x 的 `buildState` 慢路径 |
|
|
103
110
|
|
|
104
111
|
### 版本敏感点(请读)
|
|
105
112
|
|
|
@@ -125,6 +132,9 @@ Host route (lib/api.js) ──► service (lib/service.js)
|
|
|
125
132
|
titleMaxBytes: 120
|
|
126
133
|
allowRemote: false # 默认只接受 loopback / webRuntime.trustedHosts
|
|
127
134
|
sessionsRoot: '' # 仅在 sessionPersistence.locate 缺失时作为定位兜底
|
|
135
|
+
pageLimitMax: 50 # /sessions 单页上限(1–200)
|
|
136
|
+
sizesTtlMs: 60000 # /sizes 全量大小快照的进程内 TTL(1s–1h)
|
|
137
|
+
sizeScanMax: 20000 # /sizes 最多统计的会话数,超出返回 sizes-pending 降级
|
|
128
138
|
```
|
|
129
139
|
|
|
130
140
|
## 安全边界
|
|
@@ -137,7 +147,7 @@ Host route (lib/api.js) ──► service (lib/service.js)
|
|
|
137
147
|
## 开发
|
|
138
148
|
|
|
139
149
|
```sh
|
|
140
|
-
npm test # node --test,
|
|
150
|
+
npm test # node --test,Host 单测 + 客户端 vm 测试
|
|
141
151
|
node --check index.js client.js lib/*.js
|
|
142
152
|
npm --cache /tmp/dsh-npm-cache pack --dry-run
|
|
143
153
|
```
|
|
@@ -146,16 +156,20 @@ npm --cache /tmp/dsh-npm-cache pack --dry-run
|
|
|
146
156
|
|
|
147
157
|
## 当前状态与下一步
|
|
148
158
|
|
|
159
|
+
- `0.2.0`(本地实现与测试完成,已在隔离实例完成实机只读验收,待 Desktop 重启确认与发布):Host 侧新增零会话日志 IO 的会话 catalog 与 7 条只读路由(`/overview`、`/sessions`、`/search`、`/session`、`/blanks`、`/sizes`,`/state` 保留);首屏只取概览,工作区展开才按 50 条一页取行;搜索改由宿主完成;选择只作用于已加载行;详情独立取数不再被刷新踢出;分支跨页不再误报父会话已删除。10000 条合成基准:overview ≈ 10 ms / 1.3 KB,单页 50 行 ≈ 9 ms。129 个测试全绿(Host 72 + 客户端 vm 57)。
|
|
149
160
|
- `0.1.4` 已发布到 npm / GitHub / Release:详情页标题行吸顶;操作结果改为浮动 toast(成功 5 秒自动消失);头部按钮移到标题右侧;新增「归档空会话(N)」,「清理空会话(N)」只要有已归档空会话就显示,且超过 50 条自动分批预览/删除。
|
|
150
161
|
- `0.1.3` 已发布到 npm / GitHub / Release:三态会话模型(根/分支/子代理),分支默认显示并缩进在父会话下;删除父会话不再级联删掉普通分支;父会话有历史分支时也能移动;兼容声明增加 DSH `0.2.1-rc.3`。
|
|
151
162
|
- `0.1.2` 已发布:空会话默认隐藏、清理空会话、删除范围模态确认。
|
|
152
|
-
-
|
|
163
|
+
- 129 个测试全绿;0.2.0 包 41 个文件 / 628.2 kB(unpacked 978.2 kB)。
|
|
153
164
|
- 市场条目已收录:PR [#9672](https://github.com/awesome-dsh-plugin/awesome-dsh-plugin/pull/9672) 已于 2026-10-27 合并(`check` 与仓库年龄 gate 均通过);卡片版本随 npm 自动更新,当前 0.1.4。
|
|
154
|
-
-
|
|
165
|
+
- 下一项主任务见 [接手说明(0.2.0 之后)](docs/HANDOVER-2026-10-29.md):先完成 0.2.0 的实机只读验收与发版,再安排全文内容搜索、导出、置顶等候选。
|
|
155
166
|
|
|
156
167
|
## 文档索引
|
|
157
168
|
|
|
158
|
-
- [
|
|
169
|
+
- [接手说明(2026-10-27)](docs/HANDOVER-2026-10-27.md)
|
|
170
|
+
- [接手说明(0.2.0 之后)](docs/HANDOVER-2026-10-29.md)
|
|
171
|
+
- [0.2.0 实施计划(overview + 分页 sessions)](docs/PLAN-2026-10-29.md)
|
|
172
|
+
- [0.2.0 发布检查清单](docs/RELEASE-CHECKLIST-0.2.0.md)
|
|
159
173
|
- [实施计划(批准时原样归档)](docs/PLAN-2026-10-26.md)
|
|
160
174
|
- [0.1.0 发布检查清单](docs/RELEASE-CHECKLIST-0.1.0.md)
|
|
161
175
|
- [0.1.1 实施计划](docs/PLAN-2026-10-27.md)
|
package/ROADMAP.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Roadmap
|
|
2
2
|
|
|
3
|
-
> 当前:`0.
|
|
3
|
+
> 当前:`0.2.0` 已在 `main` 实现并测试通过(Host overview + 分页 sessions + 客户端两段式),等待实机验收与发布;线上 npm `latest` 仍为 `0.1.4`。0.2.0 计划与验收见 [docs/PLAN-2026-10-29.md](docs/PLAN-2026-10-29.md) 与 [docs/RELEASE-CHECKLIST-0.2.0.md](docs/RELEASE-CHECKLIST-0.2.0.md)。下一任接手见 [docs/HANDOVER-2026-10-29.md](docs/HANDOVER-2026-10-29.md)。
|
|
4
4
|
|
|
5
5
|
## 0.1.0 — delivered
|
|
6
6
|
|
|
@@ -40,22 +40,23 @@
|
|
|
40
40
|
- 头部三个按钮移到会话管理标题右侧;副标题与统计信息独占下方整行。
|
|
41
41
|
- 空会话:「归档空会话(N)」一键分批归档;「清理空会话(N)」只要有已归档空会话就显示;删除范围预览与删除按 `maxBatch` 分批,超过 50 条也能一次确认完成。
|
|
42
42
|
|
|
43
|
-
## 0.2.0 —
|
|
43
|
+
## 0.2.0 — implemented (awaiting publication)
|
|
44
44
|
|
|
45
|
-
首要目标:真正支撑 1000–10000 条会话,不再首屏拉全量 `state
|
|
45
|
+
首要目标:真正支撑 1000–10000 条会话,不再首屏拉全量 `state`。计划与实施记录见 [docs/PLAN-2026-10-29.md](docs/PLAN-2026-10-29.md)。
|
|
46
46
|
|
|
47
|
-
- `
|
|
48
|
-
- `GET /
|
|
49
|
-
-
|
|
50
|
-
-
|
|
51
|
-
-
|
|
52
|
-
-
|
|
53
|
-
-
|
|
47
|
+
- **零 IO catalog**:`lib/catalog.js` 从 `workspaceRegistry.headers` + `sessionProjectionCache` 组装行;两个内部 seam 特性检测,缺失回退 `buildState` 慢路径。
|
|
48
|
+
- `GET /overview`:工作区计数/归档数/空会话/totals/capabilities/orphans,无会话行;10k 合成约 9.5 ms / 1.3 KB。
|
|
49
|
+
- `GET /sessions`:按 `workspaceId/tab/query/sort/offset/limit` 分页(≤50 行),branch-aware 排序 + `id` tie-break + `parentStub`;10k 单页约 8.8 ms / 25 KB,不触发全量扫描。
|
|
50
|
+
- `GET /search` / `/session` / `/blanks` / `/sizes`:跨工作区标题搜索、详情单行、空会话 id、按工作区/全局大小(一次 `persistence.list()` + 60 s TTL,只聚合可见行)。
|
|
51
|
+
- Client 两段式加载:overview → 展开取页 → 加载更多;搜索防抖走宿主;选择只作用于已加载行;详情独立取数;老 Host 回退 `/state` 并保留每组 50 条本地分页。
|
|
52
|
+
- 兼容:`GET /state` 保留;0.1.x 客户端不受影响。
|
|
53
|
+
- 验收:129 测试全绿(Host 72 + 客户端 vm 57);10k 基准不调用 `persistence.list` / `sessionController.list` / 批量 `readTitleSnapshots`。实机验收与发版待执行,见 [docs/RELEASE-CHECKLIST-0.2.0.md](docs/RELEASE-CHECKLIST-0.2.0.md)。
|
|
54
54
|
|
|
55
55
|
## Later candidates
|
|
56
56
|
|
|
57
57
|
- 侧栏会话「...」菜单快捷入口(生成标题 / 会话管理详情),复用同一套 Host 操作。
|
|
58
|
-
-
|
|
58
|
+
- 内容全文搜索(本部署宿主 FTS 默认关闭且索引不含标题;接入前先确认 composition 与结果模型)。
|
|
59
|
+
- `(sortValue,id)` keyset 游标,替换 0.2.0 的裸 offset 分页,进一步抗数据变化。
|
|
59
60
|
- 导出所选会话为 Markdown / JSON(删除前的安全网;批量)。
|
|
60
61
|
- 置顶 / 取消置顶(`workspaceRegistry.pinSession` / `unpinSession`)。
|
|
61
62
|
- 整枝移动(父会话 + 分支会话 + 子代理后代一起迁移),或在移动时保留父链接。
|