dsh-code-server-app 0.3.15 → 0.3.16

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
@@ -221,8 +221,10 @@ extension → host POST /code-server-bridge/ask push an editor question in
221
221
  extension → host GET /code-server-bridge/health unauthenticated liveness probe
222
222
  extension → host POST /code-server-bridge/event extension reports open/close etc. (host log tail)
223
223
  host → extension <extensionsDir>/.dshcs-bridge/bridge.json endpoint + token, re-read every 5s
224
- (the directory is announced via the host-injected `DSHCS_EXTENSIONS_DIR` — the extension lives in
225
- the built-in tree now, so it cannot derive it from its own path)
224
+ (the same content is also written **next to the built-in extension** in
225
+ `<tree>/lib/vscode/extensions/.dshcs-bridge/` the env var is only injected when the host
226
+ spawns the IDE, and an **adopted** IDE is a process from an earlier start that never saw it,
227
+ so the extension must be able to find the config from its own location alone)
226
228
  ```
227
229
 
228
230
  Requests use `http.request({ socketPath })` (`fetch` has no socket support) and **no port is ever opened**.
package/README.md CHANGED
@@ -216,7 +216,9 @@ DSH 用**资源地址**命名文件,`openFile` 只负责把地址交给右侧栏
216
216
  扩展 → host GET /code-server-bridge/health 无鉴权探活(便于重启后一眼确认)
217
217
  扩展 → host POST /code-server-bridge/event 扩展上报打开/关闭文件等(进 host 日志尾)
218
218
  host → 扩展 <extensionsDir>/.dshcs-bridge/bridge.json 端点 + 令牌(扩展每 5s 重读)
219
- (目录由 host 注入的 `DSHCS_EXTENSIONS_DIR` 告知 —— 扩展装在内置目录里,自己推不出来)
219
+ (同一份内容还会写到**内置扩展旁边** `<树>/lib/vscode/extensions/.dshcs-bridge/` ——
220
+ 环境变量只在 host spawn IDE 时注入,而被**接管**的 IDE 是上一次启动的进程、拿不到它,
221
+ 扩展得能只靠自身位置读到配置)
220
222
  ```
221
223
 
222
224
  请求走 `http.request({ socketPath })`(`fetch` 不支持 socket),**不开任何端口**。
package/lib/index.js CHANGED
@@ -850,6 +850,30 @@ export async function apply(ctx, config) {
850
850
  isLive: () => bridgeMeta !== null && !bridgeContext.isStale(),
851
851
  });
852
852
 
853
+ /** 桥配置要写的目录(可能有**两个**):
854
+ *
855
+ * ① `<extensionsDir>/.dshcs-bridge/` —— 权威位置;host 侧 /status 与诊断都指向它,
856
+ * 扩展在有 `DSHCS_EXTENSIONS_DIR` 时也读它;
857
+ * ② `<树>/lib/vscode/extensions/.dshcs-bridge/` —— **内置扩展自己会去找的位置**。
858
+ * 为什么需要 ②:`bridge-client` 的兜底是"从自身位置反推"(`<ext>/lib/` 上溯两级),
859
+ * 对内置扩展就是 `<树>/lib/vscode/extensions`。而环境变量只在 host **spawn** IDE 时才注入 ——
860
+ * **adopt(接管正在运行的 IDE)拿不到**:那个进程是上一次启动的,env 早已定死。
861
+ * 没有 ② 的话,被接管的 IDE 即使重载窗口也读不到配置,桥只能等 IDE 重启。
862
+ * 两份内容完全一致(同一个 write/remove 一起写),不存在优先级问题。 */
863
+ function bridgeConfigDirs() {
864
+ const dirs = [bridgeExtensionsDir];
865
+ try {
866
+ const target = extensionTarget(bridgeExtensionsDir, 'dshcs-editor-bridge', 'builtin');
867
+ if (target.builtin) {
868
+ const sibling = path.join(path.dirname(target.dst), BRIDGE_DIRNAME);
869
+ if (!dirs.includes(sibling)) dirs.push(sibling);
870
+ }
871
+ } catch {
872
+ // 树不可用 → 只有权威位置
873
+ }
874
+ return dirs;
875
+ }
876
+
853
877
  /** 同步桥运行时:写入/更新 bridge.json(端点 = 本机 IPC 路径 + 令牌 + pid)。
854
878
  * 端点、令牌、pid 三者任一变化都重写 —— 扩展每 5s 重读,故不需要任何推送。
855
879
  * 监听口起不来时**不写配置**(宁可休眠,不可指向死端点),并说明一次。 */
