dsh-remote-bridge 2.6.1 → 2.7.1

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.
package/README.en.md CHANGED
@@ -9,7 +9,7 @@
9
9
  </p>
10
10
 
11
11
  <p align="center">
12
- <img alt="Version" src="https://img.shields.io/badge/version-v2.6.1-087f8c">
12
+ <img alt="Version" src="https://img.shields.io/badge/version-v2.7.1-087f8c">
13
13
  <img alt="DSH plugin" src="https://img.shields.io/badge/DeepSeek_Harness-plugin-1f2328">
14
14
  <img alt="Platforms" src="https://img.shields.io/badge/platform-Windows%20%7C%20macOS%20%7C%20Linux-586069">
15
15
  <img alt="License" src="https://img.shields.io/badge/license-AGPL--3.0-2da44e">
@@ -102,10 +102,10 @@ dsh plugin --profile web add dsh-remote-bridge
102
102
  dsh plugin --profile web add dsh-remote-bridge --registry https://registry.npmmirror.com
103
103
 
104
104
  # 2. tarball from the GitHub release
105
- dsh plugin --profile web add https://github.com/westanke/dsh-remote-bridge/releases/download/v2.6.1/dsh-remote-bridge-v2.6.1.tgz
105
+ dsh plugin --profile web add https://github.com/westanke/dsh-remote-bridge/releases/download/v2.7.1/dsh-remote-bridge-v2.7.1.tgz
106
106
 
107
107
  # 3. tarball from the Gitee release (faster from mainland China)
108
- dsh plugin --profile web add https://gitee.com/westanke/dsh-remote-bridge/releases/download/v2.6.1/dsh-remote-bridge-v2.6.1.tgz
108
+ dsh plugin --profile web add https://gitee.com/westanke/dsh-remote-bridge/releases/download/v2.7.1/dsh-remote-bridge-v2.7.1.tgz
109
109
 
110
110
  npx @deepseek-ai/dsh web
111
111
  ```
@@ -122,7 +122,7 @@ Restart DSH after installation, then open settings — The section is titled **
122
122
  To install a downloaded release archive:
123
123
 
124
124
  ```sh
125
- dsh plugin --profile web add ./dsh-remote-bridge-v2.6.1.tgz
125
+ dsh plugin --profile web add ./dsh-remote-bridge-v2.7.1.tgz
126
126
  ```
127
127
 
128
128
  ## First connection
@@ -380,22 +380,51 @@ pnpm check
380
380
  pnpm pack
381
381
  ```
382
382
 
383
- `pnpm check` covers type-checking, documentation consistency, and tests. It currently passes **67 test files / 557 cases**, plus **8 browser-layer cases** (Playwright measuring real computed styles, including the 375px narrow-viewport contract).
383
+ `pnpm check` covers type-checking, documentation consistency, and tests. It currently passes **76 test files / 698 cases**, plus **8 browser-layer cases** (Playwright measuring real computed styles, including the 375px narrow-viewport contract).
384
384
 
385
385
  `npm pack` produces roughly a **0.64 MB** archive (v2.6.1 measured 669,434 bytes, SHA-256 `9bf0189b…2cd35`): 2.2.0 dropped the standalone page and its editor dependencies and turned source maps off, down from 1.72 MB; it has since grown slightly with projection passthrough, the permission BFF, and the five-dimension hardening.
386
386
 
387
387
  v2.5.0 was verified on DSH **0.2.1-rc.2** on real hardware: all 14/14 host services injected, the three jobs endpoints exercised, and the permission catalog returned the kernel's real three presets. The development baseline is upstream `dsh-v0.2.1-rc.2` (commit `687f282e8625c6b8d11ff58211a90524be2e4317`); see `engines.dsh` above for the supported range. CI covers Windows, Ubuntu, and macOS.
388
388
 
