dsh-zen-remote 2.2.4 → 2.2.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (111) hide show
  1. package/AGENTS.md +15 -3
  2. package/README.md +12 -4
  3. package/README.zh-CN.md +12 -4
  4. package/docs/interface.md +18 -1
  5. package/docs/plugin-bridge.md +1 -1
  6. package/docs/remote-access.en.md +10 -3
  7. package/docs/remote-access.md +10 -3
  8. package/lib/adapters/dsh-better-sidebar/index.js +28 -7
  9. package/lib/adapters/dsh-better-sidebar/index.js.map +1 -1
  10. package/lib/adapters/dsh-better-sidebar/methods.js +2 -0
  11. package/lib/adapters/dsh-better-sidebar/methods.js.map +1 -1
  12. package/lib/client-routes.js +3 -0
  13. package/lib/client-routes.js.map +1 -1
  14. package/lib/client.js +1164 -193
  15. package/lib/fetch-route-intercept.js +1 -1
  16. package/lib/index.js +73 -16
  17. package/lib/index.js.map +1 -1
  18. package/lib/intercept.js +13 -0
  19. package/lib/intercept.js.map +1 -1
  20. package/lib/invoke-binary.js +8 -2
  21. package/lib/invoke-binary.js.map +1 -1
  22. package/lib/lan-gate-server.cjs +109 -2
  23. package/lib/owner-peer.js +23 -0
  24. package/lib/owner-peer.js.map +1 -1
  25. package/lib/plugin-adapter-core.js +2 -2
  26. package/lib/relay-access.js +24 -2
  27. package/lib/relay-access.js.map +1 -1
  28. package/lib/relay-client.js +2 -2
  29. package/lib/relay-server.js +103 -100
  30. package/lib/relay-server.js.map +1 -1
  31. package/lib/types/adapters/dsh-better-sidebar/index.d.ts +1 -1
  32. package/lib/types/adapters/dsh-better-sidebar/index.d.ts.map +1 -1
  33. package/lib/types/adapters/dsh-better-sidebar/methods.d.ts.map +1 -1
  34. package/lib/types/client/MobileAttachButton.d.ts +5 -2
  35. package/lib/types/client/MobileAttachButton.d.ts.map +1 -1
  36. package/lib/types/client/MobileAttachChips.d.ts.map +1 -1
  37. package/lib/types/client/MobileHome.d.ts.map +1 -1
  38. package/lib/types/client/RemoteFileDownload.d.ts +57 -0
  39. package/lib/types/client/RemoteFileDownload.d.ts.map +1 -0
  40. package/lib/types/client/attach-upload.d.ts +32 -0
  41. package/lib/types/client/attach-upload.d.ts.map +1 -1
  42. package/lib/types/client/effects/remote-drop.d.ts +27 -0
  43. package/lib/types/client/effects/remote-drop.d.ts.map +1 -0
  44. package/lib/types/client/index.d.ts.map +1 -1
  45. package/lib/types/client/locales.d.ts +11 -0
  46. package/lib/types/client/locales.d.ts.map +1 -1
  47. package/lib/types/client/remote-file-save.d.ts +112 -0
  48. package/lib/types/client/remote-file-save.d.ts.map +1 -0
  49. package/lib/types/client/settings/SettingsSection.d.ts.map +1 -1
  50. package/lib/types/client/styles/compat.css.d.ts +1 -1
  51. package/lib/types/client/styles/compat.css.d.ts.map +1 -1
  52. package/lib/types/client/styles/header.css.d.ts +1 -1
  53. package/lib/types/client/styles/header.css.d.ts.map +1 -1
  54. package/lib/types/client/styles/home.css.d.ts +1 -1
  55. package/lib/types/client/styles/home.css.d.ts.map +1 -1
  56. package/lib/types/client/styles/layout.css.d.ts +1 -1
  57. package/lib/types/client/styles/layout.css.d.ts.map +1 -1
  58. package/lib/types/client/styles/remote-session.css.d.ts +1 -1
  59. package/lib/types/client/styles/remote-session.css.d.ts.map +1 -1
  60. package/lib/types/client-data/remote-drop.d.ts +99 -0
  61. package/lib/types/client-data/remote-drop.d.ts.map +1 -0
  62. package/lib/types/client-data/settings-form.d.ts +7 -0
  63. package/lib/types/client-data/settings-form.d.ts.map +1 -1
  64. package/lib/types/client-routes.d.ts +6 -0
  65. package/lib/types/client-routes.d.ts.map +1 -1
  66. package/lib/types/index.d.ts.map +1 -1
  67. package/lib/types/intercept.d.ts.map +1 -1
  68. package/lib/types/invoke-binary.d.ts +4 -1
  69. package/lib/types/invoke-binary.d.ts.map +1 -1
  70. package/lib/types/owner-peer.d.ts +9 -0
  71. package/lib/types/owner-peer.d.ts.map +1 -1
  72. package/lib/types/plugin-adapter-core.d.ts +1 -1
  73. package/lib/types/relay-access.d.ts.map +1 -1
  74. package/lib/types/relay-server.d.ts +10 -7
  75. package/lib/types/relay-server.d.ts.map +1 -1
  76. package/package.json +37 -37
  77. package/pwa/inject.js +20 -9
  78. package/pwa/sw.js +97 -21
  79. package/scripts/check-attach-upload.mjs +37 -0
  80. package/scripts/check-remote-drop.mjs +114 -0
  81. package/scripts/check-settings-form.mjs +3 -2
  82. package/scripts/check-upload-endpoint.mjs +14 -3
  83. package/src/adapters/dsh-better-sidebar/index.ts +27 -7
  84. package/src/adapters/dsh-better-sidebar/methods.ts +2 -0
  85. package/src/client/MobileAttachButton.tsx +14 -9
  86. package/src/client/MobileAttachChips.tsx +4 -0
  87. package/src/client/MobileHome.tsx +79 -12
  88. package/src/client/RemoteFileDownload.tsx +173 -0
  89. package/src/client/attach-upload.ts +47 -0
  90. package/src/client/effects/remote-drop.ts +269 -0
  91. package/src/client/index.tsx +47 -0
  92. package/src/client/locales.ts +32 -0
  93. package/src/client/remote-file-save.ts +232 -0
  94. package/src/client/settings/SettingsSection.tsx +61 -1
  95. package/src/client/styles/compat.css.ts +43 -12
  96. package/src/client/styles/header.css.ts +63 -15
  97. package/src/client/styles/home.css.ts +39 -1
  98. package/src/client/styles/layout.css.ts +24 -7
  99. package/src/client/styles/remote-session.css.ts +38 -0
  100. package/src/client-data/remote-drop.ts +127 -0
  101. package/src/client-data/settings-form.ts +10 -0
  102. package/src/client-routes.ts +8 -0
  103. package/src/fetch-route-intercept.ts +1 -1
  104. package/src/index.ts +71 -18
  105. package/src/intercept.ts +13 -0
  106. package/src/invoke-binary.ts +8 -2
  107. package/src/owner-peer.ts +32 -0
  108. package/src/plugin-adapter-core.ts +2 -2
  109. package/src/relay-access.ts +24 -2
  110. package/src/relay-client.ts +2 -2
  111. package/src/relay-server.ts +114 -90
package/AGENTS.md CHANGED
@@ -22,7 +22,7 @@
22
22
  | `src/activity.ts` | 会话活动统计 + 闲置休眠扫描(`idleHours`,运行中/等待中不计时) |
23
23
  | `src/share-ops.ts` | `agent/created` 的自动共享 / 分叉跟随 / busy 恢复 |
24
24
  | `src/share-export.ts` | 分享图路由 `GET /_dsh/mobile-nav/share-export`(完整日志折叠人类转写) |
25
- | `src/relay-server.ts` | 服务端中继路由 `/_dsh/zen-remote/relay/*`:ping / handshake / invoke / NDJSON stream / event-result / `v1/http`(改动摘要 / diff 的 plain-HTTP 直通,进程内交宿主 `/api` 共享 handler)/ unshare |
25
+ | `src/relay-server.ts` | 服务端中继路由 `/_dsh/zen-remote/relay/*`:ping / handshake / invoke / NDJSON stream / event-result / `v1/http`(改动摘要 / diff 的 plain-HTTP 直通,进程内交宿主 `/api` 共享 handler)/ `v1/upload`(远程会话附件字节转宿主暂存,返回回执)/ unshare |
26
26
  | `src/relay-access.ts` | 中继的按方法登记访问控制表(服务端那一张;`v1/http` 的按路由登记表也在这里) |
27
27
  | `src/relay-filter.ts` | 全局流与全局列表的输出过滤(`workspace/follow` / `session/control` / `session/list` / @ 引用候选行) |
28
28
  | `src/session-reference.ts` | 两端共用的 `dsh-session:` 引用编解码与「可注入文本」扫描规则(prompt content、排队消息 edit、`commands/execute` 全部字符串):服务端照它校验、子客户端照它改写,同一份规则防两端漂移 |
@@ -36,7 +36,7 @@
36
36
  | `src/adapters/` | 适配器目录(PB-11):`index.ts` 只导出 `ADAPTERS` 数组(本单为空,PB-12 加第一个),`types.ts` 放适配器作者接口,实现各占一个子目录;**除 `src/index.ts` 接线外任何文件不得 import 此目录**,适配器实现只可 import `types.ts` 与纯工具 |
37
37
  | `src/client-data/plugin-bridge.ts` | 设置页纯函数(PB-5):桥接状态 → 文案键、整机数据同意表的切换(只动一键);浏览器半边,不 import 主包 |
38
38
  | `src/fetch-route-intercept.ts` | 子客户端本机拦截的第二半:包装宿主连接服务 `fetchRoutes` 表的上传与导出两项——远程会话的非图片附件经 `relay/v1/upload` 流式转服务端(超限本地拒、失败回宿主自己的 200 失败信封)、虚拟 id 的导出后台 403(形态检测、懒装重试、卸载守卫) |
39
- | `src/virtual-id.ts` | `zr~<serverId>~<id>` 虚拟 id 算术(纯函数,无状态) |
39
+ | `src/virtual-id.ts` | `zr~<serverId>~<id>` 虚拟 id 算术(纯函数、零依赖;client-data 半边许可 import 它做 zr~ 判定,先例 remote-drop.ts / remote-status.ts) |
40
40
  | `src/merge-streams.ts` | 三条全局流/列表的本地 + 远程合并状态机(侧边栏远程分组) |
41
41
  | `src/fingerprint.ts` | DSH 接口指纹:规范化描述符 → 分组 JSON Schema 哈希,供握手比对 |
