本版把宿主下限抬到 @deepseek-ai/dsh >= 0.2.2-rc.2:请先升宿主,再升插件——用 npm i -g @deepseek-ai/dsh@next 装宿主,再以 dsh --version 校验,因为 npm 上的 latest 仍指向 0.2.2-rc.1,用 latest 装到的宿主不满足本版下限,在它上面点「更新」会被保护性拒绝。除此之外,本版把浏览器视图的闲置页面回收、梁神模式的按需工具族分页与插件页的批量更新各推进一步,并从任务看板移除了 /goal 运行选项与 goal 验收;对已经跑在 0.2.2-rc.2 上的用户,本版同时是一次修复:0.4.16 的 web-ui-agents 行在 rc.2 宿主上导入即失败。四个卫星仓在本版同版本对齐到 0.4.17。
宿主下限抬到
@deepseek-ai/dsh >= 0.2.2-rc.2,先升宿主再升插件:全部家族包的dsh.engines.dsh与@deepseek-ai/dsh对等依赖下限从>=0.2.2-rc.1移到>=0.2.2-rc.2,随本版一起移到 rc.2 的还有工作区全部@deepseek-ai/*区间、CI 与发布挂载的DSH_CLI_VERSIONpin、两个根 README 与全部 32 个包 README 的徽章,以及 lockfile。升级顺序是宿主优先:npm i -g @deepseek-ai/dsh@next之后用dsh --version确认已到0.2.2-rc.2,再在插件页升级全家桶。npm 的latest仍是0.2.2-rc.1(rc.2 只发在next标签上),用latest装出来的宿主不满足本版下限:dsh --version若还报0.2.2-rc.1,这趟升级就没到位,别急着升插件。
rc.1 宿主上点「更新」会看到保护性拒绝,这是预期行为而不是故障:更新请求在动手之前解析目标包声明的宿主下限,运行中的宿主不满足即返回 HTTP 412,界面显示... requires DSH >=0.2.2-rc.2 (current DSH 0.2.2-rc.1); upgrade DSH before updating(宿主侧完整形态是plugin-manager: <包名> requires DSH >=0.2.2-rc.2 (current DSH 0.2.2-rc.1); upgrade DSH before updating)。这条拒绝发生在任何写入之前,写入为零:profile、磁盘上的包与看板账本都不会被改动,按提示把宿主升到位后重试即可。
若在 rc.1 上手工装了 0.4.17:dsh web仍能启动,但整套 dsh-web 插件不加载:官方 boot gate 按 bundle 粒度跳过不满足下限的包,stderr只有一行dsh: skipping profile bundle "@linxin666/dsh-web-all": <原因>(格式为<binName>: skipping profile bundle <JSON 包名>: <原因>),不抛错、不删任何数据、其余 bundle 照常启动。把宿主升到0.2.2-rc.2再重启即恢复,profile 不用改。应急手段有两条:一是为这个精确版本开豁免——dsh plugin --profile <profile> allow-version <包名>@<版本> --dsh-version 0.2.2-rc.1 --accept-risk,豁免只作用于该包与该 DSH 版本的组合;二是把包移除、回退到0.4.16。
对已在0.2.2-rc.2上的宿主,本版是一次修复:rc.2 移除了@deepseek-ai/dsh-subagent/internal子路径导出,而0.4.16的dsh-agents在模块顶层静态导入它,于是聚合包的web-ui-agents行在导入阶段抛出ERR_PACKAGE_PATH_NOT_EXPORTED: './internal',被故障隔离壳按stage: import记为降级行——这一行的界面与工具全部缺失,其余行照常工作。本版改为优先探测Symbol.for('dsh.subagent.deliverPrompt')、缺省回退到subagents.sendMessage(caller, target.id, content, { signal }),同一份产物在两代宿主上都能加载与工作。
浏览器视图:闲置满 3 天的页面自动关闭:TabRecord.lastActiveAt在接入 target 时落一次,之后只由能解析到该页面的browser_*调用刷新;BrowserViewService.sweepIdle每十分钟扫一次(定时器unref、dispose 时清除),把超出窗口的页面走既有的closeTab路径关掉——指向它的会话绑定被丢弃、钉在它上面的面板回退到剩下的标签页、面板状态被广播;没有浏览器在跑时既不扫描也不拉起。窗口是新设置idleCloseDays:默认 3 天、最小 0、设 0 关闭该能力,每次扫描现读,所以改设置在下一次扫描就生效,既不用重挂插件也不用重连浏览器。接管的真实浏览器页面永远不会被自动关闭:候选只限插件自己创建(origin: 'created')的标签页,在面板里看它、选中它的 chip 与投屏帧都不算活跃。闲置时钟只在内存里,宿主重启后每个页面的计时重新开始。
梁神模式:按需工具族出厂开启:出厂pagedToolPatterns从只分页 MCP 桥接扩到['mcp__*', 'browser_*', 'task_board_*', 'team_*', 'squad*', 'ui_*', 'ssh_*'],宿主内建工具(shell、文件系统、glob/grep、后台作业、skill、ask_user_question、todo_write、web_search、子代理委派、plan、goal、fact_register、tool_activate与 MCP 资源读取)全部常驻。被扣留的族在目录里以一行命名空间摘要宣告,首次调用前需要tool_activate({ namespace })把命名空间挂回:mcp__*取工具名的第一个__分段(mcp__codegraph__codegraph_explore→codegraph),其余按字面头部推导(task_board_*→task_board、squad*→squad),裸写一个*会被拒绝。最多同时保持 3 个已激活的命名空间,激活第四个时把最久未用的那个逐回摘要;ptc呈现下这些摘要代表真正不可达的命名空间——既不在该请求的tools:sdk段,也不能在run_code程序内调用。设置卡片把列表暴露为「按需工具族」字段,写成空值即取消分组、恢复全量常驻(三处读取同一份模式表的行一并改写)。实测同一套会话的系统提示词从 104,949 字符降到 58,961 字符,tools:sdk段从 73,675 字符降到 27,666。
任务看板移除/goal运行选项与 goal 验收:goalRunEnabled与TaskRecord.goalRun、/goal的派发、session/projections的目标阶段判定、五个goalVerification*配置键、TaskRecord.skipVerification、ExecutionRecord.verification契约、tools/pre-execute上的update_goal(action: complete)拦截门、裁判模型执行器与task_board_manage(action: 'reset-verification')一并移除;手动执行、定时触发与rework返工一律按普通单回合运行,结算只看该回合的turn/end结果,不再产生额外的裁判模型调用。旧卡片与历史执行记录完整保留:权威账本$DSH_HOME/task-board/ledger-v2.json仍是schemaVersion: 7,旧行残留的goalRun、skipVerification、verification在加载时直接丢弃、绝不因此拒绝整行,也不再回写;非严格插件配置加载同样忽略旧 profile 补丁里残留的键。对task_board_manage传reset-verification现在按未知动作拒绝。
插件页批量更新:一次请求跑完整批,单行被拒不中断其余行:更新改走官方updateBundle(name, version, { requestId })这一条原语(管理器自己校验目标、移除已装版本、按找到的勾选状态安装、失败时把旧版本装回),批量成为本 host 对同一原语的串行排序执行,浏览器只发一次请求并轮询同一个任务。每行在任务里有一条自己的结果(phase/targetVersion/landed/error/restartRequired),请求在动手前按单条路由自己的规则逐条解析,拒绝变成那一行的错误而不是整批失败;整批上限 50 行、重复 id 只解析一次,最后一行答复后整批一律结束。已落地但当前进程加载不了的包记成「需要重启」的行而不是错误,两处界面都写明包名——更新后可能仍需重启 DSH 才加载新版本。
全新安装若报ERR_PNPM_IGNORED_BUILDS,按提示先批准构建再重跑:在还没有批准过构建脚本的 profile 上首次安装,pnpm 会以[ERR_PNPM_IGNORED_BUILDS] Ignored build scripts: cloudflared@..., cpu-features@..., ssh2@...结束并给出Run "pnpm approve-builds" to pick which dependencies should be allowed to run scripts.,dsh plugin add随之以退出码 1 结束,且不会把包挂进dsh.profile.bundles——也就是「装了但没生效」。按提示先执行pnpm approve-builds批准这三个依赖的构建脚本,再重跑同一条dsh plugin add。
升级须知
- 宿主下限从
>=0.2.2-rc.1抬到>=0.2.2-rc.2:本版抬高了dsh.engines.dsh与@deepseek-ai/dsh对等依赖下限,停在0.2.2-rc.1的宿主不再满足条件。升级顺序是宿主优先,而 npm 的latest仍是0.2.2-rc.1:装宿主必须用next标签(npm i -g @deepseek-ai/dsh@next),装完用dsh --version校验。 - rc.1 宿主上的更新拒绝是保护性设计:HTTP 412 加
requires DSH >=0.2.2-rc.2 (current DSH 0.2.2-rc.1); upgrade DSH before updating,发生在任何写入之前,不留下半装状态。看到它说明宿主还没升到位,不需要排查插件。 - rc.1 上手工装了 0.4.17 的恢复路径:
dsh web仍能启动,stderr 只有一行dsh: skipping profile bundle ...,整套插件不加载;把宿主升到0.2.2-rc.2重启即恢复,profile 无需改动。应急可用dsh plugin --profile <profile> allow-version <包名>@<版本> --dsh-version 0.2.2-rc.1 --accept-risk为该精确组合开豁免,或移除包回退到0.4.16。 - rc.2 宿主上的
web-ui-agents导入失败已在本版修复:0.4.16在 rc.2 上会因./internal子路径消失而以ERR_PACKAGE_PATH_NOT_EXPORTED丢掉这一行;本版的双队列探测让同一产物在 rc.1 与 rc.2 上都能加载。 - 浏览器视图新增
idleCloseDays,默认 3 天:只回收插件自己创建的页面,接管的真实浏览器页面不受影响;设 0 关闭该能力;闲置时钟只在内存,宿主重启后计时重来。只在面板里被观看、没有任何工具调用的页面同样会在窗口到期时关闭。 - 梁神模式的工具面默认分组:出厂分页
mcp__*、browser_*、task_board_*、team_*、squad*、ui_*、ssh_*,宿主内建工具常驻;被扣留的族在tool_activate({ namespace })之前不可达,最多同时激活 3 个;设置卡片里把「按需工具族」写成空值即恢复全量常驻。 - 任务看板的退役字段与账本兼容:本版删除
/goal运行选项与 goal 验收,账本 schema 仍是 v7,旧卡片与历史执行记录完整保留,退役字段在加载时丢弃且不回写,不需要任何迁移动作。 - 批量更新与重启事实:插件页的「全部更新」现在是一次请求、一个任务,单行被拒不中断其余行;已落地但当前进程加载不了的包会明确标注需要重启 DSH。本版不再自拼「移除再安装」的两阶段替换,层序(
dsh.profile.bundles中的位置)在连续更新后保持原样。 - 全新安装的
ERR_PNPM_IGNORED_BUILDS陷阱:dsh plugin add会以退出码 1 结束且不挂 bundle,先pnpm approve-builds再重跑。 - 平台验证声明:本版在 Linux(Ubuntu x86_64)的钉定 rc.2 宿主树上跑过仓库门禁(
typecheck、build、test、test:scripts、libs:check、aggregate:check、docs:check、i18n:check、emoji:check等)。Windows 与 macOS 未在物理实机上验证。发布时运行中的宿主未被重启,因此新增的idleCloseDays设置卡与插件页批量更新工具条的真实 GUI 观察,要在重启宿主并刷新页面之后才能补上。
新功能
- [plugin-manager] 批量更新改走官方
updateBundle并在本 host 串行排序执行:一次请求、一个任务、每行一条自己的结果,单行被拒不中断其余行,需重启的行记为已落地事实 - [remote-bridge] 新增
session.attachment.path:按会话自己 transcript 里点名的绝对路径提供那张图的字节,白名单只由该会话的 offload 占位符与 durable 工具结果发布的图片引用构成,路径须逐字节相等、realpath()解析到自身、确实是常规文件且首字节命中四种图片签名之一(不看扩展名)
修复
- [agents,liangshen] 桥接 DSH 0.2.2-rc.2 的运行期契约:
dsh-agents去掉对@deepseek-ai/dsh-subagent/internal的静态导入并双队列探测投递、startActivation同时传顶层字段与request嵌套字段、兼容drainChildren/drainDescendants/started.dispose(),并在官方agent-team行在场时让位;dsh-liangshen的 dispatch-guard 在agents.roots()缺省时回退探测subagents.rootOf(caller) - [sdk] 根宿主面承载
@deepseek-ai/dsh-error@0.2.2-rc.2,dsh-agents与dsh-remote-web-ui把zod钉到 4.6.6,并由dsh-agents自持 Team identity 的 prompt context 位置 125(rc.2 已从中央顺序表删掉该名字) - [agents] 成员与小队草稿被拒时点名具体字段:
gateMemberRequestBody/gateTeamRequestBody返回单条原因,取代固定的「not a usable definition」,客户端改名或新增字段时能看出是哪一个不被接受 - [remote-bridge] 一并读取 durable 工具结果里的 JSON 图片引用(
{ path, image: { ... } },即run_code程序自身返回值的持久化形态),并以mediaType必须以image/开头作为闸门,避免把工具仅仅提到过的文件放进白名单 - [sdk]
0.2.2-rc.2宿主上聚合包web-ui-agents行的ERR_PACKAGE_PATH_NOT_EXPORTED: './internal'导入失败,由上面两条双队列改动消除
行为变化
- [browser-view] 插件自己创建的页面闲置满窗口即自动关闭:窗口是新设置
idleCloseDays(默认 3 天、最小 0、设 0 关闭),每次扫描现读;接管的真实浏览器页面不是候选,在面板里观看也不算活跃;闲置时钟只在内存,宿主重启后计时重来 - [liangshen] 按需工具族出厂开启:
pagedToolPatterns默认['mcp__*', 'browser_*', 'task_board_*', 'team_*', 'squad*', 'ui_*', 'ssh_*'],宿主内建工具常驻;被扣留的族在tool_activate({ namespace })之前既不在 wire 与生成的 SDK 上、也不能在run_code程序内调用,最多同时激活 3 个,设置里把列表写成空值即取消分组 - [task-board] 移除
/goal运行选项与 goal 验收:执行形态统一为普通单回合、结算只看turn/end,不再有裁判模型调用与reset-verification解卡动作;账本 schema 仍是 v7,旧卡片与历史执行记录完整保留,退役字段加载时丢弃且不回写
其他改动
- [market] 把 2026-11-08、11-09、11-10、11-11 四轮卫星登记与本轮的升序索引重建依次钉进子模块 gitlink 并重出
market/dist,当前商店目录为 66 套皮肤、12 只宠物、124 个插件、33 个预设 - [task-board] 详情页运行折叠行的 key 从
detail.settings.advanced改为detail.settings.run,标题与新建对话框统一为「运行方式」/Run Mode/Режим запуска,折叠结构与唯一的会话复用开关不动 - [team-hub]
PROTOCOL.md七处把「自动验收」改写为按宿主自己的执行判定结算(移除验收门后的对齐),字段名、结算端点签名、in_review/failed状态与全部数值常量未变 - [docs] 浏览器与 GUI 验收改为以会话挂载的
browser_*工具为主,Playwright 退为回退手段与提交门禁pnpm test:mount,并把这条默认的归属写进决策笔记 - [lib]
dsh-market与dsh-web-all提交的lib/产物随区间内改动重建 - [satellites]
dsh-skins、dsh-pet、dsh-community-plugins与dsh-presets四个子模块 gitlink 前移到各自的 0.4.17 发布提交 - [remote-bridge] 附件门禁用例按门禁要求的角色命名(仅测试重命名,无行为变化)
- [notes] 记录 0.2.2-rc.2 队列及其原生优先重叠盘点等决策笔记
English
This release raises the host floor to @deepseek-ai/dsh >= 0.2.2-rc.2: upgrade the host first, then the plugins. Install it with npm i -g @deepseek-ai/dsh@next and confirm with dsh --version, because npm's latest still points at 0.2.2-rc.1 and a host installed from latest does not satisfy this release's floor - its update button refuses the upgrade protectively. Beyond that, this release moves browser-view idle page reclamation, LiangShen's on-demand tool-family paging and the Plugins page batch update one step each, and removes the task board's /goal run option and goal acceptance; for anyone already on 0.2.2-rc.2 this release is also a fix, because 0.4.16's web-ui-agents row fails to import on an rc.2 host. The four satellite repositories align to 0.4.17.
The host floor rises to
@deepseek-ai/dsh >= 0.2.2-rc.2; upgrade the host first:dsh.engines.dshand the@deepseek-ai/dshpeer dependency of every family package move from>=0.2.2-rc.1to>=0.2.2-rc.2, and the same move carries every workspace@deepseek-ai/*range, theDSH_CLI_VERSIONpin in CI and the release mount, the badges of both root READMEs and all 32 package READMEs, and the lockfile. Upgrade the host first:npm i -g @deepseek-ai/dsh@next, confirm withdsh --versionthat it reads0.2.2-rc.2, then update the family on the Plugins page. npm'slateststill reads0.2.2-rc.1(rc.2 ships on thenexttag only), so a host installed fromlatestdoes not satisfy this floor: ifdsh --versionstill reports0.2.2-rc.1, the host upgrade has not landed yet and the plugins should wait.
On an rc.1 host the update button shows a protective refusal, which is expected rather than a fault: the update request resolves the target package's declared host floor before touching anything and answers HTTP 412 when the running host does not satisfy it, showing... requires DSH >=0.2.2-rc.2 (current DSH 0.2.2-rc.1); upgrade DSH before updating(the host-side full form isplugin-manager: <package> requires DSH >=0.2.2-rc.2 (current DSH 0.2.2-rc.1); upgrade DSH before updating). The refusal happens before any write, so nothing is written: the profile, the packages on disk and the task board ledger are untouched, and retrying after the host upgrade is all that is needed.
If 0.4.17 was installed by hand on rc.1,dsh webstill starts but the whole dsh-web plugin set does not load: the official boot gate skips bundles that do not satisfy the floor, one bundle at a time, andstderrcarries a single line,dsh: skipping profile bundle "@linxin666/dsh-web-all": <reason>(the format is<binName>: skipping profile bundle <JSON package name>: <reason>). Nothing is thrown, no data is deleted, and the remaining bundles boot normally. Raise the host to0.2.2-rc.2and restart to recover; the profile needs no edit. Two stopgaps exist: grant the exact-version exemption withdsh plugin --profile <profile> allow-version <package>@<version> --dsh-version 0.2.2-rc.1 --accept-risk, which applies only to that package and that DSH version, or remove the package and roll back to0.4.16.
For hosts already on0.2.2-rc.2, this release is a fix: rc.2 removed the@deepseek-ai/dsh-subagent/internalsubpath export, and 0.4.16'sdsh-agentsimported it statically at module top level, so the aggregate'sweb-ui-agentsrow threwERR_PACKAGE_PATH_NOT_EXPORTED: './internal'at import time and was recorded as a degraded row atstage: import- that row's UI and tools were missing while the other rows kept working. This release probesSymbol.for('dsh.subagent.deliverPrompt')first and falls back tosubagents.sendMessage(caller, target.id, content, { signal }), so one artifact loads and works on both host generations.
Browser view: pages idle for three days close themselves:TabRecord.lastActiveAtis stamped when a target is adopted and refreshed only by abrowser_*call that resolves to that page;BrowserViewService.sweepIdleruns every ten minutes (anunref'd timer, cleared on dispose) and closes pages past the window through the existingcloseTabpath - the session binding pointing at it is dropped, a panel pinned to it falls back to the remaining tabs, and panel state is broadcast; nothing is scanned and no browser is launched when none is running. The window is the newidleCloseDayssetting: default 3 days, minimum 0, 0 disables the capability, read on every sweep, so an edit takes effect on the next sweep without remounting the plugin or reconnecting the browser. Adopted real-browser pages are never candidates: only tabs the plugin created (origin: 'created') qualify, and watching a page in the panel, selecting its chip or projecting its frames does not count as activity. The idle clock lives in memory only, so a host restart restarts every page's window.
LiangShen pages plugin tool families by default: the shippedpagedToolPatternsgrows from the MCP bridge alone to['mcp__*', 'browser_*', 'task_board_*', 'team_*', 'squad*', 'ui_*', 'ssh_*'], while host builtins (shell, the file system,glob/grep, background jobs,skill,ask_user_question,todo_write,web_search, subagent delegation, plan, goal,fact_register,tool_activateand the MCP resource readers) stay resident. A withheld family is announced as one namespace summary in the catalog and needstool_activate({ namespace })before its first call:mcp__*takes the first__segment of the tool name (mcp__codegraph__codegraph_explorebecomescodegraph) while the others derive a literal-prefix family (task_board_*totask_board,squad*tosquad), and a bare*is refused. At most three activated namespaces are held at once, and activating a fourth returns the least recently used one to its summary; underptcthose summaries are genuinely unreachable - absent from the request'stools:sdksection and not callable inside arun_codeprogram. The settings card exposes the list as the on-demand tool family field, and writing it empty removes the grouping and returns every tool to the resident face (all three rows that page from that one pattern list are rewritten together). Measured on one session, the system prompt dropped from 104,949 to 58,961 characters and thetools:sdksection from 73,675 to 27,666.
The task board loses the/goalrun option and goal acceptance:goalRunEnabledandTaskRecord.goalRun, the/goaldispatch, thesession/projectionsgoal-phase settlement, the fivegoalVerification*keys,TaskRecord.skipVerification, theExecutionRecord.verificationcontract, theupdate_goal(action: complete)gate ontools/pre-execute, the judge-model runner andtask_board_manage(action: 'reset-verification')are all removed; manual runs, scheduled triggers andreworknow run as an ordinary single turn and settle from that turn'sturn/endresult, with no extra judge-model calls. Existing cards and execution history stay intact: the authoritative ledger$DSH_HOME/task-board/ledger-v2.jsonkeepsschemaVersion: 7, leftovergoalRun,skipVerificationandverificationfields on old rows are dropped at load rather than rejecting the row, and they are never written back; non-strict plugin config loading likewise ignores leftover keys in old profile patches. Passingreset-verificationtotask_board_manageis now refused as an unknown action.
Plugins page batch update: one request runs the whole batch, and a refused row does not stop the others: updates now go through the officialupdateBundle(name, version, { requestId })primitive (the manager verifies the target, removes the installed version, installs with the selection it found and restores on failure), so a batch is this host running that one primitive over its rows in order and the browser sends one request and polls one job. Each row carries its own result (phase,targetVersion,landed,error,restartRequired), the request resolves every id by the single route's own rules before touching anything, and a refusal becomes that row's error instead of failing the batch; a batch is capped at 50 rows, duplicate ids resolve once, and the batch always settles after the last row answers. A package that landed but cannot be loaded in this process is a restart row rather than an error, named on both surfaces - a restart of DSH may still be needed before the new version loads.
A fresh install that reportsERR_PNPM_IGNORED_BUILDSneeds the builds approved and the command re-run: on a profile that has never approved build scripts, pnpm ends with[ERR_PNPM_IGNORED_BUILDS] Ignored build scripts: cloudflared@..., cpu-features@..., ssh2@...plusRun "pnpm approve-builds" to pick which dependencies should be allowed to run scripts.,dsh plugin addexits 1, and the package is not added todsh.profile.bundles- installed but not in effect. Runpnpm approve-buildsfor those three dependencies and re-run the samedsh plugin add.
Upgrade Notes
- The host floor moves from
>=0.2.2-rc.1to>=0.2.2-rc.2: this release raisesdsh.engines.dshand the@deepseek-ai/dshpeer floor, so a host on0.2.2-rc.1no longer qualifies. The host goes first, and npm'slatestis still0.2.2-rc.1: install it from thenexttag (npm i -g @deepseek-ai/dsh@next) and verify withdsh --version. - The refusal on an rc.1 host is protective by design: HTTP 412 plus
requires DSH >=0.2.2-rc.2 (current DSH 0.2.2-rc.1); upgrade DSH before updating, raised before any write, leaving no half-installed state. Seeing it means the host has not been upgraded yet, and nothing about the plugin needs investigating. - Recovery after a hand install of 0.4.17 on rc.1:
dsh webstill starts, stderr carries a singledsh: skipping profile bundle ...line, and the plugin set does not load; raising the host to0.2.2-rc.2and restarting recovers it without touching the profile. The stopgaps aredsh plugin --profile <profile> allow-version <package>@<version> --dsh-version 0.2.2-rc.1 --accept-riskfor that exact combination, or removing the package and rolling back to0.4.16. - The
web-ui-agentsimport failure on rc.2 hosts is fixed here: 0.4.16 lost that row on rc.2 toERR_PACKAGE_PATH_NOT_EXPORTEDonce the./internalsubpath disappeared; the dual-cohort probing in this release makes one artifact load on both rc.1 and rc.2. - Browser view gains
idleCloseDays, default 3 days: only pages the plugin created are reclaimed, adopted real-browser pages are untouched, 0 disables the capability, and the idle clock lives in memory so a host restart restarts the window. A page watched in the panel with no tool call still closes when its window expires. - LiangShen's tool face is grouped by default: the shipped page list is
mcp__*,browser_*,task_board_*,team_*,squad*,ui_*andssh_*while host builtins stay resident; a withheld family is unreachable beforetool_activate({ namespace }), at most three stay activated, and writing the on-demand tool family field empty restores the full resident face. - Retired task board fields and ledger compatibility: this release removes the
/goalrun option and goal acceptance while the ledger schema stays v7, existing cards and execution history stay intact, retired fields are dropped at load and never written back, and no migration step is needed. - Batch update and the restart fact: the Plugins page's update all is now one request and one job, a refused row does not stop the others, and a package that landed but cannot load in this process is explicitly marked as needing a DSH restart. The hand-written remove-then-install replacement is gone, and the layer order (the position in
dsh.profile.bundles) survives consecutive updates. - The fresh-install
ERR_PNPM_IGNORED_BUILDStrap:dsh plugin addexits 1 without adding the bundle, so runpnpm approve-buildsfirst and retry. - Platform verification: this release ran the repository gates on Linux (Ubuntu x86_64) against a pinned rc.2 host tree (
typecheck,build,test,test:scripts,libs:check,aggregate:check,docs:check,i18n:check,emoji:checkamong them). Windows and macOS were not verified on physical hardware. The host running at release time was not restarted, so the real GUI observation of the newidleCloseDayssettings card and the batch update toolbar lands only after the host is restarted and the page refreshed.
New Features
- [plugin-manager] Batch updates go through the official
updateBundleas one ordered run in this host: one request, one job, one result per row, a refused row leaves the rest running, and a restart-required row is recorded as a landed fact - [remote-bridge] Add
session.attachment.path, serving the bytes of one image by the absolute path that session's own transcript named, with a whitelist built only from that session's offload placeholders and the image references its durable tool results published; a path is served only when it matches byte for byte,realpath()resolves it to itself, a regular file is there and its first bytes match one of four image signatures (the extension is never consulted)
Bug Fixes
- [agents,liangshen] Bridge the runtime contracts of a DSH 0.2.2-rc.2 host:
dsh-agentsdrops its static@deepseek-ai/dsh-subagent/internalimport and probes both delivery paths, passes both top-level fields and the nestedrequesttostartActivation, acceptsdrainChildren,drainDescendantsandstarted.dispose(), and steps aside while the officialagent-teamrow is present;dsh-liangshen's dispatch guard falls back tosubagents.rootOf(caller)whenagents.roots()is absent - [sdk] Carry
@deepseek-ai/dsh-error@0.2.2-rc.2as a root host face, pinzodto 4.6.6 indsh-agentsanddsh-remote-web-ui, and havedsh-agentssupply the Team identity prompt-context position 125 that rc.2 dropped from the central order table - [agents] Name the refused field when a member or squad draft is not usable:
gateMemberRequestBodyandgateTeamRequestBodyreturn one reason instead of the fixed "not a usable definition", so a client that renames or adds a draft field can tell which one was not accepted - [remote-bridge] Read the JSON image reference of a durable tool result too (
{ path, image: { ... } }, the persisted shape of arun_codeprogram's own return value), gated on animageobject whosemediaTypestarts withimage/so a file a tool merely named never enters the whitelist - [sdk] The
ERR_PACKAGE_PATH_NOT_EXPORTED: './internal'import failure of the aggregate'sweb-ui-agentsrow on a0.2.2-rc.2host, removed by the two dual-cohort changes above
Behavior Changes
- [browser-view] Pages the plugin created close themselves once idle past the window: the window is the new
idleCloseDayssetting (default 3 days, minimum 0, 0 disables), read per sweep; adopted real-browser pages are never candidates and watching a page in the panel is not activity; the clock lives in memory, so a host restart restarts it - [liangshen] On-demand tool families ship enabled:
pagedToolPatternsdefaults to['mcp__*', 'browser_*', 'task_board_*', 'team_*', 'squad*', 'ui_*', 'ssh_*']while host builtins stay resident, a withheld family is absent from the wire and the generated SDK and cannot be called inside arun_codeprogram beforetool_activate({ namespace }), at most three stay activated, and writing the list empty in the settings removes the grouping - [task-board] The
/goalrun option and goal acceptance are removed: execution is an ordinary single turn and settlement readsturn/end, with no judge-model calls and noreset-verificationunstick action; the ledger schema stays v7, existing cards and execution history stay intact, and retired fields are dropped at load and never written back
Other Changes
- [market] Pin the 2026-11-08, 11-09, 11-10 and 11-11 satellite registration rounds and this round's ascending-id index rebuild into the submodule gitlinks and regenerate
market/dist, leaving the store catalog at 66 skins, 12 pets, 124 plugins and 33 presets - [task-board] Rename the detail run fold key from
detail.settings.advancedtodetail.settings.runand give it the create dialog's title (Run Mode / 运行方式 / Режим запуска), keeping the fold and its single session-reuse switch - [team-hub] Rewrite seven places in
PROTOCOL.mdso settlement follows the host's own execution verdict rather than automated acceptance, with field names, the settle endpoint signature, thein_review/failedstates and every numeric constant unchanged - [docs] Drive browser and GUI verification with the session's
browser_*tools, keeping Playwright as the fallback and as the committed mount gatepnpm test:mount, and record the owner of that default in a decision note - [lib] Rebuild the committed
lib/artifacts ofdsh-marketanddsh-web-allwith the changes in this range - [satellites] Advance the four submodule gitlinks (
dsh-skins,dsh-pet,dsh-community-plugins,dsh-presets) to their 0.4.17 release commits - [remote-bridge] Name the attachment gate cases by the role the gate requires (a test rename only, no behavior change)
- [notes] Record the 0.2.2-rc.2 cohort and its native-first overlap inventory, among other decision notes