389
- **v2.6.1 verification status**: 74 test files / 682 cases green, plus 8 Playwright browser cases
389
+ **v2.7.1 verification status**: 76 test files / **701 cases** green; `typecheck`, `docs:check`, and the
390
+ build all pass. This release touches only `agentFor` in `src/host/dsh-0.2-bridge.ts` plus its regression
391
+ tests; every other byte is identical to v2.7.0.
392
+
393
+ **v2.7.0 verification status**: 76 test files / 698 cases green, plus 8 Playwright browser cases
390
394
  (including the 375px narrow-viewport contract); `typecheck`, `docs:check`, and the build all pass.
391
- The SEC-H11 attack chain was confirmed **by measurement** (a fake LLM endpoint was stood up and the
392
- kernel was observed sending the real `Authorization: Bearer` to it); each of the four gates now has a
393
- regression assertion. The three device-identity specs (27 + 13 + 12 cases) cover the UA detection
394
- order, "a `declared` name is never overwritten", and idempotent migration of the old table shape.
395
+ All four capabilities were exercised on an isolated DSH **0.2.1-rc.3** instance rather than inferred:
396
+ the plugin inventory returned `loaded: 14 / 16 / problems: 2`, the model catalog reported
397
+ `ctx=1048576` for `free:mimo-v2.6-flash-free`, the four `reuseBlank` semantics were each verified,
398
+ and the client bundle contains `dsh-remote-bridge-plugins` and `sidebarRightTabs`. Screenshots live
399
+ in `dsh-021cmp/shots/`. The compatibility review was itself measured: 305 packages compared by
400
+ sha256, 285 with zero code changes and 20 substantively changed, all ten hard-dependency providers
401
+ inside the zero-change set, and 4 slots retained with 0 removed.
395
402
 
396
403
  ## Project
397
404
 
398
- - Version: `v2.6.1`
405
+ - Version: `v2.7.1`
406
+ - **v2.7.1 is a defect-fix release**: the kernel's `sessionController.resolveAgent()` returns an
407
+ `{ agent }` / `{ error }` **envelope**, not the Agent itself (`dsh-api-session-controller/lib/index.js:365-368`
408
+ `liveAgent()` and `:221-246` `resolve()` both have that shape). The bridge used to hand the envelope
409
+ straight to `fileUploads.upload()`, so the kernel reading `agent.session.header.origin` blew up with
410
+ `DSH_TYPEERROR: Cannot read properties of undefined (reading 'header')` — on a real device this showed up
411
+ as "sending a file always fails with 400/500 and the message points nowhere", breaking both attachment
412
+ upload and agent-preset selection. The bridge now detects the envelope, unwraps `.agent` on success, and
413
+ rethrows `.error` as-is (keeping the kernel's stable code, so "session not found" is no longer flattened
414
+ into "session not running"), while still accepting a bare object. Three regression tests pin all three
415
+ return shapes.
416
+ - **v2.7.0 aligns with DSH 0.2.1-rc.3 and lifts four capabilities**: (1) the model catalog now carries
417
+ `contextWindow` / `maxTokens` — the kernel's `ModelCatalogModel` only has id/name/description, so the
418
+ bridge resolves capacity through `llm.resolveModelInfo`, caching per `provider + model` for ten
419
+ minutes, never caching a failure, and never overwriting a value the kernel already supplied;
420
+ (2) the plugin inventory gains a right-sidebar form (the bridge becomes a `SidebarRightTabDefinition`
421
+ provider, so from DSH 0.2.1-rc.3 the card can be pinned; on rc.2 it still renders but has no pin or
422
+ More menu, which is the expected degradation); (3) `POST /chat/sessions` accepts an optional
423
+ `reuseBlank`, matching the 0.2.1 desktop behaviour where New Session returns to the workspace's
424
+ existing blank session, skipping blanks whose preset contradicts the request; (4) the settings page
425
+ gains a Plugins card (inventory / enable / disable / check for updates) and an "open plugin list"
426
+ button (rc.2 has no `pluginNavigation.openList`, so the bridge feature-detects instead of checking
427
+ versions).
399
428
  - **v2.6.1 is the security-fix + device-identity release**: it closes a **high-severity** hole —
400
429
  the three provider `baseURL` entry points (create / update / model discovery) performed no
401
430
  validation at all, so a device holding `settings.write` could point the baseURL at its own server
