@michengai/dsh-archive-manager 0.1.0 → 0.1.2
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 +85 -29
- package/README.zh-CN.md +84 -28
- package/lib/client.js +8 -8
- package/lib/workspace.js +39 -62
- package/package.json +16 -2
package/README.md
CHANGED
|
@@ -5,67 +5,123 @@
|
|
|
5
5
|
<h1 align="center">DSH Archive Manager</h1>
|
|
6
6
|
|
|
7
7
|
<p align="center">
|
|
8
|
-
<strong>
|
|
8
|
+
<strong>A DeepSeek Harness Web plugin for safely managing archived sessions.</strong>
|
|
9
9
|
</p>
|
|
10
10
|
|
|
11
11
|
<p align="center">
|
|
12
12
|
<a href="https://github.com/MichengAI/dsh-archive-manager/issues">Report an issue</a>
|
|
13
|
-
· <a href="https://
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
<p align="center">
|
|
17
|
-
<strong>English</strong> · <a href="README.zh-CN.md">简体中文</a>
|
|
13
|
+
· <a href="https://www.npmjs.com/package/@michengai/dsh-archive-manager">View on npm</a>
|
|
14
|
+
· <a href="README.zh-CN.md">简体中文</a>
|
|
18
15
|
</p>
|
|
19
16
|
|
|
20
17
|
<p align="center">
|
|
21
18
|
<a href="LICENSE"><img src="https://img.shields.io/badge/license-Apache--2.0-blue.svg" alt="Apache License 2.0"></a>
|
|
19
|
+
<a href="https://www.npmjs.com/package/@michengai/dsh-archive-manager"><img src="https://img.shields.io/npm/v/%40michengai/dsh-archive-manager?label=npm" alt="npm package"></a>
|
|
22
20
|
<img src="https://img.shields.io/badge/DSH-Web%20Plugin-10b981" alt="DSH Web Plugin">
|
|
23
21
|
<img src="https://img.shields.io/badge/Node.js-22%2B-339933?logo=nodedotjs&logoColor=white" alt="Node.js 22 or later">
|
|
24
22
|
</p>
|
|
25
23
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
24
|
+
> DSH Archive Manager is a community-maintained plugin, not an official DeepSeek AI product.
|
|
25
|
+
|
|
26
|
+
## Features
|
|
27
|
+
|
|
28
|
+
- Lists archived sessions by workspace in **Settings → Archived Sessions**.
|
|
29
|
+
- Safely restores a session to its original workspace position.
|
|
30
|
+
- Permanently deletes a confirmed session, its workspace association, archive marker, and projection cache.
|
|
31
|
+
- Removes unloaded deleted sessions from connected sidebars immediately.
|
|
32
|
+
|
|
33
|
+

