github zhu1090093659/dsh-web v0.4.9
dsh-web v0.4.9

3 hours ago

本次发布把 agent 真正能开的浏览器搬进右栏:新增 @linxin666/dsh-client-ui-browser-view,一个由 CDP 驱动的真实 Chromium,agent 用 browser_navigate、browser_snapshot、browser_click 这一组工具操作它,用户看到的就是它正在渲染的那一页;Chrome 懒启动,插件挂载时不会被拉起。家族新增两条行:dsh-agents 把 agent 小队做成可整队运行的真实会话(成员可钉 agent 预设、权限、模型与思考档位,成员简介进入该成员会话的系统提示),dsh-message-edit 可以改写一条纯文本消息、在前一个事件边界分叉并在新分支上重发。任务看板这一版把子任务交给父卡片派发,并把看板的能力面经 dsh-task-board-remote 绑到远程桥(board.v1),配对的手机读到的就是同一本账。远程桥继续沿协议 v1 扩张:用量台账(usage.v1、usage.stats.v1)、工作区与会话管理写方法(workspace.v1、session.admin.v1)、斜杠指令(commands.v1)、小队(squads.v1)、待答提问对账(questions.list.v1)与推送通道(push.v1,含 APNs 发送器与实况卡)。宿主下限一并抬到 0.2.1-rc.3,与 CI 钉住的 DSH 版本同版。

