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.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-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.
13
+ A static profile plugin (npm package with host + client bundle) that ships the **VS Code server tree** from a [code-server](https://github.com/coder/code-server) release as a **platform-independent dependency package** (pack-time artifact `vendor/vscode` → `@jinsiyu/dshcs-vscode-server`, no install scripts, no postinstall). The code-server **Node service layer is replaced by the plugin's own `lib/launcher.mjs`**: it drives `<tree>/lib/vscode/out/server-main.js` (`loadCodeWithNls()` / `createServer()` / `handleRequest()` / `handleUpgrade()`) directly and re-adds the few HTTP endpoints code-server used to provide (`/healthz`, `/manifest.json`, `/_static/*`, `/proxy/:port`). The 16 native modules (node-pty / @vscode/sqlite3 / spdlog / …) 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, **no argon2/C++ toolchain**.
14
14
 
15
15
  ## UI carrier (chosen by the DSH version, feature-detected at runtime)
16
16
 
@@ -25,7 +25,21 @@ A static profile plugin (npm package with host + client bundle) that ships [code
25
25
  - In sidebar mode the settings card hides "Reserve space above the composer" (floating-window geometry only). "Open in a window (new tab)" still applies to every entry point.
26
26
  - `windowedOpen` has the highest priority: when on, entry buttons always open a browser tab.
27
27
 
28
- ## Floating ball / window (legacy-DSH fallback path only)
28
+ ## Serving mode (`serve`)
29
+
30
+ | Mode | What it does | Requires |
31
+ |---|---|---|
32
+ | **`loopback` (default)** | the plugin listens on its own loopback port (`host:port`) and the sidebar iframe connects cross-origin; the process can be adopted after a DSH host restart | nothing |
33
+ | **`dsh`** | the IDE is mounted on **DSH's own HTTP port** at `/code-server/*` (HTTP prefix route) plus `/code-server/<quality>-<commit>` (exact WebSocket route), forwarded to the launcher's **named pipe**; **no extra port**; every request (including the WS handshake) first passes `ctx.connection.requestRejection()` — the same Host/Origin fence and browser-cookie authentication as `/api` | DSH providing `webServer` (web profile); desktop falls back to loopback automatically |
34
+
35
+ - Switch it in `config.serve` in `cordis.patch.yml` or in Settings → Plugins → Code Server (takes effect on the next start).
36
+ - Benefits of `dsh`: a single URL/port (remote access to DSH gives you the IDE), no extra loopback listener, authentication on par with DSH.
37
+ - Two **known trade-offs** of `dsh`: the iframe shares DSH's origin, so `sandbox` is dropped there (same-origin plus
38
+ `allow-same-origin` is escapable by the frame itself; in `loopback` mode the iframe is cross-origin and `sandbox` stays
39
+ as real protection — clipboard is still granted via `allow="clipboard-read; clipboard-write"`); and forwarded-port
40
+ **WebSockets** cannot be routed because `registerUpgrade` matches exact paths while `/proxy/:port` carries the port in
41
+ the path (HTTP forwarding works; use `loopback` when you need WS forwarding).
42
+
29
43
 
30
44
  - **Floating ball** (bottom-right, official code-server icon, above the composer): click to **expand the floating window and light it up** (blue glow), click again to **collapse**; **drag to any position** (remembered across refreshes; no accidental click after drag);
31
45
  no sidebar button, no window control button group (the ball is the only entry/toggle); the ball carries a status dot (green = running / amber = starting / red = error);
@@ -46,20 +60,21 @@ A static profile plugin (npm package with host + client bundle) that ships [code
46
60
  crash/exit updates status live; after a DSH host restart the plugin **adopts** a still-running instance (verifies pid + `/healthz`), without duplicate start or killing unrelated processes;
47
61
  - `node_modules` and the pack-time artifact `vendor/` are git-ignored; after cloning, follow
48
62
  "Install the plugin (script-free install; code-server bundled)" below — `pnpm install` → `pnpm run build:client` →
49
- `pnpm run vendor:code-server` → `pnpm pack` + `dsh plugin --profile web add`.
63
+ `pnpm run vendor:vscode` → `pnpm pack` + `dsh plugin --profile web add`.
50
64
 
51
65
  > Verified locally (BM: Windows 11 ARM64): `code-server@4.136.2` (with Code 1.136.1) bundled in the plugin,
52
66
  > placed offline at activation → VS Code internal deps installed → started → healthz 200 →
53
67
  > cwd switch restart while running → stopped → fully recycled.
54
68
 
69
+ ## Floating ball / window (legacy-DSH fallback path only)
55
70
  ## Packaging (how to build the tarball)
56
71
 
57
72
  ```powershell
58
73
  cd C:\Users\User\Desktop\dsh-code-server-app
59
74
  pnpm install # dev deps (esbuild + motion); allowBuilds is explicit → no postinstall runs
60
75
  pnpm run build:client # src/factory.js → lib/client.js (not committed; must be built first)
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 (the upstream tree)
76
+ pnpm run vendor:check # optional: show the bundled tree version vs the latest code-server release
77
+ pnpm run vendor:vscode # ① produce vendor/vscode (the trimmed VS Code tree, ~197MB)
63
78
  pnpm run repack:build -- --target win32-arm64,win32-x64 --pack # ② one script builds every sub-package
64
79
  pnpm run publish:repacks # ③ publish every @jinsiyu/* sub-package (default dist-tag: next)
65
80
  pnpm pack # ④ → dsh-code-server-app-<version>.tgz (~107KB)
@@ -81,18 +96,17 @@ pnpm run promote -- <version>
81
96
 
82
97
  | Sub-package | Content | os/cpu |
83
98
  |---|---|---|
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> |
99
+ | `@jinsiyu/dshcs-vscode-server@<code-server version>` | the trimmed VS Code tree (`lib/vscode` + `out/browser` + `src/browser`; **without** code-server's `out/node` and its 136 runtime deps) | platform-independent |
86
100
  | `@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> |
101
+ | `@jinsiyu/dsh-code-server-runtime-win32-<arch>` | platform aggregator: its `dependencies` map those 16 natives back to their original names via `npm:` aliases | win32-<arch> |
88
102
 
89
103
  | Goal | Command |
90
104
  |---|---|
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 |
92
- | **Pin a version** | `pnpm run vendor:code-server -- --version 4.136.2` |
93
- | **Snapshot from an existing tree** | `pnpm run vendor:code-server -- --from <code-server dir>` (seconds) |
105
+ | **Build from the latest upstream release** | `pnpm run vendor:latest` (= `--force`): pulls `code-server@latest`'s tree into `vendor/vscode`; afterwards you **must** re-run `repack:build` and republish every sub-package |
106
+ | **Pin a version** | `pnpm run vendor:vscode -- --version 4.136.2` |
107
+ | **Snapshot from an existing tree** | `pnpm run vendor:vscode -- --from <code-server dir>` (seconds) |
94
108
  | **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) |
109
+ | **Rebuild only the tree/aggregator packages** | `node scripts/vendor-repacks.mjs --reuse --target win32-arm64,win32-x64 --pack` (reuses the natives already in `repack/build`) |
96
110
  | **Publish sub-packages** | `pnpm run publish:repacks` (`--dry-run` to preview; `--only <substr>` to filter; `--otp <code>` / `--limit N` for 2FA) |
97
111
  | **Publish the plugin itself** | `pnpm run publish:plugin` (publishes the exact tarball that was verified; no re-packing; default dist-tag `next`) |
98
112
  | **Promote `latest`** | `pnpm run promote -- <version>` (only after the user restarted and confirmed; `--dry-run` shows the current tags first) |
@@ -107,90 +121,73 @@ pnpm run promote -- <version>
107
121
 
108
122
  ```powershell
109
123
  # no postinstall in the package → no pnpm approve-builds / allowBuilds; one command installs everything
110
- dsh plugin --profile web add dsh-code-server-app@0.1.40
124
+ dsh plugin --profile web add dsh-code-server-app@0.2.0
111
125
  # a local tarball works the same way:
112
- dsh plugin --profile web add C:\Users\User\Desktop\dsh-code-server-app\dsh-code-server-app-0.1.40.tgz
126
+ dsh plugin --profile web add C:\Users\User\Desktop\dsh-code-server-app\dsh-code-server-app-0.2.0.tgz
113
127
  ```
114
128
 
115
129
  Ready to use immediately — **no second step, no "Install environment", no install-guide modal**.
116
- Since 0.1.40 the main package is only **~107KB** (the plugin's own code); everything else is dependencies:
130
+ The main package is only **~110KB** (the plugin's own code plus the launcher); everything else is dependencies:
117
131
 
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`;
132
+ - **the VS Code tree** (`lib/vscode` 196.9MB + `out/browser` + `src/browser`) is a **platform-independent package**
133
+ `@jinsiyu/dshcs-vscode-server@<code-server version>` declared in the plugin's `dependencies`; it runs from
134
+ `<profile>\node_modules\@jinsiyu\dshcs-vscode-server\vscode` (the legacy full tree at
135
+ `@jinsiyu/dshcs-code-server/code-server` is still recognised as a fallback);
121
136
  - the **pure-JS part** of VS Code's inner dependencies (35 packages: xterm / katex / typescript / ws / tar …) is
122
137
  declared in the plugin's `dependencies` and installed by pnpm into the profile's `node_modules` (hoisted);
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**
138
+ - the **binary part** comes entirely from `@jinsiyu/dshcs-*` platform packages: 16 native packages mapped back to their
139
+ **original names** (`node-pty` / `@vscode/sqlite3` / `@vscode/spdlog` / …) by the **platform aggregator**
126
140
  `@jinsiyu/dsh-code-server-runtime-win32-<arch>` using `npm:` aliases; the aggregators sit in the plugin's
127
141
  `optionalDependencies`, so pnpm auto-selects the right platform;
128
142
  - consequently the dependency graph contains **no package with pre/install/postinstall or a `binding.gyp`** →
129
143
  no profile `allowBuilds`, no build script ever runs, and **the user machine needs no C++ toolchain**;
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).
144
+ - **upgrading the plugin no longer re-downloads the tree**: the tree package is cached by version
145
+ (~60MB, ~197MB unpacked).
132
146
 
133
147
  ### Install mechanism (why it is built this way)
134
148
 
135
149
  - **The pnpm 11 hard constraint**: any package in the dependency graph whose manifest has
136
- `preinstall|install|postinstall` (or whose tarball contains `binding.gyp`/`.hooks`) is treated as
137
- "requires build" and must be approved through the **host profile's** `pnpm-workspace.yaml` (`allowBuilds`),
138
- otherwise `dsh plugin add` exits 1 with `[ERR_PNPM_IGNORED_BUILDS]`. A dependency's own `pnpm.allowBuilds`,
139
- `.npmrc`, the `patch:` protocol and `optionalDependencies` are all ineffective (measured 2026-09, pnpm 11.25);
140
- - **the code-server tree** is prepared at pack time with `npm install code-server@<version> --ignore-scripts`
141
- (skips the official `sh ./postinstall.sh` there is no `sh` on Windows and the script only accepts npm/yarn
142
- user agents, so it always fails under pnpm) supply the argon2 native binary (no Windows prebuild exists;
143
- compile with `node-gyp-build`, or reuse an existing `argon2.node` via `DSHCS_ARGON2_BINARY`) strip leftover
144
- install scripts snapshot to `vendor/code-server/`;
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-*`:
154
- copy the already-compiled package directory **delete `scripts` / `files` / `binding.gyp` / `.hooks` /
155
- `.npmignore`** (keeping the compiled `.node` and every runtime file) rewrite dependencies that belong to the
156
- same set to `npm:` aliases platform-specific ones get an `os`/`cpu` pair and a `-<platform>-<arch>` suffix;
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;
161
- - **resolution path**: the host resolves the runtime root with
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.
180
-
181
- > **Upgrading from ≤ 0.1.35**: the old install root `<profile>\.code-server-app` (with ~1.4GB of inner
182
- > dependencies) and the "Install environment" step are gone. The new version detects the old root and logs that it
183
- > can be safely deleted: `Remove-Item -Recurse -Force <profile>\.code-server-app`. Old
184
- > `dsh-code-server-app: false` entries in the profile's `pnpm-workspace.yaml` can be removed too (no build
185
- > approval is needed any more).
186
-
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);
190
- > if an old install root is still around, delete `<profile>\.code-server-app` manually.
191
-
192
- > After install/dependency changes, **restart `dsh web`** (the static plugin row and host probe paths load at startup).
193
-
150
+ `preinstall|install|postinstall` (or that ships a `binding.gyp`/`.hooks`) counts as "needs building" and must be
151
+ approved by the **host profile's** `pnpm-workspace.yaml` via `allowBuilds`, otherwise `dsh plugin add` exits 1 with
152
+ `[ERR_PNPM_IGNORED_BUILDS]`. A dependency's own `pnpm.allowBuilds`, `.npmrc`, `patch:` protocol and
153
+ `optionalDependencies` do not help (measured 2026-09, pnpm 11.25);
154
+ - **the tree** is prepared at pack time with `npm install code-server@<version> --ignore-scripts` (skipping the official
155
+ `sh ./postinstall.sh`, which cannot run on Windows), then `scripts/vendor-vscode-server.mjs` keeps **only the VS Code
156
+ tree**: `lib/vscode/**`, `out/browser/**`, `src/browser/**` plus the license files are copied to `vendor/vscode/`, and a
157
+ generated root `package.json` records the upstream code-server version. code-server's own `out/node/**` and its 136
158
+ runtime dependencies **no longer ship** — they are replaced by `lib/launcher.mjs`;
159
+ - **the packages that need a toolchain** are repacked into `@jinsiyu/dshcs-*` by `scripts/vendor-repacks.mjs`:
160
+ the compiled package directory is copied and its `scripts` / `files` / `binding.gyp` / `.hooks` / `.npmignore` are
161
+ **removed** (the built `.node` and every runtime file stay) sibling packages in its dependency list become `npm:`
162
+ aliases platform-specific ones get `os`/`cpu` plus a `-<platform>-<arch>` suffix. For win32 targets the script also
163
+ verifies each `.node` PE machine (0x8664=x64 / 0xaa64=arm64) so a cross-compiled artifact cannot ship the wrong arch;
164
+ - **the platform aggregator** maps those repacks back to their original names (e.g.
165
+ `"node-pty": "npm:@jinsiyu/dshcs-node-pty@1.2.0-beta.15"`), so VS Code's `import('node-pty')` needs no change; the
166
+ aggregator is itself `os`/`cpu` gated, and the plugin declares both win32-arm64 and win32-x64 in
167
+ `optionalDependencies`, so one command picks the right one;
168
+ - **resolution path**: the host finds the tree with `require.resolve('@jinsiyu/dshcs-vscode-server/package.json')`
169
+ (then the inner `vscode/` directory) and the entry is `vscode/lib/vscode/out/server-main.js`; VS Code's inner deps are
170
+ resolved upwards from that root (`vscode/lib/vscode/node_modules`package `node_modules` `<profile>/node_modules`).
171
+ The legacy full tree (`@jinsiyu/dshcs-code-server/code-server`) is still recognised as a fallback;
172
+ - **runtime layout self-healing** (`ensureRuntimeLayout()` in `lib/native.js`, idempotent, run **at activation before
173
+ `envCheck` and again before every start**): the host adds two kinds of **junctions** (Windows junctions / POSIX dir
174
+ symlinks) into the tree:
175
+ 1. `ensureAliasLinks()`: re-links the native aliases the aggregator carries into `<tree>/node_modules` — pnpm nests
176
+ `os`/`cpu`-gated packages under the aggregator's own `node_modules`, and `lib/vscode/out/server-main.js` uses
177
+ **ESM imports** (ESM ignores `NODE_PATH`), so a missing link means an immediate 500;
178
+ 2. `ensureInnerModuleLinks()`: restores VS Code's **inner dependency directories**
179
+ `lib/vscode/node_modules` and `lib/vscode/extensions/node_modules` from the two `package.json` files the trimmed
180
+ tree ships neither, and code that builds dependency paths explicitly (e.g. the bundled TypeScript extension looking
181
+ for `<ext>/../node_modules/typescript/lib/tsserver.js`) otherwise reports
182
+ "VS Code's tsserver was deleted by another application…" (measured with 1.136.1).
183
+ > **Size note**: the plugin tarball is **~110KB**; `@jinsiyu/dshcs-vscode-server` is **~60MB** (~197MB unpacked);
184
+ > the 16 native packages add ~250MB. A full install downloads roughly 310MB. Neither `vendor/` nor `repack/` is committed to git (see `.gitignore`).
185
+
186
+ > **Upgrading from 0.1.43**: the tree package changed from `@jinsiyu/dshcs-code-server` (the full code-server tree with
187
+ > `out/node` and 136 runtime deps) to `@jinsiyu/dshcs-vscode-server` (the trimmed tree). **The new code defaults to
188
+ > `serve: loopback`, which behaves exactly like 0.1.43**; switch to `serve: dsh` for same-origin mounting. The install
189
+ > command is unchanged (`dsh plugin --profile web add dsh-code-server-app@<version>`), and pnpm drops the old
190
+ > `dshcs-code-server` sub-package.
194
191
  ### Development: install from source (changes take effect immediately)
195
192
 
196
193
  ```powershell
@@ -198,7 +195,7 @@ dsh plugin --profile web add C:\Users\User\Desktop\dsh-code-server-app
198
195
  ```
199
196
 
200
197
  > A source path installs via `link:`. On a dev machine without `vendor/code-server`, run
201
- > `pnpm run vendor:code-server` first. Dependencies (inner JS deps + the platform aggregator) are installed by pnpm
198
+ > `pnpm run vendor:vscode -- --dev-links` first. Dependencies (inner JS deps + the platform aggregator) are installed by pnpm
202
199
  > too — but the not-yet-published local `@jinsiyu/*` packages must either be published first, or the
203
200
  > `repack/tgz/*.tgz` files must be installed into the profile as `file:` dependencies.
204
201
  >
@@ -214,7 +211,7 @@ dsh plugin --profile web add C:\Users\User\Desktop\dsh-code-server-app
214
211
  |---|---|---|---|
215
212
  | Node.js | **v24.x** (latest code-server requirement; v24.13.1 here) | required | required |
216
213
  | npm / pnpm | npm ships with Node; pnpm comes from DSH | required (installs deps) | required |
217
- | **MSVC build tools** | **VS Community 2026 + C++ desktop workload** | ❌ **not needed** | pack time (16 native packages + argon2) |
214
+ | **MSVC build tools** | **VS Community 2026 + C++ desktop workload** | ❌ **not needed** | pack time (16 native packages) |
218
215
  | **VS Spectre-mitigated libs** | one set for ARM64 **and** one for x86/x64 ("MSVC v14x Spectre-mitigated libs") | ❌ not needed | pack time (otherwise MSB8040) |
219
216
  | Python | **3.13.x** | ❌ not needed | pack time (node-gyp) |
220
217
  | node-gyp | **13.x** (older versions don't recognize VS 2026) | ❌ not needed | pack time |
@@ -235,30 +232,30 @@ dsh plugin --profile web add C:\Users\User\Desktop\dsh-code-server-app
235
232
  - If you don't need the self-contained install (e.g. a global code-server already exists), skip it:
236
233
  the plugin falls back to a configured/PATH `bin` (see the "Config" table).
237
234
 
238
- ### Upgrading the code-server version
235
+ ### Upgrading the VS Code tree (upstream = a code-server release)
239
236
 
240
- - **The version is decided at pack time**: `pnpm run vendor:latest` (= `--force`) rebuilds with the npm
241
- **latest** version; or use `pnpm run vendor:code-server -- --version 4.136.2` / `DSHCS_CODE_SERVER_VERSION`.
242
- With an existing `vendor/code-server`, a plain `pnpm pack` never upgrades (it is a no-op).
243
- - **Check first**: `pnpm run vendor:check` prints the bundled version / npm latest.
237
+ - **The version is decided at pack time**: `pnpm run vendor:latest` (= `--force`) pulls the tree of the npm **latest**
238
+ release; or use `pnpm run vendor:vscode -- --version 4.136.2` / `DSHCS_CODE_SERVER_VERSION`.
239
+ With an existing `vendor/vscode`, a plain `pnpm pack` never upgrades (it is a no-op).
240
+ - **Check first**: `pnpm run vendor:check` prints the bundled version / upstream latest.
244
241
  - **A version bump means rebuilding and republishing the sub-packages** (all with the same script):
245
242
  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.
243
+ (`@jinsiyu/dshcs-vscode-server@<new version>`) and the natives rebuilt against the new inner dependencies (the
244
+ script also rewrites the plugin's pure-JS `dependencies` and both aggregator versions);
245
+ 2. `pnpm run republish:repacks` (`pnpm run publish:repacks`) → publish; then bump the plugin version → `pnpm pack`
246
+ → publish the plugin.
247
+ - `productPath` (`<quality>-<commit>`, part of the client WebSocket path) is **computed from `lib/vscode/product.json`**,
248
+ so upgrading the tree needs no code change — but the routes are registered at activation, so restart `dsh web` afterwards.
250
249
  - **No runtime auto-upgrade anymore**: nothing fetches latest at startup; the version is fully determined by the bundled artifact.
251
- - Bundled locally right now: `code-server@4.136.2` (with Code 1.136.1).
250
+ - Bundled locally right now: the tree of `code-server@4.136.2` (VS Code 1.136.1, `productPath=stable-8d5f383f…`).
252
251
 
253
252
  ### Compatibility with the old install locations
254
253
 
255
- Host probe order: `@jinsiyu/dshcs-code-server/code-server` (**the real layout since 0.1.40**) >
254
+ Host probe order: `@jinsiyu/dshcs-vscode-server/vscode` (**the real layout since 0.2.0**) >
255
+ `@jinsiyu/dshcs-code-server/code-server` (the full tree, 0.1.40–0.1.43) >
256
256
  `@jinsiyu/dshcs-code-server-<platform>-<arch>/code-server` (the 0.1.37 platform sub-packages) >
257
- the in-package `vendor/code-server` (0.1.36 and earlier / development) > the old install root
258
- `<profile>\.code-server-app\node_modules\code-server` (0.1.35 and earlier) > plugin-internal
259
- `node_modules/code-server` (development) > PATH/config `bin`. The old root is only mentioned in a startup log
260
- line; nothing writes to it any more.
261
-
257
+ the in-package `vendor/vscode` > the in-package `vendor/code-server` (development). The old install root
258
+ `<profile>\.code-server-app` is only mentioned in a startup log line; nothing writes to it any more.
262
259
  ## Settings card (Settings → Plugins → Code Server)
263
260
 
264
261
  Modeled after dsh-auto-open-web's custom card, registered on the `settings.plugin.item` slot,
@@ -274,7 +271,7 @@ persisted via the official settings domain (`settingsScope`, namespace `code-ser
274
271
  > so the host re-registers the settings namespace (schema includes the new key); otherwise save/validation of the new key won't work.
275
272
 
276
273
  The bottom of the card is **Environment check** (click "Check environment" to read the host `status.env`): entry,
277
- `native` (argon2), VS Code inner dependencies, and **prebuilt native packages** (platform aggregator name +
274
+ the tree version / `productPath` / server entry, VS Code inner dependencies, and **prebuilt native packages** (platform aggregator name +
278
275
  resolved module count). Since 0.1.36 there is no "Install environment" button — dependencies are installed by the
279
276
  package manager, and the card only reports the result.
280
277
 
@@ -339,9 +336,19 @@ so users cannot remove it from the extensions panel.
339
336
 
340
337
  ## Known limitations
341
338
 
342
- - **No sub-path**: the code-server front-end uses root paths/WebSocket/Service Worker, so it must be a direct iframe on its own port;
343
- no DSH webServer reverse proxy; `--base-path` is not officially supported.
344
- - **Single instance across sessions**: one shared code-server per host; switching cwd requires a restart (the sidebar tab / floating window handles it and hints).
345
- - **Sidebar tab switching reloads**: DSH's right sidebar renders only the active tab's body, so switching away and back remounts the iframe (a full code-server reload); keep the tab active or float it for long-running sessions.
346
- - **Remote access**: default is loopback + no auth. Cross-machine access requires `host` + `auth: password` + `passwordToken`,
347
- and the browser must be able to reach that host directly (the plugin's "open in new tab" builds the URL from `host:port`).
339
+ - ~~No sub-path~~ **no longer true (corrected with measurements in 0.2.0)**: the workbench HTML VS Code renders references
340
+ **only relative URLs** (9 references measured, 0 absolute; `serverBasePath="."`, `rootEndpoint="."`), and the client
341
+ builds its WebSocket path from `location.pathname + join(serverBasePath ?? '/', <quality>-<commit>)`. The IDE can
342
+ therefore be mounted directly under DSH's own `/code-server/*` (`serve: dsh`) no second port, no HTML rewriting.
343
+ Item-by-item evidence: `docs/analysis-code-server-as-dsh-plugin.md`.
344
+ - **`serve: dsh` cannot proxy forwarded-port WebSockets**: `registerUpgrade` matches exact paths while `/proxy/:port`
345
+ carries the port in the path, so WebSocket forwarding for the Ports panel is unavailable in that mode (HTTP forwarding
346
+ works). Use `serve: loopback` when you need it.
347
+ - **`serve: dsh` shares DSH's origin**, so the iframe is not sandboxed there (same-origin plus `allow-same-origin` is
348
+ escapable by the frame itself); in `loopback` mode the iframe is cross-origin and `sandbox` stays as real protection.
349
+ - **Single instance across sessions**: one shared IDE per host; switching cwd requires a restart (the sidebar tab /
350
+ floating window handles it and hints).
351
+ - **Sidebar tab switching reloads**: DSH's right sidebar renders only the active tab's body, so switching away and back
352
+ remounts the iframe (a full VS Code reload); keep the tab active or float it for long-running sessions.
353
+ - **Remote access**: with `serve: dsh` the browser only needs to reach DSH itself (one port, protected exactly like `/api`);
354
+ `serve: loopback` stays loopback-only with `auth: none`, and 0.2.0 no longer supports `auth: password`.