dsh-web
zhu1090093659/dsh-webDeepSeek Harness(DSH)Web 插件聚合生态包 · 一切皆插件,创意工坊分发(dsh-market.com)
会话太多删不掉?归档只是隐藏、记录还躺在磁盘上?想给一个会话换个名字还要翻菜单?
给 DSH 补上会话管理:侧栏「⋯」菜单一键删除(永久删除、可配置),对话区头部一键重命名。
⚠️ 删除是永久删除,不可恢复(本插件没有回收站)。删除正在运行的会话时,会先停止该会话,然后再删除。

# npm
dsh plugin --profile <profile> add dsh-session-tool
# 本地目录
dsh plugin --profile <profile> add file:C:/path/to/dsh-session-tool
# GitHub
dsh plugin --profile <profile> add github:<owner>/dsh-session-tool
装完重启 DSH。<profile> 替换成你的 profile 名(如 web、desktop)。
sessions 服务,改完侧栏与头部标题即时更新cancel 并等静默(最多 15 秒),再 flush/detach,最后删除目录并清理记账hidden)~/.dsh/logs/dsh-session-tool.log写在 profile 的 cordis.patch.yml(~/.dsh/profiles/<profile>/cordis.patch.yml),键名区分大小写,改完重启 DSH 生效。
只写你要改的部分,没写的键全部用默认值。
- id: dsh-session-tool
name: dsh-session-tool
config:
MenuItems: # ⋯ 菜单里的项
official: # 官方 4 项(不写 = 一个都不碰)
pin: { } # 可写:label / activeLabel / order / hidden
rename: { } # 只支持 hidden(重命名对话框是官方内部实现)
fork: { } # 可写:label / order / hidden
archive: { } # 可写:label / activeLabel / order / hidden
plugin:
delete:
label: "删除会话" # 文案(留空 = 跟随系统语言)
order: 500 # 顺序,越小越靠前
hidden: false # true = 隐藏这一项
danger: true # 红色危险样式
disabled: false # 禁用态:变灰、点不动
shortcut: null # 【已登记,本阶段未实现】
separatorBefore: false # 【已登记,本阶段未实现】
ButtonItems: # 会话行悬停时的图标按钮
official:
archive: { hidden: false } # 只支持 hidden
pin: { hidden: false } # 只支持 hidden(已归档的行上本来也不显示)
plugin: { } # 占位:本插件不提供悬停按钮
order 是普通数字,升序排列:越小越靠前;不写等于 0(会排在最前面);数字相同则按注册顺序(官方先注册,排在我们前面)。
| order | 菜单项 | 来源 | 能否修改 |
|---|---|---|---|
| 100 | 置顶会话 pin | 官方 | label / activeLabel / order / hidden |
| 200 | 重命名 rename | 官方 | ⚠️ 只能 hidden |
| 300 | 分叉会话 fork | 官方 | label / order / hidden |
| 400 | 归档会话 archive | 官方 | label / activeLabel / order / hidden |
| 500 | 删除会话 delete | 本插件(默认) | 全部字段 |
| order | 悬停按钮 | 来源 | 能否修改 |
|---|---|---|---|
| 100 | 归档按钮 | 官方 | ⚠️ 只能 hidden |
| 200 | 置顶按钮 | 官方 | ⚠️ 只能 hidden |
# order 参考:官方 pin 100 / rename 200 / fork 300 / archive 400;本插件 delete 默认 500
- id: dsh-session-tool
name: dsh-session-tool
config:
MenuItems: # ⋯ 菜单里的项
official: # 官方 4 项:不写就不碰
pin: {} # 可写:label / activeLabel / order / hidden
rename: {} # 只支持 hidden
fork: {} # 可写:label / order / hidden
archive: {} # 可写:label / activeLabel / order / hidden
plugin:
delete: # 本插件唯一的菜单项
label: "删除会话"
order: 500
hidden: false
danger: true # 红色危险样式
disabled: false # 禁用态(变灰、点不动)
ButtonItems: # 会话行【悬停时】的图标按钮
official:
archive:
hidden: true # 隐藏官方悬停「归档」按钮
pin:
hidden: true # 隐藏官方悬停「置顶」按钮
plugin: {} # 占位:本插件不提供悬停按钮
| 位置 | 内容 |
|---|---|
| 侧栏会话行「⋯」菜单 | 「删除会话」(文案/顺序/显隐/危险样式/禁用态可配) |
| 对话区头部工具栏 | ✏️「重命名会话」(该排最左侧) |
| 会话行悬停区 | 官方归档/置顶按钮(可隐藏);本插件不提供悬停按钮 |
删除弹窗四态
| 状态 | 触发 | 表现 |
|---|---|---|
| 正常 | 会话在列表且未运行 | 副标题「删除后,该对话将不可恢复」+ 勾选框 + 删除按钮(未勾选时禁用) |
| 运行中 | 会话正在运行 | 多一行 ⚠「会话正在运行 —— 删除会立即中断它正在进行的任务」,勾选框与按钮变成「停止并删除」 |
| 会话不存在 | 列表里找不到该会话 | 提示刷新后重试,隐藏勾选框、禁用删除按钮 |
| 删除成功 | 删除完成 | 「已删除」+「该对话已永久删除,无法恢复。」+ 完成按钮 |
重命名:输入框预填当前名称、自动聚焦;名称为空时「确定」禁用;回车提交、Esc 取消;失败在弹窗内显示原因。
删除链路(六步)
cancel 取消回合并等待静默(最多 15 秒)flush 写盘 + 从内存会话表 detach,避免收尾阶段把日志目录重建回来sessionIds、归档集合加载稳健性
apply 必须同步完成:任何 await(尤其是网络请求)都可能让入口永远停在 loadingduplicate exact route)官方悬停按钮的隐藏是怎么实现的(维护提示)
插槽契约写着「复用官方 id 就会替换那一行」,但实测跨插件不可靠:框架给每个插件各自分配注册优先级, 官方注册的条目数量多、计数更靠前,于是官方那行仍然胜出。所以本插件改用 DOM/CSS 级隐藏:
<style id="dsh-session-tool-hide-shipped">
button[aria-label="归档会话"],button[aria-label="取消归档"],
button[aria-label="Archive session"],button[aria-label="Unarchive session"],
button[aria-label="置顶会话"],button[aria-label="取消置顶"],
button[aria-label="Pin session"],button[aria-label="Unpin session"] { display: none !important; }
</style>
⚠️ 维护提示:这段选择器依赖官方按钮的
aria-label文案(中英各 2 种状态,共 8 条)。 如果 DSH 更新后官方改了这些文案(或新增状态),隐藏会失效 —— 此时只需在lib/client.js的ARCHIVE_LABELS/PIN_LABELS两个数组里补上新文案即可。日志里每次加载都会记录cssRules=<条数>,可用来核对。
~/.dsh/logs/dsh-session-tool.log(超过 1 MB 轮转为 .log.1)
[2026-10-16T09:08:44.519Z] delete ok id=session-9cc49402-… title="创建三个空子智能(9cc49402)" running=false stopped=false dirs=1 elapsed=0.0s
[...] plugin info HTTP 路由已注册:/list /config /diag /delete
[...] config warn 未知的配置键 "menuItems" → 你是否想写 "MenuItems"?(键名区分大小写)
[...] client info config #1: ok | changed=true | hiddenButtons=archive,pin | cssRules=8
配置写错不会打断 DSH 启动,只会记一行日志并忽略该项。
dsh plugin --profile <profile> remove dsh-session-tool
完整版本记录见 changelog/CHANGELOG.md。
MIT
Too many sessions and no way to remove them? Archiving only hides a session while its files stay on disk? Renaming a session means digging through menus?
Session management for DSH: delete from the sidebar "..." menu (permanent, configurable) and rename from the conversation header.
⚠️ Deletion is permanent and unrecoverable (there is no trash). Deleting a running session first stops it, then removes it.