42
42
  | `src/restart-fields.ts` / `restart-watcher.ts` | 需重启字段的指纹监测,变化即重载插件行 |
@@ -137,9 +137,21 @@ workflow 自带的 `GITHUB_TOKEN`,不需要额外密钥——但 job 的 `perm
137
137
  - **CSS 分工没变**:排版类规则在 `src/client/styles/`;`pwa/app.css` 只留壳级
138
138
  规则(iOS 输入框防缩放、安全区滚动补偿、代码块横向滚动)。两边抢同一个元素
139
139
  是历史事故的根源,加规则前先确认归属。
140
- - **`lib/` 是产物,不手改**:改 `src/` → `pnpm build` → 提交 `lib/`。
140
+ - **`lib/` 是产物,不手改**:改 `src/` → `pnpm build` → 提交 `lib/`。**删 src 时必须手动 `git rm` 对应 lib 产物**:tsc 只增量写、从不清理已删源文件的旧产物,CI 的 `git diff --exit-code -- lib` 关卡对死产物全盲(2026-10-24 PR #34 吸收剥离踩过,靠对抗审查拦下)。
141
141
  - **桌面必须 no-op**:≥1024px 逐像素与未安装时一致。
142
142
  是从真机事故里攒出来的,改相关代码前先读。
143
+ - **首帧壳只能内联注入**:冷启动占位壳由网关 `injectBootShell` 写进第一帧
144
+ HTML(`BOOT_SHELL_*`),DSH 一往 `#root` 渲染就同步摘掉。壳的 CSS/标记/脚本
145
+ 都是网关里的内联常量(不放进 `pwa/app.css` 或客户端样式),带 30s CSS 渐隐
146
+ 兜底;移除脚本有真实 vm 用例(DCL / 晚渲染 / `#root` 缺失 / 保险丝)。不能
147
+ 挪进客户端插件——那个 bundle 正是首帧要等的东西;不能引入额外请求;显式
148
+ `desktop` 设备不注入、≥1024px 由 CSS 隐藏。`test/gateway.test.cjs` 钉住。
149
+ - **长缓存只给内容寻址 URL**:网关只给 `/assets/` 下**哈希形状**(8+ 位且含
150
+ 数字或大小写混合,排除 `vendor-bootstrap.css` 这类普通词)、且响应不是 HTML
151
+ 的文件补 `immutable`(上游已有缓存头时让上游说话);service worker 只对同一
152
+ 判定与 `?rev=<hex 构建修订>`(DSH 按 mtime/ctime/size 生成,且 DSH 自己已
153
+ 按 immutable 提供)的插件批次缓存优先;响应类型必须与 URL 声明一致,
154
+ HTML/错误页不得存进资源缓存。给无哈希 URL 做长缓存就是重演 v2 的「新 DOM + 旧 CSS」事故。
143
155
  - **要藏宿主刚渲染出来的东西,别用 `requestAnimationFrame`**:React 在该帧的
144
156
  rAF 阶段之后才提交 DOM,所以从 mutation 里排的 rAF 落在**下一帧**——中间那
