# DSH-better-sidebar

> DSH-better-sidebar 仓库自带的聚合双挂载测试夹具,模拟聚合 bundle 抢先挂载场景,验证插件自身 bundle patch 在重复挂载时自动退让避免崩溃。

## Metadata

- Author: [@omdsh-dev](https://github.com/omdsh-dev)
- Repo: <https://github.com/omdsh-dev/DSH-better-sidebar.git>
- GitHub: [omdsh-dev/DSH-better-sidebar](https://github.com/omdsh-dev/DSH-better-sidebar)
- Stars: 2,447
- Language: TypeScript
- License: [MIT](https://spdx.org/licenses/MIT.html)
- Topics: `deepseek`, `deepseek-harness`, `dsh`, `dsh-better-sidebar`, `dsh-plugin`, `sidebar`
- Forks: 182
- Open Issues: 140
- Last push: 2026-08-20T14:52:41.000Z
- Added: 2026-08-20T00:00:00.000Z

## Install

```bash
dsh plugin --profile web add github:omdsh-dev/DSH-better-sidebar/tests/fixtures/aggregate-better-sidebar
```

## Wiki

## 一句话定位
这是 DSH-better-sidebar 仓库自带的 CI 测试夹具包,用来在端到端测试中复刻"聚合 bundle 抢先挂载主插件"的场景,验证主插件自身的 bundle patch 在重复挂载时会主动退让而不是让 `dsh web` 因为重复 `/sidebar/api` 路由崩溃。

## 核心能力
- 以独立 entry id(`aggregate-better-sidebar`)在 cordis patch 里挂载名为 `dsh-better-sidebar` 的 bundle,模拟 `@linxin666/dsh-web-ui-all` 这类聚合包抢先一步把主插件打包进自己条目的形态
- 触发主插件自身 `cordis.patch.yml` 上的守卫表达式(PR #200 引入),检测到同包名 bundle 已被启用挂载就让自己的挂载行 `disabled`,避免两行同时生效重复注册 `/sidebar/api` 前缀路由
- 提供一个 no-op 的 `lib/index.js`(`export function apply() {}`)作为 npm pack 合法性的占位入口,确保打包出来的 tarball 符合 dsh plugin add 的最小契约
- 被仓库自带的 `scripts/e2e-aggregate-mount.sh` 调用,在全新 scratch profile 里按"夹具先行 → 主插件后到"的真实顺序完成打包、安装、启动、断言

## 技术实现
- **语言**: TypeScript 编译产物(ESM),但本夹具本身的代码就是一个空函数,实际"功能"写在 `cordis.patch.yml`
- **关键依赖**: 无 —— 这是独立包,既不依赖主插件的运行时也不引入第三方库;唯一的"引用"是 `cordis.patch.yml` 里 `name: 'dsh-better-sidebar'` 这条挂载声明
- **架构模式**: cordis patch 注入 —— 通过 `- insert: { id, name }` 把一个 bundle 条目写进 `~/.dsh/profiles/web/cordis.patch.yml`,bundle 的 `name` 字段是 cordis 识别"同包"的依据(不是 npm 包名),这也是为什么夹具的 `package.json#name` 可以写成 `fixture-aggregate-better-sidebar`
- **入口文件**: `lib/index.js`(no-op 占位);真正的挂载面是 `cordis.patch.yml`

## 适用场景
仅供 DSH-better-sidebar 仓库自身 CI 跑聚合双挂载冒烟测试 —— 模拟第三方聚合包(比如 `dsh-web-ui-all`)以独立条目 id 抢先把 dsh-better-sidebar 装进用户 profile,验证主插件自身的 bundle patch 在这种情况会自动退让,最终让侧边栏由聚合行接管而不是崩溃。如果你不是这个仓库的维护者、不在跑它的 CI,这个包对你没有用处。

## 前置依赖与兼容性
| 依赖 | 最低版本 | 说明 |
|---|---|---|
| DSH | 0.1.0-rc.8+ | 夹具跟随主仓库适配 DSH 0.1.0-rc.8(README.md:56、AGENTS.md 钉版说明) |
| Node.js | 未声明 | 包自身未声明 engines;实际跑 CI 需主仓库 README.md:113 要求的 Node ≥ 20 |
| 平台 | 跨平台 | 夹具本体跨平台,但它所模拟的"主插件"在不同平台依赖 node-pty 预编译二进制 |
| 原生模块 | 无 | 夹具自身不引入任何原生模块 |
| 父仓库 | DSH-better-sidebar | 必须配套装主插件才能复现完整 CI 流程;夹具自身只是先行触发器 |

## 安装方式
```bash
dsh plugin --profile web add github:omdsh-dev/DSH-better-sidebar/tests/fixtures/aggregate-better-sidebar
```

> 注意:这条命令仅作为 dsh plugin add 语法支持性的展示。夹具真实使用方式是仓库自身的 `scripts/e2e-aggregate-mount.sh`,脚本会用 `npm pack` 把它打成 tarball 然后以 `file:<tarball>` 形式装进临时 scratch profile。

## 配置项
本插件无需额外配置。

> 夹具自身的 `package.json` 没有任何 `config`/`dsh.bundle.config` 字段,`cordis.patch.yml` 也只有 entry id 与 bundle name,没有传任何配置项;它只是挂载声明,不修改 dsh-better-sidebar 的运行时行为。

## 常见问题

**Q: 这个包是给普通用户装的吗?**

A: 不是。它是 DSH-better-sidebar 仓库自带的一个 CI 测试夹具(`package.json` 里写明 `"private": true`、版本钉死 `0.0.0`),既不在 npm 上发布、也不应通过插件市场安装。它的实际使用方式只有一种:仓库的 `scripts/e2e-aggregate-mount.sh` 在 CI 里用 `npm pack` 把它打成 tarball 再用 `file:` 路径装进全新 scratch profile。

**Q: 它和主插件 dsh-better-sidebar 是什么关系?**

A: 它是一个空壳包,只有一个 `cordis.patch.yml`,里面用 `insert` 把 name 为 `dsh-better-sidebar` 的 bundle 以独立 entry id(`aggregate-better-sidebar`)挂到 cordis。cordis 因此看到两个不同 entry id 都在挂同一个 bundle name,正是这个冲突触发了主插件自身的退让守卫表达式(PR #200 引入,`cordis.patch.yml` 的 `when` 条件)。

**Q: 装上之后能在界面上看到什么?**

A: 什么也看不到。`lib/index.js` 是个空的 no-op `apply()`,包本身不注册任何 UI、不暴露任何服务、不挂任何路由;它只是替主插件"占位"了一行挂载声明,真正的侧边栏界面由主插件(或聚合行)提供。

**Q: 这个夹具在防什么 bug?**

A: 防 PR #200 修复的「duplicate prefix route」崩溃。聚合 bundle(比如 `dsh-web-ui-all`)以独立 id 抢先挂载 dsh-better-sidebar、主插件自身的 bundle patch 后到时,如果两行都生效就会重复注册 `/sidebar/api` 前缀路由,导致整个 `dsh web` 启动失败;主插件的 `cordis.patch.yml` 守卫表达式会检测到已有同包名启用挂载、自动让自身那行 `disabled`。这个夹具就是这条行为在 CI 里的固定重现器。

**Q: 我能在生产 profile 里装它吗?**

A: 技术上能 —— 它是个合法 npm 包,`dsh plugin add` 也会接受;但没有意义。装上后只会让你的 cordis patch 多一行挂载声明、不会带来任何新功能,反而会触发主插件的退让守卫(等于白装一份,实际跑起来还是主插件或聚合行在工作)。

## 上手难度
专家级 — 因为它不是给终端用户使用的,只给仓库自身 CI 脚本读取;唯一"接入"路径是 clone 仓库后跑 `bash scripts/e2e-aggregate-mount.sh`,理解它需要先看懂主插件的 `cordis.patch.yml` 守卫表达式、PR #200 的设计意图,以及 cordis loader 对同 bundle name 的处理顺序。

## 已知问题与限制
- `lib/index.js` 是 no-op,包本身没有任何运行时行为;即使被错误地装入真实 profile,也不会向 UI 提供任何东西 —— 它只是 cordis patch 层的一个声明占位
- `package.json#name` 写的是 `fixture-aggregate-better-sidebar`(不是真正的 `dsh-better-sidebar`),但 `cordis.patch.yml` 的 `name` 字段写的是 `dsh-better-sidebar`;cordis 通过 bundle `name` 而不是 npm 包名识别"同包",所以夹具可以用任意 npm 包名,只要 `name` 字段对齐主插件就行
- 版本钉死 `0.0.0`、`private: true`,不会被 `npm publish` 上传到 npm;唯一分发方式是仓库内 `npm pack` 出 tarball
- 夹具与主插件的 DSH 版本适配是隐式同步的:主仓库在 README.md:56 声明"本版适配 DSH 0.1.0-rc.8",夹具跟着主仓库的 release 走,自身没有任何 DSH 版本断言

---

This document is auto-generated by [deepseek-plugin.org](https://deepseek-plugin.org). HTML page: [DSH-better-sidebar](https://deepseek-plugin.org/plugins/omdsh-dev/DSH-better-sidebar/tests/fixtures/aggregate-better-sidebar)
Wiki generated by AI (model: `MiniMax-M3`)
