dsh-remote-bridge 2.3.4 → 2.3.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.
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.3.4-087f8c">
12
+ <img alt="Version" src="https://img.shields.io/badge/version-v2.3.6-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">
@@ -73,10 +73,10 @@ dsh plugin --profile web add dsh-remote-bridge
73
73
  dsh plugin --profile web add dsh-remote-bridge --registry https://registry.npmmirror.com
74
74
 
75
75
  # 2. tarball from the GitHub release
76
- dsh plugin --profile web add https://github.com/westanke/dsh-remote-bridge/releases/download/v2.3.4/dsh-remote-bridge-v2.3.4.tgz
76
+ dsh plugin --profile web add https://github.com/westanke/dsh-remote-bridge/releases/download/v2.3.6/dsh-remote-bridge-v2.3.6.tgz
77
77
 
78
78
  # 3. tarball from the Gitee release (faster from mainland China)
79
- dsh plugin --profile web add https://gitee.com/westanke/dsh-remote-bridge/releases/download/v2.3.4/dsh-remote-bridge-v2.3.4.tgz
79
+ dsh plugin --profile web add https://gitee.com/westanke/dsh-remote-bridge/releases/download/v2.3.6/dsh-remote-bridge-v2.3.6.tgz
80
80
 
81
81
  npx @deepseek-ai/dsh web
82
82
  ```
@@ -93,7 +93,7 @@ Restart DSH after installation, then open settings — The section is titled **
93
93
  To install a downloaded release archive:
94
94
 
95
95
  ```sh
96
- dsh plugin --profile web add ./dsh-remote-bridge-v2.3.4.tgz
96
+ dsh plugin --profile web add ./dsh-remote-bridge-v2.3.6.tgz
97
97
  ```
98
98
 
99
99
  ## First connection
@@ -323,15 +323,15 @@ pnpm check
323
323
  pnpm pack
324
324
  ```
325
325
 
326
- `pnpm check` covers type-checking, documentation consistency, and tests. It currently passes **19 test files / 113 cases**, plus **3 browser-layer cases** (Playwright measuring real computed styles).
326
+ `pnpm check` covers type-checking, documentation consistency, and tests. It currently passes **30 test files / 226 cases**, plus **4 browser-layer cases** (Playwright measuring real computed styles).
327
327
 
328
- `npm pack` produces roughly a **0.25 MB** archive: 2.2.0 dropped the standalone page and its editor dependencies and turned source maps off, down from 1.72 MB.
328
+ `npm pack` produces roughly a **0.29 MB** archive: 2.2.0 dropped the standalone page and its editor dependencies and turned source maps off, down from 1.72 MB.
329
329
 
330
- v2.3.4 was developed against DSH `master@47f943859bef60e4160492346772ded9b24f765a`. CI covers Windows, Ubuntu, and macOS.
330
+ v2.3.6 was developed against DSH `master@47f943859bef60e4160492346772ded9b24f765a`. CI covers Windows, Ubuntu, and macOS.
331
331
 
332
332
  ## Project
333
333
 