package/README.md CHANGED
@@ -9,7 +9,7 @@
9
9
  </p>
10
10
 
11
11
  <p align="center">
12
- <img alt="Version" src="https://img.shields.io/badge/version-v2.6.1-087f8c">
12
+ <img alt="Version" src="https://img.shields.io/badge/version-v2.7.1-087f8c">
13
13
  <img alt="DSH plugin" src="https://img.shields.io/badge/DeepSeek_Harness-plugin-1f2328">
14
14
  <img alt="Platforms" src="https://img.shields.io/badge/platform-Windows%20%7C%20macOS%20%7C%20Linux-586069">
15
15
  <img alt="License" src="https://img.shields.io/badge/license-AGPL--3.0-2da44e">
@@ -93,10 +93,10 @@ dsh plugin --profile web add dsh-remote-bridge
93
93
  dsh plugin --profile web add dsh-remote-bridge --registry https://registry.npmmirror.com
94
94
 
95
95
  # ② GitHub Release 的 tarball
96
- dsh plugin --profile web add https://github.com/westanke/dsh-remote-bridge/releases/download/v2.6.1/dsh-remote-bridge-v2.6.1.tgz
96
+ dsh plugin --profile web add https://github.com/westanke/dsh-remote-bridge/releases/download/v2.7.1/dsh-remote-bridge-v2.7.1.tgz
97
97
 
98
98
  # ③ Gitee Release 的 tarball(国内访问更快)
99
- dsh plugin --profile web add https://gitee.com/westanke/dsh-remote-bridge/releases/download/v2.6.1/dsh-remote-bridge-v2.6.1.tgz
99
+ dsh plugin --profile web add https://gitee.com/westanke/dsh-remote-bridge/releases/download/v2.7.1/dsh-remote-bridge-v2.7.1.tgz
100
100
 
101
101
  npx @deepseek-ai/dsh web
102
102
  ```
@@ -112,7 +112,7 @@ npx @deepseek-ai/dsh web
112
112
  从 GitHub Release 下载离线安装包时,可直接安装 tarball:
113
113
 
114
114
  ```sh
115
- dsh plugin --profile web add ./dsh-remote-bridge-v2.6.1.tgz
115
+ dsh plugin --profile web add ./dsh-remote-bridge-v2.7.1.tgz
116
116
  ```
117
117
 
118
118
  ## 第一次使用
@@ -411,7 +411,7 @@ pnpm check
411
411
  pnpm pack
412
412
  ```
413
413
 
414
- `pnpm check` 覆盖类型检查、文档一致性与测试;当前 **67 个测试文件 / 557 个用例**,外加 **8 个浏览器层用例**(Playwright 实测量出的计算样式,含 375px 窄屏契约),全部通过。
414
+ `pnpm check` 覆盖类型检查、文档一致性与测试;当前 **76 个测试文件 / 698 个用例**,外加 **8 个浏览器层用例**(Playwright 实测量出的计算样式,含 375px 窄屏契约),全部通过。
415
415
 
416
416
  `npm pack` 的产物约 **0.64 MB**(v2.6.1 实测 669,434 字节,SHA-256 `9bf0189b…2cd35`):2.2.0 删除独立页及其编辑器依赖、并关闭 source map 之后从 1.72 MB 降下来,之后随投影透传、权限 BFF 与五维加固小幅增长。
417
417
 
@@ -419,15 +419,37 @@ v2.5.0 在 DSH **0.2.1-rc.2** 上完成真机验证:14/14 宿主服务全部
419
419
  权限档位目录返回内核真实三档。开发基线为上游 `dsh-v0.2.1-rc.2`(commit `687f282e8625c6b8d11ff58211a90524be2e4317`),
420
420
  兼容范围见上文 `engines.dsh`。CI 覆盖 Windows、Ubuntu 和 macOS。
421
421
 
