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

4 hours ago

本次发布集中在控制面治理、跨平台运行环境加固与底层协议健壮性提升:应用市场(dsh-market)中继控制面全面重做,引入收敛缓存与统一限流预算以彻底解决 Cloudflare 账号 API 配额耗尽问题,部署流程全量迁移至 Cloudflare 官方 cf CLI;远程接入(dsh-remote-bridge)修正推送中继缺省地址并支持按订阅层级路由中继租约;插件管理器(dsh-plugin-manager)支持在 systemd 用户服务下请求 unit 级重启,并补充 bundle 挂载落地校验;家族聚合包退役 web-ui-update 行;Windows 终端(dsh-win-bash)改为从包外受校验缓存副本执行载荷并在进程退出时回收私有临时目录,根除 ERR_PNPM_EPERM 阻塞;浏览器视图(dsh-browser-view)支持带选区裁剪与缩放的高清 PNG 截图;dsh-git-graph 固定子进程英文环境避免误判覆盖守卫。四个卫星仓在本版同版本对齐到 0.4.14。

中继控制面全面重做与限流预算收紧:中继控制面引入收敛缓存与 D1 额度守卫(每 5 分钟 600 次),有效租约直接基于缓存响应而不再消耗 Cloudflare 账号 API 额度,彻底解决申领风暴造成的全站限流;传输模式默认值翻转为 bridge,租约支持按订阅层级路由与多会合点分流;D1 迁移 0011 新增三列缓存字段;全部 15 项中继限制统一在 relay-limits.js 声明并冻结,注册/申领与 bridge 连接窗口收紧至 300 秒;中继失败一律回落至统一冻结错误码;deploy-market 部署脚本全面迁至官方 cf CLI 并增加网络层故障重试;推送中继缺省地址修正为应用真实使用的账号服务。
插件管理器支持 systemd 重启与 Bundle 落地校验:当宿主运行在 systemd 用户服务下时,插件管理器从 cgroup 与 INVOCATION_ID 准确识别所属用户 unit 并请求 systemd 重启当前服务,线协议新增第四态 systemd;新增 bundle 选择落地判定(bundleSelectionMissing),杜绝因构建脚本门禁导致依赖已写入 profile 但 bundle 挂载丢失的假成功现象;家族聚合包正式退役 web-ui-update(dsh-update)挂载行,存量 profile 凭 tombstone 导出与 retiredPlugins 清单平滑兼容。
Windows 终端环境与生命周期加固:彻底解决 Windows 下常驻进程占用导致包目录无法删除、阻碍插件更新与重装的 ERR_PNPM_EPERM 缺陷(issue #1996),dsh-win-bash 改为通过内容校验哈希将可执行载荷解包至 <DSH_HOME>/win-bash/runtime/<key> 包外目录运行;每个 shell 进程退出、超时、中止或任务取消时,强制回收其专属私有临时目录,并在插件挂载时自动清理孤儿目录(issue #1993)。
浏览器视图支持带选区与缩放的高清 PNG 截图:dsh-browser-view 的 browser_screenshot 工具支持 clip(CSS 像素裁剪矩形,无缝承接 browser_snapshot 节点外框)、scale(1x/2x/3x 缩放)与 format(默认 png 无损格式),避免全视口低画质 JPEG 压缩丢失微小界面细节或过度消耗模型视觉 Token 预算,支持基于当前标签页真实视口规格规划截图。
任务看板事件流健壮性与团队配置卡片优化:修复任务看板 SSE 事件流在网络静默或写入故障时不报错导致状态镜像僵死的问题,在连接/重连时主动同步快照,并在有在途执行任务时按间隔轮询宿主对齐状态;团队协作插件设置项重构为嵌套设置卡片规范布局,修复多语言标签换行挤压与排版割裂问题;任务看板支持同步 GitHub Issue 关闭状态并按仓库分组。
四个卫星仓同版本对齐到 0.4.14:四个卫星仓先发并对齐至 0.4.14。皮肤中心(dsh-skins,ff01ddcfe00588656ade6e35a8410f91bdf8a12c)包含 intake 决策记录提交 f4c2992;宠物(dsh-pet,9ed843bccee3d2604ce0ac31f55cbde9bda97c7f)包含 review 决策记录提交 da737fc;社区插件索引(dsh-community-plugins,a58eab289e159a9e8bf9f634ef4ed09537042536)扩充至 150 条(新增 dsh-model-everything 与 dsh-composer-ease,既有条目零改写);预设中心(dsh-presets,d6828f85ac7900c02e8f5a6e1fa66e4995895cfc)纯版本对齐。

升级须知

  • 中继控制面限流预算收紧:中继控制面(dsh-market Worker)的限流窗口从 60 秒收紧至 300 秒,per-id 额度由 6 次降至 3 次,per-IP 额度调整为 60 次(按客户端 IP 原样计数);桥门(bridge door)复用同一 300 秒窗口,连接预算等效由「6 次/分钟」变为「6 次/5 分钟」。这是用户可感知的行为变化:在网络抖动或频繁断线重连时,客户端更容易触发 HTTP 429 限流响应,客户端在遇到限流时会自动按退避窗口等待。
  • 中继数据库迁移与传输模式翻转:
    • 新增 D1 迁移 0011_relay_lease_convergence_cache.sql,仅对 relay_leases 表追加三列可空字段(converged_at / token_cache / token_at),旧行读出 NULL 会自动触发重新收敛并填充缓存,无需历史数据回填;部署顺序由 scripts/deploy-market 严格保证「先 cf d1 migrations apply,再 cf deploy」。
    • 中继租约传输模式的部署默认值已由 quick 翻转为 bridge,但既有租约行保持自己记录的传输模式(upsert 的 ON CONFLICT 分支不覆写 mode 列),因此默认值翻转仅对新申领的租约生效。
  • 重启线协议第四态与旧页面兼容:dsh-plugin-manager 重启线协议新增第四态 systemd(线传输形态 {restart: {mode: 'systemd', unit}})。若宿主运行在 systemd 用户服务下,未刷新 JS 的旧前端页面点击「立即重启」会因无法识别 systemd 模式而弹出错误提示,此时只需直接刷新浏览器页面即可恢复正常交互与重启,无数据损失。
  • 聚合包退役 web-ui-update 行:家族聚合包 @linxin666/dsh-web-all 移除 web-ui-update(dsh-update)挂载行,保留 tombstone 子路径导出与 retiredPlugins 清单登记。曾将该行显式设为 disabled 的用户 profile,在每次启动时会在控制台输出一条 patch: entry "web-ui-update" not found 提示,直到用户在插件管理器中执行一次常规更新以清理孤儿覆盖配置;该提示不影响宿主正常启动,也不会造成配置或数据丢失。
  • 升级入口支持矩阵与人工迁移:
    • 升级支持矩阵沿用 0.4.13:仓库内不存在 Doctor 预启动迁移;直接执行 dsh web 不会安装新版本(仅在启动后修复插件行名);插件管理器的更新任务是唯一具备配置备份、--dump-config 预检与异常自动回滚的迁移入口。通过手工 CLI 升级会保留孤儿 disabled 覆盖行。
    • 若升级中途中断或需要手工恢复,请遵循标准三步:
      1. dsh plugin remove @linxin666/dsh-web-all(或旧包名 @linxin666/dsh-web-ui-all)
      2. dsh plugin add @linxin666/dsh-web-all@0.4.14
      3. 将 dsh.profile.bundles 中的旧包名原位替换为 @linxin666/dsh-web-all(官方 CLI 仅写入 dependencies 而不写入 bundles,遗漏此步会导致 skipping profile bundle)。若中断后 profile 出现空 dependencies 但 bundles 仍指旧名,切勿执行 dsh plugin install,直接重新执行上述三步。
  • 平台验证声明:本版在 Linux(Ubuntu x86_64)环境下完成了完整的本地门禁套件、运行时验证与发布前审计(已实测)。macOS 与 Windows 未在物理实机上验证;未经验证的具体面包括:dsh-win-bash 的包外载荷解包与私有临时目录回收(Windows 专属代码路径,仅经单平台 CI 自动化测试覆盖)、dsh-plugin-manager 的 systemd 重启分支在生产用户环境的表现(本地仅通过单测与临时 unit 桩验证,未覆盖复杂 cgroup 嵌套)、以及 Windows 下插件管理器的文件权限、重命名与备份逻辑。

新功能

  • [remote-bridge] 支持按订阅层级路由中继租约
  • [remote-bridge] 支持自定义中继控制面基址与公共后缀
  • [remote-bridge] 重塑配对面板文案并展示 iOS 测试群链接
  • [browser-view] 支持带选区裁剪(clip)与缩放(scale)的高清 PNG 截图
  • [market] 使用 Cloudflare 官方 cf CLI 部署 Workers 与 D1 迁移
  • [dsh-web-all] 家族聚合包退役 dsh-update 挂载行
  • [task-board] 支持同步 GitHub Issue 关闭状态并按仓库分组展示

修复

  • [remote-bridge] 推送中继缺省地址指向 App 真正使用的账号服务
  • [plugin-manager] 宿主由 systemd 用户服务拉起时请求当前 unit 重启
  • [market] 在入库绑定前校验 tunnel id 避免生成 undefined 导致 D1 写入拒绝
  • [market] 向收敛缓存检查传递 lease id,避免缓存比对失效导致重复收敛
  • [market] 为桥接租约补齐所有字段占位,杜绝 undefined 绑定引发存储异常
  • [task-board-team] 团队设置卡片默认收起以契合看板设置项行为
  • [task-board-team] 团队设置区块重构为标准嵌套设置卡片
  • [market] 注册写入失败时统一返回冻结的存储故障响应
  • [win-bash] 从包外受校验缓存副本启动载荷,避免 Windows 进程锁定导致更新报 EPERM (#1996)
  • [win-bash] shell 进程结束时回收其私有临时目录并清理孤儿目录 (#1993)
  • [market] 短窗口回收原始心跳遥测并透传部署捕获输出
  • [market] 引入收敛缓存与额度守卫,避免中继申领耗尽账号 API 预算
  • [market] 桥接流加入流量控制窗口,链路异常一律返回冻结状态码
  • [market] 识别 CLI 网络层报错短语并在部署瞬态故障时自动重试
  • [git-graph] 固定 git 子进程语言为英文(LANG=C),避免覆盖守卫误判
  • [test] 允许 cohort 门禁识别工作区 overrides 声明的豁免包
  • [remote-bridge] 仅在有配对设备或需配对时按需申领中继租约,并对状态日志去重
  • [market] 账号预算耗尽时停止向 Cloudflare 发起调用
  • [remote-bridge] 将申领重试间隔上限约束在 Cloudflare 限流窗口内
  • [market] 约束中继租约 GC 范围并在账号预算耗尽时降级处理
  • [remote-bridge] 推送通知中携带审批类通知的 category 标识以便渲染交互按钮
  • [task-board] 及时关闭挂起的 SSE 事件流并在存在在途任务时轮询校验状态
  • [plugin-manager] 检测到 bundle 选择未写入 profile 时判定安装失败
  • [plugin-manager] 在 CLI 创建的 profile 上真正清理指向已退役行的孤儿覆盖行
  • [plugin-manager] 迁移回滚检查移除新包退出码并在失败时如实报告未完成
  • [plugin-manager] 允许更新启动预检失败后直接重试重装而不受 409 拦截

其他改动

  • [remote-bridge] 记录 local1 测试机显式配置中继地址的原因
  • [notes] 记录桥接流控栅栏判定机制与静默等待窗口
  • [remote-bridge] 用拒绝栅栏替代固定 sleep 等待,明确测试静默窗口
  • [market] 完善中继测试桩以拒绝 D1 不支持的非法绑定
  • [notes] 将控制面决策记录指向单一限流模块
  • [market] 统一声明中继全部 15 项限流与窗口预算至单一模块
  • [market] 固化中继代理路径的错误响应状态与响应体规范
  • [market] 钉住社区合并提交并重建商店目录(扩充至 150 个插件)
  • [archive] 记录中继申领风暴导致 Cloudflare 429 的根本原因
  • [notes] 在重试决策记录中补充 CLI 网络层报错短语
  • [notes] 记录 cohort 门禁解除桌面宿主锁定的决策
  • [notes] 记录 cohort 门禁对 overrides 声明豁免的判定逻辑
  • [deps] 为 rc.5 依赖 overrides 重新生成 pnpm-lock.yaml
  • [deps] 将工作区 @deepseek-ai 依赖钉在宿主 DSH 运行树(开发模式)
  • [notes] 记录冷启动窗口内客户端自行重建 socket 纪元的机制
  • [archive] 将切流回退步骤指向新中继备份
  • [archive] 记录实测中继回滚过程与数据
  • [archive] 记录中继切流指标读数与回滚及重入流程
  • [archive] 归档中继切流交接记录、实证与后续步骤
  • [notes] 记录已上线中继服务环境契约与 HTTP 透传边界
  • [notes] 提出将中继会合点迁移出 Cloudflare 的设计提案
  • [notes] 同步中继控制面关于预算守卫的决策记录
  • [archive] 记录桌面外壳 SSE 转发探针验证结果
  • [task-board] 记录事件流中断恢复机制与在途任务校验决策
  • [task-board] 在 README 中梳理看板镜像重新读取的 5 处入口
  • [task-board] 将事件流异常纳入看板镜像重新读取触发条件

English

This release focuses on control plane governance, cross-platform runtime hardening, and low-level protocol resilience: the Workshop (dsh-market) relay control plane has been overhauled with a convergence cache and unified rate-limit budgets to eliminate Cloudflare account API exhaustion, and its deployment pipeline is fully migrated to the Cloudflare official cf CLI; remote access (dsh-remote-bridge) corrects the default push relay address and routes relay leases by subscription tier; the plugin manager (dsh-plugin-manager) adds systemd user unit restarts and bundle landing verification; the aggregate package retires the web-ui-update row; the Windows shell (dsh-win-bash) runs payloads from a verified cache outside the package and cleans up private temporary directories upon exit to eliminate ERR_PNPM_EPERM locks; the browser view (dsh-browser-view) supports clipped and scaled lossless PNG screenshots; and dsh-git-graph pins child git processes to English to prevent overwrite guard misjudgment. The four satellite repositories align to 0.4.14.

Relay control plane overhaul and rate-limit budget tightening: The relay control plane introduces a convergence cache and a D1 account budget guard (capped at 600 calls per 5 minutes), answering active claims directly from cached state without spending Cloudflare account API quota and resolving claim storm throttles. The default transport mode flips to bridge, and leases support subscription-tier routing and multi-meeting-point distribution. D1 migration 0011 adds three nullable convergence cache columns. All 15 relay limits are unified and locked in relay-limits.js, with registration/claim and bridge connection windows tightened to 300 seconds. Relay failures return unified frozen error codes. deploy-market switches completely to the official cf CLI with network-layer retry logic, and the default push relay endpoint is corrected to the account service actually used by the mobile app.
Plugin manager adds systemd service restart and bundle landing verification: When the host runs under a systemd user service, the plugin manager identifies the cgroup and INVOCATION_ID to request a unit-level restart via systemd, adding a fourth systemd state to the restart wire protocol. A new bundle landing verification check (bundleSelectionMissing) rejects updates where build-script gates write dependencies to the profile but drop bundle entries. The aggregate package officially retires the web-ui-update (dsh-update) row, maintaining smooth compatibility for existing profiles via tombstone exports and retiredPlugins registration.
Windows shell execution and lifecycle hardening: Resolves the ERR_PNPM_EPERM package-directory lock defect on Windows (issue #1996), where persistent background bash processes blocked plugin updates and reinstalls; dsh-win-bash now unpacks and executes verified payloads outside node_modules under <DSH_HOME>/win-bash/runtime/<key>. Each shell process reclaims its private temporary directory upon termination, timeout, abort, or cancellation, and orphaned temporary directories are swept on plugin mount (issue #1993).
Browser view adds clipped and scaled lossless PNG screenshots: dsh-browser-view adds clip (CSS pixel bounding box matching browser_snapshot), scale (1x/2x/3x), and format (defaulting to lossless png) parameters to browser_screenshot, preventing fine 1-2px layout details from being lost to lossy JPEG compression or wasting vision token budgets, while planning screenshot sizes based on the tab's active viewport.
Task board event stream resilience and team settings card refinement: Resolves an issue where silent disconnects or write failures caused SSE event streams to stall without triggering browser reconnects; the transport now resynchronizes snapshots on connect/reconnect and polls in-flight tasks until settled. The team settings section is refactored into a standard nested settings card layout to prevent label squeezing and broken wrapping, and task boards support syncing GitHub issue close state grouped by repository.
The four satellite repositories align to 0.4.14: All four satellites publish first and align to 0.4.14. The skin center (dsh-skins, ff01ddcfe00588656ade6e35a8410f91bdf8a12c) includes intake decision commit f4c2992; pet (dsh-pet, 9ed843bccee3d2604ce0ac31f55cbde9bda97c7f) includes review decision commit da737fc; the community plugin index (dsh-community-plugins, a58eab289e159a9e8bf9f634ef4ed09537042536) expands to 150 plugins (adding dsh-model-everything and dsh-composer-ease with zero modifications to existing entries); and the preset center (dsh-presets, d6828f85ac7900c02e8f5a6e1fa66e4995895cfc) aligns versions cleanly.

Upgrade Notes

  • Relay Control Plane Rate Limit Budget Tightening: The rate-limit window for the relay control plane (dsh-market Worker) is tightened from 60s to 300s, the per-id budget is lowered from 6 to 3, and the per-IP budget is adjusted to 60 (counted per client IP directly); the bridge door reuses this 300s window, effectively reducing connection budgets from 6 per minute to 6 per 5 minutes. This is a user-perceptible change: under network jitter or frequent reconnects, clients are more likely to receive HTTP 429 rate-limit responses, and clients will wait according to their backoff window.
  • Relay Database Migration and Transport Mode Flip:
    • D1 migration 0011_relay_lease_convergence_cache.sql adds three nullable columns (converged_at / token_cache / token_at) to relay_leases. Legacy rows reading NULL automatically re-converge and populate the cache without requiring a backfill. The deployment sequence in scripts/deploy-market strictly enforces cf d1 migrations apply before cf deploy.
    • The default relay lease transport mode flips from quick to bridge, but existing lease rows retain their recorded transport mode (the upsert's ON CONFLICT clause does not overwrite the mode column), so the default flip only affects newly created leases.
  • Restart Protocol Fourth State and Legacy Page Compatibility: The restart wire protocol in dsh-plugin-manager adds a fourth state systemd (wire shape {restart: {mode: 'systemd', unit}}). On hosts managed by systemd user units, an unrefreshed browser page clicking Restart will display an error due to the unrecognized mode; simply refreshing the page restores normal behavior with no data loss.
  • Retirement of web-ui-update Row from Aggregate: Aggregate @linxin666/dsh-web-all removes the web-ui-update (dsh-update) mount row while maintaining tombstone subpath exports and retiredPlugins registration. Profiles that previously set this entry to disabled will log a patch: entry "web-ui-update" not found warning on startup until the user runs an update via the plugin manager; host startup and data integrity are unaffected.
  • Upgrade Entry Support Matrix and Manual Recovery:
    • The upgrade matrix follows 0.4.13: There is no Doctor pre-launch migration; executing dsh web directly does not install new versions (it only fixes row names after startup); only the plugin manager update task performs backups, --dump-config prechecks, and rollbacks. Manual CLI upgrades retain orphaned disabled override rows.
    • If manual recovery is needed, follow the three standard steps:
      1. dsh plugin remove @linxin666/dsh-web-all (or legacy name @linxin666/dsh-web-ui-all)
      2. dsh plugin add @linxin666/dsh-web-all@0.4.14
      3. In dsh.profile.bundles, in-place replace the legacy name with @linxin666/dsh-web-all (the official CLI only updates dependencies, not bundles; missing this step causes skipping profile bundle). If interrupted leaving empty dependencies while bundles points to the old name, do not run dsh plugin install; repeat the three steps above.
  • Platform Verification Notice: This release was fully verified with the complete local test suite, runtime checks, and pre-release audits on Linux (Ubuntu x86_64) (tested). macOS and Windows remain unverified on physical hardware. Unverified areas include: dsh-win-bash out-of-package runtime staging and private temp directory reclamation (Windows-specific paths covered only by single-platform CI), dsh-plugin-manager systemd restarts in production environments (verified via unit tests and mock units, but not in complex cgroup hierarchies), and file permissions, rename, and backup behavior on Windows.

New Features

  • [remote-bridge] Route relay leases by subscription tier
  • [remote-bridge] Make relay control plane base and suffix configurable
  • [remote-bridge] Reword pairing panel and link iOS beta Discord
  • [browser-view] Capture lossless PNG screenshots with clip and scale
  • [market] Deploy Cloudflare Workers and D1 migrations with official cf CLI
  • [dsh-web-all] Retire dsh-update row from aggregate package
  • [task-board] Sync GitHub issue close state and group by repository

Bug Fixes

  • [remote-bridge] Point default push relay URL to account service used by the app
  • [plugin-manager] Request systemd unit restart when host is launched by systemd user service
  • [market] Grade tunnel id before binding to prevent undefined values in D1 batch
  • [market] Pass lease id into convergence cache check to prevent redundant re-convergences
  • [market] Supply explicit nulls for bridged lease fields to eliminate undefined bindings
  • [task-board-team] Open team settings card collapsed by default
  • [task-board-team] Render team settings block as a nested settings card
  • [market] Return frozen storage failure code when registration write fails
  • [win-bash] Run payload from verified cache copy outside package to prevent EPERM locks on Windows (#1996)
  • [win-bash] Reclaim each shell's private temporary directory upon termination and sweep orphans (#1993)
  • [market] Prune raw heartbeats on short window and forward captured deployment output
  • [market] Prevent relay claim path from spending account API budget via convergence cache and guards
  • [market] Add flow-control window to bridge streams and return frozen error codes on failure
  • [market] Retry deployments on CLI network-layer failure wording
  • [git-graph] Pin git child locale to English (LANG=C) to prevent overwrite guard misjudgment
  • [test] Allow cohort gate to recognize workspace overrides as declared exemptions
  • [remote-bridge] Claim relay leases on demand and deduplicate state logs
  • [market] Stop calling Cloudflare API once account budget is exhausted
  • [remote-bridge] Cap failed claim retries within Cloudflare rate-limit window
  • [market] Bound relay lease GC and gracefully handle exhausted account budgets
  • [remote-bridge] Include approval category in push payloads to render actionable banner buttons
  • [task-board] Terminate stalled SSE event streams and poll in-flight tasks until settled
  • [plugin-manager] Fail installation when bundle selection fails to land in profile
  • [plugin-manager] Clean up orphan overrides pointing to retired rows on CLI-created profiles
  • [plugin-manager] Check exit code when removing new package during migration rollback and report incomplete status
  • [plugin-manager] Allow retrying updates directly after boot preflight failure without 409 blocking

Other Changes

  • [remote-bridge] Document reason for explicit relay URL configuration on local1 test host
  • [notes] Record bridge flow-control fence and quiet window
  • [remote-bridge] Replace fixed sleeps with refusal fences to define test quiet window
  • [market] Update relay test doubles to refuse bindings rejected by D1
  • [notes] Point control-plane note at limits module
  • [market] Consolidate all 15 relay limits and window budgets into a single module
  • [market] Pin frozen error codes and response schemas for relay proxy path
  • [market] Pin community merge commits and rebuild store catalog (expanded to 150 plugins)
  • [archive] Record root cause of Cloudflare 429 throttles from relay claim storm
  • [notes] Add CLI network-layer wording to retry note
  • [notes] Record removal of desktop host coupling from cohort gate
  • [notes] Document cohort gate declared overrides exemption logic
  • [deps] Regenerate pnpm-lock.yaml for rc.5 workspace overrides
  • [deps] Pin workspace @deepseek-ai cohort to host DSH tree (development mode)
  • [notes] Document client-initiated socket epoch recreation within cold-start window
  • [archive] Point cutover return step at new-relay backup
  • [archive] Record measured relay rollback
  • [archive] Record cutover readings and rollback/return procedure
  • [archive] Hand off relay cutover, evidence, and remaining steps
  • [notes] Record shipped relay server, env contract, and HTTP passthrough boundary
  • [notes] Propose moving relay meeting point off Cloudflare
  • [notes] Synchronize relay control-plane note with budget guards
  • [archive] Record desktop shell SSE forwarding probe results
  • [task-board] Record event stream stall recovery and in-flight verification note
  • [task-board] Document five mirror re-read entry points in README
  • [task-board] List stream error among mirror re-read trigger conditions

Don't miss a new dsh-web release

NewReleases is sending notifications on new releases.