# dsh-session-manager — DeepSeek Harness 会话与工作区管理器

[English](README.md) | 中文

[![npm version](https://img.shields.io/npm/v/dsh-session-manager)](https://www.npmjs.com/package/dsh-session-manager)
[![DeepSeek Harness](https://img.shields.io/badge/DeepSeek%20Harness-宿主-1082ff)](https://github.com/deepseek-ai/deepseek-harness)
[![GitHub](https://img.shields.io/badge/GitHub-仓库-blue)](https://github.com/hkkz9522/dsh-session-manager)
[![CI](https://github.com/hkkz9522/dsh-session-manager/actions/workflows/ci.yml/badge.svg)](https://github.com/hkkz9522/dsh-session-manager/actions/workflows/ci.yml)
[![Awesome DSH Plugin](https://awesome-dsh-plugin.com/badge.svg)](https://awesome-dsh-plugin.com)

## 0 简介

DSH 会话与工作区管理——工作区：归档与显示。会话：跨工作区移动、预设迁移、删除；收藏、待回看、优先级、标签、备注。批量操作。

已在官方 DSH Desktop 客户端完成实际测试，当前验证范围见「5 兼容性」；两种环境共用本插件的 Host 与客户端功能，具体安装方式见下文。

## 1 功能

### 1.1 会话生命周期管理

- **删除**：不可逆操作，UI 始终要求二次确认。subagent 会话和尚未落盘的空白会话占位不能删除。
- **归档 / 移出归档**：把会话移出或移回主列表，不删除磁盘内容。
- **移动至工作区**：跨工作区移动时保留历史、标题、归档状态和派生会话关系，同时把 `cwd` 重写为目标工作区，实时同步活动 Agent 的运行时 `workingDirectory` 投影，并就地更新 live writer 的 header，使挂起的工具调用继续落到新路径。若会话的 `cwd` 本来就等于目标工作区、只是归属未登记，则只补全归属记录，不改写 `cwd`、不重写或移动工件、不重启会话。
- **迁移 Agent 预设**：原预设被改名或删除导致会话无法恢复时，可修复该会话。迁移会就地重写最后一条 `agent-preset/selected` 事件（若从未记录则修改会话 header），不改动历史消息。

### 1.2 会话快捷管理

- **收藏 / 待回看**：长期标记和手动提醒；不会随归档或会话结束自动清除。
- **搜索**：按标题、会话 ID、备注、标签不区分大小写匹配，自动去除首尾空格，不读取聊天历史。
- **筛选与排序**：工作区（全部 / 未分组 / 具体）与归档状态（全部 / 未归档 / 已归档）可叠加；可叠加收藏 / 待回看、标签和优先级筛选；排序支持最近更新（默认）、最早更新、最新创建、最早创建、名称升序（A → Z）、名称降序（Z → A）以及**优先级（1 → 5）**。
- **优先级**：下拉 **1 最高、2 高、3 普通、4 低、5 最低**，**默认 3（普通）**；旧数据中的 `null` 归一化为 3。
- **标签 / 备注**：每会话最多 20 个标签（每个 ≤ 32 字符）、备注最多 2000 字符。英文 `,` 与中文 `，` 都是分隔符，首尾空白被去除，重复标签按大小写不敏感合并。
- **AI 整理（手动、可选）**：标签 / 备注编辑窗口内的 **复制 Prompt** 把结构化提示复制到剪贴板，**导入** 解析剪贴板 JSON（可识别 Markdown 代码块、对话包裹、智能引号、孤立反斜杠和开头 BOM），按相同规则校验后填入字段；两者都不会自动调用模型。
- 标记保存在 `dsh-session-manager/annotations.v1.json`，按会话 ID 关联；同源客户端实例通过 `BroadcastChannel` 同步；保存可跨进程崩溃恢复，版本冲突会提示"载入最新内容"。

### 1.3 批量处理

- **批量模式入口**：在会话管理窗口顶部点击 **批量处理** 切换按钮，行左侧出现复选框，工具栏出现 **全选筛选 / 清空选择** 和 **批量按钮区**；退出批量模式会清空当前选中。
- **批量按钮区** 列出所有批量动作：
  - **标记切换**：**归档 / 取消归档 / 收藏 / 取消收藏 / 待回看 / 取消待看**。
  - **变更操作**：**添加标签 / 清空标签 / 设置优先级 / 移动至工作区 / 迁移预设 / 删除会话**。
- **执行流程**：非破坏性操作（归档 / 取消归档 / 收藏 / 取消收藏 / 待回看 / 取消待看 / 添加标签 / 清空标签 / 设置优先级 / 移动至工作区 / 迁移预设）立即执行，结果按会话逐条展示在 **结果对话框** 的 **成功 / 失败 / 跳过** 分组里，并提供 **重试失败项** 一键把失败 ID 重新加入选中；破坏性操作（**删除会话**）先弹 **预览对话框** 列出受影响的会话，再显示进度条，最后给出逐条结果。

### 1.4 插件更新与设置卡片

- **检查更新**：会话管理窗口顶部提供 **npm 图标按钮**（检查更新），点击可检查新版本并在有更新时展示小红点提示；点击弹出更新窗口，展示当前版本与最新版本，支持完全独立的一键自动更新，内置安装源保护、HMR 与非 HMR 环境自适应协调、更新状态持久化校验、失败自动回滚和重启/刷新提示。
- **设置卡片**：注册在 DSH 设置的插件配置页（`settings.plugin.item`）。展示当前安装版本、最新版本状态、卡片内检查更新与更新按钮、自动检查偏好开关以及 GitHub 仓库链接。
- **安装源选择**：在设置卡片中可随时切换安装源，可选 **npm 官方源**（`registry.npmjs.org`，默认）与 **中国大陆镜像源**（`registry.npmmirror.com`）；检查更新与版本下载将直接请求所选源。
- **弹窗透明度**：设置卡片「偏好设置」区域提供 50%–100% 滑块（步长 5%，默认 100%）与「恢复默认」按钮，支持调节插件弹窗的背景填充透明度，文字、按钮、输入框、标签与边框等内容保持不透明并即时生效。
- **主题**：全面跟随 DSH 当前主题（包含第三方主题插件），弹窗、设置卡片、标题栏按钮、下拉菜单、输入框等界面元素自动适配浅色与深色主题。
- **统一下拉样式**：所有下拉选择框（排序、筛选、优先级等）采用无四周阴影的统一圆角自定义浮层，严格对齐触发框宽度，并解决 Chromium 原生系统弹层与自定义浮层重叠的双层问题。

### 1.5 工作区归档与管理

- **双页面切换**：在管理弹窗顶部可在「会话管理」与「工作区管理」之间无缝切换，保留各自的搜索与筛选状态。
- **工作区列表**：完整展示全部已注册工作区，包含工作区名称、物理路径、所属会话数、基于所属会话计算的最近更新时间及状态开关。
- **工作区搜索与筛选**：支持按名称和路径不区分大小写搜索；支持全部 / 未归档 / 已归档筛选；支持按最近更新 / 最早更新 / 名称升序 / 名称降序排序；支持批量归档与取消归档；工具栏按钮自适应折行。
- **显示开关与归档**：
  - **关闭开关（归档）**：执行安全检查（运行中会话拒绝归档），直接将工作区及其所有未归档会话一并归档，并从 DSH 原生侧边栏隐藏。若发生局部失败，自动执行完整回滚以确保状态一致。
  - **开启开关（恢复）**：解除工作区归档标记并恢复在原生侧边栏显示，自动恢复此前归档工作区时归档的会话；用户单独归档的会话继续保持归档。新建路径相同的工作区自动恢复显示。
- **原生侧边栏无缝隐藏**：采用派生快照拦截与会话 ID 归属处理，隐藏工作区不会导致其会话错误流入「未分组」，支持深浅主题、持久化存储与 DSH 重启保持。

## 2 UI入口

### 2.1 标题栏入口

标题栏右侧对**当前会话**提供：**归档 / 移出归档**、**收藏**、**待回看**、**标签 / 备注**、**移动至工作区**、**删除会话**以及**更多操作**（`⋯`），与 DSH 原生顶栏按钮规范完全对齐（28px 高度、无边框幽灵透明样式、SVG 矢量描边图标）。

### 2.2 会话与工作区管理入口与界面

从 DSH 侧边栏底部进入 **会话与工作区**，可浏览全部会话与工作区：会话管理页支持切换工作区、按标题 / ID / 备注 / 标签搜索、应用筛选与排序，并对每条会话执行 **打开 / 归档 / 移出归档 / 标签 / 备注 / 移动 / 迁移预设 / 删除** 操作；工作区管理页支持搜索、排序、批量处理与显示开关切换。

### 2.3 批量管理入口

管理窗口顶部的 **批量处理** 按钮即是入口：点一下进入批量模式，行左侧出现复选框，工具栏出现 **全选筛选 / 清空选择** 和 **批量操作** 按钮；再点一次退出批量模式。

### 2.4 设置卡片入口

在 DSH 设置中进入插件设置页（会话管理），可查看版本信息、切换 npm 官方源或中国大陆镜像源、开启/关闭自动检查更新，或手动检查并更新。

## 3 安装

### 3.1 从插件安装

在 DSH 的 **插件** 中添加插件，搜索 `dsh-session-manager` 并安装。该方式适用于官方 Web UI 和 Desktop 客户端。

### 3.2 从第三方插件市场安装

本插件已被 [dsh-market](https://github.com/dsh-market/dsh-market) 和 [awesome-dsh-plugin](https://github.com/awesome-dsh-plugin/awesome-dsh-plugin) 收录。

### 3.3 通过 CLI 安装至 Web profile

从 npm 安装：

```powershell
dsh plugin --profile web add npm:dsh-session-manager
```

从 GitHub 安装：

```powershell
dsh plugin --profile web add github:hkkz9522/dsh-session-manager
```

安装后重启 DSH Web。若浏览器仍加载旧的客户端代码，可使用 `Ctrl+Shift+R` 强制刷新。

> `desktop` profile 由官方 Desktop 客户端管理，普通 `dsh` CLI 不用于修改该 profile。Desktop 用户请通过客户端内的 **插件** 安装插件。

### 3.4 本地开发 / 测试

#### Web profile

通过 CLI 安装本地仓库：

```powershell
dsh plugin --profile web add <本仓库路径>
```

本地仓库会作为插件 checkout 链接到当前 profile，适合直接修改源码并进行测试。

#### Desktop 客户端

在官方 Desktop 客户端中打开 **插件**，使用本地仓库的绝对路径作为安装源。

对于 Client 端代码，在 HMR 正常工作的情况下，保存修改后可以自动重新加载；若修改未立即生效，可重新加载当前界面或重启对应的 DSH Web / Desktop 客户端。

修改插件依赖、`package.json`、bundle 配置等安装或加载相关内容后，建议重新安装插件或重启对应客户端。

## 4 安全说明

- **删除不可恢复**，UI 始终要求二次确认；删除前校验会话 ID、目录边界和工件 header，不允许通过路径穿越、符号链接或 junction 操作其他目录。
- 移动和迁移预设保留 live session / agent；只有删除才会取消运行并释放会话。移动会更新保存的 cwd 和 live writer 的 header。
- 会话管理列表隐藏 subagent 会话，移动接口也拒绝 subagent；尚未落盘的空白会话不能跨工作区移动。
- 冷会话重写保留原工件格式（V1 / V2 / V3 / V4 都可读，绝不强制升级）。损坏或截断的 Zstd 日志、缺少完整尾行的 JSONL 会拒绝移动 / 重写，不会把部分历史当作完整日志保存。
- 迁移预设按"备份 → 发布 → 回滚"分阶段处理。如果回滚失败，会保留恢复文件并在错误中报告路径；不要删除这些文件。
- **工作区归档事务保护**：若工作区内存在运行中会话则拒绝归档；批量归档会话若中途遇到异常会自动回滚已变更状态，避免部分成功导致状态不一致。
- 启动时若发现 `cwd` 对应已注册工作区但归属记录遗漏的会话，会通过 DSH 官方接口补全登记（幂等）；扫描不完整时只跳过清理，不会误删现有归属，也不会清除仍在内存中或扫描期间新加入的会话。
- 同一会话的插件写操作按顺序执行；请求体限制为 64 KiB。该队列不替代 DSH 自身的持久化写入协调。
- **集中 API 鉴权与安全门禁**：所有 `/session-manager/api/*` 接口统一接入 DSH 官方 `connection.admit()` / `requestRejection()` 校验，严格限制仅 Owner 权限主体可调用，服务未就绪时默认拒绝（HTTP 503 Fail-Closed），有效阻断公网隧道或反向代理暴露下的未授权访问。

## 5 兼容性

下表列出 DeepSeek Harness（DSH）与 `dsh-session-manager` 已验证的版本组合。

> **版本验证说明**：自 0.6.3 起，本插件仅在官方 DSH Desktop 客户端上进行验证（Web UI 与本插件共用同一套 Host / 客户端代码，但不再纳入常规验证范围）。

| DeepSeek Harness (DSH) | dsh-session-manager | 验证环境 |
| :--- | :--- | :--- |
| **v0.2.1-rc.2** | `0.7.5`, `0.7.4`, `0.7.3`, `0.7.2` | Desktop |
| **v0.2.0-rc.2** | `0.7.1`, `0.7.0`, `0.6.4`, `0.6.3`, `0.6.2`, `0.5.4` | Desktop |
| **v0.1.7-rc.2** | `0.5.3` | Desktop / Web UI |
| **v0.1.7-rc.1** | `0.5.2` | Desktop / Web UI |
| **v0.1.6-alpha.2** | `0.5.1` | Web UI |
| **v0.1.5-rc.2** | `0.4.11` | Web UI |
| **v0.1.5-rc.1** | `0.4.10`, `0.4.9`, `0.4.7` | Web UI |
| **v0.1.3-alpha.2** | `0.4.6`, `0.4.4`, `0.4.1` | Web UI |
| **v0.1.2-rc.1** | `0.4.0` | Web UI |
| **v0.1.0-rc.7** | `0.1.2`, `0.1.1`, `0.1.0` | Web UI |

以上版本组合已在官方 Web UI 或 Desktop 客户端中完成测试。其他版本组合可能同样兼容，但未逐一验证。

使用独立 DSH CLI / runtime 时，需要 Node.js 22.15+（22.x）或 24+，以提供内置 Zstd 支持。官方 Desktop 客户端单独携带并管理与其版本匹配的 runtime。

本插件是 Cordis 插件，peer dependency 为 `cordis: ">=4.0.0-rc <5"`。

## 6 开发

- `lib/index.js` 是 host 端 ESM 插件，`lib/client.js` 是客户端 UI bundle，无需构建步骤。
- 提交修改前请运行：

```powershell
npm run check
npm test
npm run check:package
git diff --check
```

测试使用隔离临时目录和真实插件入口，不操作真实会话。CI 在 Windows / Linux、Node 22.15.0 / 24 上执行相同检查。

可选集成检查：对正在运行的 DSH Web profile 测试实例执行 `node scripts/smoke-test.mjs`；它会请求实际服务，不属于默认单元测试。

发布记录见 [CHANGELOG.md](CHANGELOG.md)。

## 7 致谢

感谢每一位安装和使用 dsh-session-manager 的用户，也感谢提交 Issue 与 Pull Request 帮助改进本插件的朋友们。欢迎提出修改意见。

## 8 开源许可

[MIT](LICENSE)