@@ -859,18 +883,22 @@ export async function apply(ctx, config) {
859
883
  if (handle === null) {
860
884
  if (bridgeMeta !== null) {
861
885
  bridgeMeta = null;
862
- try { removeBridgeConfig(bridgeExtensionsDir); } catch { /* 删不掉也不影响:扩展会因端点在而连不上 */ }
886
+ for (const dir of bridgeConfigDirs()) {
887
+ try { removeBridgeConfig(dir); } catch { /* 删不掉也不影响:扩展会因端点在而连不上 */ }
888
+ }
863
889
  }
864
890
  return;
865
891
  }
866
892
  bridgeToken ??= mintBridgeToken();
867
893
  const changed = bridgeMeta === null || bridgeMeta.pipe !== handle.path || bridgeMeta.token !== bridgeToken || bridgeMeta.pid !== pid;
868
894
  bridgeMeta = { pipe: handle.path, token: bridgeToken, pid, startedAt: startedAt ?? null };
869
- try {
870
- writeBridgeConfig(bridgeExtensionsDir, { pipe: handle.path, token: bridgeToken, pid, startedAt: startedAt ?? null });
871
- } catch (err) {
872
- console.warn(`[code-server] 编辑器桥配置写入失败(${bridgeExtensionsDir}):${err && err.message ? err.message : err}`);
873
- return;
895
+ const value = { pipe: handle.path, token: bridgeToken, pid, startedAt: startedAt ?? null };
896
+ for (const dir of bridgeConfigDirs()) {
897
+ try {
898
+ writeBridgeConfig(dir, value);
899
+ } catch (err) {
900
+ console.warn(`[code-server] 编辑器桥配置写入失败(${dir}):${err && err.message ? err.message : err}`);
901
+ }
874
902
  }
875
903
  if (changed) {
876
904
  // 只打印端点与配置文件位置,不打印令牌本身(与 path-token 同一决策)。
@@ -900,10 +928,12 @@ export async function apply(ctx, config) {
900
928
  bridgeEvents.reset();
901
929
  if (bridgeMeta === null) return;
902
930
  bridgeMeta = null;
903
- try {
904
- removeBridgeConfig(bridgeExtensionsDir);
905
- } catch {
906
- // 配置删不掉不影响正确性(扩展会因 IDE 不可达而休眠)
931
+ for (const dir of bridgeConfigDirs()) {
932
+ try {
933
+ removeBridgeConfig(dir);
934
+ } catch {
935
+ // 配置删不掉不影响正确性(扩展会因 IDE 不可达而休眠)
936
+ }
907
937
  }
908
938
  }
909
939
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-code-server-app",
3
- "version": "0.3.15",
3
+ "version": "0.3.16",
4
4
  "description": "VS Code (from a code-server release) inside DSH: a right-sidebar tab driven by the plugin's own launcher over the in-process VS Code server (lib/launcher.mjs). Since 0.3.0 the bundle also ships an editor bridge (assets/extensions/dshcs-editor-bridge): a read-only channel between the in-tree VS Code extension host and DSH, giving the agent what only the editor knows (unsaved buffers, language-server diagnostics, the active selection) and letting editor gestures drive the session. The tab claims DSH file addresses (dsh-resource://file/**) by file type (setting claimExtensions), so the product's own produced-file chips, delivered-file previews and inline prose mentions open in the workbench. The IDE is a resident surface moved with Element.moveBefore instead of being remounted, so switching sidebar tabs no longer reloads it. Opening the tab switches the right sidebar to fullscreen by default (setting fullscreenOnOpen). Following a workspace switch is lightweight: the workbench re-navigates with the new ?folder= and the IDE process is not restarted (since 0.2.12). Requires a DSH with the right-sidebar services (sidebarRightTabs/sidebarRight, >= 0.1.5-alpha.1); older DSH versions get a single upgrade notice on the settings page and no other UI. Two serving modes: loopback port (default) or same-origin mount on DSH's own webServer (/code-server, protected by ctx.connection.requestRejection). No code-server Node layer, no argon2, no C++ toolchain.",
5
5
  "homepage": "https://github.com/jinsiyu/dsh-code-server-app",
6
6
  "repository": {
@@ -3,7 +3,7 @@
3
3
  "vscodeVersion": "1.137.0",
4
4
  "productPath": "stable-b11dabdaca0d3369986975be285db92c8795cea5",
5
5
  "layout": "vscode-only",
6
- "preparedAt": "2026-09-13T05:15:19.676Z",
6
+ "preparedAt": "2026-09-13T05:19:14.035Z",
7
7
  "source": "registry",
8
8
  "node": "v24.21.0",
9
9
  "platform": "win32",