Skip to content

Releases

v0.6.5 — 适配核心 0.1.5-alpha.2:图标与分隔条回归原生

Choose a tag to compare

@lehhair lehhair released this 11 Sep 00:58

主要变化(自 v0.5.0)

  • 适配核心 0.1.5-alpha.2 的面板模型:核心把中央列改成 keyed 的 main 槽,插件改为接管 main 的 conversation 键;0.1.2-rc.1 上仍可用(0.1.5 才有的东西不存在时优雅降级)。
  • pane 的图标全部来自核心:分屏 / 上下分屏 / 全屏 / 关闭的 glyph 由 scripts/sync-icons.mjs 从核心源码提取生成,不再手抄 —— 和核心自己的按钮同款、同尺寸、同描边。
  • 分隔条不画任何东西:与核心的列 resize handle 一致(核心注释:"No handle draws a visible pill"),只保留 cursor;键盘 :focus-visible 时才有一条品牌色描边,键盘调节仍可用。
  • 新建对话的 pane 那栏只留图标:行几何照抄核心 header(顶内边距 10px + 30px 标题行),图标和旁边会话 pane 的按钮落在同一条线上。
  • 上游跟踪与发布:每 6h 检测核心 release,只在上游真正触碰本插件消费的接触面时开升级 PR(全绿才开,发版仍人工);核心 pin 记在 core-pin.json;构建产物跨机器逐字节可复现。

兼容性

开发与发布基线是核心 0.1.5-alpha.2(vendored 渲染器副本来自该版本)。0.1.5-rc.2 已实测:插件消费的接触面(渲染器 / 图标 / 会话契约)逐字节未变,无需改动。0.1.2-rc.1 也可用。

安装

下载下面的 dsh-external-dsh-split-panes.tgz(固定文件名,releases/latest/download/dsh-external-dsh-split-panes.tgz 永远指向最新构建),装法见 README。

v0.5.0 — 免补丁分屏:跑核心自己的渲染器

Choose a tag to compare

@lehhair lehhair released this 09 Sep 01:50

免补丁分屏,跑核心自己的渲染器

架构(最大变化)

每个 pane 不再手写 slot dispatch,而是把核心的 slot 渲染器逐字节 vendor 进插件,给它一个 pane 作用域的 SlotRendererHost(公开接口)——核心的 outlet 用该 pane 的 session binding 渲染。于是 header、消息流、composer、hero 全是核心自己的代码,插件的 dispatch 复刻层整体删除。

  • src/client/vendor/renderer/{bind.ts,bindings.tsx,scoped-slots.tsx}:逐字节副本
  • scripts/sync-renderer-vendor.mjs:从核心检出同步;--check 只比对
  • tests/renderer-vendor.spec.ts:在测试里再比对一次,上游一改就红
  • root standard-source binding 用 ctx.inject 反应式补齐(workspaces / keyed resource)

修复

  • 输入框 / 会话内容乱渲染:旧的手写 dispatch 与核心漂移(t 座位每帧新身份、keyed hook 每帧重订阅)——现在跑的就是核心代码。
  • 右侧边栏点"展开侧栏"没反应:ui-sidebar-right 的 store handle 被 pane 与核心渲染的区域共享,解析成了两个实例;现在 handle.create(scopeKey) 全局按 key 记忆化,两侧共用同一实例。
  • 分屏后 pane 已有会话时点"新会话"没反应:核心的 conversation 槽是 session-maybe,选中变化会重挂载整个工作区,旧的"上一次选中"ref 因此失效;改成与焦点 pane 自身会话做幂等比较。
  • 嵌套分屏的分隔条拖不动:setRatio 未递归到嵌套 split。

新增

  • 窗格全屏:pane header 的全屏按钮把该窗格铺满整列,分屏树原样保留;再点一次或按 Esc 退出,精确回到分屏状态。

交互模型

  • 点 pane → 它成为焦点,全局选中跟随(侧边栏高亮同步)
  • 点侧边栏会话 → 改的是焦点 pane 的内容,其余 pane 保持 pinned
  • 拖侧边栏会话到 pane 中心 = 替换;拖到边缘 = 向该侧分屏
  • 占位 pane 里选工作区 → 新会话落回发起它的那个 pane

