把左侧栏变成可展开的会话树,随时给任意子会话发消息
30/100
综合分
0
GitHub 星标
—
npm 周下载
—/5
用户评分
数据截至 2026/10/2 · 周下载取自 npm 全网(含 CI / 镜像),非本站安装数;综合分由星标、活跃度与兼容性检查合成。
安装命令 · 需先装 dsh CLI 引擎
dsh plugin --profile web add orphiczhou/dsh-session-tree该包不可直接 npm 安装,改从 GitHub 源安装(明细见下方安装检查)
状态速览
判定依据:实装验证 · 静态安装检查 · 自动扫描 · 仓库维护状态信任档位:待复验
是什么
dsh 原生插件 · browser
安全吗
本站尚未对该插件做风险分级
暂未覆盖,不等同于无风险
还在维护吗
更新放缓:最近一次提交在 33 天前
档位由哪些信号合成
本站实装验证(真实安装 L4 覆盖全站;L5 为运行时冒烟或实机截图,覆盖范围小于 L4) · 验证所用 dsh 版本 · 静态安装检查 · 风险分级 · 仓库维护状态。 下方各区块是它的证据明细。
社区实装还没有人打卡 · 装过的第一个就是你
安全扫描自动 · 静态分析源码v2.7.0🟢 扫描:未发现敏感能力尚无人工评估展开查看扫描说明与证据 ↓
安全扫描自动 · 静态分析源码
v2.7.0静态扫描未发现敏感能力:最多只发网络请求、读取自身元数据或只读文件,未发现执行命令、文件写入或敏感信息读取。
扫描于 2026/11/4(0 天前) · 范围 入口闭包 + 发布文件清单 · 来源 GitHub 仓库
静态扫描只反映源码中出现的调用,不构成安全背书;人工评估与自动扫描相互独立、互不覆盖。
给这个插件打分还没有人投票↓
用户评分
还没有人投票,来当第一个
功能亮点
- 左侧栏会话树
- 点击直达多轮对话
- 向任意会话发消息
DeepSeek Harness 的左侧栏会话树:每个会话连同嵌套的子代理后代,点击直达多轮对话,还有 tree_send 工具,可给树中任意可继续的会话发消息。
README
由 DeepSeek 最新模型翻译生成dsh-session-tree
一个 DeepSeek Harness 的 profile bundle:把左侧栏换成会话树——每个会话下面挂着它的 subagent 后代,可逐层展开、层数不限,点任意节点就能打开该会话的多轮对话。它还注册了宿主工具 tree_send,让智能体能给树里任意一个可续聊的子会话发消息,包括内置通讯 API 够不到的兄弟会话。
功能
| 功能 | 说明 |
| 树形视图 | 显示工作区的全部会话,origin: 'subagent' 的子会话按持久化的父子关系(parentId)嵌在父会话下,层数不限。 |
| 按需展开 | 初始全部折叠;展开某个节点才构建它的子树,缩进每层加 13 px(最多 8 层)。 |
| 渲染上限 | 每层最多渲染 300 个子行,其余以明确的“另有 N 个未显示”提示给出,不静默丢弃。 |
| 四态状态圆点 | 每行一个:进行中(蓝、带呼吸动画)、已完成但还没看过(绿)、已完成且已看过(灰)、正在等你回应(橙)。颜色取自 DSH 主题 token,随明暗主题变化。 |
| 视图选项 | 标题栏 … 菜单:按最近更新或按名称排序(置顶会话始终在前)、已归档会话「隐藏 / 显示 / 仅显示」、展开全部、全部折叠、重新加载标题。 |
| 每行 …
展开完整文档(README 剩余 1 节)
dsh-session-tree
一个 DeepSeek Harness 的 profile bundle:把左侧栏换成会话树——每个会话下面挂着它的 subagent 后代,可逐层展开、层数不限,点任意节点就能打开该会话的多轮对话。它还注册了宿主工具 tree_send,让智能体能给树里任意一个可续聊的子会话发消息,包括内置通讯 API 够不到的兄弟会话。
功能
| 功能 | 说明 |
| 树形视图 | 显示工作区的全部会话,origin: 'subagent' 的子会话按持久化的父子关系(parentId)嵌在父会话下,层数不限。 |
| 按需展开 | 初始全部折叠;展开某个节点才构建它的子树,缩进每层加 13 px(最多 8 层)。 |
| 渲染上限 | 每层最多渲染 300 个子行,其余以明确的“另有 N 个未显示”提示给出,不静默丢弃。 |
| 四态状态圆点 | 每行一个:进行中(蓝、带呼吸动画)、已完成但还没看过(绿)、已完成且已看过(灰)、正在等你回应(橙)。颜色取自 DSH 主题 token,随明暗主题变化。 |
| 视图选项 | 标题栏 … 菜单:按最近更新或按名称排序(置顶会话始终在前)、已归档会话「隐藏 / 显示 / 仅显示」、展开全部、全部折叠、重新加载标题。 |
| 每行 … 菜单 | 置顶 / 取消置顶、重命名(行内编辑:回车提交、Esc 取消、失焦提交)、Fork、归档 / 取消归档。 |
| ↗ 在右侧栏打开 | 把子会话的对话以 subagentchat 资源的形式打开在右侧栏,单独占一个窗格。 |
| 新建会话 | 标题栏的 + 按钮——接管左栏后自带浏览器的新建入口被遮蔽,这里补上。 |
| 搜索框 | 按标签或会话 id 过滤;过滤时不分层,结果平铺显示。 |
| 折叠后的侧栏 | 左栏被折叠成图标条时渲染一个 ≡ 按钮,点击即可展开侧栏。 |
| tree_send 工具 | 宿主半工具:向树里任意可续聊的子会话投递消息,兄弟会话也可以。 |
安装
DSH 没有中心化的插件市场——没有应用内商店、没有插件索引、也没有发布 API。插件就是一个普通包,靠 README 被人发现;下面这条安装命令就是全部的传播方式。这个仓库本身就是那份“上架信息”。
DSH 以 profile bundle 的形式安装插件。应用的 Plugins 页面(Add plugin)接受四种 spec:npm 包名、Git URL、tarball、绝对本地路径。本 bundle 是纯 ESM、不需要构建,下面几种方式都可以直接用。
图形界面安装
1. 打开左侧栏的 Plugins 页面。
2. 选择 Add plugin。
3. 把仓库地址粘进 spec 输入框:
https://github.com/orphiczhou/dsh-session-tree
4. 确认。bundle 会装进当前 profile,左栏立即变成会话树,无需重启。
命令行安装
dsh plugin add orphiczhou/dsh-session-tree
owner/repo 是 GitHub 简写,github:orphiczhou/dsh-session-tree 与完整 clone 地址等价;加 --profile <name> 可以指定默认之外的 profile。dsh plugin <args...> 只是把参数转发给 profile 目录里的 pnpm,所以这就是一次普通的 pnpm 安装,外加在 profile 的 dsh.profile.bundles 里追加一条。
git 安装拉取的是源码而不是构建产物,而 pnpm ≥ 10 默认拒绝执行依赖的构建脚本,除非用户显式放行。本包没有任何构建脚本、也不需要构建,因此不会出现放行提示。
从本地 checkout 安装
dsh plugin --profile <name> add /absolute/path/to/dsh-session-tree
路径必须是绝对路径;pnpm 会把它记成 link: 依赖。
确认装好了
- 切到启用了本 bundle 的 profile 打开 DSH:左栏标题应当变成 会话树(英文界面下是 Sessions)——这说明当前渲染的是本插件,而不是自带的会话浏览器。
- 展开任意一个右侧带子会话数量的行,子会话会嵌套显示在下面。
- 如果左栏和自带的会话列表一模一样,去 Plugins 页面确认 id 为 session-tree 的那一行是启用状态。已启用但仍无变化,见疑难排查。
可选:让智能体列一下自己的工具,tree_send 在列表里就说明宿主半挂上了。(该工具只在 tools、subagents、sessionQuery 三个服务都存在时注册;缺服务的组合里插件照常加载,只是不提供这个工具。)
使用
展开与打开
- 点行首的 ▶ 展开或折叠;没有子会话的行不显示这个三角。
- 折叠状态下有子会话的行,右侧会显示子会话数量。
- 点行的其他位置打开该会话。顶层会话走自带导航 openSession(sessionId);子会话行走 openSession({ parentSessionId, childSessionId, mode }),所以可续聊的子会话会显示多轮历史并接受你的后续提问,而已经结束的一次性子会话打开后是只读的——这是 DSH 自带的行为,不是本插件造成的。
- 子会话行上的 ↗ 会把同一个对话打开到右侧栏,单独占一个 subagentchat 窗格,左栏不受影响。
- 标题栏的 + 新建会话。
视图选项
标题栏的 … 按钮打开菜单:
- 排序方式——最近更新 或 按名称。两种排序下置顶会话都在最前。
- 已归档会话——隐藏已归档(默认)、显示已归档、仅显示已归档。
- 展开全部 / 全部折叠。
- 重新加载标题——从宿主重新读取每个会话的当前标题(见实现要点)。
每行操作
行上的 … 按钮(悬停时出现)打开:置顶 / 取消置顶、重命名、Fork 分支会话、归档 / 取消归档。重命名是行内编辑——回车提交、Esc 取消、失焦提交。Fork 只对普通会话提供,子会话行不显示。
tree_send
tree_send 用来给不是你直接父会话、也不是你直接子会话的子会话投递消息。自带的 send_message 按“活的发送者”授权,因此强制邻接关系,兄弟之间没有路径可走;tree_send 改按目标的持久化父地址授权,这正是兄弟能被寻址的原因。
| 参数 | 必填 | 含义 |
| target | 是 | 目标子会话(可续聊)的 session id。 |
| message | 是 | 要投递的正文。 |
| delivery | 否 | steer(默认)在目标最近的一个 step 边界投递;queue 投给之后的某个 turn。 |
| parent | 否 | 目标的直接父会话 id。省略时由工具从目标自己的会话日志里读出。 |
它只返回“已受理”(messageId),不等待、也不返回回复:
{ "messageId": "…", "parent": "session-1d637ac2-…", "delivery": "steer" }
一个完整的例子
一个顶层会话 A,两个可续聊的子会话 B、C,以及挂在 B 下面的孙会话 D:
A (顶层会话,由它来调用 tree_send) ├── B (可续聊子会话) │ └── D (可续聊子会话) └── C (可续聊子会话)
兄弟 → 兄弟。 B 里的智能体要把一个发现交给 C,它调用:
{ "target": "C", "message": "你问的那个 schema 在 packages/session/session-title/src/types.ts。", "delivery": "steer" }
省略了 parent,工具于是去读 C 的日志,取出它的 parentSession(也就是 A),再从那个地址投递。A 在线,投递被受理。这正是内置 API 表达不了的情况——B 并不是 C 的父会话。
父 → 子。 A 给 B 或 C 发消息,就是同一个调用换个 target,解析方式也一样——B 自己的日志里写着父会话是 A,那正是投递用的地址。
顶层 → 孙会话仍然没有路径。 A 给 D 发消息需要经由 D 的直接父地址(B)投递,而从工具的授权角度看 D 并不是 B 的孩子,请求会以 subagent/parent-unavailable 被拒。请分两步:A → B,再 B → D。
明确的边界
- 目标必须是可续聊(mode: 'continuable')的子会话;一次性的子会话会以"不可恢复"被拒。
- 目标的直接父会话必须在线,否则调用失败:subagent/parent-unavailable。
- 调用只返回受理结果(message id),既不等待回复也不返回回复。
- 日志里没有 parentSession 的目标不是子会话,无法这样寻址。显式传入 parent 就等于指定投递地址;传错会被服务拒绝。
- 两个互不相关的顶层会话之间依然没有路径。 它们没有共同的父地址——tree_send 扩展的是“谁可以被寻址”,不是“谁可以被触达”。
失败会以抛错形式报告,带 tree_send: 前缀,例如 tree_send: delivery rejected — subagent/parent-unavailable: …。
实现要点
- 席位。 插件占用 sidebar.workspaces——左栏那个单占用(single)席位,优先级 -100。single 席位取优先级最低的注册者渲染,而在已被占用的优先级上注册会在加载时抛错,所以必须用一个不同的优先级。自带的 WorkspaceBrowser 是 0,于是本插件拿到席位,而自带那一行仍然留在册——停用本插件,自带侧栏原样回来。
- 数据。 全部来自槽位 props(useSessions),不走宿主 RPC:state.byId 给出每个会话一行,state.projectionsBySession 给出投影快照。这些行本来就带血缘信息(parentId 加 origin: 'subagent')——因为自带侧栏刻意隐藏了 origin: 'subagent' 的行,整棵嵌套树其实早就在 store 里,本插件只是不再隐藏它。子会话自己没有对应行时,用 subagentCatalog 补上。
- 标题。 最新标题在挂载时通过 remote.session.list({}) 从宿主读取——那是每次现读、覆盖全部会话、并带上各自当前 projections.values.title 的接口。客户端 store 里的投影快照每个连接只加载一次基线,之后 refreshProjections 就是空操作,因此 store 里可能永远停在一个早期的 fallback 标题上。选 重新加载标题 可以再读一次。
- 打开会话。 点击节点复用自带导航(openSession),所以打开的就是普通的对话界面、普通的标题栏和输入区。
- 宿主半只注册一个工具 tree_send。工具定义直接写成 defineTool() 产出的纯对象形状,因此不导入 @deepseek-ai/dsh-tools,它也不是依赖。
兼容性与版本策略
本 bundle 不声明任何 peerDependencies。
这是刻意的。DSH 唯一强制检查的兼容字段,就是 @deepseek-ai/dsh 与 @deepseek-ai/dsh- 上的 peerDependencies,它会拿正在运行的运行时版本做 semver 匹配,任何一个范围不匹配就跳过该 bundle。没有声明 DSH peer 就不构成任何约束,所以不声明意味着运行升级时本插件不会硬失败。
这句话说的是兼容闸门,不是“以后每个 DSH 版本都能用”的承诺。插件使用的客户端服务是 slots、sessions、uiWorkspace、sidebarRight、locale,宿主侧用的是 subagents.prompt 与 sessionQuery.filterSessions;如果将来的 DSH 改动了这些接口,相应功能会失效,尽管安装依然成功。需要可复现的安装就钉住一个 commit(github:orphiczhou/dsh-session-tree#<sha>)。
停用 / 卸载
停用即刻还原自带侧栏,不需要重启。
- 图形界面: 在 Plugins 页面关掉 id 为 session-tree 的那一行。
- 命令行: dsh plugin --profile <name> remove @orphiczhou/dsh-session-tree,依赖与 bundle 层一起移除。
完全卸载后,tree_send 会在下一次重启后从工具列表里消失(原因见下)。
疑难排查
左栏空白,或者加载时报了席位(slot)相关的错。 sidebar.workspaces 是单占用席位:只能有一个注册者,而在已被占用的优先级上注册会在加载时抛错。不要和另一个同样占用 sidebar.workspaces 的插件一起装——两者必有一个加载失败。已经装成这样了,就在 Plugins 页面停用其中一个。
改了代码,侧栏没变化。 客户端 bundle 是按文件大小与修改时间派生版本来提供的,所以代码改动要在刷新页面后才生效。改完 client.js 请刷新浏览器窗口。(要做到“改完不刷新就自动重建”,得是带 web dev watcher 的源码 checkout;装的是已发布的包时,刷新即可。)
启用/停用之后侧栏没变化。 启用与停用是即时作用于当前页面的。若没看到变化,刷新一次页面。
改了宿主半(index.js),工具没变化。 Loader 对已导入的宿主模块是按包名缓存的,所以改已安装包的宿主半必须重启 DSH 才生效——停用再启用、卸载重装、把入口指向新文件路径,拿到的都还是缓存里那一代。只有换一个新的包名才能绕过这份缓存。客户端半不受此影响,刷新页面即可。
某一行显示的文字不是会话标题。 这是有意为之,而且与应用其他地方保持一致。对子会话来说,DSH 在主窗口标题栏和右侧栏标签里显示的本来就是子智能体的描述符标签(创建它时的委派标签),不是 session/title。本插件渲染同一个字符串,正是为了让行上的文字和点开后看到的东西对得上。会话自身的标题作为次要信息保留:以 标签 — 标题 的形式出现在该行的 tooltip 里。普通(非子会话)行显示的是持久化的会话标题。
某一行的标签是灰的,tooltip 说标题尚未加载。 该会话既没有可用的描述符标签、也没有宿主标题,于是这一行退化成了目录名或短 id 之类的东西,用降低不透明度明确表示“这不是应用自己会显示的那个字符串”。可以在视图选项里点 重新加载标题,或者展开它的父节点,让子会话的投影被请求一次。
父节点明明有子智能体,却没有展开箭头。 它的子会话目录还没加载。展开时会(尽力)请求该父会话的投影;如果目录始终没来,客户端就不知道有哪些子会话,也就不会有箭头。
开发
仓库是纯 ESM,不需要编译。
dsh-session-tree/
├── index.js # 宿主半:tree_send 工具 ├── client.js # 客户端半:整个侧栏 UI(浏览器 bundle) ├── cordis.patch.yml # 本 bundle 贡献的唯一一条 Cordis 行 ├── package.json # 清单:dsh.bundle、dsh.client、exports ├── locale/{en,zh}.json # Plugins 页面的展示元数据 ├── icon.svg # bundle 图标 ├── scripts/verify-bundle.mjs # 清单自检 ├── test/render.test.cjs # headless 渲染测试 ├── LICENSE ├── README.md # 英文 README └── README.zh.md # 本文件
跑渲染测试:
node test/render.test.cjs
它在 Node 沙箱里加载真实的 client.js(stub 掉 window.__ModuleLoader__ 和 React),用按实时会话数据重建的会话表驱动它,然后断言产出的行结构:默认是否全折叠、逐级展开后的行数、各层缩进、key 是否唯一、畸形行是否被容错处理,以及点击顶层会话与子会话行是否用正确的寻址方式导航。
按 DSH 安装 bundle 时实际执行的规则自检清单(patch 文件存在且可解析、exports["./client"] 与 dsh.client.platform、客户端模块 id 与包名一致、图标大小、locale 文件、以及声明了哪些 DSH peer):
node scripts/verify-bundle.mjs
许可证
MIT © orphiczhou
为 DeepSeek Harness 而做。DSH、Cordis 以及自带的 @deepseek-ai/dsh- 包均为各自作者的作品;本 bundle 只是占用了一个客户端席位、注册了一个宿主工具。预览分享卡片长什么样 ↓
分享 · DeepSeek Harness Hub
orphiczhou/dsh-session-tree
把左侧栏变成可展开的会话树,随时给任意子会话发消息
相关插件 · 浏览器
智能体插件框架deepseek-ai/deepseek-harness
DeepSeek Harnessdsh是由 DeepSeek AI 开发的开源 agent harness智能体框架。
★ 270,422已汉化DSH
71.9
多设备 Agent 看板YaoApp/yao
✨ 所有 Agent 和工作区集中管理,覆盖你的每一台设备。任务看板追踪进度,桌面端、移动端、浏览器、API…
★ 8,147已汉化DSH
71.2
可扩展侧边栏工作台omdsh-dev/DSH-better-sidebar
DSH 的双工作台:原生右侧栏 + 自绘底部面板,并把 ctx.betterSidebar 服务开放给所有插件
★ 4,761已汉化DSH
71.1
浏览器自动化桥Tencent/BrowserSkill
你的 Agent。你的浏览器。连接,就能协作。
★ 9,967已汉化DSH
71
AI 小说创作工作台EthanYoQ/AI-Novel-Writer
AI 小说作家 / AI Novel Writer
★ 1,591已汉化DSH
70.7
智能体浏览器引擎platonai/Browser4
DeepSeek Harness 集成
★ 1,175已汉化DSH
70.4
这是你的仓库?认领条目