334
- - Version: `v2.3.4`
334
+ - Version: `v2.3.6`
335
335
  - Author: upstream [Hakunm](https://github.com/Hakunm); this fork maintained by [westanke](https://github.com/westanke)
336
336
  - Repository: [GitHub](https://github.com/westanke/dsh-remote-bridge) · [Gitee](https://gitee.com/westanke/dsh-remote-bridge)
337
337
  - npm: [`dsh-remote-bridge`](https://www.npmjs.com/package/dsh-remote-bridge) ([mainland-China mirror](https://registry.npmmirror.com/dsh-remote-bridge))
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.3.4-087f8c">
12
+ <img alt="Version" src="https://img.shields.io/badge/version-v2.3.6-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">
@@ -70,10 +70,10 @@ dsh plugin --profile web add dsh-remote-bridge
70
70
  dsh plugin --profile web add dsh-remote-bridge --registry https://registry.npmmirror.com
71
71
 
72
72
  # ② GitHub Release 的 tarball
73
- dsh plugin --profile web add https://github.com/westanke/dsh-remote-bridge/releases/download/v2.3.4/dsh-remote-bridge-v2.3.4.tgz
73
+ dsh plugin --profile web add https://github.com/westanke/dsh-remote-bridge/releases/download/v2.3.6/dsh-remote-bridge-v2.3.6.tgz
74
74
 
75
75
  # ③ Gitee Release 的 tarball(国内访问更快)
76
- dsh plugin --profile web add https://gitee.com/westanke/dsh-remote-bridge/releases/download/v2.3.4/dsh-remote-bridge-v2.3.4.tgz
76
+ dsh plugin --profile web add https://gitee.com/westanke/dsh-remote-bridge/releases/download/v2.3.6/dsh-remote-bridge-v2.3.6.tgz
77
77
 
78
78
  npx @deepseek-ai/dsh web
79
79
  ```
@@ -89,7 +89,7 @@ npx @deepseek-ai/dsh web
89
89
  从 GitHub Release 下载离线安装包时,可直接安装 tarball:
90
90
 
91
91
  ```sh
92
- dsh plugin --profile web add ./dsh-remote-bridge-v2.3.4.tgz
92
+ dsh plugin --profile web add ./dsh-remote-bridge-v2.3.6.tgz
93
93
  ```
94
94
 
95
95
  ## 第一次使用
@@ -315,15 +315,15 @@ pnpm check
315
315
  pnpm pack
316
316
  ```
317
317
 
318
- `pnpm check` 覆盖类型检查、文档一致性与测试;当前 **19 个测试文件 / 113 个用例**,外加 **3 个浏览器层用例**(Playwright 实测量出的计算样式),全部通过。
318
+ `pnpm check` 覆盖类型检查、文档一致性与测试;当前 **30 个测试文件 / 226 个用例**,外加 **4 个浏览器层用例**(Playwright 实测量出的计算样式),全部通过。
319
319
 
320
- `npm pack` 的产物约 **0.25 MB**:2.2.0 删除独立页及其编辑器依赖、并关闭 source map 之后,从 1.72 MB 降下来。
320
+ `npm pack` 的产物约 **0.29 MB**:2.2.0 删除独立页及其编辑器依赖、并关闭 source map 之后,从 1.72 MB 降下来。
321
321
 
322
- v2.3.4 基于 DSH `master@47f943859bef60e4160492346772ded9b24f765a` 开发,CI 覆盖 Windows、Ubuntu 和 macOS。
322
+ v2.3.6 基于 DSH `master@47f943859bef60e4160492346772ded9b24f765a` 开发,CI 覆盖 Windows、Ubuntu 和 macOS。
323
323
 
324
324
  ## 项目信息
325
325
 
326
- - 当前版本:`v2.3.4`
326
+ - 当前版本:`v2.3.6`
327
327
  - 作者:上游 [Hakunm](https://github.com/Hakunm),本 fork 维护 [westanke](https://github.com/westanke)
328
328
  - 仓库:[GitHub](https://github.com/westanke/dsh-remote-bridge) · [Gitee](https://gitee.com/westanke/dsh-remote-bridge)
329
329
  - npm:[`dsh-remote-bridge`](https://www.npmjs.com/package/dsh-remote-bridge)([国内镜像](https://registry.npmmirror.com/dsh-remote-bridge))
@@ -1,7 +1,7 @@
1
1
  asyncapi: 3.0.0
2
2
  info:
3
3
  title: DeepSeek Harness Mobile Events
4
- version: 2.3.4
4
+ version: 2.3.6
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.3.4
4
+ version: 2.3.6
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.3.4 }
27
+ pluginVersion: { type: string, const: 2.3.6 }
28
28
  /pairings/exchange:
29
29
  post:
30
30
  security: []
@@ -1005,6 +1005,13 @@ components:
1005
1005
  id: { type: string }
1006
1006
  rootId: { type: string }
1007
1007
  cwd: { $ref: '#/components/schemas/WirePath' }
1008
+ cwdAbsolute:
1009
+ type: string
1010
+ description: >-
1011
+ Absolute path of the session working directory. Optional; older clients
1012
+ ignore it. Needed to compose `@absolute-path` mentions. Note that an
1013
+ empty `cwd` is legal and means the session working directory IS the
1014
+ authorized root itself.
1008
1015
  updatedAt: { type: integer }
1009
1016
  running: { type: boolean }
1010
1017
  blank: { type: boolean }
@@ -4,7 +4,7 @@ plugins {
4
4
  }
5
5
 
6
6
  group = "ai.deepseek.dsh"
7
- version = "2.3.4"
7
+ version = "2.3.6"
8
8
 
9
9
  repositories { mavenCentral() }
10
10
 
package/lib/index.d.ts CHANGED
@@ -626,6 +626,15 @@ interface WorkspaceRegistryLike {
626
626
  updatedAt: string;
627
627
  sessionIds?: readonly string[];
628
628
  }[];
629
+ /**
630
+ * 注册表级(registry-global)归档集合:被归档、应从**所有**分组界面隐藏的会话 id。
631
+ *
632
+ * 内核 `dsh-workspace` 的 `WorkspaceRegistry` 用 getter 暴露它
633
+ * (`lib/types/index.d.ts` 的 `get archivedSessionIds(): readonly SessionId[]`),
634
+ * 且 `ctx.workspaceRegistry` 就是这个实体。声明成可选:老内核或测试替身可能没有,
635
+ * 读不到时退化成空集合,只是过滤失效,不该让整条列表读崩掉。
636
+ */
637
+ readonly archivedSessionIds?: readonly string[];
629
638
  }
630
639
  interface SettingsControllerLike {
631
640
  describe(): {
@@ -1131,6 +1140,22 @@ interface ChatSessionView {
1131
1140
  id: string;
1132
1141
  rootId: string;
1133
1142
  cwd: string;
1143
+ /**
1144
+ * 会话工作目录的**绝对路径**(可选,老客户端会忽略)。
1145
+ *
1146
+ * `cwd` 是**相对授权根**的 wire 路径(列举接口要的正是这个),手机端要往输入框
1147
+ * 里插一条 `@绝对路径` 时却需要绝对路径 —— 而客户端手里没有根的 realPath
1148
+ * (`RootView` 刻意不含它,那是机器信息)。此前 App 拿 `cwd` 去 `/roots/resolve`
1149
+ * 换,可那个端点**要求绝对路径输入**、对相对路径直接 400 —— 于是补全必然失败。
1150
+ *
1151
+ * 这里补的这一个字段就是那条缺失的桥:会话的绝对 cwd 服务端本来就有(`matchRoot`
1152
+ * 的入参就是它),它又一定落在**这台设备已授权**的根内(不匹配的会话压根不会出现在
1153
+ * 列表里),所以给出它不扩大任何可见范围。
1154
+ *
1155
+ * `cwd` 为空字符串是**合法**的:会话工作目录正好就是授权根本身时,
1156
+ * `path.relative(root, root)` 返回空串 —— 客户端必须把它当作「根目录」而不是「没有」。
1157
+ */
1158
+ cwdAbsolute?: string;
1134
1159
  updatedAt: number;
1135
1160
  running: boolean;
1136
1161
  blank: boolean;
package/lib/index.js CHANGED
@@ -244,7 +244,9 @@ var DshChatAdapter = class {
244
244
  const visible = [];
245
245
  for (const session of value.items) {
246
246
  if (archivedSessionIds.has(session.sessionId)) continue;
247
- const match = session.cwd === void 0 ? void 0 : matchRoot(roots, session.cwd);
247
+ const absoluteCwd = session.cwd;
248
+ if (absoluteCwd === void 0) continue;
249
+ const match = matchRoot(roots, absoluteCwd);
248
250
  if (match === void 0) continue;
249
251
  const workspace = workspaces.find((item) => item.rootId === match.root.id && item.path === match.relative);
250
252
  const title = sessionTitle(session);
@@ -252,6 +254,7 @@ var DshChatAdapter = class {
252
254
  id: session.sessionId,
253
255
  rootId: match.root.id,
254
256
  cwd: match.relative,
257
+ cwdAbsolute: absoluteCwd,
255
258
  updatedAt: session.updatedAt,
256
259
  running: session.running,
257
260
  blank: session.blank,
@@ -2179,12 +2182,30 @@ function isUserQuestionAnswerLike(value) {
2179
2182
  return Array.isArray(entry.selected) && entry.selected.every((label) => typeof label === "string");
2180
2183
  });
2181
2184
  }
2182
- /** Best-effort projection of an Agent identity to its session id. */
2185
+ /**
2186
+ * Best-effort projection of an Agent identity to its session id.
2187
+ *
2188
+ * 内核侧有两个真相来源,顺序不能反:
2189
+ * - `Agent.id` **就是** `SessionId`(`dsh-agent/lib/types/types.d.ts:11-14` 的
2190
+ * `readonly id: SessionId`,运行时由 `dsh-agent-loop/lib/index.js:773` 的
2191
+ * `this.id = id` 赋值)。这是直给的那个,必须第一个查;
2192
+ * - `agent.session` 是 `dsh-session` 的 **class** `Session`,它**没有** `id` 属性 ——
2193
+ * session id 挂在 `header.id`(`SessionHeader.id`)。只查 `session.id` 永远落空。
2194
+ *
2195
+ * 这两条都曾经被漏掉,代价极大:审批与提问两个 waterfall 监听都以
2196
+ * 「`sessionId === undefined` → 原样交给下游」收场,于是**电脑端一切正常、手机端
2197
+ * 一张卡都没有** —— 而且失败是静默的,两侧日志都不会说一句话。
2198
+ */
2183
2199
  function sessionIdOfAgent(agent) {
2184
2200
  if (!agent || typeof agent !== "object") return void 0;
2185
2201
  const candidate = agent;
2186
2202
  if (typeof candidate.sessionId === "string") return candidate.sessionId;
2187
- if (candidate.session && typeof candidate.session === "object" && typeof candidate.session.id === "string") return candidate.session.id;
2203
+ if (typeof candidate.id === "string") return candidate.id;
2204
+ const session = candidate.session;
2205
+ if (session && typeof session === "object") {
2206
+ if (typeof session.id === "string") return session.id;
2207
+ if (session.header && typeof session.header.id === "string") return session.header.id;
2208
+ }
2188
2209
  }
2189
2210
  /** Best-effort projection of a session view to its session id. */
2190
2211
  function sessionIdOf(summary) {
@@ -2377,6 +2398,21 @@ async function handoffImagesForTextOnlyModel(host, roots, fallbackDir, subdir, l
2377
2398
  }
2378
2399
  }
2379
2400
  /**
2401
+ * 读注册表级归档集合,读不到就返回空数组。
2402
+ *
2403
+ * 让 `workspace.list` 把内核的归档状态透传给上层(chat-adapter 靠它把已归档会话
2404
+ * 从列表里滤掉)。getter 缺失(老内核、测试替身)时退化成空集合:过滤失效,
2405
+ * 但列表本身照常可读 —— 比抛错更接近旧的可用行为。
2406
+ *
2407
+ * @param registry - 内核工作区注册表(`ctx.workspaceRegistry`)。
2408
+ * @returns 归档的会话 id;字段缺失或不是字符串数组时为空数组。
2409
+ */
2410
+ function readArchivedSessionIds(registry) {
2411
+ const value = registry.archivedSessionIds;
2412
+ if (!Array.isArray(value)) return [];
2413
+ return value.filter((item) => typeof item === "string");
2414
+ }
2415
+ /**
2380
2416
  * Build the `apiProxy` replacement out of 0.2.x host services.
2381
2417
  *
2382
2418
  * Every method keeps the old `{ rpcId, payload }` request shape and the old
@@ -2384,7 +2420,6 @@ async function handoffImagesForTextOnlyModel(host, roots, fallbackDir, subdir, l
2384
2420
  * `chat-adapter.ts` and `settings-adapter.ts` are written against.
2385
2421
  *
2386
2422
  * @param host - host services resolved from the plugin context.
2387
- * @param host - host services resolved from the plugin context.
2388
2423
  * @returns a `SettingsApiProxy` (i.e. `DshApiProxy` plus the settings surfaces).
2389
2424
  */
2390
2425
  function createDsh02ApiProxy(host, options = {}) {
@@ -2586,7 +2621,7 @@ function createDsh02ApiProxy(host, options = {}) {
2586
2621
  createdAt: row.createdAt,
2587
2622
  updatedAt: row.updatedAt
2588
2623
  })),
2589
- archivedSessionIds: []
2624
+ archivedSessionIds: readArchivedSessionIds(host.workspaceRegistry)
2590
2625
  };
2591
2626
  }),
2592
2627
  create: (request) => call(() => host.workspaceController.create(request.payload)),
@@ -3679,7 +3714,7 @@ async function inspectResolvedPath(root, wirePath) {
3679
3714
  }
3680
3715
  //#endregion
3681
3716
  //#region src/shared/version.ts
3682
- const PLUGIN_VERSION = "2.3.4";
3717
+ const PLUGIN_VERSION = "2.3.6";
3683
3718
  //#endregion
3684
3719
  //#region src/host/router.ts
3685
3720
  var ApiRouter = class {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-remote-bridge",
3
- "version": "2.3.4",
3
+ "version": "2.3.6",
4
4
  "description": "Versioned REST bridge for DeepSeek Harness: remote access for trusted clients (chat, files, devices) plus a Phone-settings panel inside the DSH WebUI.",
5
5
  "type": "module",
6
6
  "packageManager": "pnpm@11.19.0",