@michengai/dsh-archive-manager 0.1.32 → 0.1.34

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 CHANGED
@@ -4,7 +4,21 @@
4
4
 
5
5
  Published release notes are retained below; new versions are added without removing earlier entries.
6
6
 
7
- ## Unreleased
7
+ ## 0.1.34 - 2026-09-09
8
+
9
+ - Unified settings headings, descriptions, and action layouts; maintenance controls no longer squeeze titles or versions. The layout adapts to native DSH settings without Codex UI.
10
+
11
+ ## 0.1.33 - 2026-09-08
12
+
13
+ - Added real live-session deletion coverage for `0.1.3-alpha.2` with JSONL and Zstandard: verify pending event durability, write-handle closure before directory removal, completion notification, archive bookkeeping cleanup, and no resurrection after reopening storage or a later flush; no production deletion change was required.
14
+
15
+ - Validate isolated storage test entry points, dependency versions, and resolved paths before loading host modules to prevent false failures from local legacy links; add `test:latest`, build before the matrix, and assert a single completion event for legacy live deletion.
16
+
17
+ - Added an isolated full regression matrix for DSH `0.1.1-rc.2` / Cordis `4.0.1`, `0.1.2-rc.1` / `4.0.2`, and `0.1.3-alpha.2` / `4.0.2`, passing 134, 134, and 137 tests respectively; corrected legacy client/event test fixtures and explicitly accepted the `0.1.1-rc.2` prerelease peer range.
18
+
19
+ - Added compatibility with DeepSeek Harness `0.1.3-alpha.2` (official master `c389f96`), including persistence snapshot listings and read-only session handles while retaining legacy API paths.
20
+ - Fixed sessions remaining under Ungrouped after batch deletion on the newer host (#19): remove every log generation in the session directory, confirm persistence removal before committing bookkeeping and broadcasting completion, and include cold subagents in cascading deletion.
21
+ - Updated development dependencies and added isolated tests against real JSONL / Zstandard storage, covering queries and reopening storage after deletion, fork preservation, and archived projection reads.
8
22
 
9
23
  ## 0.1.32 - 2026-09-07
10
24
 
@@ -4,7 +4,21 @@
4
4
 
5
5
  以下发布说明会持续保留;新增版本时不再删除较早记录。
6
6
 
7
- ## 未发布
7
+ ## 0.1.34 - 2026-09-09
8
+
9
+ - 统一设置页标题、说明与操作布局,标题及版本不再被维护按钮挤压;适配原生 DSH 设置内容区,无需安装 Codex UI。
10
+
11
+ ## 0.1.33 - 2026-09-08
12
+
13
+ - 补齐 `0.1.3-alpha.2` 真实实时会话删除回归(JSONL / Zstandard):验证未手动 flush 的事件落盘、目录删除前写句柄关闭、完成事件、归档记账清理,以及重新打开存储和后续 flush 均不复活会话;无需修改产品删除逻辑。
14
+
15
+ - 存储回归在加载宿主前检查隔离入口、依赖版本及解析路径,避免本机旧依赖链接造成误报;新增 `test:latest` 入口,矩阵运行前自动构建,并补充旧版实时删除只发一次完成事件的断言。
16
+
17
+ - 增加隔离的新旧宿主全量回归矩阵:DSH `0.1.1-rc.2` / Cordis `4.0.1`、`0.1.2-rc.1` / `4.0.2`、`0.1.3-alpha.2` / `4.0.2`,分别通过 134、134、137 项;修正旧客户端与事件接口的测试夹具,并明确接纳 `0.1.1-rc.2` 的预发布依赖范围。
18
+
19
+ - 适配 DeepSeek Harness `0.1.3-alpha.2`(官方 master `c389f96`):支持持久化快照列表与只读会话句柄,保留旧版接口兼容路径。
20
+ - 修复新版宿主批量删除后会话残留在“未分组”的问题(#19):清理会话目录中的全部日志代际,确认持久化已移除后再提交记账并广播完成通知,同时修复冷子会话级联遗漏。
21
+ - 将开发依赖升级至新版基线,并新增隔离的真实 JSONL / Zstandard 存储回归,覆盖删除后查询和重新打开存储、fork 保留及归档投影读取。
8
22
 
9
23
  ## 0.1.32 - 2026-09-07
10
24
 
package/README.md CHANGED
@@ -21,16 +21,12 @@
21
21
 
22
22
  ## Features
23
23
 
24
- - Archive a session from the sidebar session menu.
25
- - Archive every active chat in a workspace from its sidebar action menu.
26
- - Search archived chats, sort them by update time, creation time, or title, and filter them by workspace in **Settings → Archived sessions**.
27
- - Restore a session to its original workspace with **Unarchive**.
28
- - Restore or permanently delete every archived chat in a project group.
29
- - Restore all archived chats from the page header.
30
- - Permanently delete a confirmed session, its workspace association, archive marker, and projection cache.
31
- - Delete all archived chats after confirmation, including child agents.
32
- - Remove unloaded deleted sessions from connected sidebars immediately.
33
- - Paste one sentence into DSH, Codex, or WorkBuddy and let that agent install the plugin locally.
24
+ Put inactive conversations away and find them again when needed. Search, restore, and clean up archives in one place while keeping everyday task lists tidy.
25
+
26
+ - **Put finished tasks away**: archive one conversation or all active chats in a workspace.
27
+ - **Find past work**: search titles, filter by project, and sort by time or title in **Settings → Archived sessions**.
28
+ - **Resume your work**: restore one conversation, a project group, or all archived chats.
29
+ - **Clean up records**: permanently delete individual chats or batches after confirmation. **Permanent deletion cannot be undone.**
34
30
 
35
31
  ## Screenshots
36
32
 
@@ -44,57 +40,56 @@ Search, sort, filter by project, unarchive, or permanently delete chats in **Set
44
40
 
45
41
  ## DSH product ecosystem
46
42
 
47
- This product can be installed independently or used through the desktop app or Web suite. They share the same DSH core but serve different ways of working:
43
+ For a ready-to-use workbench, download [DSH Codex Desktop](https://github.com/MichengAI/dsh-codex-desktop/releases). If you already use [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness), install any of these eight plugins individually. The desktop app includes all eight.
48
44
 
49
- | Product | Relationship to this product |
45
+ | Plugin | What you can do |
50
46
  | --- | --- |
51
- | [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness) | The host runtime that provides models, sessions, tools, and the plugin system |
52
- | [DSH Codex Desktop](https://github.com/MichengAI/dsh-codex-desktop) | A ready-to-install desktop product with this product and the other five feature products built in |
53
- | [DSH Codex Suite](https://github.com/MichengAI/dsh-codex-ui/tree/main/packages/dsh-codex-suite) | A one-click suite for existing DSH Web environments that installs this product and the other five feature products |
54
- | Six feature products | [Codex UI](https://github.com/MichengAI/dsh-codex-ui) · [IM Connect](https://github.com/MichengAI/dsh-im-connect) · [Automation](https://github.com/MichengAI/dsh-automation) · [Skills Manager](https://github.com/MichengAI/dsh-skills-manager) · [Archive Manager](https://github.com/MichengAI/dsh-archive-manager) · [Agency Agents](https://github.com/MichengAI/dsh-agency-agents) |
47
+ | [Codex UI](https://github.com/MichengAI/dsh-codex-ui) | Organize projects and conversations, search tasks, and navigate chat turns |
48
+ | [IM Connect](https://github.com/MichengAI/dsh-im-connect) | Send tasks and receive replies through your usual messenger |
49
+ | [Automation](https://github.com/MichengAI/dsh-automation) | Schedule tasks and review each run |
50
+ | [Skills Manager](https://github.com/MichengAI/dsh-skills-manager) | Find, enable, create, and import local skills |
51
+ | [Archive Manager](https://github.com/MichengAI/dsh-archive-manager) | Search, restore, or clean up archived conversations |
52
+ | [Agency Agents](https://github.com/MichengAI/dsh-agency-agents) | Choose and summon specialists for your task |
53
+ | [BTW](https://github.com/MichengAI/dsh-btw) | Ask side questions without interrupting the main task |
54
+ | [Simplify](https://github.com/MichengAI/dsh-simplify) | Use /simplify to improve code within your Git changes |
55
55
 
56
56
  ## Prerequisites
57
57
 
58
+ - Plugin `0.1.33` and later support DeepSeek Harness `0.1.3-alpha.2` (official master `c389f96`) alongside the verified legacy hosts listed below. Later master commits require separate validation.
59
+
58
60
  - A working DeepSeek Harness Web installation with `dsh` available in PowerShell.
59
61
  - Examples use the `web` profile; replace it with the target profile.
60
62
  - Source installation and development require Node.js 22+ and pnpm. npm installation does not require running `pnpm install` separately.
61
63
 
62
64
  ## Installation
63
65
 
64
- `dsh plugin add` forwards to `pnpm add` in the profile directory. Without a version and official registry, a local mirror or minimum-release-age policy can leave you on an older build.
66
+ Run `pnpm test:compat` to test the same plugin artifacts with isolated host dependencies. The following combinations have passed; this does not claim coverage of every intermediate release:
65
67
 
66
- ### Ask another agent to install it
68
+ - `pnpm test`: build and run local tests, excluding `test/fixtures`; local host links may affect dependency resolution.
69
+ - `pnpm test:matrix`: build, then install three isolated host versions and run the full matrix.
70
+ - `pnpm test:latest`: build, then run the six real storage tests against the isolated latest baseline.
71
+ - `pnpm test:compat`: validate legacy cache migration and run the full matrix.
67
72
 
68
- This plugin runs inside DeepSeek Harness Web. Copy one of the sentences below into DSH, Codex, or WorkBuddy and let that agent install it into your local `web` profile.
73
+ Do not run `test/fixtures/*.mjs` directly. Fixtures validate the isolated entry point, dependency versions, and resolved paths before loading the host. If local dependencies have drifted, run `pnpm install --frozen-lockfile` to restore declared development dependencies. This does not guarantee removal of undeclared packages or host links under `test/node_modules`; use the isolated commands for compatibility acceptance.
69
74
 
70
- From npm:
75
+ | DSH | Cordis | Automated regression |
76
+ | --- | --- | --- |
77
+ | `0.1.1-rc.2` | `4.0.1` | 134 passed, plus legacy cache migration validation |
78
+ | `0.1.2-rc.1` | `4.0.2` | 134 passed |
79
+ | `0.1.3-alpha.2` | `4.0.2` | 137 passed |
71
80
 
72
- ```text
73
- Install the latest DSH plugin @michengai/dsh-archive-manager into my local web profile using the official npm registry: dsh plugin --profile web add @michengai/dsh-archive-manager@latest --registry=https://registry.npmjs.org/. Then run dsh --profile web --dump-config, confirm archive-manager is mounted, and remind me to restart DSH Web and hard-refresh the browser.
74
- ```
81
+ Coverage includes client Remote integration, archive/restore, real JSONL/Zstandard deletion and subagent cascades, and queries/reopened storage after deletion. Tested on Windows / Node.js 24; a full DSH Web browser acceptance run has not been performed. The latest storage fixture isolates only the upstream POSIX `fs-ext` import that cannot load on Windows; file operations and native Windows locking still use the official implementation.
75
82
 
76
- From source:
83
+ The installation commands below use the official npm registry.
77
84
 
78
- ```text
79
- Install the DSH plugin from source at https://github.com/MichengAI/dsh-archive-manager: clone it, run pnpm install --frozen-lockfile and pnpm build, then run dsh plugin --profile web add . from that directory. Do not copy lib by itself. Then run dsh --profile web --dump-config, confirm archive-manager is mounted, and remind me to restart DSH Web and hard-refresh the browser.
80
- ```
85
+ ### Ask an agent to install it (recommended)
81
86
 
82
- | Product | How to use it |
83
- | --- | --- |
84
- | DSH | Send one of the sentences above to the current session. |
85
- | Codex | Send one of the sentences above to Codex and let it install locally. |
86
- | WorkBuddy | Send one of the sentences above to WorkBuddy; for a source install you can also paste `https://github.com/MichengAI/dsh-archive-manager`. |
87
+ Send the prompt below to any agent that can run terminal commands on your computer. Replace `web` with your actual profile. Once installed, use the plugin in DSH.
87
88
 
88
- Codex and WorkBuddy only install the plugin. After that, open DSH Web and use **Settings → Archived sessions**.
89
-
90
- You can also run the same npm command yourself:
91
-
92
- ```powershell
93
- dsh plugin --profile web add @michengai/dsh-archive-manager@latest --registry=https://registry.npmjs.org/
89
+ ```text
90
+ Install the DSH plugin @michengai/dsh-archive-manager into my local web profile by running: dsh plugin --profile web add @michengai/dsh-archive-manager@latest --registry=https://registry.npmjs.org/. Then run dsh --profile web --dump-config, confirm the configuration includes workspace-archive-manager, ui-workspace-archive-manager, and explain how to reload DSH and start using the plugin.
94
91
  ```
95
92
 
96
- If `dsh` is not on PATH, replace the leading `dsh` with `npx --yes @deepseek-ai/dsh`.
97
-
98
93
  ### Install the latest package from the official npm registry
99
94
 
100
95
  Run this from any PowerShell directory:
@@ -110,24 +105,6 @@ To pin a release, replace `@latest` with a specific version such as `@x.y.z`.
110
105
 
111
106
  The configuration output should contain `workspace-archive-manager` and `ui-workspace-archive-manager`. Restart DSH Web and hard-refresh the browser. Do not copy client files manually: the Settings page and archive menu need the mounted plugin.
112
107
 
113
- ### Install from source
114
-
115
- Use this for debugging or unpublished changes. The cloned directory becomes the plugin source path:
116
-
117
- ```powershell
118
- [Console]::OutputEncoding = [System.Text.Encoding]::UTF8
119
- $OutputEncoding = [System.Text.Encoding]::UTF8
120
- Set-Location D:\Repository\deepseek-harness-plugin
121
- git clone https://github.com/MichengAI/dsh-archive-manager.git
122
- Set-Location .\dsh-archive-manager
123
- pnpm install --frozen-lockfile
124
- pnpm build
125
- dsh plugin --profile web add .
126
- dsh --profile web --dump-config
127
- ```
128
-
129
- Restart DSH Web and hard-refresh the browser. `dsh plugin ... add .` reads the package metadata and `cordis.patch.yml`; do not install by copying `lib` directly.
130
-
131
108
  ## Updates
132
109
 
133
110
  The settings title shows the installed version and a **Check for updates** button. When a newer release is available, **Update automatically** runs only when the DSH CLI or Desktop update service is available; otherwise, the dialog provides a profile-specific manual command to copy and run.
@@ -155,6 +132,24 @@ If the entry is missing after installation or upgrade, restart DSH Web and hard-
155
132
 
156
133
  ## Secondary development
157
134
 
135
+ ### Install from source
136
+
137
+ Use this for debugging or unpublished changes. The cloned directory becomes the plugin source path:
138
+
139
+ ```powershell
140
+ [Console]::OutputEncoding = [System.Text.Encoding]::UTF8
141
+ $OutputEncoding = [System.Text.Encoding]::UTF8
142
+ Set-Location D:\Repository\deepseek-harness-plugin
143
+ git clone https://github.com/MichengAI/dsh-archive-manager.git
144
+ Set-Location .\dsh-archive-manager
145
+ pnpm install --frozen-lockfile
146
+ pnpm build
147
+ dsh plugin --profile web add .
148
+ dsh --profile web --dump-config
149
+ ```
150
+
151
+ Restart DSH Web and hard-refresh the browser. `dsh plugin ... add .` reads the package metadata and `cordis.patch.yml`; do not install by copying `lib` directly.
152
+
158
153
  `src` is the sole maintained source directory. `pnpm build` uses esbuild to compile it into publishable `lib` output. Do not edit `lib` directly because the next build overwrites it.
159
154
 
160
155
  - [src\index.js](src/index.js): host service entry point.
@@ -188,7 +183,3 @@ pnpm verify
188
183
  ## License
189
184
 
190
185
  Licensed under [Apache License 2.0](LICENSE).
191
-
192
- ## Changelog
193
-
194
- See [CHANGELOG.md](CHANGELOG.md) for retained release notes.
package/README.zh-CN.md CHANGED
@@ -21,16 +21,12 @@
21
21
 
22
22
  ## 功能概览
23
23
 
24
- - 在侧栏会话菜单中选择「归档会话」。
25
- - 在工作区侧栏操作菜单中一键归档该工作区全部未归档聊天。
26
- - 在「设置 → 归档会话」按工作区查看归档会话,并支持搜索、按更新时间/创建时间/标题排序和按项目筛选。
27
- - 安全取消归档,将会话恢复到原工作区位置。
28
- - 在项目分组中批量恢复或永久删除该项目的全部已归档聊天。
29
- - 在页面顶部一键恢复全部已归档聊天。
30
- - 经确认后永久删除会话、工作区归属、归档标记和投影缓存。
31
- - 经确认后删除全部已归档聊天,包含子代理。
32
- - 已删除的未加载归档会话会立即从已连接客户端的侧栏移除。
33
- - 可把一句话复制到 DSH、Codex 或 WorkBuddy,让对方代装到本机 DSH。
24
+ 把暂时不用的会话收起来,需要时再找回。集中搜索、恢复和清理归档记录,让日常任务列表更清爽。
25
+
26
+ - **收起已完成的任务**:归档单条聊天,也可归档整个工作区的未归档聊天。
27
+ - **快速找回历史**:在「设置 → 归档会话」搜索标题、按项目筛选,或按时间和标题排序。
28
+ - **恢复继续工作**:恢复单条会话、整个项目或全部归档会话。
29
+ - **按需清理记录**:支持单条或批量永久删除,执行前会要求确认。**永久删除无法撤销。**
34
30
 
35
31
  ## 界面预览
36
32
 
@@ -44,57 +40,56 @@
44
40
 
45
41
  ## DSH 产品生态
46
42
 
47
- 本产品既可以独立安装,也可以随桌面端或 Web 套件一起使用。它们共享同一个 DSH 核心,但面向不同的使用方式:
43
+ 想直接使用完整工作台,可下载 [DSH Codex Desktop](https://github.com/MichengAI/dsh-codex-desktop/releases);已有 [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness) 环境,可按需独立安装以下 8 个自研插件。桌面端已随附这些插件。
48
44
 
49
- | 产品 | 与本产品的关系 |
45
+ | 插件 | 你可以用它做什么 |
50
46
  | --- | --- |
51
- | [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness) | 本产品的运行宿主,提供模型、会话、工具和插件系统 |
52
- | [DSH Codex Desktop](https://github.com/MichengAI/dsh-codex-desktop) | 下载安装即用的桌面产品,已内置本产品和其他 5 个功能产品 |
53
- | [DSH Codex Suite](https://github.com/MichengAI/dsh-codex-ui/tree/main/packages/dsh-codex-suite) | 面向已有 DSH Web 环境的一键套件,会安装本产品和其他 5 个功能产品 |
54
- | 6 个功能产品 | [Codex UI](https://github.com/MichengAI/dsh-codex-ui) · [IM Connect](https://github.com/MichengAI/dsh-im-connect) · [Automation](https://github.com/MichengAI/dsh-automation) · [Skills Manager](https://github.com/MichengAI/dsh-skills-manager) · [Archive Manager](https://github.com/MichengAI/dsh-archive-manager) · [Agency Agents](https://github.com/MichengAI/dsh-agency-agents) |
47
+ | [Codex UI](https://github.com/MichengAI/dsh-codex-ui) | 整理项目与会话、搜索任务、跳转对话轮次 |
48
+ | [IM Connect](https://github.com/MichengAI/dsh-im-connect) | 从微信、飞书、钉钉等消息平台下任务、收回复 |
49
+ | [Automation](https://github.com/MichengAI/dsh-automation) | 按计划执行任务,查看每次运行的结果 |
50
+ | [Skills Manager](https://github.com/MichengAI/dsh-skills-manager) | 统一查找、启停、创建和导入本机技能 |
51
+ | [Archive Manager](https://github.com/MichengAI/dsh-archive-manager) | 搜索、恢复或清理已归档会话 |
52
+ | [Agency Agents](https://github.com/MichengAI/dsh-agency-agents) | 按任务选择并召唤专业角色 |
53
+ | [BTW](https://github.com/MichengAI/dsh-btw) | 在当前上下文中临时旁问,不打断主任务 |
54
+ | [Simplify](https://github.com/MichengAI/dsh-simplify) | 用 /simplify 整理 Git 改动范围内的代码 |
55
55
 
56
56
  ## 前置条件
57
57
 
58
+ - 从插件 `0.1.33` 起支持 DeepSeek Harness `0.1.3-alpha.2`(官方 master `c389f96`),同时兼容下表中已验证的旧版宿主。后续 master 提交需另行验证。
59
+
58
60
  - 已可正常运行 DeepSeek Harness Web,且可在 PowerShell 中使用 `dsh`。
59
61
  - 以下示例使用 `web` profile;请替换为实际目标 profile。
60
62
  - 从源码安装或二次开发需要 Node.js 22+ 与 pnpm;仅从 npm 安装无需另外执行 `pnpm install`。
61
63
 
62
64
  ## 安装
63
65
 
64
- `dsh plugin add` 会转发到 profile 目录里的 `pnpm add`。不写版本、不指定官方源时,本机镜像和最短发布间隔可能让你停在旧版。
66
+ 源码回归使用 `pnpm test:compat`,在隔离依赖环境中运行同一份插件产物,已验证以下组合(不代表覆盖所有中间版本):
65
67
 
66
- ### 交给其他 Agent 一句话安装
68
+ - `pnpm test`:构建并执行本地常规测试,不包含 `test/fixtures`;实际依赖可能受本机宿主链接影响。
69
+ - `pnpm test:matrix`:先构建,再隔离安装三个宿主版本,执行完整矩阵。
70
+ - `pnpm test:latest`:先构建,再隔离运行最新版的 6 项真实存储回归。
71
+ - `pnpm test:compat`:旧缓存迁移验证加完整矩阵。
67
72
 
68
- 本插件运行在 DeepSeek Harness Web 里。把下面其中一句复制到 DSH、Codex 或 WorkBuddy,让它代你安装到本机 `web` profile。
73
+ 不要直接执行 `test/fixtures/*.mjs`;夹具会在加载宿主前检查隔离入口、依赖版本及实际路径。若本机依赖脱节,可先执行 `pnpm install --frozen-lockfile` 恢复声明的开发依赖;它不保证清理未声明包或 `test/node_modules` 的宿主链接,兼容性验收以隔离命令为准。
69
74
 
70
- 从 npm 安装:
75
+ | DSH | Cordis | 自动回归 |
76
+ | --- | --- | --- |
77
+ | `0.1.1-rc.2` | `4.0.1` | 134 项通过,另含旧缓存迁移验证 |
78
+ | `0.1.2-rc.1` | `4.0.2` | 134 项通过 |
79
+ | `0.1.3-alpha.2` | `4.0.2` | 137 项通过 |
71
80
 
72
- ```text
73
- 请把 DSH 插件 @michengai/dsh-archive-manager 最新版装进本机 web profile,使用官方 npm 源执行:dsh plugin --profile web add @michengai/dsh-archive-manager@latest --registry=https://registry.npmjs.org/。装完执行 dsh --profile web --dump-config,确认已挂载 archive-manager,并提醒我重启 DSH Web 后硬刷新浏览器。
74
- ```
81
+ 覆盖客户端 Remote、归档/恢复、真实 JSONL/Zstandard 删除与子会话级联、删除后重新查询及重新打开存储。验证环境为 Windows / Node.js 24;尚未执行完整 DSH Web 浏览器人工验收。新版存储夹具仅隔离上游无法在 Windows 加载的 POSIX `fs-ext` 导入,实际文件操作与 Windows 原生锁仍使用官方实现。
75
82
 
76
- 从源码安装:
83
+ 以下安装命令使用官方 npm 源。
77
84
 
78
- ```text
79
- 请从源码安装 DSH 插件 https://github.com/MichengAI/dsh-archive-manager:克隆到本机后执行 pnpm install --frozen-lockfile 和 pnpm build,再用 dsh plugin --profile web add . 把当前目录装进 web profile。不要只复制 lib。装完执行 dsh --profile web --dump-config,确认已挂载 archive-manager,并提醒我重启 DSH Web 后硬刷新浏览器。
80
- ```
85
+ ### 让 Agent 帮你安装(推荐)
81
86
 
82
- | 产品 | 怎么用 |
83
- | --- | --- |
84
- | DSH | 把上面其中一句发给当前会话。 |
85
- | Codex | 把上面其中一句发给 Codex,让它在本机执行安装。 |
86
- | WorkBuddy | 把上面其中一句发给 WorkBuddy;源码安装也可同时粘贴仓库地址 `https://github.com/MichengAI/dsh-archive-manager`。 |
87
+ 把下面这段话发给任意能够执行本机终端命令的 Agent。将 `web` 替换为实际使用的 profile;安装完成后,在 DSH 中使用本插件。
87
88
 
88
- Codex 和 WorkBuddy 只负责代装;装好后仍要打开 DSH Web 使用「设置 → 归档会话」。
89
-
90
- 也可以自己执行同一条 npm 命令:
91
-
92
- ```powershell
93
- dsh plugin --profile web add @michengai/dsh-archive-manager@latest --registry=https://registry.npmjs.org/
89
+ ```text
90
+ 请将 DSH 插件 @michengai/dsh-archive-manager 安装到本机 web profile,执行:dsh plugin --profile web add @michengai/dsh-archive-manager@latest --registry=https://registry.npmjs.org/。安装后执行 dsh --profile web --dump-config,确认配置包含 workspace-archive-manager, ui-workspace-archive-manager,并告诉我如何重新加载 DSH 和开始使用。
94
91
  ```
95
92
 
96
- 未把 `dsh` 装进 PATH 时,把开头的 `dsh` 换成 `npx --yes @deepseek-ai/dsh`。
97
-
98
93
  ### 从官方 npm 安装最新版
99
94
 
100
95
  在任意 PowerShell 目录执行:
@@ -110,24 +105,6 @@ dsh --profile web --dump-config
110
105
 
111
106
  配置输出中应包含 `workspace-archive-manager` 与 `ui-workspace-archive-manager`。安装后重启 DSH Web 并在浏览器硬刷新;请勿手工复制客户端文件,否则设置页和归档菜单不会被挂载。
112
107
 
113
- ### 从源码安装
114
-
115
- 适用于调试或使用未发布改动。克隆后的目录会直接作为插件安装路径:
116
-
117
- ```powershell
118
- [Console]::OutputEncoding = [System.Text.Encoding]::UTF8
119
- $OutputEncoding = [System.Text.Encoding]::UTF8
120
- Set-Location D:\Repository\deepseek-harness-plugin
121
- git clone https://github.com/MichengAI/dsh-archive-manager.git
122
- Set-Location .\dsh-archive-manager
123
- pnpm install --frozen-lockfile
124
- pnpm build
125
- dsh plugin --profile web add .
126
- dsh --profile web --dump-config
127
- ```
128
-
129
- 完成后重启 DSH Web 并硬刷新浏览器。`dsh plugin ... add .` 会读取当前目录的包信息和 `cordis.patch.yml`;不要改为直接复制 `lib` 目录。
130
-
131
108
  ## 在线更新
132
109
 
133
110
  设置标题会显示当前版本和“检查更新”按钮。发现新版后,只有检测到 DSH CLI 或 Desktop 更新服务时才可使用“自动更新”;其他环境会在弹窗中提供可复制、与当前 Profile 对应的手工更新命令。
@@ -155,6 +132,24 @@ dsh --profile web --dump-config
155
132
 
156
133
  ## 二次开发
157
134
 
135
+ ### 从源码安装
136
+
137
+ 适用于调试或使用未发布改动。克隆后的目录会直接作为插件安装路径:
138
+
139
+ ```powershell
140
+ [Console]::OutputEncoding = [System.Text.Encoding]::UTF8
141
+ $OutputEncoding = [System.Text.Encoding]::UTF8
142
+ Set-Location D:\Repository\deepseek-harness-plugin
143
+ git clone https://github.com/MichengAI/dsh-archive-manager.git
144
+ Set-Location .\dsh-archive-manager
145
+ pnpm install --frozen-lockfile
146
+ pnpm build
147
+ dsh plugin --profile web add .
148
+ dsh --profile web --dump-config
149
+ ```
150
+
151
+ 完成后重启 DSH Web 并硬刷新浏览器。`dsh plugin ... add .` 会读取当前目录的包信息和 `cordis.patch.yml`;不要改为直接复制 `lib` 目录。
152
+
158
153
  `src` 是唯一可维护源码目录,`pnpm build` 使用 esbuild 将其编译为可发布的 `lib`。请勿直接修改 `lib`,否则下次构建会覆盖改动:
159
154
 
160
155
  - [src\index.js](src/index.js):客户端插件 Host 服务入口。
@@ -188,7 +183,3 @@ pnpm verify
188
183
  ## 许可证
189
184
 
190
185
  本项目采用 [Apache License 2.0](LICENSE)。
191
-
192
- ## 更新日志
193
-
194
- 完整保留的发布说明见 [CHANGELOG.zh-CN.md](CHANGELOG.zh-CN.md)。
package/lib/client.js CHANGED
@@ -3021,9 +3021,9 @@
3021
3021
  ]
3022
3022
  });
3023
3023
  }
3024
- const ARCHIVE_SETTINGS_CSS = ".dsham_settings{box-sizing:border-box;width:min(100%,760px);margin:0 auto;padding:0 0 32px;color:var(--dsw-alias-label-primary)}.dsham_settingsHeader{display:flex;align-items:flex-start;justify-content:space-between;gap:16px;margin-bottom:12px}.dsham_settings h2{margin:0;font-size:20px;font-weight:650;letter-spacing:-.2px;line-height:28px}.dsham_settingsIntro{margin:4px 0 0;max-width:42em;color:var(--dsw-alias-label-tertiary);font-size:13px;line-height:1.5}.dsham_settingsDanger{display:inline-flex;align-items:center;gap:6px;min-height:32px;padding:0 12px;color:var(--dsw-alias-state-error-primary);background:transparent;border:1px solid var(--dsw-alias-state-error-primary);border-radius:8px;cursor:pointer;font:inherit;font-size:13px;font-weight:500}.dsham_settingsDanger:hover{background:color-mix(in srgb,var(--dsw-alias-state-error-primary) 20%,transparent)}.dsham_settingsToolbar{display:flex;gap:8px;margin-bottom:16px}.dsham_settingsSearch{display:flex;align-items:center;gap:8px;min-width:0;flex:1;height:32px;padding:0 12px;color:var(--dsw-alias-label-tertiary);background:var(--dsw-alias-bg-layer-3,var(--dsw-alias-button-elevated-fill));border:1px solid var(--dsw-alias-border-l2);border-radius:8px}.dsham_settingsSearch:focus-within{border-color:var(--dsw-alias-label-tertiary)}.dsham_settingsSearch input{width:100%;min-width:0;padding:0;color:var(--dsw-alias-label-primary);background:transparent;border:0;outline:0;font:inherit;font-size:12px}.dsham_settingsSearch input::placeholder{color:var(--dsw-alias-label-tertiary)}.dsham_settingsFilter{position:relative;min-width:168px;flex:none}.dsham_selectTrigger{box-sizing:border-box;display:flex;align-items:center;justify-content:space-between;gap:8px;width:100%;min-height:32px;padding:0 10px;color:var(--dsw-alias-label-primary);background:var(--dsw-alias-bg-layer-3,var(--dsw-alias-button-elevated-fill));border:1px solid var(--dsw-alias-border-l2);border-radius:8px;cursor:pointer;font:inherit;font-size:13px;line-height:20px;text-align:left}.dsham_selectTrigger:hover{background:var(--dsw-alias-interactive-bg-hover)}.dsham_selectTrigger:focus-visible{outline:2px solid var(--dsw-alias-state-success-primary);outline-offset:2px}.dsham_selectTrigger[aria-expanded='true']{border-color:var(--dsw-alias-state-success-primary)}.dsham_selectValue{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.dsham_selectCaret{flex:none;width:12px;height:12px;color:var(--dsw-alias-label-tertiary)}.dsham_selectMenu{position:absolute;top:calc(100% + 4px);left:0;right:0;z-index:30;box-sizing:border-box;min-width:100%;max-height:280px;overflow:auto;padding:4px;border:1px solid var(--dsw-alias-border-l2);border-radius:10px;background:var(--dsw-specific-menu,var(--dsw-alias-bg-layer-2));box-shadow:var(--dsw-shadow-lv3)}.dsham_selectOption{box-sizing:border-box;display:flex;align-items:center;width:100%;min-height:32px;padding:0 10px;border:0;border-radius:8px;background:transparent;color:var(--dsw-alias-label-primary);font:inherit;font-size:13px;line-height:20px;text-align:left;cursor:pointer}.dsham_selectOption:hover,.dsham_selectOption[data-active='true']{background:var(--dsw-alias-interactive-bg-hover)}.dsham_selectOption[aria-selected='true']{color:var(--dsw-alias-state-success-primary)}.dsham_settingsGroup{margin:0 0 20px}.dsham_settingsGroupHeading{display:flex;align-items:center;justify-content:space-between;gap:12px;margin:0 0 14px}.dsham_settingsGroupTitle{display:flex;align-items:center;gap:8px;min-width:0;margin:0;color:var(--dsw-alias-label-primary);font-size:13px;font-weight:600}.dsham_settingsGroupTitle svg{flex:none;color:var(--dsw-alias-label-secondary)}.dsham_settingsCount{flex:none;color:var(--dsw-alias-label-tertiary);font-size:12px}.dsham_settingsList{overflow:hidden;border:1px solid var(--dsw-alias-border-l2);border-radius:12px;background:var(--dsw-alias-bg-layer-2,var(--dsw-alias-button-elevated-fill))}.dsham_settingsRow{display:flex;align-items:center;gap:12px;min-height:60px;padding:10px 16px;border-bottom:1px solid var(--dsw-alias-border-l2)}.dsham_settingsRow:last-child{border-bottom:0}.dsham_settingsContent{min-width:0;flex:1}.dsham_settingsTitle{overflow:hidden;color:var(--dsw-alias-label-primary);font-size:13px;font-weight:600;line-height:18px;text-overflow:ellipsis;white-space:nowrap}.dsham_settingsMeta{margin-top:2px;color:var(--dsw-alias-label-tertiary);font-size:12px;line-height:16px}.dsham_settingsActions{display:flex;align-items:center;gap:8px}.dsham_settingsAction{min-height:32px;padding:0 12px;color:var(--dsw-alias-label-primary);background:transparent;border:1px solid var(--dsw-alias-border-l2);border-radius:8px;cursor:pointer;font:inherit;font-size:13px;font-weight:500}.dsham_settingsAction:hover{filter:brightness(1.12)}.dsham_settingsDelete{display:flex;align-items:center;justify-content:center;width:28px;height:28px;color:var(--dsw-alias-label-tertiary);background:transparent;border:0;border-radius:8px;cursor:pointer}.dsham_settingsDelete:hover{color:var(--dsw-alias-state-error-primary);background:var(--dsw-alias-interactive-bg-hover)}.dsham_settingsEmpty{padding:28px 8px;color:var(--dsw-alias-label-secondary);text-align:center}.dsham_settingsError{margin-top:10px;color:var(--dsw-alias-state-error-primary);font-size:12px}@media(max-width:720px){.dsham_settings{width:100%;margin:28px auto 48px;padding:0 16px}.dsham_settingsHeader{margin-bottom:28px}.dsham_settingsToolbar{flex-wrap:wrap;margin-bottom:28px}.dsham_settingsSearch{flex-basis:100%}.dsham_settingsFilter{flex:1;min-width:0}.dsham_settingsGroup{margin-bottom:32px}.dsham_settingsRow{padding:10px 12px}.dsham_settingsActions{gap:4px}}";
3025
- const ARCHIVE_SETTINGS_BATCH_CSS = ".dsham_settingsHeaderActions,.dsham_settingsGroupMeta{display:flex;align-items:center;gap:8px;flex:none}.dsham_settingsRestoreAll{display:inline-flex;align-items:center;min-height:32px;padding:0 12px;color:var(--dsw-alias-label-primary);background:transparent;border:1px solid var(--dsw-alias-border-l2);border-radius:8px;cursor:pointer;font:inherit;font-size:13px;font-weight:500}.dsham_settingsRestoreAll:hover{background:var(--dsw-alias-interactive-bg-hover)}.dsham_settingsRestoreAll:disabled,.dsham_settingsDanger:disabled,.dsham_settingsGroupMenu:disabled{cursor:not-allowed;opacity:.5}.dsham_settingsGroupMenu{display:flex;align-items:center;justify-content:center;width:28px;height:28px;padding:0;color:var(--dsw-alias-label-tertiary);background:transparent;border:0;border-radius:8px;cursor:pointer}.dsham_settingsGroupMenu:hover{color:var(--dsw-alias-label-primary);background:var(--dsw-alias-interactive-bg-hover)}.dsham_settingsStatus{margin-top:10px;color:var(--dsw-alias-label-secondary);font-size:12px}@media(max-width:720px){.dsham_settingsHeader{flex-direction:column}.dsham_settingsHeaderActions{align-self:flex-end}}";
3026
- const ARCHIVE_SETTINGS_EXTERNAL_LINK_CSS = ".dsham_settingsTitleRow{display:flex;align-items:center;gap:8px;min-width:0}.dsham_settingsLinks{display:flex;align-items:center;gap:4px}.dsham_settingsExternalLink{display:inline-flex;align-items:center;gap:5px;min-height:28px;padding:0 8px;color:var(--dsw-alias-label-secondary);background:transparent;border:1px solid var(--dsw-alias-border-l2);border-radius:7px;font-size:12px;font-weight:500;line-height:18px;text-decoration:none;white-space:nowrap}.dsham_settingsExternalLink:hover{color:var(--dsw-alias-label-primary);background:var(--dsw-alias-interactive-bg-hover)}.dsham_settingsExternalLink:focus-visible{outline:2px solid var(--dsw-alias-state-success-primary);outline-offset:2px}.dsham_settingsExternalLink svg{flex:none}@media(max-width:720px){.dsham_settingsTitleRow{flex-wrap:wrap}}";
3024
+ const ARCHIVE_SETTINGS_CSS = ".dsham_settings{container-type:inline-size;min-width:0;box-sizing:border-box;width:min(100%,760px);margin:0 auto;padding:0 0 32px;color:var(--dsw-alias-label-primary)}.dsham_settingsHeader{display:flex;flex-direction:column;align-items:stretch;gap:16px;margin-bottom:16px}.dsham_settings h2{margin:0;font-size:24px;line-height:32px;font-weight:600;letter-spacing:-.4px;white-space:nowrap}.dsham_settingsIntro{margin:12px 0 0;max-width:42em;color:var(--dsw-alias-label-tertiary);font-size:14px;line-height:22px}.dsham_settingsDanger{display:inline-flex;align-items:center;gap:6px;min-height:32px;padding:0 12px;color:var(--dsw-alias-state-error-primary);background:transparent;border:1px solid var(--dsw-alias-state-error-primary);border-radius:8px;cursor:pointer;font:inherit;font-size:13px;font-weight:500}.dsham_settingsDanger:hover{background:color-mix(in srgb,var(--dsw-alias-state-error-primary) 20%,transparent)}.dsham_settingsToolbar{display:flex;gap:8px;margin-bottom:16px}.dsham_settingsSearch{display:flex;align-items:center;gap:8px;min-width:0;flex:1;height:32px;padding:0 12px;color:var(--dsw-alias-label-tertiary);background:var(--dsw-alias-bg-layer-3,var(--dsw-alias-button-elevated-fill));border:1px solid var(--dsw-alias-border-l2);border-radius:8px}.dsham_settingsSearch:focus-within{border-color:var(--dsw-alias-label-tertiary)}.dsham_settingsSearch input{width:100%;min-width:0;padding:0;color:var(--dsw-alias-label-primary);background:transparent;border:0;outline:0;font:inherit;font-size:12px}.dsham_settingsSearch input::placeholder{color:var(--dsw-alias-label-tertiary)}.dsham_settingsFilter{position:relative;min-width:168px;flex:none}.dsham_selectTrigger{box-sizing:border-box;display:flex;align-items:center;justify-content:space-between;gap:8px;width:100%;min-height:32px;padding:0 10px;color:var(--dsw-alias-label-primary);background:var(--dsw-alias-bg-layer-3,var(--dsw-alias-button-elevated-fill));border:1px solid var(--dsw-alias-border-l2);border-radius:8px;cursor:pointer;font:inherit;font-size:13px;line-height:20px;text-align:left}.dsham_selectTrigger:hover{background:var(--dsw-alias-interactive-bg-hover)}.dsham_selectTrigger:focus-visible{outline:2px solid var(--dsw-alias-state-success-primary);outline-offset:2px}.dsham_selectTrigger[aria-expanded='true']{border-color:var(--dsw-alias-state-success-primary)}.dsham_selectValue{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.dsham_selectCaret{flex:none;width:12px;height:12px;color:var(--dsw-alias-label-tertiary)}.dsham_selectMenu{position:absolute;top:calc(100% + 4px);left:0;right:0;z-index:30;box-sizing:border-box;min-width:100%;max-height:280px;overflow:auto;padding:4px;border:1px solid var(--dsw-alias-border-l2);border-radius:10px;background:var(--dsw-specific-menu,var(--dsw-alias-bg-layer-2));box-shadow:var(--dsw-shadow-lv3)}.dsham_selectOption{box-sizing:border-box;display:flex;align-items:center;width:100%;min-height:32px;padding:0 10px;border:0;border-radius:8px;background:transparent;color:var(--dsw-alias-label-primary);font:inherit;font-size:13px;line-height:20px;text-align:left;cursor:pointer}.dsham_selectOption:hover,.dsham_selectOption[data-active='true']{background:var(--dsw-alias-interactive-bg-hover)}.dsham_selectOption[aria-selected='true']{color:var(--dsw-alias-state-success-primary)}.dsham_settingsGroup{margin:0 0 20px}.dsham_settingsGroupHeading{display:flex;align-items:center;justify-content:space-between;gap:12px;margin:0 0 14px}.dsham_settingsGroupTitle{display:flex;align-items:center;gap:8px;min-width:0;margin:0;color:var(--dsw-alias-label-primary);font-size:13px;font-weight:600}.dsham_settingsGroupTitle svg{flex:none;color:var(--dsw-alias-label-secondary)}.dsham_settingsCount{flex:none;color:var(--dsw-alias-label-tertiary);font-size:12px}.dsham_settingsList{overflow:hidden;border:1px solid var(--dsw-alias-border-l2);border-radius:12px;background:var(--dsw-alias-bg-layer-2,var(--dsw-alias-button-elevated-fill))}.dsham_settingsRow{display:flex;align-items:center;gap:12px;min-height:60px;padding:10px 16px;border-bottom:1px solid var(--dsw-alias-border-l2)}.dsham_settingsRow:last-child{border-bottom:0}.dsham_settingsContent{min-width:0;flex:1}.dsham_settingsTitle{overflow:hidden;color:var(--dsw-alias-label-primary);font-size:13px;font-weight:600;line-height:18px;text-overflow:ellipsis;white-space:nowrap}.dsham_settingsMeta{margin-top:2px;color:var(--dsw-alias-label-tertiary);font-size:12px;line-height:16px}.dsham_settingsActions{display:flex;align-items:center;gap:8px}.dsham_settingsAction{min-height:32px;padding:0 12px;color:var(--dsw-alias-label-primary);background:transparent;border:1px solid var(--dsw-alias-border-l2);border-radius:8px;cursor:pointer;font:inherit;font-size:13px;font-weight:500}.dsham_settingsAction:hover{filter:brightness(1.12)}.dsham_settingsDelete{display:flex;align-items:center;justify-content:center;width:28px;height:28px;color:var(--dsw-alias-label-tertiary);background:transparent;border:0;border-radius:8px;cursor:pointer}.dsham_settingsDelete:hover{color:var(--dsw-alias-state-error-primary);background:var(--dsw-alias-interactive-bg-hover)}.dsham_settingsEmpty{padding:28px 8px;color:var(--dsw-alias-label-secondary);text-align:center}.dsham_settingsError{margin-top:10px;color:var(--dsw-alias-state-error-primary);font-size:12px}@container(max-width:520px){.dsham_settingsHeader{margin-bottom:16px}.dsham_settingsToolbar{flex-wrap:wrap;margin-bottom:28px}.dsham_settingsSearch{flex-basis:100%}.dsham_settingsFilter{flex:1;min-width:0}.dsham_settingsGroup{margin-bottom:32px}.dsham_settingsRow{padding:10px 12px}.dsham_settingsActions{gap:4px}}";
3025
+ const ARCHIVE_SETTINGS_BATCH_CSS = ".dsham_settingsHeaderActions,.dsham_settingsGroupMeta{display:flex;align-items:center;gap:8px;flex:none;flex-wrap:wrap}.dsham_settingsRestoreAll{display:inline-flex;align-items:center;min-height:32px;padding:0 12px;color:var(--dsw-alias-label-primary);background:transparent;border:1px solid var(--dsw-alias-border-l2);border-radius:8px;cursor:pointer;font:inherit;font-size:13px;font-weight:500}.dsham_settingsRestoreAll:hover{background:var(--dsw-alias-interactive-bg-hover)}.dsham_settingsRestoreAll:disabled,.dsham_settingsDanger:disabled,.dsham_settingsGroupMenu:disabled{cursor:not-allowed;opacity:.5}.dsham_settingsGroupMenu{display:flex;align-items:center;justify-content:center;width:28px;height:28px;padding:0;color:var(--dsw-alias-label-tertiary);background:transparent;border:0;border-radius:8px;cursor:pointer}.dsham_settingsGroupMenu:hover{color:var(--dsw-alias-label-primary);background:var(--dsw-alias-interactive-bg-hover)}.dsham_settingsStatus{margin-top:10px;color:var(--dsw-alias-label-secondary);font-size:12px}@media(max-width:720px){.dsham_settingsHeader{flex-direction:column}.dsham_settingsHeaderActions{align-self:flex-start}}";
3026
+ const ARCHIVE_SETTINGS_EXTERNAL_LINK_CSS = ".dsham_settingsTitleRow{display:flex;align-items:center;gap:8px 12px;min-width:0;flex-wrap:wrap}.dsham_settingsLinks{display:flex;align-items:center;gap:4px;flex-wrap:wrap}.dsham_settingsExternalLink{display:inline-flex;align-items:center;gap:5px;min-height:28px;padding:0 8px;color:var(--dsw-alias-label-secondary);background:transparent;border:1px solid var(--dsw-alias-border-l2);border-radius:7px;font-size:12px;font-weight:500;line-height:18px;text-decoration:none;white-space:nowrap}.dsham_settingsExternalLink:hover{color:var(--dsw-alias-label-primary);background:var(--dsw-alias-interactive-bg-hover)}.dsham_settingsExternalLink:focus-visible{outline:2px solid var(--dsw-alias-state-success-primary);outline-offset:2px}.dsham_settingsExternalLink svg{flex:none}@media(max-width:720px){.dsham_settingsTitleRow{flex-wrap:wrap}}";
3027
3027
  const ARCHIVE_SETTINGS_DELETE_CONFIRM_CSS = ".dsham_settingsDeleteConfirm{color:var(--dsw-alias-state-error-primary)!important;background:transparent!important;border-color:var(--dsw-alias-state-error-primary)!important}.dsham_settingsDeleteConfirm:hover:not(:disabled){background:color-mix(in srgb,var(--dsw-alias-state-error-primary) 20%,transparent)!important}.dsham_settingsDeleteConfirm:focus-visible{outline:2px solid var(--dsw-alias-state-error-secondary);outline-offset:2px}.dsham_settingsDeleteConfirm:disabled{cursor:not-allowed;opacity:.5}";
3028
3028
  const ARCHIVE_WORKSPACE_CONFIRM_CSS = ".dsham_archiveWorkspaceConfirm{color:var(--dsw-alias-state-error-primary)!important;background:transparent!important;border-color:var(--dsw-alias-state-error-primary)!important}.dsham_archiveWorkspaceConfirm:hover:not(:disabled){background:color-mix(in srgb,var(--dsw-alias-state-error-primary) 20%,transparent)!important}.dsham_archiveWorkspaceConfirm:focus-visible{outline:2px solid var(--dsw-alias-state-error-secondary);outline-offset:2px}.dsham_archiveWorkspaceConfirm:disabled{cursor:not-allowed;opacity:.5}";
3029
3029
  const ARCHIVE_SETTINGS_SELECTION_CSS = ".dsham_settingsSelection{display:flex;align-items:center;gap:10px;min-height:40px;margin:-8px 0 16px;padding:4px 10px;border:1px solid var(--dsw-alias-border-l2);border-radius:8px;background:var(--dsw-alias-bg-layer-2,var(--dsw-alias-button-elevated-fill))}.dsham_settingsSelectionToggle{display:inline-flex;align-items:center;gap:8px;min-width:0;color:var(--dsw-alias-label-primary);font-size:13px;cursor:pointer}.dsham_settingsCheckbox{width:16px;height:16px;margin:0;accent-color:#3b82f6}.dsham_settingsSelectionCount{margin-right:auto;color:var(--dsw-alias-label-tertiary);font-size:12px}.dsham_settingsSelectionAction{min-height:28px;padding:0 10px;color:var(--dsw-alias-label-primary);background:transparent;border:1px solid var(--dsw-alias-border-l2);border-radius:7px;cursor:pointer;font:inherit;font-size:12px;font-weight:500}.dsham_settingsSelectionAction:hover{background:var(--dsw-alias-interactive-bg-hover)}.dsham_settingsSelectionDelete{color:var(--dsw-alias-state-error-primary);border-color:var(--dsw-alias-state-error-primary)}.dsham_settingsSelectionAction:disabled{cursor:not-allowed;opacity:.5}@media(max-width:720px){.dsham_settingsSelection{flex-wrap:wrap}.dsham_settingsSelectionCount{margin-right:0}.dsham_settingsSelectionAction{margin-left:auto}.dsham_settingsSelectionAction+.dsham_settingsSelectionAction{margin-left:-2px}}";
package/lib/workspace.js CHANGED
@@ -10,7 +10,7 @@ function jsonlSessionDirectory(persistence, header, location) {
10
10
  if (persistence.name !== "session-persistence-jsonl" || location.kind !== "jsonl") return;
11
11
  const root = persistence.root ?? persistence.config?.root;
12
12
  if (typeof root !== "string" || !isAbsolute(root) || !isAbsolute(location.path)) return;
13
- if (!["session.jsonl", "session.jsonl.zstd"].includes(basename(location.path))) return;
13
+ if (!/^session(?:\.v[1-9][0-9]*)?\.jsonl(?:\.zstd)?$/.test(basename(location.path))) return;
14
14
  if (typeof header.id !== "string" || header.id.length === 0) return;
15
15
  const encode = (text) => text.replace(/[^A-Za-z0-9._-]/g, (ch) => `~${ch.charCodeAt(0).toString(16).toUpperCase().padStart(4, "0")}`);
16
16
  const segment = header.id === "." ? "~002E" : header.id === ".." ? "~002E~002E" : encode(header.id);
@@ -300,10 +300,10 @@ var ArchiveWorkspaceRegistry = class extends WorkspaceRegistry {
300
300
  const persistence = this.ctx.get("sessionPersistence");
301
301
  const projections = this.ctx.get("sessionProjections");
302
302
  if (cache === void 0 || typeof cache.cachedSnapshot !== "function" || typeof cache.put !== "function") return false;
303
- if (persistence === void 0 || typeof persistence.readFrom !== "function" || projections === void 0 || typeof projections.restore !== "function") return false;
303
+ if (persistence === void 0 || typeof persistence.readFrom !== "function" && typeof persistence.open !== "function" || projections === void 0 || typeof projections.restore !== "function") return false;
304
304
  try {
305
305
  if (!header.isSeeded && cache.cachedSnapshot(header, 0) !== void 0) return false;
306
- const stored = await persistence.readFrom(header.id, 0);
306
+ const stored = await this.readStoredProjectionSource(persistence, header.id);
307
307
  const meta = stored.meta ?? header;
308
308
  if (meta.isSeeded === true && stored.inheritedEventCount === void 0) {
309
309
  this.ctx.logger.warn(`archive-manager: projection repair for seeded archived session "${header.id}" skipped because its inherited event count is unavailable`);
@@ -329,6 +329,17 @@ var ArchiveWorkspaceRegistry = class extends WorkspaceRegistry {
329
329
  return false;
330
330
  }
331
331
  }
332
+ /** 新版读句柄必须关闭;旧版仍沿用 readFrom,避免激活 Agent 或写入会话日志。 */
333
+ async readStoredProjectionSource(persistence, sessionId) {
334
+ if (typeof persistence.readFrom === "function") return persistence.readFrom(sessionId, 0);
335
+ const handle = await persistence.open(sessionId, "read");
336
+ try {
337
+ const { events } = await handle.read(0);
338
+ return { meta: handle.header, inheritedEventCount: handle.inheritedEventCount, events };
339
+ } finally {
340
+ await handle.close();
341
+ }
342
+ }
332
343
  /**
333
344
  * 把一个会话移出注册表全局归档集合,恢复其正常可见性(其记账位从未
334
345
  * 移动,会话在原工作区位置重新出现)。幂等:未归档的已知会话直接返回
@@ -516,8 +527,17 @@ var ArchiveWorkspaceRegistry = class extends WorkspaceRegistry {
516
527
  await this.removeFromWorkspaceAccounts(sessionId);
517
528
  this.forgetIndexedSession(sessionId);
518
529
  if (deletedHeader !== void 0) this.deletedIdentities.set(sessionId, headerIdentity(deletedHeader));
530
+ this.publishDeletedSession(sessionId);
519
531
  return { deleted: true };
520
532
  }
533
+ /** 删除完成后通知全部客户端;新版不再通过伪造冷会话生命周期触发通知。 */
534
+ publishDeletedSession(sessionId) {
535
+ try {
536
+ this.ctx.emit("api-session/removed", sessionId);
537
+ } catch (error) {
538
+ this.ctx.logger.warn(`archive-manager: session "${sessionId}" deleted but removal notification failed: ${String(error)}`);
539
+ }
540
+ }
521
541
  /**
522
542
  * 从父类内存索引中遗忘已删除会话,并阻止后续 indexHeaders 把它加回。
523
543
  * 实时会话以同 id 重新出现时(自定义 id 复用)会撤掉墓碑。
@@ -559,7 +579,7 @@ var ArchiveWorkspaceRegistry = class extends WorkspaceRegistry {
559
579
  if (persistence === void 0 || typeof persistence.list !== "function") return false;
560
580
  let header;
561
581
  try {
562
- header = (await persistence.list()).find((item) => item.id === id);
582
+ header = (await this.listStoredHeaders()).find((item) => item.id === id);
563
583
  } catch (error) {
564
584
  this.ctx.logger.warn(`archive-manager: cold-reuse probe for "${id}" failed: ${String(error)}`);
565
585
  return false;
@@ -579,6 +599,13 @@ var ArchiveWorkspaceRegistry = class extends WorkspaceRegistry {
579
599
  if (this.deletedSessionIds.has(header.id)) return;
580
600
  return super.indexHeader(header);
581
601
  }
602
+ /** 统一旧版头部数组与 0.1.3 的持久化快照,供父类索引和本插件枚举共用。 */
603
+ async listStoredHeaders() {
604
+ return (await this.ctx.sessionPersistence.list()).map((item) => item.header ?? item);
605
+ }
606
+ async indexHeaders(items) {
607
+ for (const item of items) await this.indexHeader(item.header ?? item);
608
+ }
582
609
  /** 为未处于实时状态的持久化会话发布相同的移除事件。 */
583
610
  async publishColdSessionRemoval(sessionId, sessions) {
584
611
  const persistence = this.ctx.get("sessionPersistence");
@@ -627,6 +654,9 @@ var ArchiveWorkspaceRegistry = class extends WorkspaceRegistry {
627
654
  this.ctx.logger.warn(`archive-manager: session "${sessionId}": JSONL directory ownership could not be verified; falling back to artifact-only deletion at "${location.path}" (parent directory retained)`);
628
655
  }
629
656
  await rm(target.path, { recursive: true, force: true });
657
+ if (typeof persistence.stat === "function" && await persistence.stat(sessionId) !== void 0) {
658
+ throw new Error(`session "${sessionId}" is still present in persistence after artifact removal`);
659
+ }
630
660
  } catch (error) {
631
661
  const message = `cannot delete session "${sessionId}": cleanup of ${target.kind} "${target.path}" failed; bookkeeping retained for retry`;
632
662
  const detail = `${message}: ${String(error)}`;
@@ -660,7 +690,7 @@ var ArchiveWorkspaceRegistry = class extends WorkspaceRegistry {
660
690
  if (sessions !== void 0) for (const session of sessions.list()) {
661
691
  if (session.header.parentSession === sessionId && session.header.origin === "subagent") descendants.push(session.id);
662
692
  }
663
- for (const header of await this.ctx.sessionPersistence.list()) {
693
+ for (const header of await this.listStoredHeaders()) {
664
694
  if (header.parentSession === sessionId && header.origin === "subagent" && !descendants.includes(header.id)) descendants.push(header.id);
665
695
  }
666
696
  for (const childId of descendants) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@michengai/dsh-archive-manager",
3
- "version": "0.1.32",
3
+ "version": "0.1.34",
4
4
  "description": "NPM-installable DSH Web plugin for managing archived sessions.",
5
5
  "type": "module",
6
6
  "packageManager": "pnpm@11.22.0",
@@ -28,29 +28,31 @@
28
28
  "scripts": {
29
29
  "build": "node scripts/build.mjs && node scripts/check-package.mjs",
30
30
  "test": "pnpm build && node --test test/*.test.mjs",
31
- "test:compat": "node scripts/test-legacy-compatibility.mjs",
31
+ "test:matrix": "pnpm build && node scripts/test-version-matrix.mjs",
32
+ "test:latest": "pnpm build && node scripts/test-latest-compatibility.mjs",
33
+ "test:compat": "node scripts/test-legacy-compatibility.mjs && pnpm test:matrix",
32
34
  "pack:check": "pnpm pack --dry-run",
33
35
  "verify": "pnpm test && pnpm test:compat && pnpm pack:check && node scripts/check-generated.mjs",
34
36
  "prepublishOnly": "pnpm verify"
35
37
  },
36
38
  "peerDependencies": {
37
39
  "@deepseek-ai/cordis": "^4.0.1",
38
- "@deepseek-ai/dsh-client-connection": ">=0.1.0-rc.5 <0.2.0",
39
- "@deepseek-ai/dsh-client-locale": ">=0.1.0-rc.5 <0.2.0",
40
- "@deepseek-ai/dsh-client-runtime": ">=0.1.0-rc.5 <0.2.0",
41
- "@deepseek-ai/dsh-client-store": ">=0.1.0-rc.5 <0.2.0",
42
- "@deepseek-ai/dsh-client-ui-conversation": ">=0.1.0-rc.5 <0.2.0",
43
- "@deepseek-ai/dsh-client-ui-primitives": ">=0.1.0-rc.5 <0.2.0",
44
- "@deepseek-ai/dsh-client-ui-sidebar": ">=0.1.0-rc.5 <0.2.0",
45
- "@deepseek-ai/dsh-client-ui-workspace": ">=0.1.0-rc.5 <0.2.0",
46
- "@deepseek-ai/dsh-host-webserver": ">=0.1.0-rc.5 <0.2.0",
47
- "@deepseek-ai/dsh-session": ">=0.1.0-rc.5 <0.2.0",
48
- "@deepseek-ai/dsh-session-projection-cache": ">=0.1.0-rc.5 <0.2.0",
49
- "@deepseek-ai/dsh-spill-local": ">=0.1.0-rc.5 <0.2.0",
50
- "@deepseek-ai/dsh-storage-domain": ">=0.1.0-rc.5 <0.2.0",
51
- "@deepseek-ai/dsh-typert-protocol": ">=0.1.0-rc.5 <0.2.0",
52
- "@deepseek-ai/dsh-typert-registry": ">=0.1.0-rc.5 <0.2.0",
53
- "@deepseek-ai/dsh-workspace": ">=0.1.0-rc.5 <0.2.0"
40
+ "@deepseek-ai/dsh-client-connection": ">=0.1.0-rc.5 <0.2.0 || >=0.1.1-rc.2 <0.1.2 || >=0.1.2-rc.1 <0.1.3 || >=0.1.3-alpha.2 <0.1.4",
41
+ "@deepseek-ai/dsh-client-locale": ">=0.1.0-rc.5 <0.2.0 || >=0.1.1-rc.2 <0.1.2 || >=0.1.2-rc.1 <0.1.3 || >=0.1.3-alpha.2 <0.1.4",
42
+ "@deepseek-ai/dsh-client-runtime": ">=0.1.0-rc.5 <0.2.0 || >=0.1.1-rc.2 <0.1.2 || >=0.1.2-rc.1 <0.1.3 || >=0.1.3-alpha.2 <0.1.4",
43
+ "@deepseek-ai/dsh-client-store": ">=0.1.0-rc.5 <0.2.0 || >=0.1.1-rc.2 <0.1.2 || >=0.1.2-rc.1 <0.1.3 || >=0.1.3-alpha.2 <0.1.4",
44
+ "@deepseek-ai/dsh-client-ui-conversation": ">=0.1.0-rc.5 <0.2.0 || >=0.1.1-rc.2 <0.1.2 || >=0.1.2-rc.1 <0.1.3 || >=0.1.3-alpha.2 <0.1.4",
45
+ "@deepseek-ai/dsh-client-ui-primitives": ">=0.1.0-rc.5 <0.2.0 || >=0.1.1-rc.2 <0.1.2 || >=0.1.2-rc.1 <0.1.3 || >=0.1.3-alpha.2 <0.1.4",
46
+ "@deepseek-ai/dsh-client-ui-sidebar": ">=0.1.0-rc.5 <0.2.0 || >=0.1.1-rc.2 <0.1.2 || >=0.1.2-rc.1 <0.1.3 || >=0.1.3-alpha.2 <0.1.4",
47
+ "@deepseek-ai/dsh-client-ui-workspace": ">=0.1.0-rc.5 <0.2.0 || >=0.1.1-rc.2 <0.1.2 || >=0.1.2-rc.1 <0.1.3 || >=0.1.3-alpha.2 <0.1.4",
48
+ "@deepseek-ai/dsh-host-webserver": ">=0.1.0-rc.5 <0.2.0 || >=0.1.1-rc.2 <0.1.2 || >=0.1.2-rc.1 <0.1.3 || >=0.1.3-alpha.2 <0.1.4",
49
+ "@deepseek-ai/dsh-session": ">=0.1.0-rc.5 <0.2.0 || >=0.1.1-rc.2 <0.1.2 || >=0.1.2-rc.1 <0.1.3 || >=0.1.3-alpha.2 <0.1.4",
50
+ "@deepseek-ai/dsh-session-projection-cache": ">=0.1.0-rc.5 <0.2.0 || >=0.1.1-rc.2 <0.1.2 || >=0.1.2-rc.1 <0.1.3 || >=0.1.3-alpha.2 <0.1.4",
51
+ "@deepseek-ai/dsh-spill-local": ">=0.1.0-rc.5 <0.2.0 || >=0.1.1-rc.2 <0.1.2 || >=0.1.2-rc.1 <0.1.3 || >=0.1.3-alpha.2 <0.1.4",
52
+ "@deepseek-ai/dsh-storage-domain": ">=0.1.0-rc.5 <0.2.0 || >=0.1.1-rc.2 <0.1.2 || >=0.1.2-rc.1 <0.1.3 || >=0.1.3-alpha.2 <0.1.4",
53
+ "@deepseek-ai/dsh-typert-protocol": ">=0.1.0-rc.5 <0.2.0 || >=0.1.1-rc.2 <0.1.2 || >=0.1.2-rc.1 <0.1.3 || >=0.1.3-alpha.2 <0.1.4",
54
+ "@deepseek-ai/dsh-typert-registry": ">=0.1.0-rc.5 <0.2.0 || >=0.1.1-rc.2 <0.1.2 || >=0.1.2-rc.1 <0.1.3 || >=0.1.3-alpha.2 <0.1.4",
55
+ "@deepseek-ai/dsh-workspace": ">=0.1.0-rc.5 <0.2.0 || >=0.1.1-rc.2 <0.1.2 || >=0.1.2-rc.1 <0.1.3 || >=0.1.3-alpha.2 <0.1.4"
54
56
  },
55
57
  "peerDependenciesMeta": {
56
58
  "@deepseek-ai/dsh-client-runtime": {
@@ -62,29 +64,29 @@
62
64
  },
63
65
  "devDependencies": {
64
66
  "@deepseek-ai/cordis": "4.0.2",
65
- "@deepseek-ai/dsh-api-gateway": "0.1.2-rc.1",
66
- "@deepseek-ai/dsh-client-connection": "0.1.2-rc.1",
67
- "@deepseek-ai/dsh-client-locale": "0.1.2-rc.1",
68
- "@deepseek-ai/dsh-client-store": "0.1.2-rc.1",
69
- "@deepseek-ai/dsh-client-ui-conversation": "0.1.2-rc.1",
70
- "@deepseek-ai/dsh-client-ui-primitives": "0.1.2-rc.1",
71
- "@deepseek-ai/dsh-client-ui-sidebar": "0.1.2-rc.1",
72
- "@deepseek-ai/dsh-client-ui-slots": "0.1.2-rc.1",
73
- "@deepseek-ai/dsh-client-ui-workspace": "0.1.2-rc.1",
74
- "@deepseek-ai/dsh-host-webserver": "0.1.2-rc.1",
75
- "@deepseek-ai/dsh-invariants": "0.1.2-rc.1",
76
- "@deepseek-ai/dsh-scope": "0.1.2-rc.1",
77
- "@deepseek-ai/dsh-session": "0.1.2-rc.1",
78
- "@deepseek-ai/dsh-session-persistence": "0.1.2-rc.1",
79
- "@deepseek-ai/dsh-session-projection": "0.1.2-rc.1",
80
- "@deepseek-ai/dsh-session-projection-cache": "0.1.2-rc.1",
81
- "@deepseek-ai/dsh-spill": "0.1.2-rc.1",
82
- "@deepseek-ai/dsh-spill-local": "0.1.2-rc.1",
83
- "@deepseek-ai/dsh-storage": "0.1.2-rc.1",
84
- "@deepseek-ai/dsh-storage-domain": "0.1.2-rc.1",
85
- "@deepseek-ai/dsh-typert-protocol": "0.1.2-rc.1",
86
- "@deepseek-ai/dsh-typert-registry": "0.1.2-rc.1",
87
- "@deepseek-ai/dsh-workspace": "0.1.2-rc.1",
67
+ "@deepseek-ai/dsh-api-gateway": "0.1.3-alpha.2",
68
+ "@deepseek-ai/dsh-client-connection": "0.1.3-alpha.2",
69
+ "@deepseek-ai/dsh-client-locale": "0.1.3-alpha.2",
70
+ "@deepseek-ai/dsh-client-store": "0.1.3-alpha.2",
71
+ "@deepseek-ai/dsh-client-ui-conversation": "0.1.3-alpha.2",
72
+ "@deepseek-ai/dsh-client-ui-primitives": "0.1.3-alpha.2",
73
+ "@deepseek-ai/dsh-client-ui-sidebar": "0.1.3-alpha.2",
74
+ "@deepseek-ai/dsh-client-ui-slots": "0.1.3-alpha.2",
75
+ "@deepseek-ai/dsh-client-ui-workspace": "0.1.3-alpha.2",
76
+ "@deepseek-ai/dsh-host-webserver": "0.1.3-alpha.2",
77
+ "@deepseek-ai/dsh-invariants": "0.1.3-alpha.2",
78
+ "@deepseek-ai/dsh-scope": "0.1.3-alpha.2",
79
+ "@deepseek-ai/dsh-session": "0.1.3-alpha.2",
80
+ "@deepseek-ai/dsh-session-persistence": "0.1.3-alpha.2",
81
+ "@deepseek-ai/dsh-session-projection": "0.1.3-alpha.2",
82
+ "@deepseek-ai/dsh-session-projection-cache": "0.1.3-alpha.2",
83
+ "@deepseek-ai/dsh-spill": "0.1.3-alpha.2",
84
+ "@deepseek-ai/dsh-spill-local": "0.1.3-alpha.2",
85
+ "@deepseek-ai/dsh-storage": "0.1.3-alpha.2",
86
+ "@deepseek-ai/dsh-storage-domain": "0.1.3-alpha.2",
87
+ "@deepseek-ai/dsh-typert-protocol": "0.1.3-alpha.2",
88
+ "@deepseek-ai/dsh-typert-registry": "0.1.3-alpha.2",
89
+ "@deepseek-ai/dsh-workspace": "0.1.3-alpha.2",
88
90
  "react": "18.3.1",
89
91
  "react-dom": "18.3.1",
90
92
  "esbuild": "0.25.0"