dsh-session-pages 0.0.0-stage → 0.5.6

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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 dsh-plugin contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,3 +1,105 @@
1
- # Temporary Holding Version
1
+ # dsh-session-pages
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ DeepSeek Harness 的第四个对话视图标签:**窗口**(在「对话 / 轨迹 / 轨迹plus」右边)。
4
+
5
+ 会话按**压缩(compaction)分界**切成若干窗口:第一窗从会话开头起算,之后每次压缩的 checkpoint 开头即新一窗。
6
+
7
+ ## 每一窗画两层
8
+
9
+ 一个窗口**就是**两层,所以视图也分两层画:
10
+
11
+ 每个窗口带一个诞生时刻(`startTime`):窗口 1 取日志第一条事件的时间,之后每一窗取其 checkpoint 的时间。投影与折叠两条路径结果一致。
12
+
13
+ **框(frame)—— 这一窗的每一次请求都带在对话前面的东西**
14
+
15
+ | 行 | 来源 | 备注 |
16
+ | --- | --- | --- |
17
+ | 系统提示词 | `system/message` / `developer/message` | 只有会话开头那一条;后续窗口标「沿用上一窗」 |
18
+ | 工具声明 | `request/header` 的 `tools[]` | 只取名字;个数随插件增减,各窗可能不同 |
19
+ | 开窗摘要 | checkpoint 的 `<compacted-summary>` | 折叠显示,点开看全文 |
20
+ | 保留尾部 | checkpoint 事件的 `surfaceOp` | 报替换区间与尾部消息条数;实际重发集合未逐条记录,所以只报区间与计数 |
21
+
22
+ **行(rows)—— 这一窗自己的时间线**
23
+
24
+ 注入(`runtime-context` / `skill-catalog` / `time-context`…)、用户、助手、工具调用、工具结果,按 seq 排。
25
+
26
+ 行是**按需拉取**的,并且**按 200 条切块**:`/state` 只发框(一个长会话 14KB);点「展开明细」拉第 1 块,其余块各自折叠,点块头才请求 `/items?page=N&chunk=K`(每块约 40–60KB)。轮询 10 秒一次,且只在标签打开时。
27
+
28
+ ## 路由
29
+
30
+ | 路由 | 用途 |
31
+ | --- | --- |
32
+ | `GET /dsh-session-pages/state?sessionId=…` | 窗口清单 + 框 + 统计(不含行) |
33
+ | `GET /dsh-session-pages/items?sessionId=…&page=N&chunk=K[&chunkSize=200]` | 一个窗口的一块行 |
34
+
35
+ 两条都只接受 loopback + 同源 Origin,非 GET 一律 405,没有任何写路径。
36
+
37
+
38
+ ## 可选:接入 dsh-log-trim 的裁剪统计
39
+
40
+ 装了 `dsh-log-trim` 时,本插件会读 `~/.dsh/dsh-log-trim/ledger.json`(只读、best-effort),在视图标题行加一句:
41
+
42
+ ```
43
+ 2 个窗口 · 累计裁掉 2 窗 / 1,033 条
44
+ ```
45
+
46
+ 悬停显示最近一次:「最近一次 2026-11-04 12:57 · (裁窗口,3→2 窗) · 已省 921,910 字节」。字节数只在 tooltip 里出现。
47
+
48
+ 没有该包、没有该会话记录、或 JSON 损坏 → 什么都不显示,也不报错。
49
+
50
+ ## 数据从哪来
51
+
52
+ 窗口的计数(轮次、步数、消息数、工具调用、峰值 token、条数)来自**会话投影**,不是每次读日志现算:
53
+
54
+ ```js
55
+ ctx.sessionProjections.register({
56
+ key: 'sessionPages', stateVersion: 1, stateSchema, init, apply,
57
+ })
58
+ ```
59
+
60
+ 运行时每提交一个事件就驱动一次折叠,`/state` 直接读当前状态(`stateOf`)。活会话因此是 O(1),不再重扫日志。
61
+
62
+ 历史(已关闭)会话没有活的投影单元,退回读日志的折叠路径;那次解码按会话缓存 30 秒。
63
+
64
+ 两条路径**逐项对拍过**(`?fold=1` 可强制走折叠做对比):总量、每窗条数、步数、消息数、峰值、摘要字符数全部相等。
65
+
66
+ 实测(2,370 行、2 个窗口的会话):
67
+
68
+ | 路径 | 耗时 |
69
+ | --- | --- |
70
+ | 投影(活会话) | ~2 ms |
71
+ | 折叠(同会话强制) | ~5 ms |
72
+ | 已关闭的大会话(缓存命中) | ~0.8 ms |
73
+
74
+ 再次打开一个 5.2 MB 的旧会话,耗时从 8.5 秒降到毫秒级。
75
+
76
+ ## 已知边界
77
+
78
+ - **保留尾部有区间、没有逐条清单**。checkpoint 事件的 `surfaceOp`(`{op:'replace', startSeq, endSeq}`)记录了被替换的区间,补集即尾部区间,条数可数;但实际重发的集合还受 surface 记账影响,日志没有逐条记录,所以只报区间与条数。
79
+ - **系统提示词按“第一条非空”取**。中途的 developer 更新是追加,不是替换,所以不参与“这一窗的框”。
80
+ - 只到“每行一段”,不展开完整正文(正文按 220/140/260 字符截断,并标出真实长度)。
81
+
82
+ ## 安装
83
+
84
+ ```yaml
85
+ - insert:
86
+ - id: dsh-session-pages
87
+ name: 'dsh-session-pages'
88
+ ```
89
+
90
+ 装进 profile 后刷新页面,在「+」里选 **窗口** 标签。宿主半侧改代码要重载插件(改一次 profile 的 `cordis.patch.yml` 会触发热重载)。
91
+
92
+ ## 配置
93
+
94
+ | 选项 | 默认 | 说明 |
95
+ | --- | --- | --- |
96
+ | `clipChars` | 220 | 消息正文截断 |
97
+ | `toolArgsChars` | 140 | 工具参数截断 |
98
+ | `toolResultChars` | 260 | 工具结果截断 |
99
+ | `maxItemsPerPage` | 20000 | 单窗行数上限(安全阀) |
100
+
101
+ ## 测试
102
+
103
+ ```
104
+ node --test test/*.test.js # 12 条:切窗 / 摘要 / 框继承 / 注入分类 / 懒加载 / 注册契约
105
+ ```
@@ -0,0 +1,13 @@
1
+ # dsh-session-pages bundle patch.
2
+ #
3
+ # One row. The name is the BARE package name on purpose: the client-module
4
+ # scanner resolves <name>/package.json to find the dsh.client declaration, so a
5
+ # subpath entry would be cached as "not a client package" and the browser half
6
+ # would never load.
7
+ #
8
+ # The node half serves the loopback-only GET /dsh-session-pages/state route,
9
+ # which folds one session log into windows. The browser half registers the
10
+ # "windows" conversation view tab.
11
+ - insert:
12
+ - id: dsh-session-pages
13
+ name: 'dsh-session-pages'
package/package.json CHANGED
@@ -1,6 +1,61 @@
1
1
  {
2
2
  "name": "dsh-session-pages",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
6
- }
3
+ "version": "0.5.6",
4
+ "description": "Fourth conversation view for DeepSeek Harness: the session split into windows at every compaction, each window headed by its checkpoint summary.",
5
+ "type": "module",
6
+ "main": "src/index.js",
7
+ "exports": {
8
+ ".": "./src/index.js",
9
+ "./client": "./src/client.js",
10
+ "./logic": "./src/logic.js",
11
+ "./package.json": "./package.json"
12
+ },
13
+ "files": [
14
+ "src",
15
+ "cordis.patch.yml",
16
+ "test",
17
+ "README.md"
18
+ ],
19
+ "keywords": [
20
+ "deepseek-harness",
21
+ "dsh",
22
+ "dsh-plugin",
23
+ "compaction",
24
+ "window",
25
+ "conversation-view"
26
+ ],
27
+ "license": "MIT",
28
+ "engines": {
29
+ "node": ">=22"
30
+ },
31
+ "scripts": {
32
+ "test": "node --test test/*.test.js"
33
+ },
34
+ "dsh": {
35
+ "bundle": {
36
+ "patch": "./cordis.patch.yml"
37
+ },
38
+ "client": {
39
+ "platform": "web",
40
+ "inject": [
41
+ "@deepseek-ai/dsh-client-locale",
42
+ "@deepseek-ai/dsh-client-ui-renderer",
43
+ "@deepseek-ai/dsh-client-ui-conversation"
44
+ ]
45
+ },
46
+ "engines": {
47
+ "dsh": ">=0.1.6-alpha.2"
48
+ }
49
+ },
50
+ "repository": {
51
+ "type": "git",
52
+ "url": "git+https://github.com/DDDMUC/dsh-session-pages.git"
53
+ },
54
+ "homepage": "https://github.com/DDDMUC/dsh-session-pages#readme",
55
+ "bugs": {
56
+ "url": "https://github.com/DDDMUC/dsh-session-pages/issues"
57
+ },
58
+ "publishConfig": {
59
+ "access": "public"
60
+ }
61
+ }