Skip to content

Releases

0.2.3

Choose a tag to compare

@xiaoso456 xiaoso456 released this 09 Oct 05:35

Added

  • 插件图标与 README 词标(品牌资产):assets/ 新增插件页图标 icon.webp(448、圆角 104、WebP 无损,由 1254² 母版按黄金比例裁框而来,205 KiB)、README 头图 icon-full.webp(整幅不裁)与词标 wordmark.png(Jua 400,三色 #4d6bfe / #37b3cb / #e0a93f)。package.json 顶层 icon 指向 assets/icon.webp,files 同时收进 icon-full.webp 与 wordmark.png——README 引用了它们,不进包则 npm 包页面上的两张图会 404。两份 1254² 母版(icon-source.png / icon-art.png)入库但不进包
  • 两版 README 的居中排头:开头改为居中「icon-full.webp(宽 140)+ wordmark.png(宽 360)」并去掉 H1,正文不变;中英两版同步

Fixed

  • 命令任务不再被 shell 执行器的默认截止时间杀掉:shell.resolve 现在显式传 onExpiry: 'none'。此前它没传,于是落到执行器默认值(PwshLocalExecutor / LocalBashExecutor 的 onExpiry: request.onExpiry ?? 'kill' + timeoutMs 默认 120000),任何超过 2 分钟的命令任务都会在第 120 秒被 deadline 杀掉,且因为 killed 一律被映射成不带 detail 的 { status: 'killed' },在会话里只表现为一句 finished [status: killed]、job_output 空空如也,完全看不出原因(真机实例:pi-agent 的「Build Gateway Binaries」两次被杀,间隔精确 120s)。背景作业本就不该受执行器 deadline 约束——官方 dsh-tool-bash / dsh-tool-pwsh 在后台分支同样显式传 onExpiry: 'none',只由作业自身生命周期(cancel / owner 回收 / 服务 teardown)决定何时结束。注:这是 dsh 0.1.7 的官方回归——0.1.5/0.1.6 的 shell.start() 后台路径本就注释写明「Background runs ignore timeoutMs」,0.1.7 的 d6bebc5783 把 run()/start() 合并为 execute() 并引入 onExpiry(默认 kill)后,后台不再豁免(该提交自述 "the 'start ignores timeoutMs' wart dies")。我们插件迁移 0.1.7 时只换了 API 名、没跟上默认语义
  • cancel 现在也能中断「准备阶段」:作业持有自己的 AbortController,signal 随 spec 交给执行器;cancel 先 controller.abort(reason) 再对已存在的句柄 kill()。此前 cancel 只能对已解析的 ShellExecution 调 kill(),若 kill 请求到达时进程尚未 spawn 完成(慢启动 / 受限模式下的 confine 准备),这次取消会整个丢失。受限执行器在准备阶段被 abort 时会 reject execute(dsh-pwsh-sandbox 的 mapError 在 spec.signal.aborted 时重新抛出),该分支按官方 processJob 的口径映射为 killed 而非 failed
  • killed 的起因不再被抹平:{ status: 'killed' } 现在带上 signal: <SIG>(或 killed before exit),于是「deadline 杀 / 用户 job_kill / owner 回收」在通知里可区分。刻意不回显 killedReason——dsh-jobs-local 结算时本就会把它追加进 detail(killJob → ${detail}; ${killReason}),回显会得到 user stopped it; user stopped it
  • 任务写入边界加固:type / scope 现在经运行时白名单校验(RPC 参数、工具 schema 的 enum、validateTaskInput 三处),并在存储边界再校验一次。此前非白名单值会被原样写进存储,而存储层只在 open 时解析记录——一次坏写就会让下次 open 失败、openTaskStore(apply 的第一句)抛错、整个插件起不来且没有任何 UI 路径可修复
  • 命令任务验收脚本不再因侧边栏时序而假红:tests/cdp-pwsh.mjs 开侧边栏后固定等 800ms 就取会话行,而大会话库的 profile 此刻项目行已渲染、会话行尚未加载完,选择器落空后回退到 rows[0](项目行)→ 点它进的是工作区而非会话 → 脚本在创建任务前就退出。改为轮询等待真实会话行出现再点击

Changed

  • 插件显示元数据:新增 locale/en.json + locale/zh.json(meta.title / meta.description)与 package.json 的 ./locale/*.json 导出——官方 readPluginMeta 会在插件管理界面显示中英标题与描述(格式与 dsh-schedule 等官方包一致,已用官方读取器实测)
  • 客户端渲染开销与竞态:RunControl 的任务分组改为 useMemo,pendingRun 交接查找改用当前工作区可见集(visibleTasks)而非全量列表,并对依赖数组补全(工作区/任务变化会重新定位可操作目标)
  • 纯逻辑抽离:hero 运行目标判定抽为 core/heroRun.ts、语言上报抽为 core/localeReport.ts(无 React、无浏览器 API,可单测)

说明

  • 真机验收(2026-10-08,独立 profile + 端口 3191,未动 3190):同一台真机、同一个真 SandboxPwshExecutor、同样配 8s deadline 的 A/B——旧形状(不传 onExpiry)下 20s 命令 status=killed、timedOut=true、8.0s 被砍;修好后同样 20s 命令 status=completed、exit=0、跑满 20.6s。完整插件链路(真实例 tasks/run,与 ▶ 按钮同路径)40s 命令在 8s deadline 下 elapsed 42s 且 marker 按时写出 → PASS
  • e2e 验收套件(13 个 cdp-*.mjs,每脚本独立 profile + 独立调试端口):10 PASS / 1 SKIP(按设计)/ 2 FAIL,两个 FAIL 均已定位为非插件回归——cdp-header-order 单独重跑 PASS(抖动);cdp-pwsh 为上述侧边栏时序缺陷,修复后连跑 PASS
  • 自测:tsc --noEmit 0 诊断 · 139 单测全过(command-runner.spec.ts 5→9 条;新增 hero-run 7 / task-write-boundary 6 / locale-report 3)· biome check 0 error · tsdown 0 · build:types 0
  • 环境提示:本机 workspace-write 模式下无可用沙箱后端,命令任务会以 [status: failed, exit code: 127] 失败(看着像命令不存在,实为沙箱拒绝运行);真机跑命令任务请用 DSH_PERMISSION_MODE=danger-full-access
  • 插件图标的接线方式与硬约束:图标经 package.json 顶层 icon 字段发布——实测已安装的 dsh 0.2.0-rc.2 的 iconOf 只认该字段,没有 ${specifier}/icon 导出的解析路径(后者是 0.2.1-alpha 之后才加的),故只加导出在现运行时无效。约束是硬的:相对路径、realpath 后必须留在包目录内、普通文件、≤256 KiB,违反任一条会直接抛错并在插件页显示 metadata error(不是静默回落到默认图标)。旧版根目录 icon.png 已无任何引用(仍在 .gitignore 中)

0.2.2

Choose a tag to compare

@xiaoso456 xiaoso456 released this 29 Sep 12:51

[0.2.2] - 2026-09-29

正式版,发布在 latest。适配 dsh 0.2.0-rc.2。与 0.2.1 互不兼容(peer 精确写死,运行时版本不一致就会被官方闸门禁用):dsh 0.2.0-rc.1 线继续用 0.2.1,0.1.7 线用 0.2.0。

Changed

  • 适配 dsh 0.2.0-rc.2:33 个 dsh devDependencies 与 13 个 peerDependencies 由 0.2.0-rc.1 精确改到 0.2.0-rc.2;pnpm-workspace.yaml 的发布年龄白名单同步加白。零业务代码改动——逐包核对官方 rc.1→rc.2 的 187 个提交(630 个文件)后确认本插件用到的契约全部未变:实质源改动只有 IconThinkOutline* 的图形微调、新增 MenuGroup 组件、ui-renderer 的一处 hooks 顺序修复、ui-workspace 把重命名快捷键从 Ctrl+Alt+R 改成 Ctrl+Alt+G、api/remotes 多挂一个新包 dsh-user-questions
  • 验收脚本参数化:6 个仍写死 http://127.0.0.1:3190 的 tests/cdp-*.mjs 改为读 DSH_BASE(12 个脚本口径一致;3190 被其它实例占用时一样能验收)
  • tests/cdp-llm-run.mjs 补上 hero「先绑定工作区」前置:未绑定工作区时点运行只会把 prompt 填进草稿、无法提交,send 分支会因此假红(实测 3/3 确定性失败,先在 hero 选好工作区即恢复正常);菜单选择同时改为「点开即读 + 重试」(菜单卡会被「工作区/任务列表落地」关掉,一次性 sleep 会错过窗口)

说明

  • 真机验收(全局 CLI 0.2.0-rc.2 + 独立 profile 端口 3191 + 全新 profile 的 headless Chrome):插件加载零错误(闸门通过);e2e-crud 8 个 RPC 端点全通并自清理;client bundle 到达 HTTP 200;cdp-refresh / cdp-header-order / cdp-workspace-select / cdp-combo / cdp-llm-run(send 与 fill 两分支)/ cdp-double-run / cdp-config-description-clear / cdp-shot 全过、console error 0
  • 自测:tsc --noEmit 0 诊断 · 109 单测全过 · biome check 0 error · tsdown 构建 0 · build:types 0;官方 API 触点逐符号核验 63/63(含 15 个纯副作用导入可达)
  • 数据无迁移:任务仍在 $DSH_HOME/storages/task_runner.json(domain task_runner),RPC 端点、工具名、locale、slot 挂载点均未变

说明

  • 与 0.2.1 互不兼容:本版 peer 精确写死 0.2.0-rc.2,0.2.1 写死 0.2.0-rc.1;官方闸门按 semver.satisfies(runtime, range, { includePrerelease: true }) 判定,运行时版本不一致的那一版会被禁用。dsh 0.2.0-rc.1 线请继续用 0.2.1,0.1.7 线用 0.2.0,0.1.5 线用 0.1.5
  • 适配本身零业务代码改动:官方 rc.1 → rc.2 的 187 个提交里,本插件用到的契约全部未变
  • 数据无迁移:任务仍在 $DSH_HOME/storages/task_runner.json(domain task_runner),RPC 端点、工具名 task_run_config、locale 命名空间、slot 挂载点均未变
  • 自测:tsc --noEmit 0 诊断 · 109 单测全过 · biome check 0 error · tsdown 构建 0 · build:types 0;官方 API 触点逐符号核验 63/63(含 15 个纯副作用导入可达)
  • 真机验收(全局 CLI 0.2.0-rc.2 + 独立 profile 端口 3191 + 每脚本全新 headless profile):插件加载零错误(闸门通过);e2e-crud 8 个 RPC 端点全通并自清理;client bundle 到达 HTTP 200;cdp-refresh / cdp-header-order / cdp-workspace-select / cdp-combo / cdp-llm-run(send+fill)/ cdp-double-run / cdp-config-description-clear / cdp-shot 全过、console error 0
  • 本轮顺带修了验收工具本身:6 个仍写死 3190 的 cdp 脚本改为读 DSH_BASE;cdp-llm-run 补上 hero「先绑定工作区」前置(未绑定时 send 分支假红)

对比 0.2.1

0.2.1

Choose a tag to compare

@xiaoso456 xiaoso456 released this 28 Sep 15:41

[0.2.1] - 2026-09-28

正式版,发布在 latest。首个适配 dsh 0.2.0-rc.1 的版本。版号取补丁位是有意的破例(维护者拍板):本版把 13 个 dsh peerDependencies 精确写死为 0.2.0-rc.1,因此在 dsh 0.1.7 线上会被官方闸门禁用——对使用 ^0.2.0 的环境而言,这等于「补丁号里含破坏性变更」,按 semver 本应是 0.3.0。升级前请确认运行时就是 0.2.0-rc.1。本版同时收进 0.2.0 之后未发布的运行控件 UI 迭代(窄视口、加载三态、拖拽、连点门、保存提示等)。

Added

  • 新增 client 侧纯函数模块(无 React/浏览器 API,可单测):core/createInput.ts(对话框「新增」的作用域推导)、core/pendingRun.ts(hero → 会话的待运行交接规则)、core/firstVisibleTask.ts(对话框打开时的默认选中)、core/taskListState.ts(列表「加载中 / 空 / 失败」三态推导)、core/draft.ts
  • 新增 UI 组件:components/Spinner(加载态转圈,尊重 reduced-motion)、components/TaskListNotice(加载中 / 加载失败的行内提示)
  • 新增验收脚本与基础设施:tests/lib/{cdp-endpoint,cdp-chrome-launch,web-session}.mjs(CDP 端点可覆盖、私有 headless Chrome 启动、launch token 换会话 cookie 与 RPC 调用)、tests/cdp-{reorder,saved-hint,double-run,config-description-clear,hero-add-workspace}.mjs、tests/external/(外部依赖验收通道:本地 mock provider + 编排脚本)
  • 新增单测:tests/{create-scope,draft,pending-run,store-upsert,task-update-patch,ui-state,vitest-collection,acceptance-tooling}.spec.ts

Changed

  • 适配 dsh 0.2.0-rc.1(npm next 线):插件版号 0.2.0 → 0.2.1。33 个 @deepseek-ai/dsh-* devDependencies 与 13 个 peerDependencies 全部对齐 0.2.0-rc.1,且 peer 精确写死(不写 ^)。本轮零业务代码改动(证据见 docs/决策记录.md D31):tsc --noEmit 0 诊断、109 单测全过、biome check 0 error、tsdown 构建 0、build:types 0;官方 API 触点逐符号核验 63/63 解析到 0.2.0-rc.1 的真实声明(含 15 个纯副作用导入可达);宿主真实包验证 verify-skill / verify-tool-schema / verify-pwsh 全过。逐包核对官方 packages/**/src 后确认本插件用到的表面全部未变——jobs / shell / tools / storage-domain / skill / settings / client-connection / client-locale / client-ui-settings / client-ui-slots 等包在 0.1.7-rc.2 → 0.2.0-rc.1 之间只改了 package.json 的版本号(源码逐字节相同);客户端契约的改动全是可选新增(SessionInput.submit(mode?, source?)、ISessions.fork({onCreated?})、UiWorkspace.forkSession(id, onCreated?)),本插件的调用点都不传这些新参数

  • peer 精确写死的已知后果(用户要求,接受):官方插件版本闸门是 semver.satisfies(runtimeVersion, range, {includePrerelease:true})(官方 packages/boot/app-boot/src/plugin-compatibility.ts:77,0.1.7-rc.2 → 0.2.0-rc.1 之间该文件无改动)。写死版本意味着运行时只要不是 0.2.0-rc.1(如 0.2.0-rc.2、0.2.0 正式版、0.2.1),插件行会被禁用,需要配套发新版,或用 dsh plugin allow-version 做精确版本豁免

  • 真机验收(dsh 0.2.0-rc.1,独立测试 profile + 端口 3190):插件加载零错误(闸门通过);8 个 RPC 端点 CRUD 全通并自清理;client bundle 到达 HTTP 200;cdp-refresh / cdp-header-order / cdp-workspace-select / cdp-combo / cdp-double-run / cdp-config-description-clear / cdp-llm-run / cdp-hero-llm / cdp-shot 全部通过。4 个红灯(cdp-pwsh / cdp-reorder / cdp-saved-hint / cdp-hero-add-workspace)逐条定位为验收脚本自身的时序与下标选择器问题,以及双服务共享 ~/.dsh 导致的 no live agent(D15/D29 既有现象)——未发现插件侧回归;脚本侧修法记入 docs/决策记录.md D31 待办

  • task_run_config 的 scope 默认值改为 workspace(原为 global):不传 scope 时落到当前会话的工作区(路径从会话 cwd 推断),拿不到会话工作区时报错失败关闭,不再静默创建对所有工作区可见的全局配置——工具描述与 skill 正文一直这么声明,此前实现与文档相反

  • 运行配置对话框的「新增」按钮改为在当前工作区新建配置(原硬编码 scope: 'global'):与工具默认值、以及对话框「全局 / 当前工作区 / 其他工作区」的分组语义一致;连当前会话 cwd 与已注册工作区都取不到时拒绝创建并提示保存失败,不再退化成全局配置

  • 文案/契约修正:命令任务字段提示改为「在当前会话的工作目录执行(会话没有工作目录时用任务所属工作区)」(原写「任务配置所属工作区」,与会话 cwd 优先的实现不符);hero 页无可用工作区时的提示改为「请先选择一个工作区」(原误用「没有可见任务运行配置」);「复制」按钮的提示/无障碍名写明产生的是同名副本(可在右侧改名);tasks/run 端点删除无人消费的 locale 参数

  • @deepseek-ai/dsh-skill 正式纳入 peerDependencies(^0.1.7-rc.2,与其它 12 个 dsh peer 写法一致;devDependencies 的安装声明保留):skills 本来就是插件的硬服务(inject 里一直有 skills),此前 src/host/skill.ts 因缺该包的类型合并而用结构 cast 注册 ctx.skills.register,字段漂移 tsc 发现不了;现在直接走官方的 SkillRegistration 类型(src/index.ts 补一行 type-only merge),改字段名/加必填字段会立刻编译报错。锁文件无需改动:pnpm v9 的根 importer 只记录 dependencies/devDependencies,不记录 peer 声明(install --lockfile-only 后 pnpm-lock.yaml 字节不变)

Fixed

  • 修复窄视口(≤640px)下 hero 运行控件行溢出、官方的「标准模式」被静默裁掉:插件的组合控件 min-width: auto 解析成自身的 max-content(190px),所以官方 hero 工作区行(display: flex 且不换行的固定行)拒绝收缩我们,直接把排在后面的官方「标准模式」推出视口(实测 414px:行 clientWidth 351 / scrollWidth 393,官方控件右边界 x=449 > 视口 414,且 bodyScrollWidth=414 连横向滚动条都没有)。现在窄视口允许组合控件收缩(任务名走省略号),把空间让回官方控件——1440/768 与修复前逐像素一致,414/375 三档溢出归零、视口内无被裁元素
  • 修复窄视口下对话框关闭按钮越界 10px:@media (max-width: 640px) 里同时把 .modalContent 设成 calc(100vw - 24px),比官方卡片(被 24px 内边距盒压到 366px)宽 24px,把卡片头部的关闭按钮推到卡片右边界之外(实测按钮右边界 400 > 卡片 390,而桌面端间距是 14px);现在只约束卡片自身宽度,内容宽度交回官方的 .content { width: 100% },窄屏间距与桌面端一致为 14px
  • 修复对话框右栏「可滚动但看不出来」:该运行时用的是覆盖式滚动条(实测保留宽度恒为 0px,scrollbar-width/::-webkit-scrollbar 都不改变这一点),所以 clientHeight 258 / scrollHeight 523 的右栏看上去"表单到此为止"。现在右栏加上随滚动位置出现的上下缘渐变提示(实测:停在顶部时下缘亮度 233 vs 内部 255,滚到底后上缘 225 而下缘恢复 255),滚动条本身也按主题着色
  • 修复任务列表把「加载失败」说成「没有配置」:加载中与空态文案原本完全相同、tasks/list 失败后 toast 4 秒消失就只剩「没有可见任务运行配置」。现在 store 记 tasksStatus/loadError,三态在文案与呈现上都分开:加载中=转圈 +「正在加载任务运行配置…」、确实为空=「没有可见任务运行配置」、加载失败=警示图标 +「任务配置加载失败」并保持到重新加载成功(hero 与会话头部控件、两处下拉、对话框左右栏统一;中英 locale 同步;刷新已加载缓存时保持原有措辞,避免空列表在每次重拉时闪一下"加载中")
  • 修复运行按钮 tooltip 拆断任务名:气泡宽度上限 280px 小于「在当前工作区运行任务配置「{name}」」这句固定模板(约 182px)加常见任务名,把专名硬断成「拉取并合并远程分 / 支」;上限改为 400px 后实测 294×46(两行)→ 313×26(一行),且官方 Tooltip 的视口钳制保证窄屏仍不出界
  • 修复打开运行配置对话框时不默认选中任何条目:左栏有 9 条配置、右栏却是空态「暂无任务配置」,而同一 store 状态下 hero 的组合控件会回落到第一条。现在按左栏渲染顺序(全局 → 当前工作区 → 其他工作区)默认选中第一条可见配置(纯函数 core/firstVisibleTask.ts),已存在且仍有效的显式选中(如会话头部"编辑该配置")原样保留
  • build:types 先清空 lib/types 再生成:tsc -p tsconfig.build.json 不清理输出目录,源码目录重构后旧路径的声明文件会一直留在产物里(0.2.0 的发布包里就混进了 8 个 lib/types/client/*.d.ts 扁平旧路径的陈旧声明),现改为生成前先 rmSync('lib/types'),清理后重新编译的产物是 29 个声明(exports 引用的声明路径不变)
  • 修复运行配置列表跨分组拖拽写进无意义的顺序:onDrop 用持久化数组(taskOrder)的索引算 from/to,而用户拖的是分组渲染出来的行(全局 → 当前工作区 → 其他工作区),两个序列不同源——把一个组里的配置拖到另一个组的上方,实际写进的是「顺序没变」或「另一组错位」的结果,屏幕上那行纹丝不动,而 taskOrder 已经变了。现在跨组 drop 直接忽略,只有组内拖拽会写顺序(合成拖拽实测:改前跨组后 [W1,G2,G1,W2]→[G2,W1,G1,W2],改后保持不变,组内拖拽仍生效)
  • 修复切换 scope/type 后记录里残留上一个语义的字段:validateTaskInput 现在按新的 scope/type 落地字段(workspacePath 只在 scope=workspace、llmPrompt/autoSend 只在 type=llm、command/notifyLlm 只在 type=command),TaskStore.update 也不再以 {...current} 打底,丢掉的键不会被旧值复活。此前 scope 从 workspace 改成 global 后记录仍带 workspacePath、type 从 llm 改成 command 后仍带 llmPrompt/autoSend——表单里没有任何字段能显示或改掉它们,模型可见的 list 输出却照实报告。副作用(有意):把配置切回 scope=workspace 时必须显式给 workspacePath(对话框本来就每次都发,工具参数说明也这么写),否则报错失败而不是静默复用旧路径
  • 修复同一配置在 2 秒内保存两次时「已保存」提示提前消失:提示状态原为布尔量,第二次写成功后 setSaved(true) 不改变 effect 依赖,2 秒计时器不重启——第二次保存的提示按第一次的剩余时间消失(实测 841ms 就没了,用户会以为没保存上)。现在改用递增计数(0 表示无提示),每次保存各自计时(实测 2081ms),换选中项时仍立即清除
  • 修复会话头部运行按钮在同一 tick 内连点会重复启动命令任务:runTask 原来只用 busy state 做门,同一 tick 内的多次点击读到的都是刷新前的状态(实测连点 3 次发出 3 个 tasks/run,即 3 个后台进程)。现在加同步 ref 门(与 hero「创建工作区」的 createGate 同一写法),3 次点击只发 1 个请求;llm 分支是同步填充输入框,不受影响

说明

  • 版号说明(有意的 semver 破例):本版把 13 个 dsh peerDependencies 精确写死为 0.2.0-rc.1(不写 ^),因此在 dsh 0.1.7 线上会被官方闸门禁用——对写 ^0.2.0 的环境而言,这等于「补丁号里含破坏性变更」,按 semver 本应发 0.3.0。维护者明确选择补丁号,升级前请确认运行时就是 0.2.0-rc.1
  • 闸门语义:官方按 semver.satisfies(runtimeVersion, range, { includePrerelease: true }) 判定。写死版本意味着运行时只要不是 0.2.0-rc.1(例如 0.2.0-rc.2、0.2.0 正式版、0.2.1 及以后的 dsh 版本号),本插件的行就会被禁用:需要配套发新版,或用 dsh plugin allow-version 做精确版本豁免
  • dsh 0.1.7 / 0.1.5 线请分别继续使用插件 0.2.0 / 0.1.5
  • 数据无迁移:任务仍在 $DSH_HOME/storages/task_runner.json(storage domain 名 task_runner),RPC 端点、工具名 task_run_config、locale 命名空间、slot 挂载点全部未变
  • 依赖适配本身零业务代码改动:官方 0.1.7-rc.2 → 0.2.0-rc.1 之间,本插件用到的包(jobs / shell / tools / storage-domain / skill / settings / client-connection / client-locale / client-ui-settings / client-ui-slots 等)源码逐字节未变,客户端契约的改动全是可选新增参数
  • 自测:tsc --noEmit 0 诊断 · vitest run 18 文件 / 109 用例全过 · biome check 0 error · tsdown 构建 0 · build:types 29 个声明;官方 API 触点逐符号核验 63/63(含 15 个纯副作用导入可达)
  • 真机验收(全局 CLI 0.2.0-rc.1 + 独立测试 profile 端口 3190 + 每脚本全新 profile 的 headless Chrome):插件加载零错误(闸门通过);8 个 RPC 端点 CRUD 全通并自清理;client bundle 到达 HTTP 200;cdp-refresh / cdp-combo / cdp-header-order / cdp-workspace-select / cdp-double-run / cdp-config-description-clear / cdp-llm-run / cdp-hero-llm / cdp-shot 全过、console error 0;另产出 14 张功能验收截图
  • 已知环境问题(与插件无关):验收机 DeepSeek API 额度用尽;测试实例与桌面版共享 ~/.dsh,被查看的会话的 live agent 属另一个进程,命令任务无法在浏览器内跑到最后一步(cdp-pwsh 因此为红灯,插件正确地呈现为「运行失败:no live agent for session …」)
  • 4 个红灯验收脚本(cdp-pwsh / cdp-reorder / cdp-saved-hint / cdp-hero-add-workspace)的成因均为脚本自身的时序与下标选择器,修法记录在 docs/决策记录.md D31,尚未落地

对比 0.2.0

0.2.0

Choose a tag to compare

@xiaoso456 xiaoso456 released this 28 Sep 15:41

[0.2.0] - 2026-09-26

正式版,发布在 latest。首个适配 dsh 0.1.7 线的版本。此前为验证打过的本地预发布号 0.2.0-beta.1 未发布,其内容已并入本节。

Added

  • tests/cdp-llm-run.mjs:新建会话 → 选中 LLM 任务 → 点运行 的端到端验收脚本,覆盖 autoSend 两条分支(send 断言消息进入会话且输入框被提交清空、fill 断言 prompt 只留在输入框不提交),每轮用唯一标记防止读到上一轮会话内容造成的假阳性
  • tests/rpc-route.spec.ts 的 tasks/create 字段转发回归用例(autoSend: false / description / notifyLlm: false)
  • CHANGELOG.md(本文件)

Changed

  • 适配 dsh 0.1.7 线(0.1.7-rc.1 起):44 处 @deepseek-ai/dsh-* 由 0.1.5-rc.1/0.1.7-rc.1 对齐到 0.1.7-rc.2,@deepseek-ai/cordis 由 ^4.0.2 改 ^4.0.4(Volatile 类型所在版本)、@deepseek-ai/schemastery 由 ^3.18.1 改 ^3.18.4(.volatile() 所在版本);peerDependencies 全部抬到 ^0.1.7-rc.2
  • 设置面从「运行时注册命名空间」改为「插件自己的 Config」:dsh 0.1.7 删除了整个 SettingsProvider/SettingsScope/SettingsApplies 与 settings.register(ns, schema, …)(连 settings-file 包一并删除),改为把插件条目自身的 Cordis Config 投影成表单。现在 toolEnabled 是 Config 上的 .volatile() 字段,由官方设置表单按 profile 条目 id task-runner 读写,写入落到当前 profile 的 cordis patch(用户补丁层在插件升级后依然保留)
  • 配置变更的监听方式随语义变化:.volatile() 写值是原地替换引用、不会重跑插件(官方 packages/boot/hmr 的用例可证:entry.update({config}) 后 apply 不重入,但同一个引用立刻返回新值),因此开关变更改由 settings/document-updated 事件触发重新同步工具注册,而不是靠插件重载
  • 客户端设置改走共享配置表单:ctx.settingsScope.bind({namespace}) → ctx.configForms.get('task-runner'),类型 SettingsScope<T> → ConfigForm<T>;set/unset/mutate 的返回值由 Promise<void> 改为 Promise<boolean>(宿主拒绝返回 false 而不再 reject),运行设置弹窗对拒绝补上保存失败提示
  • 命令任务执行迁移到 shell.execute:dsh 0.1.7 移除了 ShellExecutor.start(),改为 execute(spec): Promise<ShellExecution>;作业的 run 钩子必须同步返回 hooks,所以在钩子内捕获 spawn promise 并投影(cancel 对已解析的句柄调 kill,spawn 失败交由注册表判 failed)。readOutput()/status/exitCode/kill()/done 未变
  • 后台作业契约迁移到 0.1.7:JobSnapshot → JobView;JobSpec.owner 由 Agent 改为 SessionId;JobOutcome.output → result(job_output 仍可读到全量输出,本插件刻意不设 outputLimitBytes 的行为不变);抑制官方通知的 JobView.reported 标记取消,改为 settled 事件的 awaited(释放了一个 live wait 即为 awaited,官方 tool-jobs 会跳过这类结算)
  • 完成通知的 message source 改为插件自声明 kind:0.1.7 移除了通用的 plugin kind,每个生产者要在自己模块里声明(MessageSourceMap 合并 'task-runner')。通知正文与抑制机制不变,仍是「挂一个 jobs.wait 抑制官方 tool-jobs + 自己发一条逐字对齐的通知」
  • 图标改用 0.1.7 的中性命名:Icon*Outline14/16 → Icon*OutlineMedium/Regular(原 14px=1.3px 笔画 → Medium,原 16px=1px → Regular),涉及 13 个图标、73 处引用;显式 size 属性全部保留,尺寸表现不变
  • 会话选择改用官方替代选择器:SessionListState.current 在 0.1.7 被移除,运行设置弹窗改用官方同款写法(Object.values(state.byId).find(s => (s.retainedBy.mainView ?? 0) > 0),见 ui-layout 的 DocumentTitle 与 ui-settings-general 的 SettingsRoot)
  • AGENTS.md 补 Windows 无 shim 的运行方式:本机 pnpm 是 pnpm.cmd 脚本,每条 pnpm <script> 都会拉起一个可见的 cmd.exe(用户在电脑前会看到控制台窗口一闪而逝),改列 node node_modules/{typescript/bin/tsc,vitest/vitest.mjs,@biomejs/biome/bin/biome,tsdown/dist/run.mjs} 直跑入口,并约定不再使用 powershell

Fixed

  • 修复 hero 页新建会话后点运行、LLM 任务发不出去:connectWorkspace 成功后落到的是空会话,而空会话不渲染会话头部 —— 挂在待运行槽里的任务没有任何组件消费,命令被静默丢弃(表现是点了运行毫无反应,控制台也没有报错)。现在 hero 直接通过官方的会话级输入面执行标准发送流程:ctx.sessions.binding(sessionId).ctx → ctx.conversation.input.for(该 ctx) 取到该会话的 SessionInput,用 setDraft + submit 完成「填入 + 发送」(这正是会话头部 RunControl 拿到的同一套 InputActions);绑定尚未就绪时按 10×200ms 重试,仍取不到才回退原来的待运行槽
  • 修复 新建任务时 autoSend 与「描述」字段被丢弃:tasks/create 端点是逐个手写字段转发给存储的,漏了 autoSend 和 description 两个(tasks/update 走整包 patch,因此一直没暴露)。后果是新建 LLM 任务时「运行后直接发送」开关不生效(一律直接发送,用户以为开关坏了)、描述字段也存不下来。已补齐两个字段,并在 tests/rpc-route.spec.ts 增加回归用例锁住(false 必须原样透传,不能写成真值判断)
  • 删除 hero 页读取 ctx.sessions.currentProvideInfo 的死路径:该成员在 dsh 0.1.5 与 0.1.7 的安装包里都不存在(全量扫描 0 命中),一旦执行必抛 TypeError。它原本要覆盖的场景正是上面那个 hero 发送 bug,现在由会话级输入面正经实现
  • 修复 tests/cdp-combo.mjs 的 tooltip 判定在 0.1.7 下失配:0.1.7 把 tooltip 文本包进 <span class="label"> 并新增 shortcutKeys/input-modality,原来「扫描无子元素的 span」的写法不再成立。改为按 role="tooltip" 匹配文本、每次重新测量锚点矩形、失败重试 6 次
  • 修复 tests/verify-pwsh.mjs 仍调用 0.1.5 的 shell.run()(.mjs 不在 tsc 范围内,上一次迁移漏改):改为 await shell.execute(spec) + await execution.result()

Removed

  • settings.register / SettingsScope / SettingsApplies / installTaskRunnerSettings 等 0.1.5 时代的设置 API 用法
  • ShellExecutor.start()、JobSnapshot、JobOutcome.output、JobView.reported、SessionListState.current、通用 plugin message source、ctx.settingsScope、Icon*Outline14/16 等已从 dsh 0.1.7 删除的 API 用法

说明

  • 不兼容 dsh 0.1.5 线:0.1.5 版插件在 dsh 0.1.7 上无法加载(它调用的 settings.register、shell.start、JobSnapshot 在 0.1.7 已不存在);反过来本版也不能装在 dsh 0.1.5 上。dsh 0.1.5 线请继续使用插件 0.1.5
  • 数据无迁移:任务仍在 $DSH_HOME/storages/task_runner.json,storage domain 名、RPC 端点、工具名、locale 命名空间、slot 挂载点全部未变
  • 真机验收环境:全局 CLI dsh 0.1.7-rc.2 + 独立测试 profile(端口 3190,link: 指向源码)。结果:插件加载零错误;cdp-refresh / cdp-combo / cdp-header-order / cdp-workspace-select / cdp-llm-run 全部通过且 console error 为 0;verify-skill / verify-tool-schema / verify-pwsh 在真实包上通过;单测 49 条通过
  • 已知环境问题:验收时 DeepSeek API 额度用尽(会话内显示「当前请求的额度已用尽」),模型回复全部失败;发送链路的断言不依赖模型成功,与此无关

对比 0.1.5