feat: 服务化改造 — ctx.betterSidebar 注册表(registerTab/registerFileViewer),内置 6 tab + 6 viewer 迁移到 registry,v0.4.0

- 新增 src/client/service.ts: BetterSidebarService 接口 + createBetterSidebarService 工厂
  - registerTab/registerFileViewer 返回 disposer(HMR-safe,挂到 cordis fiber)
  - matchFileViewer 三段匹配: priority desc → detect(内容嗅探) → exts
  - openTab 走 descriptor.dedupeKey 统一去重(替代 isSingle/editor-path/diff-id 三分支)
  - createTab 回调支持自定义 tab 创建(terminal 的 nextTerminal 递增)
- 新增 src/client/builtins.tsx: 6 内置 tab + 6 内置 viewer 自我注册(吃狗粮)
  - tab: editor(hidden) / explorer / git / subagent / terminal / diff(hidden)
  - viewer: image / pdf / docx / xlsx / pptx / binary-download
  - code/markdown 保持 EditorView 内联兜底(matchFileViewer 返回 undefined 时走 fsRead+CodeMirror)
- 新增 src/client/OrphanedTab.tsx: 未注册 type 的占位组件(插件未加载时降级)
- 改造 src/client/index.tsx: ctx.provide('betterSidebar') + registerBuiltins
- 改造 src/client/Sidebar.tsx: TabContent/buildNewTabOptions/onNewTab 查表替代 switch
- 改造 src/client/EditorView.tsx: 预览路由查 matchFileViewer 替代 if/else 链
- 改造 src/client/state.ts: TabType 联合字面量→string,sanitizeNode 接受所有 string type
- 改造 src/context-types.ts: declare module 'cordis' 加 betterSidebar 字段
- 改造 src/index.ts: re-export Context + 服务类型(consumer import type 触发 augmentation)
- package.json: 加 ./client/service exports 子路径,version 0.4.0
- tests/service.spec.ts: 12 个新测试覆盖 register/dispose/matchFileViewer/dedupe/createTab
- tests/unit.spec.ts: sanitizeState 测试更新(未知 type 不再被拒绝,渲染 OrphanedTab)
This commit is contained in:
HuanLinOTO
2026-08-11 00:31:23 +08:00
parent fbebcf5138
commit 291158a3ba
15 changed files with 878 additions and 156 deletions
+7
View File
@@ -20,6 +20,7 @@
import type { IncomingMessage, ServerResponse } from 'node:http'
import type { Duplex } from 'node:stream'
import type { Context } from 'cordis'
import type { BetterSidebarService } from './client/service.ts'
/** One named webserver route (mirror of the host-webserver WebRoute). */
export interface SidebarWebRoute {
@@ -309,6 +310,12 @@ declare module 'cordis' {
settings: SidebarSettingsService
invariants: SidebarInvariantsService
tools: SidebarToolsService
/**
* The client-side sidebar registry: external plugins register tab types
* and file previewers here. Provided by the client half (see
* {@link ./client/index.tsx}); undefined on the host side.
*/
betterSidebar: BetterSidebarService
/**
* Register a lifecycle callback (DSH-vendored cordis): runs at plugin
* activation; its returned cleanup runs at disposal.