Bundle
@local/dsh-session-dustbin
DSH session dustbin: delete sessions straight from the left sidebar session menu (next to rename / fork / archive) and manage archived sessions from Settings -> Plugins -> Configurable. Head-frame only: no session log is ever decoded.
- Source
- Github-CJX
- License
- MIT
- Updated
- Updated 12 hours ago
Readme
# dsh-session-dustbin **DSH 会话纸篓** — 在左侧会话行菜单里直接删除会话(与「重命名 / 分支会话 / 归档会话」并列),并在 **设置 → 插件 → 可配置** 里管理已归档会话。    > v0.2.0 为**全新重写**:旧仓库代码已全部作废,本目录可整体覆盖 `Github-CJX/dsh-session-dustbin`。 ## 功能 - **左侧会话菜单删除项**:会话行「⋯」菜单里在「归档会话」下方追加「🗑 删除会话」,点击后弹出 DSH 风格确认框(需勾选「我了解这会永久删除,且无法恢复」)。 - **删除链路(无需重启)**:先经平台 `workspaceRegistry.archiveSession()` 归档(侧边栏**立即**收走该行)→ 删除本地会话目录 → 删除头帧缓存 → 清理 `workspace.json` 标记。 - **归档会话管理卡片**:设置 → 插件 → 可配置 → 「会话纸篓」,列出归档会话,逐条删除。 - **只展示头帧**:列表只读取平台为每个会话持久化的头帧投影(`session_projcache`,标题 / 创建时间 / 轮数),**从不解压 `session.jsonl.zstd`**,单条 O(1),与对话长度无关。 - **无需查看详情**:没有任何对话内容读取接口,也不提供展开查看——按需求刻意不做。 ## 工作原理 | 数据 | 位置 | 用途 | |---|---|---| | 归档集合 | 运行中 `workspaceRegistry.archivedSessionIds`;落盘 `~/.dsh/storages/workspace.json` | 判定 archived、驱动删除前归档 | | 会话头帧 | `~/.dsh/storages/session_projcache/sessions/<id>.json` | 标题 / 创建时间 / 轮数(列表唯一数据源) | | 会话数据 | `~/.dsh/sessions/<项目>/<id>/session.jsonl.zstd` | 只用于判断存在与删除,从不解码 | 删除顺序(缺一不可): ``` 删除请求 ├─① workspaceRegistry.archiveSession(id) 内存归档 + 广播 → 侧边栏立即收行 ├─② 删除 ~/.dsh/sessions/<项目>/<id>/ 数据彻底清除 ├─③ 删除头帧 session_projcache/<id>.json 列表不会复活该行 └─④ 清理 workspace.json 标记(尽力而为) 运行中的 host 可能回写,列表按目录存在性过滤 ``` ## 目录结构 ``` dsh-session-dustbin/ ├── lib/ # 宿主半(Node ESM) │ ├── index.js # 插件入口:设置命名空间 + 路由挂载 │ ├── protocol.js # 共享常量(命名空间 / 路由 / id 校验) │ ├── sessions.js # 头帧读取、列表、删除(框架无关,可单测) │ ├── routes.js # loopback 围栏桥(ping / list / delete) │ └── client.js # 预构建客户端 bundle(提交以便克隆即用) ├── src/client/ # 浏览器半(rolldown 打包) │ ├── index.ts # 入口:locale + 设置卡片 + 侧边栏菜单注入 │ ├── DustbinCard.tsx # 会话纸篓卡片(头帧列表 / 删除) │ ├── sidebar-menu.tsx # 会话行菜单注入「删除会话」 │ ├── locales.ts # zh / en 文案 │ ├── protocol.ts # 与 lib/protocol.js 对应的类型 │ └── dustbin-card.module.css ├── docs/ # installation / architecture / troubleshooting ├── build-client.mjs # 客户端构建(CSS Modules 内联 + ModuleLoader 包装) ├── sync-profile.mjs # 一键装进 DSH profile(镜像 + 注册 + pnpm install) ├── test-host.mjs # 宿主逻辑测试(临时目录,不碰真实数据) ├── test-mount.mjs # 挂载测试(桩 cordis ctx) └── smoke-client.mjs # 客户端 bundle 冒烟(桩 loader/DOM) ``` ## 开发与验证 ```bash pnpm install node test-host.mjs # 42 checks:头帧/列表/删除/围栏 node build-client.mjs # 重建 lib/client.js node test-mount.mjs # 9 checks:设置段 + 三条路由 + 处理器 node smoke-client.mjs # 14 checks:bundle 契约 + apply() 挂载 node sync-profile.mjs # 装进 profile(然后重启 DSH Desktop) ``` ## 样式一致性 - 卡片严格复用平台的卡片契约:外壳 / 头部 / 正文 / 页脚取自 `@deepseek-ai/dsh-client-ui-settings-plugins` 的 `PluginCard.module.css`,行 / 标签 / 胶囊 / hint 取自同包的 `fields.module.css`(数值逐条照抄,仅类名本地化),因此在「设置 → 插件 → 可配置」里与「终端」「agent 循环」等卡片外观一致。 - 菜单注入项深拷贝平台的「归档会话」项,图标用平台原生 `IconTrashOutline16` 的路径,配色与 hover 走 `Menu.module.css` 的 `.danger` 令牌(`--dsw-alias-state-error-primary` / `--dsw-alias-interactive-bg-hover-danger`)。 ## 已知约束 - **菜单注入是 DOM 注入**:平台会话菜单是 `dsh-client-ui-workspace` 里写死的数组,没有 slot 可扩展。注入项在菜单每次打开时重新追加;React 重渲染可能吞掉已注入节点,重开菜单即恢复。 - **会话 id 靠标题反查**:会话行 DOM 不携带 id,注入项点击后通过 list 桥按标题匹配(重复标题取第一个)。 - **删除不可逆**:目录 + 头帧 + 标记一并清除,卡片与菜单均带需勾选的确认框。 - **残留标记**:运行中的 host 内存里仍保留已删 id,直到下次重启才彻底干净;列表按目录存在性过滤,不会显示空条目(卡片会提示「N 条归档标记已无对应数据」)。 - **不读对话内容**:这是刻意设计(性能),需要看内容请用平台的会话打开功能。 安装与排障见 [docs/installation.md](docs/installation.md)、[docs/architecture.md](docs/architecture.md)、[docs/troubleshooting.md](docs/troubleshooting.md)。
Install
dsh plugin --profile web add github:Github-CJX/dsh-session-dustbin
Profile: web
With the hub plugin installed, ask your agent to install it by name — it resolves the same plan shown here.
dsh plugin --profile web add github:stvlynn/dsh.fish#path:packages/dsh-plugin-hub
install local-dsh-session-dustbin from the hub
- This package builds from source on install. pnpm will ask you to allow its build script — that is permission to run the package’s code on your machine, outside the agent sandbox. Only allow sources you trust.
- This source has no pinned commit, so a later push upstream changes what installs. Prefer pinning a commit.