feat: adapt to DSH 0.1.7-alpha.1 and yield the read-only previews

DSH 0.1.7-alpha.1 is 1299 commits past 0.1.6-alpha.2 and rewrites four
contracts this plugin was built on. The peer floor moves to
^0.1.7-alpha.1 (semver's prerelease rule means ^0.1.6-alpha.2 can never
match a 0.1.7 prerelease); 0.1.6-alpha.2 and earlier stay on v0.19.1.
Released as 0.21.0-alpha.1 (dist-tag alpha).

Hard breaks:
- dsh-settings was rewritten: register(ns, schema) is gone, a form is
  addressed by the plugin row's Loader entry id and read from the
  module's exported Config. The preferences are merged into Config and
  marked volatile — which requires DSH's own schemastery, because only
  that build wraps a volatile field in the cosmokit reference the
  loader's volatile commit walks. With the public package a settings
  write reports success and revision 1 while the effective value never
  changes.
- ui-primitives renamed its whole icon family (IconXxx14/16 ->
  IconXxxRegular/Medium): 26 imported symbols, 17 files. The failing
  mode is render-time, not load-time. Five call sites that relied on the
  old 14px default now pass size={14} explicitly.
- Session format v4 rejects source.kind === 'plugin'; the side-chat
  boundary injection now writes plugin:dsh-better-sidebar, the same kind
  DSH's own v3->v4 migration produces, so historical threads survive.
  Tool results moved to role 'tool' with top-level content/isError; all
  four parsers accept both shapes.
- The client session snapshot dropped subagentsByParent/jobsBySession
  and the on-demand subagent-catalog observation API. The Tasks page
  reads projectionsBySession and a new jobs.list route.

Yields and convergence:
- The read-only previews go to DSH's documentpreview (Office->PDF, a
  spreadsheet worker, zoom, per-directory refresh); editor.canOpen
  refuses those 26 extensions. Markdown, HTML (with its sandbox
  switches) and the editable code buffer stay.
- The host browser kind is desktop-profile-only now, so the web e2e
  lanes expect no browser entry and assert its absence.
- Link takeover claims only urlTarget links and passes the rest to the
  host, fixing a regression from the 0.1.6 round: the fallback pointed
  at a 'browser' type the plugin no longer registers, so http links in
  its own markdown did nothing.

Also fixed, found along the way:
- The file tree refreshes live (new directory watch over the plugin's
  own socket), since the plugin owns the `files` kind.
- ctx.sessions.list has no `current` field at either tag; the three
  readers were dead. They now use ctx.sidebarRight.mounted.
- package.json.files was missing lib/client-locale.js.
- Two genuinely dead call sites: sessions.openSubagent/open/
  refreshSubagents do not exist on the current baseline, so the
  topology click, the jump-back and the retry were all no-ops.
- The test harness window shim lacked addEventListener, which the 0.1.7
  primitives call at module-evaluation time; and the e2e token exchange
  needs Playwright's request stack, not Node's fetch.