先升级 DSH,再升级本包:聚合包的 dsh.engines.dsh 与 peer 依赖 @deepseek-ai/dsh 一起从上一版本线抬到 >=0.2.1-rc.3,与 CI 固定的 DSH_CLI_VERSION 0.2.1-rc.3 同版。DSH 低于该版本的宿主会因引擎门跳过家族行——症状是插件在面板里消失,而不是报错,所以先升级 DSH,再升级本包。需要回滚时回装 @linxin666/dsh-web-all@0.4.8。
会真正迁移的入口只有一个:本仓已没有 Doctor 启动前迁移路径,dsh-doctor 现在只是 tombstone,装不上也没有启动前置消费者。唯一具备预检、版本断言与回滚的路径是插件管理器更新(含旧聚合名 @linxin666/dsh-web-ui-all 的迁移分支);直接 dsh web 不执行安装,也不做任何预检,旧 profile 会原样保留。手工恢复用 dsh plugin --profile <name> add @linxin666/dsh-web-all@0.4.9。
本版没有删除或重命名任何持久化或线协议标识符:设置 section id、配置 key、localStorage 键、控制面 API path 与聚合行 id 全部保持原值。新增的都是纯增量:聚合行多出 web-ui-agents、web-ui-message-edit、web-ui-browser-view、web-ui-task-board-remote 四行,远程桥多出 usage.v1、usage.stats.v1、workspace.v1、session.admin.v1、commands.v1、questions.list.v1、squads.v1、push.v1 八个能力位。
未钉工作区的卡片不再运行:卡片解析不到工作区时直接拒绝,不再静默落进 profile 目录。旧卡片若没钉过工作区,要补一个工作区才能跑。
转发而来的请求不再被当作本机回环:远程面与共享层把回环判定分层,被转发的上游请求要被显式声明为可信才作数,任务看板只额外接纳宿主连接已鉴权的代理请求(#1930)。反代部署需要在配置里显式打开信任,否则会被当作外部请求。
新包首发:@linxin666/dsh-client-ui-browser-view 此前不在 npm 上,本次以 0.4.9 首次发布,随聚合包一起下发,为聚合包提供可被 agent 驱动的浏览器标签页能力。它懒启动——挂载时不启动 Chrome,等第一次真正的浏览动作才起,所以装好之后不占进程。
刚发布的版本可能被 pnpm 的发布龄期挡住:pnpm 若启用 minimumReleaseAge(常见默认 24 小时),在卫星包刚发布不久执行的更新会被直接拒掉。补救是在 profile 的 pnpm-workspace.yaml 里为 @linxin666/* 补上 minimumReleaseAgeExclude,或者等龄期过去再更新。
卫星范围在同一批次里对齐:四个卫星仓先各自发布 0.4.9,registry 可解析之后,聚合包的依赖范围才从 ^0.4.8 抬到 ^0.4.9:

  • 皮肤中心(dsh-skins):@linxin666/dsh-client-ui-skin-center@0.4.9
  • 宠物(dsh-pet):@linxin666/dsh-pet@0.4.9
  • 社区插件索引(dsh-community-plugins):@linxin666/dsh-client-ui-community-plugins@0.4.9
  • 预设中心(dsh-presets):@linxin666/dsh-client-ui-preset-center@0.4.9

新功能

  • [browser-view] 新增包 dsh-client-ui-browser-view:右栏停靠的实况浏览器标签页,agent 驱动一个真实 Chromium,用户看到的就是它正在渲染的那一页
  • [browser-view] 工具面覆盖导航、快照、点击、输入、按键、滚动、截图、控制台、网络与标签页管理(browser_navigate、browser_snapshot、browser_click、browser_type、browser_press、browser_scroll、browser_screenshot、browser_console、browser_network、browser_tabs、browser_close)
  • [browser-view] 标签页归开启它的会话所有,会话被释放时一并销毁
  • [agents] 新增 dsh-agents 小队子插件,以家族行并入全家桶
  • [agents] 小队可整队运行:运行期 fork 官方 Agent Teams,每个成员是一次真实 DSH 会话
  • [agents] 模型拿到可调用的小队与成员定义工具面
  • [agents] 成员表单的模型与思考档位改为下拉选择
  • [agents] 小队表单改分段布局,支持工作区下拉与由模型起草成员简介
  • [message-edit] 新增 dsh-message-edit:改写一条纯文本用户消息,在前一个事件边界分叉,并在新分支上重发
  • [task-board-remote] 聚合包收进 dsh-task-board-remote 行,手机的 Tasks 面拿到 board.v1
  • [task-board] 子任务改由父卡片派发,不再由宿主逐层级联
  • [task-board] 卡片详情改为两栏折叠面板,与面板的披露与动作契约对齐
  • [task-board] 看板开着的时候隐藏官方的 automation-tasks 入口
  • [remote-bridge] usage.v1:读会话请求组成与 DeepSeek 账户余额
  • [remote-bridge] usage.stats.v1:用量台账聚合,usage.session 补上 modelContextWindow
  • [remote-bridge] workspace.list 与五个会话管理写方法
  • [remote-bridge] commands.v1:列出斜杠指令与技能并执行一行
  • [remote-bridge] questions.list.v1:手机可对账仍持有的待答提问
  • [remote-bridge] squads.v1:手机可读写 agent 小队
  • [remote-bridge] push.v1:push.register 与 APNs 发送器,实况卡改为按会话投影与投递
  • [remote-bridge] 桥自持常驻观察者,没有客户端连接也能收到回合结束
  • [remote-bridge] 手机离线时替登记过推送的设备认领提问
  • [remote-bridge] 一张锁屏卡上叠几个会话
  • [remote-web-ui] 已授权设备可命名,同一 UA 的重复设备合并
  • [relay] 新增具名隧道控制面与第二个连接器
  • [relay] 在快路径之后新增可增量的 Durable Object 桥
  • [usage] 按配置汇率用人民币或美元显示花费 (#1937)
  • [usage] 鲸元券改由每个提供方签发
  • [ssh] SSH 连接超时可配置 (#1931, #1932)
  • [task-board-github] GitHub 流量走可配置代理
  • [session-archive] 记录可选的观测归档时间 (#1908)
  • [market] 支持 DIY Journal 皮肤,并把 dsh-free-search 从编辑精选中撤下
  • [market] 超过 Workers 资源上限的皮肤包直接跳过,不让整次抓取失败

修复

  • [plugin-manager] 已经落地、但要等一次重启才生效的更新,如实报告为已落地 (#1905)
  • [liangshen] 去掉官方已移除的 subagent list-agents 行 (#1940)
  • [liangshen] 探测报告没有字段时仍保留一条已授权路由对
  • [liangshen] 按执行器行选择协议线,适配 0.2.x cohort
  • [remote-bridge] Windows 上的名册写入改为串行
  • [remote-bridge] 等名册清理的真实写入完成,不再空转事件循环
  • [remote-bridge] 名册行标题改从行内投影读取
  • [remote-bridge] usage.session 按宿主名册判定会话存在,存在过的会话不再被说成不存在
  • [remote-bridge] hello 公告的 minor 由 16 升到 17
  • [remote-bridge] 锁屏卡按会话投影与投递
  • [remote-bridge] 带括号的会话名保留,终端行去掉,卡片改用 App 自己的说法
  • [remote-bridge] 复制动作只在确有可复制内容时渲染,并为复制结果补上朗读区域
  • [remote-web-ui] 局域网可达性改由运行时转发器提供 (#1917)
  • [remote-web-ui] 回环判定分层,隧道里的手机恢复配对 (#1919)
  • [remote-web-ui] 转发插件请求头 (#1925)
  • [remote-web-ui] 中继租约按传输而不是隧道认领
  • [shared] 服务未注入时回答 not-paired,而不是抛错 (#1942)
  • [shared] 被转发的回环上游请求可被显式信任 (#1918)
  • [usage] 用量分区经 shell 的设置存储打开 (#1921)
  • [agents] 服务探测改走 ctx.get,修掉本行的致命挂载失败
  • [agents] 成员卡与页头的对齐缺陷按 KFL 归位
  • [agents] 设置卡补上家族标记图标
  • [market] 瞬时下载失败会重试,并把 Cloudflare 挑战如实报出 (#1941)
  • [market] 桥接租约不必有隧道或 CNAME 也能认领
  • [task-board] 未钉工作区的卡片拒绝运行,不再静默落进 profile 目录
  • [task-board] 接纳宿主连接已鉴权的代理请求 (#1930)
  • [ssh] agent 路径为空时提交 agent 认证 (#1910)
  • [message-edit] 编辑器宽度与输入框对齐
  • [web-all] 根视口锁定改由属性承载,不再依赖 :has() (#1913, #1916)
  • [scripts] i18n 门禁里占位符不一致改为精确报错,而不是让脚本崩掉

其他改动

  • [sdk] 插件 cohort 前移到 0.2.1-rc.3,聚合包的 dsh 引擎与 peer 范围一并抬到 >=0.2.1-rc.3
  • [hooks] 拦下钉住未推送卫星内容的 gitlink 推送
  • [ci] 新增 Windows 车道,跑桥接与浏览器视图套件
  • [ci] 记录二十个包的覆盖率基线
  • [satellites] 四个卫星仓的 gitlink 前移到各自的 0.4.9 发布提交
  • [market] 跟随卫星仓的合并刷新皮肤、宠物、社区插件与预设的钉版
  • [libs] 重建聚合包 bundle 并刷新记录指纹
  • [task-board] 设置卡专题改为嵌套密度并压缩文案
  • [remote-bridge] 协议 v1 配对面板改用官方 Modal 与 Button
  • [test] 钉住 snapshot 分页的 hasMore 语义
  • [test] 补齐推送通道用例的标题与 Given/When/Then 结构
  • [docs] 记录工作区与会话管理通道、小队运行期、远程桥常驻观察者与 commands.v1 的放弃项,并同步 issue 批次的双语 README
  • [docs] 记录 Windows smoke 车道的存在与代价

English

This release moves a browser the agent can actually drive into the right dock: the new @linxin666/dsh-client-ui-browser-view package runs a real CDP-driven Chromium that the agent operates through browser_navigate, browser_snapshot, browser_click and their siblings, so the page the user watches is the page it is rendering; Chrome starts lazily and is not launched when the plugin mounts. The family gains two rows: dsh-agents turns agent squads into real sessions that run as a whole squad (a member pins an agent preset, a permission, a model and a reasoning level, and its brief joins that member session's system prompt), and dsh-message-edit rewrites a text-only user message, forks at the preceding event boundary and resends on the new branch. The task board hands subtask dispatch to the parent card in this version, and its capability face is bound to the remote bridge through dsh-task-board-remote (board.v1), so a paired phone reads the same ledger. The remote bridge keeps extending protocol v1: usage statistics (usage.v1, usage.stats.v1), workspace and session-management write methods (workspace.v1, session.admin.v1), slash commands (commands.v1), squads (squads.v1), reconciliation of held questions (questions.list.v1) and a push channel (push.v1, with an APNs sender and live cards). The host floor moves to 0.2.1-rc.3, the same version CI pins.

Upgrade DSH first, then this package: the aggregate's dsh.engines.dsh and its @deepseek-ai/dsh peer dependency both move from the previous line to >=0.2.1-rc.3, the version CI pins as DSH_CLI_VERSION 0.2.1-rc.3. A host below that version skips the family rows at the engine gate — the symptom is plugins disappearing from the panel rather than an error — so upgrade DSH first and this package second. To roll back, reinstall @linxin666/dsh-web-all@0.4.8.
Only one entry point really migrates: this repository no longer has a Doctor pre-launch migration path; dsh-doctor is only a tombstone today, it cannot be installed and no launcher consumer exists. The plugin-manager update (including the legacy aggregate-name @linxin666/dsh-web-ui-all migration branch) is the only path with preflight, version assertion and rollback; a direct dsh web performs no install and no preflight, so an old profile stays exactly as it is. To recover by hand, run dsh plugin --profile <name> add @linxin666/dsh-web-all@0.4.9.
This version deletes or renames no persisted or wire-protocol identifier: settings section ids, configuration keys, localStorage keys, control-plane API paths and aggregate row ids all keep their values. Everything new is purely additive: the aggregate gains the rows web-ui-agents, web-ui-message-edit, web-ui-browser-view and web-ui-task-board-remote, and the bridge gains the capability bits usage.v1, usage.stats.v1, workspace.v1, session.admin.v1, commands.v1, questions.list.v1, squads.v1 and push.v1.
A card without a pinned workspace no longer runs: when no workspace resolves, the card refuses instead of quietly landing in the profile directory. A card that never pinned one needs a workspace before it can run again.
A forwarded request is no longer treated as loopback: the remote face and the shared layer decide loopback in layers, an upstream request that was forwarded counts only when it is explicitly declared trusted, and the task board additionally admits Host connection-authenticated proxy requests (#1930). A reverse-proxy deployment must switch that trust on in its configuration, or its requests are refused as external.
A new package's first release: @linxin666/dsh-client-ui-browser-view did not exist on npm before; it debuts at 0.4.9 and ships with the aggregate in this version, and gives the aggregate a browser tab the agent can drive. It starts lazily — mounting the plugin does not launch Chrome, the first real browsing action does — so an install costs no process.
A freshly published version may be held back by pnpm's release age: with minimumReleaseAge enabled (24 hours by common default), an update that runs right after the satellite packages publish is refused outright. The remedy is minimumReleaseAgeExclude for @linxin666/* in the profile's pnpm-workspace.yaml, or waiting the window out before updating.
The satellite ranges move in the same batch: the four satellite repositories publish 0.4.9 first, and only once the registry resolves them does the aggregate's dependency range move from ^0.4.8 to ^0.4.9:

  • Skin center (dsh-skins): @linxin666/dsh-client-ui-skin-center@0.4.9
  • Pet (dsh-pet): @linxin666/dsh-pet@0.4.9
  • Community plugin index (dsh-community-plugins): @linxin666/dsh-client-ui-community-plugins@0.4.9
  • Preset center (dsh-presets): @linxin666/dsh-client-ui-preset-center@0.4.9

New Features

  • [browser-view] New dsh-client-ui-browser-view package: a live browser tab docked on the right, where the agent drives a real Chromium and the user watches the page it is rendering
  • [browser-view] The tool surface covers navigation, snapshots, clicks, typing, keys, scrolling, screenshots, console, network and tab management (browser_navigate, browser_snapshot, browser_click, browser_type, browser_press, browser_scroll, browser_screenshot, browser_console, browser_network, browser_tabs, browser_close)
  • [browser-view] A tab belongs to the session that opened it and is disposed with that session
  • [agents] New dsh-agents squad sub-plugin, mounted as a family row of the aggregate
  • [agents] A squad runs as a whole squad: its runtime forks official Agent Teams, and each member is a real DSH session
  • [agents] Models get a tool surface for the same squad and member definitions
  • [agents] A member form picks its model and reasoning level from a dropdown
  • [agents] The squad form switches to a segmented layout with a workspace dropdown and a model-drafted member brief
  • [message-edit] New dsh-message-edit: rewrite a text-only user message, fork at its preceding event boundary, and resend on the new branch
  • [task-board-remote] The aggregate gains the dsh-task-board-remote row, and the phone's Tasks face gets board.v1
  • [task-board] Subtasks dispatch from the parent card instead of a Host cascade
  • [task-board] The card detail becomes a two-column folded panel that follows the panel's disclosure and action contract
  • [task-board] The official automation-tasks entry hides while the board is on
  • [remote-bridge] usage.v1 reads the composition of a session's requests and the DeepSeek account balance
  • [remote-bridge] usage.stats.v1 aggregates the usage ledger, and usage.session carries modelContextWindow
  • [remote-bridge] workspace.list plus five session-management write methods
  • [remote-bridge] commands.v1 lists slash commands and skills and executes one line
  • [remote-bridge] questions.list.v1 reconciles the questions a phone still holds
  • [remote-bridge] squads.v1 lets a phone read and write agent squads
  • [remote-bridge] push.v1 adds push.register and an APNs sender, and live cards project and deliver per session
  • [remote-bridge] The bridge keeps its own standing watcher, so a turn end arrives even with no client connected
  • [remote-bridge] A question is claimed for a registered push device while the phone is offline
  • [remote-bridge] Several sessions lay out on one lock-screen card
  • [remote-web-ui] An authorized device can be named, and same-UA duplicates merge
  • [relay] A named-tunnel control plane and a second connector
  • [relay] An additive Durable Object bridge behind the quick path
  • [usage] Spend displays in CNY or USD at a configured rate (#1937)
  • [usage] The whale-yuan voucher is minted from every provider
  • [ssh] The SSH connection timeout is configurable (#1931, #1932)
  • [task-board-github] GitHub traffic goes through a configurable proxy
  • [session-archive] An opt-in observed archive time is recorded (#1908)
  • [market] The DIY Journal skin is featured, and dsh-free-search leaves the editor picks
  • [market] A skin archive over the Workers asset cap is skipped instead of failing the whole fetch

Bug Fixes

  • [plugin-manager] An update that landed but only a restart loads is reported as landed (#1905)
  • [liangshen] The subagent list-agents row the official side removed is dropped (#1940)
  • [liangshen] An authorized route pair survives a probe that reports no fields
  • [liangshen] The wire is selected by executor row, which suits the 0.2.x cohort
  • [remote-bridge] Roster writes are serialized on Windows
  • [remote-bridge] Roster cleanup waits on the real write promise instead of spinning the event loop
  • [remote-bridge] A roster row's title is read from its in-row projection
  • [remote-bridge] usage.session judges existence by the host roster, so a session that existed is no longer reported absent
  • [remote-bridge] The hello announcement raises its minor from 16 to 17
  • [remote-bridge] Live cards project and deliver per session
  • [remote-bridge] Bracketed names stay, terminal rows go, and the card uses the App's own words
  • [remote-bridge] The copy action renders only with real content, and its result announces through a live region
  • [remote-web-ui] LAN reachability comes from the runtime forwarder (#1917)
  • [remote-web-ui] Loopback is decided in layers, and a tunnelled phone pairs again (#1919)
  • [remote-web-ui] Plugin request headers are forwarded (#1925)
  • [remote-web-ui] The relay lease is claimed for the transport, not the tunnel
  • [shared] An un-injected service answers not-paired instead of throwing (#1942)
  • [shared] A forwarded loopback upstream request can be trusted explicitly (#1918)
  • [usage] The usage section opens through the shell's settings store (#1921)
  • [agents] Service probing goes through ctx.get, which fixes a fatal mount failure in this row
  • [agents] The member card and page-header alignment defects are put back on the KFL grid
  • [agents] The settings card carries the family marker icon
  • [market] A transient download failure retries, and a Cloudflare challenge is reported as such (#1941)
  • [market] A bridged lease claims without a tunnel or a CNAME
  • [task-board] A card without a pinned workspace refuses to run instead of quietly landing in the profile directory
  • [task-board] Host connection-authenticated proxy requests are admitted (#1930)
  • [ssh] Agent authentication is submitted when the agent path is empty (#1910)
  • [message-edit] The editor width lines up with the composer
  • [web-all] The root viewport lock rides an attribute instead of :has() (#1913, #1916)
  • [scripts] A placeholder mismatch in the i18n gate reports precisely instead of crashing

Other Changes

  • [sdk] The plugin cohort advances to 0.2.1-rc.3, and the aggregate's dsh engine and peer range move to >=0.2.1-rc.3 with it
  • [hooks] A gitlink pinning unpushed satellite content is blocked on push
  • [ci] A Windows lane runs the bridge and browser-view suites
  • [ci] The coverage baseline is recorded for all twenty packages
  • [satellites] The four satellites' gitlinks move to their 0.4.9 release commits
  • [market] Follow the satellites' merges in the skin, pet, community-plugin and preset pins
  • [libs] Rebuild the aggregate bundles and refresh the recorded fingerprints
  • [task-board] The settings card topic switches to nested density and tighter copy
  • [remote-bridge] The protocol v1 pairing panel uses the official Modal and Button
  • [test] Pin the semantics of hasMore at a snapshot page boundary
  • [test] Give the push-channel cases role titles and Given/When/Then structure
  • [docs] Record the workspace and session-management channels, the squad runtime, the bridge's standing watcher and what commands.v1 gave up, and sync the bilingual READMEs for the issue batch
  • [docs] Record what the Windows smoke lane costs and why it exists

Don't miss a new dsh-web release

NewReleases is sending notifications on new releases.