The v0.19.0 regression, its root cause in 223b254, the four decisions
(native landing, narrow-viewport park, jump-back always expands, bottom
workbench keeps its own flows), the change list, and the evidence — including
the environment trap that the PATH `dsh` on this machine is 0.1.2-rc.1 and
cannot register the `file:` tarball into a scratch profile.
12 KiB
12 KiB
DSH 0.1.5-alpha.2 适配(v0.19.0-alpha.1 基线)
日期:2026-09-09 分支:feat/dsh-0.1.5-alpha.2
背景
DSH dsh-v0.1.5-alpha.1..dsh-v0.1.5-alpha.2 的宿主契约里有一批会实际波及本插件的变更。本计划记录哪些值得处理、哪些只做兼容、以及每一处的子系统级落点。插件对外的全部行为差异以 docs/external-plugin-guide.md 为准;仓库级适配要点(基线、CI 钉版、宿主契约)同步到 AGENTS.md §3。
上游 delta(alpha.1 → alpha.2,影响本插件的六项)
| # | 上游变更 | 对插件的影响 |
|---|---|---|
| 1 | SidebarRightGuideEntry 去掉 description 字段;指南条目变为「图标 + 标题」胶囊 |
删除 TabDescriptor.description 与 6 个 guideDesc* 词典键(连同 nativeGuideDesc 兜底句——不再有第二行说明) |
| 2 | 新增全局面板:根级 keyed main 槽(预留 key conversation,由 ui-conversation 注册为 main.conversation)、根级 sidebar.panellist 列表槽(SidebarPanelMetadata / SidebarPanelIconOwnerProps)、`ctx.layout.selectPanel(MainPanelId |
null)/beginNavigation()/dispose()、全局标准 prop usePanelInfo;rightbar改根级并新增会话级rightbar.session` 子槽 |
| 3 | 原生 tab 体宿主 .paneBody(dsh-client-ui-dockkit)是有确定高度的块级滚动容器,不是 flex 容器;DSH 自己的 tab 体(ui-sidebar-documentpreview 的文档预览、ui-sidebar-files 的 FilesBody)在根上声明 height: 100% |
原生适配层给每个 tab 体包一层 height: 100% 的列 flex 宿主(sidebar.module.css .nativeTabHost,带 data-dsh-native-tab-host),修复 sidechat 输入框贴不到面板底的根塌陷 |
| 4 | 文件地址语法:fileAddressFor 一律返回 session 作用域地址(绝对路径保留前导 /);parseFileAddress 前缀解析并去 ?/#;absoluteFileAddress 仍在 |
镜像 alpha.2 语法(插件自实现于 src/client/resource-address.ts——客户端 bundle 纯度门禁禁 value-import 未列名的 @deepseek-ai/*,不能直接引 DSH 工具包) |
| 5 | ui-sidebar-textpreview 被 ui-sidebar-documentpreview 取代(同 text kind、fallback 带、dsh-resource://file/** 模式) |
插件 editor 仍以 extension 优先级认领 dsh-resource://file/**,压过其 text 的 fallback 带 |
| 6 | 基线升到 0.1.5-alpha.2(peer 下限 / manifest / CI 钉版) | 插件基线 = alpha.2 only;alpha.1 用户留在 v0.19.0-alpha.0 |
后续(2026-09-10):
SidebarRightGuideEntry.description在 DSH 0.1.5-rc.1 回归(可选,且宿主只在 guide 列出的条目 ≤ 4 条时渲染),插件已在 v0.19.0 恢复该字段——见 2026-09-10-dsh-0.1.5-rc.1-adaptation.md。后续(2026-09-10):退役自绘右侧面板(#605)时,
use-host-feeds.ts的三处自动激活被误改成target: 'bottom',任务页因此落到插件自己的底部工作台而非 DSH 原生右侧栏。修复见 2026-09-10-auto-activation-native-landing-fix.md。
决策
- 基线 = alpha.2 only:peer 下限
^0.1.5-alpha.2、manifest>=0.1.5-alpha.2、CI 钉@deepseek-ai/dsh@0.1.5-alpha.2;不再对 alpha.1 做运行时兼容。 - 全局面板:兼容 only,不接入——不迁移到
main槽 /sidebar.panellist/ctx.layout/usePanelInfo/ 根级rightbar,仅保证在 alpha.2 宿主上不破坏。 - 删除
TabDescriptor.description:宿主不再渲染第二行,字段留着只会在类型上撒谎;同步删 6 个guideDesc*与nativeGuideDesc兜底句。 - 修复 tab 体填充:native 适配层为每个 tab 体(含 orphaned 回退)包
height:100%列 flex 宿主.nativeTabHost;tab 组件根遵循flex:1/height:100%+min-height:0契约。 - 镜像 alpha.2 地址语法:
fileAddressFor不再产生absolute作用域(但仍解析旧地址与第三方地址),parseFileAddress前缀解析并去?/#。 - 中心列锚点跟随 alpha.2:
center-column.ts的CENTER_COLUMN_SELECTOR改为#root [data-slot="main.conversation"], #root [data-slot="conversation"],resolveCenterColumn从对话槽宿主向上跳过display: contents祖先取真实列;alpha.1 的[data-slot="conversation"]依旧认可。
改动清单(子系统级)
| 子系统 | 文件 | 变更 |
|---|---|---|
| 基线 | package.json |
版本 → 0.19.0-alpha.1;dsh-* peer 全部 ^0.1.5-alpha.2;devDeps 同步钉 0.1.5-alpha.2 |
| 基线 | pnpm-lock.yaml |
锁文件对齐 alpha.2 |
| 基线 | dsh.plugin.json |
version → 0.19.0-alpha.1;engines.dsh → >=0.1.5-alpha.2 |
| 基线 | .github/workflows/ci.yml |
mount lane 钉 @deepseek-ai/dsh@0.1.5-alpha.2 |
| 基线 | package.json |
按 §3-9 补提 dsh-session-persistence(pnpm peers check 唯一新失配项) |
| 基线 | package.json |
上游打包缺陷:@deepseek-ai/dsh-client-ui-primitives@0.1.5-alpha.2 的 manifest 不再声明任何 dependencies(alpha.1 声明了 19 个),但其 lib/*.js 仍裸 import anser / shiki / @shikijs/langs/* / mdast-util-* / micromark-* / katex。宿主自身由预构建前端 bundle 满足,独立安装的消费方(本仓库的 dev/test 树)必须自备,故把 alpha.1 声明的同一组版本提升进 devDependencies(@shikijs/langs、@types/mdast、anser、katex、mdast-util-from-markdown/gfm/math、micromark-core-commonmark/extension-gfm/extension-math/factory-space/util-character/util-classify-character/util-sanitize-uri/util-symbol/util-types、shiki;clsx 已在 dependencies) |
| 基线/文档 | AGENTS.md |
§2/§3 基线戳、§10 补 alpha.2 行为差异(本 workstream 回填) |
| Tab 契约 | src/client/service.ts |
TabDescriptor 删除 description 字段;SIDEBAR_SERVICE_VERSION → 0.19.0-alpha.1 |
| Tab 契约 | src/client/builtins/tabs.tsx |
6 个内置 tab 删除 description 行 |
| Tab 契约 | src/client/native/index.ts |
native 注册的 guide 条目去掉 description(删 descriptionOf 与通用兜底);guide 条目只剩 order/title/icon |
| 词典 | src/client/locales.ts + 各 locales-*.ts |
删除 nativeGuideDesc + 6 个 guideDesc* 词条(zh/en + 全部第三方语言) |
| Tab 高度 | src/client/native/tab-adapter.tsx |
NativeTabBody 把 live 组件与 orphaned 回退都包进 css.nativeTabHost(带 data-dsh-native-tab-host) |
| Tab 高度 | src/client/sidebar.module.css |
新增 .nativeTabHost(display:flex; flex-direction:column; height:100%; min-height:0) |
| 地址语法 | src/client/resource-address.ts |
重写为镜像 alpha.2 文件地址语法(fileAddressFor 不再产 absolute 作用域、parseFileAddress 前缀去 ?/#、保留 absolute 解析) |
| 中心列锚点 | src/client/center-column.ts |
CENTER_COLUMN_SELECTOR 加 main.conversation;新增 columnOfSlotHost 跳过 display: contents 祖先 |
| 中心列锚点 | src/client/sidebar/use-center-column.ts |
宿主查找逻辑对齐 alpha.2 |
| 中心列锚点 | src/client/layout.css |
选择器/注释同步 main.conversation 与 display: contents 跳过 |
| 测试 | tests/builtins.spec.ts |
指南断言从 description 改成 title(图标+标题胶囊) |
| 测试 | tests/native-surface.spec.ts |
注册/guide 断言去 description;断言 guide 条目不再携带 description |
| 测试 | tests/center-column-locator.spec.ts |
覆盖 main.conversation 解析与 display: contents 跳过 |
| 测试 | tests/resource-address.spec.ts |
覆盖 alpha.2 地址语法 |
| 测试 | tests/e2e/mount.e2e.ts |
guide 页断言跟随胶囊形态;新增 tab 体填充断言(可见 tab 的 [data-dsh-native-tab-host] 盒高 == 其带盒祖先高 ±2px,且 sidechat composer 底边距面板底 ≤12px) |
| 文档 | docs/external-plugin-guide.md |
§0 行为差异表、§4.1 删 description、§10 加 tab 体高度契约、§12 中心列锚点、ui-sidebar-documentpreview |
| 文档 | docs/plans/2026-09-09-dsh-0.1.5-alpha.2-adaptation.md |
本计划 |
已知差距
- side-chat 线程仍只携带
subagent/descriptor,不携带 alpha.2 的subagent/catalog:DSH 自己的直接子代理发现现在优先读catalog,而我们沿用的subagents.listDescendants(src/subagent-live-route.ts)与转录种子的type: 'subagent/descriptor'(src/sidechat-routes.ts)路径不变。catalog 只作为新增读面出现,不构成对现有路径的破坏,本期不跟进。
验证
- 门禁(本分支 HEAD):
pnpm typecheck/pnpm lint/pnpm check:consumer-types全绿;pnpm vitest run --exclude '**/*.e2e.ts'= 124 files / 1295 passed / 9 skipped;pnpm peers check= No peer dependency issues found。 - 真机挂载冒烟(
DSH_CMD指向 npm 安装的 DSH 0.1.5-alpha.2,scripts/e2e-mount.sh):7 passed。新增的 tab 体填充断言(可见 tab 的[data-dsh-native-tab-host]盒高 == 其带盒祖先 ±2px,sidechat composer 底边距面板底 ≤12px)是这次修复的回归守护——它在修复前失败(gap -862px,因为断言最初漏跳过display: contents槽宿主)。 - 真机 3080(web profile 升到 alpha.2 + 插件 0.19.0-alpha.1):
- 原生 guide 六行均为 48px「图标+标题」胶囊,无第二行:文件 / 文件变动 / 任务管理 / 侧边对话(beta) / 终端 / 浏览器。
- 文件树点击
AGENTS.md→ tab 标题AGENTS.md+ CodeMirror 挂载(editor接管成立)。 - sidechat 输入框贴底:原生右侧栏
hostHeight 962 == paneBodyHeight 962(fillGap 0),composer 底边距面板底 8px(即它自己的 margin);底部工作台同样 8px。 - 底部工作台中心列锚点:
[data-dsh-bottom-panel]与[data-dsh-center-col]左右边完全重合(gap 0)——证明main.conversation+ 跳过display: contents的解析在真机成立;真机[data-slot]清单同时确认main/main.conversation/rightbar.session已存在、旧conversation槽已消失。 pageerror0 条;控制台仅POST /api/dsh-worktree/attach500(第三方 dsh-tauri-worktree 插件,与本次改动无关)。- 未覆盖:聊天里的文件链接点击——当前可见会话没有可解析的文件提及(内联
code是纯文本,不是链接),该漏斗(ctx.sidebarRight.openResource(fileAddressFor(...)))由挂载车道与tests/resource-address.spec.ts覆盖,本实例未实测。
- 仓库没有守护指南文档章节的测试;
tests/builtins.spec.ts/tests/native-surface.spec.ts守护的是 guide 行形态而非文档文本。 - 早期本分支相关测试曾整体收集失败:
@deepseek-ai/dsh-client-ui-primitives@0.1.5-alpha.2在模块加载时裸import 'anser',而该包 manifest 已不再声明依赖。补齐 devDependencies 后恢复(见改动清单)。
不做
- 不接入 alpha.2 全局面板(
main槽 /sidebar.panellist/ctx.layout/usePanelInfo/ 根级rightbar)。 - 不引入
subagent/catalog读取面。 - 不改 DSH 源码(仓库硬约束 §1)。
落地
- #603 → #604 → #605 → #609 依序合入
main(各自 retarget 到 main 后以 merge commit 合并);main 的package.json为0.19.0-alpha.1、engines.dsh为>=0.1.5-alpha.2。main 的 CI 首轮ci-windows因既有的 pty/git 5s 超时抖动失败,重跑后三 job 全绿。 - 发布 v0.19.0-alpha.1:
release.yml通过全门禁后经 npm Trusted Publishing 发布,npmalphadist-tag →0.19.0-alpha.1(带 provenance)。发布产物核对:lib/index.js与本地已验证构建逐字节一致;lib/client.js仅差打包非确定性(已知);package.json仅少 dev-only 字段(packageManager/prepare/prepublishOnly,npm 发布时剥离)。 - 注意:新版本在 registry 上可见有约 5 分钟传播延迟(版本元数据先到、tarball 后到),期间
npm view/tarball 可能 404——不是发布失败。