@omdp/dsh-archived-sessions 0.3.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 dsh-archived-sessions 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 ADDED
@@ -0,0 +1,133 @@
1
+ # @omdp/dsh-archived-sessions
2
+
3
+ > Archived-sessions manager for the DeepSeek Harness web UI — fork of [`@muwinds/dsh-archived-sessions`](https://github.com/MuWinds/dsh-archived-sessions) (0.2.0), adapted for DSH **0.1.5-rc.1**.
4
+
5
+ DSH 归档会话管理:在 设置 → 归档会话 中查看、释放、删除已归档会话(支持按树删除子会话、清理孤儿会话)。
6
+
7
+ [English](#english) · [中文](#中文)
8
+
9
+ ---
10
+
11
+ ## 中文
12
+
13
+ ### 这是什么
14
+
15
+ DSH 的会话可以归档(移到「归档云店」),本插件在设置页提供归档会话的管理界面:
16
+
17
+ - **列表**:标题、会话 ID、所属工作区、磁盘占用、创建时间、是否运行中;
18
+ - **释放**:把会话从归档集合移回活动列表(不删数据);
19
+ - **删除**:从硬盘删除会话目录 + 从归档集合移除(两步确认);
20
+ - **按树删除**:删除主会话时,其下的 subagent 子会话(`parentSession` 链)一并删除,不再留孤儿(修复上游 issue #2);
21
+ - **孤儿清理**:一键扫描并清理「父会话已删除、自己还在盘上」的残留子会话目录;
22
+ - **详情**:展开查看会话内容(前 100 条消息)。
23
+
24
+ ### 为什么有这个 fork
25
+
26
+ 上游 `@muwinds/dsh-archived-sessions` 0.2.0 与 DSH **0.1.5-rc.1 不兼容**(作者已一个月未维护):
27
+
28
+ | 症状 | 根因 |
29
+ | --- | --- |
30
+ | 归档列表全部显示「文件缺失」 | 0.1.5-rc.1 的 `sessionPersistence.list()` 返回 `SessionPersistenceSnapshot[]`(`{header, revision, eventCount?, sizeBytes?}`),不再是裸 `SessionHeader[]`;插件按旧形状取值,`header.id` 变 `undefined` |
31
+ | 「删除」和「释放」行为相同(都只移除归档标记) | 0.1.5-rc.1 抽象服务移除了 `locate(meta)`;插件 `persistence.locate(header)` 返回 `undefined` → `.path` 抛 TypeError → 被 catch 吞掉 → 走 `no-artifact` 分支,跳过删目录 |
32
+
33
+ 本 fork 的修复:
34
+
35
+ 1. `list()` 改为识别快照形状,从 `snapshot.header` 取值;优先用快照自带的 `sizeBytes`;
36
+ 2. 不再依赖 `locate()`,改用 DSH JSONL 后端同款路径编码(`encodeSegment` / `projectKey`)自行解析会话目录,并经 `fs.resolve` 确认存在后才操作;
37
+ 3. 删除前校验目录名必须是会话目录(`session-<uuid>` 或裸 UUID),**拒绝删除任何非会话路径**,杜绝误删;
38
+ 4. 删除按 `parentSession` 递归收集整棵子树,连同子会话一起删 + 一起移出归档集合;
39
+ 5. 新增 `/dsh-archived/orphans` 与 `/dsh-archived/sweep`:扫描/清理孤儿子会话(父会话已不在 persistence 中)。
40
+
41
+ ### 安装
42
+
43
+ ```bash
44
+ pnpm add @omdp/dsh-archived-sessions -w
45
+ ```
46
+
47
+ > 若从 `@muwinds/dsh-archived-sessions` 迁移:先在 profile 的 package.json 中移除旧依赖(`github:MuWinds/dsh-archived-sessions`),再安装本包。旧包与新版 API 路由相同(`/dsh-archived/*`),安装后刷新页面即可。
48
+
49
+ ### 要求 / Requirements
50
+
51
+ - DeepSeek Harness **0.1.5-rc.1**(实测版本)
52
+ - `@deepseek-ai/cordis` ^4.0.1(peer)
53
+ - `@deepseek-ai/dsh-session-persistence-jsonl`(可选,随 DSH 自带;缺失时回退到内置路径编码)
54
+
55
+ ### API
56
+
57
+ | 方法 | 请求 | 响应 |
58
+ | --- | --- | --- |
59
+ | `POST /dsh-archived/list` | `{}` | `{ items, totalBytes }` |
60
+ | `POST /dsh-archived/unarchive` | `{ sessionId }` | `{ ok, changed, archivedSessionIds }` |
61
+ | `POST /dsh-archived/delete` | `{ sessionId }` | `{ ok, deleted, sessionId, alsoDeleted[], reason? }` |
62
+ | `POST /dsh-archived/detail` | `{ sessionId }` | `{ id, createdAt, cwd, parentSession, totalEvents, messageCount, truncated, messages }` |
63
+ | `POST /dsh-archived/orphans` | `{}` | `{ items, totalBytes }` |
64
+ | `POST /dsh-archived/sweep` | `{}` | `{ removed, freedBytes, items }` |
65
+
66
+ ### 变更记录
67
+
68
+ - **0.3.0**(2026-09-10):fork 自 0.2.0;适配 DSH 0.1.5-rc.1(list 快照形状 + 路径自解析);按树删除子会话;孤儿清理;删除路径安全校验。
69
+
70
+ ---
71
+
72
+ ## English
73
+
74
+ ### What is this
75
+
76
+ DSH sessions can be archived; this plugin adds an archived-session manager under **Settings → 归档会话**:
77
+
78
+ - **List**: title, session ID, workspace, disk usage, created time, running state;
79
+ - **Release** (释放): move a session out of the archive set back to active (no data deleted);
80
+ - **Delete** (删除): delete the session directory from disk + remove from the archive set (two-step confirm);
81
+ - **Tree delete**: deleting a main session also deletes its subagent children (`parentSession` chain) — fixes upstream issue #2;
82
+ - **Orphan sweep**: scan and clean leftover subagent dirs whose parent session is already gone;
83
+ - **Detail**: expand to read the session content (first 100 messages).
84
+
85
+ ### Why this fork
86
+
87
+ Upstream `@muwinds/dsh-archived-sessions` 0.2.0 is **incompatible with DSH 0.1.5-rc.1** (author unmaintained for a month):
88
+
89
+ | Symptom | Root cause |
90
+ | --- | --- |
91
+ | All archived items show 文件缺失 (missing) | 0.1.5-rc.1 `sessionPersistence.list()` returns `SessionPersistenceSnapshot[]` (`{header, revision, eventCount?, sizeBytes?}`), not bare `SessionHeader[]`; the plugin read the old shape, so `header.id` was `undefined` |
92
+ | Delete behaves like Release (both only prune the archive id) | 0.1.5-rc.1 removed `locate(meta)` from the abstract service; `persistence.locate(header)` returned `undefined` → `.path` threw TypeError → swallowed by catch → `no-artifact` branch skipped the disk deletion |
93
+
94
+ Fixes in this fork:
95
+
96
+ 1. `list()` recognizes the snapshot shape and reads `snapshot.header`; prefers the snapshot's `sizeBytes`;
97
+ 2. No longer uses `locate()`; resolves the session directory with the same path encoding as the DSH JSONL backend (`encodeSegment` / `projectKey`), confirmed via `fs.resolve`;
98
+ 3. Refuses to delete anything whose directory name is not a session dir (`session-<uuid>` or bare UUID) — no accidental deletions;
99
+ 4. Delete collects the whole `parentSession` subtree recursively and removes children together (dirs + archive set);
100
+ 5. New `/dsh-archived/orphans` and `/dsh-archived/sweep` to scan/clean orphan subagent sessions (parent no longer in persistence).
101
+
102
+ ### Install
103
+
104
+ ```bash
105
+ pnpm add @omdp/dsh-archived-sessions -w
106
+ ```
107
+
108
+ > Migrating from `@muwinds/dsh-archived-sessions`: remove the old dependency (`github:MuWinds/dsh-archived-sessions`) from the profile package.json first, then install this package. Same API routes (`/dsh-archived/*`); refresh the page after installing.
109
+
110
+ ### Requirements
111
+
112
+ - DeepSeek Harness **0.1.5-rc.1** (tested version)
113
+ - `@deepseek-ai/cordis` ^4.0.1 (peer)
114
+ - `@deepseek-ai/dsh-session-persistence-jsonl` (optional, ships with DSH; falls back to the built-in path encoding when absent)
115
+
116
+ ### API
117
+
118
+ | Method | Request | Response |
119
+ | --- | --- | --- |
120
+ | `POST /dsh-archived/list` | `{}` | `{ items, totalBytes }` |
121
+ | `POST /dsh-archived/unarchive` | `{ sessionId }` | `{ ok, changed, archivedSessionIds }` |
122
+ | `POST /dsh-archived/delete` | `{ sessionId }` | `{ ok, deleted, sessionId, alsoDeleted[], reason? }` |
123
+ | `POST /dsh-archived/detail` | `{ sessionId }` | `{ id, createdAt, cwd, parentSession, totalEvents, messageCount, truncated, messages }` |
124
+ | `POST /dsh-archived/orphans` | `{}` | `{ items, totalBytes }` |
125
+ | `POST /dsh-archived/sweep` | `{}` | `{ removed, freedBytes, items }` |
126
+
127
+ ### Changelog
128
+
129
+ - **0.3.0** (2026-09-10): forked from 0.2.0; DSH 0.1.5-rc.1 support (snapshot list shape + self path resolution); tree delete; orphan sweep; deletion path safety check.
130
+
131
+ ## License
132
+
133
+ MIT — original by MuWinds (upstream package), fork maintained by XJungit.
@@ -0,0 +1,7 @@
1
+ # dsh bundle patch: inserts this plugin into a profile's layer stack.
2
+ # One row drives both halves: the host API (lib/index.js, injects webServer)
3
+ # and the browser UI (lib/client.js, discovered through the dsh.client
4
+ # declaration in package.json).
5
+ - insert:
6
+ - id: archived-sessions
7
+ name: '@omdp/dsh-archived-sessions'
package/package.json ADDED
@@ -0,0 +1,48 @@
1
+ {
2
+ "name": "@omdp/dsh-archived-sessions",
3
+ "version": "0.3.0",
4
+ "description": "Archived-sessions manager for the DeepSeek Harness web UI: list / unarchive / delete / detail from Settings. · DSH 归档会话管理:设置页查看、释放、删除已归档会话(含按树删除子会话与孤儿清理)。",
5
+ "type": "module",
6
+ "main": "lib/index.js",
7
+ "exports": {
8
+ ".": "./lib/index.js",
9
+ "./client": "./lib/client.js",
10
+ "./cordis.patch.yml": "./cordis.patch.yml",
11
+ "./package.json": "./package.json"
12
+ },
13
+ "files": [
14
+ "lib",
15
+ "cordis.patch.yml",
16
+ "README.md",
17
+ "LICENSE"
18
+ ],
19
+ "keywords": [
20
+ "deepseek-harness",
21
+ "dsh",
22
+ "dsh-plugin",
23
+ "archived-sessions",
24
+ "session-management"
25
+ ],
26
+ "license": "MIT",
27
+ "repository": {
28
+ "type": "git",
29
+ "url": "git+https://github.com/XJungit/omdp.git",
30
+ "directory": "dsh-archived-sessions"
31
+ },
32
+ "dsh": {
33
+ "bundle": {
34
+ "patch": "./cordis.patch.yml"
35
+ },
36
+ "client": {
37
+ "inject": [
38
+ "@deepseek-ai/dsh-client-runtime",
39
+ "@deepseek-ai/dsh-client-ui-slots",
40
+ "@deepseek-ai/dsh-client-ui-settings"
41
+ ],
42
+ "platform": "web"
43
+ }
44
+ },
45
+ "peerDependencies": {
46
+ "@deepseek-ai/cordis": "^4.0.1"
47
+ }
48
+ }