DeepSeek Harness 插件

TianYa-DAO/dsh-pinned-sessions

Star 数 ★ 0 下载量(近 30 天) 377 分类 会话与消息 收录于 2026-10-16 npm dsh-pinned-sessions

把运行中、跑完未点开和当前打开的会话固定在 DSH Web 侧栏工作区分组上方,并可从任意会话/工作区的「...」菜单里全局置顶。

安装

# npm 包(预构建)

dsh plugin --profile web add dsh-pinned-sessions

# Release 预构建包

dsh plugin --profile web add "https://github.com/TianYa-DAO/dsh-pinned-sessions/releases/latest/download/dsh-pinned-sessions-0.2.0.tgz"

# GitHub 源码(首次需按提示配置 allowBuilds 构建授权后重试)

dsh plugin --profile web add github:TianYa-DAO/dsh-pinned-sessions

装任何插件都等于在你的机器上跑第三方代码,权限和你本人一样大——能读你的文件、用你的凭据、访问网络,工具审批管不到它。GitHub 来源的插件还会在安装时执行构建脚本——pnpm 默认拦截,所以安装可能停在 ERR_PNPM_GIT_DEP_PREPARE_NOT_ALLOWED 或 ERR_PNPM_IGNORED_BUILDS;dsh 会打印出需要添加的确切键名,把它加进该 profile 的 pnpm-workspace.yaml 的 allowBuilds 下,重跑一次即可装上。放行构建本身就是一次信任判断:请只安装可信来源,并尽量锁定 commit(github:owner/repo#sha)。

README

反馈 / Feedback:遇到 bug 或有改进建议,请到 Issues 提;也可以直接发邮件到 2842425998@qq.com。

把你不该跟丢的会话固定在 DSH Web 侧栏工作区列表顶部,并且允许从任意会话/工作区自己的「...」菜单里全局置顶。

English | 中文

置顶区里有什么

顺序如下,位于区域标题下方、所有工作区分组上方:

侧栏
├─ 工作区              ← 区域标题(搜索 / 视图选项 / 添加工作区)
├─ 置顶                ← 本插件插入
│   ├─ 全局置顶 2       ← 从会话「...」菜单置顶的会话
│   │   ● 会话标题…            proj
│   ├─ 进行中 1         ← 由会话状态推导
│   │   ● 会话标题…            other
│   ├─ 待查看 1
│   ├─ 当前打开 1
│   └─ 置顶工作区       ← 从工作区「...」菜单置顶的工作区
│       ▸ proj  4
├─ 工作区分组一         ← 被置顶的工作区在这里消失
└─ 工作区分组二
  1. 全局置顶的会话:从会话「...」菜单置顶;同时仍保留在下方它自己的工作区分组里。

  2. 进行中 / 待查看 / 当前打开:由会话状态推导:

    分组 判据 圆点
    进行中 会话状态 running === true 蓝色呼吸点
    待查看 会话状态 completionUnread === true(跑完但你还没点开) 绿色点
    当前打开 会话被主视图持有(retainedBy.mainView > 0) 空心环

    一个会话只进其中一个分组(优先级如上)。被全局置顶的会话不再出现在这些分组里——它的状态由置顶行前面那个点表示。

  3. 全局置顶的工作区:从工作区「...」菜单置顶;在置顶区里渲染成可展开的分组,里面的会话可直接点开,而该工作区在下方列表里的原分组会被隐藏。

已归档会话、subagent 子会话不出现。组内按最近更新倒序;空的部分不显示;所有部分都为空时整段不渲染。点击行即打开该会话。

置顶区只在「按工作区分组 / 工作区树」模式下显示;侧栏收起成图标栏、切成「一张扁平列表」、或列表正在显示搜索结果时自动隐藏——而且它隐藏时不会隐藏下方任何东西。

置顶与取消置顶

  1. 会话「...」菜单里新增 全局置顶 / 取消全局置顶:这是 DSH 官方槽位 sidebar.workspaces.session.menu.item 里的真实菜单项,和自带的置顶、重命名、分叉、归档并列。
  2. 工作区「...」菜单里同样新增这一项。DSH 没有为工作区菜单声明槽位,所以这一项是插件门户注入进那个弹层的——靠打开行的 data-row-key="workspace:<key>" 定位。
  3. 置顶会话行与置顶工作区标题行悬停时右侧都有取消置顶的 ×;工作区那个是必需的,因为它原来的行在置顶期间被隐藏了。

置顶区插在列表自己的滚动容器最前面,所以置顶项很多时,它和工作区分组共用同一个滚动条,不会被自己裁掉。

开关

设置 → 通用 → 置顶会话区。偏好(开关、置顶的会话、置顶的工作区、哪些置顶工作区是折叠的)持久化在共享客户端 store,localStorage 键为 dsh.pinned-sessions.prefs.v1。

安装

npm:

dsh plugin add dsh-pinned-sessions

Release tarball:

dsh plugin add https://github.com/TianYa-DAO/dsh-pinned-sessions/releases/latest/download/dsh-pinned-sessions-0.2.0.tgz

桌面版可在「插件」页里安装。包内声明了 dsh.bundle,profile 会挂载它的 cordis.patch.yml 行,客户端注册表随之为浏览器提供 ./client.js。

实现要点

  1. 纯客户端插件:client.js 通过动态客户端模块协议(window.__ModuleLoader__.load)加载;overlay 行注册进增量槽 shell.overlay,由它承载下面两个 portal。
  2. 侧栏工作区区域(sidebar.workspaces)是 single 槽、区域内部没有可插入的插槽,因此本插件不改动也不替换自带浏览器:自己创建一个 host 元素,插到 div[data-slot="sidebar.workspaces"] 内列表自己的滚动容器(带浏览器 list 类、即 overflow-y: auto 的那个元素)最前面。插件卸载时 host 被移除。
  3. 位置与模式判定全部通过稳定的 DOM 事实完成:listArea 类名定位列表区;projectRow / searchResultRow 行类名区分工作区分组 / 扁平列表 / 搜索结果;根节点上的 rail 类名判定侧栏收起。MutationObserver 负责结构变化,1.5s 轮询兜底区域被整体替换的情况。
  4. 工作区菜单项被 portal 进打开菜单的弹层;弹层是 React portal 到 document.body 的,它属于哪一行由 data-row-key 加打开态类名确定。
  5. 数据来自客户端根标准 hook:useSessions / useSessionStatus / useWorkspaces;打开会话走 ctx.get("uiWorkspace").openSession(id)。
  6. 样式只用自己的 dshps-* 类,颜色全部取自 --dsw-alias-* 主题 token,跟随主题/皮肤。客户端半只依赖平台模块(react、react-dom、@deepseek-ai/dsh-client-store、@deepseek-ai/dsh-client-ui-primitives),所以本包没有任何安装期 npm 依赖。

自检

npm test

用桩化的动态模块协议加载 client.js,校验:工厂与导出形状、apply() 的三次注册(槽位 / id / order / 共享 store / inject face / 双语字典)、分区推导(优先级、归档与 subagent 过滤、空会话、显式置顶、置顶工作区)以及渲染树。

已知限制

  1. 依赖自带客户端的 DOM 与类名(listArea / projectRow / searchResultRow / rail / list)。DSH 若重构侧栏结构,需要同步更新 client.js 里的锚点选择器。
  2. 工作区「...」菜单项是注入的(DSH 没有该槽位);那个弹层的结构一变,就要同步更新 client.js 里的定位逻辑。
  3. 客户端包版本变化(如方法或 hook 改名)可能导致注册失败;client.js 对 uiWorkspace 缺失做了降级告警,不做静默失败。
  4. 实测环境为 DSH 0.2.0-rc.2。

许可

MIT

内容来自项目 README(GitHub)↗

链接

同类插件

查看整个分类 →

社区评论

评论公开保存在 GitHub Discussions。加载评论会连接 GitHub 和 Giscus;发表内容需要 GitHub 账号。