145
157
  一帧已经画到屏幕上,用户就看见闪。两个月内三次「晚一帧」的 bug(2026-08-18
package/README.md CHANGED
@@ -94,7 +94,7 @@ dsh plugin --profile web add dsh-zen-remote
94
94
  // ~/.dsh/profiles/desktop/package.json
95
95
  {
96
96
  "dependencies": {
97
- "dsh-zen-remote": "^2.2.4" // for local development: "link:/path/to/dsh-zen-remote"
97
+ "dsh-zen-remote": "^2.2.6" // for local development: "link:/path/to/dsh-zen-remote"
98
98
  }
99
99
  }
100
100
  ```
@@ -296,6 +296,7 @@ The `push_notify` tool. The model should call it when you explicitly asked to be
296
296
  - Turn-process folding, left-edge swipe back, Android back-gesture takeover, phone-local attachment upload
297
297
  - A pairing code buys a long-lived device token; identity follows the token, not the IP, revocable at any time
298
298
  - Real PWA + real Web Push (VAPID + aes128gcm), firing only for approvals and questions by default
299
+ - Cold start paints an app-shaped skeleton from the first HTML byte; content-hashed build assets are cached for a year, so a repeat open reuses the shell instead of re-downloading it
299
300
 
300
301
  **Host (2.0 additions)**
301
302
 
@@ -305,7 +306,8 @@ The `push_notify` tool. The model should call it when you explicitly asked to be
305
306
  **Desktop client (2.0 additions)**
306
307
 
307
308
  - Remote groups in the sidebar ("server name · workspace name"), remote sessions open like local ones: full history, live progress, messages, cancels, queue edits, approvals and question answers, model selection, file tree, changes list plus changes summary/diff, goals, slash commands, agent presets, subagent prompts/interrupts, attachments and @ references, terminals running server-side
308
- - Remote sessions can attach **non-image files**: the upload request is caught by the sub-client's own backend and streamed through the relay to the server session; the 100 MiB cap is the relay's own (local uploads have no such limit), an over-limit pick is refused locally on the client with a readable message, and slow links are bounded by the 300-second timeout
309
+ - Artifacts a remote session produces can be **downloaded to this computer**: the deliverable card and the document preview header each carry a "download to this computer" action that reads the host file through the relay in byte windows (any file size, never held whole in memory) and hands it to the browser; Word/Excel/PPT previews are now rendered to PDF by the host's LibreOffice (`officeToPdf/*` is on the relay allowlist) instead of failing with "not supported in remote sessions"
310
+ - Remote sessions can attach **non-image files**: the upload request is caught by the sub-client's own backend and streamed through the relay to the server session; the 500 MiB cap is the relay's own (local uploads have no such limit), an over-limit pick is refused locally on the client with a readable message, and slow links are bounded by the client's 15-minute upload budget (the host HTTP server's 5-minute request deadline is the practical ceiling: 500 MiB needs ~14 Mbps sustained).
309
311
  - The model picker in a remote session lists the **server's** model catalog (groups named "server name · group name"), local sessions list only local models; the last-fetched server groups survive while the relay is offline; server groups never appear in local settings such as the vision router. Known boundary: a session created on the server that has never sent a message shows the local default model in the picker
310
312
  - New sessions created inside a remote group run on the server's workspace and are shared automatically; remote sessions can be renamed, archived, pinned, forked, and their remote access closed (with confirmation) from the client
311
313
  - Title-row connection icon per remote session (online / offline / version differs); a "remote closed" banner with the reason when a session is slept or closed server-side; offline groups go grey with input disabled and reconnect automatically with backoff
@@ -315,6 +317,10 @@ The `push_notify` tool. The model should call it when you explicitly asked to be
315
317
 
316
318
  - The **plugin bridge**: another plugin registers one bridge declaration and its panel data in remote sessions is served by the HOST — the sub-client reroutes the declared GET requests to the server, which executes them over loopback and streams the answer back; local data never leaks into a remote session. Bridged requires the plugin name, exact version and declaration to agree on BOTH ends; whole-machine data additionally needs the server owner's per-plugin consent in the settings page. Author guide: [the plugin bridge](docs/plugin-bridge.md)
317
319
 
320
+ **Desktop client (2.2 additions)**
321
+
322
+ - Dragging files into a remote session attaches them by **upload**: the desktop app's same-machine shortcut (a dragged file keeps its disk path and would become an `@absolute path` mention naming a file on YOUR machine, unreadable on the server) is intercepted in the browser and the drop is re-shaped into an ordinary upload — the same relay path as the attach button, so the server session gets the bytes. Dragging a **folder** into a remote session is not supported: the drop is stopped with a short on-screen notice. Local sessions are untouched — the shortcut keeps working there — and the guard's status is visible in the settings page diagnostics.
323
+
318
324
  In depth: [interface](docs/interface.md) · [public access + relay protocol](docs/remote-access.en.md)
319
325
 
320
326
  ---
@@ -346,7 +352,7 @@ What a paired device is trusted with, stated plainly:
346
352
  - "Export session" is disabled in a remote session (the menu item is hidden, and the backend refuses virtual session ids); the changes panel's **summary and diff do work** (relayed), while the entries that would pop a dialog on the server machine — "open", "reveal in Finder", "open in app", on the changes panel and deliverable cards alike — are hidden there.
347
353
  - The host truncates @-mention candidates to the **first 50 rows before** share-filtering: on a server with many sessions, a shared one may be missing from the candidate list (the reference check itself is unaffected — references you type out are still verified one by one).
348
354
  - A third-party plugin's own endpoints work in remote sessions only through the [plugin bridge](docs/plugin-bridge.md): cooperative plugins register themselves, third-party plugins are covered by built-in adapters. A plugin with neither has its panels degraded or hidden in remote sessions (its **tools** still run on the server, unaffected).
349
- - With [dsh-better-sidebar](https://github.com/omdsh-dev/DSH-better-sidebar) installed, remote sessions have TWO treatments: **0.25.0, 0.26.0 and 0.26.1** are bridged by zen-remote's built-in adapter — its file / git / task panels read and write the SERVER's data in a remote session (consent required, see the security boundary doc). Any OTHER version keeps the hide-local-surfaces treatment: its surfaces are hidden in remote sessions because they would read and write the **client machine's own** files; and because 0.19+ takes over the host's "Files" tab, an unbridged remote session has no sidebar file browser for now; file links in chat or deliverables open an empty right column in a remote session.
355
+ - With [dsh-better-sidebar](https://github.com/omdsh-dev/DSH-better-sidebar) installed, remote sessions have TWO treatments: **0.25.0, 0.26.0, 0.26.1, 0.28.0-alpha.0 and 0.28.0** are bridged by zen-remote's built-in adapter — its file / git / task panels read and write the SERVER's data in a remote session (consent required, see the security boundary doc). Any OTHER version keeps the hide-local-surfaces treatment: its surfaces are hidden in remote sessions because they would read and write the **client machine's own** files; and because 0.19+ takes over the host's "Files" tab, an unbridged remote session has no sidebar file browser for now; file links in chat or deliverables open an empty right column in a remote session.
350
356
  - Both ends need the **same zen-remote version** (identical relay protocol version). DSH versions may differ; interface differences are annotated "(版本有差异)".
351
357
 
352
358
  ---
@@ -355,6 +361,8 @@ What a paired device is trusted with, stated plainly:
355
361
 
356
362
  **iOS 26.x standalone PWA viewport shrinkage**: after adding to the home screen, the viewport loses a status-bar's height at the bottom; an ordinary Safari tab is fine. This is an iOS defect — the missing region is outside the document and CSS cannot reach it. The plugin ships three layers of mitigation (light manifest background, safe-area compensation, forced reflow) which reduce it without guaranteeing a fix. Only quitting and reopening the whole app restores it fully.
357
363
 
364
+ **iOS 26+ standalone PWA system top progressive blur**: when opened from the home screen on iOS 26+, WebKit draws a system-level scroll-edge progressive blur (`WKScrollPocket` / `UIScrollEdgeEffect`) across the top ~95px of the window (status bar plus the upper half of the top bar). Because it is an OS compositor layer outside the DOM, page CSS cannot remove it directly; entering a session and returning to the session list clears it on the list page. Android and regular Safari tabs are unaffected.
365
+
358
366
  **In a few environments the soft keyboard is completely invisible to the browser, and the lift falls back to an estimate**: in some combinations the system never tells the page the keyboard's height (visualViewport and the VirtualKeyboard API both fail; both ruled out by measurement). The fallback probes for ~1.2s after focus and lifts the input box by an estimated height when the keyboard is judged invisible. If the lift is visibly off, tune `keyboardLiftRatio` / `keyboardLiftMaxPx` / `keyboardSafetyPadPx` in the settings page. Normal environments never take this path.
359
367
 
360
368
  **Settings pages don't open through the reverse proxy** (the plugin config list is blank, model cards report "settings are unavailable in this browser"): DSH's settings RPCs are loopback-only by design — a remote browser's settings mirror starts out `unavailable`. Workaround: change settings from a browser on the machine running DSH. The gateway-forwarded plugin settings page shows the same limitation. Nothing to do with this plugin.
@@ -377,7 +385,7 @@ The mobile UI has specific adaptations for the plugins below. Every adaptation i
377
385
 
378
386
  | Plugin | What the mobile adaptation does | Version tested |
379
387
  | --- | --- | --- |
380
- | [dsh-better-sidebar](https://github.com/omdsh-dev/DSH-better-sidebar) | 0.19+: all its tabs live in DSH 0.1.5's native right sidebar, which the host takes full screen on a phone (padded clear of the notch / home indicator) — the session header keeps an entry button for it, the left-edge swipe-back closes it, and tapping an @-reference in the file tree closes it. ≤ 0.18 (own right panel, DSH < 0.1.5 only): full-width phone drawer with notch safe area and a centred close pill. **Plugin bridge**: **0.25.0, 0.26.0 and 0.26.1** are bridged by zen-remote’s built-in adapter — in remote sessions its file / git / task panels read and write the SERVER’s data (whole-machine data, per-plugin consent on the server’s settings page; that equals whole-disk access and git writes on the server, see the [security boundary](docs/remote-access.md)); any other version stays unbridged and keeps the hide-local-surfaces treatment | 0.19.1 (legacy rules: 0.15.0; adapter: 0.25.0, 0.26.0, 0.26.1) |
388
+ | [dsh-better-sidebar](https://github.com/omdsh-dev/DSH-better-sidebar) | 0.19+: all its tabs live in DSH 0.1.5's native right sidebar, which the host takes full screen on a phone (padded clear of the notch / home indicator) — the session header keeps an entry button for it, the left-edge swipe-back closes it, and tapping an @-reference in the file tree closes it. ≤ 0.18 (own right panel, DSH < 0.1.5 only): full-width phone drawer with notch safe area and a centred close pill. **Plugin bridge**: **0.25.0, 0.26.0, 0.26.1, 0.28.0-alpha.0 and 0.28.0** are bridged by zen-remote’s built-in adapter — in remote sessions its file / git / task panels read and write the SERVER’s data (whole-machine data, per-plugin consent on the server’s settings page; that equals whole-disk access and git writes on the server, see the [security boundary](docs/remote-access.md)); any other version stays unbridged and keeps the hide-local-surfaces treatment | 0.19.1 (legacy rules: 0.15.0; adapter: 0.25.0, 0.26.0, 0.26.1, 0.28.0-alpha.0, 0.28.0) |
381
389
  | [@nanmicoder/dsh-agent-teams](https://github.com/NanmiCoder/dsh-agent-teams) | The AgentTeams activity overlay moves below the session header (its original position covered the header buttons) and hides itself on the session list; a subagent session keeps a tappable parent-session title in its header for jumping back | 0.1.9 |
382
390
  | [@ychris12138/dsh-usage-stats](https://github.com/Ychris12138/dsh-usage-stats) | Usage and balance entries fold into the home-screen chips row | 0.2.9 |
383
391
  | [@opendsh/dsh-plugin-scheduled-tasks](https://github.com/Ceelog/dsh-plugins) | The scheduled-tasks entry folds into the home-screen chips row | 0.2.3 |
package/README.zh-CN.md CHANGED
@@ -94,7 +94,7 @@ dsh plugin --profile web add dsh-zen-remote
94
94
  // ~/.dsh/profiles/desktop/package.json
95
95
  {
96
96
  "dependencies": {
97
- "dsh-zen-remote": "^2.2.4" // 本地开发换成 "link:/path/to/dsh-zen-remote"
97
+ "dsh-zen-remote": "^2.2.6" // 本地开发换成 "link:/path/to/dsh-zen-remote"
98
98
  }
99
99
  }
100
100
  ```
@@ -296,6 +296,7 @@ cd ~/.dsh/profiles/desktop && pnpm install
296
296
  - 回合过程折叠、左缘右滑返回、安卓返回手势接管、手机本地附件上传
297
297
  - 配对码换长期设备令牌,认令牌不认 IP,可随时吊销
298
298
  - 真 PWA + 真 Web Push(VAPID + aes128gcm),默认只在等授权/等回答时响
299
+ - 冷启动从第一帧就画出手机主屏骨架;带内容哈希的构建产物长缓存,重复打开不再重下应用壳
299
300
 
300
301
  **主服务端(2.0 新增)**
301
302
 
@@ -305,7 +306,8 @@ cd ~/.dsh/profiles/desktop && pnpm install
305
306
  **桌面应用端(2.0 新增)**
306
307
 
307
308
  - 侧边栏远程分组(「服务端名 · 工作区名」),远程会话与本地会话同等使用:完整历史、实时进度、发消息、取消、排队调整、审批与提问应答、模型选择、文件树、改动列表与改动摘要 / diff、目标、斜杠命令、预设切换、子智能体提问/中断、附件与 @ 引用、开在服务端的终端
308
- - 远程会话可附加**非图片文件**:上传请求由子客户端在本机后台接住、经中继流式转到服务端会话;上限 100 MiB 是中继自定的(本机上传无此限),超限在子客户端本地即提示;慢速链路受 300 秒超时约束
309
+ - 远程会话里的产物文件可**下载到本机**:产出台卡片与文档预览头各一个「下载到本机」,经中继按窗口读取服务端文件字节后由浏览器落盘(任何大小的文件都走分段读取,不占满内存);Word/Excel/PPT 预览改由服务端 LibreOffice 出 PDF(`officeToPdf/*` 已登记进中继白名单),不再报「此功能暂不支持远程会话」
310
+ - 远程会话可附加**非图片文件**:上传请求由子客户端在本机后台接住、经中继流式转到服务端会话;上限 500 MiB 是中继自定的(本机上传无此限),超限在子客户端本地即提示;慢速链路受客户端侧 15 分钟上传预算约束(宿主 HTTP 服务的 5 分钟请求期限才是实际上限:500 MiB 约需 14 Mbps 持续带宽)
309
311
  - 远程会话里的模型下拉框显示**服务端**的模型目录(分组名「服务端名 · 分组名」),本机会话只显示本机模型;中继离线时保留上次拉到的服务端分组;视觉路由等本机设置里不会出现服务端分组。已知边界:服务端新建且未发过消息的会话,下拉框按本机默认模型显示
310
312
  - 远程分组里新建的会话跑在服务端对应工作区、自动开启远程;远程会话可改名、归档、置顶、分叉,也可从子客户端关闭其远程(带确认)
311
313
  - 远程会话标题行连接图标(在线 / 离线 / 版本有差异);会话被休眠或服务端关闭时显示「远程已关闭」及原因;服务端离线时分组变灰、输入禁用,后台自动退避重连
@@ -315,6 +317,10 @@ cd ~/.dsh/profiles/desktop && pnpm install
315
317
 
316
318
  - **插件桥**:其他插件登记一份桥接声明后,它的面板数据在远程会话里取自主服务端——子客户端本机把声明命中的 GET 请求改道到服务端,服务端以本机回环执行、流式交回,本机数据绝不混入远程会话。两端插件名、确切版本与声明一致才算已桥接;整机数据另需主服务端主人在设置页逐插件同意。接入指南见[插件桥](docs/plugin-bridge.md)
317
319
 
320
+ **桌面应用端(2.2 新增)**
321
+
322
+ - 往远程会话里拖文件一律走**上传**:桌面端原本有「同机零拷贝」捷径——拖入的文件带着本机磁盘路径,会被变成 `@本机绝对路径` 的引用(服务端读不到你这台机器上的文件)。浏览器半边把这个拖拽拦截下来,改写成普通上传——与附件按钮同一条中继链路,服务端会话拿到的是文件字节。往远程会话拖**文件夹**暂不支持:拖拽会被拦下并短暂提示。本机会话不受影响,捷径照常;守卫的状态可在设置页诊断区查看。
323
+
318
324
  深度说明:[界面](docs/interface.md) · [公网接入 + 中继协议](docs/remote-access.md)
319
325
 
320
326
  ---
@@ -346,7 +352,7 @@ cd ~/.dsh/profiles/desktop && pnpm install
346
352
  - 远程会话里「导出会话」已禁用(菜单项隐藏,后台对虚拟会话 id 一律拒绝);改动面板的**摘要与 diff 可以看**(经中继转发),但「打开 / 在访达中显示 / 在应用中打开」这类会在服务端机器上弹窗的入口在远程会话里隐藏(交付物卡片同理)。
347
353
  - @ 引用候选由宿主**先截前 50 条再按共享过滤**:服务端会话很多时,已共享会话可能不出现在候选列表里(不影响引用检查本身——直接写出的引用仍会被逐条校验)。
348
354
  - 第三方插件自己的接口要经[插件桥](docs/plugin-bridge.md)才能在远程会话里工作:协作插件自行登记,第三方插件靠内置适配器。都没接的插件,其面板在远程会话里降级或隐藏(插件的**工具**跑在服务端,不受影响)。
349
- - 装了 [dsh-better-sidebar](https://github.com/omdsh-dev/DSH-better-sidebar) 时,远程会话里它有两档处理:**0.25.0、0.26.0 与 0.26.1** 三版由内置适配器桥接——面板读写的是主服务端的数据(整机数据,需在主服务端设置页逐插件同意,见[安全边界](docs/remote-access.md));**其他版本维持隐藏**——那些版本的面板读写的是子客户端**本机**的文件,且因为它接管了宿主的「文件」标签,未桥接的远程会话里侧栏文件 tab 显示「未桥接」说明占位;聊天或交付物里的文件链接在远程会话里会打开一个空的右栏。
355
+ - 装了 [dsh-better-sidebar](https://github.com/omdsh-dev/DSH-better-sidebar) 时,远程会话里它有两档处理:**0.25.0、0.26.0、0.26.1、0.28.0-alpha.0 与 0.28.0** 五版由内置适配器桥接——面板读写的是主服务端的数据(整机数据,需在主服务端设置页逐插件同意,见[安全边界](docs/remote-access.md));**其他版本维持隐藏**——那些版本的面板读写的是子客户端**本机**的文件,且因为它接管了宿主的「文件」标签,未桥接的远程会话里侧栏文件 tab 显示「未桥接」说明占位;聊天或交付物里的文件链接在远程会话里会打开一个空的右栏。
350
356
  - 两端 zen-remote 需为**相同版本**(中继协议版本一致);DSH 版本可以不同,接口指纹有差异时远程分组标注「(版本有差异)」。
351
357
 
352
358
  ---
@@ -355,6 +361,8 @@ cd ~/.dsh/profiles/desktop && pnpm install
355
361
 
356
362
  **iOS 26.x 独立 PWA 视口缩水**:加到主屏后视口底部会少掉一条状态栏高度,普通 Safari 标签页正常。这是 iOS 系统缺陷,缺掉的区域在文档之外,CSS 够不着;本插件做了三层缓解(浅色 manifest 背景 + 安全区补偿 + 强制重排),能减轻但不保证复原。彻底恢复只能整个 App 退出重开。
357
363
 
364
+ **iOS 26+ 独立 PWA 窗口顶部系统渐进模糊**:加到主屏后从桌面打开时,iOS WebKit 会在窗口顶部约 95px 区域(状态栏至顶栏上半截)叠加一层系统级滚动边缘模糊遮罩(`WKScrollPocket` / `UIScrollEdgeEffect`)。该遮罩由系统合成层绘制在网页 DOM 之外,CSS 无法直接消除;点进任意会话再退回会话列表页即可在列表页恢复正常。Android 与普通 Safari 标签页不受影响。
365
+
358
366
  **个别环境软键盘对浏览器完全不可见,输入框抬升靠估算兜底**:部分组合里系统不把键盘高度告知页面(visualViewport、VirtualKeyboard API 一并失效,均已实测排除)。插件聚焦后探测约 1.2 秒,判定「键盘不可见」就按估计高度抬升输入框。抬升高度差得明显的话,在设置页里调 `keyboardLiftRatio` / `keyboardLiftMaxPx` / `keyboardSafetyPadPx`。正常环境完全不走这条路径。
359
367
 
360
368
  **经反代访问时设置页打不开**(插件配置列表空白、模型卡片报「settings are unavailable in this browser」):DSH 官方设计是设置类 RPC 只对回环连接开放,远程浏览器的设置镜像初始即 `unavailable`。绕法:回跑 DSH 的那台机器用本机浏览器改。经网关打开的插件设置页同样受此限制。与本插件无关。
@@ -378,7 +386,7 @@ cd ~/.dsh/profiles/desktop && pnpm install
378
386
 
379
387
  | 插件 | 移动端适配内容 | 实测版本 |
380
388
  | --- | --- | --- |
381
- | [dsh-better-sidebar](https://github.com/omdsh-dev/DSH-better-sidebar) | 0.19+:它的全部 tab 都在 DSH 0.1.5 官方右侧栏里、手机上宿主自己切全屏(避让刘海与底部指示条)——会话页头部留入口按钮,左缘回退手势收它,文件树里点 @ 引用后自动收起。≤ 0.18(自绘右栏,只在 DSH < 0.1.5 上):手机全宽抽屉并避让刘海安全区、底部居中的关闭按钮。**插件桥**:**0.25.0、0.26.0 与 0.26.1** 三版由 zen-remote 的内置适配器桥接——远程会话里它的文件 / git / 任务面板读写的是主服务端的数据(整机数据,需在主服务端设置页逐插件同意;等于让桌面应用端读写服务端整盘并执行 git 写操作,见[安全边界](docs/remote-access.md));其他版本不桥接,远程会话维持「隐藏本机界面」的原有处理 | 0.19.1(老版规则 0.15.0;适配器 0.25.0, 0.26.0, 0.26.1) |
389
+ | [dsh-better-sidebar](https://github.com/omdsh-dev/DSH-better-sidebar) | 0.19+:它的全部 tab 都在 DSH 0.1.5 官方右侧栏里、手机上宿主自己切全屏(避让刘海与底部指示条)——会话页头部留入口按钮,左缘回退手势收它,文件树里点 @ 引用后自动收起。≤ 0.18(自绘右栏,只在 DSH < 0.1.5 上):手机全宽抽屉并避让刘海安全区、底部居中的关闭按钮。**插件桥**:**0.25.0、0.26.0、0.26.1、0.28.0-alpha.0 与 0.28.0** 五版由 zen-remote 的内置适配器桥接——远程会话里它的文件 / git / 任务面板读写的是主服务端的数据(整机数据,需在主服务端设置页逐插件同意;等于让桌面应用端读写服务端整盘并执行 git 写操作,见[安全边界](docs/remote-access.md));其他版本不桥接,远程会话维持「隐藏本机界面」的原有处理 | 0.19.1(老版规则 0.15.0;适配器 0.25.0, 0.26.0, 0.26.1, 0.28.0-alpha.0, 0.28.0) |
382
390
  | [@nanmicoder/dsh-agent-teams](https://github.com/NanmiCoder/dsh-agent-teams) | AgentTeams 活动浮层挪到会话头部下方(原位置压住头部按钮)、会话列表页自动隐藏;子代理会话头部保留可点的父会话标题,一键切回主会话 | 0.1.9 |
383
391
  | [@ychris12138/dsh-usage-stats](https://github.com/Ychris12138/dsh-usage-stats) | 用量与余额入口收进主屏 chips 行 | 0.2.9 |
384
392
  | [@opendsh/dsh-plugin-scheduled-tasks](https://github.com/Ceelog/dsh-plugins) | 定时任务入口收进主屏 chips 行 | 0.2.3 |
package/docs/interface.md CHANGED
@@ -35,6 +35,7 @@ v1.0.0(fork 自 [mexiaosqwq/dsh-web-mobile](https://github.com/mexiaosqwq/dsh-
35
35
 
36
36
  - **远程分组**:侧边栏在本地工作区后面按「服务端名 · 工作区名」多出几组,默认收起,里面是服务端已开启远程的会话;服务端的工作区只有其中至少一个会话开启了远程才会成组——没动过的工作区不显示成空分组,已显示过的分组里会话全部关闭后空分组留到刷新页面(DSH 界面对移除过的工作区 id 不再接受,见根 README 已知限制);服务端离线时分组标注「(离线)」、输入禁用、后台退避重连;解配 / 吊销保留分组只换标注,这两种状态同样禁用输入、也不等自动重连(只能从设置页重新配对才恢复);仅当换到另一台服务端才整组移除;
37
37
  - **标题行连接图标**(同一槽位,order 26):每个远程会话的连接状态——在线 / 离线 / 版本有差异;点击可关闭该会话的远程(二次确认,文案写明「关闭后需要在服务端重新开启」);
38
+ - **产物下载**:产出台的卡片(`deliverables.file.actions`,order 40)与文档预览头(`sidebar.right.tab.document.actions`,order 40)各多一个「下载到本机」。远程会话里官方只有「预览」和「在服务端机器上打开」,产物此前无法落到子客户端磁盘——这个按钮用中继已放行的 `workspaceFiles/readBytes` 按窗口(默认 2 MiB,宿主的 `maxBytes` 更小时按 `details.limit` 自动缩小)读回字节,再由浏览器落盘;卡片上的入口从卡片自己的预览按钮 `title`(宿主 `resolveWorkspacePath` 的绝对路径)取路径,预览头直接用 owner 给的 `absolutePath`。两个入口都只在虚拟 id 会话渲染,主服务端与本地会话逐像素 no-op。同一版起 Word/Excel/PPT 预览改由**服务端** LibreOffice 出 PDF(`officeToPdf/render` 登记进中继白名单,PDF 字节走 `INVOKE_BINARY_RESULT_METHODS` 标记),不再报「此功能暂不支持远程会话」。
38
39
  - **composer 横幅**(`conversation.input.dock`,order 15):四种状态——会话被休眠或服务端关闭时显示「远程已关闭」及原因;服务端离线显示「暂时只读,恢复连接后自动可用」;令牌被吊销、解除配对也显示横幅(这两者不会自己恢复,文案指向设置页重新配对)。横幅出现的同时**输入一律禁用**,禁用走宿主自己的 composer-block 契约(`ctx.conversation.blocks.set(sessionId, { reason })`,输入框、发送钮与模型控件一起禁掉,`reason` 成为占位文案),链接恢复或组件卸载时清除,不碰宿主 DOM;
39
40
  - 面板长尾:远程会话里带会话 id 的调用自动走中继;改动摘要 / diff 是例外路径——它们不走 typert 网关而是 plain-HTTP GET,浏览器侧的 fetch 包装把带虚拟 id 的 `/api/changes.*` 请求改写到子客户端路由 `/_dsh/zen-remote/client/http/<route>` 再经中继;离线时写一律本地拒绝,`terminal/follow` 也按写处理(它的附带会接管终端的输入控制权,离线放行等于悄悄抢走一条不在线连接的控制权,所以离线即拒绝);认不准数据来源的面板直接隐藏,而不是显示本机错误数据(清单见根 README「已知限制」)。
40
41
  - **关闭的会话与断线恢复**(CP4 / CP4-client-fix2):服务端关闭某会话的远程(或它被闲置休眠扫掉)时,该会话**从侧边栏列表隐藏**——按「已归档」处理(宿主 `sessionVisible` 在默认筛选下不显示 archived 里的会话),打开「显示已归档」筛选仍能找到。唯一的例外是此刻正打开的会话页:页面停在原处——关闭不重试,已出过帧的会话流也不再报错,静默保持到页面自己关掉它(宿主把会话流的任何终止错误都渲染成对话区顶部的「历史加载失败:…」,而关闭原因只该由横幅表达);若之后服务端重新共享、又有对它的调用成功,关闭记录随之清掉,这条流改为**正常结束**——宿主把它当作载具恢复、带着新历史自动重开。零帧的会话流、其他面板的流以及对它的 typert 单次请求仍以错误结束,但文字统一为「远程已关闭」,不透出服务端的内部报错(改动摘要 / diff 走的 plain-HTTP 转发例外:那里仍是只带错误码的 403)。composer 横幅显示「远程已关闭」及原因,输入经 composer-block 禁用;当前会话绝不进 archived(否则宿主守卫 `clearArchivedCurrent` 会把正打开的页踢回首页,横幅就无从显示),用户切到别的会话后(当前会话信号来自宿主持久化的选择存储,逐帧读取、另有 1 秒轮询兜底)它才转为隐藏。服务端重新共享(id 回到某工作区的 `sessionIds`)即从 archived 移出、回到正常位置。服务端断线期间已打开的远程会话页保持原状:会话流与任务列表类面板在中继恢复后自动续上——已出过帧的流以干净 end 结束,宿主界面把它当作载具错误立即重开、拿到恢复后的新快照;零帧的原位重开,重开同样走退避(1 秒起翻倍、上限 30 秒)。「远程已关闭」与「暂时只读」是真判决,不在续上之列;文件树变更与终端面板断线后需重新打开。
@@ -50,6 +51,7 @@ v1.0.0(fork 自 [mexiaosqwq/dsh-web-mobile](https://github.com/mexiaosqwq/dsh-
50
51
  | 插件设置区块 | `plugins.row.config` | 两角色(内容按角色不同) |
51
52
  | 标题行远程图标 + 会话「…」菜单项 | `conversation.session.header.actions` / `sidebar.workspaces.session.menu.item` | host |
52
53
  | 标题行连接图标 + composer 横幅 | 同上槽位 / `conversation.input.dock` | client(仅远程会话渲染) |
54
+ | 产物下载按钮 | `deliverables.file.actions` / `sidebar.right.tab.document.actions` | client(仅远程会话渲染) |
53
55
  | 远程分组(流合并进侧边栏) | `workspace/follow` 全局流的运行时包装 | client |
54
56
 
55
57
  门外留下的只有这些;手机外壳本体(两级页面栈、composer 重排、手势、调试徽章)仍受门与 `<768px` 断点的双重约束,桌面 ≥1024px 逐像素 no-op 的硬约束不变。
@@ -131,6 +133,14 @@ composer 最左的回形针打开的是**手机本地**的文件选择器(iOS
131
133
 
132
134
  安全上的几句话:这个功能给插件的 host 半区新增了一条 HTTP 路由(`POST /_dsh/mobile-nav/upload`),只接受同源请求,文件名清洗后只取叶子名,写入路径校验不允许越出工作目录,单文件默认上限 20MB(可在 profile 里的插件行用 `maxUploadBytes` 调整)。远程访问时,这条路由和其它请求一样在 网关半边的配对墙之后。
133
135
 
136
+ ### 远程会话拖拽附件(2.2.6)
137
+
138
+ 桌面端把文件从访达拖进会话输入区时,宿主有一条「同机零拷贝」捷径:Electron 的 `__DSH_HOST_PATHS__` 能读出拖入文件的磁盘路径,`addFiles` 于是不传字节、直接插一条 `@本机绝对路径` 的引用。远程会话里这个路径是**子客户端机器**的路径,服务端的会话永远读不到,引用落地就是坏的。2.2.6 起浏览器半边在 document 上装了一个 **capture 阶段**的 drop 拦截(`src/client/effects/remote-drop.ts`,判定纯函数在 `src/client-data/remote-drop.ts`):当前会话是 `zr~` 虚拟 id 时,把拖入的文件重包装成不带磁盘路径的 `File`(`new File([f], …)`,Electron 对 JS 构造的 File 返回空路径),塞进新的 `DataTransfer` 后在 document 上重派发一个合成 drop 事件——宿主自己的 drop 管道(mask 清理、busy 拒绝、目录判定、addFiles 分支)原样接手,把它当普通浏览器拖拽走字节上传,下游由既有的 fetch-route 拦截经中继转服务端暂存。合成事件 `isTrusted === false`,拦截器自己不会再处理它,天然防自重入。
139
+
140
+ 三重触发门,任一不满足就零干预(`passthrough`):`__DSH_HOST_PATHS__` 存在(手机 / 纯浏览器宿主本来就走上传,不装拦截)、当前会话是远程虚拟 id(当前会话读 `localStorage['dsh.sessions.current']`,事件发生时现场读;读不到按本机会话处理——误判方向安全:最坏把本机拖拽当成远程多传了字节,不会丢数据)、事件是受信的。拖入**文件夹**时整批拦下(文件夹没法用单文件上传修),出一条 3 秒自动消失的提示(locale key `remoteDropFolderBlocked`)。`webkitGetAsEntry` 不可用时视为无文件夹(与宿主同一默认)。重包装或 `DataTransfer.items.add` 抛错时放行原事件回归现状——宁坏勿丢。
141
+
142
+ 降级:`DragEvent` 不可用或 `DataTransfer` 不可构造时**整体不装**,行为与未安装本功能完全一致。诊断:设置页(子客户端角色)诊断区新增「远程拖拽守卫」一行,显示安装状态与拦截 / 重派发 / 拦下文件夹 / 放行 / 重包失败五个计数(`remoteDropDiagnostics()`,浏览器端计数,渲染时现读)。
143
+
134
144
  ### 分享图
135
145
 
136
146
  信息卡操作行的第五枚按钮「分享图」把当前会话导出成可保存/转发的 PNG 长图(issue #7:手机上滚动截图拼长图太麻烦)。范围可选「全部对话」或「最近 3/5/10 轮」——后者在服务端裁剪,长会话只传尾部数据;轮次按**真提问**计数(复刻宿主 next-step 收件箱状态机:轮中的插话/授权回复留在轮内、不另起一轮),与 Chat 视图的肉眼轮次一致。
@@ -193,6 +203,13 @@ composer 最左的回形针打开的是**手机本地**的文件选择器(iOS
193
203
  下载);超 24 片保尾去头并在首片标注省略数;长代码行/宽表格永不横向裁剪;助手正文
194
204
  按 markdown 子集渲染。手机上滚动截图拼长图太麻烦,这是第一等诉求(见「分享图」一节)。
195
205
 
206
+ **新增**
207
+
208
+ - 远程会话产物下载:产出台卡片与文档预览头各一个「下载到本机」,经中继
209
+ `workspaceFiles/readBytes` 分段读回后由浏览器落盘;Word/Excel/PPT 预览改由服务端
210
+ LibreOffice 出 PDF(`officeToPdf/*` 进入中继白名单,PDF 字节走二进制标记)。此前
211
+ 子客户端只能预览,产物拿不到本机。
212
+
196
213
  **修复**
197
214
 
198
215
  - 适配 DSH `0.1.5`(0.1.2 → 0.1.5-rc.2 的一批回归,2026-09-11 真机报告、逐项实测):
@@ -366,7 +383,7 @@ composer 最左的回形针打开的是**手机本地**的文件选择器(iOS
366
383
  ## 兼容插件
367
384
 
368
385
  - [dsh-better-sidebar](https://github.com/omdsh-dev/DSH-better-sidebar)(0.19+:它的全部 tab 都在 DSH 0.1.5 官方右侧栏里,手机上宿主自己切全屏,本插件在会话页头部给它留入口位、左缘回退手势收它、文件树里点 @ 引用后自动收起——面板全屏盖住会话页,草稿变化看不见,收起本身就是点击反馈;≤ 0.18 自绘右栏的老版本:全宽抽屉 + 安全区 + 底部关闭 pill,只在 DSH < 0.1.5 上还会走到)——本机实测 **0.19.1**(老版规则实测 0.15.0)
369
- - dsh-better-sidebar 的**远程会话处理**(PB-12 起分两档):**0.25.0、0.26.0 与 0.26.1** 三版由 zen-remote 的内置适配器(`src/adapters/dsh-better-sidebar/`)**代理**——它的文件浏览、编辑器、git 变动、任务等界面在远程会话里读写的是主服务端的数据(整机数据,需主服务端主人在设置页同意;`open.external` 远程拒绝、`settings.*` 与 `/sidebar/bundle` 留本机、侧聊转发(子会话继承父会话共享);0.26 新方法已一并接入(`fs.readPage` 分页读、`sidechat.dequeue` 撤回排队消息、`sidechat.model`/`sidechat.models` 线程切模型、`/sidebar/write` 编辑器保存;`ws/sidechat` 推送不桥接,远程侧聊走 0.26 自带的 15s 兜底轮询,正确性无损))。**其他版本维持隐藏**:那些版本的界面都带 `{sessionId, cwd}` 语境调它自己的 `/sidebar/api/*` 接口,远程会话里这些请求落到子客户端本机——文件树会显示本机同名文件、编辑会真的写本机文件;远程会话(`html[data-zr-remote-session="1"]`)里按插件自己的挂载/渲染标记隐藏这些界面,选择器在 `src/client/styles/remote-session.css.ts`,未安装时一条都不命中。因为它接管了宿主的「文件」标签,未桥接的远程会话里暂时没有侧栏文件浏览;聊天或交付物里的文件链接(`dsh-resource://file/**`)会被它的编辑器注册抢先接住,展开一个空的右栏(根治要等 zen-remote 自己的远程文件树)。隐藏档的定位仍是**隐藏而非代理**:插件组件保持挂载并继续静默发只读请求,但所有写控件都在被隐藏的界面里,不会误写本机。PB-14 起显示规则按桥接状态生效:已桥接(0.25.0/0.26.0 且主服务端同意)时远程会话里**照常显示**(面板数据经适配器来自主服务端,隐藏规则全部让位);未桥接时维持隐藏,已打开的 tab 空态改为一行说明占位(better-sidebar 未在远程会话桥接——中英双语,随浏览器语言),空白工作台浮动按钮一并隐藏
386
+ - dsh-better-sidebar 的**远程会话处理**(PB-12 起分两档):**0.25.0、0.26.0、0.26.1、0.28.0-alpha.0 与 0.28.0** 五版由 zen-remote 的内置适配器(`src/adapters/dsh-better-sidebar/`)**代理**——它的文件浏览、编辑器、git 变动、任务等界面在远程会话里读写的是主服务端的数据(整机数据,需主服务端主人在设置页同意;`open.external` 远程拒绝、`settings.*` 与 `/sidebar/bundle` 留本机、侧聊转发(子会话继承父会话共享);0.26 新方法已一并接入(`fs.readPage` 分页读、`sidechat.dequeue` 撤回排队消息、`sidechat.model`/`sidechat.models` 线程切模型、`/sidebar/write` 编辑器保存;`ws/sidechat` 推送不桥接,远程侧聊走 0.26 自带的 15s 兜底轮询,正确性无损))。**其他版本维持隐藏**:那些版本的界面都带 `{sessionId, cwd}` 语境调它自己的 `/sidebar/api/*` 接口,远程会话里这些请求落到子客户端本机——文件树会显示本机同名文件、编辑会真的写本机文件;远程会话(`html[data-zr-remote-session="1"]`)里按插件自己的挂载/渲染标记隐藏这些界面,选择器在 `src/client/styles/remote-session.css.ts`,未安装时一条都不命中。因为它接管了宿主的「文件」标签,未桥接的远程会话里暂时没有侧栏文件浏览;聊天或交付物里的文件链接(`dsh-resource://file/**`)会被它的编辑器注册抢先接住,展开一个空的右栏(根治要等 zen-remote 自己的远程文件树)。隐藏档的定位仍是**隐藏而非代理**:插件组件保持挂载并继续静默发只读请求,但所有写控件都在被隐藏的界面里,不会误写本机。PB-14 起显示规则按桥接状态生效:已桥接(0.25.0/0.26.0 且主服务端同意)时远程会话里**照常显示**(面板数据经适配器来自主服务端,隐藏规则全部让位);未桥接时维持隐藏,已打开的 tab 空态改为一行说明占位(better-sidebar 未在远程会话桥接——中英双语,随浏览器语言),空白工作台浮动按钮一并隐藏
370
387
  - [@nanmicoder/dsh-agent-teams](https://github.com/NanmiCoder/dsh-agent-teams)(AgentTeams 活动浮层:手机端挪到会话头部下方、避开安全区,会话列表页隐藏;子代理会话头部保留可点的父会话面包屑用于切回)——本机实测 **0.1.9**
371
388
  - [@ychris12138/dsh-usage-stats](https://github.com/Ychris12138/dsh-usage-stats)(用量与余额,主屏 chips 行可直接打开;旧包名 `dsh-usage-stats` 已废弃,两个名字同时留在 profile 里会因重复的 `usage-stats` 行让 DSH 起不来)——本机实测 **0.2.9**
372
389
  - [@opendsh/dsh-plugin-scheduled-tasks](https://github.com/Ceelog/dsh-plugins)(定时任务,主屏 chips 行自动收割入口)——本机实测 **0.2.3**
@@ -127,7 +127,7 @@ content-type: application/json; charset=utf-8
127
127
 
128
128
  ## 开发一个适配器
129
129
 
130
- 先确认目标插件真的需要适配器:能让作者加几行 `zenRemote.bridge(...)` 就优先走协作声明——适配器只在第三方插件不配合时使用。当前唯一在册的适配器是 **`dsh-better-sidebar`(0.25.0、0.26.0 与 0.26.1 三版)**(`src/adapters/dsh-better-sidebar/`),新适配器照它写。
130
+ 先确认目标插件真的需要适配器:能让作者加几行 `zenRemote.bridge(...)` 就优先走协作声明——适配器只在第三方插件不配合时使用。当前唯一在册的适配器是 **`dsh-better-sidebar`(0.25.0、0.26.0、0.26.1、0.28.0-alpha.0 与 0.28.0 五版)**(`src/adapters/dsh-better-sidebar/`),新适配器照它写。
131
131
 
132
132
  步骤:
133
133
 
@@ -15,8 +15,9 @@ Built on the MIT [dsh-mobile-gate](https://github.com/Bernardxu123/dsh-mobile-ga
15
15
  | 🔑 **Public-internet identity** | The gateway listens on `127.0.0.1` only, sitting behind your own reverse proxy. New devices trade a pairing code for a long-lived device token (cookie `lg_device` for web devices, a JSON token for desktop clients) — identity follows the token, not the source IP |
16
16
  | 👥 **Device roles** | A pairing code is minted for one role: **web app device** (phones/tablets/browsers through the gateway, see all sessions) or **desktop app device** (another DSH desktop running this plugin as the client role — relay prefix only, shared sessions only). A code offered to the wrong channel is refused with a clear message, not consumed |
17
17
  | 📡 **Remote relay** | Desktop clients talk to the host over zen-remote's own relay protocol (HTTP invokes + NDJSON stream subscriptions); the server re-verifies session ownership per request against a per-method allowlist — data of an unshared session never leaves the box |
18
- | 📱 **Real PWA** | `manifest.json` + service worker: once the proxy provides HTTPS, "Add to Home Screen" actually works — standalone full-screen app with icon, splash, theme-color, maskable assets |
19
- | 🌐 **Offline** | SW v3: only the true static shell (manifest/icons/offline page) is cache-first, everything else (DSH client bundle JS/CSS, API, page HTML) is network-first — a new deploy is picked up immediately instead of lingering behind stale cached CSS |
18
+ | 📱 **Real PWA** | `manifest.json` + service worker: once the proxy provides HTTPS, "Add to Home Screen" actually works — standalone full-screen app with icon, splash, theme-color, maskable assets; cold start paints the phone home screen's frame before the JS bundle exists instead of a blank page |
19
+ | 🌐 **Offline** | SW v4: the true static shell AND every content-addressed URL (Vite filename hashes, DSH's `?rev=<build revision>` plugin batches (a sha1 slice over mtime/ctime/size)) are cache-first; everything else (unhashed JS/CSS, API, page HTML) stays network-first — a new deploy changes the URL instead of the bytes behind one, so the phone is both fast and never stale |
20
+ | ⚡ **Instant first paint** | The gateway inlines an app-shaped skeleton (top bar / session cards / new-session pill) into the first HTML byte and removes it the moment DSH renders into `#root`; explicit "desktop" devices are never injected and ≥1024px hides it in CSS, so desktop stays pixel-identical |
20
21
  | 👆 **Touch gestures** | Pinch-to-resize font (resettable); edge-swipe-back has been handed off to the interface half (see "Division of labor" below), pull-to-refresh has been removed entirely (an accidental overscroll used to fire a full reload mid-conversation) |
21
22
  | 🔔 **Push when you're actually needed** | Real Web Push (VAPID-signed, aes128gcm-encrypted). By default it fires only when something is genuinely waiting on you: a tool needs authorization, or the model asked you a question. Plain turn-end is opt-in (`DSH_PUSH_TURN_END=1`). The notification carries no conversation content unless you ask for it |
22
23
  | 🛎️ **`push_notify` tool** | A model-callable push tool (registered by the push half): the model can decide mid-task that the user needs a decision, that a key milestone was reached, or that an error needs a human — and push straight to the lock screen instead of waiting for the turn to end. Usage discipline (don't call this often) is spelled out in the tool description; the host also enforces it with rate limits (max 1 per 60s per session, 20/hour globally) — over the limit, the call is silently dropped, never an error. Same aes128gcm end-to-end encryption, same lock-screen-only exposure. Turn it off entirely with `pushTool: false` (or `DSH_PUSH_TOOL=0`); it's also skipped automatically on hosts without a tool registry (`ctx.tools`), with no effect on the rest of the plugin |
@@ -58,6 +59,12 @@ Inside this single plugin, the boundary between the two halves is: **this repo o
58
59
 
59
60
  ---
60
61
 
62
+ ## Cold start: paint the shell, then load
63
+
64
+ DSH's web shell is an empty `<div id="root">`; it only fills once the app and plugin JavaScript (~1.7 MB shell + ~12 MB plugin graph, ~5 MB gzipped) has downloaded and executed. Behind a reverse proxy on a phone, that is a blank page for seconds. The gateway now inlines the phone home screen's frame — top bar, two session cards, the new-session pill — into the first HTML byte, and removes it synchronously when DSH first renders into `#root` (its own boot screen). No extra request, no session data read, no touch blocked; an explicit "desktop" device never gets it and ≥1024px hides it in CSS, so desktop stays pixel-identical.
65
+
66
+ After the first visit, a repeat cold start no longer re-downloads the build output: DSH's static server sends no cache headers for `/assets/`, so the gateway adds `Cache-Control: immutable` to hash-shaped files (8+ characters containing a digit or both letter cases) that are not HTML, and service worker v4 only cache-firsts those content-addressed URLs (plus plugin batches carrying `?rev=<hex build revision>`). The worker refuses to store an HTML login/error page as an asset (a stored response must have the Content-Type its URL claims). The hash follows the bytes, so a new deploy is a new URL — no "new DOM + old CSS". The first visit still downloads the full JS (that layer can only be fixed upstream in DSH), but the user sees a shaped interface from the first frame instead of a white screen.
67
+
61
68
  ## Quick start
62
69
 
63
70
  ### 1. Install the plugin
@@ -328,7 +335,7 @@ The `/v1/http` route is a second allowlist, keyed by **route name** (not part of
328
335
  - Terminals are deliberate (a desktop client is a trusted device): what opens is a **server-side** PTY running as the server user, without the agent sandbox or approval restrictions; closing the session's remote access kills its terminal streams with it;
329
336
  - `workspaceFiles/read` and friends are not contained to the session directory (DSH itself does not contain them) — anything the server process can read is readable, under the same trusted-device premise as terminals;
330
337
  - The plugin bridge's whole-machine data requires the server owner's per-plugin consent — the toggles in the settings page's Plugin bridge section, everything OFF by default; the loopback carries the operator's cookie, so a bridged plugin sees the same permissions the local browser sees. The bridge's boundary is therefore the DECLARED route set (exact equality) plus the share table — there is **no** parameter-level scanning;
331
- - **Adapters (better-sidebar)**: beyond cooperative declarations, zen-remote ships a built-in adapter for `dsh-better-sidebar` **0.25.0, 0.26.0 and 0.26.1** (`src/adapters/` — non-cooperative third-party plugins are bridged by it, with prefix/path-segment route matching and session-id rewriting in JSON bodies and path segments). **Consenting to its whole-machine toggle hands the paired desktop client whole-disk file read/write on the server, git write operations (commit, push, revert, …), and model spend through commit-message generation** — the product decision is "both directions forward, no path fencing", and a server owner should treat that toggle as terminal-grade trust in the paired machine; `open.external` (launching processes on the host) refuses for remote sessions, `settings.*` and `/sidebar/bundle` stay on the sub-client's own machine; the two WebSockets (`/sidebar/ws/fs-watch` file-tree watch, `/sidebar/ws/agent-opens` open push) bridge over the byte tunnel (frames pass through untouched — the browser never reads the session id inside a push); side chat (`sidechat.*`) forwards — its child sessions carry `meta.parentSession`, so they inherit the parent's share through the ancestor chain, and the `childId` in `sidechat.start`'s answer is virtualized before it reaches the browser; 0.26's `ws/sidechat` push socket is **not** bridged — remote side chat falls back to 0.26's built-in 15s polling, correctness intact, only the push cadence degrades to polling; `sidechat.models` shows the **sub-client's own** model catalog in the picker while the choice goes through `sidechat.model` and takes effect on the **server** — when the two machines' catalogs differ, what the server actually applies is authoritative;
338
+ - **Adapters (better-sidebar)**: beyond cooperative declarations, zen-remote ships a built-in adapter for `dsh-better-sidebar` **0.25.0, 0.26.0, 0.26.1, 0.28.0-alpha.0 and 0.28.0** (`src/adapters/` — non-cooperative third-party plugins are bridged by it, with prefix/path-segment route matching and session-id rewriting in JSON bodies and path segments). **Consenting to its whole-machine toggle hands the paired desktop client whole-disk file read/write on the server, git write operations (commit, push, revert, …), and model spend through commit-message generation** — the product decision is "both directions forward, no path fencing", and a server owner should treat that toggle as terminal-grade trust in the paired machine; `open.external` (launching processes on the host) refuses for remote sessions, `settings.*` and `/sidebar/bundle` stay on the sub-client's own machine; the two WebSockets (`/sidebar/ws/fs-watch` file-tree watch, `/sidebar/ws/agent-opens` open push) bridge over the byte tunnel (frames pass through untouched — the browser never reads the session id inside a push); side chat (`sidechat.*`) forwards — its child sessions carry `meta.parentSession`, so they inherit the parent's share through the ancestor chain, and the `childId` in `sidechat.start`'s answer is virtualized before it reaches the browser; 0.28's (alpha.0 and stable) `changes.ops` long-poll (`wait: true`, parks up to 25 s — past the relay's 15 s header wait) has `wait` stripped on the server, so a remote session's "this round's files" view polls on 0.26's 2.5 s cadence; 0.26's `ws/sidechat` push socket is **not** bridged — remote side chat falls back to 0.26's built-in 15s polling, correctness intact, only the push cadence degrades to polling; `sidechat.models` shows the **sub-client's own** model catalog in the picker while the choice goes through `sidechat.model` and takes effect on the **server** — when the two machines' catalogs differ, what the server actually applies is authoritative;
332
339
  - Concurrent streams are budgeted per device (32), and so are invokes kept in flight at once — past the per-device cap the invoke answers 429 `too-many-invokes`. Error codes shaped `*/internal` (`gateway/internal` and friends) are returned as the bare code with no message — that kind of message quotes server-side internals. Event answers are matched against the subscription and device they were forwarded to. Approval/question forwarding is **first come, first served**: whichever of the server's own UI and the sub-client answers first wins; the later answer is refused by the gateway and the client syncs to "already handled". The relay **never answers on the client's behalf**: an unshared session's approval/question events are not forwarded at all, and with the server's own UI offline too, the approval simply keeps waiting — the gateway re-delivers still-pending events to the next `$events` subscriber. A wait, never a rejection (an abstention would fail every pending approval of the session at once and break the push → wake → approve flow). Notification-type events (EMIT frames: session-list summaries, account expirations and other server-wide state) of an unshared session are never forwarded.
333
340
 
334
341
 
@@ -13,8 +13,9 @@
13
13
  | 🔑 **公网身份** | 网关只监听 `127.0.0.1`,放在你自己的反代后面;新设备用配对码换取长期设备令牌(Web 应用端存 Cookie `lg_device`,桌面应用端拿 JSON 令牌),身份跟着令牌走,与来源 IP 完全无关 |
14
14
  | 👥 **设备角色** | 配对码生成时绑定角色:**Web 应用端**(手机/平板/浏览器,经网关访问全部会话)与**桌面应用端**(另一台 DSH 桌面端、zen-remote 子客户端角色,只能访问中继前缀、只见已共享会话)。拿错通道用码会被明确拒绝且不消耗码 |
15
15
  | 📡 **远程中继** | 桌面应用端与主服务端之间走 zen-remote 自己的中继协议(HTTP 单次调用 + NDJSON 流式订阅),服务端按「方法允许清单」逐请求复核会话归属,未共享会话的数据一步都出不来 |
16
- | 📱 **真 PWA** | `manifest.json` + service worker:反代带来 HTTPS 后,手机浏览器「添加到主屏」真正生效,全屏独立窗口运行,带图标/启动屏/主题色 |
17
- | 🌐 **离线可用** | service worker(v3):只有真正的静态壳(manifest/图标/离线页)缓存优先,其余(DSH 客户端 JS/CSS、API、页面 HTML)一律网络优先——装了新版本手机上立刻吃到,不会像早期版本那样在部署之后还残留旧 CSS |
16
+ | 📱 **真 PWA** | `manifest.json` + service worker:反代带来 HTTPS 后,手机浏览器「添加到主屏」真正生效,全屏独立窗口运行,带图标/启动屏/主题色;冷启动首帧先画出手机主屏骨架,不再空白等 JS |
17
+ | 🌐 **离线可用** | service worker(v4):静态壳与**所有内容寻址 URL**(Vite 文件名哈希、DSH 带 `?rev=<构建修订>`(mtime/ctime/size 的 sha1 截断)的插件批次)缓存优先,其余(无哈希 JS/CSS、API、页面 HTML)一律网络优先——新版本换 URL 而不是换同一个 URL 下的内容,手机上既快又不会残留旧 CSS |
18
+ | ⚡ **首帧不白屏** | 网关把手机主屏形状的骨架(顶栏 / 会话卡 / 新建按钮)内联进第一帧 HTML,DSH 一往 `#root` 渲染就同步移除;显式「桌面」设备不注入、≥1024px 由 CSS 隐藏,桌面逐像素不变 |
18
19
  | 👆 **触屏手势** | 捏合缩放字体(可重置);左缘返回手势已让位给界面半边(见下方「分工」),下拉刷新已整体移除(误触发全页重载会把人从对话中间弹回列表) |
19
20
  | 🔔 **卡住了就推送** | 真 Web Push(VAPID 签名 + aes128gcm 加密)。默认只在**真正需要你**的时候推:某个工具在等授权、模型在等你回答问题。「回合结束」默认不推(设 `DSH_PUSH_TURN_END=1` 打开)。通知里默认不带对话内容 |
20
21
  | 🛎️ **`push_notify` 工具** | 模型可主动调用的推送工具(由推送半边注册):任务中途要用户拿主意、跑到关键节点、或出错需要人来处理时,模型自己决定推一条到锁屏。纪律写在工具描述里明确要求模型别高频用;宿主侧再兜底限流(同会话 60 秒最多 1 条、全局每小时最多 20 条),超额直接不发送、不报错。同样是 aes128gcm 端到端加密,推送服务器只见密文,暴露面只有你自己的锁屏。`pushTool` 关掉(或 `DSH_PUSH_TOOL=0`)可整体关闭;宿主没装工具注册服务(`ctx.tools`)时自动跳过,不影响插件其余功能 |
@@ -69,6 +70,12 @@
69
70
 
70
71
  ---
71
72
 
73
+ ## ⚡ 冷启动:先画壳,再加载
74
+
75
+ DSH 的网页外壳是一个空的 `<div id="root">`,要等应用与插件 JS(约 1.7 MB 壳 + 约 12 MB 插件图,gzip 后约 5 MB)下载执行完才有内容;手机经反代冷启动时,这段时间就是一片空白。现在网关把此刻本该出现的手机主屏骨架——顶栏、两张会话卡、右下角的新建按钮——直接内联进第一帧 HTML,并在 DSH 第一次往 `#root` 渲染(通常是它自己的启动页)时同步摘掉。没有额外请求、不读任何会话数据、不挡触摸;显式「桌面」设备不注入,≥1024px 由 CSS 隐藏,桌面保持逐像素不变。
76
+
77
+ 首访之后,重复打开不再重新下载构建产物:DSH 的静态服务器对 `/assets/` 不发缓存头,网关给哈希形状(8+ 位且含数字或大小写混合)且响应不是 HTML 的文件补上 `Cache-Control: immutable`;service worker v4 也只对同一判定的内容寻址 URL(以及带 `?rev=<hex 构建修订>` 的插件批次)缓存优先,并且不会把登录页/错误页这类 HTML 响应存成资源(响应类型必须与 URL 声明的资源类型一致)。哈希随内容变,URL 就随版本变,不会出现「新 DOM 配旧 CSS」。首次访问仍要下载完整 JS(这一层只能由 DSH 上游解决),但用户从第一帧起看到的就是成型的界面,而不是白屏。
78
+
72
79
  ## 🚀 快速开始
73
80
 
74
81
  ### 1. 安装插件
@@ -345,7 +352,7 @@ sudo cloudflared service install # 通了再装成常驻服务
345
352
  - 终端是有意开放的(桌面应用端是可信设备):开的是**服务端**的 PTY,以服务端用户身份运行、不受智能体沙箱与审批限制;关闭会话的远程时终端流一并终止;
346
353
  - `workspaceFiles/read` 等文件预览接口不限制在会话目录内(DSH 自身就不限制),服务端进程可读的文件都能读——信任前提与终端相同;
347
354
  - 插件桥的整机数据需要主服务端主人逐插件同意——设置页「插件桥」里的开关,缺省全部关闭;回环执行带操作者 cookie,插件接口看到的权限与本机浏览器相同,因此桥接的边界就是声明登记的路径(exact 相等)加会话共享表,**不做**参数级扫描;
348
- - **适配器(better-sidebar)**:协作声明之外,zen-remote 为 `dsh-better-sidebar` **0.25.0、0.26.0 与 0.26.1** 内置了一个适配器(`src/adapters/`,不配合的第三方插件由它代为桥接,路由按前缀/路径段匹配、会话 id 在 JSON 体与路径段里改写)。**同意它的整机数据开关,等于让已配对的桌面应用端读写主服务端整盘文件、执行 git 写操作(提交、推送、回滚……),并通过提交信息生成消耗主服务端的模型额度**——产品上的决定就是「读写都接、不加路径围栏」,主服务端主人应当把它当成给对方一台本机终端级别的信任来开;`open.external`(在宿主机起进程)对远程会话拒绝,`settings.*` 与 `/sidebar/bundle` 留在子客户端本机;两条 WebSocket(`/sidebar/ws/fs-watch` 文件树监视、`/sidebar/ws/agent-opens` 打开推送)经字节隧道桥接(帧原样透传,浏览器不消费推送里的会话 id);侧聊(`sidechat.*`)转发——侧聊子会话带 `meta.parentSession`,按祖先链自动继承父会话的共享,`sidechat.start` 响应里的 `childId` 会换算成虚拟 id 回给浏览器;0.26 新增的 `ws/sidechat` 侧聊推送**不桥接**——远程侧聊走 0.26 自带的 15s 兜底轮询,正确性无损,只是推送降级为轮询节奏;`sidechat.models` 的模型选择器显示的是**子客户端本机**的模型目录,而选择经 `sidechat.model` 作用在**服务端**——两机目录不一致时以服务端实际生效为准;
355
+ - **适配器(better-sidebar)**:协作声明之外,zen-remote 为 `dsh-better-sidebar` **0.25.0、0.26.0、0.26.1、0.28.0-alpha.0 与 0.28.0** 内置了一个适配器(`src/adapters/`,不配合的第三方插件由它代为桥接,路由按前缀/路径段匹配、会话 id 在 JSON 体与路径段里改写)。**同意它的整机数据开关,等于让已配对的桌面应用端读写主服务端整盘文件、执行 git 写操作(提交、推送、回滚……),并通过提交信息生成消耗主服务端的模型额度**——产品上的决定就是「读写都接、不加路径围栏」,主服务端主人应当把它当成给对方一台本机终端级别的信任来开;`open.external`(在宿主机起进程)对远程会话拒绝,`settings.*` 与 `/sidebar/bundle` 留在子客户端本机;两条 WebSocket(`/sidebar/ws/fs-watch` 文件树监视、`/sidebar/ws/agent-opens` 打开推送)经字节隧道桥接(帧原样透传,浏览器不消费推送里的会话 id);侧聊(`sidechat.*`)转发——侧聊子会话带 `meta.parentSession`,按祖先链自动继承父会话的共享,`sidechat.start` 响应里的 `childId` 会换算成虚拟 id 回给浏览器;0.28(alpha.0 与正式版)的 `changes.ops` 长轮询(`wait: true`,最长挂 25 秒,超过中继 15 秒的响应头等待)在服务端去掉 `wait`,远程会话的「本轮文件」退回 0.26 的 2.5 秒轮询;0.26 新增的 `ws/sidechat` 侧聊推送**不桥接**——远程侧聊走 0.26 自带的 15s 兜底轮询,正确性无损,只是推送降级为轮询节奏;`sidechat.models` 的模型选择器显示的是**子客户端本机**的模型目录,而选择经 `sidechat.model` 作用在**服务端**——两机目录不一致时以服务端实际生效为准;
349
356
  - 每台设备并发流数有上限(32)、同时在途的 invoke 数也有上限(32,超出 429 `too-many-invokes`);`*/internal` 形状的错误码(`gateway/internal` 等)只回码不带消息——那类消息引用的是服务端内部细节。事件应答按「转发时的订阅 + 设备」核对归属。审批/提问的转发是**先到先得**:服务端自己的界面和子客户端谁先应答谁生效,后答的一方被网关拒绝、同步成「已处理」。中继**不代答**:未共享会话的审批/提问事件不会被转发,服务端界面也不在线时这个审批就一直等待——网关会把仍未应答的事件转交给下一个连上来的订阅,等,而不是替你拒绝(代答会把整批待审批一次性判死,砸掉「推送 → 唤醒 → 审批」链路)。未共享会话的**通知类**事件(EMIT 帧:会话列表摘要、账号到期之类的服务端全局状态)一律不转发;唯一的例外是已共享会话(含其子会话)的 `api-session/status`——它只描述单个会话的运行/空闲,逐帧按共享表判定,子客户端靠它在主机侧一轮开始或结束时同步运行状态徽标(断线期间的翻转由重连后补拉列表纠正)。
350
357
 
351
358
 
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * The dsh-better-sidebar adapter (PB-12), written against EXACTLY
3
- * versions 0.25.0, 0.26.0 and 0.26.1 (PB-15 widened the list; 0.26.1 is a
3
+ * versions 0.25.0, 0.26.0, 0.26.1, 0.28.0-alpha.0 and 0.28.0 (PB-15 widened the list; 0.26.1 is a
4
4
  * perf-only patch with the same wire surface as 0.26.0; 0.26.0 is a JSON-api
5
5
  * superset of 0.25.0 — it grows fs.readPage and the sidechat dequeue/model/
6
6
  * models methods, and moves fs.write's content onto the new raw-text
@@ -35,7 +35,7 @@ import { SIDEBAR_METHODS, sidebarMethodNameOf } from './methods.js';
35
35
  * modules — and pinned to the original by a test in
36
36
  * test/adapter-better-sidebar.test.cjs, which fails the pair apart when
37
37
  * either side moves. */
38
- const RELAY_UPLOAD_CAP_BYTES = 100 * 1024 * 1024;
38
+ const RELAY_UPLOAD_CAP_BYTES = 500 * 1024 * 1024;
39
39
  /** better-sidebar's own JSON body bound (lib/index.js:863
40
40
  * `MAX_BODY_BYTES = 1 << 20`) — the adapter forwards at most what the
41
41
  * backend would accept anyway. */
@@ -47,7 +47,16 @@ export const dshBetterSidebarAdapter = {
47
47
  // 0.26.1 (perf patch): JSON-api method set, routes and WebSocket paths
48
48
  // identical to 0.26.0's wire surface (verified against the npm build;
49
49
  // lib/index.js itself differs — a perf refactor, not byte-identical).
50
- versions: ['0.25.0', '0.26.0', '0.26.1'],
50
+ // 0.28.0-alpha.0 (DSH 0.2.1-alpha.5+): same routes and WebSockets; the
51
+ // JSON api grows `git.graph` (session-scoped read, no ids in the answer);
52
+ // `changes.ops` gains a `wait: true` long-poll (parks up to 25 s), which
53
+ // the server hook below strips — see there. Routes now admit through the
54
+ // host's `ctx.connection.requestRejection` (Host fence + signed cookie),
55
+ // which the loopback courier already satisfies (127.0.0.1 + cookie).
56
+ // 0.28.0 (stable, DSH 0.2.1-rc.1+): lib/index.js byte-identical to
57
+ // 0.28.0-alpha.0; the client bundles differ only in CSS-module map order
58
+ // and the service version string. alpha.0 stays for DSH 0.2.1-alpha.5.
59
+ versions: ['0.25.0', '0.26.0', '0.26.1', '0.28.0-alpha.0', '0.28.0'],
51
60
  routes: [
52
61
  {
53
62
  // The JSON API: the method name rides the path tail, the session
@@ -148,10 +157,22 @@ export const dshBetterSidebarAdapter = {
148
157
  }
149
158
  return { allow: true };
150
159
  }
151
- if (ctx.route.path === '/sidebar/api' && ctx.body !== null && typeof ctx.body === 'object' && !Array.isArray(ctx.body) && 'cwd' in ctx.body) {
152
- const stripped = { ...ctx.body };
153
- delete stripped.cwd;
154
- return { allow: true, body: stripped };
160
+ if (ctx.route.path === '/sidebar/api' && ctx.body !== null && typeof ctx.body === 'object' && !Array.isArray(ctx.body)) {
161
+ const record = ctx.body;
162
+ // 0.28.0-alpha.0: a primed `changes.ops` asks with `wait: true` and the
163
+ // backend parks it up to 25 s — longer than the relay's 15 s header
164
+ // wait, so every bridged long-poll would die as request-timeout. The
165
+ // client polls on a fixed 2.5 s interval with an in-flight guard
166
+ // either way, so dropping `wait` degrades a remote session to the
167
+ // 0.26 cadence (same precedent as the unbridged ws/sidechat push).
168
+ const stripWait = apiMethodOf(ctx.pathname) === 'changes.ops' && 'wait' in record;
169
+ if ('cwd' in record || stripWait) {
170
+ const stripped = { ...record };
171
+ delete stripped.cwd;
172
+ if (stripWait)
173
+ delete stripped.wait;
174
+ return { allow: true, body: stripped };
175
+ }
155
176
  }
156
177
  return { allow: true };
157
178
  },
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/adapters/dsh-better-sidebar/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/adapters/dsh-better-sidebar/index.ts"],"names":[],"mappings":"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"}
@@ -87,6 +87,8 @@ export const SIDEBAR_METHODS = {
87
87
  'git.diff-head': forward('read'),
88
88
  'git.branch': forward('read'),
89
89
  'git.log': forward('read'),
90
+ // 0.28.0-alpha.0:只读拓扑提交图(lib/index.js:8626),sessionId 定位,响应无会话 id。
91
+ 'git.graph': forward('read'),
90
92
  'git.commit-diff': forward('read'),
91
93
  'git.show': forward('read'),
92
94
  'git.blame': forward('read'),
@@ -1 +1 @@
1
- {"version":3,"file":"methods.js","sourceRoot":"","sources":["../../../src/adapters/dsh-better-sidebar/methods.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"methods.js","sourceRoot":"","sources":["../../../src/adapters/dsh-better-sidebar/methods.ts"],"names":[],"mappings":"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"}
@@ -391,6 +391,7 @@ export function createClientHandler(options) {
391
391
  // that.
392
392
  const intercept = options.getIntercept?.();
393
393
  const fetchRouteIntercept = options.getFetchRouteIntercept?.();
394
+ const serviceProbe = options.getServiceProbe?.();
394
395
  const pluginRouteIntercept = options.getPluginRouteIntercept?.();
395
396
  const compatRelay = options.getRelayClient?.();
396
397
  const compat = compatRelay?.compat !== undefined || (intercept?.incompatibleCalls.length ?? 0) > 0
@@ -410,6 +411,8 @@ export function createClientHandler(options) {
410
411
  next = { ...next, intercept };
411
412
  if (fetchRouteIntercept !== undefined)
412
413
  next = { ...next, fetchRouteIntercept };
414
+ if (serviceProbe !== undefined)
415
+ next = { ...next, serviceProbe };
413
416
  if (pluginRouteIntercept !== undefined)
414
417
  next = { ...next, pluginRouteIntercept };
415
418
  return compat === undefined ? next : { ...next, compat };