🎁 福利专区全网大模型免费应用 + 新用户福利 + 注册活动入口,低成本玩转 AI

会话标签页 thezavtrak-a11y/dsh-session-tabs

DeepSeek Harness
thezavtrak-a11y30 天前有提交已提供中文文档扫描:未发现敏感能力

把打开的会话变成浏览器式标签,可切换拖动或拖出成窗

30/100
综合分
0
GitHub 星标
—
npm 周下载
—/5
用户评分

数据截至 2026/10/4 · 周下载取自 npm 全网(含 CI / 镜像),非本站安装数;综合分由星标、活跃度与兼容性检查合成。

安装命令 · 需先装 dsh CLI 引擎
dsh plugin --profile web add thezavtrak-a11y/dsh-session-tabs
该包不可直接 npm 安装,改从 GitHub 源安装(明细见下方安装检查)

状态速览

判定依据:实装验证 · 静态安装检查 · 自动扫描 · 仓库维护状态
信任档位:已验证
是什么
dsh 原生插件 · browser
装得上吗
本站已在 dsh 0.2.1-rc.5 下真实安装成功
非静态推断
L5 · 运行时冒烟等级说明 →
安全吗
本站尚未对该插件做风险分级
暂未覆盖,不等同于无风险
还在维护吗
活跃:最近一次提交在 30 天前
档位由哪些信号合成

本站实装验证(真实安装 L4 覆盖全站;L5 为运行时冒烟或实机截图,覆盖范围小于 L4) · 验证所用 dsh 版本 · 静态安装检查 · 风险分级 · 仓库维护状态。 下方各区块是它的证据明细。

验证判据与等级说明 →
社区实装还没有人打卡 · 装过的第一个就是你
安全扫描自动 · 静态分析源码
v2.7.0
🟢 扫描:未发现敏感能力尚无人工评估
展开查看扫描说明与证据 ↓

静态扫描未发现敏感能力:最多只发网络请求、读取自身元数据或只读文件,未发现执行命令、文件写入或敏感信息读取。

扫描于 2026/11/4(0 天前) · 范围 入口闭包 + 发布文件清单 · 来源 GitHub 仓库

静态扫描只反映源码中出现的调用,不构成安全背书;人工评估与自动扫描相互独立、互不覆盖。

给这个插件打分还没有人投票↓
用户评分
还没有人投票,来当第一个

功能亮点

  • 会话转为标签页
  • 切换关闭标签
  • 拖拽排序

README

由 DeepSeek 最新模型翻译生成
dsh-session-tabs 给 DeepSeek Harness 窗口里打开的会话加上浏览器风格的标签页——切换、关闭、拖动排序,还能把标签页拖出来变成独立窗口。这是一个 DeepSeek Harness 客户端插件。 窗口碰过的每个会话都会变成标签,排在应用顶部的标签条里。点标签切换过去,用 × / 中键 / 右键菜单关闭,左右拖动调整顺序,或者拖出标签条交给新窗口。关闭标签永远不会删除会话——就像关闭浏览器标签永远不会删除网页一样。 上游代码一行都没改。插件注册进 Web 客户端官方的 slot、locale 和 Session 接口,所以 DSH 升级后依然能用,卸载只需删掉一行。 你能得到什么 - 为打开的会话显示标签 —— 这个窗口显示的每个会话对应一个标签,顺序就是你离开时的顺序。 - 切换 —— 点标签。如果有全局面板开着,点击会先回到对话。 - 关闭 —— 标签上的 ×、鼠标中键,或者右键菜单(Close tab、Close other tabs、Close all tabs)。会话本身还留在侧边栏,点一下就能重新打开。 - 排序 —— 左右拖动标签,相邻标签会随拖动让位,新顺序会写进这个窗口的标签列表。 - 拖出成独立窗口 —— 把标签拖出标签条再松手:指针在外面时,光标下方会出现提示,会话随即在新窗口打开。
展开完整文档(README 剩余 1 节)
dsh-session-tabs

给 DeepSeek Harness 窗口里打开的会话加上浏览器风格的标签页——切换、关闭、拖动排序,还能把标签页拖出来变成独立窗口。这是一个 DeepSeek Harness 客户端插件。

窗口碰过的每个会话都会变成标签,排在应用顶部的标签条里。点标签切换过去,用 × / 中键 / 右键菜单关闭,左右拖动调整顺序,或者拖出标签条交给新窗口。关闭标签永远不会删除会话——就像关闭浏览器标签永远不会删除网页一样。

上游代码一行都没改。插件注册进 Web 客户端官方的 slot、locale 和 Session 接口,所以 DSH 升级后依然能用,卸载只需删掉一行。

你能得到什么