|
|
29
34
|
|
|
30
|
-
|
|
35
|
+
## Prerequisites
|
|
31
36
|
|
|
32
|
-
|
|
37
|
+
- A working DeepSeek Harness Web installation with `dsh` available in PowerShell.
|
|
38
|
+
- Examples use the `web` profile; replace it with the target profile.
|
|
39
|
+
- Source installation and development require Node.js 22+ and pnpm. npm installation does not require running `npm install` in an arbitrary directory.
|
|
33
40
|
|
|
34
|
-
|
|
35
|
-
- **Dark session cards** — show the session title and update time with explicit restore and delete actions.
|
|
36
|
-
- **Safe unarchive** — restores a session to its original workspace position.
|
|
37
|
-
- **Permanent deletion** — removes the transcript, workspace accounting, archive marker, and projection-cache record after confirmation.
|
|
38
|
-
- **Immediate sidebar cleanup** — deleted cold sessions emit the standard removal event, so they do not reappear under Recent.
|
|
41
|
+
## Installation
|
|
39
42
|
|
|
40
|
-
|
|
43
|
+
### Install from npm
|
|
41
44
|
|
|
42
|
-
|
|
45
|
+
Run this from any PowerShell directory. Install into the DSH profile through `dsh plugin`, not as a dependency of an unrelated project:
|
|
43
46
|
|
|
44
47
|
```powershell
|
|
45
48
|
[Console]::OutputEncoding = [System.Text.Encoding]::UTF8
|
|
46
49
|
$OutputEncoding = [System.Text.Encoding]::UTF8
|
|
47
50
|
dsh plugin --profile web add @michengai/dsh-archive-manager
|
|
51
|
+
dsh --profile web --dump-config
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
Restart DSH Web and hard-refresh the browser after installation or upgrade. If a package mirror is behind, append `--registry=https://registry.npmjs.org/`.
|
|
55
|
+
|
|
56
|
+
### Install from source
|
|
57
|
+
|
|
58
|
+
Use this for debugging or unpublished changes. The cloned directory becomes the plugin source path:
|
|
59
|
+
|
|
60
|
+
```powershell
|
|
61
|
+
[Console]::OutputEncoding = [System.Text.Encoding]::UTF8
|
|
62
|
+
$OutputEncoding = [System.Text.Encoding]::UTF8
|
|
63
|
+
Set-Location D:\Repository\deepseek-harness-plugin
|
|
64
|
+
git clone https://github.com/MichengAI/dsh-archive-manager.git
|
|
65
|
+
Set-Location .\dsh-archive-manager
|
|
66
|
+
pnpm install --frozen-lockfile
|
|
67
|
+
pnpm build
|
|
68
|
+
dsh plugin --profile web add .
|
|
69
|
+
dsh --profile web --dump-config
|
|
48
70
|
```
|
|
49
71
|
|
|
50
|
-
|
|
72
|
+
Restart DSH Web and hard-refresh the browser. Local installation applies `cordis.patch.yml`; do not copy `lib` or client files manually.
|
|
51
73
|
|
|
52
|
-
##
|
|
74
|
+
## Usage
|
|
53
75
|
|
|
54
76
|
1. Open **Settings → Archived Sessions**.
|
|
55
|
-
2.
|
|
56
|
-
3.
|
|
57
|
-
4. Confirm deletion.
|
|
77
|
+
2. Expand a workspace group to inspect its archived sessions.
|
|
78
|
+
3. Select **Unarchive** to restore a session, or **Delete** to remove it permanently.
|
|
79
|
+
4. Confirm deletion. **It cannot be undone.**
|
|
58
80
|
|
|
59
|
-
|
|
81
|
+
If the entry is missing after installation or upgrade, restart DSH Web and hard-refresh the browser. It is located directly after **Connectors** in Settings.
|
|
82
|
+
|
|
83
|
+
## Data handling limits
|
|
60
84
|
|
|
61
85
|
- Deletion always requires confirmation.
|
|
62
|
-
-
|
|
63
|
-
-
|
|
86
|
+
- It removes the session directory, workspace records, archive set, and projection cache.
|
|
87
|
+
- A live session finishes writing before cleanup to prevent data truncation.
|
|
88
|
+
- The plugin replaces DSH’s default workspace and projection services. Install through the DSH profile instead of manually composing the patch.
|
|
89
|
+
|
|
90
|
+
## Secondary development
|
|
91
|
+
|
|
92
|
+
This repository has no `src` directory. `lib` is directly maintained runtime source, which is its current layout rather than the recommended layout for new plugins. New plugins should prefer `src` built to `lib`.
|
|
93
|
+
|
|
94
|
+
- [lib\index.js](lib/index.js): host service entry point.
|
|
95
|
+
- [lib\workspace.js](lib/workspace.js): archived-session and workspace service.
|
|
96
|
+
- [lib\projcache.js](lib/projcache.js): session projection cache.
|
|
97
|
+
- [lib\client.js](lib/client.js): Settings page and archive UI.
|
|
98
|
+
- `test\*.test.mjs`: host, client, Remote, and styling coverage.
|
|
99
|
+
|
|
100
|
+
After changing the runtime source, validate, test, and install from the local directory:
|
|
101
|
+
|
|
102
|
+
```powershell
|
|
103
|
+
[Console]::OutputEncoding = [System.Text.Encoding]::UTF8
|
|
104
|
+
$OutputEncoding = [System.Text.Encoding]::UTF8
|
|
105
|
+
pnpm build
|
|
106
|
+
pnpm test
|
|
107
|
+
pnpm pack:check
|
|
108
|
+
dsh plugin --profile web add .
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
`pnpm build` validates package integrity; it does not compile `lib` into another directory.
|
|
112
|
+
|
|
113
|
+
## Validation
|
|
64
114
|
|
|
65
|
-
|
|
115
|
+
```powershell
|
|
116
|
+
[Console]::OutputEncoding = [System.Text.Encoding]::UTF8
|
|
117
|
+
$OutputEncoding = [System.Text.Encoding]::UTF8
|
|
118
|
+
pnpm build
|
|
119
|
+
pnpm test
|
|
120
|
+
pnpm pack:check
|
|
121
|
+
```
|
|
66
122
|
|
|
67
|
-
|
|
123
|
+
`prepublishOnly` runs the build check and tests before publishing.
|
|
68
124
|
|
|
69
125
|
## License
|
|
70
126
|
|
|
71
|
-
Licensed under
|
|
127
|
+
Licensed under [Apache License 2.0](LICENSE).
|
package/README.zh-CN.md
CHANGED
|
@@ -5,66 +5,122 @@
|
|
|
5
5
|
<h1 align="center">DSH Archive Manager</h1>
|
|
6
6
|
|
|
7
7
|
<p align="center">
|
|
8
|
-
<strong
|
|
8
|
+
<strong>安全管理已归档会话的 DeepSeek Harness Web 插件。</strong>
|
|
9
9
|
</p>
|
|
10
10
|
|
|
11
11
|
<p align="center">
|
|
12
12
|
<a href="https://github.com/MichengAI/dsh-archive-manager/issues">反馈问题</a>
|
|
13
|
-
· <a href="https://
|
|
14
|
-
</
|
|
15
|
-
|
|
16
|
-
<p align="center">
|
|
17
|
-
<a href="README.md">English</a> · <strong>简体中文</strong>
|
|
13
|
+
· <a href="https://www.npmjs.com/package/@michengai/dsh-archive-manager">在 npm 查看</a>
|
|
14
|
+
· <a href="README.md">English</a>
|
|
18
15
|
</p>
|
|
19
16
|
|
|
20
17
|
<p align="center">
|
|
21
18
|
<a href="LICENSE"><img src="https://img.shields.io/badge/license-Apache--2.0-blue.svg" alt="Apache License 2.0"></a>
|
|
19
|
+
<a href="https://www.npmjs.com/package/@michengai/dsh-archive-manager"><img src="https://img.shields.io/npm/v/%40michengai/dsh-archive-manager?label=npm" alt="npm 包"></a>
|
|
22
20
|
<img src="https://img.shields.io/badge/DSH-Web%20Plugin-10b981" alt="DSH Web Plugin">
|
|
23
21
|
<img src="https://img.shields.io/badge/Node.js-22%2B-339933?logo=nodedotjs&logoColor=white" alt="Node.js 22 或更高版本">
|
|
24
22
|
</p>
|
|
25
23
|
|
|
26
|
-
<p align="center">
|
|
27
|
-
<img src="assets/screenshots/archived-sessions.png" alt="已归档会话设置页面" width="1200">
|
|
28
|
-
</p>
|
|
29
|
-
|
|
30
24
|
> DSH Archive Manager 是社区维护的插件,并非 DeepSeek AI 官方产品。
|
|
31
25
|
|
|
32
|
-
##
|
|
26
|
+
## 功能概览
|
|
27
|
+
|
|
28
|
+
- 在「设置 → 已归档」按工作区展示归档会话。
|
|
29
|
+
- 安全取消归档,将会话恢复到原工作区位置。
|
|
30
|
+
- 经确认后永久删除会话、工作区归属、归档标记和投影缓存。
|
|
31
|
+
- 已删除的未加载归档会话会立即从已连接客户端的侧栏移除。
|
|
32
|
+
|
|
33
|
+

|
|
34
|
+
|
|
35
|
+
## 前置条件
|
|
33
36
|
|
|
34
|
-
-
|
|
35
|
-
-
|
|
36
|
-
-
|
|
37
|
-
- **永久删除**:确认后移除会话记录、工作区归属、归档标记和投影缓存。
|
|
38
|
-
- **立即清理侧栏**:删除未加载的归档会话时也会发送标准移除事件,不会重新出现在「最近」。
|
|
37
|
+
- 已可正常运行 DeepSeek Harness Web,且可在 PowerShell 中使用 `dsh`。
|
|
38
|
+
- 以下示例使用 `web` profile;请替换为实际目标 profile。
|
|
39
|
+
- 从源码安装或二次开发需要 Node.js 22+ 与 pnpm;仅从 npm 安装无需在任意目录执行 `npm install`。
|
|
39
40
|
|
|
40
|
-
##
|
|
41
|
+
## 安装
|
|
41
42
|
|
|
42
|
-
|
|
43
|
+
### 从 npm 安装
|
|
44
|
+
|
|
45
|
+
在任意 PowerShell 目录执行。请通过 `dsh plugin` 安装到 DSH profile,而不是在普通项目中安装该 npm 包:
|
|
43
46
|
|
|
44
47
|
```powershell
|
|
45
48
|
[Console]::OutputEncoding = [System.Text.Encoding]::UTF8
|
|
46
49
|
$OutputEncoding = [System.Text.Encoding]::UTF8
|
|
47
50
|
dsh plugin --profile web add @michengai/dsh-archive-manager
|
|
51
|
+
dsh --profile web --dump-config
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
安装或升级后重启 DSH Web,并在浏览器硬刷新。若镜像未同步最新版本,可在安装命令末尾追加 `--registry=https://registry.npmjs.org/`。
|
|
55
|
+
|
|
56
|
+
### 从源码安装
|
|
57
|
+
|
|
58
|
+
适用于调试或使用未发布改动。克隆后的目录会直接作为插件安装路径:
|
|
59
|
+
|
|
60
|
+
```powershell
|
|
61
|
+
[Console]::OutputEncoding = [System.Text.Encoding]::UTF8
|
|
62
|
+
$OutputEncoding = [System.Text.Encoding]::UTF8
|
|
63
|
+
Set-Location D:\Repository\deepseek-harness-plugin
|
|
64
|
+
git clone https://github.com/MichengAI/dsh-archive-manager.git
|
|
65
|
+
Set-Location .\dsh-archive-manager
|
|
66
|
+
pnpm install --frozen-lockfile
|
|
67
|
+
pnpm build
|
|
68
|
+
dsh plugin --profile web add .
|
|
69
|
+
dsh --profile web --dump-config
|
|
48
70
|
```
|
|
49
71
|
|
|
50
|
-
|
|
72
|
+
完成后重启 DSH Web 并硬刷新浏览器。`dsh plugin ... add .` 会自动应用 `cordis.patch.yml`;不要手工复制 `lib` 或客户端文件。
|
|
51
73
|
|
|
52
|
-
##
|
|
74
|
+
## 使用
|
|
53
75
|
|
|
54
76
|
1. 打开「设置 → 已归档」。
|
|
55
77
|
2. 展开工作区分组,查看其中的归档会话。
|
|
56
|
-
3.
|
|
57
|
-
4.
|
|
78
|
+
3. 点击「取消归档」恢复会话;点击「删除」永久移除会话。
|
|
79
|
+
4. 删除前确认提示。**删除无法撤销。**
|
|
80
|
+
|
|
81
|
+
安装或升级后找不到入口时,重启 DSH Web 并硬刷新浏览器;入口位于「设置」中,紧随「连接器」之后。
|
|
82
|
+
|
|
83
|
+
## 数据处理边界
|
|
84
|
+
|
|
85
|
+
- 删除操作始终需要确认。
|
|
86
|
+
- 删除会移除会话目录、工作区记录、归档集合和投影缓存。
|
|
87
|
+
- 正在写入的会话会在完成写入后清理,避免截断数据。
|
|
88
|
+
- 本插件替换 DSH 默认的工作区和会话投影服务;请仅通过 DSH profile 安装,避免手工拼接补丁配置。
|
|
89
|
+
|
|
90
|
+
## 二次开发
|
|
58
91
|
|
|
59
|
-
|
|
92
|
+
当前仓库未提供 `src` 源目录,`lib` 是直接维护的运行源码;这是当前仓库的实现方式,不是新插件的推荐布局。新插件建议使用 `src` 开发并构建到 `lib`:
|
|
60
93
|
|
|
61
|
-
-
|
|
62
|
-
-
|
|
63
|
-
-
|
|
94
|
+
- [lib\index.js](lib/index.js):客户端插件 Host 服务入口。
|
|
95
|
+
- [lib\workspace.js](lib/workspace.js):归档会话和工作区服务实现。
|
|
96
|
+
- [lib\projcache.js](lib/projcache.js):会话投影缓存实现。
|
|
97
|
+
- [lib\client.js](lib/client.js):设置页和归档会话界面。
|
|
98
|
+
- `test\*.test.mjs`:Host、客户端、Remote 和样式边界测试。
|
|
64
99
|
|
|
65
|
-
|
|
100
|
+
修改后运行检查、测试并用本地目录重新安装:
|
|
101
|
+
|
|
102
|
+
```powershell
|
|
103
|
+
[Console]::OutputEncoding = [System.Text.Encoding]::UTF8
|
|
104
|
+
$OutputEncoding = [System.Text.Encoding]::UTF8
|
|
105
|
+
pnpm build
|
|
106
|
+
pnpm test
|
|
107
|
+
pnpm pack:check
|
|
108
|
+
dsh plugin --profile web add .
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
`pnpm build` 负责发布包完整性检查,不会将 `lib` 重新编译为其他目录。
|
|
112
|
+
|
|
113
|
+
## 验证
|
|
114
|
+
|
|
115
|
+
```powershell
|
|
116
|
+
[Console]::OutputEncoding = [System.Text.Encoding]::UTF8
|
|
117
|
+
$OutputEncoding = [System.Text.Encoding]::UTF8
|
|
118
|
+
pnpm build
|
|
119
|
+
pnpm test
|
|
120
|
+
pnpm pack:check
|
|
121
|
+
```
|
|
66
122
|
|
|
67
|
-
|
|
123
|
+
`prepublishOnly` 会在发布前执行构建检查与测试。
|
|
68
124
|
|
|
69
125
|
## 许可证
|
|
70
126
|
|
package/lib/client.js
CHANGED
|
@@ -492,9 +492,9 @@ window.__ModuleLoader__.load({
|
|
|
492
492
|
* except workspace Rename/Delete and session Rename/Fork/Archive; the session
|
|
493
493
|
* and workspace hover cards are suppressed while a menu is open.
|
|
494
494
|
*/
|
|
495
|
-
/** Row display title: blank rows show the localized New Session label. */
|
|
496
|
-
function displayTitle(node, t) {
|
|
497
|
-
return node.blank ? t("session.new") : node.title;
|
|
495
|
+
/** Row display title: blank rows show the localized New Session label. */
|
|
496
|
+
function displayTitle(node, t) {
|
|
497
|
+
return node.blank ? t("session.new") : node.title ?? node.displayTitle ?? "";
|
|
498
498
|
}
|
|
499
499
|
/** Localized compact relative time ("刚刚"/"5分钟" in zh, "now"/"5min" in en). */
|
|
500
500
|
function timeLabel(updatedAt, now, t) {
|
|
@@ -2872,6 +2872,7 @@ window.__ModuleLoader__.load({
|
|
|
2872
2872
|
id: "archived-sessions",
|
|
2873
2873
|
order: 18,
|
|
2874
2874
|
label: () => ctx.locale.bind(NS)("archived.badge"),
|
|
2875
|
+
icon: "archive",
|
|
2875
2876
|
locale: NS,
|
|
2876
2877
|
inject: () => ({
|
|
2877
2878
|
sessionStore: ctx.sessions.list,
|
|
@@ -2884,8 +2885,9 @@ window.__ModuleLoader__.load({
|
|
|
2884
2885
|
}
|
|
2885
2886
|
//#endregion
|
|
2886
2887
|
/** Pure derivation surface for dsh-archive-manager self-tests (no-op for the runtime). */
|
|
2887
|
-
exports.__test = {
|
|
2888
|
-
|
|
2888
|
+
exports.__test = {
|
|
2889
|
+
displayTitle,
|
|
2890
|
+
sessionVisible,
|
|
2889
2891
|
deriveGroups,
|
|
2890
2892
|
deriveFlat,
|
|
2891
2893
|
deriveSearchResults,
|
|
@@ -2898,6 +2900,4 @@ window.__ModuleLoader__.load({
|
|
|
2898
2900
|
exports.inject = inject;
|
|
2899
2901
|
return module.exports;
|
|
2900
2902
|
}
|
|
2901
|
-
});
|
|
2902
|
-
|
|
2903
|
-
//# sourceMappingURL=client.js.map
|
|
2903
|
+
});
|
package/lib/workspace.js
CHANGED
|
@@ -7,51 +7,18 @@ import {
|
|
|
7
7
|
import { bindTypertRemote, Remote } from "@deepseek-ai/dsh-typert-protocol";
|
|
8
8
|
import { sessionDir } from "@deepseek-ai/dsh-spill-local";
|
|
9
9
|
//#region lib/types/index.js
|
|
10
|
-
/**
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
* - `deleteSession(sessionId)` — PERMANENT deletion, no trace left on disk:
|
|
23
|
-
* 1. validate the session is known (live, header-indexed, or persisted);
|
|
24
|
-
* 2. if live: flush buffered events to disk, then detach the session from
|
|
25
|
-
* the sessions store (`session/disposed` is emitted, so the browser
|
|
26
|
-
* receives `host/session-removed` and greys the composer);
|
|
27
|
-
* 3. wait for the projection cache's dispose write-behind (`whenIdle`) so
|
|
28
|
-
* the final cache row is durable BEFORE it is deleted;
|
|
29
|
-
* 4. remove the transcript directory (the whole `session-<id>` dir under
|
|
30
|
-
* the persistence root, located through `sessionPersistence.locate`);
|
|
31
|
-
* 5. remove the id from `archivedSessionIds` (durable `setState`);
|
|
32
|
-
* 6. remove the id from every workspace record's `sessionIds` and refresh
|
|
33
|
-
* the in-memory entity snapshots (durable `table.update`, so the host
|
|
34
|
-
* stream pushes `host/workspace-changed` to every browser);
|
|
35
|
-
* 7. delete the projection-cache row (`sessionProjectionCache.delete`);
|
|
36
|
-
* 8. best-effort (failures only warn): cascade-delete SUBAGENT child
|
|
37
|
-
* sessions of the deleted session (`header.origin === "subagent"` ONLY —
|
|
38
|
-
* a fork branch carries `parentSession` too but is an independent user
|
|
39
|
-
* session and is never cascade-deleted) and clear its spill data.
|
|
40
|
-
*
|
|
41
|
-
* Core steps throw on failure (no half-delete states: every failing step is
|
|
42
|
-
* idempotent and re-runnable, so a retry heals); cascade/spill are
|
|
43
|
-
* best-effort by design.
|
|
44
|
-
*
|
|
45
|
-
* The two new methods are also exported as Typert Remote endpoints
|
|
46
|
-
* (`workspaceRegistry/unarchiveSession`, `workspaceRegistry/deleteSession`)
|
|
47
|
-
* through the service's `typertRemote` binding + `Remote` markers — the
|
|
48
|
-
* browser reaches them through the standard typert gateway SRC path, keeping
|
|
49
|
-
* the legacy `/api/workspace.*` gateway untouched.
|
|
50
|
-
*
|
|
51
|
-
* The default export is a Service subclass (same shape as the shipped
|
|
52
|
-
* `@deepseek-ai/dsh-workspace` package), so the profile patch can substitute
|
|
53
|
-
* this package for the `workspace` row with no other wiring change.
|
|
54
|
-
*/
|
|
10
|
+
/**
|
|
11
|
+
* dsh-archive-manager 宿主侧归档会话管理。
|
|
12
|
+
*
|
|
13
|
+
* `deleteSession(sessionId)` 的顺序即语义:校验已知会话;实时会话先
|
|
14
|
+
* flush 再 detach;等待投影缓存写入完成;移除归档标记和工作区记账;
|
|
15
|
+
* 删除投影缓存,级联删除 SUBAGENT 子会话并清理 spill;最后才删除转录
|
|
16
|
+
* 目录。fork 分支虽有 `parentSession`,但属于独立用户会话,不参与级联。
|
|
17
|
+
*
|
|
18
|
+
* 所有可失败的持久化清理都先于不可逆的物理删除。此前任一步失败时,
|
|
19
|
+
* 转录仍保留,可重试删除;物理删除失败时记录残留路径供人工排查。
|
|
20
|
+
* `unarchiveSession` 与 `deleteSession` 通过 Typert Remote 暴露给浏览器。
|
|
21
|
+
*/
|
|
55
22
|
function markRemoteMethod(instance, method) {
|
|
56
23
|
// Simulate the TS decorator pipeline `@Remote(method)` for one method:
|
|
57
24
|
// `Remote` returns a standard method decorator; we hand it a decorator
|
|
@@ -128,21 +95,22 @@ var ArchiveWorkspaceRegistry = class extends WorkspaceRegistry {
|
|
|
128
95
|
sessions.detachEntered(entry);
|
|
129
96
|
} else if (sessions !== void 0) await this.publishColdSessionRemoval(sessionId, sessions);
|
|
130
97
|
const projCache = this.ctx.get("sessionProjectionCache");
|
|
131
|
-
// The dispose write-behind must land BEFORE the cache row is deleted,
|
|
132
|
-
// otherwise the row is written back after deletion (resurrected).
|
|
133
|
-
await projCache?.whenIdle?.();
|
|
134
|
-
|
|
135
|
-
const state = this.requireState();
|
|
98
|
+
// The dispose write-behind must land BEFORE the cache row is deleted,
|
|
99
|
+
// otherwise the row is written back after deletion (resurrected).
|
|
100
|
+
await projCache?.whenIdle?.();
|
|
101
|
+
// 物理删除不可逆:先完成所有可失败的持久化清理,失败时仍可重试。
|
|
102
|
+
const state = this.requireState();
|
|
136
103
|
if (state.archivedSessionIds.includes(sessionId)) {
|
|
137
104
|
await this.setState({
|
|
138
105
|
...state,
|
|
139
106
|
archivedSessionIds: state.archivedSessionIds.filter((id) => id !== sessionId)
|
|
140
107
|
});
|
|
141
|
-
}
|
|
142
|
-
await this.removeFromWorkspaceAccounts(sessionId);
|
|
143
|
-
if (projCache !== void 0) await projCache.delete(sessionId);
|
|
144
|
-
await this.deleteDescendants(sessionId);
|
|
145
|
-
await this.cleanSpill(sessionId);
|
|
108
|
+
}
|
|
109
|
+
await this.removeFromWorkspaceAccounts(sessionId);
|
|
110
|
+
if (projCache !== void 0) await projCache.delete(sessionId);
|
|
111
|
+
await this.deleteDescendants(sessionId);
|
|
112
|
+
await this.cleanSpill(sessionId);
|
|
113
|
+
await this.removeTranscriptDirectory(sessionId);
|
|
146
114
|
return { deleted: true };
|
|
147
115
|
}
|
|
148
116
|
/** 为未处于实时状态的持久化会话发布相同的移除事件。 */
|
|
@@ -162,17 +130,26 @@ var ArchiveWorkspaceRegistry = class extends WorkspaceRegistry {
|
|
|
162
130
|
this.ctx.logger.warn(`archive-manager: could not publish removal for stored session "${sessionId}": ${String(error)}`);
|
|
163
131
|
}
|
|
164
132
|
}
|
|
165
|
-
/**
|
|
166
|
-
|
|
167
|
-
async removeTranscriptDirectory(sessionId) {
|
|
133
|
+
/** 删除会话的转录目录;仅在所有记账清理完成后调用。 */
|
|
134
|
+
async removeTranscriptDirectory(sessionId) {
|
|
168
135
|
const persistence = this.ctx.get("sessionPersistence");
|
|
169
136
|
if (persistence === void 0 || typeof persistence.locate !== "function") {
|
|
170
137
|
throw new Error(`cannot delete session "${sessionId}": the session persistence backend does not expose locate() to resolve its transcript directory`);
|
|
171
138
|
}
|
|
172
|
-
const header = await this.readSessionHeader(sessionId);
|
|
173
|
-
const location = persistence.locate(header);
|
|
174
|
-
|
|
175
|
-
|
|
139
|
+
const header = await this.readSessionHeader(sessionId);
|
|
140
|
+
const location = persistence.locate(header);
|
|
141
|
+
if (location === void 0 || typeof location.path !== "string") {
|
|
142
|
+
throw new Error(`cannot delete session "${sessionId}": the session persistence backend could not resolve its transcript directory`);
|
|
143
|
+
}
|
|
144
|
+
const transcriptDir = dirname(location.path);
|
|
145
|
+
try {
|
|
146
|
+
await rm(transcriptDir, { recursive: true, force: true });
|
|
147
|
+
} catch (error) {
|
|
148
|
+
const message = `cannot delete session "${sessionId}": transcript directory "${transcriptDir}" remains after bookkeeping cleanup`;
|
|
149
|
+
this.ctx.logger.warn(`archive-manager: ${message}: ${String(error)}`);
|
|
150
|
+
throw new Error(`${message}: ${String(error)}`, { cause: error });
|
|
151
|
+
}
|
|
152
|
+
}
|
|
176
153
|
/** Drop the id from every workspace record and refresh entity snapshots. */
|
|
177
154
|
async removeFromWorkspaceAccounts(sessionId) {
|
|
178
155
|
const table = this.requireTable();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@michengai/dsh-archive-manager",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2",
|
|
4
4
|
"description": "NPM-installable DSH Web plugin for managing archived sessions.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"packageManager": "pnpm@11.21.0",
|
|
@@ -28,7 +28,21 @@
|
|
|
28
28
|
"test": "node --test test/*.test.mjs",
|
|
29
29
|
"pack:check": "pnpm pack --dry-run",
|
|
30
30
|
"prepublishOnly": "pnpm build && pnpm test"
|
|
31
|
-
},
|
|
31
|
+
},
|
|
32
|
+
"devDependencies": {
|
|
33
|
+
"@deepseek-ai/cordis": "4.0.1",
|
|
34
|
+
"@deepseek-ai/dsh-api-gateway": "0.1.0-rc.6",
|
|
35
|
+
"@deepseek-ai/dsh-client-runtime": "0.1.0-rc.6",
|
|
36
|
+
"@deepseek-ai/dsh-client-ui-slots": "0.1.0-rc.6",
|
|
37
|
+
"@deepseek-ai/dsh-client-web-react": "0.1.0-rc.6",
|
|
38
|
+
"@deepseek-ai/dsh-session-projection-cache": "0.1.0-rc.6",
|
|
39
|
+
"@deepseek-ai/dsh-spill-local": "0.1.0-rc.6",
|
|
40
|
+
"@deepseek-ai/dsh-typert-protocol": "0.1.0-rc.6",
|
|
41
|
+
"@deepseek-ai/dsh-typert-registry": "0.1.0-rc.6",
|
|
42
|
+
"@deepseek-ai/dsh-workspace": "0.1.0-rc.6",
|
|
43
|
+
"react": "18.3.1",
|
|
44
|
+
"react-dom": "18.3.1"
|
|
45
|
+
},
|
|
32
46
|
"license": "Apache-2.0",
|
|
33
47
|
"dsh": {
|
|
34
48
|
"bundle": {
|