422
- **v2.6.1 的验证状态**:74 个测试文件 / 682 个用例全绿、8 个 Playwright 浏览器用例
423
- (含 375px 窄屏契约)、`typecheck`/`docs:check`/构建通过。SEC-H11 的攻击链是**用实测**
424
- 确认的(起一个假 LLM 端点,抓到内核把真实 `Authorization: Bearer` 打过去),修复后的
425
- 四道闸门各有回归断言;设备身份的三个 spec(27 + 13 + 12 例)覆盖 UA 判定顺序、
426
- 「`declared` 永不覆盖」与老表结构迁移幂等。
422
+ **v2.7.1 的验证状态**:76 个测试文件 / **701 个用例**全绿、`typecheck`/`docs:check`/构建通过。
423
+ 这一版只改 `src/host/dsh-0.2-bridge.ts` 的 `agentFor` 与对应回归测试,其余代码与 v2.7.0 逐字节相同。
424
+
425
+ **v2.7.0 的验证状态**:76 个测试文件 / 698 个用例全绿、8 个 Playwright 浏览器用例
426
+ (含 375px 窄屏契约)、`typecheck`/`docs:check`/构建通过。这一版的四项能力都在
427
+ DSH **0.2.1-rc.3** 隔离实例上**实跑验过**,不是静态推断:插件清单返回
428
+ `loaded: 14 / 16 / problems: 2`、模型目录里 `free:mimo-v2.6-flash-free` 带出
429
+ `ctx=1048576`、`reuseBlank` 的四种语义逐一验过、客户端 bundle 里能找到
430
+ `dsh-remote-bridge-plugins` 与 `sidebarRightTabs`。截图存于 `dsh-021cmp/shots/`。
431
+ 兼容性核对本身也是实测:305 个包逐个 sha256 比对,285 个代码零改动、20 个有实质改动,
432
+ 10 个硬依赖服务的提供方**全部**落在零改动名单,4 个 slot 全保留、删除 0。
427
433
 
428
434
  ## 项目信息
429
435
 
430
- - 当前版本:`v2.6.1`
436
+ - 当前版本:`v2.7.1`
437
+ - **v2.7.1 是缺陷修复版**:内核 `sessionController.resolveAgent()` 返回的是 `{ agent }` / `{ error }`
438
+ **包装对象**而非 Agent 本体(`dsh-api-session-controller/lib/index.js:365-368` 的 `liveAgent()` 与
439
+ `:221-246` 的 `resolve()` 都是这个形状),桥此前把包装对象直接当 Agent 传给 `fileUploads.upload()`,
440
+ 内核读 `agent.session.header.origin` 就炸成
441
+ `DSH_TYPEERROR: Cannot read properties of undefined (reading 'header')` —— 真机表现是
442
+ 「发文件永远 400/500,报错信息完全指不到原因」,附件上传与 agent preset 选择两条路径都挂在这里。
443
+ 现在识别包装形状、成功解出 `.agent`、失败原样抛 `.error`(保留内核稳定 code,「会话不存在」不再
444
+ 被压成「会话没在跑」),同时保留裸对象兼容。新增 3 条回归测试钉住三种返回形状。
445
+ - **v2.7.0 是对齐 DSH 0.2.1-rc.3 的能力提升版**:四项 —— ①模型目录补上 `contextWindow` / `maxTokens`
446
+ (内核的 `ModelCatalogModel` 只有 id/name/description,容量得另走 `llm.resolveModelInfo`,桥按
447
+ `provider + model` 缓存 10 分钟、失败不缓存、内核自己给了就不覆盖);②插件清单多了右侧栏形态
448
+ (成为 `SidebarRightTabDefinition` 提供方,DSH 0.2.1-rc.3 起该卡片可被 pin;rc.2 上正常显示但
449
+ 没有 pin 与 More 菜单,属预期降级);③`POST /chat/sessions` 新增可选 `reuseBlank`,对齐 0.2.1
450
+ 桌面端「新会话回到那个工作区已有的空白会话」的语义,并跳过 preset 与请求不符的空白;
451
+ ④设置页新增「插件」卡片(清单 / 启停 / 检查更新)与「打开插件列表」按钮(rc.2 无
452
+ `pluginNavigation.openList`,故做特性检测而非版本判断)。
431
453
  - **v2.6.1 是安全修复 + 设备身份版**:修掉一个**高危**问题 —— 供应商 `baseURL` 的三个入口
