Skip to content
dsh.fish
Bundle

dsh-multi-clear

DSH Web 插件: 侧边栏多选清空(归档)工作区对话。在会话列表底部提供"多选"按钮, 进入多选模式后勾选若干会话, 一键清空(归档)选中的全部会话。

Source
Flonger
License
MIT
Updated
Updated 3 days ago

Readme

# dsh-multi-clear

DSH Web 插件:**多选清空(归档)工作区对话 + 批量删除空工作区**。

在侧边栏会话列表底部新增「多选」入口,进入多选模式后**每一行都会出现勾选框**,
点选若干会话/工作区后一键「清空选中」——批量归档全部选中的对话;
会话已清空的**空工作区**可用红色勾选框批量**删除工作区**。

![示例预览图](./assets/preview.png)

## 功能特性

- **多选模式**:点击侧边栏底部「多选」按钮进入;再次点击、按 `Esc` 或工具条「✕ 退出」退出;
  退出后行上的勾选框会**完全清理**,不留任何痕迹。
- **三种勾选框,一眼看懂**:
  - 🔵 **蓝色框(清空会话)**——普通会话行、以及仍有会话的工作区头行。勾选工作区头 = 选中该工作区
    **全部可清空会话**(含折叠分组、含「展开其余 N 个会话」里隐藏的会话);部分选中显示半选态「—」。
  - 🔴 **红色框(删除工作区)**——会话已全部归档、没有内容可清空的工作区。勾选 = 标记删除该工作区
    (从列表移除;**文件夹与会话日志保留**,会话移至未分组)。可多选批量删除。
  - ⚪ **灰色框(无可操作内容)**——空白「新会话」草稿行等,点击无效果。
- **全选**:一键勾选**全部工作区(含折叠分组)**的所有可清空会话;再次点击全部取消。
- **批量清空(归档)会话**:二次确认后逐个归档,实时显示进度(`清理中 3/10…`);
  失败项保留选中并在 toast 提示,其余成功项已归档。
- **批量删除空工作区**:红色框勾选后点「删除工作区(N)」→ 二次确认(列出工作区名)→ 逐个删除。
- **双语文案**:中文 / English。
- **窄侧边栏保护**:侧边栏收起(rail)态点击时提示「请先展开侧边栏再使用多选」。

### 为什么有灰色/红色框?

「清空」在平台语义里是**归档**(archive):会话从列表移除、日志与文件保留。
一个工作区的普通会话**全部归档后就没有内容可清了**——此时灰色/红色框就是在告诉你
"这行已经没有可清空的会话"。要彻底移除这个工作区,请用**红色删除框**。

## 架构

```
┌─────────────────────────────────────────────┐
│ 浏览器插件 (client bundle)                    │
│ · sidebar.footer.action 槽位注册「多选」入口   │
│ · 多选模式: 行勾选框 / 工具条 / 确认弹窗        │
│ · 分组感知行映射(标题匹配, 不依赖内部组件)       │
└──────────┬──────────────────────────────────┘
           │ 读取 ctx.sessions.list / ctx.workspaces.list
           │ 调用 archiveSession() / delete()
┌──────────▼──────────────────────────────────┐
│ 平台客户端服务 (SessionRuntime / WorkspaceRuntime)│
│ · 会话/工作区基线投影(zustand store)            │
│ · RPC: workspace.archiveSession / workspace.delete│
└──────────┬──────────────────────────────────┘
           │ Host RPC
┌──────────▼──────────────────────────────────┐
│ 服务器插件 (cordis 插件行)                     │
│ · 声明插件行 + GET /multi-clear/status        │
└─────────────────────────────────────────────┘
```

- **零侵入**:行 → 会话/工作区的映射全部基于平台公开数据
  (`sessions.list` / `workspaces.list` 快照)+ DOM 行标题匹配,
  不依赖任何内部组件实现;`dsh.bundle.patch` 为纯 insert,兼容热挂载。
- **性能**:勾选框为纯 DOM 注入(MutationObserver 增量同步),无额外网络请求;
  归档/删除逐个调用平台既有 RPC(与侧边栏「⋯ → 归档会话/删除工作区」同源)。
- **安全**:清空与删除均有二次确认;失败项不静默丢失(保留选中 + toast 提示)。

## 安装

### 方式一:使用 DSH CLI 自动安装(推荐)

```bash
# npm 安装(发布后)
dsh plugin --profile web add dsh-multi-clear

# 或本地源码安装
dsh plugin --profile web add /path/to/dsh-multi-clear
```

会自动应用本包 `dsh.bundle.patch`(`cordis.patch.yml`)注册插件行。

### 方式二:GitHub Release tarball(无需 npm)

把以下依赖加入 `$DSH_HOME/profiles/web/package.json`:

```json
{
  "dependencies": {
    "dsh-multi-clear": "https://github.com/Flonger/dsh-multi-clear/releases/latest/download/dsh-multi-clear-0.1.0.tgz"
  },
  "dsh": {
    "profile": {
      "bundles": [ "…", "dsh-multi-clear" ]
    }
  }
}
```

然后在 `$DSH_HOME/profiles/web` 下执行 `pnpm install`,重启 DSH 应用。

