dsh-delete-session 0.1.9 → 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/LICENSE +21 -21
- package/README.md +201 -96
- package/cordis.patch.yml +7 -7
- package/package.json +3 -2
- package/src/client.js +1450 -415
- package/src/index.js +2007 -517
- package/test/artifacts.host.test.js +953 -0
- package/test/checkbox.dom.test.js +1844 -0
package/LICENSE
CHANGED
|
@@ -1,21 +1,21 @@
|
|
|
1
|
-
MIT License
|
|
2
|
-
|
|
3
|
-
Copyright (c) 2026 DDDMUC
|
|
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.
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 DDDMUC
|
|
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,6 +1,9 @@
|
|
|
1
1
|
# dsh-delete-session
|
|
2
2
|
|
|
3
|
-
**DeepSeek Harness 会话删除插件 —— 在侧边栏会话菜单里直接删除会话。**
|
|
3
|
+
**DeepSeek Harness 会话删除插件 —— 在侧边栏会话菜单里直接删除会话。**
|
|
4
|
+
|
|
5
|
+
给 DSH Web 侧边栏的会话 `...` 菜单(重命名 / 分叉 / 归档)补上「删除会话」,并可选地把这个对话产出的文件一起收走。
|
|
6
|
+
删除默认进**系统回收站**,点错了能还原;想彻底抹掉就在设置里关掉那个开关。
|
|
4
7
|
|
|
5
8
|
[中文](#中文) · [English](#english)
|
|
6
9
|
|
|
@@ -8,30 +11,24 @@
|
|
|
8
11
|
|
|
9
12
|
## 中文
|
|
10
13
|
|
|
11
|
-
<div align="center">
|
|
12
|
-
<a href="https://raw.githubusercontent.com/DDDMUC/dsh-delete-session/main/assets/menu.jpg">
|
|
13
|
-
<img src="https://raw.githubusercontent.com/DDDMUC/dsh-delete-session/main/assets/menu.jpg" alt="侧边栏会话菜单里的删除会话" width="820" />
|
|
14
|
-
</a>
|
|
15
|
-
<br>
|
|
16
|
-
<sub>▲ 侧边栏会话菜单里的「删除会话」(红色)</sub>
|
|
17
|
-
</div>
|
|
18
|
-
|
|
19
14
|
### 为什么需要它
|
|
20
15
|
|
|
21
|
-
DSH 侧边栏的会话菜单只有**重命名 / 分叉 /
|
|
16
|
+
DSH 侧边栏的会话菜单只有**重命名 / 分叉 / 归档**——归档只是把会话藏起来,**不删数据**;而插件全家桶里的「会话归档管理」在设置深处,删一个会话要跳好几个界面。
|
|
22
17
|
|
|
23
18
|
这个插件把「删除」放回你最常点的位置:会话行的 `...` 菜单。
|
|
24
19
|
|
|
25
20
|
### 特性
|
|
26
21
|
|
|
27
|
-
- **菜单内删除** ——
|
|
28
|
-
-
|
|
29
|
-
-
|
|
30
|
-
-
|
|
31
|
-
-
|
|
32
|
-
-
|
|
22
|
+
- **菜单内删除** —— 注册进宿主官方槽位 `sidebar.workspaces.session.menu.item`,紧挨「归档会话」下方多出「删除会话」;会话 ID 由宿主直接注入,永远作用于你点的那一行,**不会切换当前会话**
|
|
23
|
+
- **删除至系统回收站(默认开)** —— 会话日志、工作区记账与投影缓存一并进**系统回收站**:Windows 回收站、macOS 废纸篓、Linux 的 `gio trash`。删错了从回收站还原即可。设置页可以关掉它,关掉后就是**直接从硬盘移除,不可恢复**
|
|
24
|
+
- **对话框文案跟随开关** —— 勾选时写「并放进系统回收站」,取消勾选时写「永久删除…不可恢复」。你看到的永远是你实际会得到的
|
|
25
|
+
- **风险确认** —— 每次删除弹出确认对话框,显示会话标题与 ID。要不要弹这个框**只在设置页改**,弹窗里没有快捷勾选;**按住 Shift 点击**可以临时强制弹窗
|
|
26
|
+
- **多选批量删除** —— 会话菜单「多选」进入选择模式:勾选多行后底部操作条显示「已选 N 个 / 取消 / 删除」;点删除立即批量执行,被选中的行乐观隐藏、操作条实时显示进度,客户端 6 路并发、工作区记账串行;失败的行恢复显示并保持选中,方便重试;Esc 退出
|
|
27
|
+
- **产出文件隔离(可选,默认关闭)** —— 打开后,删除会话时还能把这个对话在工作目录里产出的文件**移进隔离夹**,而不是直接删掉;范围可选「仅新建」或「新建的和改过的」,模式可选「全部直接隔离」或「先列清单由你勾选」
|
|
28
|
+
- **跳过 git 仓库内的文件(默认开)** —— 在项目里干过活的对话,产出文件里往往就是项目源码。开启后仓库内的文件一律不碰,避免删一个对话把项目搬空
|
|
29
|
+
- **删除后回到新会话** —— 若删除的正是当前打开的会话,自动切到一个全新会话,而不是落到已不可用的邻居页
|
|
33
30
|
- **默认安全** —— 宿主路由仅限本机回环(回环 socket + 回环 Host 头 + 同源校验);被 DSH 打开占用的会话会被明确拒绝(409),绝不与活跃写者竞争
|
|
34
|
-
- **中英双语** ——
|
|
31
|
+
- **中英双语** —— 菜单项、对话框与设置页跟随 DSH 界面语言(zh / en)
|
|
35
32
|
- **零依赖** —— 不引入任何 DSH SDK,所有服务(`sessions` / `sessionPersistence` / `agents` / `workspaceRegistry` / `webServer`)都在调用时通过 cordis 上下文获取
|
|
36
33
|
|
|
37
34
|
### 安装
|
|
@@ -42,7 +39,7 @@ npm(推荐):
|
|
|
42
39
|
dsh plugin --profile web add dsh-delete-session
|
|
43
40
|
```
|
|
44
41
|
|
|
45
|
-
或从 GitHub
|
|
42
|
+
或从 GitHub 直接安装:
|
|
46
43
|
|
|
47
44
|
```sh
|
|
48
45
|
dsh plugin --profile web add github:DDDMUC/dsh-delete-session
|
|
@@ -52,47 +49,105 @@ dsh plugin --profile web add github:DDDMUC/dsh-delete-session
|
|
|
52
49
|
|
|
53
50
|
### 使用
|
|
54
51
|
|
|
55
|
-
1.
|
|
56
|
-
2.
|
|
57
|
-
3.
|
|
58
|
-
4.
|
|
59
|
-
5.
|
|
52
|
+
1. 鼠标移到侧边栏的会话行,点 `...`
|
|
53
|
+
2. 选择「删除会话」
|
|
54
|
+
3. 首次会弹确认框;不想再看到它,去插件管理页关掉「删除时询问」
|
|
55
|
+
4. 删错了:打开系统回收站,找到 `session-<id>` 与 `session-<id>.json`,还原即可
|
|
56
|
+
5. 批量:会话菜单 →「多选」→ 勾选多个 → 底部「删除」;Esc 或「取消」退出
|
|
57
|
+
|
|
58
|
+
### 设置项一览
|
|
59
|
+
|
|
60
|
+
插件管理页 → dsh-delete-session:
|
|
61
|
+
|
|
62
|
+
| 设置 | 默认 | 作用 |
|
|
63
|
+
| --- | --- | --- |
|
|
64
|
+
| 删除时询问 | 开 | 关掉后点菜单项直接删,不弹框(但产出文件选「先列清单」时仍会弹,清单只在对话框里) |
|
|
65
|
+
| **删除至回收站** | **开** | 开:进系统回收站,可还原。关:直接从硬盘移除,不可恢复 |
|
|
66
|
+
| 不处理产出文件 | 开 | 打开本项表示**不**处理产出文件,与旧版行为一致 |
|
|
67
|
+
| 产出文件默认全部进隔离夹 | 关 | 关:先列清单由你勾选;开:整批自动移走,不列清单也不扫描 |
|
|
68
|
+
| 范围:仅新建 / 新建的和改过的 | 仅新建 | 只动对话自己创建的文件,还是连它改写过的既有文件一起 |
|
|
69
|
+
| **跳过 git 仓库内的文件** | **开** | 仓库内的文件一律不碰 |
|
|
70
|
+
| 隔离夹保存位置 | 空(= `$DSH_HOME`) | 可手输、可点「选择文件夹…」调系统对话框、可点「打开」在资源管理器里定位 |
|
|
71
|
+
|
|
72
|
+
### 删除之后文件在哪
|
|
73
|
+
|
|
74
|
+
| 平台 | 去处 |
|
|
75
|
+
| --- | --- |
|
|
76
|
+
| Windows | 系统回收站(`Microsoft.VisualBasic.FileIO.FileSystem` 的 SendToRecycleBin) |
|
|
77
|
+
| macOS | 废纸篓(Finder,经 `osascript`) |
|
|
78
|
+
| Linux | 桌面回收站(`gio trash`) |
|
|
79
|
+
| 以上不可用时 | `$DSH_HOME/session-trash-<时间戳>-<pid>-<序号>/`,手工搬回 |
|
|
80
|
+
|
|
81
|
+
顺序是**先 rename 到暂存区,再在后台送进回收站**:改路径是微秒级,而系统回收站操作要 ~600ms,所以界面不会等你。后台失败时文件仍在暂存区,不会丢。
|
|
82
|
+
|
|
83
|
+
**取消勾选「删除至回收站」后**,目录用 `rm` 直接移除,暂存区不留副本,回收站里也没有。
|
|
84
|
+
|
|
85
|
+
### 产出文件隔离
|
|
86
|
+
|
|
87
|
+
这一档**默认关闭**。打开后(插件管理页 → dsh-delete-session),删除会话时除了对话记录,还会处理**这个对话在工作目录里碰过的文件**:
|
|
60
88
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
<br>
|
|
66
|
-
<sub>▲ 删除确认对话框(首次删除)</sub>
|
|
67
|
-
</div>
|
|
89
|
+
| 范围 | 处理什么 |
|
|
90
|
+
| --- | --- |
|
|
91
|
+
| 仅新建的文件(默认) | 本对话自己创建的文件 |
|
|
92
|
+
| 新建的和改过的文件 | 再加上被本对话改写的**既有**文件 —— 移走它们会改变工作目录里原本的内容 |
|
|
68
93
|
|
|
69
|
-
|
|
94
|
+
- **移动,不删除**:文件进 `$DSH_HOME/purge-quarantine-<时间戳>/`,保留相对于工作目录的路径。每次删除**独占**一个新的隔离目录(同名已存在时自动让位),且**永不覆盖**已有文件
|
|
95
|
+
- **先算后动**:删除前由宿主端从会话日志重新推导清单;界面里勾选的结果只能缩小范围,不能扩大
|
|
96
|
+
- **「新建」怎么判定**:依据 `fs-observation-policy` 的不变量 —— `write` 覆盖既有文件前必须先成功 `read` 它,所以"首次写之前没有成功读过"就是新建。判定按**文件身份**而非路径拼写:软链接别名、Windows 上仅大小写不同的写法,都算同一个文件
|
|
97
|
+
- **四道安全过滤**:必须是普通文件、真实路径严格在工作目录内、不在 `$DSH_HOME` 内、必须仍然存在;被跳过的一律在对话框里列出原因
|
|
98
|
+
- **批量删除不走这一档**:只有单条删除会处理产出文件
|
|
70
99
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
-
|
|
100
|
+
### 与 dsh-session-relocate 协作(可选)
|
|
101
|
+
|
|
102
|
+
装了 [dsh-session-relocate](https://github.com/DDDMUC/dsh-session-relocate) 时,多选底栏会多出「移动」,可以把选中的会话整批搬到另一个工作区。
|
|
103
|
+
|
|
104
|
+
两边靠一组公开能力位对接,缺任一侧都只是少一个按钮,不影响删除:
|
|
105
|
+
|
|
106
|
+
- 本插件在 `apply()` 时设置 `window.__DSH_DELETE_SESSION__ = { supportsBulkMove: true }`,并派发 `dsh-session-delete:ready`
|
|
107
|
+
- relocate 据此隐藏自己那套批量入口,并暴露 `window.__DSH_SESSION_RELOCATE__.moveSelection(ids, { onProgress })`
|
|
108
|
+
- 返回值固定为 `{ canceled?, moved, failed, skipped, total, results }`;缺字段会被当作错误报出来,不做兜底猜测
|
|
109
|
+
|
|
110
|
+
### 速度
|
|
111
|
+
|
|
112
|
+
| 操作 | 耗时 |
|
|
113
|
+
| --- | --- |
|
|
114
|
+
| 删除(勾选回收站) | ~60 ms 返回,回收站在后台完成 |
|
|
115
|
+
| 删除(不勾选) | ~10 ms |
|
|
116
|
+
| 打开系统文件夹对话框 | ~120 ms(编译过的 helper),首次编译在插件加载时后台完成 |
|
|
117
|
+
| 产出文件扫描 | 1000 次工具调用的长会话约 20 ms |
|
|
118
|
+
|
|
119
|
+
两个 helper(选目录、送回收站)是首次使用时用 `csc.exe` 编译成小 exe 缓存在 `$DSH_HOME/cache/dsh-delete-session/`;插件加载时就后台编译好,第一次点击不用等。没有 `csc` 的机器自动回退到 PowerShell 路径,只是慢一些。
|
|
74
120
|
|
|
75
121
|
### 测试
|
|
76
122
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
123
|
+
```
|
|
124
|
+
node test/artifacts.host.test.js # 59 项,宿主半
|
|
125
|
+
node test/checkbox.dom.test.js # 67 项,客户端半
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
客户端测试把真实的 `src/client.js` 跑在一个可读的 DOM 实现上,经由**注册进槽位的组件**、它们渲染出的元素树、以及插件自己生成的 DOM 来驱动。宿主测试驱动真实的 `src/index.js`,覆盖"新建 vs 改过"的判定、每一道安全过滤、隔离移动保留目录结构、git 跳过、回收站与直接删除的分支。
|
|
129
|
+
|
|
130
|
+
两条测试都做过**变异验证**:把实现改回旧写法或改坏,对应断言必须变红。这一步抓出过几条"看起来测了、其实没测到"的地方(例如扫描请求里的字段、宿主侧的开关分支)。
|
|
82
131
|
|
|
83
132
|
### 已知限制
|
|
84
133
|
|
|
85
|
-
-
|
|
86
|
-
-
|
|
87
|
-
-
|
|
88
|
-
-
|
|
134
|
+
- **取消勾选「删除至回收站」后不可恢复**,没有撤销
|
|
135
|
+
- **系统回收站有每盘容量上限**:超出时 Windows 会永久删除而不是报错。会话只有 KB~MB,实际碰不到
|
|
136
|
+
- **macOS 首次使用会请求 Finder 自动化权限**,拒绝后文件留在暂存目录,不会假装删掉
|
|
137
|
+
- 被 DSH 打开占用的会话:删除会自动等待写所有权释放(通常几秒)后完成;极少数仍被占用时提示稍后重试或重启 DSH
|
|
138
|
+
- 多选勾选框仍是对会话行的 DOM 装饰,依赖宿主 `data-row-key="session:<id>"`;核心 UI 若改名,多选会静默失效(**菜单与对话框不受影响**,它们走官方槽位)
|
|
139
|
+
- 产出文件清理默认关闭,打开后仍有几条边界:`bash` / `pwsh` 里创建的文件(`npm run build`、`git clone`、`> file`)**永远检测不到**;**目录永不移走**;清单上限 500 条;**没有还原界面**,隔离夹靠手工搬回
|
|
140
|
+
- 「新建 vs 改过」的判定依赖 `fs-observation-policy` 保持启用
|
|
141
|
+
- 批量删除(多选)**不**处理产出文件
|
|
142
|
+
- 暂存目录与隔离夹**没有自动清理**,会一直堆在 `$DSH_HOME` 下
|
|
89
143
|
|
|
90
144
|
### 兼容性
|
|
91
145
|
|
|
92
|
-
- DSH `0.1
|
|
146
|
+
- **宿主半**在 DSH `0.2.1-rc.2` 上实测通过:回环 socket、Host 头、跨站 Origin 守卫、会话 ID 校验、405/404 路径
|
|
147
|
+
- **客户端半**在 DSH `0.2.1-rc.2` 上实测通过;槽位迁移后的版本已在浏览器里实跑
|
|
93
148
|
- 宿主链路对缺少服务的旧版本会退化为纯文件系统清理
|
|
94
149
|
|
|
95
|
-
如果这个插件帮到了你,欢迎给仓库点个 ⭐([GitHub](https://github.com/DDDMUC/dsh-delete-session)
|
|
150
|
+
如果这个插件帮到了你,欢迎给仓库点个 ⭐([GitHub](https://github.com/DDDMUC/dsh-delete-session))。
|
|
96
151
|
|
|
97
152
|
### License
|
|
98
153
|
|
|
@@ -102,91 +157,141 @@ MIT
|
|
|
102
157
|
|
|
103
158
|
## English
|
|
104
159
|
|
|
105
|
-
<div align="center">
|
|
106
|
-
<a href="https://raw.githubusercontent.com/DDDMUC/dsh-delete-session/main/assets/menu.jpg">
|
|
107
|
-
<img src="https://raw.githubusercontent.com/DDDMUC/dsh-delete-session/main/assets/menu.jpg" alt="Delete session in the sidebar menu" width="820" />
|
|
108
|
-
</a>
|
|
109
|
-
<br>
|
|
110
|
-
<sub>▲ "Delete session" (red) in the sidebar session menu</sub>
|
|
111
|
-
</div>
|
|
112
|
-
|
|
113
160
|
### Why you need it
|
|
114
161
|
|
|
115
|
-
The DSH sidebar session menu
|
|
162
|
+
The DSH sidebar session menu offers **Rename / Fork / Archive** — and archiving only hides a session, it does not delete data. The "session archive manager" in the settings deep-dive takes several screens per session.
|
|
116
163
|
|
|
117
|
-
This plugin puts Delete back where you already click: the session row's `...` menu.
|
|
164
|
+
This plugin puts **Delete** back where you already click: the session row's `...` menu.
|
|
118
165
|
|
|
119
166
|
### Features
|
|
120
167
|
|
|
121
|
-
- **Delete from the menu** —
|
|
122
|
-
- **
|
|
123
|
-
- **
|
|
124
|
-
- **
|
|
125
|
-
- **
|
|
126
|
-
- **
|
|
127
|
-
- **
|
|
128
|
-
- **
|
|
129
|
-
- **
|
|
168
|
+
- **Delete from the menu** — registered through the official `sidebar.workspaces.session.menu.item` slot, right under "Archive session". The session id is injected by the host, so it always targets the row you clicked and **never switches the open session**
|
|
169
|
+
- **Delete to the system trash (on by default)** — the session log, workspace accounting and projection cache go to the **system trash**: the Windows Recycle Bin, the macOS Trash, or `gio trash` on Linux. A wrong click is restored from the trash. The settings page can turn it off, and then the delete removes the files from the disk for good
|
|
170
|
+
- **The sentence matches the switch** — checked says "…and puts them in the system trash"; unchecked says "permanently deletes… cannot be undone". What you read is what you get
|
|
171
|
+
- **Confirmation dialog** — shows the session title and id. Whether a delete asks is changed on the plugin page only, never from the dialog; Shift-click forces the dialog back
|
|
172
|
+
- **Multi-select batch delete** — enter selection mode from the session menu, tick rows, then Delete: rows hide optimistically, the bar reports progress, six requests run in parallel while workspace accounting stays serial, failures come back visible and still selected, Esc leaves
|
|
173
|
+
- **Produced-file quarantine (optional, off by default)** — when enabled, a delete also moves the files this conversation produced in its working directory into a quarantine folder instead of destroying them. Scope: files it created, or those plus files it rewrote. Mode: list them for you to tick, or move the whole set
|
|
174
|
+
- **Skip files inside git repositories (on by default)** — a conversation that worked in a project produces that project's source. With this on, nothing inside a repository is touched
|
|
175
|
+
- **Lands on a fresh session** — deleting the session you are looking at switches to a new one instead of an unusable neighbour page
|
|
176
|
+
- **Safe by default** — host routes are loopback-only (loopback socket, loopback Host header, same-origin check); a session the host still holds open is refused with 409 rather than raced
|
|
177
|
+
- **Bilingual** — menu rows, dialog and settings follow the DSH UI language (zh / en)
|
|
178
|
+
- **Zero dependencies** — no DSH SDK import; `sessions`, `sessionPersistence`, `agents`, `workspaceRegistry` and `webServer` are all resolved from the cordis context at call time
|
|
130
179
|
|
|
131
180
|
### Install
|
|
132
181
|
|
|
133
|
-
From npm (recommended):
|
|
134
|
-
|
|
135
182
|
```sh
|
|
136
183
|
dsh plugin --profile web add dsh-delete-session
|
|
137
184
|
```
|
|
138
185
|
|
|
139
|
-
|
|
186
|
+
or straight from GitHub:
|
|
140
187
|
|
|
141
188
|
```sh
|
|
142
189
|
dsh plugin --profile web add github:DDDMUC/dsh-delete-session
|
|
143
190
|
```
|
|
144
191
|
|
|
145
|
-
Restart `dsh web`
|
|
192
|
+
Restart `dsh web` afterwards.
|
|
146
193
|
|
|
147
194
|
### Usage
|
|
148
195
|
|
|
149
|
-
1. Hover a session row in the sidebar and click `...`
|
|
150
|
-
2. Pick "Delete session"
|
|
151
|
-
3.
|
|
152
|
-
4.
|
|
153
|
-
5. Batch
|
|
196
|
+
1. Hover a session row in the sidebar and click `...`
|
|
197
|
+
2. Pick "Delete session"
|
|
198
|
+
3. Confirm; to stop seeing the dialog, turn off "Ask before deleting" on the plugin page
|
|
199
|
+
4. Deleted by mistake? Open the system trash, restore `session-<id>` and `session-<id>.json`
|
|
200
|
+
5. Batch: session menu → "Select multiple" → tick rows → Delete; Esc leaves
|
|
201
|
+
|
|
202
|
+
### Settings
|
|
203
|
+
|
|
204
|
+
Plugin manager → dsh-delete-session:
|
|
205
|
+
|
|
206
|
+
| Setting | Default | Effect |
|
|
207
|
+
| --- | --- | --- |
|
|
208
|
+
| Ask before deleting | On | Off deletes straight from the menu. Ask mode for produced files still opens the dialog, because the list lives there |
|
|
209
|
+
| **Delete to the system trash** | **On** | On: the trash, restorable. Off: removed from the disk for good |
|
|
210
|
+
| Do not handle produced files | On | Ticked means the produced-file feature is off and a delete behaves like the old version |
|
|
211
|
+
| Move every produced file automatically | Off | Off lists them for you to tick; on moves the whole set with no listing and no scan |
|
|
212
|
+
| Scope: created only / created and changed | created only | Whether files this conversation rewrote are included |
|
|
213
|
+
| **Skip files inside git repositories** | **On** | Nothing inside a repository is touched |
|
|
214
|
+
| Quarantine folder | empty (= `$DSH_HOME`) | Typed, chosen with the system folder dialog, or opened in the file manager |
|
|
215
|
+
|
|
216
|
+
### Where the files go
|
|
217
|
+
|
|
218
|
+
| Platform | Destination |
|
|
219
|
+
| --- | --- |
|
|
220
|
+
| Windows | The Recycle Bin (`Microsoft.VisualBasic.FileIO.FileSystem`, SendToRecycleBin) |
|
|
221
|
+
| macOS | The Trash, through Finder via `osascript` |
|
|
222
|
+
| Linux | The desktop trash, through `gio trash` |
|
|
223
|
+
| None available | `$DSH_HOME/session-trash-<stamp>-<pid>-<n>/`, moved back by hand |
|
|
224
|
+
|
|
225
|
+
The order is **rename into a staging folder, then hand it to the trash in the background**: a rename costs microseconds while the shell's trash operation costs ~600 ms, so the UI never waits for it. If the background call fails the files simply stay staged.
|
|
226
|
+
|
|
227
|
+
**With "Delete to the system trash" unchecked**, the directory is removed outright: nothing staged, nothing in the trash.
|
|
228
|
+
|
|
229
|
+
### Produced-file quarantine
|
|
230
|
+
|
|
231
|
+
Off by default. When enabled, a delete also handles the files this conversation touched inside its working directory:
|
|
154
232
|
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
<br>
|
|
160
|
-
<sub>▲ The confirmation dialog (first delete)</sub>
|
|
161
|
-
</div>
|
|
233
|
+
| Scope | What moves |
|
|
234
|
+
| --- | --- |
|
|
235
|
+
| Only files it created (default) | Files this conversation created |
|
|
236
|
+
| Created and changed | Plus pre-existing files it rewrote — moving them changes what was already there |
|
|
162
237
|
|
|
163
|
-
|
|
238
|
+
- **Moved, never deleted**: into `$DSH_HOME/purge-quarantine-<stamp>/`, keeping the path relative to the working directory. Every delete claims its own folder and never overwrites an existing file
|
|
239
|
+
- **Derived first, then moved**: the host re-derives the list from the session log; ticking in the dialog can only narrow it
|
|
240
|
+
- **How "created" is decided**: from the `fs-observation-policy` invariant — a `write` that overwrites must be preceded by a successful `read`, so "first write with no successful read before it" means created. Identity, not spelling: symlink aliases and case-only differences on Windows are the same file
|
|
241
|
+
- **Four safety filters**: a regular file, its real path strictly inside the working directory, outside `$DSH_HOME`, and still present. Anything skipped is listed with its reason
|
|
242
|
+
- **Batch delete never touches produced files**
|
|
164
243
|
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
-
|
|
244
|
+
### Interop with dsh-session-relocate (optional)
|
|
245
|
+
|
|
246
|
+
With [dsh-session-relocate](https://github.com/DDDMUC/dsh-session-relocate) installed, the multi-select bar gains a "Move" button that relocates the selected sessions to another workspace.
|
|
247
|
+
|
|
248
|
+
The two sides meet over public capability bits; either side missing just means one button fewer:
|
|
249
|
+
|
|
250
|
+
- This plugin sets `window.__DSH_DELETE_SESSION__ = { supportsBulkMove: true }` in `apply()` and dispatches `dsh-session-delete:ready`
|
|
251
|
+
- Relocate uses that to hide its own bulk entry and exposes `window.__DSH_SESSION_RELOCATE__.moveSelection(ids, { onProgress })`
|
|
252
|
+
- The result is fixed at `{ canceled?, moved, failed, skipped, total, results }`; missing fields are reported as an error rather than guessed
|
|
253
|
+
|
|
254
|
+
### Speed
|
|
255
|
+
|
|
256
|
+
| Operation | Cost |
|
|
257
|
+
| --- | --- |
|
|
258
|
+
| Delete (trash on) | returns in ~60 ms, the trash finishes in the background |
|
|
259
|
+
| Delete (trash off) | ~10 ms |
|
|
260
|
+
| System folder dialog | ~120 ms with the compiled helper; the first compile runs at plugin load |
|
|
261
|
+
| Produced-file scan | ~20 ms for a 1000-tool-call session |
|
|
262
|
+
|
|
263
|
+
Both helpers (folder picker, trash) are compiled once with `csc.exe` into `$DSH_HOME/cache/dsh-delete-session/` and reused. The compilation starts in the background when the plugin loads, so the first click does not pay for it. A machine without `csc` falls back to the PowerShell path — slower, same behaviour.
|
|
168
264
|
|
|
169
265
|
### Tests
|
|
170
266
|
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
267
|
+
```
|
|
268
|
+
node test/artifacts.host.test.js # 59, host half
|
|
269
|
+
node test/checkbox.dom.test.js # 67, client half
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
The client tests run the real `src/client.js` against a readable DOM, driven through the components it registers into slots, the element tree they render and the DOM the plugin produces. The host tests drive the real `src/index.js`: created-vs-changed classification, every safety filter, quarantine moving with directory structure, git skipping, and the trash/permanent branches.
|
|
273
|
+
|
|
274
|
+
Both suites are **mutation-checked**: reverting an implementation or breaking it must turn the matching assertions red. That step has caught several "looks tested, isn't" spots — the scan request field, and the host-side switch branch among them.
|
|
176
275
|
|
|
177
276
|
### Known limitations
|
|
178
277
|
|
|
179
|
-
-
|
|
180
|
-
- The
|
|
181
|
-
-
|
|
182
|
-
-
|
|
278
|
+
- **Unchecking "Delete to the system trash" is not recoverable** — there is no undo
|
|
279
|
+
- **The system trash has a per-volume size cap**: over it Windows deletes permanently instead of complaining. Sessions are KB–MB, so this does not come up in practice
|
|
280
|
+
- **macOS asks for Finder automation permission the first time**; denied, the files stay in the staging folder rather than pretending the delete happened
|
|
281
|
+
- A session the host holds open is waited for (usually seconds); in rare cases it asks you to retry or restart DSH
|
|
282
|
+
- The multi-select tick is still a DOM decoration on session rows and depends on `data-row-key="session:<id>"`. If core UI renames it, multi-select goes quiet (the menu and dialog are unaffected — they use official slots)
|
|
283
|
+
- Produced-file handling is off by default and still has edges: files created inside `bash` / `pwsh` (`npm run build`, `git clone`, `> file`) are **never detected**; **directories are never moved**; the list caps at 500; there is **no restore UI** — move files back from the quarantine by hand
|
|
284
|
+
- Created-vs-changed depends on `fs-observation-policy` staying enabled
|
|
285
|
+
- Batch delete does **not** handle produced files
|
|
286
|
+
- Staging and quarantine folders **are never cleaned up automatically**
|
|
183
287
|
|
|
184
288
|
### Compatibility
|
|
185
289
|
|
|
186
|
-
-
|
|
187
|
-
-
|
|
290
|
+
- **Host half** verified on DSH `0.2.1-rc.2`: loopback socket, Host header, cross-origin guard, session id validation, 405/404 paths
|
|
291
|
+
- **Client half** verified on DSH `0.2.1-rc.2`; the post-migration version has been exercised in a real browser
|
|
292
|
+
- Against older hosts that lack a service, the delete path degrades to plain filesystem cleanup
|
|
188
293
|
|
|
189
|
-
If this plugin
|
|
294
|
+
If this plugin helped, a ⭐ on [GitHub](https://github.com/DDDMUC/dsh-delete-session) is appreciated.
|
|
190
295
|
|
|
191
296
|
### License
|
|
192
297
|
|
package/cordis.patch.yml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
# dsh-delete-session bundle patch: inserts the plugin row into the profile
|
|
2
|
-
# roster. The node half serves the /dsh-delete-session/* JSON routes; the
|
|
3
|
-
# browser half (exports "./client") injects the sidebar session-row menu item
|
|
4
|
-
# and the confirmation dialog.
|
|
5
|
-
- insert:
|
|
6
|
-
- id: dsh-delete-session
|
|
7
|
-
name: 'dsh-delete-session'
|
|
1
|
+
# dsh-delete-session bundle patch: inserts the plugin row into the profile
|
|
2
|
+
# roster. The node half serves the /dsh-delete-session/* JSON routes; the
|
|
3
|
+
# browser half (exports "./client") injects the sidebar session-row menu item
|
|
4
|
+
# and the confirmation dialog.
|
|
5
|
+
- insert:
|
|
6
|
+
- id: dsh-delete-session
|
|
7
|
+
name: 'dsh-delete-session'
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-delete-session",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "Delete sessions from the DSH Web sidebar: adds a Delete action to the session row menu with a risk-consent dialog,
|
|
3
|
+
"version": "0.2.0",
|
|
4
|
+
"description": "Delete sessions from the DSH Web sidebar: adds a Delete action to the session row menu with a risk-consent dialog, sends the session log, workspace accounting and live session state to the system trash (or removes them outright), and, when opted in, quarantines the files the conversation produced.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "src/index.js",
|
|
7
7
|
"exports": {
|
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
},
|
|
12
12
|
"files": [
|
|
13
13
|
"src",
|
|
14
|
+
"test",
|
|
14
15
|
"cordis.patch.yml",
|
|
15
16
|
"README.md",
|
|
16
17
|
"LICENSE"
|