dsh-code-server-app 0.1.40 → 0.1.42

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
@@ -10,7 +10,7 @@
10
10
  > - Microsoft **open-source** extensions (Python, TypeScript debugger, ESLint, …) are mirrored on Open VSX and install normally by search;
11
11
  > - **If you need a proprietary Microsoft extension**: download the `.vsix` from the Marketplace page and install it manually with `code-server --install-extension <file>` (or drop it into `--extensions-dir`).
12
12
 
13
- A static profile plugin (npm package with host + client bundle) that ships [code-server](https://github.com/coder/code-server) as a **platform-specific sub-package dependency** (a pack-time artifact at `vendor/code-server` → `@jinsiyu/dshcs-code-server-<platform>-<arch>`, with no install scripts and no postinstall) and runs it outside the plugin directory. VS Code's inner dependencies and the prebuilt native modules are **all installed by the package manager together with the plugin** — no global npm install, no `bin` configuration, no profile config changes, no second install command.
13
+ A static profile plugin (npm package with host + client bundle) that ships [code-server](https://github.com/coder/code-server) as a **platform-independent dependency package** (a pack-time artifact at `vendor/code-server` → `@jinsiyu/dshcs-code-server`, with no install scripts and no postinstall); its binaries (argon2 plus 16 native modules) come from `@jinsiyu/dshcs-*-win32-<arch>` platform packages selected automatically per architecture by the platform aggregator. VS Code's inner dependencies and the prebuilt native modules are **all installed by the package manager together with the plugin** — no global npm install, no `bin` configuration, no profile config changes, no second install command.
14
14
 
15
15
  ## UI carrier (chosen by the DSH version, feature-detected at runtime)
16
16
 
@@ -59,23 +59,43 @@ cd C:\Users\User\Desktop\dsh-code-server-app
59
59
  pnpm install # dev deps (esbuild + motion); allowBuilds is explicit → no postinstall runs
60
60
  pnpm run build:client # src/factory.js → lib/client.js (not committed; must be built first)
61
61
  pnpm run vendor:check # optional: show the bundled code-server version vs npm latest
62
- pnpm run vendor:code-server # ① produce vendor/code-server (code-server + its own deps)
63
- pnpm run repack:code-server -- --target win32-arm64,win32-x64 --pack # ② platform sub-packages (incl. argon2)
64
- node scripts/vendor-repacks.mjs --target win32-arm64,win32-x64 --pack # build/repack the VS Code natives
65
- pnpm run publish:repacks # ④ publish every @jinsiyu/* sub-package
66
- pnpm pack # ⑤ dsh-code-server-app-<version>.tgz (~105KB)
67
- npm publish dsh-code-server-app-<version>.tgz --access public # publish the plugin itself (same verified tarball)
62
+ pnpm run vendor:code-server # ① produce vendor/code-server (the upstream tree)
63
+ pnpm run repack:build -- --target win32-arm64,win32-x64 --pack # ② one script builds every sub-package
64
+ pnpm run publish:repacks # publish every @jinsiyu/* sub-package (default dist-tag: next)
65
+ pnpm pack # ④ dsh-code-server-app-<version>.tgz (~107KB)
66
+ pnpm run publish:plugin # ⑤ publish the plugin itself (default dist-tag: next)
67
+ # once the user has restarted dsh web and confirmed it works, promote latest:
68
+ pnpm run promote -- <version>
68
69
  ```
69
70
 
71
+ > **dist-tag policy (mandatory)**: every release goes to **`next`** and **never touches `latest`**;
72
+ > `latest` always points at the most recent *confirmed bug-free* version and is only moved by
73
+ > `pnpm run promote -- <version>` (= `npm dist-tag add dsh-code-server-app@<version> latest`)
74
+ > **after the user restarts `dsh web` and confirms it works**. That way
75
+ > `dsh plugin add dsh-code-server-app` (no version) — and anything else resolving `latest` — never picks up an
76
+ > unverified build. Sub-packages (`@jinsiyu/dshcs-*`, the aggregators) are referenced by exact/caret versions,
77
+ > so their dist-tags do not affect resolution, but they default to `next` as well.
78
+ > Inspect the current tags with `npm dist-tag ls dsh-code-server-app`.
79
+
80
+ `repack:build` (`scripts/vendor-repacks.mjs`) is the **single script that produces every sub-package**:
81
+
82
+ | Sub-package | Content | os/cpu |
83
+ |---|---|---|
84
+ | `@jinsiyu/dshcs-code-server@<code-server version>` | the code-server tree (`out/` + `lib/vscode` + its 136 runtime deps), **no machine-specific binary** | platform-independent |
85
+ | `@jinsiyu/dshcs-argon2-win32-arm64` / `-x64` | the argon2 module plus its compiled `.node` for that architecture (arm64 0xaa64 / x64 0x8664) | win32-<arch> |
86
+ | `@jinsiyu/dshcs-<name>[-win32-<arch>]` ×24 | the VS Code inner packages that need building (node-pty / @vscode/sqlite3 / kerberos / koffi / ssh2 / …) | gated when platform-specific |
87
+ | `@jinsiyu/dsh-code-server-runtime-win32-<arch>` | platform aggregator: its `dependencies` map those 16 natives **plus argon2** back to their original names via `npm:` aliases | win32-<arch> |
88
+
70
89
  | Goal | Command |
71
90
  |---|---|
72
- | **Build the latest code-server from npm** | `pnpm run vendor:latest` (= `--force`): snapshots `code-server@latest` into `vendor/code-server`; afterwards you **must** re-run `repack:code-server` (republish the sub-packages) and `vendor-repacks.mjs` (the inner dependency versions change) |
91
+ | **Build the latest code-server from npm** | `pnpm run vendor:latest` (= `--force`): snapshots `code-server@latest` into `vendor/code-server`; afterwards you **must** re-run `repack:build` and republish every sub-package |
73
92
  | **Pin a version** | `pnpm run vendor:code-server -- --version 4.136.2` |
74
93
  | **Snapshot from an existing tree** | `pnpm run vendor:code-server -- --from <code-server dir>` (seconds) |
75
- | **Rebuild the code-server sub-packages** | `pnpm run repack:code-server -- --target win32-arm64,win32-x64 --pack` (x64 compiles argon2 and checks the PE machine type) |
76
- | **Rebuild prebuilt natives** | `node scripts/vendor-repacks.mjs [--from <existing full install>] --target win32-arm64,win32-x64 --pack` (without `--from` it npm-installs and compiles the source tree itself — slow) |
94
+ | **Rebuild every sub-package** | `pnpm run repack:build -- --target win32-arm64,win32-x64 --pack` (without `--from` it npm-installs and compiles the source tree itself — slow) |
95
+ | **Rebuild only the code-server/argon2 packages** | `node scripts/vendor-repacks.mjs --reuse --target win32-arm64,win32-x64 --pack` (reuses the natives already in `repack/build`, no source-tree analysis) |
77
96
  | **Publish sub-packages** | `pnpm run publish:repacks` (`--dry-run` to preview; `--only <substr>` to filter; `--otp <code>` / `--limit N` for 2FA) |
78
- | **Publish the plugin itself** | `npm publish dsh-code-server-app-<version>.tgz --access public` (publishes the exact tarball that was verified; no re-packing) |
97
+ | **Publish the plugin itself** | `pnpm run publish:plugin` (publishes the exact tarball that was verified; no re-packing; default dist-tag `next`) |
98
+ | **Promote `latest`** | `pnpm run promote -- <version>` (only after the user restarted and confirmed; `--dry-run` shows the current tags first) |
79
99
  | **Just report versions** | `pnpm run vendor:check` |
80
100
 
81
101
  > `pnpm pack`'s `prepack` runs the vendor-code-server script once; when `vendor/code-server` already exists it is
@@ -87,28 +107,28 @@ npm publish dsh-code-server-app-<version>.tgz --access public # ⑥ publish th
87
107
 
88
108
  ```powershell
89
109
  # no postinstall in the package → no pnpm approve-builds / allowBuilds; one command installs everything
90
- dsh plugin --profile web add dsh-code-server-app@0.1.37
110
+ dsh plugin --profile web add dsh-code-server-app@0.1.40
91
111
  # a local tarball works the same way:
92
- dsh plugin --profile web add C:\Users\User\Desktop\dsh-code-server-app\dsh-code-server-app-0.1.37.tgz
112
+ dsh plugin --profile web add C:\Users\User\Desktop\dsh-code-server-app\dsh-code-server-app-0.1.40.tgz
93
113
  ```
94
114
 
95
115
  Ready to use immediately — **no second step, no "Install environment", no install-guide modal**.
96
- Since 0.1.37 the main package is only **~105KB** (the plugin's own code); everything else is dependencies:
116
+ Since 0.1.40 the main package is only **~107KB** (the plugin's own code); everything else is dependencies:
97
117
 
98
- - **the code-server tree** (`lib/vscode` 196.9MB + its own 136 runtime dependencies) ships as a **platform-specific
99
- sub-package** `@jinsiyu/dshcs-code-server-<platform>-<arch>@<code-server version>` (gated by `os`/`cpu`, listed in
100
- the plugin's `optionalDependencies`) → pnpm picks the right one for the architecture; it runs from
101
- `<profile>\node_modules\@jinsiyu\dshcs-code-server-win32-arm64\code-server`;
118
+ - **the code-server tree** (`lib/vscode` 196.9MB + its own 136 runtime dependencies) is a **platform-independent
119
+ package** `@jinsiyu/dshcs-code-server@<code-server version>` declared in the plugin's `dependencies`; it runs from
120
+ `<profile>\node_modules\@jinsiyu\dshcs-code-server\code-server`;
102
121
  - the **pure-JS part** of VS Code's inner dependencies (35 packages: xterm / katex / typescript / ws / tar …) is
103
122
  declared in the plugin's `dependencies` and installed by pnpm into the profile's `node_modules` (hoisted);
104
- - the **packages that need compiling** (node-pty / @vscode/sqlite3 / kerberos / koffi / ssh2 / cpu-features /
105
- @parcel/watcher / @vscode/windows-* … 16 in total) are provided as prebuilt `@jinsiyu/dshcs-*` packages,
106
- pulled back under their **original names** by the **platform aggregator**
107
- `@jinsiyu/dsh-code-server-runtime-<platform>-<arch>` using `npm:` aliases;
123
+ - the **binary part** comes entirely from `@jinsiyu/dshcs-*` platform packages (one per platform, `os`/`cpu` gated):
124
+ `@jinsiyu/dshcs-argon2-win32-<arch>` and 16 native packages, mapped back to their **original names**
125
+ (`argon2` / `node-pty` / `@vscode/sqlite3` / …) by the **platform aggregator**
126
+ `@jinsiyu/dsh-code-server-runtime-win32-<arch>` using `npm:` aliases; the aggregators sit in the plugin's
127
+ `optionalDependencies`, so pnpm auto-selects the right platform;
108
128
  - consequently the dependency graph contains **no package with pre/install/postinstall or a `binding.gyp`** →
109
129
  no profile `allowBuilds`, no build script ever runs, and **the user machine needs no C++ toolchain**;
110
- - **upgrading the plugin no longer re-downloads code-server**: the sub-package is cached by version, so only a
111
- code-server version change pulls those ~58MB again.
130
+ - **upgrading the plugin no longer re-downloads code-server**: the tree package is cached by version, so only a
131
+ code-server version change pulls those ~60MB again (the argon2 platform package is only ~1.5MB).
112
132
 
113
133
  ### Install mechanism (why it is built this way)
114
134
 
@@ -122,34 +142,41 @@ Since 0.1.37 the main package is only **~105KB** (the plugin's own code); everyt
122
142
  user agents, so it always fails under pnpm) → supply the argon2 native binary (no Windows prebuild exists;
123
143
  compile with `node-gyp-build`, or reuse an existing `argon2.node` via `DSHCS_ARGON2_BINARY`) → strip leftover
124
144
  install scripts → snapshot to `vendor/code-server/`;
125
- - `scripts/vendor-code-server-pkg.mjs` then turns it into **platform sub-packages**: the tree lives in an inner
126
- `code-server/` directory (npm/pnpm packing **always excludes the package root's `node_modules`**; a subdirectory
127
- covered by `files` is included), and the sub-package declares **no `dependencies`** (those 136 packages are
128
- already files inside `code-server/node_modules`; declaring them would make pnpm install a second copy).
129
- `os`/`cpu` gated, each with its own compiled argon2 (arm64 0xaa64 / x64 0x8664);
130
- - **packages that need compiling** are repacked by `scripts/vendor-repacks.mjs` into `@jinsiyu/dshcs-*`:
145
+ - the same script then builds the **platform-independent tree package**: the tree lives in an inner `code-server/`
146
+ directory (npm/pnpm packing **always excludes the package root's `node_modules`**; a subdirectory covered by
147
+ `files` is included), the package declares **no `dependencies`** (those 136 packages are already files inside
148
+ `code-server/node_modules`; declaring them would make pnpm install a second copy) and its
149
+ `node_modules/argon2` is removed entirely;
150
+ - **argon2** becomes two platform packages (`@jinsiyu/dshcs-argon2-win32-arm64` / `-x64`) built with the very same
151
+ rules as the other natives (delete `scripts`/`files`/`binding.gyp`, delete `prebuilds/` so both always load
152
+ `build/Release`), each compiled with `node-gyp rebuild --arch=<arch>` and PE-checked (0xaa64 / 0x8664);
153
+ - **packages that need compiling** are repacked into `@jinsiyu/dshcs-*`:
131
154
  copy the already-compiled package directory → **delete `scripts` / `files` / `binding.gyp` / `.hooks` /
132
155
  `.npmignore`** (keeping the compiled `.node` and every runtime file) → rewrite dependencies that belong to the
133
156
  same set to `npm:` aliases → platform-specific ones get an `os`/`cpu` pair and a `-<platform>-<arch>` suffix;
134
- - **the platform aggregator** maps those repacks back to their original names (e.g.
135
- `"node-pty": "npm:@jinsiyu/dshcs-node-pty@1.2.0-beta.15"`), so VS Code's `require('node-pty')` needs no change.
136
- The aggregator itself is `os`/`cpu` gated, and the plugin declares both win32-arm64 and win32-x64 in
137
- `optionalDependencies` → one command picks the right one automatically;
157
+ - **the platform aggregator** maps those repacks and argon2 back to their original names (e.g.
158
+ `"node-pty": "npm:@jinsiyu/dshcs-node-pty@1.2.0-beta.15"`, `"argon2": "npm:@jinsiyu/dshcs-argon2-win32-arm64@0.44.0"`),
159
+ so code-server's and VS Code's `require(...)` calls need no change. The aggregator itself is `os`/`cpu` gated,
160
+ and the plugin declares both win32-arm64 and win32-x64 in `optionalDependencies` → one command picks the right one;
138
161
  - **resolution path**: the host resolves the runtime root with
139
- `require.resolve('@jinsiyu/dshcs-code-server-<platform>-<arch>/package.json')` (then the inner `code-server/`
140
- directory) and launches `code-server/out/node/entry.js`; VS Code's inner dependencies are resolved upward from
141
- there: `code-server/node_modules` → the sub-package's `node_modules` → `<profile>/node_modules` (hoisted
142
- layout), exactly what the runtime sees. The in-package `vendor/code-server` is only a development/legacy
143
- fallback.
144
-
145
- > **Size note**: the plugin tarball is **~105KB**; each `@jinsiyu/dshcs-code-server-win32-*` sub-package is
146
- > **~58–60MB** (249MB unpacked); the inner dependencies and prebuilt natives add ~250MB. A full install downloads
147
- > roughly 310MB. Neither `vendor/` nor `repack/` is tracked by git (see `.gitignore`).
148
-
149
- > **Upgrading from 0.1.36**: the in-package `vendor/code-server/` moved into the platform sub-packages and the
150
- > main package shrank to ~105KB. The upgrade command is unchanged
151
- > (`dsh plugin --profile web add dsh-code-server-app@<version>`); the old `vendor/` disappears with the old
152
- > package directory.
162
+ `require.resolve('@jinsiyu/dshcs-code-server/package.json')` (then the inner `code-server/` directory) and
163
+ launches `code-server/out/node/entry.js`; inner dependencies resolve upward from there
164
+ (`code-server/node_modules` → the package's `node_modules` → `<profile>/node_modules`).
165
+ - **pnpm's nesting gotcha and the safety net**: `os`/`cpu`-gated packages are often installed **nested inside the
166
+ aggregator** (e.g. `<profile>/node_modules/@jinsiyu/dsh-code-server-runtime-win32-arm64/node_modules/argon2`),
167
+ i.e. neither at the profile root nor inside the code-server tree → the host adds that directory to the child
168
+ process's **`NODE_PATH`**, and the environment check resolves against both anchors
169
+ (code-server root + aggregator directory) see `lib/native.js`.
170
+
171
+ > **Size note**: the plugin tarball is **~107KB**; `@jinsiyu/dshcs-code-server` is **~60.5MB** (242MB unpacked);
172
+ > each argon2 platform package is **~1.5MB**; the 16 native packages add ~250MB. A full install downloads
173
+ > roughly 315MB. Neither `vendor/` nor `repack/` is tracked by git (see `.gitignore`).
174
+
175
+ > **Upgrading from ≤ 0.1.39**: code-server moved from a platform-specific sub-package to **one
176
+ > platform-independent package plus two argon2 platform packages**, and every binary is now produced by the single
177
+ > repack script. The upgrade command is unchanged
178
+ > (`dsh plugin --profile web add dsh-code-server-app@<version>`); the old `dshcs-code-server-win32-*`
179
+ > sub-packages are removed by pnpm.
153
180
 
154
181
  > **Upgrading from ≤ 0.1.35**: the old install root `<profile>\.code-server-app` (with ~1.4GB of inner
155
182
  > dependencies) and the "Install environment" step are gone. The new version detects the old root and logs that it
@@ -157,9 +184,9 @@ Since 0.1.37 the main package is only **~105KB** (the plugin's own code); everyt
157
184
  > `dsh-code-server-app: false` entries in the profile's `pnpm-workspace.yaml` can be removed too (no build
158
185
  > approval is needed any more).
159
186
 
160
- > **Uninstall**: `dsh plugin --profile web remove dsh-code-server-app` is enough; the code-server sub-package and
161
- > the natives are separate dependencies, so to remove everything run e.g.
162
- > `dsh plugin --profile web remove @jinsiyu/dshcs-code-server-win32-arm64` (or `pnpm remove` inside the profile);
187
+ > **Uninstall**: `dsh plugin --profile web remove dsh-code-server-app` is enough; the tree package, argon2 and the
188
+ > natives are separate dependencies, so to remove everything run e.g.
189
+ > `dsh plugin --profile web remove @jinsiyu/dshcs-code-server` (or `pnpm remove` inside the profile);
163
190
  > if an old install root is still around, delete `<profile>\.code-server-app` manually.
164
191
 
165
192
  > After install/dependency changes, **restart `dsh web`** (the static plugin row and host probe paths load at startup).
@@ -214,18 +241,19 @@ dsh plugin --profile web add C:\Users\User\Desktop\dsh-code-server-app
214
241
  **latest** version; or use `pnpm run vendor:code-server -- --version 4.136.2` / `DSHCS_CODE_SERVER_VERSION`.
215
242
  With an existing `vendor/code-server`, a plain `pnpm pack` never upgrades (it is a no-op).
216
243
  - **Check first**: `pnpm run vendor:check` prints the bundled version / npm latest.
217
- - **A version bump requires republishing two kinds of sub-packages** (the inner dependency versions change with
218
- code-server):
219
- 1. `pnpm run repack:code-server -- --target win32-arm64,win32-x64 --pack` the new code-server sub-packages;
220
- 2. `node scripts/vendor-repacks.mjs --target win32-arm64,win32-x64 --pack` the prebuilt natives (also rewrites
221
- the plugin's pure-JS `dependencies` and both aggregator versions);
222
- 3. `pnpm run publish:repacks` → publish; then bump the plugin version → `pnpm pack` → publish the plugin.
244
+ - **A version bump means rebuilding and republishing the sub-packages** (all with the same script):
245
+ 1. `pnpm run repack:build -- --target win32-arm64,win32-x64 --pack` → the new tree package
246
+ (`@jinsiyu/dshcs-code-server@<new version>`), the new argon2 platform packages and the natives rebuilt
247
+ against the new inner dependencies (the script also rewrites the plugin's pure-JS `dependencies` and both
248
+ aggregator versions);
249
+ 2. `pnpm run publish:repacks` → publish; then bump the plugin version → `pnpm pack` → publish the plugin.
223
250
  - **No runtime auto-upgrade anymore**: nothing fetches latest at startup; the version is fully determined by the bundled artifact.
224
251
  - Bundled locally right now: `code-server@4.136.2` (with Code 1.136.1).
225
252
 
226
253
  ### Compatibility with the old install locations
227
254
 
228
- Host probe order: `@jinsiyu/dshcs-code-server-<platform>-<arch>/code-server` (**the real layout since 0.1.37**) >
255
+ Host probe order: `@jinsiyu/dshcs-code-server/code-server` (**the real layout since 0.1.40**) >
256
+ `@jinsiyu/dshcs-code-server-<platform>-<arch>/code-server` (the 0.1.37 platform sub-packages) >
229
257
  the in-package `vendor/code-server` (0.1.36 and earlier / development) > the old install root
230
258
  `<profile>\.code-server-app\node_modules\code-server` (0.1.35 and earlier) > plugin-internal
231
259
  `node_modules/code-server` (development) > PATH/config `bin`. The old root is only mentioned in a startup log
@@ -254,7 +282,7 @@ package manager, and the card only reports the result.
254
282
 
255
283
  | Key | Default | Description |
256
284
  |---|---|---|
257
- | `bin` | `code-server` (placeholder) | Launch priority: explicit `bin` in config > the platform sub-package `@jinsiyu/dshcs-code-server-<platform>-<arch>/code-server/out/node/entry.js` > the in-package `vendor/code-server` > the old install root `.code-server-app` > plugin-internal `node_modules` > `code-server` on PATH. None present → startup error with troubleshooting hints |
285
+ | `bin` | `code-server` (placeholder) | Launch priority: explicit `bin` in config > the tree package `@jinsiyu/dshcs-code-server/code-server/out/node/entry.js` > the old platform sub-packages `@jinsiyu/dshcs-code-server-<platform>-<arch>` > the in-package `vendor/code-server` > the old install root `.code-server-app` > plugin-internal `node_modules` > `code-server` on PATH. None present → startup error with troubleshooting hints |
258
286
  | `host` | `127.0.0.1` | Bind address; `auth: none` only allows loopback (localhost/127.0.0.1/::1) |
259
287
  | `port` | `8090` | Port; on conflict startup fails with diagnostics (no automatic port change) |
260
288
  | `auth` | `none` | `none` \| `password`; non-loopback host automatically requires password |
package/README.md CHANGED
@@ -11,8 +11,8 @@
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-<平台>-<架构>`,
15
- 无安装脚本、无 postinstall),插件目录外就地运行;
14
+ **作为平台无关的依赖包随插件安装**(打包期产物 `vendor/code-server` → `@jinsiyu/dshcs-code-server`,无安装脚本、无 postinstall),
15
+ 二进制部分(argon2 + 16 个原生模块)由 `@jinsiyu/dshcs-*-win32-<架构>` 平台包经聚合包按架构自动选中;
16
16
  VS Code 内部依赖与预编译原生模块**全部由包管理器随插件一起装好** —— 无需全局 npm 安装、无需配置 `bin`、
17
17
  无需改 profile 配置、无需第二条安装命令。
18
18
 
@@ -68,23 +68,41 @@ cd C:\Users\User\Desktop\dsh-code-server-app
68
68
  pnpm install # 开发依赖(esbuild + motion);allowBuilds 已显式声明 → 不执行任何 postinstall
69
69
  pnpm run build:client # src/factory.js → lib/client.js(不入库,必须先构建)
70
70
  pnpm run vendor:check # 可选:查看内置 code-server 版本 vs npm 最新版
71
- pnpm run vendor:code-server # ① 生成 vendor/code-server(code-server 本体 + 自身依赖)
72
- pnpm run repack:code-server -- --target win32-arm64,win32-x64 --pack # ② 打成平台专属子包(含 argon2 原生)
73
- node scripts/vendor-repacks.mjs --target win32-arm64,win32-x64 --pack # 生成/重打包 VS Code 原生包
74
- pnpm run publish:repacks # ④ 发布全部 @jinsiyu/* 子包( npm 登录)
75
- pnpm pack # ⑤ dsh-code-server-app-<version>.tgz(约 105KB)
76
- npm publish dsh-code-server-app-<version>.tgz --access public # 发布插件本体(同一次验证的 tarball)
71
+ pnpm run vendor:code-server # ① 生成 vendor/code-server(上游 code-server )
72
+ pnpm run repack:build -- --target win32-arm64,win32-x64 --pack # ② 统一脚本产出全部子包(见下表)
73
+ pnpm run publish:repacks # 发布全部 @jinsiyu/* 子包(默认 dist-tag = next)
74
+ pnpm pack # ④ dsh-code-server-app-<version>.tgz( 107KB)
75
+ pnpm run publish:plugin # ⑤ 发布插件本体(默认 dist-tag = next)
76
+ # 用户重启 dsh web 确认无误后,再把 latest 推进到该版本:
77
+ pnpm run promote -- <version>
77
78
  ```
78
79
 
80
+ > **dist-tag 政策(必须遵守)**:发布一律发到 **`next`**,**不动 `latest`**;
81
+ > `latest` 只保留「最近一个确认无 bug 的版本」,由 `pnpm run promote -- <version>`
82
+ > (= `npm dist-tag add dsh-code-server-app@<version> latest`)在**用户重启 dsh web 确认无误后**才推进。
83
+ > 这样 `dsh plugin add dsh-code-server-app`(不带版本)和任何按 latest 安装的流程都不会拿到未验证的版本。
84
+ > 子包(`@jinsiyu/dshcs-*`、聚合包)被依赖以精确/插入符版本引用,dist-tag 不影响解析,但同样默认发 `next`。
85
+ > 查看当前标签:`npm dist-tag ls dsh-code-server-app`。
86
+
87
+ `repack:build`(`scripts/vendor-repacks.mjs`)是**唯一的子包产出脚本**,一次生成:
88
+
89
+ | 子包 | 内容 | os/cpu |
90
+ |---|---|---|
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> |
95
+
79
96
  | 目标 | 命令 |
80
97
  |---|---|
81
- | **打 npm 最新版 code-server** | `pnpm run vendor:latest`(= `--force`):从 registry 取 `code-server@latest` 快照到 `vendor/code-server`;之后**必须**重跑 `repack:code-server`(重发子包)与 `vendor-repacks.mjs`(内部依赖版本会变) |
98
+ | **打 npm 最新版 code-server** | `pnpm run vendor:latest`(= `--force`):从 registry 取 `code-server@latest` 快照到 `vendor/code-server`;之后**必须**重跑 `repack:build` 并重发全部子包 |
82
99
  | **指定版本** | `pnpm run vendor:code-server -- --version 4.136.2` |
83
100
  | **从已装好的树快照** | `pnpm run vendor:code-server -- --from <code-server 目录>`(秒级) |
84
- | **重打 code-server 子包** | `pnpm run repack:code-server -- --target win32-arm64,win32-x64 --pack`(x64 会现编 argon2 并校验 PE) |
85
- | **重建预编译原生包** | `node scripts/vendor-repacks.mjs [--from <已完整安装的树>] --target win32-arm64,win32-x64 --pack`(不给 `--from` 会自己 npm install 解包 + 编译,耗时) |
101
+ | **完整重打子包** | `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` 里已有的原生包,不重新分析源树) |
86
103
  | **发布子包** | `pnpm run publish:repacks`(`--dry-run` 预览;`--only <子串>` 过滤;`--otp <code>` / `--limit N` 应对 2FA) |
87
- | **发布插件本体** | `npm publish dsh-code-server-app-<version>.tgz --access public`(发布**已验证过的那份 tarball**,不会重新打包) |
104
+ | **发布插件本体** | `pnpm run publish:plugin`(发布**已验证过的那份 tarball**,不会重新打包;默认 dist-tag = `next`) |
105
+ | **推进 latest** | `pnpm run promote -- <version>`(用户重启确认无误后;`--dry-run` 先看当前标签) |
88
106
  | **只报告版本** | `pnpm run vendor:check` |
89
107
 
90
108
  > `pnpm pack` 的 `prepack` 会自动跑一次 `vendor-code-server` 脚本;`vendor/code-server` 已存在时它是
@@ -95,27 +113,27 @@ npm publish dsh-code-server-app-<version>.tgz --access public # ⑥ 发布插
95
113
 
96
114
  ```powershell
97
115
  # 包内无 postinstall → 无需 pnpm approve-builds / allowBuilds;一条命令装完
98
- dsh plugin --profile web add dsh-code-server-app@0.1.37
116
+ dsh plugin --profile web add dsh-code-server-app@0.1.40
99
117
  # 本地 tarball 同理:
100
- dsh plugin --profile web add C:\Users\User\Desktop\dsh-code-server-app\dsh-code-server-app-0.1.37.tgz
118
+ dsh plugin --profile web add C:\Users\User\Desktop\dsh-code-server-app\dsh-code-server-app-0.1.40.tgz
101
119
  ```
102
120
 
103
- 装完即用,**没有第二步、没有「安装环境」、不弹安装指引**。0.1.37 起主包只有 **~105KB**(插件自身代码),
121
+ 装完即用,**没有第二步、没有「安装环境」、不弹安装指引**。0.1.40 起主包只有 **~107KB**(插件自身代码),
104
122
  其余全部是依赖:
105
123
 
106
- - **code-server 本体**(含 `lib/vscode` 196.9MB + 它自带的 136 个运行时依赖)打成**平台专属子包**
107
- `@jinsiyu/dshcs-code-server-<platform>-<arch>@<code-server 版本>`(os/cpu 限定,
108
- 挂在插件 `optionalDependencies`)→ pnpm 按架构自动选中,运行根在
109
- `<profile>\node_modules\@jinsiyu\dshcs-code-server-win32-arm64\code-server`;
110
- - VS Code 内部依赖里**纯 JS 的部分**(35 个:xterm / katex / typescript / ws / tar …)写在插件
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`;
127
+ - VS Code 内部依赖里**纯 JS 的部分**(35 个:xterm / katex / typescript / ws / tar …)也写在插件
111
128
  `dependencies`,由 pnpm 装到 profile 的 `node_modules`(hoisted);
112
- - **需要编译的原生包**(node-pty / @vscode/sqlite3 / kerberos / koffi / ssh2 / cpu-features /
113
- @parcel/watcher / @vscode/windows-* …共 16 个)由 `@jinsiyu/dshcs-*` 预编译包提供,
114
- 经**平台聚合包** `@jinsiyu/dsh-code-server-runtime-<platform>-<arch>` 用 `npm:` 别名装回**原始名字**;
129
+ - **二进制部分**全部由 `@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 按架构自动选;
115
133
  - 因此依赖图里**没有任何带 pre/install/postinstall 或 binding.gyp 的包** →
116
134
  不需要 profile 的 `allowBuilds`、不执行任何构建、**使用者机器不需要 C++ 工具链**;
117
- - **升级插件不再重下 code-server**:子包版本按 code-server 版本缓存,pnpm 会直接复用;
118
- 只有 code-server 版本变化时才重新下载那 ~58MB
135
+ - **升级插件不再重下 code-server**:本体包版本按 code-server 版本缓存,pnpm 直接复用;
136
+ 只有 code-server 版本变化时才重新下载那 ~60MB,argon2 平台包只有 ~1.5MB
119
137
 
120
138
  ### 安装机制(为什么这样设计)
121
139
 
@@ -127,38 +145,44 @@ dsh plugin --profile web add C:\Users\User\Desktop\dsh-code-server-app\dsh-code-
127
145
  `sh ./postinstall.sh`:Windows 无 sh,且它只认 npm/yarn 的 user-agent)拿到树 → 补齐 argon2 native
128
146
  (win32-arm64 上游无预编译;可复用本机已有 `argon2.node`,见 `DSHCS_ARGON2_BINARY`)→
129
147
  剥掉残留安装脚本 → 快照到 `vendor/code-server/`;
130
- - 随后 `scripts/vendor-code-server-pkg.mjs` 把它打成**平台子包**:树放在包内子目录 `code-server/`
148
+ - 随后同一脚本把 `vendor/code-server` 打成**平台无关的本体包**:树放在包内子目录 `code-server/`
131
149
  (npm/pnpm 打包**永远排除包根目录的 node_modules**,放在被 `files` 覆盖的子目录里才会随包发布),
132
- 子包**不写 `dependencies`**(那 136 个依赖已经作为文件打包在 `code-server/node_modules` 里,
133
- 写成 dependencies 会让 pnpm 再装一份);`os`/`cpu` 限定 + 各自编译好的 argon2(arm64 0xaa64 / x64 0x8664);
134
- - **需要编译的包**由 `scripts/vendor-repacks.mjs` 重打包成 `@jinsiyu/dshcs-*`:
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-*`:
135
156
  复制已编译的包目录 → **删除 `scripts` / `files` / `binding.gyp` / `.hooks` / `.npmignore`**
136
157
  (保留编译好的 `.node` 与全部运行时文件)→ 依赖里的同集包改成 `npm:` 别名 → 平台专属的加
137
158
  `os`/`cpu` 与 `-<platform>-<arch>` 后缀;
138
- - **平台聚合包**把重打包包按原始名字装回去(如 `"node-pty": "npm:@jinsiyu/dshcs-node-pty@1.2.0-beta.15"`),
139
- 于是 VS Code 内部代码 `require('node-pty')` 不用改;聚合包本身 `os`/`cpu` 限定,
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` 限定,
140
162
  插件 `optionalDependencies` 同时声明 win32-arm64 与 win32-x64 两份 → 一条命令自动选对;
141
- - **解析路径**:host 用 `require.resolve('@jinsiyu/dshcs-code-server-<平台>-<架构>/package.json')`
142
- 找到运行根(子目录 `code-server/`),入口 `code-server/out/node/entry.js`;
143
- VS Code 内部依赖从该运行根向上查找:`code-server/node_modules` → 子包 `node_modules` →
144
- `<profile>/node_modules`(hoisted 布局),与运行时完全一致。包内 `vendor/code-server` 仅作
145
- 开发期/兼容回退。
146
-
147
- > **体积提示**:插件 tarball 约 **105KB**;`@jinsiyu/dshcs-code-server-win32-*` 子包各约 **58–60MB**
148
- > (解包 ~249MB);内部依赖与预编译原生包约 250MB。全部合计安装下载约 310MB。
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。
149
173
  > `vendor/` 与 `repack/` 都不入 git(见 `.gitignore`)。
150
174
 
151
- > **从 ≤ 0.1.36 升级**:插件包内的 `vendor/code-server/` 已移出到平台子包,主包瘦身到 ~105KB;
152
- > 升级命令不变(一条 `dsh plugin --profile web add dsh-code-server-app@<版本>`),
153
- > 旧的 `vendor/` 会随旧版本包目录一起被 pnpm 清掉。
175
+ > **从 ≤ 0.1.39 升级**:code-server 从「平台专属子包」改成「**一个平台无关本体包 + 两个 argon2 平台包**」,
176
+ > 二进制部分全部并入统一的原生包脚本管理;升级命令不变(一条
177
+ > `dsh plugin --profile web add dsh-code-server-app@<版本>`),旧的 `dshcs-code-server-win32-*` 子包会被 pnpm 清掉。
154
178
 
155
179
  > **从 ≤ 0.1.35 升级**:旧版的安装根 `<profile>\.code-server-app`(含约 1.4GB 内部依赖)与
156
180
  > 「安装环境」步骤都不再需要 —— 新版本会检测到它并打一条日志提示可安全删除:
157
181
  > `Remove-Item -Recurse -Force <profile>\.code-server-app`。profile 的 `pnpm-workspace.yaml` 里
158
182
  > 若还留着 `dsh-code-server-app: false` 之类的旧条目,也可以删掉(新版不再需要任何构建许可)。
159
183
 
160
- > **卸载**:`dsh plugin --profile web remove dsh-code-server-app` 即可;code-server 子包与原生包
161
- > 是独立依赖,若要彻底清干净可再 `dsh plugin --profile web remove @jinsiyu/dshcs-code-server-win32-arm64`
184
+ > **卸载**:`dsh plugin --profile web remove dsh-code-server-app` 即可;本体包、argon2 与原生包
185
+ > 是独立依赖,若要彻底清干净可再 `dsh plugin --profile web remove @jinsiyu/dshcs-code-server`
162
186
  > (或直接在 profile 里 `pnpm remove`);若还残留旧安装根,再手动删除 `<profile>\.code-server-app`。
163
187
 
164
188
  > 安装/依赖变化后请**重启 `dsh web`**(静态插件行与 host 探测路径在启动时加载)。
@@ -211,17 +235,18 @@ dsh plugin --profile web add C:\Users\User\Desktop\dsh-code-server-app
211
235
  也可 `pnpm run vendor:code-server -- --version 4.136.2` 或设 `DSHCS_CODE_SERVER_VERSION`。
212
236
  已有 `vendor/code-server` 时,不带 `--force`/`--version` 不会升级(日常 `pnpm pack` 是 no-op)。
213
237
  - **先查再升**:`pnpm run vendor:check` 打印「内置版本 / npm latest」。
214
- - **换版本后要重发两类子包**(内部依赖版本会跟着 code-server 变):
215
- 1. `pnpm run repack:code-server -- --target win32-arm64,win32-x64 --pack` → 新版本号的 code-server 平台子包;
216
- 2. `node scripts/vendor-repacks.mjs --target win32-arm64,win32-x64 --pack` → 预编译原生包(并把新的
217
- 「纯 JS 直装集」写进插件 `dependencies`、更新两个聚合包版本);
218
- 3. `pnpm run publish:repacks` → 发布;然后 bump 插件版本 → `pnpm pack` → 发布插件。
238
+ - **换版本后重新出子包并发布**(全部由同一个脚本):
239
+ 1. `pnpm run repack:build -- --target win32-arm64,win32-x64 --pack` → 新的本体包
240
+ (`@jinsiyu/dshcs-code-server@<新版本>`)、新的 argon2 平台包、以及按新内部依赖重建的原生包
241
+ (脚本会把新的「纯 JS 直装集」写进插件 `dependencies`、更新两个聚合包版本);
242
+ 2. `pnpm run publish:repacks` → 发布;然后 bump 插件版本 → `pnpm pack` → 发布插件。
219
243
  - **不再有运行期自动升级**:不会在启动时联网取 latest;版本完全由内置产物决定。
220
244
  - 本机当前内置:`code-server@4.136.2`(with Code 1.136.1)。
221
245
 
222
246
  ### 兼容旧安装位
223
247
 
224
- host 探测顺序:`@jinsiyu/dshcs-code-server-<平台>-<架构>/code-server`(**0.1.37+ 正式布局**)> 插件包内
248
+ host 探测顺序:`@jinsiyu/dshcs-code-server/code-server`(**0.1.40+ 正式布局**)>
249
+ `@jinsiyu/dshcs-code-server-<平台>-<架构>/code-server`(0.1.37 平台专属子包)> 插件包内
225
250
  `vendor/code-server`(0.1.36 及更早 / 开发期)> 旧版安装根
226
251
  `<profile>\.code-server-app\node_modules\code-server`(兼容 0.1.35 及更早)> 插件包内
227
252
  `node_modules/code-server`(开发期)> PATH/配置 `bin`。旧安装根只在启动日志里提示可删除,不再被写入。
@@ -248,7 +273,7 @@ host 探测顺序:`@jinsiyu/dshcs-code-server-<平台>-<架构>/code-server`(**0
248
273
 
249
274
  | 键 | 默认 | 说明 |
250
275
  |---|---|---|
251
- | `bin` | `code-server`(占位) | 启动优先级:本配置显式 `bin` > 平台子包 `@jinsiyu/dshcs-code-server-<平台>-<架构>/code-server/out/node/entry.js` > 包内 `vendor/code-server` > 旧安装根 `.code-server-app` > 插件包内 `node_modules` > PATH 中的 `code-server`。都不存在时启动报错并给出排查提示 |
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`。都不存在时启动报错并给出排查提示 |
252
277
  | `host` | `127.0.0.1` | 绑定地址;`auth: none` 仅允许回环(localhost/127.0.0.1/::1) |
253
278
  | `port` | `8090` | 端口;被占用时启动失败并给出诊断(不自动换端口) |
254
279
  | `auth` | `none` | `none` \| `password`;非回环 host 自动要求 password |
package/lib/index.js CHANGED
@@ -48,7 +48,7 @@ import {
48
48
  vendoredVersion,
49
49
  vendorReady,
50
50
  } from './vendor.js';
51
- import { aliasNodePathDirs, resolveNativeDir, resolveRuntime, runtimePackageName, verifyNatives } from './native.js';
51
+ import { aliasNodePathDirs, ensureRuntimeLayout, resolveNativeDir, resolveRuntime, runtimePackageName, verifyNatives } from './native.js';
52
52
 
53
53
  // schemastery 由 DSH 部署自带(官方核心依赖),仿 auto-open-web 的解析策略:
54
54
  // 常规 import 优先,不可用时回退到全局 npm 布局的 DSH 部署副本。
@@ -645,6 +645,8 @@ export async function apply(ctx, config) {
645
645
 
646
646
  let proc;
647
647
  try {
648
+ // 启动前再自愈一次依赖布局(插件重装/树被替换后可能丢失;幂等且只做存在性检查)
649
+ ensureRuntimeLayout();
648
650
  const isCmd = launch.kind === 'bin' && win32() && /\.cmd$/i.test(launch.command);
649
651
  const command = launch.kind === 'node' ? process.execPath : launch.command;
650
652
  const spawnArgs = launch.kind === 'node' ? [launch.script, ...args] : args;
@@ -878,6 +880,18 @@ export async function apply(ctx, config) {
878
880
  }
879
881
 
880
882
  state.env = envCheck();
883
+ // 补齐 code-server 树里被"拍平"掉的依赖布局:
884
+ // ① VS Code 内部依赖目录(lib/vscode/node_modules、lib/vscode/extensions/node_modules)
885
+ // —— 老模型是 npm 装在树里的真实目录,新模型拍平在 profile 根;用显式路径找依赖的代码
886
+ // (如内置 TS 扩展找 tsserver.js)否则会报 "tsserver was deleted …";
887
+ // ② 聚合包带回的原生别名(ESM import 不认 NODE_PATH,只能靠目录链)。
888
+ const layout = ensureRuntimeLayout();
889
+ if (layout.created.length > 0) {
890
+ console.log(`[code-server] 已补齐 ${layout.created.length} 个依赖链接: ${layout.created.join(', ')}`);
891
+ }
892
+ if (layout.failed.length > 0) {
893
+ console.warn(`[code-server] 依赖链接创建失败: ${layout.failed.join('; ')}`);
894
+ }
881
895
  if (!vendorReady()) {
882
896
  console.warn(`[code-server] 找不到 code-server 运行树:平台子包 ${codeServerPackageName()} 未安装,`
883
897
  + '且包内 vendor/code-server 不存在(开发期请先 `npm run vendor:code-server`)');
package/lib/native.js CHANGED
@@ -10,9 +10,10 @@
10
10
  //
11
11
  // 本模块只做两件事:
12
12
  // 1. 找到本平台聚合包(以及它的依赖清单 = 期望可解析的原生模块名);
13
- // 2. 从 code-server 运行位置出发校验这些模块是否真的能 require 到。
13
+ // 2. 从 code-server 运行位置出发校验这些模块是否真的能 require 到;
14
+ // 3. 必要时在 code-server 树里补齐别名 junction(ESM import 不认 NODE_PATH,只能靠目录链)。
14
15
  import { createRequire } from 'node:module';
15
- import { existsSync, readFileSync } from 'node:fs';
16
+ import { existsSync, readFileSync, mkdirSync, symlinkSync } from 'node:fs';
16
17
  import { dirname, join } from 'node:path';
17
18
  import { PACKAGE_ROOT, codeServerRoot, profileRootOf } from './vendor.js';
18
19
 
@@ -114,3 +115,116 @@ export function verifyNatives(modules) {
114
115
  }
115
116
  return { resolved, missing };
116
117
  }
118
+
119
+ /** 某个模块能否**只靠 code-server 运行根**(含其祖先 node_modules)解析。 */
120
+ function resolvesFromRoot(root, name) {
121
+ try {
122
+ const from = createRequire(join(root, 'package.json'));
123
+ for (const spec of [`${name}/package.json`, name]) {
124
+ try {
125
+ from.resolve(spec);
126
+ return true;
127
+ } catch { /* 试下一个 */ }
128
+ }
129
+ } catch { /* 忽略 */ }
130
+ return false;
131
+ }
132
+
133
+ /** 确保聚合包带回的别名模块能被 **code-server 树**解析。
134
+ *
135
+ * 为什么必须做:pnpm 会把带 `os`/`cpu` 限定的包**嵌套装在聚合包自己的 node_modules 下**
136
+ * (如 `<profile>/node_modules/@<scope>/dsh-code-server-runtime-win32-arm64/node_modules/@vscode/windows-registry`),
137
+ * 而 VS Code 的 `lib/vscode/out/server-main.js` 用 **ESM `import`** 加载这些包 —— ESM 不认
138
+ * `NODE_PATH`(那是 CJS 的兜底),只认目录链。所以这里在 `<codeServerRoot>/node_modules` 下
139
+ * 为每个「从树里解析不到」的别名补一个 junction,指向聚合包内的真实目录。
140
+ * 幂等、可重复调用;插件重装后由下次激活/启动自愈。
141
+ * @returns {{created:string[], failed:string[]}} */
142
+ export function ensureAliasLinks() {
143
+ const runtime = resolveRuntime();
144
+ const csRoot = codeServerRoot();
145
+ if (runtime === null || csRoot === null) return { created: [], failed: [] };
146
+ const linkRoot = join(csRoot, 'node_modules');
147
+ const created = [];
148
+ const failed = [];
149
+ for (const alias of runtime.modules) {
150
+ if (resolvesFromRoot(csRoot, alias)) continue; // 目录链已能看到(profile 根或树内),无需补
151
+ const target = resolveNativeDir(alias);
152
+ if (target === null) continue; // 该平台包没装上 → 交给 envCheck 报缺
153
+ const link = join(linkRoot, alias);
154
+ try {
155
+ if (existsSync(link)) continue;
156
+ mkdirSync(dirname(link), { recursive: true });
157
+ symlinkSync(target, link, process.platform === 'win32' ? 'junction' : 'dir');
158
+ created.push(alias);
159
+ } catch (error) {
160
+ failed.push(`${alias}: ${error && error.message ? error.message : String(error)}`);
161
+ }
162
+ }
163
+ return { created, failed };
164
+ }
165
+
166
+ /** 从**插件依赖图**解析(插件 node_modules → <profile>/node_modules),即包管理器装出来的真实包目录。
167
+ * 与 `resolveNativeDir` 的区别:不走 code-server 树(树里可能有别的同名版本,例如 code-server 自带的
168
+ * typescript 5.9.3,而 VS Code 要的是 inner deps 里那份 6.0.3)。 */
169
+ function resolveFromPlugin(name) {
170
+ try {
171
+ const from = createRequire(join(PACKAGE_ROOT, 'package.json'));
172
+ for (const spec of [`${name}/package.json`, name]) {
173
+ try {
174
+ return dirname(from.resolve(spec));
175
+ } catch { /* 试下一个 */ }
176
+ }
177
+ } catch { /* 忽略 */ }
178
+ return null;
179
+ }
180
+
181
+ /** 把 VS Code 的「内部依赖目录」用 junction 补回老布局。
182
+ *
183
+ * 为什么需要:老模型里 `lib/vscode/node_modules` 与 `lib/vscode/extensions/node_modules` 是 npm 在树里
184
+ * 装出来的**真实目录**;新模型把同一批依赖拍平装在 `<profile>/node_modules`,靠模块解析往上层找没问题,
185
+ * 但**用显式路径拼依赖的代码会失效** —— 例如内置 TypeScript 扩展(1.136.1 实测):
186
+ * `path.join(extensionPath, '..', 'node_modules', 'typescript', 'lib', 'tsserver.js')`
187
+ * 找不到就弹 "VS Code's tsserver was deleted by another application …"。
188
+ * 这里按两个 package.json 的 dependencies 逐个补 junction(指向插件依赖图里的真实包),幂等、可自愈。
189
+ * @returns {{created:string[], failed:string[]}} */
190
+ export function ensureInnerModuleLinks() {
191
+ const csRoot = codeServerRoot();
192
+ if (csRoot === null) return { created: [], failed: [] };
193
+ const vscode = join(csRoot, 'lib', 'vscode');
194
+ const targets = [
195
+ { manifest: join(vscode, 'package.json'), dir: join(vscode, 'node_modules') },
196
+ { manifest: join(vscode, 'extensions', 'package.json'), dir: join(vscode, 'extensions', 'node_modules') },
197
+ ];
198
+ const created = [];
199
+ const failed = [];
200
+ for (const { manifest, dir } of targets) {
201
+ let deps;
202
+ try {
203
+ deps = JSON.parse(readFileSync(manifest, 'utf8')).dependencies ?? {};
204
+ } catch { continue; }
205
+ for (const name of Object.keys(deps)) {
206
+ const link = join(dir, name);
207
+ if (existsSync(join(link, 'package.json'))) continue; // 已在位(真实目录或链接)
208
+ const target = resolveFromPlugin(name);
209
+ if (target === null) continue; // 该依赖没装(envCheck 会另行报告)
210
+ try {
211
+ mkdirSync(dirname(link), { recursive: true });
212
+ symlinkSync(target, link, process.platform === 'win32' ? 'junction' : 'dir');
213
+ created.push(name);
214
+ } catch (error) {
215
+ failed.push(`${name}: ${error && error.message ? error.message : String(error)}`);
216
+ }
217
+ }
218
+ }
219
+ return { created, failed };
220
+ }
221
+
222
+ /** 一次性补齐两类链接:VS Code 内部依赖目录 + 聚合包别名。 */
223
+ export function ensureRuntimeLayout() {
224
+ const inner = ensureInnerModuleLinks();
225
+ const aliases = ensureAliasLinks();
226
+ return {
227
+ created: [...inner.created, ...aliases.created],
228
+ failed: [...inner.failed, ...aliases.failed],
229
+ };
230
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-code-server-app",
3
- "version": "0.1.40",
3
+ "version": "0.1.42",
4
4
  "description": "Integrate code-server (VS Code in the browser) into DSH Web and Desktop: right-sidebar tab (DSH >= 0.1.5-alpha.1) with a floating-ball fallback for older hosts, over the Connection /api channel (ctx.connection.fetch; no webServer dependency) with host-side process lifecycle.",
5
5
  "homepage": "https://github.com/jinsiyu/dsh-code-server-app",
6
6
  "repository": {
@@ -106,6 +106,8 @@
106
106
  "vendor:check": "node scripts/vendor-code-server.mjs --check",
107
107
  "repack:build": "node scripts/vendor-repacks.mjs",
108
108
  "publish:repacks": "node scripts/publish-repacks.mjs",
109
+ "publish:plugin": "node scripts/publish-plugin.mjs",
110
+ "promote": "node scripts/promote.mjs",
109
111
  "build:client": "node scripts/build-client.mjs"
110
112
  }
111
113
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "codeServerVersion": "4.136.2",
3
- "preparedAt": "2026-09-10T06:32:05.257Z",
3
+ "preparedAt": "2026-09-10T07:11:10.362Z",
4
4
  "source": "registry",
5
5
  "node": "v24.13.1",
6
6
  "platform": "win32",