# 0.2.1-rc.2 兼容性对照:`dsh-todo-board` 0.13.1 - 核查时间:2026-10-17 - 目标运行时:`dsh-desktop-runtime` **0.2.1-rc.1**,内部 `@deepseek-ai/*` 全部 **0.2.1-rc.2**,cordis **4.0.5** - 插件版本:`dsh-todo-board` **0.13.1** - 核查方式:`cordis_inspect`(Service / Event / Slots 三个 Provider,读**运行中**的真机注册表)+ 桌面端 `app.asar` 内 0.2.1-rc.2 源码逐处比对 + 本机 `node --check` / `tools/smoke.mjs` 实跑 - **全程只读**:本步未修改插件任何一行代码 > 上一版适配报告是 0.12.0 的(针对 0.2.0-rc.2)。本文件只记录 **0.2.0-rc.2 → 0.2.1-rc.2** 这一跳的增量结论,以及插件对它们的实际依赖。 --- ## 一、结论(先看这里) **1. 插件依赖的 host 服务,一个都没少。** 逐个核对了 `ctx.get(...)` / `ctx.inject([...])` 用到的 14 个服务键,全部在 0.2.1-rc.2 的运行中注册表里,签名也都在插件用到的那些方法上保持兼容。 **2. 插件依赖的 host 事件,两个都在,且语义未变。** **3. 会话格式仍是 v4**(`SESSION_FORMAT_VERSION = 4`),0.11.2 的 v4 适配继续有效,**不需要新的会话格式适配**。 **4. 唯一需要动的是版本门**:插件声明 `>=0.1.7-rc.2`,语义上已覆盖 0.2.1-rc.2,**但从未针对 0.2.1 做过任何验证,也没有上界声明**。这是第 2 步要处理的事,不是代码 bug。 **5. 本次核查没有发现任何必须修改的代码不兼容点。** ⚠️ 这条结论建立在一个前提下:`targetAlive` 那处一度被我判成「`sessions.has()` 已被删除」,**那是我读错了** —— 该处的 `sessions` 是 `liveSessions()` 返回的 `Map`,`Map.prototype.has` 合法存在,与服务层 `ctx.sessions` 无关。已在 §四 留档,避免下次重复踩。 --- ## 二、host 服务逐项核对 来源:`cordis_inspect_query(platform=host, provider=Service, method=listService)` | 插件用到的键 | 插件调用点(`lib/index.js`) | 0.2.1-rc.2 实际状态 | 结论 | | --- | --- | --- | --- | | `agents` | `:1052` `agents.list()`、`:1862/:1893/:1947/:1960` `agents.get()` / `.create()` | `list(): Agent[]`、`get(id)`、`async create(options)` 全在 | ✅ 兼容 | | `attachments` | `:1425` 取服务、`:3120` 取服务 | `saveImages`、`validateImage`、`imageLimits`、`readImage` 全在 | ✅ 兼容 | | `llm` | `:1641` `llm.listModels(provider)`、`:1830` `llm.stream({...})` | `async listModels(provider): LlmModelInfo[]`、`stream(options): AsyncIterable` 全在 | ✅ 兼容 | | `agentDefaultModel` | `:1671` 读默认模型 | `currentSelection(): ModelSelection` 在 | ✅ 兼容 | | `sessionQuery` | `:1802` 取服务、`:1810` `query.readSurface(id)` | `readSurface(sessionId): Promise` **仍在** | ✅ 兼容 | | `agentPresets` | `:1870` 取服务、`resolve()` / `mount()` | `async resolve(id?)`、`async mount(ctx, id?)` 全在 | ✅ 兼容 | | `systemPrompt` | `:2275` `ctx.inject(['systemPrompt'])` + `section(...)` | `section(section)` 在 | ✅ 兼容 | | `skills` | `:2892` `ctx.inject(['skills'])`、`:2897` `skills.register(...)` | `register(skill)` 在 | ✅ 兼容 | | `commands` | `:2913` `ctx.inject(['commands'])` | 服务在 | ✅ 兼容 | | `tools` | `:2425` `ctx.inject(['tools'])` | `register(definition)`、`get()` 在 | ✅ 兼容 | | `webServer` | `:3136/:3163` `ctx.inject(['webServer'])`、`hostCtx.webServer.register(...)` | `register(route)` 在 | ✅ 兼容 | | `approval` | 审批门经 `dsh-tools` 间接消费 | `request()`、`overrideOf()` 均在 | ✅ 兼容 | | `permissionPresets` | 不直接调用(auto-review 用) | `current()`、`set()`、`overrideOf` 兼容 | ✅ 兼容 | | `sessions` | 仅 `plain()` 内的 `liveSessions()` Map,**非服务** | 服务在;插件未依赖其方法 | ✅ 兼容 | ### 需要特别记一笔的两处 **`sessionQuery.readSurface` 保住了。** 这是插件唯一一处「读别人的会话正文」的能力,用在 `newSession` 交接前自动生成摘要(`maybeWriteHandoffSummary`)。它不在最显眼的几个方法里,若被改名会**静默降级**成「没有摘要、照常交接」——正是 0.13.0 设计里刻意留的失败姿态,但当时没人验证过它在 0.2.1 上还在。**这次确认在。** **`sessions` 服务在 0.2.1 里确实没有 `has()`。** 核查中一度据此判定插件 `:1132` 会抛 `TypeError`,复核后推翻:该行 `sessions` 是 `const sessions = live === undefined ? liveSessions() : live`(`:1099`)拿到的 **`Map`**,`Map.has` 合法。结论是**插件无此问题**,但这条值得记住 —— 服务名与局部变量重名,会让「看代码找不兼容」这件事产生假阳性。 --- ## 三、host 事件核对 来源:`cordis_inspect_query(platform=host, provider=Event, method=listEvents)` | 事件 | 插件用法 | 0.2.1-rc.2 签名 | 结论 | | --- | --- | --- | --- | | `agent/pre-step` | `:2154` waterfall,改注入的消息 | `'agent/pre-step'(this, payload:{agent,messages,turn,step,signal}, next): Promise` | ✅ 未变 | | `agent/turn-stopping` | `:2206` serial,回合结束接续队列 | `'agent/turn-stopping'(this, payload:{agent,turn,signal}): Promise \| void` | ✅ 未变 | | `tools/pre-execute` | `:2411` 审批门 | `'tools/pre-execute'(this, exec: ToolExecution, next): Promise` | ✅ 未变 | | `agent/status` | 未直接监听(靠 `agents.list()` 读 status) | `'agent/status'(this, payload:{agent,status})` | ✅ 无影响 | --- ## 四、会话格式 | 项 | 0.2.1-rc.2 实际值 | 证据 | | --- | --- | --- | | `SESSION_FORMAT_VERSION` | **4** | `dsh/node_modules/@deepseek-ai/dsh-session/lib/index.js:56` | | 写入处 version 字面量 | `4` | 同文件 `:1069`、`:1819` | | 导出符号 | `SESSION_FORMAT_VERSION` 仍在导出列表 | 同文件 `:2052` | → **0.11.2 起的 v4 适配(producer-owned source `plugin:dsh-todo-board`)继续有效,无需再改。** → `tools/check-session-format.mjs` 那套「把消息喂给真 `adoptSessionEvent()`」的守卫,对着 0.2.1 应当仍然有效(第 5 步真机验证时确认)。 --- ## 五、client(浏览器半)核对 来源:`cordis_inspect_query(platform=client, provider=Slots, method=listSubTree)` + client Service 契约 + 内嵌 client bundle 比对 | 依赖 | 插件用法(`client/client.js`) | 0.2.1-rc.2 实际 | 结论 | | --- | --- | --- | --- | | `shell.overlay` slot | `:3243` `ctx.slots.inject('shell.overlay', ...)` | slot 仍在,`kind: list`、`scope: root`,注册参数仍是 `{id, order?, label?}` | ✅ 兼容 | | `useSessions` store 形状 | `:1202` `s.byId` 遍历 | 快照仍是 `{ ids, byId, phase, projectionsBySession }`,**无 `current` 键** | ✅ 与 0.11.4 的修法一致 | | `retainedBy.mainView` | `:1209` `((row.retainedBy ?? {}).mainView ?? 0) > 0` | `mainView` 仍被消费:`dsh-client-ui-layout/lib/client.js` 有 `mainView ?? 0`,workspace bundle 里 8 处、session bundle 里 2 处 | ✅ 兼容 | | 样式 `data-plugin` 标记 | 0.13.1 已给每个 `