兼容性

  • 开发与测试基线:核心 0.1.5-alpha.1(vendor 的渲染器即该版本)
  • 0.1.2-rc.1 实测可用:分屏、双 pane 各自会话、焦点路由、拖拽替换均正常;0.1.5 才有的功能(右侧栏等)在该版本上不存在,插件优雅降级
  • 安装:dsh plugin --profile web add link:/path/to/dsh-split-panes

安装包

固定地址(始终指向最新构建):

https://github.com/lehhair/dsh-split-panes/releases/latest/download/dsh-external-dsh-split-panes.tgz

v0.4.0 — stable hook order; split-panes-only scope

Choose a tag to compare

@lehhair lehhair released this 08 Sep 07:30

v0.4.0 — hook 顺序稳定 + 只做分屏

修复

  • 输入框时常不渲染 / Cannot read properties of null (reading 'destroy'):composer 输入条是 session-maybe 槽,其 InputBar 组件实例跨 hero/active 转换保持。keyed projection hook 的 absent 分支此前不调用 useSyncExternalStore,导致组件跨状态转换时 hook 调用数变化、React hook 链损坏。现在 absent 分支与官方渲染器的 keyedObservableHook absent 臂一致(始终订阅 absent source,selector 永不被调用)。
  • 移除全局标题栏/侧边栏 chrome 修改(PaneGlobal.module.css):插件现在在 pane 表面之外零视觉修改,只做分屏。

焦点同步模型(验证通过)

  • 分屏后点击侧边栏会话 → 新会话路由到焦点 pane(其余 pane 保持各自的会话)
  • 点击 pane → 全局选择跟随该 pane 的会话(侧边栏高亮同步)
  • 新分出的 pane 是新建对话占位(hero),在其中开始对话才创建会话并绑定

31 tests 全绿,typecheck + build 通过。

v0.3.0 — pure-extension: capture ConversationRoot (native layout per pane)

Choose a tag to compare

@lehhair lehhair released this 08 Sep 07:08

v0.3.0 — 纯扩展架构修正:捕获 ConversationRoot,不再复刻布局

重大架构修正。之前「接管 conversation 槽 + 自建渲染层 + 复刻布局」的方向被证明不可行,现已改为纯扩展的正确做法,端到端验证通过。

核心修正

核心没有按 id 渲染的扩展点(ScopeBindingContext/host 实例/renderArea 的内容 dispatch 都是包私有),而复刻 ConversationRoot 布局(hero/workspace picker/composer/测量/width handles)既不可能(内部组件和 CSS 不导出)也不可维护(395 行复杂逻辑)。

正确做法:捕获原生 ConversationRoot 组件,喂给它 pane 会话的数据与 dispatch——每个 pane 渲染真正的原生对话界面。

变更

  • PaneConversation:捕获 conversation 槽的原生 ConversationRoot 条目(component + inject + locale),按 pane 会话通过 by-id kit 重新托管——原生对话界面逐字节渲染(hero、workspace picker、composer、消息流、width handles),只是 session 不同
  • 复用 ConversationRoot 条目的 inject(原生 selectWorkspace + hooks.composerBlock)——工作区选择逻辑无需重写
  • renderPane 渲染 ConversationRoot(单窗格=current session,分屏=各 pane 自己的 session);删除 PaneBody
  • render-host 新增 renderConversationRoot()(选中非 takeover 的原生条目)、store/inject 缓存、owner props 合并、槽级 inject 工厂、memo/forwardRef 组件支持
  • kit 的 absent hook 与渲染器 maybe-hook 语义一致(selector 不被调用——hero 态 useSession/useConversation 返回 undefined,不再报 undefined.promptError)

验证

  • takeover 渲染原生 chrome(header + composer,无「未知 surface」)
  • 分屏各 pane 渲染原生对话(15k+ HTML、分隔条、新建对话 hero、无 fallback)
  • 31 tests 全绿,typecheck + build 通过

修复的历史问题

  • 「首页新建对话只剩标题+按钮」→ ConversationRoot 的 hero 原生保留
  • 「未知 surface 事件」→ chat node 的 memo 组件 + dispatch 修复
  • 「丢失 composer/workspace picker」→ ConversationRoot 原生保留
  • 「状态丢失」→ render-host 的 store/inject 缓存

纯扩展,免补丁。

v0.2.3 — fix owner merge + slot inject in pane dispatch

Choose a tag to compare