This commit is contained in:
Menghuan1918
2026-09-22 17:09:08 +08:00
parent de99fd4cfb
commit 6586e3e2d3
96 changed files with 4567 additions and 2080 deletions
+52 -43
View File
@@ -3,7 +3,7 @@
> [!IMPORTANT]
> **已适配 DSH 原生侧边栏 API**(v0.19.0 起):右列就是 DSH 自己的右侧栏——插件的每个 tab 类型与 tab 体通过 `ctx.sidebarRightTabs` / `ctx.sidebarRight` 注册与打开,聊天里的文件打开统一走 `ctx.sidebarRight.openResource('dsh-resource://file/…')`,插件**不再自绘右侧面板**(旧的浮窗能力同步移除)。自绘的底部工作台与开放给其他插件的 `ctx.betterSidebar` 服务保持不变,接入方式见[插件接入指南](docs/external-plugin-guide.md)。
>
> **v0.20.0 起宿主支持下限是 DSH `0.1.6-alpha.2`**:DSH 该版本内置了自己的右侧栏**终端**与**浏览器**,因此插件**删掉了自研终端**(xterm + node-pty 整套)并把**浏览器视图让给内置**,只保留按协议分流的链接接管。0.1.5-rc.* 及更早用户请停留在 **v0.19.1**。
> **v0.21.0-alpha.1 起宿主支持下限是 DSH `0.1.7-alpha.1`**(peer 下限 `^0.1.7-alpha.1`;npm dist-tag `alpha`,`latest` 仍是 **v0.19.1**)。DSH 0.1.7 自带完整的文档预览(表格 / PDF / 图片 / Office),因此插件**把只读预览整体让给内置**(只保留 Markdown / HTML / 可编辑的代码编辑器)、**把外链接管收敛为「只认领声明了 `urlTarget` 的链接」**(按协议分流的三个外链接管设置项已删除),并**重写了设置接入面**(偏好迁到 profile 里本插件的挂载行,旧的 `settings.yaml` 段在首次启动时自动回迁);文件树同时获得**实时刷新**。**0.1.6-alpha.2 及更早的用户请停留在 v0.19.1**——注意 **0.20.0 这一版从未发布到 npm**,这些变更全部落在 v0.21.0-alpha.1。
<!-- Hero -->
<div align="center">
@@ -14,7 +14,7 @@
<a href="https://github.com/omdsh-dev/DSH-better-sidebar/stargazers"><img alt="GitHub stars" src="https://img.shields.io/github/stars/omdsh-dev/DSH-better-sidebar" /></a>
<a href="https://opensource.org/licenses/MIT"><img alt="License: MIT" src="https://img.shields.io/badge/License-MIT-yellow.svg" /></a>
<a href="https://dshfind.com/zh/plugins/omdsh-dev/DSH-better-sidebar?ref=badge"><img alt="dshfind" src="https://dshfind.com/api/badge/omdsh-dev/DSH-better-sidebar?lang=zh" /></a><br /><br />
<a href="https://www.npmjs.com/package/@deepseek-ai/dsh?activeTab=versions"><img alt="支持的 DSH 版本(v0.20.0 正式版):0.1.6-alpha.2+" src="https://img.shields.io/badge/DSH-0.1.6--alpha.2%2B-4d6bfe" /></a>
<a href="https://www.npmjs.com/package/@deepseek-ai/dsh?activeTab=versions"><img alt="支持的 DSH 版本(v0.21.0-alpha.1):0.1.7-alpha.1+" src="https://img.shields.io/badge/DSH-0.1.7--alpha.1%2B-4d6bfe" /></a>
<a href="https://github.com/topics/dsh-better-sidebar"><img alt="插件生态:GitHub topic dsh-better-sidebar" src="https://img.shields.io/badge/%E6%8F%92%E4%BB%B6%E7%94%9F%E6%80%81-topic%20dsh--better--sidebar-4d6bfe" /></a><br /><br />
<img alt="文件管理" src="https://img.shields.io/badge/-文件管理-4d6bfe" /> <img alt="编辑预览" src="https://img.shields.io/badge/-编辑预览-4d6bfe" /> <img alt="内置浏览器" src="https://img.shields.io/badge/-内置浏览器-4d6bfe" /> <img alt="文件变动" src="https://img.shields.io/badge/-文件变动-4d6bfe" /> <img alt="后台任务" src="https://img.shields.io/badge/-后台任务-4d6bfe" /> <img alt="侧边对话" src="https://img.shields.io/badge/-侧边对话-4d6bfe" /> <img alt="插件接入" src="https://img.shields.io/badge/-插件接入-4d6bfe" /><br /><br />
<b>右侧栏 + 底部面板双工作台</b>,并把 <code>ctx.betterSidebar</code> 服务开放给所有插件——<br />
@@ -45,10 +45,10 @@
## ✨ 功能一览
- **🗂️ 文件工作台**:资源管理器(懒加载目录树;软链接按目标类型展示——目录软链接可展开、失效链接标红;文件树与文件 tab 按扩展名显示图标——markdown / 图片 / PDF / 代码 / 配置 / 压缩包等各有 glyph,插件可经 `registerFileIcon` 注册自定义图标与目录图标)+ CodeMirror 编辑器;图片 / Markdown(含 Mermaid 图表,strict 安全渲染 + 点击放大;README 级内嵌 HTML——徽章墙 / `<details>` 折叠 / 表格内联标签经 DOMPurify 消毒真实渲染;浮动目录大纲一键跳转)/ HTML / PDF
- **🌐 内置浏览器 + 链接分流**:网页 tab 由 **DSH 内置**的 `ui-sidebar-browser` 提供(多开 / 后退前进刷新 / 沙箱 iframe);插件保留聊天与界面里的**外链接管**——HTTP 在侧边栏打开、HTTPS 走系统浏览器(设置页可分别调整),这是宿主自身不提供的按协议分流
- **💻 终端(DSH 内置)**:右侧栏终端由 **DSH 内置**的 `ui-sidebar-terminal` 提供(shell 选择 / 重命名 / 断线重连 / 刷新后恢复 / 主题跟随)。插件不再自带 xterm + node-pty 实现
- **📂 模型侧边栏打开(可选)**:全局设置开启后注入 `sidebar_open` 工具——模型可主动在侧边栏打开文件 / 文件夹(树以该目录为根)/ HTTP(S) 网页
- **🗂️ 文件工作台**:资源管理器(懒加载目录树,**展开的目录由宿主按目录 watch、改动后自动重列**;软链接按目标类型展示——目录软链接可展开、失效链接标红;文件树与文件 tab 按扩展名显示图标——markdown / 图片 / PDF / 代码 / 配置 / 压缩包等各有 glyph,插件可经 `registerFileIcon` 注册自定义图标与目录图标)+ **可编辑**的 CodeMirror 编辑器;Markdown(含 Mermaid 图表,strict 安全渲染 + 点击放大;README 级内嵌 HTML——徽章墙 / `<details>` 折叠 / 表格内联标签经 DOMPurify 消毒真实渲染;浮动目录大纲一键跳转)与 HTML(沙箱 iframe + 两个宿主没有的逃生门开关)仍由插件渲染
- **🌐 浏览器与文档预览(由 DSH 内置提供)**:网页 tab 是宿主自己的 `ui-sidebar-browser`(多开 / 后退前进刷新 / 沙箱 iframe,**0.1.7 起只在 desktop profile 挂载**);表格 / PDF / 图片 / Office 预览是宿主自己的 `ui-sidebar-documentpreview`(宿主侧 Office→PDF 转换、电子表格 worker 表格、图片 / PDF 缩放视口、按目录自动刷新)。插件**不再认领**这些格式,只保留宿主没有的那一半:**外链接管**——只认领有 tab 类型通过 `urlTarget` 明确声明的链接,其余一律放行给宿主(正文链接的去向由宿主用户设置 `linkOpening` 决定)
- **💻 终端(DSH 内置)**:右侧栏终端由 **DSH 内置**的 `ui-sidebar-terminal` 提供(shell 选择 / 重命名 / 断线重连 / 刷新后恢复 / 主题跟随)。插件不再自带终端实现
- **📂 模型侧边栏打开(可选)**:全局设置开启后注入 `sidebar_open` 工具——模型可主动在侧边栏打开文件 / 文件夹(树以该目录为根)/ HTTP(S) 网页(网页 tab 需要宿主提供 `browser` kind,即 desktop profile)
- **🌿 文件变动**:Git 视角(真 diff / 历史 / 暂存·提交·还原 / worktree·子仓库选择)与本轮文件视角(模型读 / 写 / 编辑实时追踪,按文件分组、按类型筛选)**双视角合一**;统一 diff 渲染(改蓝配对 + 行内字符级高亮 + 语法着色(含 mjs/cjs/mts/cts、CSS/SCSS/Less、HTML/XML/SVG/Vue、GraphQL、JSONC/JSON5)+ 上下文折叠),底部可拖拽预览面板,可一键展开为独立 diff tab(落进工作台的 diff 分栏);`.md` 操作(读 / 写 / 编辑)预览头部可切换**阅读模式**——经共享 MarkdownText 渲染 GFM 表格 / 任务列表 / 删除线 / 脚注 / 数学公式,本地图片自动改写为 `/sidebar/file` 媒体路由;含 ```mermaid 围栏时走编辑器同款懒加载 mermaid 渲染器(图可点击缩放 / 平移);**敏感内容脱敏**——凭据形态路径整文件遮罩、普通文件按内容形态遮值(api_key: / Bearer / sk- / AKIA / ghp_ / PEM 等,字段名保留),默认开启、预览面板一键开关(localStorage 记忆),仅影响显示、不改会话数据。已知边界:mermaid 无引号节点标签含被遮密钥时,图回退源码(规避:标签加引号);`.html` 操作(读 / 写 / 编辑)预览头部可切换**渲染模式**——复用编辑器同款 `/sidebar/html` 路由 iframe,相对资源(./style.css、img/x.png)同路由解析,分段读取也渲染完整文档,恒定沙箱(opaque origin + CSP 头,无逃生门);`.pdf` 操作(读 / 写 / 编辑)同样可切换**渲染模式**——复用编辑器同款 PDF 预览(媒体路由字节流 + 显式 Blob,浏览器原生查看器内嵌,附下载入口)
- **🧩 后台任务页**:subagent 拓扑 + 后台任务(退出码 / 实时输出 / 强制终止)
- **💬 侧边对话(beta)**:Codex 风格的侧边线程——继承主会话完整上下文(含进行中的回合与工具调用)独立运行,不进入主会话;线程内可持续追问,一键「保存为新会话」提升为顶层会话
@@ -58,22 +58,22 @@
- **⚡ 按需加载**:启动只拉 ~325KB 核心,编辑器 / Mermaid 图表 / 第三语言词典等重依赖用到才按需拉取([设计文档](docs/plans/2026-08-12-lazy-chunks-design.md))
- **🌏 多语言**:界面文案跟随 DSH 语言(zh / en)实时切换;安装 `@huanlin/dsh-plugin-better-locale` 后支持日语(ja)等第三语言覆盖(见下方「🌏 第三语言覆盖」)
> 🔌 **核心理念**:服务优先——内置的 8 tab + 6 viewer 与第三方插件通过同一套 `ctx.betterSidebar` API 注册,能力完全对等;官方不再内置、可由生态提供的功能,交由生态插件实现(已有 **28+ 生态插件**,见下方「🌐 插件生态」)。接入文档见「🔌 服务化扩展」与 [外部插件接入指南](./docs/external-plugin-guide.md)。
> 🔌 **核心理念**:服务优先——内置的 5 tab + 3 viewer 与第三方插件通过同一套 `ctx.betterSidebar` API 注册,能力完全对等;官方不再内置、可由生态提供的功能,交由生态插件实现(已有 **28+ 生态插件**,见下方「🌐 插件生态」)。接入文档见「🔌 服务化扩展」与 [外部插件接入指南](./docs/external-plugin-guide.md)。
## 🚀 安装
**前置**:已装好 DSH(`dsh web` 能正常运行),Node.js ≥ 20、pnpm ≥ 10。
**支持的 DSH 版本**:
<a href="https://www.npmjs.com/package/@deepseek-ai/dsh?activeTab=versions"><img alt="支持的 DSH 版本(v0.20.0 正式版):0.1.6-alpha.2+" src="https://img.shields.io/badge/DSH-0.1.6--alpha.2%2B-4d6bfe" /></a>
<a href="https://www.npmjs.com/package/@deepseek-ai/dsh?activeTab=versions"><img alt="支持的 DSH 版本(v0.21.0-alpha.1):0.1.7-alpha.1+" src="https://img.shields.io/badge/DSH-0.1.7--alpha.1%2B-4d6bfe" /></a>
> 📌 **正式版**:`v0.20.0` 起适配 DSH **0.1.6-alpha.2+**(npm dist-tag `latest`;peer 下限 `^0.1.6-alpha.2`)。**下限必须动**:semver 的预发布规则让 `^0.1.5-rc.1` 在数学上永远匹配不到任何 `0.1.6` 预发布版。仍停在 DSH 0.1.5-rc.*(含 npm `latest` 的 0.1.5-rc.2)的用户请固定安装 **`dsh-better-sidebar@0.19.1`**——0.1.6 有两个真实破坏契约,本版不写运行时兼容层;DSH 0.1.5-alpha.2 及更早同样请用旧版(`0.19.0-alpha.1` / `0.18.x` / `0.17.1`)。
> 📌 **通道与支持线**:`v0.21.0-alpha.1` 是 **alpha 通道**(npm dist-tag `alpha`),适配 DSH **0.1.7-alpha.1+**(peer 下限 `^0.1.7-alpha.1`,CI 钉 `@deepseek-ai/dsh@0.1.7-alpha.1`)。**npm `latest` 仍是 `v0.19.1`**——注意 `v0.20.0` 这一版**从未发布到 npm**,本仓库从 0.19.1 直接跳到这条 0.21 开发线。**下限必须动**:semver 的预发布规则让 `^0.1.6-alpha.2` 在数学上永远匹配不到任何 `0.1.7` 预发布版。**DSH 0.1.6-alpha.2 及更早(含 npm `latest` 的 0.1.5-rc.2)的用户请固定安装 `dsh-better-sidebar@0.19.1`**——0.1.7 的破坏面足够大(`dsh-settings` 整体重写、`ui-primitives` 图标具名导出整族改名、会话格式 v3→v4),本版不写运行时兼容层;DSH 0.1.5-alpha.2 及更早同样请用旧版(`0.19.0-alpha.1` / `0.18.x` / `0.17.1`)。
```sh
dsh plugin --profile web add dsh-better-sidebar@latest
dsh plugin --profile web add dsh-better-sidebar@alpha
```
> v0.20.0 起插件不再依赖任何需要构建脚本的包(`node-pty` 已随自研终端删除),所以安装**一步到位**,不再需要 `pnpm approve-builds` 那轮重跑。DSH 0.1.6 也自带 Web 侧的 **Plugins 页面**(`ui-plugin-manager`)与 `plugin_manager` 工具,装完后可以直接在那里启停。
> **装 `@alpha`,不要装 `@latest`**:`latest` 还停在 `v0.19.1`(只支持 DSH 0.1.5/0.1.6 线),而本版在 `alpha` 通道上。本版插件不依赖任何需要构建脚本的包(终端连同 `node-pty` 已整体交还 DSH),所以安装**一步到位**,不需要 `pnpm approve-builds` 那轮重跑。DSH 也自带 Web 侧的 **Plugins 页面**(`ui-plugin-manager`)与 `plugin_manager` 工具,装完后可以直接在那里启停。
装完**硬刷新浏览器**(Cmd/Ctrl+Shift+R)即可看到侧边栏(DSH 对 client 改动热加载,无需重启;仅 host 半更新时需要重启)。
@@ -81,7 +81,7 @@ dsh plugin --profile web add dsh-better-sidebar@latest
```text
帮我安装 dsh-better-sidebar 插件(DSH 侧边栏工作台),步骤:
1. 执行 dsh plugin --profile web add dsh-better-sidebar@latest(v0.20.0 起一步到位,无需构建脚本放行)
1. 执行 dsh plugin --profile web add dsh-better-sidebar@alpha(注意是 alpha 通道;latest 停在只支持 DSH 0.1.5/0.1.6 的 0.19.1,装它没用)
2. 完成后提醒我硬刷新浏览器(Cmd/Ctrl+Shift+R)
遇到报错先查 https://github.com/omdsh-dev/DSH-better-sidebar README 的常见问题表。
```
@@ -92,7 +92,7 @@ dsh plugin --profile web add dsh-better-sidebar@latest
<summary><b>更新</b></summary>
```sh
dsh plugin --profile web add dsh-better-sidebar@latest
dsh plugin --profile web add dsh-better-sidebar@alpha
```
也可把 `~/.dsh/profiles/web/package.json` 里的版本号改高后 `pnpm install`。改完**硬刷新浏览器**(Cmd/Ctrl+Shift+R)即可(client 改动无需重启 DSH)。
@@ -104,12 +104,13 @@ dsh plugin --profile web add dsh-better-sidebar@latest
| 现象 | 原因与解决 |
|---|---|
| 报 `Ignored build scripts` | pnpm 11 拦截了某个传递依赖的构建脚本。在 profile 目录(`~/.dsh/profiles/web`)跑 `pnpm approve-builds` 按提示放行——v0.20.0 起本插件自身不再有构建脚本依赖。 |
| 报 `Ignored build scripts` | pnpm 11 拦截了某个传递依赖的构建脚本。在 profile 目录(`~/.dsh/profiles/web`)跑 `pnpm approve-builds` 按提示放行——本插件自身已无构建脚本依赖(终端删除后 `node-pty` 不在依赖里)。 |
| 报 `minimum release age` / 版本不足 24h | 装的版本发布不足 24 小时。等 24h 或重跑一次(pnpm 会自动补 `minimumReleaseAgeExclude`)。 |
| 报「找不到 profile 目录」 | 先跑一次 `dsh web`,让它初始化 `~/.dsh/profiles/web`。 |
| 页面出现**两个侧边栏** | 双挂载。旧的手动挂载行:`~/.dsh/profiles/web/cordis.patch.yml` 还留着 `- insert: ... better-sidebar ...`,删掉那段(同 id 重复挂载 loader 会直接报 `duplicate loader entry id`)。聚合包(如 `@linxin666/dsh-web-ui-all`)以**不同 id** 挂载本包时,0.13.x 起插件自身 bundle patch 会自动退让(检测到已有启用中的同包名挂载就不挂自己),无需手动处理;若仍双挂载,先确认聚合包的 bundle 顺序在 `dsh-better-sidebar` 之前。 |
| 终端无法使用 / 提示 shell 启动失败 | 终端与 `node-pty` 现在都由 **DSH 自身的 `ui-sidebar-terminal`** 提供(本插件 v0.20.0 起不再自带)。遇到问题请查 DSH 侧文档;若报错提到构建脚本,见上一行。 |
| 提示 `dsh: command not found` | 先安装 DSH;或直接用 `npx -y --package @deepseek-ai/dsh dsh plugin --profile web add dsh-better-sidebar@latest`。 |
| 升级后设置页的值去哪了 | DSH 0.1.7 删除了插件可注册的设置命名空间:偏好现在写在 profile 里本插件的**挂载行**上(默认 entry id `better-sidebar`),不再是 `~/.dsh/settings.yaml`。插件会在首次启动时把旧 `settings.yaml`(已被宿主改名为 `settings.yaml.imported`)里 `dsh-better-sidebar` 段一次性回迁,只迁移当前 schema 仍声明的字段、且只在该行还没有用户值时执行,不会覆盖升级后新设的值。 |
| 终端无法使用 / 提示 shell 启动失败 | 终端由 **DSH 自身的 `ui-sidebar-terminal`** 提供(本插件不再自带终端与 `node-pty`,也没有终端相关设置项)。遇到问题请查 DSH 侧文档;若报错提到构建脚本,见上一行。 |
| 提示 `dsh: command not found` | 先安装 DSH;或直接用 `npx -y --package @deepseek-ai/dsh dsh plugin --profile web add dsh-better-sidebar@alpha`。 |
</details>
@@ -122,20 +123,17 @@ dsh plugin --profile web add dsh-better-sidebar@latest
1. git clone https://github.com/omdsh-dev/DSH-better-sidebar.git ~/Code/DSH-better-sidebar
cd ~/Code/DSH-better-sidebar && pnpm install && pnpm build
2. ~/.dsh/profiles/web/package.json 的 dependencies 写 "dsh-better-sidebar": "link:<克隆目录绝对路径>"
3. ~/.dsh/profiles/web/cordis.patch.yml 追加挂载行(需要指定终端 shell 时,在行内加 `config.shell`;`config.shellArgs` 可带参启动,非空时替换默认的 `-l`。不填则自动解析 `$SHELL` / 登录 shell / powershell.exe):
3. ~/.dsh/profiles/web/cordis.patch.yml 追加挂载行(这一行的 `config` 就是本插件的设置表单:部署限额 `readLimit` / `mediaLimit` / `uploadLimit` / `listLimit` 加用户偏好字段,设置页写的就是它;不写则全部用 schema 默认值):
- insert:
- id: better-sidebar
name: 'dsh-better-sidebar'
config:
shell: /bin/zsh
shellArgs:
- --noprofile
- --no-rc
readLimit: 524288
4. 在 ~/.dsh/profiles/web 执行 pnpm install
5. 硬刷新浏览器(Cmd/Ctrl+Shift+R)即可看到效果(client 改动无需重启 DSH;host 半改动才需重启)
```
更新:`git pull && pnpm install && pnpm build` → 硬刷新浏览器即可(client 改动热加载生效,无需重启 DSH;host 半改动才需重启)。切回 npm 通道时,把依赖改回 `"dsh-better-sidebar": "^0.16.1"` 再 `pnpm install`。
更新:`git pull && pnpm install && pnpm build` → 硬刷新浏览器即可(client 改动热加载生效,无需重启 DSH;host 半改动才需重启)。切回 npm 通道时,把依赖改回 npm 上的对应版本(稳定线 `"^0.19.1"`;本 alpha 线 `"^0.21.0-alpha.1"`)再 `pnpm install`。
</details>
@@ -162,16 +160,16 @@ dsh registry enable dsh-external/dsh-better-sidebar
| | |
|---|---|
| **🗂️ 文件工作台:资源管理器**<br/><sub>支持两种格式的资源管理器:内嵌在文件预览中 / 独立显示文件树。懒加载目录树、软链接按目标类型展示(目录软链接可展开、失效链接标红)、全局文件名搜索、上传文件/文件夹与拖放上传、右键菜单(在新 Tab 打开 / 在侧边打开 / 复制路径)、悬浮 `@文件` 一键引用进输入框。</sub><br/><div align="center"><img width="420" alt="文件资源管理器" src="https://github.com/user-attachments/assets/a410bfd2-a8ba-43e6-873e-22417756e94d" /></div> | **📝 Markdown · 图片 · PDF 内联预览**<br/><sub>Markdown 预览支持 **Mermaid 图表**(`securityLevel: 'strict'` 安全渲染 + 二次清洗;点击图表弹窗放大、滚轮缩放、拖拽平移)、**README 级内嵌 HTML**(徽章墙 `<div align=center>`、`<details>` 折叠块内嵌 markdown、表格单元格内联标签——DOMPurify 白名单消毒真实渲染,`<script>` 等活性内容剥除,本地图片经会话媒体路由重写)与**浮动目录大纲**(≥3 标题出现,点击平滑跳转、自动展开折叠块);图片 / PDF 走媒体路由内联展示;Office 三件套由生态插件补齐。</sub><br/><div align="center"><img width="420" alt="Markdown + Mermaid 预览" src="https://github.com/user-attachments/assets/fe0e5182-55bb-45cc-b98b-a2877c2bdd38" /></div> |
| **🖥️ CodeMirror 代码编辑器**<br/><div align="center"><img width="420" alt="CodeMirror 代码编辑器" src="https://github.com/user-attachments/assets/b44b488e-568c-4ee0-b96c-e9c906598a77" /></div> | **🖼️ 图片内联预览**<br/><div align="center"><img width="420" alt="图片内联预览" src="https://github.com/user-attachments/assets/f9a58c30-5b7a-48b5-9e22-37d7e071f593" /></div> |
| **💻 终端(由 DSH 内置提供)**<br/><sub>v0.20.0 起右侧栏终端由 DSH 自己的 `ui-sidebar-terminal` 提供:shell 选择、双击重命名、断线重连、刷新后恢复、主题与对比度跟随。插件不再自带 xterm + node-pty 实现。<br/><br/>⚠️ **模型侧提示**:插件原来自带的 8 个 `terminal_*` 工具(默认关)是模型唯一的**跨调用持久**终端;上游等价物 `@deepseek-ai/dsh-tool-terminal` 未被任何内置 bundle 默认挂载,若你需要该能力,请在 profile 的 `cordis.patch.yml` 里自行插入一行 `tool-terminal`。</sub><br/><div align="center"><img width="420" alt="真实终端" src="https://github.com/user-attachments/assets/0dad6ad3-ff3f-4b5a-86d2-f832ce65323e" /></div> | **🌿 文件变动:Git 视角 + 本轮文件**<br/><sub>双视角合一:**Git 视角**保留完整源代码管理(暂存 / 取消暂存 / 提交(`Ctrl+Enter`)/ 还原、历史、worktree 与子仓库选择);**本轮文件视角**实时折叠会话事件日志,记录模型读 / 写 / 编辑的每个文件(按文件分组、按类型筛选、操作数角标)。点击任意改动在底部**可拖拽预览面板**查看统一 diff——删红 / 增绿 / 改蓝配对 + 行内字符级高亮 + 语法着色 + 上下文折叠——也可一键展开为 VSCode 式独立 diff tab(同一渲染栈)。</sub><br/><div align="center"><img width="420" alt="文件变动" src="https://github.com/user-attachments/assets/e7fc1220-305f-4bca-8583-e77ab4f4fa78" /></div> |
| **🌐 浏览器(页面由 DSH 内置提供)**<br/><sub>网页 tab 由 DSH 自己的 `ui-sidebar-browser` 提供(多开 / 后退前进刷新 / 地址栏 / 沙箱 iframe)。插件保留宿主没有的那一半:聊天与界面里的**外链接管**(按协议分流,HTTP 进侧边栏、HTTPS 交系统浏览器,可分别配置;Ctrl/Cmd 点击始终放行)。</sub><br/><div align="center"><img width="420" alt="内嵌浏览器" src="https://github.com/user-attachments/assets/9bc6b65a-64fc-4942-a685-76e391e55606" /></div> | **🧩 任务页:子代理拓扑 + 后台任务**<br/><sub>子代理树实时拓扑(运行状态、批量实时预览)+ 后台任务清单(退出码 / 实时输出 / 强制终止);新子代理 / 新任务可自动激活任务页,宽屏同时展开侧边栏,窄屏不强制展开全屏抽屉(可关)。</sub><br/><div align="center"><img width="420" alt="任务页:子代理拓扑" src="https://github.com/user-attachments/assets/dcd8ed2f-59fa-405b-937b-2d250f5034dd" /></div> |
| **💬 侧边对话(beta)**<br/><sub>Codex 风格侧边线程:**每个对话一个独立 Tab**;线程继承主会话完整上下文(含进行中回合,以 interrupted 诚实冻结)独立运行,不污染主会话;可持续追问、重启冷恢复;一键「保存为新会话」提升为顶层会话。</sub><br/><div align="center"><img width="420" alt="侧边对话(beta)" src="https://github.com/user-attachments/assets/3a338c36-f5de-4000-95f3-4b1cd04f60fc" /></div> | **🖥️ DSH 原生右侧栏 + 插件底部工作台**<br/><sub>右列是 DSH 自己的右侧栏:插件把每个 tab 类型注册成原生 tab(含接管内置「文件」页与文件预览),聊天里的文件点击直接落到原生栏;插件自有底部面板可与其同时展开,拖 Tab 到分栏边缘**拆分**、拖到中间**合并**,高度拖上缘调节;开合按钮在会话头右侧。</sub><br/><div align="center"><img width="420" alt="双工作台(右侧栏 + 底部面板)" src="https://github.com/user-attachments/assets/dfdb875e-a1a8-4d4b-8340-353736b1708f" /></div> |
| **⚙️ 声明式设置**<br/><sub>设置页「侧边卡片」分区:每个 tab / 预览器一张小卡片,独立开关(高亮启用态 + 品牌开关滑块);二级设置经卡片底部「功能设置」条弹窗(开关 / 文本 / 数字 / 下拉);插件自有设置持久化在 `pluginSettings`。</sub><br/><div align="center"><img width="420" alt="声明式设置:侧边卡片" src="https://github.com/user-attachments/assets/0800ca64-621e-48da-b7df-aecfddc3ec29" /></div> | **📱 移动端**<br/><sub>窄屏(<768px)自动切换为全宽抽屉:底栏 tab 一次性并入右侧栏,触屏拖拽可调。</sub><br/><div align="center"><img width="360" alt="移动端全宽抽屉" src="https://github.com/user-attachments/assets/a82ba78a-f4cf-4d85-80e8-050a05beb144" /></div> |
| **🗂️ 文件工作台:资源管理器**<br/><sub>支持两种格式的资源管理器:内嵌在文件预览中 / 独立显示文件树。懒加载目录树、**展开的目录由宿主按目录 watch、改动后自动重列**、软链接按目标类型展示(目录软链接可展开、失效链接标红)、全局文件名搜索、上传文件/文件夹与拖放上传、右键菜单(在新 Tab 打开 / 在侧边打开 / 复制路径)、悬浮 `@文件` 一键引用进输入框。</sub><br/><div align="center"><img width="420" alt="文件资源管理器" src="https://github.com/user-attachments/assets/a410bfd2-a8ba-43e6-873e-22417756e94d" /></div> | **📝 Markdown · HTML 内联预览**<br/><sub>Markdown 预览支持 **Mermaid 图表**(`securityLevel: 'strict'` 安全渲染 + 二次清洗;点击图表弹窗放大、滚轮缩放、拖拽平移)、**README 级内嵌 HTML**(徽章墙 `<div align=center>`、`<details>` 折叠块内嵌 markdown、表格单元格内联标签——DOMPurify 白名单消毒真实渲染,`<script>` 等活性内容剥除,本地图片经会话媒体路由重写)与**浮动目录大纲**(≥3 标题出现,点击平滑跳转、自动展开折叠块);HTML 走插件自带的**沙箱预览**,并带 `htmlViewerNoSandbox` / `htmlViewerDefaultUnsafe` 两个宿主没有的逃生门开关。**图片 / PDF / 表格 / Office 不再是插件能力**——那些格式由 DSH 自己的文档预览渲染。</sub><br/><div align="center"><img width="420" alt="Markdown + Mermaid 预览" src="https://github.com/user-attachments/assets/fe0e5182-55bb-45cc-b98b-a2877c2bdd38" /></div> |
| **🖥️ CodeMirror 代码编辑器**<br/><sub>**可编辑**的文本 / 代码编辑器(保存、语法高亮、预览切换)——宿主自己的文档预览是**只读**的,这是插件保留 catch-all viewer 的理由。</sub><br/><div align="center"><img width="420" alt="CodeMirror 代码编辑器" src="https://github.com/user-attachments/assets/b44b488e-568c-4ee0-b96c-e9c906598a77" /></div> | **🖼️ 图片 / PDF / 表格 / Office 预览(由 DSH 内置提供)**<br/><sub>这些只读格式由 DSH 自己的 `ui-sidebar-documentpreview` 渲染:宿主侧 Office→PDF 转换、电子表格 worker 表格、图片 / PDF 缩放视口,并**按目录自动刷新**。插件已删除自己的 image / pdf / 下载兜底 viewer,也不再认领这些扩展名。</sub><br/><div align="center"><img width="420" alt="图片内联预览" src="https://github.com/user-attachments/assets/f9a58c30-5b7a-48b5-9e22-37d7e071f593" /></div> |
| **💻 终端(由 DSH 内置提供)**<br/><sub>右侧栏终端由 DSH 自己的 `ui-sidebar-terminal` 提供:shell 选择、双击重命名、断线重连、刷新后恢复、主题与对比度跟随。插件不再自带终端实现。<br/><br/>⚠️ **模型侧提示**:插件原来自带的 8 个 `terminal_*` 工具(默认关)是模型唯一的**跨调用持久**终端;上游等价物 `@deepseek-ai/dsh-tool-terminal` 未被任何内置 bundle 默认挂载,若你需要该能力,请在 profile 的 `cordis.patch.yml` 里自行插入一行 `tool-terminal`。</sub><br/><div align="center"><img width="420" alt="真实终端" src="https://github.com/user-attachments/assets/0dad6ad3-ff3f-4b5a-86d2-f832ce65323e" /></div> | **🌿 文件变动:Git 视角 + 本轮文件**<br/><sub>双视角合一:**Git 视角**保留完整源代码管理(暂存 / 取消暂存 / 提交(`Ctrl+Enter`)/ 还原、历史、worktree 与子仓库选择);**本轮文件视角**实时折叠会话事件日志,记录模型读 / 写 / 编辑的每个文件(按文件分组、按类型筛选、操作数角标)。点击任意改动在底部**可拖拽预览面板**查看统一 diff——删红 / 增绿 / 改蓝配对 + 行内字符级高亮 + 语法着色 + 上下文折叠——也可一键展开为 VSCode 式独立 diff tab(同一渲染栈)。</sub><br/><div align="center"><img width="420" alt="文件变动" src="https://github.com/user-attachments/assets/e7fc1220-305f-4bca-8583-e77ab4f4fa78" /></div> |
| **🌐 外链接管(浏览器视图由 DSH 提供)**<br/><sub>网页 tab 是 DSH 自己的 `ui-sidebar-browser`(多开 / 后退前进刷新 / 地址栏 / 沙箱 iframe),**0.1.7 起只在 desktop profile 挂载**——Web profile 里没有这个 kind。插件保留宿主没有的那一半:**只认领有 tab 类型通过 `urlTarget` 明确声明的链接**(Ctrl/Cmd 点击始终放行),**其余一律放行给宿主**(正文链接的去向由宿主的用户设置 `linkOpening` 决定);按协议分流的三个外链接管设置项已删除,认领成功但目标类型此刻不可用时兜底到 `window.open`。</sub><br/><div align="center"><img width="420" alt="内嵌浏览器" src="https://github.com/user-attachments/assets/9bc6b65a-64fc-4942-a685-76e391e55606" /></div> | **🧩 任务页:子代理拓扑 + 后台任务**<br/><sub>子代理树实时拓扑(运行状态、批量实时预览)+ 后台任务清单(退出码 / 实时输出 / 强制终止);新子代理 / 新任务可自动激活任务页,宽屏同时展开侧边栏,窄屏不强制展开全屏抽屉(可关)。</sub><br/><div align="center"><img width="420" alt="任务页:子代理拓扑" src="https://github.com/user-attachments/assets/dcd8ed2f-59fa-405b-937b-2d250f5034dd" /></div> |
| **💬 侧边对话(beta)**<br/><sub>Codex 风格侧边线程:**每个对话一个独立 Tab**;线程继承主会话完整上下文(含进行中回合,以 interrupted 诚实冻结)独立运行,不污染主会话;可持续追问、重启冷恢复;一键「保存为新会话」提升为顶层会话。</sub><br/><div align="center"><img width="420" alt="侧边对话(beta)" src="https://github.com/user-attachments/assets/3a338c36-f5de-4000-95f3-4b1cd04f60fc" /></div> | **🖥️ DSH 原生右侧栏 + 插件底部工作台**<br/><sub>右列是 DSH 自己的右侧栏:插件把每个 tab 类型注册成原生 tab(含接管内置「文件」页),聊天里的文件点击直接落到原生栏——**宿主自己的文档预览已覆盖的格式由宿主渲染**,插件只认领 Markdown / HTML / 可编辑代码;插件自有底部面板可与其同时展开,拖 Tab 到分栏边缘**拆分**、拖到中间**合并**,高度拖上缘调节;开合按钮在会话头右侧。</sub><br/><div align="center"><img width="420" alt="双工作台(右侧栏 + 底部面板)" src="https://github.com/user-attachments/assets/dfdb875e-a1a8-4d4b-8340-353736b1708f" /></div> |
| **⚙️ 声明式设置**<br/><sub>设置页「侧边卡片」分区:每个 tab / 预览器一张小卡片,独立开关(高亮启用态 + 品牌开关滑块);二级设置经卡片底部「功能设置」条弹窗(开关 / 文本 / 数字 / 下拉);插件自有设置持久化在 `pluginSettings`,整份偏好则写在 profile 里本插件的**挂载行**上(DSH 0.1.7 起设置按 Loader entry id 寻址)。</sub><br/><div align="center"><img width="420" alt="声明式设置:侧边卡片" src="https://github.com/user-attachments/assets/0800ca64-621e-48da-b7df-aecfddc3ec29" /></div> | **📱 移动端**<br/><sub>窄屏(<768px)自动切换为全宽抽屉:底栏 tab 一次性并入右侧栏,触屏拖拽可调。</sub><br/><div align="center"><img width="360" alt="移动端全宽抽屉" src="https://github.com/user-attachments/assets/a82ba78a-f4cf-4d85-80e8-050a05beb144" /></div> |
## 🌐 插件生态
`ctx.betterSidebar` 服务向所有插件开放两个扩展点:**`registerTab`(注册侧边栏页面)** 与 **`registerFileViewer`(注册文件预览器)**。内置的 8 tab + 6 viewer 与第三方插件走同一套 API,能力完全对等。
`ctx.betterSidebar` 服务向所有插件开放两个扩展点:**`registerTab`(注册侧边栏页面)** 与 **`registerFileViewer`(注册文件预览器)**。内置的 5 tab + 3 viewer 与第三方插件走同一套 API,能力完全对等。
```ts
import type {} from 'dsh-better-sidebar' // 触发 ctx.betterSidebar 类型合并
@@ -261,11 +259,23 @@ GitHub topic [`dsh-better-sidebar`](https://github.com/topics/dsh-better-sidebar
## 🆕 最近更新
**支持的 DSH 版本**:<a href="https://www.npmjs.com/package/@deepseek-ai/dsh?activeTab=versions"><img alt="支持的 DSH 版本(v0.20.0 正式版):0.1.6-alpha.2+" src="https://img.shields.io/badge/DSH-0.1.6--alpha.2%2B-4d6bfe" /></a> · 完整发布历史见 [Releases](https://github.com/omdsh-dev/DSH-better-sidebar/releases)
**支持的 DSH 版本**:<a href="https://www.npmjs.com/package/@deepseek-ai/dsh?activeTab=versions"><img alt="支持的 DSH 版本(v0.21.0-alpha.1):0.1.7-alpha.1+" src="https://img.shields.io/badge/DSH-0.1.7--alpha.1%2B-4d6bfe" /></a> · 完整发布历史见 [Releases](https://github.com/omdsh-dev/DSH-better-sidebar/releases)
### v0.20.0
### v0.21.0-alpha.1
> 📌 **正式版**(npm `latest`,无 prerelease 后缀):仅支持 **DSH 0.1.6-alpha.2+**(peer 下限 `^0.1.6-alpha.2`,CI 钉 `@deepseek-ai/dsh@0.1.6-alpha.2`)。**这是一次破坏性变更版**:0.1.5-rc.* 用户请固定 `dsh-better-sidebar@0.19.1`。适配记录见 [docs/plans/2026-09-21-dsh-0.1.6-alpha.2-adaptation.md](docs/plans/2026-09-21-dsh-0.1.6-alpha.2-adaptation.md)。
> 🧪 **alpha 通道**(npm dist-tag `alpha`,安装 `dsh-better-sidebar@alpha`;npm `latest` 仍是 **v0.19.1**):仅支持 **DSH 0.1.7-alpha.1+**(peer 下限 `^0.1.7-alpha.1`,CI 钉 `@deepseek-ai/dsh@0.1.7-alpha.1`)。**DSH 0.1.6-alpha.2 及更早的用户请固定在 v0.19.1**——0.1.7 动了设置服务、图标具名导出与会话格式三处硬契约,本版不写运行时兼容层。⚠️ **上一版 v0.20.0 从未发布到 npm**:它的终端 / 浏览器让出也一并落在本版,npm 上从 0.19.1 直接到本版。
- 🗂️ **只读文件预览整体让给 DSH 的文档预览**:DSH 0.1.7 的 `ui-sidebar-documentpreview` 自带表格 / PDF / 图片 / Office 渲染(宿主侧 Office→PDF 转换、电子表格 worker 表格、图片 / PDF 缩放、按目录自动刷新),所以插件删掉了自己的 `image` / `pdf` / `binary-download` 三个 viewer,并在 `editor.canOpen` 里**拒绝认领**这些扩展名——`xlsx xls xlsb xlt xltx xltm ods ots fods csv tsv pdf png jpg jpeg gif webp svg bmp ico avif doc docx dot dotx ppt pptx`——把文件地址交回宿主。**插件仍保留三件宿主没有的**:Markdown(自带渲染器)、HTML(自带沙箱预览 + `htmlViewerNoSandbox` / `htmlViewerDefaultUnsafe` 两个安全开关)、以及**可编辑**的文本 / 代码编辑器(内置那几个是只读预览);未知二进制(`.zip` / `.wasm`)仍走代码编辑器判 binary 后的下载面板,功能不回归。
- 🔗 **外链接管收敛**:删掉按协议分流的三个外链接管设置项(20 份词典的相关词条一并删除)。现在插件**只认领有 tab 类型通过 `urlTarget` 明确声明认领的链接**,其余一律放行、由宿主决定(DSH 0.1.7 新增用户设置 `linkOpening`,决定正文链接进侧栏还是新标签页);**一个都没认领到时不阻止默认行为**;认领成功但目标类型在打开那一刻已不可用(插件卸载 / 被关)时兜底 `window.open(url, '_blank', 'noopener,noreferrer')`——顺手修掉了上一版留下的真实回归:插件自绘 markdown(侧边对话转录 / 编辑器预览 / diff 面板)里的 http 链接点了没反应。另外宿主的 `browser` kind **在 Web profile 已不再挂载**(0.1.7 只在 desktop profile 挂载它)。
- ⚙️ **设置接入面重写 + 用户偏好的自动回迁**:DSH 0.1.7 删除了插件可注册的设置命名空间,改为**按插件 Loader 行的 entry id 找表单**(`SettingsForms`:只剩 `describe` / `update` / `replace` / `mutate` / `configure`)。插件偏好因此落在 **profile 的 cordis patch 文档**里(即本插件的挂载行),不再是 `~/.dsh/settings.yaml`;schema 来自插件模块导出的 `Config`(本版把用户偏好并进 `Config`,并给每个偏好字段标 `meta.volatile = true`——**这一个标记就是「改设置实时生效、不重挂插件」的全部机制**)。**用户设置不会丢**:插件首次启动时会把旧 `settings.yaml` / `settings.yaml.imported` 里的 `dsh-better-sidebar` 段一次性回迁(只在该行还没有任何用户值时执行,且只迁移当前 schema 仍声明的字段)。entry id 是**运行时自发现**的(本包默认 `better-sidebar`,聚合包挂载时会是别的 id),不硬编码。
- 🔄 **文件树实时刷新**:插件接管了内置「文件」页,宿主自己的按目录 watch 覆盖不到它——本版新增 `/sidebar/ws/fs-watch`:客户端上报**已展开**的目录,宿主按目录 `fs.watch`(150ms 去抖、每连接 64 个句柄上限、路径仍走 `fs.tree` 同一道 workspace fence),改动后只重列那一层、折叠即退订。此前文件树会一直陈旧到手动刷新。
- 🐛 **会话跟随修好了**:插件此前读的是一个**不存在的 `SessionListState.current` 字段**(插件的类型镜像自己造了它,编译期一直放行),导致「按会话持久化」实际没绑上、窄屏 park 门控恒假。现在改用 DSH 0.1.7 的 `ctx.sidebarRight.mounted`(只在该列真正换成另一个会话时才变化)。
- 🖥️ **模型侧代价不变**:插件原有的 8 个 `terminal_*` 工具(默认关)已在上一版删除,上游等价物 `@deepseek-ai/dsh-tool-terminal` **仍未被任何 shipped bundle 默认挂载**,需要持久终端时请在 profile 的 `cordis.patch.yml` 里自行插入一行 `tool-terminal`(否则模型只有一次性 `bash` / `pwsh`)。
- 📐 **基线**:`@deepseek-ai/dsh-*` 全部钉 `0.1.7-alpha.1`,`@deepseek-ai/cordis` peer 下限 `^4.0.3`;`ui-primitives` 图标具名导出整族改名(`Icon<Name><14|16>` → `Icon<Name>Regular` / `Medium`,26 个具名导入随之适配);会话格式 v3→v4(sidechat 边界注入改用 `plugin:dsh-better-sidebar`,tool 结果消息改 `role: 'tool'` 顶层形状,解析器同时接受新旧两种形状以兼容历史日志)。
### v0.20.0(开发线,**从未发布**)
> 🚫 **这一版没有发布到 npm**(npm 上 `latest` 仍是 v0.19.1):它原本是 0.1.6-alpha.2 线的正式版,开发完成后被 0.21 线直接取代,所以下面这些变更实际随 **v0.21.0-alpha.1** 一起发布。原本的定位:仅支持 **DSH 0.1.6-alpha.2+**(peer 下限 `^0.1.6-alpha.2`,CI 钉 `@deepseek-ai/dsh@0.1.6-alpha.2`)。**这是一次破坏性变更版**:0.1.5-rc.* 用户请固定 `dsh-better-sidebar@0.19.1`。适配记录见 [docs/plans/2026-09-21-dsh-0.1.6-alpha.2-adaptation.md](docs/plans/2026-09-21-dsh-0.1.6-alpha.2-adaptation.md)。
- 🖥️ **终端交给 DSH 内置**:DSH 0.1.6 自带右列终端(`ui-sidebar-terminal`),所以插件删掉了整套自研终端——`pty-manager` / `agent-pty` / `pty-deps` / 8 个 `terminal_*` 工具 / xterm 视图与字体链接 / 跨会话固定终端,以及 `node-pty` 依赖、它的 `allowBuilds` 放行与安装脚本的 `-Repair` 模式。**注意**:模型因而失去跨调用持久的终端(只剩一次性 `bash` / `pwsh`);上游 `@deepseek-ai/dsh-tool-terminal` 未被内置 bundle 挂载,需要时请自行在 profile 里启用。
- 🌐 **浏览器视图让给内置**:插件删掉 `BrowserView` / 沙箱状态条 / 嵌入性探测(含宿主 `browser.probe` 路由)与两个只配置自家 iframe 的设置项;**保留**聊天与界面的外链接管(按协议分流是宿主没有的能力),目标改为 DSH 内置的 `browser` tab 类型。
@@ -608,7 +618,7 @@ GitHub topic [`dsh-better-sidebar`](https://github.com/topics/dsh-better-sidebar
## 🔌 服务化扩展
从 v0.4.0 起暴露 `ctx.betterSidebar` 服务,其他插件可注册侧边栏页面与文件预览器(内置 8 tab + 6 viewer 亦通过同一服务注册)。v0.12.1 补齐基座能力(完整类型导出、能力探测、状态订阅、tab 角标、生命周期回调、定向打开、插件自有设置等)。v0.19.0 起新增文件图标注册:`registerFileIcon` 按扩展名(或保留的 `'folder'` / `'folder-open'` 目录扩展名、`exts: []` 全局默认)替换文件树与文件 tab 的图标,彩色 ReactNode 亦可——内置消费、注册即生效,无需自己接线。
从 v0.4.0 起暴露 `ctx.betterSidebar` 服务,其他插件可注册侧边栏页面与文件预览器(内置 5 tab + 3 viewer 亦通过同一服务注册)。v0.12.1 补齐基座能力(完整类型导出、能力探测、状态订阅、tab 角标、生命周期回调、定向打开、插件自有设置等)。v0.19.0 起新增文件图标注册:`registerFileIcon` 按扩展名(或保留的 `'folder'` / `'folder-open'` 目录扩展名、`exts: []` 全局默认)替换文件树与文件 tab 的图标,彩色 ReactNode 亦可——内置消费、注册即生效,无需自己接线。
完整接入文档(全字段、匹配算法、HMR 陷阱、声明式设置、版本探测、原生栏承载面与皮肤契约):**[`docs/external-plugin-guide.md`](./docs/external-plugin-guide.md)**;仓库开发规则(硬约束 / CI / 发版)见 [`AGENTS.md`](./AGENTS.md)。
@@ -621,7 +631,7 @@ GitHub topic [`dsh-better-sidebar`](https://github.com/topics/dsh-better-sidebar
## 🛠️ 开发与构建
```sh
pnpm install # @deepseek-ai/* devDependencies 已发布(基线 0.1.2-rc.1,next dist-tag),直接解析、无需令牌
pnpm install # @deepseek-ai/* devDependencies 已发布(基线 0.1.7-alpha.1,alpha dist-tag),直接解析、无需令牌
pnpm typecheck # tsc --noEmit
pnpm lint # eslint .(flat config:js + typescript-eslint + react-hooks recommended)
pnpm build # → lib/index.js + lib/invariant.js + lib/client.js + lib/client-registry.js + lib/types
@@ -639,26 +649,25 @@ make clean # 清理 lib/、*.tgz、playwright-report/、test-results/
`pnpm check:consumer-types`:对外类型声明面守卫——以浏览器-only 消费者(无 `@types/node`、`skipLibCheck: false`)的视角对构建出的 `lib/types` 做类型检查,需先 `pnpm build`。
**架构**:单 npm 包、host/client 双半结构——host(`src/index.ts`):`/sidebar/api/*` JSON API、`/sidebar/file` 媒体路由、`/sidebar/html` 预览路由、`/sidebar/ws/terminal` WebSocket(fs / git / pty / 预览,全部会话级 + 信任围栏);client(`src/client/index.tsx`):portal 侧边栏 + 各视图 + 拦截;状态按会话持久化 localStorage。插件按 DSH 官方规范组织(无 default 导出、双 client bundle),运行期不依赖 npm / checkout(`@deepseek-ai/*` 由 web profile 提供)。
**架构**:单 npm 包、host/client 双半结构——host(`src/index.ts`):`/sidebar/api/*` JSON API、`/sidebar/file` 媒体路由、`/sidebar/html` 预览路由、`/sidebar/upload` 上传路由,以及两条 WebSocket(`/sidebar/ws/agent-opens` 模型打开推送、`/sidebar/ws/fs-watch` 文件树目录 watch;fs / git / 预览全部会话级 + 信任围栏);client(`src/client/index.tsx`):portal 侧边栏 + 各视图 + 链接接管;状态按会话持久化 localStorage。插件按 DSH 官方规范组织(无 default 导出、双 client bundle),运行期不依赖 npm / checkout(`@deepseek-ai/*` 由 web profile 提供)。
## 🔐 安全
- 路由受 Host 头信任围栏保护(与 `/api` 一致);`fs.write` 原子写入;媒体/预览路由仅限会话 cwd 内文件;git 只调 CLI、绝不设置身份
- HTML 预览与浏览器 tab 的内容在**不透明源沙箱 iframe** 中渲染(无 `allow-same-origin`/`allow-top-navigation`、`no-referrer`、权限策略全禁);`/sidebar/html` 路由带 CSP `sandbox` + 大小/路径边界;地址栏拒绝 `javascript:`/`data:`/`file:` 与 localhost 等本机地址
- 界面实时显示沙箱状态(关闭时红色警示),可临时解锁当前页面;设置页可按功能关闭沙箱(默认关闭该设置,带警告文案)——关闭后内容与界面同源,仅建议对完全可信内容使用
- 路由受 Host 头信任围栏保护(与 `/api` 一致);`fs.write` 原子写入;媒体/预览路由仅限会话 cwd 内文件(`workspaceFence` 关掉时除外,见设置页);git 只调 CLI、绝不设置身份
- HTML 预览的内容在**不透明源沙箱 iframe** 中渲染(无 `allow-same-origin`/`allow-top-navigation`、`no-referrer`、权限策略全禁);`/sidebar/html` 路由带 CSP `sandbox` + 大小/路径边界
- 设置页可按功能关闭 HTML 预览的沙箱(`htmlViewerNoSandbox` / `htmlViewerDefaultUnsafe`,默认关闭,带警告文案)——关闭后内容与界面同源,仅建议对完全可信内容使用。**网页 tab 的沙箱不再是插件的面**:浏览器视图由宿主提供(desktop profile),其沙箱与导航策略见 DSH 侧文档
## ⚠️ 已知限制
- Git 无 push/pull/fetch;Markdown 预览提供手动刷新按钮,刷新未保存编辑前会确认是否丢弃草稿;无文件 watcher/自动轮询;工具行内文件打开按钮不可拦截
- 终端 Tab 拖到另一分栏会重挂载(shell 重开)
- Office 三件套预览(.docx/.xlsx/.pptx)已移至「推荐插件」(Office 预览插件,见设置页「添加插件」弹窗);未安装时此类文件走代码/下载查看兜底
- 浏览器沙箱无登录态/第三方 Cookie 受限,部分站点登录需走弹窗;被 `X-Frame-Options`/`frame-ancestors` 拒绝嵌入的站点(如 arxiv.org)显示原因面板(含「在浏览器中打开」);iframe 内部跳转不进后退栈
- Git 无 push/pull/fetch;Markdown 预览提供手动刷新按钮,刷新未保存编辑前会确认是否丢弃草稿;文件树只对**已展开**的目录做 watch(折叠的目录不订阅,也不做全工作区递归扫描);工具行内文件打开按钮不可拦截
- **只读预览的格式由宿主决定**:表格 / PDF / 图片 / Office 走 DSH 自己的 `ui-sidebar-documentpreview`,插件只渲染 Markdown / HTML 与可编辑的文本代码;宿主的实现(渲染细节、缩放、刷新时机)随 DSH 版本走
- **浏览器视图只在 desktop profile 存在**:Web profile 没有宿主 `browser` kind,插件也不再自带浏览器 tab,因此网页 tab 只在 desktop profile 可用;登录态 / 第三方 Cookie / `X-Frame-Options` 等限制随宿主实现
- HTML 预览渲染的是已保存文件(不反映未保存草稿)
- 移动端(<768px)无底部面板:进入窄屏时其标签页一次性并入右侧栏(迁移后回桌面仍保留在右侧栏),桌面端的底部面板只在宽视口下可用。未选中会话时,点按弱化开关会显示选择会话提示;选中会话后开关打开全宽抽屉
## 🖥️ 平台支持
Windows / Linux / macOS 三平台适配(macOS 日常验证;其余经单元测试覆盖)。v0.20.0 起插件不再包含原生依赖(终端与 `node-pty` 已交还 DSH 自身),构建只需 Node + pnpm,无需编译工具链。
Windows / Linux / macOS 三平台适配(macOS 日常验证;其余经单元测试覆盖)。插件不再包含原生依赖(终端与 `node-pty` 已整体交还 DSH 自身),构建只需 Node + pnpm,无需编译工具链。
## 🤝 参与贡献