- 为打开的会话显示标签 —— 这个窗口显示的每个会话对应一个标签,顺序就是你离开时的顺序。
- 切换 —— 点标签。如果有全局面板开着,点击会先回到对话。
- 关闭 —— 标签上的 ×、鼠标中键,或者右键菜单(Close tab、Close other tabs、Close all tabs)。会话本身还留在侧边栏,点一下就能重新打开。
- 排序 —— 左右拖动标签,相邻标签会随拖动让位,新顺序会写进这个窗口的标签列表。
- 拖出成独立窗口 —— 把标签拖出标签条再松手:指针在外面时,光标下方会出现提示,会话随即在新窗口打开。右键菜单里的 Open in a new window 不用拖动也能做到。
- 恢复 —— 窗口的标签列表在页面刷新后依然保留。在侧边栏删掉的会话会失去标签;已经消失的窗口留下的标签列表,14 天后会被丢弃,不会一直堆在存储里。
- 状态圆点 —— 跳动的圆点表示会话正在工作;绿色圆点表示它已完成,且之后没被打开过。
- 滚轮滚动 —— 标签溢出时,在标签条上滚滚轮可以横向滚动。
- 键盘操作 —— 在标签上按 Enter / Space 打开,按 Delete / Backspace 关闭;标签条是 tablist,标签是 tab。
- 新建会话方块 —— 标签条左边的 + 通过客户端自己的导航服务新建会话,复用还是新建的策略留在它该在的地方。
- 标题栏模式 —— 当外壳把窗口标题栏交给页面时,标签条会移进标题栏本身,紧贴窗口顶部:原生 Windows 按钮保持原生(Snap Layouts 照常可用),颜色跟随实时主题。没有这次交接时,标签条就是页面里普通的一条。
- 不挡路的标签条 —— 它从应用自己的前置控件和原生窗口菜单右边开始,除了自己的控件之外对点击透明,所以下面的侧边栏折叠按钮照样能用。

安装

这个包声明了 dsh.client(浏览器端)和 dsh.bundle.patch(加载器行),所以安装方式和任何其他 DSH 插件一样:

from a checkout, or from a published copy
dsh plugin --profile <profile> add <checkout>
after that, reload the page once (a NEW row is picked up when the page's module table is built)

手动挂载到配置档,本仓库就是在这个环境下开发的:

1. live link so edits are picked up by client HMR without reinstalling
New-Item -ItemType Junction -Path "$env:USERPROFILE\.dsh\profiles\<profile>\node_modules\dsh-session-tabs"
-Target (Resolve-Path .).Path

2. dependency of the profile: $DSH_HOME/profiles/<profile>/package.json
"dsh-session-tabs": "file:<path to this checkout>"

3. loader row: $DSH_HOME/profiles/<profile>/cordis.patch.yml
- insert:
- id: session-tabs
name: dsh-session-tabs

这一行应该放在配置档的补丁层,而不是 dsh.profile.bundles 里,因为补丁层支持热重载:改 lib/client.js 会被客户端 HMR 直接拾取,不用重启;刷新页面则能拾取其余所有改动。补丁文件不能为空——想禁用这一层就写 []。

回滚 = 删掉 insert 行,然后刷新页面;依赖和 junction 可以留着,因为没有这一行,包根本不会被挂载。

工作原理

| 文件 | 作用 |
| index.js | 宿主端:一个空的 apply(),存在的唯一目的是让加载器能挂载这个包,也让客户端模块扫描器能找到 dsh.client 声明 |
| lib/client.js | 全部功能:标签条、按窗口隔离的标签存储、手势、标题行处理、拖出交接 |
| cordis.patch.yml | bundle 安装时应用的加载器行 |

编辑时值得保留的五个决定:

1. 标签条是 shell 的 shell.overlay 座位里的一个条目。 这个座位是覆盖在所有列之上的绝对定位层,点击可穿透,所以标签条能浮在整个应用上方。框架本身通过一条 CSS 规则下移,下移量等于标签条高度,这条规则以 data-dsh-session-tabs 属性和本插件设置的 --dsh-session-tabs-h 变量为键——这样标签条正好占据预留的那条带,拖拽手柄也算在内。
2. 会话身份和选择来自官方客户端服务:Session Controller 的列表快照,加上工作区导航服务,后者掌管当前会话(selection、openSession、startSession、clearMain)。一个标签不过是这个窗口保留的一个会话 id。
3. 窗口有哪些标签属于按窗口隔离的状态:sessionStorage 存窗口自己的 id(以及一个标志,表示这个窗口是拖出标签诞生的),localStorage 存挂在那个 id 下的标签列表,键为 dsh.session-tabs.v1:<window>。正因如此,多个窗口能同时显示不同的会话,每个窗口也能在刷新后恢复自己的标签。一个窗口被会话通过 ?dshTab= 打开时,总会生成全新身份,因为 Chromium 会把 sessionStorage 克隆进脚本打开的窗口,若继承来源窗口的列表,每个标签页都会重复。

4. 把标签页撕下来时,向 shell 请求一个真实窗口。 桌面 shell 暴露了预加载动词
window.dshShell.openSessionWindow({ href, x, y, width, height }),插件在拖放点调用它;在其他地方则回退到 window.open,并带上弹窗几何参数。无论走哪条路,新窗口都会在本页自己的地址上,以 ?dshTab=<sessionId> 的形式拿到会话,启动时通过官方 openSession 读取,再用 history.replaceState 去掉参数——所以这套机制不依赖是谁创建了窗口。启动 token 不会转发;有签名 cookie 就够了。

5. 标题行与页面看不见的 chrome 共用。 窗口在那条带子里绘制自己的控件和原生菜单栏,半透明标题栏让菜单透出来。应用自己的控件在运行时测量,菜单也预留出来;随后条带从两者之后开始。条带本身是 pointer-events: none(它自己的控件会重新启用)——否则它会吞掉侧边栏折叠按钮的点击,那个按钮看起来就像坏了——标签页之后的空白区域是单独的兄弟拖拽区,因为条带必须保持 no-drag,标签页拖拽和滚轮滚动才能工作。

自己验证

1. syntax
node --check index.js && node --check lib/client.js

2. headless logic (93 checks): registration, the per-window store, restore, switching,
closing, middle click, reorder, tear-off into a new window, a refused shell,
the ?dshTab hand-off, housekeeping, the new-session square, and the caption-row geometry
node tools/smoke.mjs

3. a running GUI is serving THIS revision (needs a live host and its launcher log)
node tools/verify-live.mjs

4. the pre-publish gate: no personal data anywhere, no forbidden APIs in the payload
node tools/audit-public.mjs

tools/smoke.mjs 让浏览器那一半跑在 mock React(带持久单元格的钩子)、mock DOM(元素、矩形、ref、属性查询)和 mock 客户端上下文(插槽、locale、Session Controller、导航服务)上——不用浏览器,不用宿主,不调用模型。

tools/verify-live.mjs 读取启动器写下的最后一行 dsh web: <url>,用启动 token 认证,然后证明两件事:dsh-session-tabs 是页面收到的启动图中的一行,以及所服务的 bundle 带有本次修订的标记。它是只读的。

安全与隐私

插件载荷(index.js、lib/client.js、cordis.patch.yml、package.json)刻意平淡无奇,一旦有变,tools/audit-public.mjs 会让构建失败:

- 无网络访问 —— 没有 fetch、XMLHttpRequest、WebSocket、EventSource、sendBeacon,没有
- 动态导入。插件只与客户端自己的服务通信。
- 存储,声明且受限 —— 恰好十处 localStorage / sessionStorage 调用,全部是上文所述的每窗口状态:窗口 id、分离窗口标志、该 id 背后的标签页列表,以及一个控制标题内边距的旋钮。键里存的是 Session id、它们的打开顺序,以及应用已经显示在屏幕上的标签——不是消息内容。没有 cookie,没有 indexedDB。审计会打印每一处声明的命中及其原因,并在第一个超出声明数量的命中处失败。
- 不注入代码或 HTML —— 没有 eval,没有 new Function,没有 document.write,没有 dangerouslySetInnerHTML,没有 innerHTML 赋值。所有 UI 都走 React 元素,样式表是静态字符串,作为 标签插入一次。
- 权限 —— 不申请任何权限;插件从不碰剪贴板 API。
- 像素和数据去向 —— 哪儿也不去。条带渲染的是应用已有的文本,撕下标签页只是把一个 Session id 交给同源的窗口。插件不会主动让任何东西离开页面。
- 与宿主的接触 —— 运行中 GUI 的 HTTP 端点只由 tools/ 里的开发工具查询(只读:启动图和已提供的 bundle),而且只查你传入的 URL。

个人数据:仓库里没有用户路径、没有邮箱地址、没有 token、没有日志。tools/audit-public.mjs 会扫描载荷和整棵树来找这些东西,所以重跑是一行命令,而不是一句承诺。

兼容性

- 针对 DSH 0.2.0 客户端契约编写:Session 选择位于 uiWorkspace 服务(selection、openSession、startSession、clearMain),dsh.client.inject 列出 @deepseek-ai/dsh-client-ui-workspace,这样该模块会先于本模块加载。
- 在未暴露 uiWorkspace 的客户端上,条带仍能正确绘制,但显示没有标签页,因为没有选择可供对账。这是本插件唯一需要的接缝;如果未来的客户端把它挪走,条带会明显失败,而不是半工作。
- 标题行模式需要一个把窗口标题栏交给页面的外壳(Electron titleBarStyle: 'hidden' 配 titleBarOverlay,本账号自己的外壳就是这样)。没有它,插件会回退到页面内的普通条带,什么也不损失。
- 俄语和英语文案通过客户端自己的 locale 服务注册,所以条带会跟随应用当前的语言。
- 工具链需要 Node 22+(engines),浏览器端:DSH web 客户端跑在什么上就用什么。

限制

- 在官方 DeepSeek Harness 应用的窗口里,标签页无法撕下,这是宿主限制,不是设置。 那个宿主拒绝所有 window.open,也不给页面任何用于创建窗口的 IPC。所以标签页留在原地,并给出提示解释原因,而不是失败静默进行。撕下操作在暴露 openSessionWindow 桥接的 shell 中以及普通浏览器中均可使用。
- 标题栏行属于窗口,不属于页面:原生菜单栏对页面不可见,其宽度只能预留。如果预留宽度与你的浏览器外壳不匹配,可以覆盖(见「诊断」)。
- 同一个会话可以同时在两个窗口中打开。宿主是唯一事实来源,但在一个窗口中所做的编辑在另一个窗口中可见;存储的「当前会话」是所有窗口共享的单个单元格,因此加载时每个窗口重新打开它自己的活动标签页,任何不一致都会自行修正。
- 当标签页完全填满标签条后,窗口便无法再通过标签条拖动——这与 Chrome 的行为相同。顶部 4 px 的细条和右侧 8 px 的列始终保持可拖动。
- 标签条高 36 px(或标题栏报告的确切高度),绘制在覆盖层中,因此不会随应用滚动。
- 在标题栏模式下,标签页宽 200 px,收缩到 92 px 后标签条才开始滚动。

诊断

此插件中没有诊断对象;标签条通过客户端自己的日志记录器报告,前缀为 dsh-session-tabs:——挂载失败、shell 拒绝新窗口、window.open 失败、会话已消失、点击无法离开全局面板。这些行会出现在页面控制台(F12)和宿主的日志中。

当标签条行为异常时,有两点值得了解:

- 标题栏内边距无需改动代码即可调整。 标签条会测量应用自身的前导控件,然后为原生菜单添加预留。按优先级顺序覆盖它:在页面启动前设置 window.__DSH_TABS_LEAD__ = <px>,或设置 localStorage['dsh.session-tabs.lead'] = <px>(然后重新加载),或在 上设置 --dsh-session-tabs-lead 自定义属性;0 禁用预留,仅保留测量到的浏览器外壳。
- 崩溃的插槽条目在页面剩余生命周期内消失——这是框架自身的错误边界,不是此插件。如果标签条消失,document.querySelector('[data-slot-error]') 指向 shell.overlay,意味着该条目已被移除,只有重新加载页面才能恢复。

许可证

MIT——见 LICENSE。

По-русски, коротко

DeepSeek Harness 网页界面的插件:打开的会话变成窗口顶部标签条中的标签页——就像浏览器一样。点击切换,× / 中键 / 上下文菜单关闭(会话不会被删除),拖动改变顺序,将标签页拖出标签条会将其撕下为独立窗口。窗口的标签页列表在页面重新加载后仍然保留。

标签页状态是按窗口的:sessionStorage 存储窗口标识符,localStorage 存储该窗口的标签页列表,因此多个窗口可以同时显示不同的会话。

撕下操作通过 shell 桥接 window.dshShell.openSessionWindow({href,x,y,width,height}) 进行,而新窗口通过参数 ?dshTab=<sessionId> 拿到会话;普通浏览器里用 window.open。在 DeepSeek Harness 官方应用窗口里没法把标签页拆出去:宿主禁止所有 window.open,也不给页面创建窗口用的 IPC——标签页留在原地,并显示提示说明原因。

当外壳把标题栏(caption row)交给页面时,标签页紧贴窗口顶部,Windows 原生按钮保持原生,颜色取自主题。这条栏向右偏移,避开面板按钮和原生菜单,除了自身元素外对点击透明。

检查:npm run check、npm run smoke(93 项检查)、npm run audit;npm run verify 需要真实 GUI。MIT 许可证。
预览分享卡片长什么样 ↓thezavtrak-a11y/dsh-session-tabs
分享 · DeepSeek Harness Hub
thezavtrak-a11y/dsh-session-tabs

把打开的会话变成浏览器式标签,可切换拖动或拖出成窗

这是你的仓库?认领条目

回到顶部