432
454
  (新建 / 修改 / 探测模型)此前不做任何校验,持有 `settings.write` 的设备可以把 baseURL
433
455
  指向自己的服务器,内核会带着**该供应商的真实 API key** 去请求 `/models`,等于凭据直接外泄;
@@ -1,7 +1,7 @@
1
1
  asyncapi: 3.0.0
2
2
  info:
3
3
  title: DeepSeek Harness Mobile Events
4
- version: 2.6.1
4
+ version: 2.7.1
5
5
  description: |
6
6
  Live file and authorized DSH chat events. Reconnect clients must refresh
7
7
  REST state; unbounded replay is not provided.
@@ -1,7 +1,7 @@
1
1
  openapi: 3.1.0
2
2
  info:
3
3
  title: DeepSeek Harness Mobile API
4
- version: 2.6.1
4
+ version: 2.7.1
5
5
  description: Versioned file and chat BFF for mobile and third-party DSH clients. HTTP and HTTPS are both supported.
6
6
  servers:
7
7
  - url: http://127.0.0.1:3090/api/v1
@@ -24,7 +24,7 @@ paths:
24
24
  properties:
25
25
  ok: { type: boolean, const: true }
26
26
  version: { type: string, const: v1 }
27
- pluginVersion: { type: string, const: 2.6.1 }
27
+ pluginVersion: { type: string, const: 2.7.1 }
28
28
  /debug/host-services:
29
29
  get:
30
30
  operationId: hostServices
@@ -772,6 +772,16 @@ paths:
772
772
  path: { $ref: '#/components/schemas/WirePath' }
773
773
  sessionId: { type: string }
774
774
  agentPreset: { type: string }
775
+ reuseBlank:
776
+ type: boolean
777
+ default: true
778
+ description: |
779
+ Only consulted when `sessionId` is absent. When true (the default) the
780
+ bridge first looks for an existing **blank** session at the requested
781
+ location and reuses it, mirroring the DSH 0.2.1 desktop "New Session"
782
+ behaviour; when false it always mints a fresh session. A blank whose
783
+ recorded `agentPreset` contradicts a requested one is skipped rather
784
+ than reused. Clients that omit this field get the desktop semantics.
775
785
  clientRequestId: { type: string, maxLength: 200 }
776
786
  responses:
777
787
  '201': { description: DSH session created or idempotently returned. }
@@ -488,14 +488,21 @@ class DshWorkspaceClient(
488
488
  ).models
489
489
  }
490
490
 
491
+ /**
492
+ * 在工作区里新建会话。
493
+ *
494
+ * [reuseBlank] 省略时由桥按桌面语义处理(复用该位置已有的空白会话);传 `false`
495
+ * 可强制新建一个全新会话。老客户端不传这个参数,行为与之前一致。
496
+ */
491
497
  fun createSessionInWorkspace(
492
498
  workspaceId: String,
493
499
  clientRequestId: String,
494
500
  agentPreset: String? = null,
501
+ reuseBlank: Boolean? = null,
495
502
  ): JsonElement {
496
503
  val body = json.encodeToString(
497
504
  WorkspaceSessionRequest.serializer(),
498
- WorkspaceSessionRequest(workspaceId, agentPreset, clientRequestId),
505
+ WorkspaceSessionRequest(workspaceId, agentPreset, clientRequestId, reuseBlank),
499
506
  )
500
507
  return executeJsonElement("chat/sessions", "POST", body)
501
508
  }
@@ -806,6 +813,7 @@ class EventSubscription internal constructor(
806
813
  val workspaceId: String,
807
814
  val agentPreset: String? = null,
808
815
  val clientRequestId: String,
816
+ val reuseBlank: Boolean? = null,
809
817
  )
810
818
  @Serializable private data class SendMessageRequest(val text: String, val mode: String, val clientRequestId: String)
811
819
  @Serializable private data class ErrorEnvelope(val error: ApiErrorBody)