dsh-code-server-app 0.1.43 → 0.2.0

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.md CHANGED
@@ -11,10 +11,16 @@
11
11
  > - **需要微软专有扩展时**:从 Marketplace 网页下载 `.vsix`,用 `code-server --install-extension <文件>`(或放入 `--extensions-dir`)手动安装,即可在插件列表使用。
12
12
 
13
13
  静态 profile 插件(npm 包形态,host + client bundle),把 [code-server](https://github.com/coder/code-server)
14
- **作为平台无关的依赖包随插件安装**(打包期产物 `vendor/code-server` → `@jinsiyu/dshcs-code-server`,无安装脚本、无 postinstall),
15
- 二进制部分(argon2 + 16 个原生模块)由 `@jinsiyu/dshcs-*-win32-<架构>` 平台包经聚合包按架构自动选中;
16
- VS Code 内部依赖与预编译原生模块**全部由包管理器随插件一起装好** —— 无需全局 npm 安装、无需配置 `bin`、
17
- 无需改 profile 配置、无需第二条安装命令。
14
+ 发行版里的 **VS Code server 树** 作为平台无关依赖随插件安装(打包期产物 `vendor/vscode` → `@jinsiyu/dshcs-vscode-server`,
15
+ 无安装脚本、无 postinstall);**code-server Node 服务层已由插件自带的 `lib/launcher.mjs` 取代**
16
+ (它直接驱动 `<树>/lib/vscode/out/server-main.js` `loadCodeWithNls()` / `createServer()` / `handleRequest()` /
17
+ `handleUpgrade()`,并补上 `/healthz`、`/manifest.json`、`/_static/*`、`/proxy/:port` 这几条 code-server 原本提供的 HTTP 面);
18
+ 原生模块(node-pty / @vscode/sqlite3 / spdlog …)由 `@jinsiyu/dshcs-*-win32-<架构>` 平台包经聚合包按架构自动选中 ——
19
+ **无需全局 npm 安装、无需配置 `bin`、无需改 profile 配置、无需第二条安装命令、无需 argon2/C++ 工具链**。
20
+
21
+ > 0.2.0 起:**argon2 与 code-server 的 136 个运行时依赖(express / proxy-agent / js-yaml / pem / limiter …)
22
+ > 全部不再随包分发**(减少 ~34.5MB + 一条原生构建链);IDE 提供方式见下方「服务方式(serve)」。
23
+ > 依据与实测证据见 `docs/analysis-code-server-as-dsh-plugin.md`(含子路径挂载、WS 路径、命名管道、fence 的逐项验证)。
18
24
 
19
25
  ## UI 载体(DSH 版本决定,运行时特性检测)
20
26
 
@@ -32,6 +38,21 @@ VS Code 内部依赖与预编译原生模块**全部由包管理器随插件一
32
38
  「窗口化打开(新标签页)」仍然生效(开启后各入口改为浏览器新标签页打开)。
33
39
  - `windowedOpen` 优先级最高:开启时入口按钮一律新开浏览器标签页。
34
40
 
41
+ ## 服务方式(serve)
42
+
43
+ | 方式 | 说明 | 需要 |
44
+ |---|---|---|
45
+ | **`loopback`(默认)** | 插件自己起一个回环端口(`host:port`),右侧栏 iframe 跨源直连;进程可被 adopt(DSH host 重启后接管) | 无 |
46
+ | **`dsh`** | IDE 挂到 **DSH 自己的 HTTP 端口**上的 `/code-server/*`(HTTP prefix 路由)+ `/code-server/<quality>-<commit>`(WS 精确路由),转发到 launcher 的**命名管道**;**没有额外端口**;每条请求(含 WS 握手)先过 `ctx.connection.requestRejection()` —— 与 `/api` 同一套 Host/Origin fence + 浏览器 cookie 认证 | DSH 提供 `webServer` 服务(web profile);desktop 无此服务 → 自动回退 loopback |
47
+
48
+ - 在 `cordis.patch.yml` 的 `config.serve` 或「设置 → 插件 → Code Server → 服务方式」切换(下次启动生效)。
49
+ - `dsh` 模式的实际收益:单一 URL/单一端口(远程访问 DSH 即可用 IDE)、不再暴露额外回环端口、认证与 DSH 同级。
50
+ - `dsh` 模式的两点**已知取舍**:
51
+ 1. iframe 与 DSH **同源** → 该模式下不再挂 `sandbox`(同源 + `allow-same-origin` 可被 frame 自行摘除,属"看起来有防护");
52
+ `loopback` 模式跨源,`sandbox` 保持原样作为真防护。剪贴板仍由 `allow="clipboard-read; clipboard-write"` 提供。
53
+ 2. 转发端口(Ports 面板)的 **WebSocket** 无法用精确升级路由覆盖(端口号在路径里)→ 该功能在 `dsh` 模式下不可用;
54
+ HTTP 转发端口正常;需要端口转发 WS 时请用 `loopback` 模式。
55
+
35
56
  ## 悬浮球 / 浮窗(仅旧版 DSH 回退路径)
36
57
 
37
58
  - **右下角悬浮球**(code-server 官方图标,输入框上方):点击**展开浮窗并亮起**(蓝色光环),再点击**收起并复原**;
@@ -53,7 +74,7 @@ VS Code 内部依赖与预编译原生模块**全部由包管理器随插件一
53
74
  - process 生命周期由 host 插件管理:启动写 `$DSH_HOME/code-server/pid.json`,停止树级终止(taskkill /T 或进程组 SIGKILL),
54
75
  崩溃/退出实时更新状态;DSH host 重启后自动 adopt 仍在运行的实例(校验 pid + /healthz),不重复启动、不误杀别的进程;
55
76
  - `node_modules`、`vendor/` 与 `repack/` 已被 `.gitignore` 排除,推送/克隆仓库后按下方
56
- "打包(如何出包)"执行 `pnpm install` → `pnpm run build:client` → `pnpm run vendor:code-server` →
77
+ "打包(如何出包)"执行 `pnpm install` → `pnpm run build:client` → `pnpm run vendor:vscode` →
57
78
  (发布预编译原生包)→ `pnpm pack` + `dsh plugin --profile web add` 即可。
58
79
 
59
80
  > 本机(BM: Windows 11 ARM64)实测:`code-server@4.136.2`(with Code 1.136.1)由平台子包
@@ -67,8 +88,8 @@ VS Code 内部依赖与预编译原生模块**全部由包管理器随插件一
67
88
  cd C:\Users\User\Desktop\dsh-code-server-app
68
89
  pnpm install # 开发依赖(esbuild + motion);allowBuilds 已显式声明 → 不执行任何 postinstall
69
90
  pnpm run build:client # src/factory.js → lib/client.js(不入库,必须先构建)
70
- pnpm run vendor:check # 可选:查看内置 code-server 版本 vs npm 最新版
71
- pnpm run vendor:code-server # ① 生成 vendor/code-server(上游 code-server )
91
+ pnpm run vendor:check # 可选:查看内置 VS Code 树版本 vs code-server 最新版
92
+ pnpm run vendor:vscode # ① 生成 vendor/vscode(精简 VS Code 树,≈197MB)
72
93
  pnpm run repack:build -- --target win32-arm64,win32-x64 --pack # ② 统一脚本产出全部子包(见下表)
73
94
  pnpm run publish:repacks # ③ 发布全部 @jinsiyu/* 子包(默认 dist-tag = next)
74
95
  pnpm pack # ④ → dsh-code-server-app-<version>.tgz(约 107KB)
@@ -88,52 +109,52 @@ pnpm run promote -- <version>
88
109
 
89
110
  | 子包 | 内容 | os/cpu |
90
111
  |---|---|---|
91
- | `@jinsiyu/dshcs-code-server@<code-server 版本>` | code-server 树(`out/` + `lib/vscode` + 自带 136 个运行时依赖),**不含任何本机二进制** | 平台无关 |
92
- | `@jinsiyu/dshcs-argon2-win32-arm64` / `-x64` | argon2 模块 + 该架构编译好的 `.node`(arm64 0xaa64 / x64 0x8664) | win32-<arch> |
93
- | `@jinsiyu/dshcs-<名字>[-win32-<arch>]` ×24 | VS Code 内部依赖里需要构建的原生包(node-pty / @vscode/sqlite3 / kerberos / koffi / ssh2 / …) | 平台专属带 os/cpu |
94
- | `@jinsiyu/dsh-code-server-runtime-win32-<arch>` | 平台聚合包:`dependencies` 用 `npm:` 别名把上面 16 个原生包 + **argon2** 装回原始名字 | win32-<arch> |
112
+ | `@jinsiyu/dshcs-vscode-server@<code-server 版本>` | 精简 VS Code 树(`lib/vscode` + `out/browser` + `src/browser`,**不含** code-server 的 `out/node` 与 136 个运行时依赖) | 平台无关 |
113
+ | `@jinsiyu/dshcs-<名字>[-win32-<arch>]` ×16 | VS Code 内部依赖里需要构建的原生包(node-pty / @vscode/sqlite3 / kerberos / koffi / ssh2 / spdlog / ) | 平台专属带 os/cpu |
114
+ | `@jinsiyu/dsh-code-server-runtime-win32-<arch>` | 平台聚合包:`dependencies` `npm:` 别名把上面 16 个原生包装回原始名字 | win32-<arch> |
115
+
116
+ > argon2 已随 code-server 服务层一起移除(0.2.0):`auth` 固定 `none`,需要对外访问请用 `serve: dsh`。
95
117
 
96
118
  | 目标 | 命令 |
97
119
  |---|---|
98
- | **打 npm 最新版 code-server** | `pnpm run vendor:latest`(= `--force`):从 registry 取 `code-server@latest` 快照到 `vendor/code-server`;之后**必须**重跑 `repack:build` 并重发全部子包 |
99
- | **指定版本** | `pnpm run vendor:code-server -- --version 4.136.2` |
100
- | **从已装好的树快照** | `pnpm run vendor:code-server -- --from <code-server 目录>`(秒级) |
120
+ | **打最新版(上游 code-server 发行版)** | `pnpm run vendor:latest`(= `--force`):从 registry 取 `code-server@latest` 的树到 `vendor/vscode`;之后**必须**重跑 `repack:build` 并重发全部子包 |
121
+ | **指定版本** | `pnpm run vendor:vscode -- --version 4.136.2` |
122
+ | **从已装好的树快照** | `pnpm run vendor:vscode -- --from <code-server 目录>`(秒级) |
123
+ | **开发期让树可直接跑** | `pnpm run vendor:vscode -- --dev-links`(额外把 `lib/vscode/node_modules` 用 junction 补上) |
101
124
  | **完整重打子包** | `pnpm run repack:build -- --target win32-arm64,win32-x64 --pack`(不给 `--from` 会自动 npm install 解包 + 编译,耗时) |
102
- | **只重打 code-server/argon2 包** | `node scripts/vendor-repacks.mjs --reuse --target win32-arm64,win32-x64 --pack`(复用 `repack/build` 里已有的原生包,不重新分析源树) |
125
+ | **只重打树包/聚合包** | `node scripts/vendor-repacks.mjs --reuse --target win32-arm64,win32-x64 --pack`(复用 `repack/build` 里已有的原生包,不重新分析源树) |
103
126
  | **发布子包** | `pnpm run publish:repacks`(`--dry-run` 预览;`--only <子串>` 过滤;`--otp <code>` / `--limit N` 应对 2FA) |
104
127
  | **发布插件本体** | `pnpm run publish:plugin`(发布**已验证过的那份 tarball**,不会重新打包;默认 dist-tag = `next`) |
105
128
  | **推进 latest** | `pnpm run promote -- <version>`(用户重启确认无误后;`--dry-run` 先看当前标签) |
106
129
  | **只报告版本** | `pnpm run vendor:check` |
107
130
 
108
- > `pnpm pack` 的 `prepack` 会自动跑一次 `vendor-code-server` 脚本;`vendor/code-server` 已存在时它是
109
- > **秒级 no-op**,所以日常只改插件代码的话直接 `pnpm pack` 即可(不会偷偷升级 code-server)。
110
- > 升级 code-server 必须显式 `pnpm run vendor:latest`(或 `--force`/`--version`),并重发子包。
131
+ > `pnpm pack` 的 `prepack` 会自动跑一次 `vendor-vscode-server` 脚本;`vendor/vscode` 已存在时它是
132
+ > **秒级 no-op**,所以日常只改插件代码的话直接 `pnpm pack` 即可(不会偷偷升级 VS Code)。
133
+ > 升级树必须显式 `pnpm run vendor:latest`(或 `--force`/`--version`),并重发子包。
111
134
 
112
135
  ## 安装插件(一条命令;依赖全部由包管理器装好)
113
136
 
114
137
  ```powershell
115
138
  # 包内无 postinstall → 无需 pnpm approve-builds / allowBuilds;一条命令装完
116
- dsh plugin --profile web add dsh-code-server-app@0.1.40
139
+ dsh plugin --profile web add dsh-code-server-app@0.2.0
117
140
  # 本地 tarball 同理:
118
- dsh plugin --profile web add C:\Users\User\Desktop\dsh-code-server-app\dsh-code-server-app-0.1.40.tgz
141
+ dsh plugin --profile web add C:\Users\User\Desktop\dsh-code-server-app\dsh-code-server-app-0.2.0.tgz
119
142
  ```
120
143
 
121
- 装完即用,**没有第二步、没有「安装环境」、不弹安装指引**。0.1.40 起主包只有 **~107KB**(插件自身代码),
144
+ 装完即用,**没有第二步、没有「安装环境」、不弹安装指引**。主包约 **110KB**(插件自身代码 + launcher),
122
145
  其余全部是依赖:
123
146
 
124
- - **code-server 本体**(`lib/vscode` 196.9MB + 它自带的 136 个运行时依赖)是**一个平台无关的包**
125
- `@jinsiyu/dshcs-code-server@<code-server 版本>`,写进插件 `dependencies`,运行根在
126
- `<profile>\node_modules\@jinsiyu\dshcs-code-server\code-server`;
147
+ - **VS Code 树**(`lib/vscode` 196.9MB + `out/browser` + `src/browser`)是**一个平台无关的包**
148
+ `@jinsiyu/dshcs-vscode-server@<code-server 版本>`(0.2.0 起),写进插件 `dependencies`,运行根在
149
+ `<profile>\node_modules\@jinsiyu\dshcs-vscode-server\vscode`;
127
150
  - VS Code 内部依赖里**纯 JS 的部分**(35 个:xterm / katex / typescript / ws / tar …)也写在插件
128
151
  `dependencies`,由 pnpm 装到 profile 的 `node_modules`(hoisted);
129
152
  - **二进制部分**全部由 `@jinsiyu/dshcs-*` 平台包提供(每个平台各一份,os/cpu 限定):
130
- `@jinsiyu/dshcs-argon2-win32-<arch>` 16 个原生包,经**平台聚合包**
131
- `@jinsiyu/dsh-code-server-runtime-win32-<arch>` `npm:` 别名装回**原始名字**
132
- (`argon2` / `node-pty` / `@vscode/sqlite3` / …),聚合包挂在插件 `optionalDependencies` → pnpm 按架构自动选;
153
+ 16 个原生包经**平台聚合包** `@jinsiyu/dsh-code-server-runtime-win32-<arch>` `npm:` 别名装回**原始名字**
154
+ (`node-pty` / `@vscode/sqlite3` / `@vscode/spdlog` / …),聚合包挂在插件 `optionalDependencies` → pnpm 按架构自动选;
133
155
  - 因此依赖图里**没有任何带 pre/install/postinstall 或 binding.gyp 的包** →
134
156
  不需要 profile 的 `allowBuilds`、不执行任何构建、**使用者机器不需要 C++ 工具链**;
135
- - **升级插件不再重下 code-server**:本体包版本按 code-server 版本缓存,pnpm 直接复用;
136
- 只有 code-server 版本变化时才重新下载那 ~60MB,argon2 平台包只有 ~1.5MB。
157
+ - **升级插件不再重下树**:树包版本按上游 code-server 版本缓存,pnpm 直接复用(约 60MB,解包 ≈197MB)。
137
158
 
138
159
  ### 安装机制(为什么这样设计)
139
160
 
@@ -141,47 +162,50 @@ dsh plugin --profile web add C:\Users\User\Desktop\dsh-code-server-app\dsh-code-
141
162
  的包都被判定"需要构建",必须由**宿主 profile** 的 `pnpm-workspace.yaml` 用 `allowBuilds` 批准,
142
163
  否则 `dsh plugin add` 直接 `[ERR_PNPM_IGNORED_BUILDS]` exit 1。依赖包自己的 `pnpm.allowBuilds`、
143
164
  `.npmrc`、`patch:` 协议、`optionalDependencies` 全都不起作用(实测 2026-09,pnpm 11.25);
144
- - **code-server 本体**打包期用 `npm install code-server@<版本> --ignore-scripts`(跳过官方
145
- `sh ./postinstall.sh`:Windows 无 sh,且它只认 npm/yarn 的 user-agent)拿到树 补齐 argon2 native
146
- (win32-arm64 上游无预编译;可复用本机已有 `argon2.node`,见 `DSHCS_ARGON2_BINARY`)→
147
- 剥掉残留安装脚本 快照到 `vendor/code-server/`;
148
- - 随后同一脚本把 `vendor/code-server` 打成**平台无关的本体包**:树放在包内子目录 `code-server/`
149
- (npm/pnpm 打包**永远排除包根目录的 node_modules**,放在被 `files` 覆盖的子目录里才会随包发布),
150
- 包**不写 `dependencies`**(那 136 个依赖已经作为文件打包在 `code-server/node_modules` 里,
151
- 写成 dependencies 会让 pnpm 再装一份),并把 `node_modules/argon2` 整个删掉;
152
- - **argon2** 单独打成两个平台包(`@jinsiyu/dshcs-argon2-win32-arm64` / `-x64`):与其它原生包同一套规则
153
- (删 `scripts`/`files`/`binding.gyp`,删 `prebuilds/` 统一走 `build/Release`),各自用
154
- `node-gyp rebuild --arch=<arch>` 现编并校验 PE machine(0xaa64 / 0x8664);
155
- - **需要编译的包**同样由该脚本重打包成 `@jinsiyu/dshcs-*`:
165
+ - **树**打包期用 `npm install code-server@<版本> --ignore-scripts`(跳过官方 `sh ./postinstall.sh`:
166
+ Windows 无 sh,且它只认 npm/yarn 的 user-agent)拿到上游发行版,然后**只保留 VS Code 树**:
167
+ `scripts/vendor-vscode-server.mjs` 复制 `lib/vscode/**`、`out/browser/**`、`src/browser/**` 与许可文件到
168
+ `vendor/vscode/`,生成树根 `package.json`(版本 = 上游 code-server 版本,便于版本比对);
169
+ code-server 自己的 `out/node/**` 136 个运行时依赖**不再进包**(由 `lib/launcher.mjs` 取代);
170
+ - **需要编译的包**由 `scripts/vendor-repacks.mjs` 重打包成 `@jinsiyu/dshcs-*`:
156
171
  复制已编译的包目录 → **删除 `scripts` / `files` / `binding.gyp` / `.hooks` / `.npmignore`**
157
172
  (保留编译好的 `.node` 与全部运行时文件)→ 依赖里的同集包改成 `npm:` 别名 → 平台专属的加
158
- `os`/`cpu` 与 `-<platform>-<arch>` 后缀;
159
- - **平台聚合包**把重打包包与 argon2 按原始名字装回去( `"node-pty": "npm:@jinsiyu/dshcs-node-pty@1.2.0-beta.15"`、
160
- `"argon2": "npm:@jinsiyu/dshcs-argon2-win32-arm64@0.44.0"`),于是 code-server 与 VS Code 的
161
- `require('argon2')` / `require('node-pty')` 都不用改;聚合包本身 `os`/`cpu` 限定,
173
+ `os`/`cpu` 与 `-<platform>-<arch>` 后缀;win32 目标还会校验 `.node` 的 PE machine
174
+ (0x8664=x64 / 0xaa64=arm64),防交叉编译产物装错架构;
175
+ - **平台聚合包**把重打包包按原始名字装回去(如 `"node-pty": "npm:@jinsiyu/dshcs-node-pty@1.2.0-beta.15"`),
176
+ 于是 VS Code 的 `import('node-pty')` 不用改;聚合包本身 `os`/`cpu` 限定,
162
177
  插件 `optionalDependencies` 同时声明 win32-arm64 与 win32-x64 两份 → 一条命令自动选对;
163
- - **解析路径**:host 用 `require.resolve('@jinsiyu/dshcs-code-server/package.json')` 找到运行根
164
- (包内子目录 `code-server/`),入口 `code-server/out/node/entry.js`;VS Code 内部依赖从该运行根向上查找
165
- (`code-server/node_modules` → 包 `node_modules` → `<profile>/node_modules`)。
166
- - **pnpm 的嵌套陷阱与兜底**:`os`/`cpu` 限定的包 pnpm 往往**嵌套装在聚合包自己的 `node_modules` 下**
167
- (如 `<profile>/node_modules/@jinsiyu/dsh-code-server-runtime-win32-arm64/node_modules/argon2`),
168
- 既不在 profile 根也不在 code-server 树里 host 在启动 code-server 时把该目录加进 **`NODE_PATH`**,
169
- 环境检测也按「code-server 运行根 + 聚合包目录」两个锚点解析(`lib/native.js`)。
170
-
171
- > **体积提示**:插件 tarball 约 **107KB**;`@jinsiyu/dshcs-code-server` **60.5MB**(解包 ~242MB);
172
- > 两个 argon2 平台包各约 **1.5MB**;16 个原生包合计约 250MB。全部合计安装下载约 315MB。
173
- > `vendor/` `repack/` 都不入 git(见 `.gitignore`)。
174
-
175
- > **从 0.1.39 升级**:code-server 从「平台专属子包」改成「**一个平台无关本体包 + 两个 argon2 平台包**」,
176
- > 二进制部分全部并入统一的原生包脚本管理;升级命令不变(一条
177
- > `dsh plugin --profile web add dsh-code-server-app@<版本>`),旧的 `dshcs-code-server-win32-*` 子包会被 pnpm 清掉。
178
+ - **解析路径**:host 用 `require.resolve('@jinsiyu/dshcs-vscode-server/package.json')` 找到运行根
179
+ (包内子目录 `vscode/`),入口 `vscode/lib/vscode/out/server-main.js`;VS Code 内部依赖从该运行根向上查找
180
+ (`vscode/lib/vscode/node_modules` → 包 `node_modules` → `<profile>/node_modules`)。
181
+ (旧全量树 `@jinsiyu/dshcs-code-server/code-server` 仍作为回退被识别。)
182
+ - **运行时布局自愈**(`lib/native.js` 的 `ensureRuntimeLayout()`,**激活时(先于 envCheck)与每次启动前**幂等执行):
183
+ host 会在 VS Code 树里补两类 **junction**(Windows junction / POSIX 目录软链):
184
+ 1. `ensureAliasLinks()`:把聚合包带回的原生别名补到 `<树>/node_modules`
185
+ —— pnpm 会把 `os`/`cpu` 限定的包**嵌套装在聚合包自己的 node_modules 下**,而 VS Code 的
186
+ `lib/vscode/out/server-main.js` **ESM import**(ESM 不认 `NODE_PATH`),缺了就直接 500;
187
+ 2. `ensureInnerModuleLinks()`:把 VS Code 的**内部依赖目录** `lib/vscode/node_modules`
188
+ `lib/vscode/extensions/node_modules` 按两个 `package.json` `dependencies` 补回老布局
189
+ —— 精简树里没有这两个目录,**用显式路径拼依赖的代码**
190
+ (如内置 TS 扩展找 `<ext>/../node_modules/typescript/lib/tsserver.js`)否则会报
191
+ 「VS Code's tsserver was deleted by another application…」(1.136.1 实测)。
192
+ 链接都指向包管理器装出来的真实包,树被重装后的断链会被自动清理重建;`envCheck` 按双锚点解析,
193
+ 并用 `NODE_PATH` 兜底 CJS。
194
+
195
+ > **体积提示**:插件 tarball 约 **110KB**;`@jinsiyu/dshcs-vscode-server` 约 **60MB**(解包 ≈197MB);
196
+ > 16 个原生包合计约 250MB。全部合计安装下载约 310MB。`vendor/` 与 `repack/` 都不入 git(见 `.gitignore`)。
197
+
198
+ > **从 ≤ 0.1.43 升级**:树包由 `@jinsiyu/dshcs-code-server`(全量 code-server,含 `out/node` 与 136 个依赖)
199
+ > 换成 `@jinsiyu/dshcs-vscode-server`(精简树);**新代码默认 `serve: loopback`,行为与 0.1.43 等价**,
200
+ > 需要同源挂载再切 `serve: dsh`。升级命令不变(一条
201
+ > `dsh plugin --profile web add dsh-code-server-app@<版本>`),旧的 `dshcs-code-server` 子包会被 pnpm 清掉。
178
202
 
179
203
  > **从 ≤ 0.1.35 升级**:旧版的安装根 `<profile>\.code-server-app`(含约 1.4GB 内部依赖)与
180
204
  > 「安装环境」步骤都不再需要 —— 新版本会检测到它并打一条日志提示可安全删除:
181
205
  > `Remove-Item -Recurse -Force <profile>\.code-server-app`。profile 的 `pnpm-workspace.yaml` 里
182
206
  > 若还留着 `dsh-code-server-app: false` 之类的旧条目,也可以删掉(新版不再需要任何构建许可)。
183
207
 
184
- > **卸载**:`dsh plugin --profile web remove dsh-code-server-app` 即可;本体包、argon2 与原生包
208
+ > **卸载**:`dsh plugin --profile web remove dsh-code-server-app` 即可;树包与原生包
185
209
  > 是独立依赖,若要彻底清干净可再 `dsh plugin --profile web remove @jinsiyu/dshcs-code-server`
186
210
  > (或直接在 profile 里 `pnpm remove`);若还残留旧安装根,再手动删除 `<profile>\.code-server-app`。
187
211
 
@@ -193,7 +217,7 @@ dsh plugin --profile web add C:\Users\User\Desktop\dsh-code-server-app\dsh-code-
193
217
  dsh plugin --profile web add C:\Users\User\Desktop\dsh-code-server-app
194
218
  ```
195
219
 
196
- > 源码路径以 `link:` 安装。开发机上没有 `vendor/code-server` 时先 `pnpm run vendor:code-server`;
220
+ > 源码路径以 `link:` 安装。开发机上没有 `vendor/vscode` 时先 `pnpm run vendor:vscode -- --dev-links`;
197
221
  > 没有平台子包时 host 会回退到包内 `vendor/code-server`(两种布局都支持)。
198
222
  > 依赖(内部 JS 依赖 + 平台子包 + 聚合包)同样由 pnpm 安装 —— 本地未发布的 `@jinsiyu/*` 需先发布,
199
223
  > 或把 `repack/tgz/*.tgz` 以 `file:` 依赖临时装进 profile(见 `.tmp-verify.mjs`)。
@@ -210,7 +234,7 @@ dsh plugin --profile web add C:\Users\User\Desktop\dsh-code-server-app
210
234
  |---|---|---|---|
211
235
  | Node.js | **v24.x**(code-server 最新要求;本机 v24.13.1) | 必需 | 必需 |
212
236
  | npm / pnpm | npm 跟随 Node;pnpm 由 DSH 提供 | 必需(装依赖) | 必需 |
213
- | **MSVC 构建工具** | **VS Community 2026 + C++ 桌面负载** | ❌ 不需要 | 打包期需要(编译 16 个原生包 + argon2) |
237
+ | **MSVC 构建工具** | **VS Community 2026 + C++ 桌面负载** | ❌ 不需要 | 打包期需要(编译 16 个原生包) |
214
238
  | **VS Spectre 缓解库** | ARM64 与 **x86/x64** 各一份("MSVC v14x Spectre-mitigated libs") | ❌ 不需要 | 打包期需要(否则 MSB8040) |
215
239
  | Python | **3.13.x** | ❌ 不需要 | 打包期需要(node-gyp) |
216
240
  | node-gyp | **13.x**(旧版不识别 VS 2026) | ❌ 不需要 | 打包期需要 |
@@ -229,27 +253,28 @@ dsh plugin --profile web add C:\Users\User\Desktop\dsh-code-server-app
229
253
  - 若不需要插件自足(例如已有全局 code-server),可跳过安装:
230
254
  插件会回退到 PATH/配置的 `bin`(见"配置"表)。
231
255
 
232
- ### 升级 code-server 版本
256
+ ### 升级 VS Code 树(上游 = code-server 发行版)
233
257
 
234
- - **打包期决定版本**:`pnpm run vendor:latest`(= `--force`)取 npm **最新版**并重建 `vendor/code-server`;
235
- 也可 `pnpm run vendor:code-server -- --version 4.136.2` 或设 `DSHCS_CODE_SERVER_VERSION`。
236
- 已有 `vendor/code-server` 时,不带 `--force`/`--version` 不会升级(日常 `pnpm pack` 是 no-op)。
237
- - **先查再升**:`pnpm run vendor:check` 打印「内置版本 / npm latest」。
258
+ - **打包期决定版本**:`pnpm run vendor:latest`(= `--force`)取 npm **最新版 code-server** 的树并重建 `vendor/vscode`;
259
+ 也可 `pnpm run vendor:vscode -- --version 4.136.2` 或设 `DSHCS_CODE_SERVER_VERSION`。
260
+ 已有 `vendor/vscode` 时,不带 `--force`/`--version` 不会升级(日常 `pnpm pack` 是 no-op)。
261
+ - **先查再升**:`pnpm run vendor:check` 打印「内置版本 / 上游 latest」。
238
262
  - **换版本后重新出子包并发布**(全部由同一个脚本):
239
- 1. `pnpm run repack:build -- --target win32-arm64,win32-x64 --pack` → 新的本体包
240
- (`@jinsiyu/dshcs-code-server@<新版本>`)、新的 argon2 平台包、以及按新内部依赖重建的原生包
263
+ 1. `pnpm run repack:build -- --target win32-arm64,win32-x64 --pack` → 新的树包
264
+ (`@jinsiyu/dshcs-vscode-server@<新版本>`)以及按新内部依赖重建的原生包
241
265
  (脚本会把新的「纯 JS 直装集」写进插件 `dependencies`、更新两个聚合包版本);
242
266
  2. `pnpm run publish:repacks` → 发布;然后 bump 插件版本 → `pnpm pack` → 发布插件。
267
+ - `productPath`(`<quality>-<commit>`,客户端 WS 路径的组成)**从 `lib/vscode/product.json` 现算**,
268
+ 升级树后无需改代码 —— 但也意味着切版本后必须重启 dsh web(路由在激活期注册)。
243
269
  - **不再有运行期自动升级**:不会在启动时联网取 latest;版本完全由内置产物决定。
244
- - 本机当前内置:`code-server@4.136.2`(with Code 1.136.1)。
270
+ - 本机当前内置:`code-server@4.136.2` 的树(VS Code 1.136.1,`productPath=stable-8d5f383f…`)。
245
271
 
246
272
  ### 兼容旧安装位
247
273
 
248
- host 探测顺序:`@jinsiyu/dshcs-code-server/code-server`(**0.1.40+ 正式布局**)>
249
- `@jinsiyu/dshcs-code-server-<平台>-<架构>/code-server`(0.1.37 平台专属子包)> 插件包内
250
- `vendor/code-server`(0.1.36 及更早 / 开发期)> 旧版安装根
251
- `<profile>\.code-server-app\node_modules\code-server`(兼容 0.1.35 及更早)> 插件包内
252
- `node_modules/code-server`(开发期)> PATH/配置 `bin`。旧安装根只在启动日志里提示可删除,不再被写入。
274
+ host 探测顺序:`@jinsiyu/dshcs-vscode-server/vscode`(**0.2.0+ 正式布局**)> `@jinsiyu/dshcs-code-server/code-server`
275
+ (0.1.40–0.1.43 全量树)> `@jinsiyu/dshcs-code-server-<平台>-<架构>/code-server`(0.1.37 平台专属子包)>
276
+ 插件包内 `vendor/vscode` > 插件包内 `vendor/code-server`(开发期)。旧安装根
277
+ `<profile>\.code-server-app` 只在启动日志里提示可删除,不再被使用。
253
278
 
254
279
  ## 设置卡片(设置 → 插件 → Code Server)
255
280
 
@@ -262,7 +287,7 @@ host 探测顺序:`@jinsiyu/dshcs-code-server/code-server`(**0.1.40+ 正式布
262
287
  | `windowedOpen` | `false` | **窗口化打开**:开启后各入口(产物按钮 / 设置卡 / 悬浮球)在浏览器**新标签页**打开 code-server(自动启动并跟随当前工作区目录);关闭(默认)使用右侧栏标签(旧版 DSH 为内部浮动窗口) |
263
288
 
264
289
  卡片底部是**环境检测**(点「检测环境」读取 host `status.env`):
265
- 入口、`native`(argon2)、VS Code 内部依赖、**预编译原生包**(平台聚合包名 + 已解析模块数)。
290
+ 树版本 / `productPath` / server 入口、VS Code 内部依赖、**预编译原生包**(平台聚合包名 + 已解析模块数)。
266
291
  0.1.36 起没有「安装环境」按钮 —— 依赖由包管理器安装,卡片里只显示结果。
267
292
 
268
293
  > 卡片改动经 `scope.watch` 实时生效(host 端 status API 同步返回 `reserveComposer` 与
@@ -273,23 +298,23 @@ host 探测顺序:`@jinsiyu/dshcs-code-server/code-server`(**0.1.40+ 正式布
273
298
 
274
299
  | 键 | 默认 | 说明 |
275
300
  |---|---|---|
276
- | `bin` | `code-server`(占位) | 启动优先级:本配置显式 `bin` > 本体包 `@jinsiyu/dshcs-code-server/code-server/out/node/entry.js` > 旧平台子包 `@jinsiyu/dshcs-code-server-<平台>-<架构>` > 包内 `vendor/code-server` > 旧安装根 `.code-server-app` > 插件包内 `node_modules` > PATH 中的 `code-server`。都不存在时启动报错并给出排查提示 |
277
- | `host` | `127.0.0.1` | 绑定地址;`auth: none` 仅允许回环(localhost/127.0.0.1/::1) |
278
- | `port` | `8090` | 端口;被占用时启动失败并给出诊断(不自动换端口) |
279
- | `auth` | `none` | `none` \| `password`;非回环 host 自动要求 password |
280
- | `passwordToken` | `''` | password 模式的 token( `PASSWORD` 环境变量传给 code-server) |
301
+ | `serve` | `loopback` | 服务方式:`loopback`(独立回环端口,iframe 跨源)→ `dsh`(挂到 DSH 自身端口的 `/code-server/*`,转发到命名管道,复用 DSH Host/Origin + cookie 防护)。需 DSH 提供 `webServer`,缺失时自动回退 loopback |
302
+ | `bin` | `''`(空 = 用自带 launcher) | 逃生舱:显式指定外部 code-server 可执行文件 / `out/node/entry.js` 时退回旧模型(不经 `lib/launcher.mjs`) |
303
+ | `host` | `127.0.0.1` | loopback 模式的绑定地址(仅允许回环) |
304
+ | `port` | `8090` | loopback 模式的端口;被占用时启动失败并给出诊断(不自动换端口) |
305
+ | `auth` | `none` | 固定 `none`(0.2.0 起 argon2 已移除;需要对外访问请用 `serve: dsh`) |
281
306
  | `userDataDir` | `$DSH_HOME/code-server/user-data` | 用户数据隔离目录 |
282
307
  | `extensionsDir` | `$DSH_HOME/code-server/extensions` | 扩展目录 |
283
- | `readyTimeoutMs` | `60000` | /healthz 就绪探测超时 |
308
+ | `locale` | `''` | 界面语言(空 = 跟随浏览器),如 `zh-cn` |
309
+ | `readyTimeoutMs` | `60000` | `/healthz` 就绪探测超时(TCP 或命名管道) |
284
310
 
285
311
  用户级覆盖示例(写在 `$DSH_HOME/profiles/web/cordis.patch.yml`,应使用 `- id: code-server` 行覆盖):
286
312
 
287
313
  ```yaml
288
314
  - id: code-server
289
315
  config:
290
- port: 8091
291
- # 显式指定(覆盖依赖安装探测):全局安装的 shim,或任意 entry.js
292
- bin: C:\Users\User\AppData\Roaming\npm\code-server.cmd
316
+ serve: dsh # 同源挂载:/code-server/*(无额外端口,复用 DSH 防护)
317
+ # port: 8091 # serve: loopback 时才生效
293
318
  ```
294
319
 
295
320
  ## JSON API(同源 fetch;web 与 desktop 同一套路径)
@@ -320,10 +345,18 @@ desktop profile 由 `apps/desktop-host` 把 `/api/*` 交给同一个 `createShar
320
345
 
321
346
  ## 已知限制
322
347
 
323
- - **子路径不支持**:code-server 前端使用根路径/WebSocket/Service Worker,因此必须独立端口
324
- iframe 直连,不做 DSH webServer 反向代理;`--base-path` 官方不支持。
325
- - **跨会话单实例**:host 级共享一份 code-server;切换 cwd 需重启实例(右侧栏标签/浮窗自动处理并提示)
326
- - **侧栏标签切换重载**:DSH 右侧栏只渲染当前激活标签的 body,切走再切回会重挂 iframe(code-server 整页重载);
348
+ - ~~子路径不支持~~ **已不成立(0.2.0 实测更正)**:VS Code 渲染出的 workbench HTML 里
349
+ **资源引用全是相对路径**(实测 9 条引用中绝对路径 0 条,`serverBasePath="."`、`rootEndpoint="."`),
350
+ 客户端 WebSocket 路径由 `location.pathname + join(serverBasePath ?? '/', <quality>-<commit>)` 拼成,
351
+ 因此可以直接挂在 DSH 自身的 `/code-server/*` 下(`serve: dsh`),不需要独立端口、
352
+ 也不需要改写 HTML。逐项证据见 `docs/analysis-code-server-as-dsh-plugin.md`。
353
+ - **`serve: dsh` 的端口转发 WS 不可用**:`registerUpgrade` 是精确路径匹配,而 `/proxy/:port` 的端口号在路径里
354
+ → 该模式下 Ports 面板的 **WebSocket** 转发不可用(HTTP 转发正常);需要时用 `serve: loopback`。
355
+ - **`serve: dsh` 的 iframe 与 DSH 同源** → 该模式不挂 `sandbox`(同源 + `allow-same-origin` 可被 frame 自行摘除);
356
+ `loopback` 模式跨源,`sandbox` 作为真防护保留。
357
+ - **跨会话单实例**:host 级共享一份 IDE;切换 cwd 需重启实例(右侧栏标签/浮窗自动处理并提示)。
358
+ - **侧栏标签切换重载**:DSH 右侧栏只渲染当前激活标签的 body,切走再切回会重挂 iframe(VS Code 整页重载);
327
359
  长驻会话请保持该标签激活或将其浮动为独立面板。
328
- - **远程访问**:默认仅回环 + 无认证。跨机访问需改 `host` + `auth: password` + `passwordToken`,
329
- 且浏览器必须能直接到达该主机(本插件的“在新标签打开”按 `host:port` 拼 URL)。
360
+ - **远程访问**:`serve: dsh` 下浏览器只需能到达 DSH 本身(单一端口,认证与 `/api` 同级);
361
+ `serve: loopback` 默认仅回环、`auth: none`,跨机访问请改用 `serve: dsh`
362
+ (0.2.0 起不再支持 `auth: password`)。
package/cordis.patch.yml CHANGED
@@ -4,26 +4,30 @@
4
4
  - id: code-server
5
5
  name: dsh-code-server-app
6
6
  config:
7
- # code-server 启动方式,优先级:
8
- # 1. 本配置的 bin(显式指定,如绝对路径/可执行名/entry.js)
9
- # 2. 插件依赖安装(node_modules/code-server/out/node/entry.js,
10
- # package.json dependencies;npm install 随插件安装)
11
- # 3. PATH 中的 code-server
12
- # 找不到时报错并在 UI 给出安装指引,不会静默失败。
13
- # bin: code-server
14
- # 绑定地址:仅允许回环与显式授权地址;非回环时强制 password 认证。
7
+ # VS Code 树的启动由插件自带的 lib/launcher.mjs 完成(0.2.0 起不再运行 code-server
8
+ # Node 服务层)。正常情况下无需配置 bin;它只是逃生舱:指向外部 code-server
9
+ # 可执行文件 / out/node/entry.js 时,插件退回旧模型(不经 launcher)。
10
+ # bin: ''
11
+ #
12
+ # ---- 服务方式(serve) ----
13
+ # loopback(默认):插件自己起一个回环端口(host:port),右侧栏 iframe 跨源直连。
14
+ # dsh :把 IDE 挂到 DSH 自己的 HTTP 端口上(/code-server/*),复用 DSH 的
15
+ # Host/Origin + cookie 防护(requestRejection),没有额外端口;
16
+ # 需要 DSH 提供 webServer 服务,缺失(如 desktop)时自动回退 loopback。
17
+ # 也可在「设置 → 插件 → Code Server」卡片里切换(下次启动生效)。
18
+ serve: loopback
19
+ # loopback 模式的绑定地址:仅允许回环(auth=none 已不再支持口令认证)。
15
20
  host: 127.0.0.1
16
- # 端口;被占用时启动失败并给出诊断(不自动换端口)。
21
+ # loopback 模式的端口;被占用时启动失败并给出诊断(不自动换端口)。
17
22
  port: 8090
18
- # 认证模式:none | password。
19
- # - none:仅限 loopback(默认)。
20
- # - password:host 非回环时自动启用;也可显式配置 token。
23
+ # 认证:0.2.0 起固定为 none —— 口令认证依赖的 argon2 已随 code-server 服务层移除。
24
+ # 需要对外访问请用 serve: dsh(由 DSH 统一防护)。
21
25
  auth: none
22
- # password 模式的一次性 token;留空则启动时生成并写入 UI 状态/日志。
23
- passwordToken: ''
24
- # code-server 数据目录(隔离用户数据,不污染真实 VS Code 设置)。
26
+ # VS Code 数据目录(隔离用户数据,不污染真实 VS Code 设置)。
25
27
  userDataDir: ''
26
28
  extensionsDir: ''
29
+ # 界面语言(留空 = 跟随浏览器);如 zh-cn。
30
+ locale: ''
27
31
  # 启动就绪探测超时(ms)。
28
32
  readyTimeoutMs: 60000
29
33
  # 注:窗口行为(是否保留输入框上方空间)由"设置 → 插件 → Code Server"