dsh-code-server-app 0.3.14 → 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 +4 -2
- package/README.md +3 -1
- package/lib/index.js +79 -14
- package/package.json +1 -1
- package/vendor/VENDOR.json +1 -1
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
|
|
225
|
-
|
|
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
|
-
(
|
|
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
|
@@ -354,6 +354,36 @@ function openFileSignalPath(userDataDir) {
|
|
|
354
354
|
return path.join(userDataDir, 'User', 'dshcs-open.json');
|
|
355
355
|
}
|
|
356
356
|
|
|
357
|
+
/** 已安装的内置扩展里最新的文件 mtime(ms);取不到返回 null。
|
|
358
|
+
*
|
|
359
|
+
* 用途:**adopt(接管正在运行的 IDE)时判断"里面跑的是不是升级前的旧代码"**。
|
|
360
|
+
* 扩展代码只在扩展宿主进程启动时被加载一次 —— 文件是新的不代表跑着的进程里是新的。
|
|
361
|
+
* `mtime > IDE 进程启动时间` 说明这些文件是在该进程起来之后写的,那个进程不可能加载过它们。
|
|
362
|
+
* (可能偏保守:之后重载过窗口就没事了 —— 所以提示写成"可能/重载即可"。) */
|
|
363
|
+
export function newestBundledExtensionMtime(extensionsDir, options = {}) {
|
|
364
|
+
const treeRoot = options.treeRoot === undefined ? vsRoot() : options.treeRoot;
|
|
365
|
+
let newest = null;
|
|
366
|
+
for (const ext of BUNDLED_EXTENSIONS) {
|
|
367
|
+
const target = extensionTarget(extensionsDir, ext.name, ext.placement, treeRoot);
|
|
368
|
+
if (!fs.existsSync(target.dst)) continue;
|
|
369
|
+
let files;
|
|
370
|
+
try {
|
|
371
|
+
files = listExtensionFiles(target.dst);
|
|
372
|
+
} catch {
|
|
373
|
+
continue;
|
|
374
|
+
}
|
|
375
|
+
for (const rel of files) {
|
|
376
|
+
try {
|
|
377
|
+
const at = fs.statSync(path.join(target.dst, rel)).mtimeMs;
|
|
378
|
+
if (newest === null || at > newest) newest = at;
|
|
379
|
+
} catch {
|
|
380
|
+
// 单个文件 stat 失败不影响结论
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
return newest;
|
|
385
|
+
}
|
|
386
|
+
|
|
357
387
|
/** 插件 package.json 里声明的内部依赖(纯 JS 直装集;排除 VS Code 树包本身)。 */
|
|
358
388
|
function declaredInnerDeps() {
|
|
359
389
|
try {
|
|
@@ -820,6 +850,30 @@ export async function apply(ctx, config) {
|
|
|
820
850
|
isLive: () => bridgeMeta !== null && !bridgeContext.isStale(),
|
|
821
851
|
});
|
|
822
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
|
+
|
|
823
877
|
/** 同步桥运行时:写入/更新 bridge.json(端点 = 本机 IPC 路径 + 令牌 + pid)。
|
|
824
878
|
* 端点、令牌、pid 三者任一变化都重写 —— 扩展每 5s 重读,故不需要任何推送。
|
|
825
879
|
* 监听口起不来时**不写配置**(宁可休眠,不可指向死端点),并说明一次。 */
|
|
@@ -829,18 +883,22 @@ export async function apply(ctx, config) {
|
|
|
829
883
|
if (handle === null) {
|
|
830
884
|
if (bridgeMeta !== null) {
|
|
831
885
|
bridgeMeta = null;
|
|
832
|
-
|
|
886
|
+
for (const dir of bridgeConfigDirs()) {
|
|
887
|
+
try { removeBridgeConfig(dir); } catch { /* 删不掉也不影响:扩展会因端点在而连不上 */ }
|
|
888
|
+
}
|
|
833
889
|
}
|
|
834
890
|
return;
|
|
835
891
|
}
|
|
836
892
|
bridgeToken ??= mintBridgeToken();
|
|
837
893
|
const changed = bridgeMeta === null || bridgeMeta.pipe !== handle.path || bridgeMeta.token !== bridgeToken || bridgeMeta.pid !== pid;
|
|
838
894
|
bridgeMeta = { pipe: handle.path, token: bridgeToken, pid, startedAt: startedAt ?? null };
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
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
|
+
}
|
|
844
902
|
}
|
|
845
903
|
if (changed) {
|
|
846
904
|
// 只打印端点与配置文件位置,不打印令牌本身(与 path-token 同一决策)。
|
|
@@ -870,10 +928,12 @@ export async function apply(ctx, config) {
|
|
|
870
928
|
bridgeEvents.reset();
|
|
871
929
|
if (bridgeMeta === null) return;
|
|
872
930
|
bridgeMeta = null;
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
931
|
+
for (const dir of bridgeConfigDirs()) {
|
|
932
|
+
try {
|
|
933
|
+
removeBridgeConfig(dir);
|
|
934
|
+
} catch {
|
|
935
|
+
// 配置删不掉不影响正确性(扩展会因 IDE 不可达而休眠)
|
|
936
|
+
}
|
|
877
937
|
}
|
|
878
938
|
}
|
|
879
939
|
|
|
@@ -1219,10 +1279,15 @@ export async function apply(ctx, config) {
|
|
|
1219
1279
|
// 桥的传输/协议变更(0.3.13 的 url → pipe)会让旧代码读到 v2 配置后休眠 —— 必须明说,否则
|
|
1220
1280
|
// 表现又是那句无法自查的"编辑器还没有上报状态"。
|
|
1221
1281
|
const synced = installBundledExtensions(extensionsDir, userDataDir);
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
|
|
1282
|
+
const newest = newestBundledExtensionMtime(extensionsDir);
|
|
1283
|
+
const staleCode = synced.updated.length > 0
|
|
1284
|
+
|| (newest !== null && record.startedAt !== null && newest > record.startedAt);
|
|
1285
|
+
if (staleCode) {
|
|
1286
|
+
console.warn('[code-server] 内置扩展文件比当前 IDE 进程新'
|
|
1287
|
+
+ `${synced.updated.length > 0 ? `(本次更新:${synced.updated.join(',')})` : ''}:`
|
|
1288
|
+
+ '被接管的 IDE 不会重新加载扩展,里面跑的**可能仍是旧代码**。'
|
|
1289
|
+
+ '若编辑器桥没有状态(editor_context 报"编辑器还没有上报状态"),'
|
|
1290
|
+
+ '请在 Code Server 标签里重载一次窗口(或重启 IDE)让扩展宿主读到新代码');
|
|
1226
1291
|
}
|
|
1227
1292
|
adoptBridgeRuntime(record.pid, state.startedAt);
|
|
1228
1293
|
return snapshot();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-code-server-app",
|
|
3
|
-
"version": "0.3.
|
|
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": {
|
package/vendor/VENDOR.json
CHANGED
|
@@ -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:
|
|
6
|
+
"preparedAt": "2026-09-13T05:19:14.035Z",
|
|
7
7
|
"source": "registry",
|
|
8
8
|
"node": "v24.21.0",
|
|
9
9
|
"platform": "win32",
|