@lehhair lehhair released this 08 Sep 06:09

v0.2.3 — 修复 dispatch 的 owner 合并、槽级 inject 与无会话门控

修复 v0.2.2 安装后的三类渲染崩溃。

修复

  • Cannot read properties of undefined (reading 'data')(ToolCallTree):pane 的 renderSlot 此前丢弃了 owner 参数——chat node 的 dispatch(ChatNodeSeat)把 node/selectedCallId/cwd/... 作为 owner props 传入,渲染器把它们最后合并(胜出)。pane dispatch 现在完全镜像该合并顺序(kit → entry inject → store → slot inject → contextual hooks → owner)。
  • 槽级 inject(chat node 的 CHAT_NODE_INJECT / useTurnData):现在读取槽 spec 的 inject face(registry spec()),其 hook 工厂按每次 dispatch 的 hookContext 绑定——与渲染器的 cachedSlotInject/bindSlotHookFactories 一致。
  • useConversation is not a function:PaneBody 对严格 session 槽(header/body/docks)按会话身份门控——无会话窗格跳过这些槽(composer bar 是 session-maybe 槽,照常渲染为惰性态),与 ui-conversation 的 ConversationRoot 一致;且 binding 中缺失的 hook 不再以 undefined 写入 props。

回归测试

新增 pane-dispatch.spec.tsx:keyed dispatch 回归,覆盖 owner 合并与 hookContext 工厂两个形态(31 tests 全绿)。

v0.2.2 — fix workspaces inject + button t seat

Choose a tag to compare

@lehhair lehhair released this 08 Sep 05:35

v0.2.2 — 修复 workspaces inject 与按钮 t seat

修复 v0.2.1 安装后的两处运行时报错。

修复

  • cannot get property "workspaces" without inject:pane kit 读取 ctx.workspaces(useWorkspaces 根源),但插件 cordis inject 列表未声明该服务——cordis 对未注入服务的 getter 直接抛错。已把 workspaces 加入 inject,并在 buildPaneKit 里对缺失该源的环境加了守卫。
  • t is not a function(SplitPaneButton / SplitVerticalButton):渲染器只为声明了 locale 命名空间的条目合成 t seat;header 按钮注册时漏了 locale: NS。三个 header 按钮现在都声明 panes 命名空间。

验证

29 tests 全绿;构建产物确认 inject 列表与按钮 locale 声明。

v0.2.1 — fix real-render crashes

Choose a tag to compare

@lehhair lehhair released this 08 Sep 04:48

v0.2.1 — 修复真实渲染崩溃 (fix real-render crashes)

修复 v0.2.0 安装后分屏渲染报错的问题。

修复

  • selector is not a function:keyed hook(useProjection 等)的 selector 现在可选(核心契约:TodoDock 调用 useProjection('todos') 不带 selector)
  • Cannot read properties of undefined (reading 'byId'):pane kit 现在携带 ROOT 标准源(useSessions/useWorkspaces/useSessionPendingInteraction),镜像渲染器的 {...root, ...session} 合成
  • t is not a function:按条目 locale 命名空间合成 t seat(ctx.locale.bind)
  • hooks 空指针崩溃:测试环境 react 双实例问题(resolve.dedupe)

测试

新增真实渲染集成测试(pane-render-host.spec.tsx):装配真实 ui-conversation,通过 pane kit 渲染真实原生组件(header + chat view + composer)。29 tests 全绿。

v0.2.0 — patch-free upgrade to DSH 0.1.3+

Choose a tag to compare

@lehhair lehhair released this 08 Sep 03:55

v0.2.0 — 免补丁升级 (patch-free upgrade)

DSH 核心 0.1.3-alpha.1 起不再需要渲染器补丁。分屏功能现完全基于核心公开 API 实现。

变更

  • 移除核心补丁 (SessionScope / conversation.panes):不再需要 patch 核心
  • 插件自持渲染层级:\ctx.uiSession.adapter.resolve\ 按窗格会话解析标准源、捕获原生槽位组件重新托管
  • \conversation\ 槽低优先级影子接管分屏;卸载即回原生渲染
  • 依赖:删除已移除的 @deepseek-ai/dsh-client-runtime\,改用 cordis + api-session-controller + ui-renderer/ui-session 等
  • 4 个测试文件 26 个用例全部通过;typecheck + build 全绿