### 方式三:让 AI 助手帮您安装

把本仓库地址或 README 交给您的 DSH/Codex/Claude 助手,它会按方式一/二完成安装。

## 使用说明

1. 点击侧边栏底部(「导入会话」下方)的 **「多选」** 按钮进入多选模式。
2. 会话树每一行左侧出现勾选框:
   - 点击**会话行**:勾选/取消该会话(不会误打开会话)。
   - 点击**蓝色框工作区头**:全选/全不选该工作区的全部会话。
   - 点击**红色框工作区头**:标记/取消删除该工作区。
3. 工具条:`✕ 退出` / `已选 N 项[ · 工作区 M]` / `全选` / `删除工作区(M)` / `清空选中`。
4. 点「清空选中」→ 确认弹窗 → 逐个归档会话。
5. 点「删除工作区(M)」→ 确认弹窗(列出工作区名)→ 逐个删除工作区。

> **规则**:仅"普通会话"可清空——子代理会话、已归档会话、空白草稿会话(新会话)不参与勾选;
> 搜索模式下不做勾选(退出搜索即可)。全选只作用于可清空会话,不含删除工作区。

## 配置(可选)

覆盖配置写进 `$DSH_HOME/profiles/web/cordis.patch.yml`:

```yaml
- id: dsh-multi-clear
  config:
    confirmBeforeClear: false   # 清空前跳过二次确认(默认 true)
```

客户端进入多选模式时会读取 `GET /multi-clear/status` 下发的 `confirmBeforeClear`。

## 验证

```bash
# 服务端插件已生效
curl http://127.0.0.1:43120/multi-clear/status
# → {"ok":true,"plugin":"dsh-multi-clear","confirmBeforeClear":true}

# 客户端 bundle 可访问
curl -o /dev/null -w "%{http_code}\n" http://127.0.0.1:43120/plugins/dsh-multi-clear/client.js
# → 200
```

刷新页面后侧边栏底部应出现「多选」按钮。

## 开发说明

```
dsh-multi-clear/
├── package.json          # dsh.client 声明(platform=web + inject 依赖)
├── cordis.patch.yml      # bundle 层插件行(纯 insert, 兼容热挂载)
├── src/index.js          # 服务端半部(插件行 + /multi-clear/status)
├── client/client.js      # 浏览器半部(lazy-CJS 客户端 bundle, 单文件无构建)
├── test/smoke-client.mjs # 客户端零依赖冒烟测试(派生逻辑 + slot 注册 + 渲染)
├── test/smoke-server.mjs # 服务端路由冒烟测试
├── .github/workflows/publish.yml  # 打 tag 自动发布 npm
├── publish-to-github.sh  # 一键发布到 GitHub + DSH 插件市场
└── assets/preview.png
```

```bash
pnpm test   # 冒烟测试: 客户端派生逻辑 + slot 注册 + 入口渲染 + 服务端路由
```

> 服务端测试需要能解析 `@deepseek-ai/schemastery` 的 node_modules
> (本仓库已建符号链接指向 web profile 的 node_modules,见 `.gitignore`)。

## 发布

```bash
GH_TOKEN=ghp_xxx ./publish-to-github.sh          # 发布到 GitHub + 插件市场
GH_TOKEN=ghp_xxx NPM_TOKEN=npm_xxx ./publish-to-github.sh   # 同时发布 npm
```

或推送 `v*` tag 触发 GitHub Actions 自动发布 npm(见 `.github/workflows/publish.yml`)。

## 常见问题 (FAQ)

**Q: 为什么有的行不能勾选?**
A: 灰色框 = 该行没有可清空的会话(会话已全部归档的工作区/空白草稿行);
子代理会话与已归档会话本身不参与勾选;「展开其余 N 个会话」里隐藏的会话
可先用工作区头行勾选或全选覆盖,或点开溢出按钮后再勾。

**Q: 清空和删除工作区有什么区别?**
A: 清空 = 归档会话(会话从列表移除,日志与文件保留,可随时通过导入重新读回);
删除工作区 = 从工作区列表移除(文件夹与会话日志保留,会话移至未分组)。
两者都不会删除磁盘上的任何文件。

**Q: 退出多选后为什么看不到圈圈了?**
A: 退出时会自动清理所有注入的勾选框/类名/数据集(并带 CSS 兜底),
保证侧边栏恢复原样。

**Q: 会误删我的会话吗?**
A: 清空与删除都需要二次确认;归档/删除逐条执行,失败项保留选中并提示。

## 📝 更新日志 (Changelog)

### v0.1.0 (2026-08-26)

- 首个发布版本。
- 多选清空(归档)工作区对话:会话行/工作区头行勾选、半选态、全选、批量归档、进度与失败提示。
- 批量删除空工作区:红色删除框标记、二次确认、逐条删除(文件夹与日志保留)。
- 分组感知行映射(消除跨分组同标题会话映射错位);退出时完整清理勾选框。
- 中英双语;窄侧边栏保护;`/multi-clear/status` 只读状态路由。

Install

dsh plugin --profile web add github:Flonger/dsh-multi-clear

Profile: web

  • This source has no pinned commit, so a later push upstream changes what installs. Prefer pinning a commit.
Source