更新日期:2026-10-04。目标是提高配置一致性和异常情况下的可靠性。
代码改进覆盖配置并发保护、多协议原子更新、前端草稿与重复提交、生命周期取消、账户缓存、上下文恢复预算、旧 Node 超时兼容和超长同步间隔。累计从 329 个离线用例增加到 352 个,全部通过。
真实 DSH 0.2.0-rc.2 独立 profile 已验证:完整包安装和启动、桥接响应、客户端资源提供及文件变化后的热发布、公共源读取、配置写入、重复同步及重启持久化。公共上游 live 检查通过,未使用有效账户凭据或发起付费模型请求。
最低运行版本已验收:真实 Node 20.0.0 与当前 Node 24 全套 352 个测试通过,零跳过。
尚未验收:浏览器实际渲染与点击及 HMR 重新挂载(本地地址被浏览器工具阻止)、真实宿主运行中卸载、付费长会话恢复。不能据现有结果宣称所有实机验收已完成。
剩余验收的证据要求:
- 页面:切档保存、恢复默认、重复同步及失败重试后的实际显示与宿主配置一致;热更新后没有重复注册或丢失草稿。
- 运行中卸载:真实宿主移除插件后桥接路由和工具消失、搜索选择恢复、当前请求取消;再次挂载恢复正常。
- 长会话:指定有效凭据名称和调用费用上限,在真实模型回合中观察剪枝、压缩、重试、取消及预算重置;不得仅凭模拟服务测试声明完成。
测试服务已停止,独立 profile 留在外层 _recon/runtime-validation 供复核;原用户 profile 未改动。修改尚未提交或发布,包版本仍为 0.7.6。
| 优先级 | 问题 | 改进 | 验证 |
|---|---|---|---|
| P1 | 设置冲突后沿用旧修改列表,可能覆盖用户配置或误删路由 | 每次重试重新读取、检查保护条件、生成修改列表 | 并发创建路由、增加 modelOverrides 的回归测试 |
| P1 | 多协议通道依次写入,后一个失败可能留下半更新状态 | 所有非空通道先检查,再通过一次原子 mutate 写入 | 后一通道冲突时零写入;多通道只提交一次 |
| P1 | 卸载时只清除定时器,正在运行的同步仍可继续写入 | 同步和目录预热关联插件生命周期的取消信号;写入前检查取消 | 卸载中止请求且禁止迟到写入 |
| P1 | 网络发现期间切换配置,旧任务仍会发布旧档位 | 写入前比较配置快照,变化时返回 config-changed;清理前再次检查 | 网络返回过程中切档,零写入 |
| P2 | 日志服务抛异常可能使上下文保护回调失败 | 日志调用单独隔离异常 | 日志抛错时保留宿主步骤结果 |
| P2 | 清理引用提示未排除改名的供应商区,并使用子串匹配 | 根据实际供应商命名空间排除,并匹配完整 key | 改名区和相似 key 回归测试 |
本轮共新增 9 个回归测试,加上原有测试共 338 个,全部通过。 模型路由同步和跨档位清理仍是两个独立事务;清理失败不会撤销成功同步。 生命周期取消无法撤销已提交给宿主设置服务的写入。
- DSH 实机验收:安装、启动、热更新、卸载;确认模型列表、插件卡片、工具注册和搜索选择的实际行为。
- 真实长会话验收:记录 token 压力、剪枝、压缩、重试和取消事件,确认与宿主接口及事件顺序一致。
- 前端交互验收:快速切档、连续保存、刷新过程中关闭卡片、桥接失败后的重新操作。
- 上游兼容性验收:通过显式的 live 验证脚本检查目录、模型和账户响应;使用账户凭据时避免把密钥写入记录。
这些实机项目尚未完成,离线测试通过不代表已验证真实服务或所有 DSH 版本。
- 前端并发用量和状态刷新共享请求,避免启动、点击刷新、可见性事件重复读取账户;新增并发回归测试。
- 卡片控制器卸载时取消桥接请求并清除保存提示定时器;已验证迟到响应不会写入用量和状态。关闭页面是否卸载控制器取决于宿主共享席位的生命周期,不能等同于插件卸载。
- live 验证脚本为公共源和端点探测增加 15 秒超时,端点鉴权检查只接受 401/403,避免把 500/503 当成检查通过。
- 离线测试共 340 个,全部通过;git diff --check 通过。
- 修改后的 npm run verify:live 通过:85 个实时模型、86 项目录;四档路由可生成;账户与搜索端点对无效密钥返回 401;无效密钥分类为 invalid-key。未执行付费模型请求。
- 本机 DSH CLI 为 0.2.0-rc.2。只读运行 dsh --profile web --dump-config-schema,输出中包含本插件,但退出码为 1:条目 /179 至 /182 报 unrecognized Loader tree carrier,并有两项其他字段警告。尚未定位具体条目来源,不能据此证明插件实机兼容。
后续优先定位宿主 Schema 诊断,并核对当前宿主的插件生命周期、事件和配置接口;随后完成实际页面操作及长会话恢复验证。
- 通过当前 DSH 配置树定位 /179 至 /182:分别是 preset-standard、preset-ptc、preset-minimal、preset-cordis,均由 @deepseek-ai/dsh-agent-preset 提供。因此这四项 Schema 导出错误不是本插件条目引起的;本轮未改动这些宿主预设。
- 只读检查本机 app.asar 内的 dsh-compaction-basic 和 dsh-web 源码:agent/pre-step、agent/request-error、compactIfNeeded(agent, trigger, signal)、可写 searchProviderId 和 registerSearchProvider 返回 disposer 仍存在。该检查只证明接口存在,不代替运行验收。
- 宿主的自动恢复在 agent/status=idle 时清空恢复预算。插件此前仅在 assistant/message 时清空,因此失败或取消回合可能影响下一用户回合;现已补齐 idle 清理,并验证 running 不重置、idle 重置。
- 341 个离线测试全部通过。
- 当前 UI 自动化环境没有打开的 DSH 浏览器页面,且不支持原生应用操作;实际页面和付费长会话验收仍未完成。
- 修复保存失败丢失草稿:被拒绝的字段仍保留用户输入和 dirty 状态,允许继续编辑或重新保存;明确点「放弃修改」才恢复宿主值。
- 使用字段级草稿跟踪,普通配置订阅刷新只更新未编辑字段。成功保存时仅清除仍与提交值一致的字段;保存过程中产生的新编辑不会被迟到的读回覆盖。
- 保存期间产生新草稿时不显示「已保存」,创建供应商操作也不会继续使用未提交的新选择。
- 更新拒绝保存的回归用例,并新增等待宿主写入期间修改同一字段的回归测试。
- 342 个离线测试全部通过,git diff --check 通过。
实际页面及长会话验收仍未完成;后续还需检查多次保存重叠和跨字段部分失败场景。
- 保存采用共享提交:连续调用 save 返回同一在途 Promise,避免两组宿主写入互相覆盖;期间的新编辑保留为下一次提交的草稿。
- 只提交当前已编辑字段,避免把未编辑字段的旧快照重新写回宿主;卸载后禁止启动保存,字段写入之间检查生命周期取消。
- 部分保存失败时,只保留失败字段为草稿;重试不会重复提交已经成功的字段。
- 回归测试验证重叠保存共享提交,以及两个字段一个成功一个失败后仅重试失败字段。
- 343 个离线测试全部通过,git diff --check 通过。
后续仍需实际页面验收、真实长会话恢复验收,并检查重复「创建 / 更新」操作的请求一致性。
- 前端重复调用创建/更新或清理共享当前操作;失败后释放在途状态,可正常重新操作;卸载后禁止发起这些操作。
- 宿主同一插件实例的同步、自动同步、桥接清理共享操作锁;重叠调用返回 sync-busy,避免网络读取后交错写入和删除路由。失败时通过 finally 释放锁;卸载后返回 plugin-stopped。
- 测试验证重复动作不重复请求、错误后可以重试,以及宿主同步中拒绝第二次同步和清理、失败后清理恢复可用。
- 345 个离线测试全部通过,git diff --check 通过。
操作锁按插件实例隔离,不是多个进程或多个插件实例的全局锁;跨实例仍依靠宿主 revision 检查及重新生成修改列表。实际页面与真实长会话验收尚未完成。
- 检查当前运行环境,未发现 DeepSeek/DSH 进程,因此没有可直接访问的现有 DSH 页面;实机验收尚需启动合适的测试环境。
- npm 打包预检发现 README 的五张本地截图不在 files 白名单中。现将 assets 和 screenshots.json 加入发布包,修复安装包内文档截图缺失。
- 对照 screenshots.json 逐项检查 npm pack --dry-run 清单:五张图片全部收入包,清单共 19 项。
- 345 个离线测试仍全部通过,git diff --check 通过。
本轮未启动或修改用户的 DSH profile;实际页面及真实长会话验收仍未完成。
- 修复早期 Node 20 缺少 AbortSignal.any 时的账户请求超时失效:取消信号和 15 秒请求上限都被保留,兼容路径在请求结束后清理事件监听器。
- 调用方已取消时不再发起账户网络请求;报告仍按原有降级规则记录失败。
- 新增缺少 AbortSignal.any 的超时回归测试和预先取消时零网络调用的回归测试。测试通过模拟能力缺失验证该分支,尚未在早期 Node 20 二进制上运行。
- 347 个离线测试全部通过,git diff --check 通过。
- 修复账户套餐缓存残留:开始新读取时清除旧缓存,读取失败、缺少凭据或响应不含套餐时不再保留上一次套餐。
- 用读取代次限制缓存更新,仅最新读取可写入缓存,取消或卸载后不提交读取结果。
- 回归测试先读出 Pro 套餐,再让账户端点返回 401,确认 describe 不再报告旧套餐。
- 348 个离线测试全部通过,git diff --check 通过。
缓存代次仅控制状态缓存,不取消已经开始的账户读取。实际页面及真实长会话恢复仍待验收。
- 在工作区外层 _recon/runtime-validation/home 使用独立 DSH_HOME,从官方 web 模板创建 cc-validation profile,并用额外 patch 挂载当前工作区 lib/index.js;没有改动原 web profile。
- 当前 DSH 0.2.0-rc.2 成功启动本地服务,真实 describe 返回 HTTP 200、ok=true,正确报告自定义 entryId、版本 0.7.6、档位和三通道。
- 在独立测试 profile 上执行真实 dry-run:85 个实时模型,GOAT 的 OpenAI 61 个、Anthropic 1 个、Responses 0 个。
- 在独立测试 profile 上执行真实同步:两条供应商均成功创建;随后 describe 确认协议、模型数和显示名正确。仅写入测试配置,没有发起聊天或付费请求。
- 本次验证证明宿主挂载、桥接、公共源读取及 settings 原子写入可以运行;尚未验证浏览器卡片、打包客户端加载、真实长会话或卸载热更新。
- 在独立 cc-validation profile 使用 dsh plugin add link 安装整个工作区包,安装成功;停止此前单独源码挂载的测试进程,按包贡献的 commandcode-goat 条目重新启动成功。
- describe 在完整包挂载后返回 ok=true、entryId=commandcode-goat、version=0.7.6。
- 通过宿主正常的测试令牌登录流程取得仅测试环境的会话,主页返回 HTTP 200,启动页面包含 dsh-commandcode-goat。
- 按启动页实际声明的带 rev 资源地址读取客户端代码,单插件与组合资源均返回 HTTP 200,包含本插件的 ModuleLoader 注册工厂。无 rev 的猜测地址返回 404 是宿主版本资源索引行为。
- UI 自动化打开 localhost 测试地址被工具返回 ERR_BLOCKED_BY_CLIENT;没有绕过该限制。因此客户端资源可加载已验证,浏览器执行、卡片渲染、点击操作仍未验证。
- 测试 Web 服务仍在独立环境运行;没有付费模型调用,没有更改原用户 profile。
- 在完整包安装的独立 profile 连续执行两次同步,两次均成功,两个通道均返回 created=false;describe 始终仅有两条已创建通道。
- 停止并重新启动同一独立 profile,未执行新的同步,describe 已读出两条持久化供应商:OpenAI 61 个模型,Anthropic 1 个模型,协议和显示名均正确。
- 验证结束后停止本次测试服务,保留独立测试配置作为复核材料。未修改原用户 profile,未发起付费模型请求。
- 可视化页面交互仍受浏览器工具 ERR_BLOCKED_BY_CLIENT 限制;真实付费长会话、热更新和运行中的卸载恢复仍未验收。
- 修复可选服务卸载后仍被 volatile-update 调用的问题:工具和搜索注入清理时移除其回调引用,避免工具被重新注册到旧服务、旧搜索选择被再次占用。
- 清理采用回调身份检查,旧注入的清理不会清除新注入已安装的回调。
- 搜索服务卸载后,状态报告不再声称该供应商仍已注册。
- 回归测试模拟可选服务 effect 清理后继续收到配置事件,确认工具不复活、原搜索选择不改变。
- 349 个离线测试全部通过,git diff --check 通过。该测试覆盖生命周期逻辑,仍不等同于真实 DSH 热更新验收。
- 修复自动同步间隔超过原生定时器最大延迟(2^31-1 毫秒,约 24.9 天)时可能被 Node 缩成 1 毫秒的问题。
- 调度器分段等待,保持原配置的总间隔,不通过缩短用户间隔规避溢出;每段检查停止状态。
- 模拟时钟验证:首次创建后等待最大分段不会同步,剩余分段走完才再次同步。
- 350 个离线测试全部通过,git diff --check 通过。
- 账户用量读取关联插件卸载信号、调用方取消信号及整次读取的 60 秒上限;各账户端点原有的 15 秒上限仍保留。
- 卸载时中止当前账户请求,后续账户端点不会继续访问,也不会把取消后的结果提交到套餐缓存。
- 回归测试在第一个账户请求期间清理插件 effect,确认请求已取消且只发起一次网络请求。
- 351 个离线测试全部通过,git diff --check 通过。真实浏览器交互、宿主热更新及付费长会话验收仍未完成。
- 修复恢复默认异步返回后无条件清除字段草稿的问题:仅当字段仍是操作开始时的值,才清除草稿;新编辑保持 dirty,可随后保存。
- 卸载后禁止启动恢复默认操作。
- 新增恢复默认等待宿主期间输入新地址的回归测试,确认新输入未丢失。
- 352 个离线测试全部通过,git diff --check 通过。真实浏览器交互、热更新及长会话验收仍未完成。
- 从 npm 提供的 Node 包运行真实 Node 20.0.0,确认版本号。
- 原测试脚本使用 tests/**/*.test.mjs,Node 20.0.0 不展开该 glob,直接报找不到文件。新增 tests/run.mjs 枚举测试文件并传给同一 Node 二进制,避免依赖运行时的 glob 功能;npm test 已改用该入口。
- 当前 Node 24 上 352 个测试通过;真实 Node 20.0.0 上账户模块 34 个测试通过,包括取消和超时兼容分支。
- Node 20.0.0 的全套显式文件运行未及时结束,已停止本轮启动的测试进程;尚不能宣称旧版本全套通过,后续需定位挂起文件及测试工具兼容问题。
- 长会话所需的凭据名称和费用上限仍待用户提供。
- 逐文件运行定位旧 Node 挂起:前端/宿主后台定时器保留进程,自动同步测试依赖 Node 20.0.0 尚无的 mock.timers。
- 在 Node 环境为后台定时器调用可选 unref;实际 Web 服务和活跃请求仍保持进程,后台定时器自身不再阻止正常退出。浏览器数值定时器不受影响。
- 为早期 Node 的测试提供 setTimeout/clearTimeout 模拟兼容层;新 Node 继续使用原生 mock.timers,没有跳过定时器测试。
- 真实 Node 20.0.0 与当前 Node 24 的完整 352 个测试均通过,零跳过,正常退出。此前最低版本全套未验证事项已解决。
- 将包和依赖复制到独立测试目录,测试 profile 改为链接该副本。最初未复制依赖时宿主报 failed to import;复制包依赖后正常启动。原工作区文件未做临时修改。
- 从真实启动页面声明的资源 URL 获取客户端代码作为基线;在副本客户端末尾增加无行为的测试注释,宿主随即发布不同 rev 的资源,代码哈希改变且新内容包含标记。
- 恢复副本原始客户端,文件哈希与工作区原件一致。立即请求仍读到上一代带标记资源,未等待恢复事件完成即停止服务,因此没有证明恢复时的第二次热发布;测试 profile 链接已恢复到原工作区。
- 已证明实际宿主文件监视和资源版本发布正常;尚未证明浏览器接收 HMR 事件后重新挂载卡片的行为。
- 未使用有效账户凭据或付费模型调用。页面交互、运行中卸载及真实长会话恢复仍待验收。