# npm
dsh plugin --profile <profile> add dsh-session-tool
# local checkout
dsh plugin --profile <profile> add file:C:/path/to/dsh-session-tool
# GitHub
dsh plugin --profile <profile> add github:<owner>/dsh-session-tool
Restart DSH afterwards. Replace <profile> with your profile name (e.g. web, desktop).
sessions service, so the sidebar and header titles update livehidden is supported)~/.dsh/logs/dsh-session-tool.logPut it in the profile patch file ~/.dsh/profiles/<profile>/cordis.patch.yml. Keys are case-sensitive and changes apply after restarting DSH.
Only write what you want to change - everything omitted keeps its default.
- id: dsh-session-tool
name: dsh-session-tool
config:
MenuItems: # items in the "..." menu
official: # the 4 shipped items (omitting one leaves it untouched)
pin: { } # writable: label / activeLabel / order / hidden
rename: { } # hidden only (its dialog is official internals)
fork: { } # writable: label / order / hidden
archive: { } # writable: label / activeLabel / order / hidden
plugin:
delete:
label: "Delete session" # empty string = follow the system language
order: 500 # ascending; smaller values come first
hidden: false # true = hide this item
danger: true # red danger styling
disabled: false # disabled state: greyed out, not clickable
shortcut: null # [registered, not implemented yet]
separatorBefore: false # [registered, not implemented yet]
ButtonItems: # hover icons on a session row
official:
archive: { hidden: false } # hidden only
pin: { hidden: false } # hidden only (never shown on archived rows anyway)
plugin: { } # placeholder: this plugin adds no hover buttons
order is a plain number, sorted ascending: smaller comes first; omitted means 0 (which puts it first); equal values keep registration order (shipped items register first, so they come before ours).
| order | Menu item | Owner | Editable |
|---|---|---|---|
| 100 | Pin session pin | shipped | label / activeLabel / order / hidden |
| 200 | Rename rename | shipped | ⚠️ hidden only |
| 300 | Fork session fork | shipped | label / order / hidden |
| 400 | Archive session archive | shipped | label / activeLabel / order / hidden |
| 500 | Delete session delete | this plugin (default) | every field |
| order | Hover button | Owner | Editable |
|---|---|---|---|
| 100 | Archive | shipped | ⚠️ hidden only |
| 200 | Pin | shipped | ⚠️ hidden only |
# order reference: shipped pin 100 / rename 200 / fork 300 / archive 400; this plugin's delete defaults to 500
- id: dsh-session-tool
name: dsh-session-tool
config:
MenuItems: # items in the "..." menu
official: # the 4 shipped items: omit = never touch
pin: {} # writable: label / activeLabel / order / hidden
rename: {} # hidden only
fork: {} # writable: label / order / hidden
archive: {} # writable: label / activeLabel / order / hidden
plugin:
delete: # the only menu item this plugin adds
label: "Delete session"
order: 500
hidden: false
danger: true # red danger styling
disabled: false # disabled state (greyed out, not clickable)
ButtonItems: # hover icons on a session row
official:
archive:
hidden: true # hide the shipped archive hover button
pin:
hidden: true # hide the shipped pin hover button
plugin: {} # placeholder: this plugin adds no hover buttons
| Where | What |
|---|---|
| Sidebar session row "..." menu | "Delete session" (label/order/visibility/danger/disabled configurable) |
| Conversation header toolbar | Pencil "Rename session" (leftmost in that row) |
| Session row hover area | shipped archive/pin buttons (can be hidden); this plugin adds none |
Delete dialog, four states
| State | Trigger | Behaviour |
|---|---|---|
| Normal | session exists and is idle | subtitle "This conversation will be permanently deleted" + checkbox + delete button (disabled until ticked) |
| Running | session is running | an extra ⚠ line "The session is running - deleting interrupts its work immediately"; checkbox and button become "Stop and delete" |
| Missing | the session is gone | asks you to refresh, hides the checkbox and disables the delete button |
| Done | deletion finished | "Deleted" + "The conversation has been permanently deleted." + a finish button |
Rename: the input is prefilled with the current title and focused; confirm is disabled while empty; Enter submits, Esc cancels; failures are shown inside the dialog.
Delete pipeline (six steps)
cancel the turn and wait for silence (up to 15 s)flush to disk and detach from the in-memory session table so dispose-time writes cannot recreate the log directorysessionIds, archived setLoad robustness
apply must finish synchronously: any await (especially a network request) can leave the entry stuck in loading foreverduplicate exact route)How the shipped hover buttons are hidden (maintenance note)
The slot contract says reusing a shipped id replaces that row, but in practice this is unreliable across plugins: the framework assigns registration priorities per plugin, and the shipped plugin registers many entries so its counter is ahead - the shipped row still wins. This plugin therefore uses DOM/CSS hiding instead:
<style id="dsh-session-tool-hide-shipped">
button[aria-label="归档会话"],button[aria-label="取消归档"],
button[aria-label="Archive session"],button[aria-label="Unarchive session"],
button[aria-label="置顶会话"],button[aria-label="取消置顶"],
button[aria-label="Pin session"],button[aria-label="Unpin session"] { display: none !important; }
</style>
⚠️ Maintenance note: these selectors depend on the shipped
aria-labelstrings (2 states in each of zh/en, 8 rules in total). If a DSH update changes those strings (or adds a state), hiding stops working - just add the new strings toARCHIVE_LABELS/PIN_LABELSinlib/client.js. Every load logscssRules=<count>so you can verify what was injected.
~/.dsh/logs/dsh-session-tool.log (rotated to .log.1 above 1 MB)
[2026-10-16T09:08:44.519Z] delete ok id=session-9cc49402-... title="Create three empty subagents (9cc49402)" running=false stopped=false dirs=1 elapsed=0.0s
[...] plugin info HTTP routes registered: /list /config /diag /delete
[...] config warn unknown config key "menuItems" -> did you mean "MenuItems"? (keys are case-sensitive)
[...] client info config #1: ok | changed=true | hiddenButtons=archive,pin | cssRules=8
A bad configuration never blocks DSH startup: it only logs one line and ignores that entry.
dsh plugin --profile <profile> remove dsh-session-tool
See changelog/CHANGELOG.md (Chinese).
MIT