# dsh-plugin-hub 插件架构文档 > 本目录用**图解为主**的方式,讲清每个插件的**功能、原理、使用方式**。 > lan-proxy、notifier、worktree-sidebar 与 mcp-manager 按 BA 业务 / AA 应用 / DA 数据 / TA 技术四视图组织(mcp-manager 与 lan-proxy、notifier 的 TOGAF 四视图同模板,基线 d5cfdf08); > 其余文档按功能概览 → 总体架构图 → 核心机制 / 时序 → 使用方式 → 安全模型与边界组织, > 与各插件包 README(安装 / 配置 / 验证的快速上手)互补。 > > 图使用两种载体(源数据均归档、可复现): > - **SVG 架构图**:按 diagram-design 编辑风手写 SVG,源文件 > 归档在 [diagrams/](diagrams/),可直接用浏览器打开源 HTML 调整后重新导出 > (`python3 scripts/lib/export-diagram-svg.py <源.html>`); > - **Mermaid 图**:内嵌在 md 中,GitHub 原生渲染,源码即文档(天然可维护)。 > > 仓库级共享机制(loopback 围栏、官方 settings 存储、client 干净模块等)见 > [「通用机制」](#通用机制)。 ## 插件索引 | 插件 | 一句话定位 | 架构文档 | |---|---|---| | `@wingsky-1/dsh-lan-proxy` | 局域网访问 dsh web:HTTP/HTTPS/WS 转发 + TLS + 响应压缩 | [dsh-lan-proxy.md](dsh-lan-proxy.md) | | `@wingsky-1/dsh-mcp-manager` | MCP 服务器管理:配置面与模型可见面管理(单池 + `ws_mcp_call` 统一寻址) | [dsh-mcp-manager.md](dsh-mcp-manager.md) | | `@wingsky-1/dsh-notifier` | 审批/完成/错误事件通知:浏览器 Notification + 系统 toast + Bark | [dsh-notifier.md](dsh-notifier.md) | | `@wingsky-1/dsh-provider-usage` | 多 provider 用量统计:v2 适配器契约 + 宿主端渲染 + 历史落盘 | [dsh-provider-usage.md](dsh-provider-usage.md) | | `@wingsky-1/dsh-verify-isolated` | 插件开发隔离浏览器验证 skill(临时 DSH_HOME + 独立 profile) | [dsh-verify-isolated.md](dsh-verify-isolated.md) | | `@wingsky-1/dsh-worktree-sidebar` | 把某个 git worktree 登记给当前会话:官方右侧栏文件树换根、会话 cwd 不变 | [dsh-worktree-sidebar.md](dsh-worktree-sidebar.md) | | `@wingsky-1/dsh-plugins-all` | 全家桶聚合包(一键装齐 + 聚合 cordis patch) | [dsh-plugins-all.md](dsh-plugins-all.md) | ## 全景:插件如何挂载进 dsh web 所有插件都不修改 DSH 源码——统一经 **`cordis.patch.yml` + profile 机制**挂载: ```mermaid flowchart LR subgraph npm["npm 分发(@wingsky-1/dsh-*)"] P1["dsh-lan-proxy"] P2["dsh-mcp-manager"] P3["dsh-notifier"] P4["dsh-provider-usage"] P5["dsh-verify-isolated"] P6["dsh-worktree-sidebar"] end subgraph profile["dsh web profile(cordis 运行时)"] CORDIS["cordis.patch.yml
insert: id + name 一行"] HOST["宿主端 lib/index.js
apply(ctx) 在 Node 进程运行"] CLIENT["客户端 lib/client.js
apply(ctx) 在浏览器运行"] ROUTES["/api 路由
loopback 围栏"] CORDIS --> HOST CORDIS --> CLIENT HOST --> ROUTES end P1 --> CORDIS P2 --> CORDIS P3 --> CORDIS P4 --> CORDIS P5 --> CORDIS P6 --> CORDIS ``` 要点: - **安装**:`dsh plugin --profile web add <包名>` → 包内 `cordis.patch.yml` 的 insert 行 被写进 profile 插件名册;`dsh web` 重启时组合 bundle,宿主端与客户端各跑一半; - **宿主端**(`exports "."` → `lib/index.js`):在 Node 进程中 `apply(ctx)`,注入 `webServer` / `tools` / `settings` / `connection` 等官方服务,注册路由与事件监听; - **客户端**(`exports "./client"` → `lib/client.js`):干净模块(`apply(ctx)` + `inject`),构建期内联样式与依赖,通过 `__DSH_ROUTES__` 拿到真实路由表; - **依赖关系**:各插件彼此独立(`dsh-mcp-manager` 提供的 `ctx.mcpManager` 为可选消费面, 无插件对其强依赖); - `dsh-plugins-all` 是聚合包:dependencies 拉齐全部子包 + 聚合 cordis patch (`scripts/gate/aggregate.ts` 自动生成,禁止手改)。 ## 通用机制 所有插件遵循仓库级共享约定(单一事实源在 `shared/` 与 [docs/DEVELOPMENT.md](../DEVELOPMENT.md)): | 机制 | 说明 | 实现位置 | |---|---|---| | **loopback 围栏** | 所有 `/api` 路由强制回环来源(remoteAddress + Host + 非跨站 + Origin 同源),非法 403 / 方法错 405——DNS 重绑定与跨站防御 | `shared/loopback.js`(`isLoopbackRequest`) | | **官方 settings 存储** | 使用此机制的插件(如 lan-proxy)将配置存官方 `settings.register` 命名空间,cordis config 作 base 层,热更新由 `scope.watch` 驱动;notifier 当前自持 `config.json`,官方 settings 仅作迁移来源,见其 DA 视图 | `shared/settings-namespace.js`(`installSettingsNamespace`) | | **客户端干净模块** | 只 `export function apply(ctx)` + `export const inject`;样式独立 `src/client/style.css`;构建期内联(`scripts/build/build-client.ts`) | 各包 `src/client/index.ts` | | **发布物自包含** | 第三方依赖构建期内联进 `lib/`,运行时零 npm 依赖;license 自动归集 `lib/THIRD-PARTY-LICENSES` | `scripts/build/` | | **loopback 服务端/客户端契约** | 宿主端在 index.ts 透出纯函数/常量,smoke 从 `lib/index.js` 导入断言(路由围栏 + 客户端契约) | `test/*.test.ts` | ## 图源归档 `diagrams/` 目录存放每张 SVG 架构图的**源文件**(diagram-design HTML),命名与文档一一对应: | 文档 | 图 | 源文件 | |---|---|---| | 本页(全景) | 挂载流程图 | mermaid 内嵌(无独立源) | | [dsh-lan-proxy.md](dsh-lan-proxy.md) | BA 业务架构 | [图源 HTML](diagrams/lan-proxy-ba.html) | | [dsh-lan-proxy.md](dsh-lan-proxy.md) | AA 应用架构 | [图源 HTML](diagrams/lan-proxy-aa.html) | | [dsh-lan-proxy.md](dsh-lan-proxy.md) | DA 数据架构 | [图源 HTML](diagrams/lan-proxy-da.html) | | [dsh-lan-proxy.md](dsh-lan-proxy.md) | TA 技术架构 | [图源 HTML](diagrams/lan-proxy-ta.html) | | [dsh-lan-proxy.md](dsh-lan-proxy.md) | 转发架构图(历史图源) | `diagrams/lan-proxy-architecture.html` | | [dsh-mcp-manager.md](dsh-mcp-manager.md) | BA / AA / DA / TA 四视图 | `diagrams/mcp-manager-{ba,aa,da,ta}.html` | | [dsh-mcp-manager.md](dsh-mcp-manager.md) | 双轨架构图(历史单图,非事实源) | `diagrams/mcp-manager-architecture.html` | | [dsh-notifier.md](dsh-notifier.md) | BA 业务架构 | [图源 HTML](diagrams/notifier-ba.html) | | [dsh-notifier.md](dsh-notifier.md) | AA 应用架构 | [图源 HTML](diagrams/notifier-aa.html) | | [dsh-notifier.md](dsh-notifier.md) | DA 数据架构 | [图源 HTML](diagrams/notifier-da.html) | | [dsh-notifier.md](dsh-notifier.md) | TA 技术架构 | [图源 HTML](diagrams/notifier-ta.html) | | [dsh-notifier.md](dsh-notifier.md) | 按域架构与通知管线图(历史图源) | `diagrams/notifier-architecture.html` | | [dsh-provider-usage.md](dsh-provider-usage.md) | 宿主端渲染架构图 | `diagrams/provider-usage-architecture.html` | | [dsh-worktree-sidebar.md](dsh-worktree-sidebar.md) | BA 业务架构(能力面 → 工具 → 可见产物) | `diagrams/worktree-sidebar-ba.html` | | [dsh-worktree-sidebar.md](dsh-worktree-sidebar.md) | AA 应用架构(组合根 + 五域 + 适配层 + 浏览器端接管) | `diagrams/worktree-sidebar-aa.html` | | [dsh-worktree-sidebar.md](dsh-worktree-sidebar.md) | DA 数据架构(写入链 / 字段与版本 / 身份凭据 / 三态与缓存 / 自愈) | `diagrams/worktree-sidebar-da.html` | | [dsh-worktree-sidebar.md](dsh-worktree-sidebar.md) | TA 技术架构(挂载 / 依赖 / 构建链 / 门禁 / 耦合点 / 命门) | `diagrams/worktree-sidebar-ta.html` | > 调整方法:用浏览器打开源 HTML → 修改 SVG 内容 → 重新导出 SVG > (`python3 scripts/lib/export-diagram-svg.py <源.html>`)替换文档中的引用。 > Mermaid 图直接改 md 源码块即可(GitHub 原生渲染)。 > > 包内 archify 旧物归档(#767 DIAGRAM-A):`packages/dsh-mcp-manager/docs/diagrams/` 的 `mcp-manager-archify-overview.html` 与 `mcp-manager-overview.architecture.json` 已移入同包 `docs/archive/`(历史留档,非事实源);6 个 `visual-check` 生成物已删除。