dsh-code-server-app 0.2.10 → 0.2.12

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
@@ -43,7 +43,7 @@ A static profile plugin (npm package with host + client bundle) that ships the *
43
43
  the narrow-viewport handling). When the button is missing it keeps the current mode and logs one `console.warn` — panel
44
44
  rendering is never affected.
45
45
  - **Resident IDE (0.2.2, on by default)**: switching to another tab or collapsing the sidebar and coming back **no longer reloads** code-server — unsaved editor buffers, terminals and debug sessions all stay put (see "Why switching tabs no longer reloads" below).
46
- - The settings card has exactly **three settings**: "**Claim scope**", "**Fullscreen on open**" and "Resident in background" — no other rows (0.2.7 removed the "Entry", "dependency install" and "environment check" rows).
46
+ - The settings card has exactly **three settings**: "**Claim types**", "**Fullscreen on open**" and "Resident in background" — no other rows (0.2.7 removed the "Entry", "dependency install" and "environment check" rows).
47
47
  Open the IDE from the **Code Server box** on the sidebar's guide page, or by clicking DSH's own produced-file chips / delivered-file previews / inline file names;
48
48
  diagnostics stay out of the UI — the `[code-server]` lines in the DSH host log are the place to look (`/api/code-server/status` still returns `env` for scripts).
49
49
  The old `windowedOpen` (open in a window) and `reserveComposer` were **removed in 0.2.6**: leftover keys in an old settings document neither fail nor apply (they are no longer part of the schema).
@@ -68,12 +68,25 @@ This plugin registers:
68
68
  |---|---|---|
69
69
  | `patterns` | `['dsh-resource://file/**']` | claims file addresses (a pattern containing `:` is matched against the **whole address**) |
70
70
  | `priority` | `'extension'` | beats the built-in plain-text preview, which sits in `fallback` on purpose — DSH's own comment calls that band "the position VS Code's text editor holds among its editors", i.e. one any more specific type should beat |
71
- | `canOpen` | see below | vetoes by the "claim scope" setting; unclaimed addresses fall back to DSH's built-in preview |
71
+ | `canOpen` | see below | vetoes by the "claim types" setting; unclaimed addresses fall back to DSH's built-in preview |
72
72
  | `title` | last address segment (= file name) | the tab chip shows the file name; a page tab (`sidebar://code-server`) still reads `Code Server` |
73
73
 
74
- - **Claim scope** (switchable in the settings card, `fileOpenScope`):
75
- - `session` (default) claim only `dsh-resource://file/session/…` (everything a session produces: deliverables, declared deliveries, prose mentions, tool views);
76
- - `all` also claim session-less `dsh-resource://file/absolute/…` addresses.
74
+ - **Claim types** (a text box in the settings card, `claimExtensions`, since 0.2.11):
75
+ **scope is no longer a thing** `dsh-resource://file/session/…` and `…/file/absolute/…` are treated alike,
76
+ and only the extension decides. Text-box grammar (semicolon-separated; `,`/whitespace/newlines also work;
77
+ `py`, `.py` and `*.py` are equivalent; case-insensitive):
78
+ - `*` — claim every other type too (catch-all);
79
+ - `py` — claim `.py`;
80
+ - `!md` — do **not** claim `.md` (**exclusion wins** over both an explicit claim and `*`);
81
+ - **default** `*;!md;!markdown;!html;!htm;!png;!jpg;!jpeg;!gif;!webp;!bmp;!ico;!svg;!pdf`
82
+ — the four categories DSH's own preview renders well (markdown / html / images / PDF) stay with it, everything
83
+ else (code, json/yaml, txt, logs, extension-less files such as `Makefile`, unknown extensions) goes to the IDE;
84
+ an empty box claims no files at all (page tabs only).
85
+ - Three practical shapes: a plain whitelist (`py;ts`, no `*` → nothing else is claimed), catch-all (`*`),
86
+ and catch-all plus exclusions (the default).
87
+ - Grammar, default and parsing all live in `lib/claim-types.js` (the host's `Config` default and the client's
88
+ `canOpen` share that single file, shipped in the package, so the two cannot drift apart);
89
+ unit tests: `scripts/test-claim-types.mjs`.
77
90
  - **How the tab body locates the file**: it parses `useTabInfo().tab.navigation.address`
78
91
  (`src/address.js`, same grammar as DSH's `parseFileAddress`), expands a workspace-relative path with that
79
92
  session's cwd, and posts the absolute path (plus optional `line`) to the host's
@@ -169,7 +182,7 @@ state preserved (no full reload). Full evidence and probe scripts: `docs/analysi
169
182
 
170
183
  ## code-server workspace and process lifecycle
171
184
 
172
- - code-server's workspace **follows the active DSH session/workspace**: switching sessions/workspaces while the IDE is open restarts code-server to the new directory
185
+ - code-server's workspace **follows the active DSH session/workspace**: switching sessions/workspaces while the IDE is open moves code-server to the new directory
173
186
  (resolution order: current session cwd → session's workspace.path → recentWorkspace.path → first workspace.path);
174
187
  the opened directory is shown inside code-server (`?folder=<cwd>`, the page reloads when following a switch);
175
188
  implementation note: the iframe `src` must carry `?folder=<cwd>` — code-server's front-end remembers the "last workspace" and restores it by itself;
@@ -177,6 +190,19 @@ state preserved (no full reload). Full evidence and probe scripts: `docs/analysi
177
190
  **Windows path format (verified)**: the `folder` parameter must start with `/` and use forward slashes only, e.g. `/C:/Users/User/Desktop/biss`;
178
191
  a bare Windows path (`C:\...`) is parsed as a URI scheme and the drive letter is stripped (page shows `\Users\User\...` with an empty file tree),
179
192
  while `file:///C:/...` reports "Workspace does not exist".
193
+ - **The switch is lightweight (since 0.2.12)**: a running instance is **not restarted** when the workspace changes — the host
194
+ only updates `state.cwd` and the workbench re-navigates with the new `?folder=` (the workspace directory was always the
195
+ client URL's business; the process cwd only affects the server's own relative-path resolution at spawn time). The switch is
196
+ much faster and no longer throws away the extension host, background tasks or server-side state.
197
+ - In `status`, `cwd` is the current workbench directory; `launchCwd` is the directory the **process was started with**
198
+ (diagnostics only; it does not change on a switch).
199
+ - The trade-off, stated plainly: background processes/terminals started by the IDE in the **old** directory are no longer
200
+ killed automatically (a full restart used to take them with it) — clean them up yourself if needed. That is the same coin
201
+ as "nothing is lost".
202
+ - The trigger does not depend on the tab being visible: **the tab body is not unmounted while the sidebar is collapsed**,
203
+ so it also follows in the background (behaviour deliberately kept in 0.2.12).
204
+ - Regression: `scripts/test-workspace-switch.mjs` (5 assertions: adopting an instance, cwd change keeps pid/status, the
205
+ process stays alive, same-directory idempotence, no-cwd does not switch; it fails again if the old behaviour returns).
180
206
  - Process lifecycle is managed by the host plugin: startup writes `$DSH_HOME/code-server/pid.json`, stop kills the tree (`taskkill /T` or process-group SIGKILL),
181
207
  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;
182
208
  - `node_modules` and the pack-time artifact `vendor/` are git-ignored; after cloning, follow
@@ -383,7 +409,7 @@ persisted via the official settings domain (`settingsScope`, namespace `code-ser
383
409
 
384
410
  | Key | Default | Description |
385
411
  |---|---|---|
386
- | `fileOpenScope` | `session` | **Claim scope** (0.2.5): `session` claims only session-scoped file addresses (`dsh-resource://file/session/…` DSH's produced files, declared deliveries, prose mentions); `all` also claims session-less `…/file/absolute/…`. Unclaimed addresses fall back to DSH's built-in preview |
412
+ | `claimExtensions` | `*;!md;!markdown;!html;!htm;!png;!jpg;!jpeg;!gif;!webp;!bmp;!ico;!svg;!pdf` | **Claim types** (0.2.11, replaces 0.2.5's `fileOpenScope`): decides by extension which files go to VS Code, semicolon-separated; `*` claims every other type, `!ext` excludes (exclusion wins). The default leaves the four categories DSH's preview renders well (markdown/html/images/PDF) to DSH and sends everything else to the IDE; an empty value claims nothing. **Scope (session vs absolute) is no longer distinguished** |
387
413
  | `fullscreenOnOpen` | `true` | **Fullscreen on open** (0.2.9): opening the Code Server tab (including clicking a file) switches the right sidebar to fullscreen (fills the window); off keeps DSH's default push mode (side by side with the conversation). Only the moment of opening is affected — a manual "Exit fullscreen" is never fought back |
388
414
  | `keepResident` | `true` | **Resident in background**: on, the host preloads the IDE into a parked surface right after start — switching tabs or collapsing the sidebar never reloads it and the first open needs no cold start; off loads it only when the panel is opened (saves memory) |
389
415
 
@@ -391,7 +417,7 @@ persisted via the official settings domain (`settingsScope`, namespace `code-ser
391
417
  settings document neither fail nor apply. `serve` remains a key in the settings namespace (usable from a settings document) but
392
418
  has **no card row** — see "Serving mode".)
393
419
 
394
- > Card changes take effect immediately via `scope.watch` (the host status API returns `keepResident`, `fileOpenScope` and
420
+ > Card changes take effect immediately via `scope.watch` (the host status API returns `keepResident`, `claimExtensions` and
395
421
  > `fullscreenOnOpen`; the client applies them at once); no dsh restart needed. **After adding new setting keys, restart dsh web before first use**,
396
422
  > so the host re-registers the settings namespace (schema includes the new key); otherwise save/validation of the new key won't work.
397
423
 
@@ -434,7 +460,7 @@ Host/Origin fence and browser auth); in the desktop profile `apps/desktop-host`
434
460
  | Method | Path | Description |
435
461
  |---|---|---|
436
462
  | GET | `/api/code-server/status` | `{ ok, running, status, host, port, pid, cwd, url, version, error, logTail, adopted }` (also `env` environment check and the `setup` compatibility field) |
437
- | POST | `/api/code-server/start` | body `{ cwd? }` (omit cwd to keep the current workspace); idempotent |
463
+ | POST | `/api/code-server/start` | body `{ cwd? }` (omit cwd to keep the current workspace); idempotent; changing cwd while running only **switches the directory, without restarting the process** (0.2.12) |
438
464
  | POST | `/api/code-server/stop` | Stop and recycle the process tree |
439
465
  | POST | `/api/code-server/setup` | **Compatibility no-op**: since 0.1.36 dependencies are installed by the package manager, so this only re-runs the env self-check and returns |
440
466
  | POST | `/api/code-server/open-file` | body `{ file }` — writes the signal consumed by the built-in `dshcs-open-file` extension to open the file in code-server |
@@ -482,12 +508,12 @@ Host/Origin fence and browser auth); in the desktop profile `apps/desktop-host`
482
508
  - **Desktop client bundles are cached by Electron; restarting the app does not guarantee a new one** (measured 2026-09, hit while shipping 0.2.5):
483
509
  - symptom: `lib/client.js` in the profile is the new version, yet the renderer keeps running the old code —
484
510
  `%APPDATA%\@deepseek-ai\dsh-desktop\Code Cache\js` only contains strings unique to the old version (e.g. `dshcs-artifacts`)
485
- and none unique to the new one (`fileOpenScope`), and `Cache\` still holds an old response body referencing
511
+ and none unique to the new one (`claimExtensions` / `fullscreenOnOpen`), and `Cache\` still holds an old response body referencing
486
512
  `dsh-code-server-app`. The same applies to first-party plugins (the cached `ui-deliverables` even lacks the current
487
513
  `data-presented-files-row` marker);
488
514
  - diagnosis (byte level — do **not** use `Select-String`, which reads files with the console encoding and gives false
489
515
  negatives on non-ASCII markers): search `Code Cache\js` for an **ASCII** marker unique to the new version
490
- (ours is `fileOpenScope`); a hit proves the new bundle really was compiled;
516
+ (since 0.2.11 ours is `claimExtensions`); a hit proves the new bundle really was compiled;
491
517
  - fix: fully close the app, delete the `Cache`, `Code Cache` and `GPUCache` directories, then start it (cache only —
492
518
  profiles, sessions and settings are untouched):
493
519
  ```powershell
@@ -520,8 +546,7 @@ What remains on the plugin side:
520
546
  works). Use `serve: loopback` when you need it.
521
547
  - **`serve: dsh` shares DSH's origin**, so the iframe is not sandboxed there (same-origin plus `allow-same-origin` is
522
548
  escapable by the frame itself); in `loopback` mode the iframe is cross-origin and `sandbox` stays as real protection.
523
- - **Single instance across sessions**: one shared IDE per host; switching cwd requires a restart (the sidebar tab
524
- handles it and hints).
549
+ - **Single instance across sessions**: one shared IDE per host; switching cwd only re-navigates the workbench (since 0.2.12 no process restart, so the old directory's background terminals are not collected).
525
550
  - **Older DSH versions are unsupported (since 0.2.3)**: on a DSH without `sidebarRightTabs` / `sidebarRight` the plugin
526
551
  offers nothing but an upgrade notice on the settings page; older-DSH users should stay on `0.2.2`
527
552
  (`dsh plugin --profile web add dsh-code-server-app@0.2.2`).
package/README.md CHANGED
@@ -57,7 +57,7 @@
57
57
  含窄视口下的连带处理)。按钮找不到时保持原模式并 `console.warn` 一条,绝不影响面板渲染。
58
58
  - **IDE 常驻(0.2.2 起,默认开)**:切到别的标签/收起侧栏再回来**不再重载** code-server——
59
59
  未保存的编辑缓冲区、终端、调试会话都留在原处(见下方「为什么切标签不再重载」)。
60
- - 设置卡片只有**三个设置**:「**认领范围**」「**打开即全屏**」与「**后台常驻(切标签不重载)**」——没有其它行(0.2.7 起移除「入口」「依赖安装」「环境检测」)。
60
+ - 设置卡片只有**三个设置**:「**认领类型**」「**打开即全屏**」与「**后台常驻(切标签不重载)**」——没有其它行(0.2.7 起移除「入口」「依赖安装」「环境检测」)。
61
61
  打开 IDE 用右侧栏「开始」页的 **Code Server 入口框**,或直接点官方的产物 chip / 交付卡片 / 正文文件名;
62
62
  诊断看 DSH host 日志里的 `[code-server]` 输出(`/api/code-server/status` 仍返回 `env` 供脚本排查)。
63
63
  旧版的 `windowedOpen`(窗口化打开)、`reserveComposer` 已在 0.2.6 移除:旧设置文档里残留的这两个键不会报错,只是被忽略(不再出现在 schema 里)。
@@ -82,12 +82,21 @@ DSH 用**资源地址**命名文件,`openFile` 只负责把地址交给右侧栏
82
82
  |---|---|---|
83
83
  | `patterns` | `['dsh-resource://file/**']` | 认领文件地址(含 `:` 的 pattern 按**整址** glob 匹配) |
84
84
  | `priority` | `'extension'` | 高于官方纯文本预览的 `fallback`——DSH 源码注释写明后者是"VS Code 文本编辑器在编辑器中的位次,任何更具体的类型都应当击败它" |
85
- | `canOpen` | 见下 | 按「认领范围」设置否决,未认领的地址由官方预览兜底 |
85
+ | `canOpen` | 见下 | 按「认领类型」设置否决,未认领的地址由官方预览兜底 |
86
86
  | `title` | 地址末段(=文件名) | tab chip 显示文件名;页面 tab(`sidebar://code-server`)仍是 `Code Server` |
87
87
 
88
- - **认领范围**(设置卡片可切,`fileOpenScope`):
89
- - `session`(默认)= 只认领 `dsh-resource://file/session/…`(会话里的产物、交付、正文提及、工具视图都走这条);
90
- - `all` = 连不带会话的 `dsh-resource://file/absolute/…` 也认领("所有文件"模式)
88
+ - **认领类型**(设置卡片里的文本框,`claimExtensions`,0.2.11 起):
89
+ **不再区分作用域** —— `dsh-resource://file/session/…` 与 `…/file/absolute/…` 一视同仁,只看扩展名。
90
+ 文本框语法(分号分隔,`,`/空白/换行也认;写 `py`、`.py`、`*.py` 等价;大小写不敏感):
91
+ - `*` = 其余类型也认领(兜底);
92
+ - `py` = 认领 `.py`;
93
+ - `!md` = 不认领 `.md`(**排除优先**于认领与 `*`);
94
+ - **默认** `*;!md;!markdown;!html;!htm;!png;!jpg;!jpeg;!gif;!webp;!bmp;!ico;!svg;!pdf`
95
+ = DSH 自带预览渲染得好的四类(markdown / html / 图片 / PDF)留给它,其余(代码、json/yaml、txt、日志、
96
+ 无扩展名如 `Makefile`、未知扩展名)都进 IDE;清空文本框 = 不认领任何文件(只保留页面 tab)。
97
+ - 三种实际形态:纯白名单(`py;ts`,无 `*` → 其余不认领)、兜底(`*`)、兜底加排除(默认)。
98
+ - 语法、默认值与解析都在 `lib/claim-types.js`(host 的 `Config` 默认值与客户端 `canOpen` 共用同一份,
99
+ 随包发布,不会两边漂移);单测 `scripts/test-claim-types.mjs`。
91
100
  - **tab body 怎么定位文件**:从 `useTabInfo().tab.navigation.address` 解析出会话与路径
92
101
  (`src/address.js`,与 DSH `parseFileAddress` 同语义),相对路径按该会话 cwd 展开成绝对路径,
93
102
  再把绝对路径 + 可选 `line` 交给 host 的 `/api/code-server/open-file`;内建扩展
@@ -140,7 +149,7 @@ DSH 用**资源地址**命名文件,`openFile` 只负责把地址交给右侧栏
140
149
  | **`loopback`(默认)** | 插件自己起一个回环端口(`host:port`),右侧栏 iframe 跨源直连;进程可被 adopt(DSH host 重启后接管) | 无 |
141
150
  | **`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 |
142
151
 
143
- - 在 `cordis.patch.yml` 的 `config.serve`(或设置文档里的 `code-server.serve`)切换,下次启动生效 —— **设置卡片不提供这一行**(卡片只有认领范围/打开即全屏/后台常驻三个设置)。
152
+ - 在 `cordis.patch.yml` 的 `config.serve`(或设置文档里的 `code-server.serve`)切换,下次启动生效 —— **设置卡片不提供这一行**(卡片只有认领类型/打开即全屏/后台常驻三个设置)。
144
153
  - `dsh` 模式的实际收益:单一 URL/单一端口(远程访问 DSH 即可用 IDE)、不再暴露额外回环端口、认证与 DSH 同级。
145
154
  - `dsh` 模式的两点**已知取舍**:
146
155
  1. iframe 与 DSH **同源** → 该模式下不再挂 `sandbox`(同源 + `allow-same-origin` 可被 frame 自行摘除,属"看起来有防护");
@@ -173,7 +182,7 @@ DSH 用**资源地址**命名文件,`openFile` 只负责把地址交给右侧栏
173
182
 
174
183
  ## code-server 服务目录与进程生命周期
175
184
 
176
- - code-server 服务目录**跟随活动工作区/会话**:打开期间切换 DSH 会话/工作区,code-server 自动重启到新目录
185
+ - code-server 服务目录**跟随活动工作区/会话**:打开期间切换 DSH 会话/工作区,code-server 自动切到新目录
177
186
  (解析优先级:当前会话 cwd → 会话所属 workspace.path → recentWorkspace.path → 首个 workspace.path);
178
187
  打开目录显示在 code-server 页面内(`?folder=<cwd>`,跟随切换时页面自动重新加载);
179
188
  实现要点:iframe src 必须带 `?folder=<cwd>`——code-server 前端会记住“最近工作区”并自行恢复,
@@ -181,6 +190,15 @@ DSH 用**资源地址**命名文件,`openFile` 只负责把地址交给右侧栏
181
190
  **Windows 路径格式(实测)**:folder 参数必须以 `/` 开头且全部正斜杠,形如 `/C:/Users/User/Desktop/biss`;
182
191
  裸 Windows 路径(`C:\...`)会被前端当 URI scheme 而剥掉盘符(页面显示 `\Users\User\...` 且文件树为空),
183
192
  `file:///C:/...` 形式则报 “Workspace does not exist”。
193
+ - **切换是"轻量"的(0.2.12 起)**:运行中切工作区**不重启 IDE 进程**,host 只把 `state.cwd` 改成新目录,
194
+ 由 workbench 拿新的 `?folder=` 重新导航(工作区目录本来就由客户端 URL 决定,进程 cwd 只影响它自己
195
+ spawn 时的相对路径解析)。因此切换**不再丢**扩展宿主/后台任务/服务端状态,也快得多。
196
+ - `status` 里 `cwd` = 当前 workbench 目录;`launchCwd` = **进程启动时**的目录(诊断用,不随切换变化)。
197
+ - 代价(要说清楚):旧目录里**由 IDE 拉起的后台进程/终端不再被自动杀掉**(以前靠"整进程重启"顺带收走)——
198
+ 需要时手动收;这也是"不丢状态"的同一枚硬币。
199
+ - 触发时机与本标签是否可见无关:**侧栏收起时标签 body 并不卸载**,所以后台也会跟随(0.2.12 明确保留此行为)。
200
+ - 回归:`scripts/test-workspace-switch.mjs`(5 项:接管实例、切目录不改 pid/不换状态、进程存活、
201
+ 同目录幂等、无 cwd 不切换;改回旧行为必挂)。
184
202
  - process 生命周期由 host 插件管理:启动写 `$DSH_HOME/code-server/pid.json`,停止树级终止(taskkill /T 或进程组 SIGKILL),
185
203
  崩溃/退出实时更新状态;DSH host 重启后自动 adopt 仍在运行的实例(校验 pid + /healthz),不重复启动、不误杀别的进程;
186
204
  - `node_modules`、`vendor/` 与 `repack/` 已被 `.gitignore` 排除,推送/克隆仓库后按下方
@@ -393,7 +411,7 @@ host 探测顺序:`@jinsiyu/dshcs-vscode-server/vscode`(**0.2.0+ 正式布局**)
393
411
 
394
412
  | 键 | 默认 | 说明 |
395
413
  |---|---|---|
396
- | `fileOpenScope` | `session` | **认领范围**(0.2.5):`session` = 只认领会话作用域的文件地址(`dsh-resource://file/session/…`,即官方产物/交付/正文提及);`all` = 连无会话的绝对路径(`…/file/absolute/…`)也认领。未认领的地址由 DSH 自带预览兜底 |
414
+ | `claimExtensions` | `*;!md;!markdown;!html;!htm;!png;!jpg;!jpeg;!gif;!webp;!bmp;!ico;!svg;!pdf` | **认领类型**(0.2.11,取代 0.2.5 的 `fileOpenScope`):按扩展名决定哪些文件交给 VS Code,分号分隔;`*` = 其余类型也认领,`!ext` = 不认领(排除优先)。默认把 DSH 预览渲染得好的四类(markdown/html/图片/PDF)留给它,其余全进 IDE;清空 = 不认领任何文件。**不再区分 session/absolute 作用域** |
397
415
  | `fullscreenOnOpen` | `true` | **打开即全屏**(0.2.9):打开 Code Server 标签(含点开文件)时自动把右侧栏切到全屏(铺满窗口);关闭则保持 DSH 默认的 push(与对话并排)。只影响打开那一刻,用户点「退出全屏」不会被抢回去 |
398
416
  | `keepResident` | `true` | **后台常驻**:开启后宿主启动即把 IDE 预加载到"停放区",切标签/收起侧栏不重载、首次打开免等待;关闭则只在打开面板时加载(省内存) |
399
417
 
@@ -404,7 +422,7 @@ host 探测顺序:`@jinsiyu/dshcs-vscode-server/vscode`(**0.2.0+ 正式布局**)
404
422
  诊断信息不再进 UI —— `/api/code-server/status` 的 `env` 字段仍返回
405
423
  树版本 / `productPath` / server 入口、VS Code 内部依赖、**预编译原生包**(平台聚合包名 + 已解析模块数),需要时用脚本查或看 host 日志。
406
424
 
407
- > 卡片改动经 `scope.watch` 实时生效(host 端 status API 同步返回 `keepResident`、`fileOpenScope` 与
425
+ > 卡片改动经 `scope.watch` 实时生效(host 端 status API 同步返回 `keepResident`、`claimExtensions` 与
408
426
  > `fullscreenOnOpen`,客户端立即生效);无需重启 dsh。**新增设置键后首次使用前需重启 dsh web**,
409
427
  > 让 host 重新注册设置命名空间(schema 含新键),否则新键的保存与校验不生效。
410
428
 
@@ -440,8 +458,8 @@ desktop profile 由 `apps/desktop-host` 把 `/api/*` 交给同一个 `createShar
440
458
 
441
459
  | 方法 | 路径 | 说明 |
442
460
  |---|---|---|
443
- | GET | `/api/code-server/status` | `{ ok, running, status, host, port, pid, cwd, url, version, error, logTail, adopted }`(另含 `env` 环境检测与 `setup` 兼容字段) |
444
- | POST | `/api/code-server/start` | body `{ cwd? }`(省略 cwd 不切换工作目录);幂等 |
461
+ | GET | `/api/code-server/status` | `{ ok, running, status, host, port, pid, cwd, launchCwd, url, version, error, logTail, adopted }`(另含 `env` 环境检测与 `setup` 兼容字段;`cwd` = 当前 workbench 目录,`launchCwd` = 进程启动目录) |
462
+ | POST | `/api/code-server/start` | body `{ cwd? }`(省略 cwd 不切换工作目录);幂等;运行中切 cwd = **只换目录不重启进程**(0.2.12) |
445
463
  | POST | `/api/code-server/stop` | 停止并回收进程树 |
446
464
  | POST | `/api/code-server/setup` | **兼容空操作**:0.1.36 起依赖由包管理器安装,调用只重新自检 `env` 并返回 |
447
465
  | POST | `/api/code-server/open-file` | body `{ file }` — 写信号文件,由内置扩展 `dshcs-open-file` 在 code-server 中打开 |
@@ -483,11 +501,11 @@ desktop profile 由 `apps/desktop-host` 把 `/api/*` 交给同一个 `createShar
483
501
  因此每次新版本在桌面端都会受这条策略约束。
484
502
  - **桌面端的客户端 bundle 会被 Electron 缓存,重启应用不保证换新**(2026-09 实测,0.2.5 踩到):
485
503
  - 现象:profile 里 `lib/client.js` 已是新版本,但渲染器仍跑旧代码——`%APPDATA%\@deepseek-ai\dsh-desktop\Code Cache\js`
486
- 里只有旧版本独有的字符串(如 `dshcs-artifacts`),新版本独有的字符串(如 `fileOpenScope`)一个都没有;
504
+ 里只有旧版本独有的字符串(如 `dshcs-artifacts`),新版本独有的字符串(如 `claimExtensions` / `fullscreenOnOpen`)一个都没有;
487
505
  `Cache\` 里也存着一份引用 `dsh-code-server-app` 的旧响应体。官方插件同理(缓存里那份 `ui-deliverables`
488
506
  连当前的 `data-presented-files-row` 都没有)。
489
507
  - 诊断手法(字节级,注意别用按控制台编码读文件的 `Select-String`,中文标记会假阴性):
490
- 在 `Code Cache\js` 里搜本版本独有的**ASCII** 标记(我们用 `fileOpenScope`),命中即说明新 bundle 真的被编译过。
508
+ 在 `Code Cache\js` 里搜本版本独有的**ASCII** 标记(0.2.11 起用 `claimExtensions`),命中即说明新 bundle 真的被编译过。
491
509
  - 修法:完全关闭应用后删 `Cache`、`Code Cache`、`GPUCache` 三个目录再启动(只清缓存,不动 profile/会话/设置):
492
510
  ```powershell
493
511
  Remove-Item -Recurse -Force "$env:APPDATA\@deepseek-ai\dsh-desktop\Cache","$env:APPDATA\@deepseek-ai\dsh-desktop\Code Cache","$env:APPDATA\@deepseek-ai\dsh-desktop\GPUCache"
@@ -505,7 +523,7 @@ desktop profile 由 `apps/desktop-host` 把 `/api/*` 交给同一个 `createShar
505
523
  → 该模式下 Ports 面板的 **WebSocket** 转发不可用(HTTP 转发正常);需要时用 `serve: loopback`。
506
524
  - **`serve: dsh` 的 iframe 与 DSH 同源** → 该模式不挂 `sandbox`(同源 + `allow-same-origin` 可被 frame 自行摘除);
507
525
  `loopback` 模式跨源,`sandbox` 作为真防护保留。
508
- - **跨会话单实例**:host 级共享一份 IDE;切换 cwd 需重启实例(右侧栏标签自动处理并提示)。
526
+ - **跨会话单实例**:host 级共享一份 IDE;切换 cwd 只换 workbench 目录(0.2.12 起不重启进程,旧目录的后台终端不会被收走)。
509
527
  - **旧版 DSH 不受支持(0.2.3 起)**:没有 `sidebarRightTabs`/`sidebarRight` 的 DSH 上,除设置页一条升级提示外无任何入口;
510
528
  旧版用户请留在 `0.2.2`(`dsh plugin --profile web add dsh-code-server-app@0.2.2`)。
511
529
  - **侧栏标签切换**(0.2.2 起不再重载):DSH 右侧栏只渲染当前激活标签的 body,React 卸载会移走 iframe;
@@ -0,0 +1,132 @@
1
+ /**
2
+ * dsh-code-server — 认领类型策略(0.2.11)
3
+ *
4
+ * 决定"哪些文件地址由本插件认领"(即交给 VS Code 打开),**只按文件类型判断,不再区分作用域**:
5
+ * `dsh-resource://file/session/…` 与 `…/file/absolute/…` 一视同仁,未认领的落回 DSH 自带预览
6
+ * (`ui-sidebar-documentpreview`,优先级 fallback),它内部按扩展名分派 markdown / html / 图片 / PDF /
7
+ * 代码高亮 / 纯文本。
8
+ *
9
+ * 文本语法(用户可在设置卡里改,分号分隔,`,`/空白/换行也认):
10
+ * * 其余类型也认领(兜底)
11
+ * py 认领 .py(写 `py`、`.py`、`*.py` 等价;大小写不敏感)
12
+ * !md 不认领 .md(排除优先于认领)
13
+ * 空文本 = 不认领任何文件类型(只保留页面 tab,文件点击全部落回 DSH 预览)。
14
+ *
15
+ * 本模块是 host(`lib/index.js` 的 Config 默认值)与 client(`src/factory.js` 的 canOpen)的
16
+ * **同一份** 事实来源,随 npm 包一起发布(见 package.json 的 files),避免两边默认值漂移。
17
+ * 纯字符串逻辑,不碰文件系统 → 可离线单测(scripts/test-claim-types.mjs)。
18
+ */
19
+
20
+ /**
21
+ * 默认策略:**DSH 自带预览渲染得好的类型留给它**(markdown / html / 图片 / PDF 四类),
22
+ * 其余(代码、json/yaml/toml、txt、日志、无扩展名、其它未知扩展名)全部进 IDE。
23
+ * 未认领的类型没有"没渲染器"的风险(DSH 预览对任何扩展名都有兜底),反之未知扩展名进 IDE 更实用。
24
+ */
25
+ export const DEFAULT_CLAIM_EXTENSIONS = '*;!md;!markdown;!html;!htm;!png;!jpg;!jpeg;!gif;!webp;!bmp;!ico;!svg;!pdf'
26
+
27
+ /** 分隔符:分号为主,逗号/空白/换行也接受(用户手抄时不该因为标点被坑)。 */
28
+ const SEPARATORS = /[;,\s]+/
29
+
30
+ /** 切词:`!` 可以和后面的扩展名隔着空白写(`! .md` ≡ `!.md`),其余按分隔符切。 */
31
+ function tokenize(text) {
32
+ return String(text).replace(/!\s+/g, '!').split(SEPARATORS)
33
+ }
34
+
35
+ /** 单个 token 归一化:去 `*.`/`.` 前缀、去首尾空白、小写;`*`/`!x` 形式保留语义。 */
36
+ function normalizeToken(raw) {
37
+ var token = typeof raw === 'string' ? raw.trim() : ''
38
+ if (token === '') return ''
39
+ var deny = token.charAt(0) === '!'
40
+ var body = deny ? token.slice(1).trim() : token
41
+ if (body === '*') return deny ? '!*' : '*'
42
+ if (body.slice(0, 2) === '*.') body = body.slice(2)
43
+ else if (body.charAt(0) === '.') body = body.slice(1)
44
+ body = body.toLowerCase()
45
+ if (body === '') return ''
46
+ return deny ? '!' + body : body
47
+ }
48
+
49
+ /**
50
+ * 归一化成一串规范文本(保存进设置用):去空、去重、保持"先出现的先写"。
51
+ * @param text - 用户输入(任意标点)。
52
+ * @returns 规范文本;输入非字符串时返回 ''。
53
+ */
54
+ export function normalizeClaimExtensions(text) {
55
+ if (typeof text !== 'string') return ''
56
+ var parts = tokenize(text)
57
+ var seen = []
58
+ for (var i = 0; i < parts.length; i += 1) {
59
+ var token = normalizeToken(parts[i])
60
+ if (token === '' || token === '!*') continue // `!*` 无意义:排除"其余"等于清空,不猜意图,直接忽略
61
+ if (seen.indexOf(token) === -1) seen.push(token)
62
+ }
63
+ return seen.join(';')
64
+ }
65
+
66
+ /**
67
+ * 解析策略文本。
68
+ * @param text - 归一化前或后的文本都接受。
69
+ * @returns {{all: boolean, allow: string[], deny: string[]}} all = `*` 出现(其余类型也认领)。
70
+ */
71
+ export function parseClaimPolicy(text) {
72
+ var normalized = normalizeClaimExtensions(text)
73
+ var tokens = normalized === '' ? [] : normalized.split(';')
74
+ var all = false
75
+ var allow = []
76
+ var deny = []
77
+ for (var i = 0; i < tokens.length; i += 1) {
78
+ var token = tokens[i]
79
+ if (token === '*') { all = true; continue }
80
+ if (token.charAt(0) === '!') deny.push(token.slice(1))
81
+ else allow.push(token)
82
+ }
83
+ return { all: all, allow: allow, deny: deny }
84
+ }
85
+
86
+ /** 路径的扩展名(小写、不含点);无扩展名(含 dotfile、目录、空路径)返回 ''。 */
87
+ export function extensionOfPath(path) {
88
+ if (typeof path !== 'string' || path === '') return ''
89
+ var name = path.replace(/[/\\]+$/, '')
90
+ var at = Math.max(name.lastIndexOf('/'), name.lastIndexOf('\\'))
91
+ if (at !== -1) name = name.slice(at + 1)
92
+ var dot = name.lastIndexOf('.')
93
+ // dot <= 0:`Makefile` / `README`(无扩展名)、`.gitignore`(dotfile)都按"无扩展名"处理
94
+ if (dot <= 0) return ''
95
+ return name.slice(dot + 1).toLowerCase()
96
+ }
97
+
98
+ /**
99
+ * 是否认领这个路径。排除优先,其次显式认领,最后看 `*`。
100
+ * @param path - 地址里的路径(可为相对路径)。
101
+ * @param policy - parseClaimPolicy 的结果。
102
+ * @returns 认领返回 true。
103
+ */
104
+ export function claimsPath(path, policy) {
105
+ if (policy == null) return false
106
+ var ext = extensionOfPath(path)
107
+ if (ext !== '' && policy.deny.indexOf(ext) !== -1) return false
108
+ if (ext !== '' && policy.allow.indexOf(ext) !== -1) return true
109
+ return policy.all === true
110
+ }
111
+
112
+ /**
113
+ * 是否认领这个文件地址(供 tab 类型的 canOpen 用)。
114
+ * @param parsed - parseFileAddress 的结果(或 null)。
115
+ * @param policy - parseClaimPolicy 的结果。
116
+ * @returns 认领返回 true。
117
+ */
118
+ export function claimsAddress(parsed, policy) {
119
+ if (parsed === null || parsed == null) return false
120
+ return claimsPath(parsed.path, policy)
121
+ }
122
+
123
+ /** 给设置卡/日志用的一句话摘要(不参与判定)。 */
124
+ export function describeClaimPolicy(text) {
125
+ var policy = parseClaimPolicy(text)
126
+ var parts = []
127
+ if (policy.all) parts.push('其余类型全部认领')
128
+ if (policy.allow.length > 0) parts.push('指定认领 ' + policy.allow.length + ' 项')
129
+ if (policy.deny.length > 0) parts.push('排除 ' + policy.deny.length + ' 项')
130
+ if (parts.length === 0) return '不认领任何文件(只有页面标签)'
131
+ return parts.join(' · ')
132
+ }
package/lib/client.js CHANGED
@@ -1,5 +1,5 @@
1
1
  window.__ModuleLoader__.load({id:'dsh-code-server-app',factory:function(require){var module={exports:{}};var exports=module.exports;
2
- var P=Object.defineProperty;var be=Object.getOwnPropertyDescriptor;var he=Object.getOwnPropertyNames;var ge=Object.prototype.hasOwnProperty;var me=(e,r)=>{for(var n in r)P(e,n,{get:r[n],enumerable:!0})},ye=(e,r,n,s)=>{if(r&&typeof r=="object"||typeof r=="function")for(let l of he(r))!ge.call(e,l)&&l!==n&&P(e,l,{get:()=>r[l],enumerable:!(s=be(r,l))||s.enumerable});return e};var we=e=>ye(P({},"__esModule",{value:!0}),e);var sr={};me(sr,{apply:()=>nr,inject:()=>ar,name:()=>lr});module.exports=we(sr);var J="dsh-resource://file/",Se="sidebar://",X="session";function H(e){return typeof e=="string"&&e.startsWith(Se)}function D(e){if(typeof e!="string"||!e.startsWith(J))return null;for(var r=e.length,n=0;n<e.length;n+=1){var s=e.charAt(n);if(s==="?"||s==="#"){r=n;break}}var l=e.slice(J.length,r).split("/"),i=l.shift();try{if(i==="session"){var d=l.shift();return d===void 0||d===""||l.length===0?null:{scope:"session",sessionId:decodeURIComponent(d),path:V(l)}}if(i==="absolute"){var f=l[0]===""&&l.length>1,p=f?l.slice(1):l,c=V(p);return(c===""||c.charAt(0)==="/")&&!f?null:f?{scope:"absolute",path:"//"+c}:c===""?null:{scope:"absolute",path:q(c)?c:"/"+c}}}catch(u){return null}return null}function V(e){for(var r=[],n=0;n<e.length;n+=1)r.push(decodeURIComponent(e[n]));return r.join("/")}function q(e){return/^[A-Za-z]:($|\/)/.test(e)}function xe(e){return typeof e!="string"||e===""?!1:e.charAt(0)==="/"?!0:q(e)}function K(e){var r=D(e);if(r===null)return"";var n=r.path.replace(/[/\\]+$/,""),s=Math.max(n.lastIndexOf("/"),n.lastIndexOf("\\")),l=s===-1?n:n.slice(s+1);return l}function $(e,r){if(e===null||e==null)return null;var n=typeof e.path=="string"?e.path:"";if(n==="")return null;if(xe(n))return n;if(typeof r!="string"||r==="")return null;var s=r.indexOf("\\")!==-1?"\\":"/",l=r.replace(/[\\/]+$/,"");return l+s+(s==="\\"?n.replace(/\//g,"\\"):n)}function ee(e,r){return e===null||e==null?!1:e.scope==="session"?!0:r==="all"}var ke="[data-sidebar-right-panel]",Ee='[data-sidebar-right-mode="fullscreen"]';function re(e){if(e==null||typeof e.closest!="function")return"no-root";var r,n;try{if(r=e.closest(ke),r==null||typeof r.querySelector!="function")return"no-panel";n=r.querySelector(Ee)}catch(s){return"lookup-failed"}if(n==null||typeof n.click!="function")return"no-control";try{n.click()}catch(s){return"click-failed"}return"clicked"}var A=typeof Element!="undefined"&&typeof Element.prototype.moveBefore=="function",Oe=-2e4,t={park:null,frame:null,currentSrc:null,sameOrigin:null,owner:null,lastRect:null,parkStrategy:"offscreen",degraded:!1,preloaded:!1,nudgeCount:0,nudgeEnabled:!0,lastNudgeAt:0,listeners:new Set};function U(){return{ready:t.frame!==null,docked:t.owner!==null,owner:t.owner,src:t.currentSrc,sameOrigin:t.sameOrigin,parkStrategy:t.parkStrategy,degraded:t.degraded,preloaded:t.preloaded,supportsMoveBefore:A,nudgeCount:t.nudgeCount,lastNudgeAt:t.lastNudgeAt}}function R(){var e=U();t.listeners.forEach(function(r){try{r(e)}catch(n){}})}function ne(e){return t.listeners.add(e),function(){t.listeners.delete(e)}}function te(){return U()}function Ce(e){e!=="offscreen"&&e!=="behind"||t.parkStrategy!==e&&(t.parkStrategy=e,t.frame!==null&&t.owner===null&&_(),R())}function Ne(){return t.parkStrategy}function Le(){var e=t.lastRect;e!==null&&(t.park.style.width=Math.max(1,Math.round(e.width))+"px",t.park.style.height=Math.max(1,Math.round(e.height))+"px")}function _(){if(t.park!==null){if(Le(),t.parkStrategy==="behind"&&t.lastRect!==null){t.park.style.left=Math.round(t.lastRect.left)+"px",t.park.style.top=Math.round(t.lastRect.top)+"px",t.park.style.visibility="visible",t.park.style.zIndex="0";return}t.park.style.left=Oe+"px",t.park.style.top="0px",t.park.style.visibility="hidden",t.park.style.zIndex="0"}}function ae(){t.frame!==null&&(t.frame.setAttribute("inert",""),t.frame.setAttribute("aria-hidden","true"))}function Ae(){t.frame!==null&&(t.frame.removeAttribute("inert"),t.frame.removeAttribute("aria-hidden"))}function Re(){var e=document.createElement("div");e.className="dshcs-park",e.setAttribute("data-dshcs-park",""),e.setAttribute("aria-hidden","true");var r=document.createElement("iframe");return r.className="dshcs-frame",r.setAttribute("title","code-server"),r.setAttribute("allow","clipboard-read; clipboard-write"),r.setAttribute("data-dshcs-resident",""),r.src="about:blank",e.appendChild(r),document.body.appendChild(e),t.park=e,t.frame=r,t.currentSrc="about:blank",t.owner=null,_(),ae(),r}function Me(e){var r=t.frame;if(r!==null){var n=t.sameOrigin!==e;!n&&r.hasAttribute("data-dshcs-attrs")||(e===!0?r.removeAttribute("sandbox"):e===!1&&r.setAttribute("sandbox","allow-scripts allow-same-origin allow-forms allow-modals allow-popups allow-pointer-lock allow-clipboard-read allow-clipboard-write"),r.setAttribute("data-dshcs-attrs",e===!0?"same-origin":"cross-origin"),t.sameOrigin=e)}}function F(e){var r=e||{};return t.frame===null&&Re(),typeof r.sameOrigin=="boolean"&&Me(r.sameOrigin),typeof r.src=="string"&&r.src!==""&&r.src!==t.currentSrc&&Te(r.src),t.frame}function Te(e){t.frame===null||typeof e!="string"||e===""||e===t.currentSrc||(t.currentSrc=e,t.frame.src=e,R())}function le(){var e=t.frame;if(t.nudgeEnabled!==!0||e===null||e.isConnected!==!0)return!1;var r=e.style.display;return e.style.display="none",e.offsetHeight,e.style.display=r,t.nudgeCount+=1,t.lastNudgeAt=Date.now(),!0}function Ie(e){return t.nudgeEnabled=e!==!1,t.nudgeEnabled}function se(e){if(t.frame!==null){if(A)try{e.moveBefore(t.frame,null);return}catch(r){t.degraded=!0,t.lastMoveError=(r&&r.name?r.name+": ":"")+(r&&r.message?r.message:String(r))}else t.degraded=!0;e.appendChild(t.frame)}}function B(e,r){if(!(t.frame===null||e==null)){var n=t.owner===null,s=e.getBoundingClientRect();s.width>=1&&s.height>=1&&(t.lastRect={left:s.left,top:s.top,width:s.width,height:s.height}),t.owner=r===void 0?null:r,Ae(),t.park.setAttribute("aria-hidden","true"),se(e),n&&le(),R()}}function M(e){t.frame!==null&&(e!==void 0&&t.owner!==e||(t.owner=null,_(),ae(),t.park.setAttribute("aria-hidden","true"),se(t.park),R()))}function G(e){var r=e||{};return F(r),t.owner===null&&(typeof r.src=="string"&&r.src!==""&&(t.preloaded=!0),M()),t.frame}function De(){t.park!==null&&t.park.parentNode!==null&&t.park.parentNode.removeChild(t.park),t.park=null,t.frame=null,t.currentSrc=null,t.sameOrigin=null,t.owner=null,t.lastRect=null,t.degraded=!1,t.preloaded=!1,t.nudgeCount=0,t.lastNudgeAt=0,R()}typeof window!="undefined"&&(window.__dshcsSurface={snapshot:U,setParkStrategy:Ce,getParkStrategy:Ne,preload:G,dock:B,park:M,nudge:le,setNudgeEnabled:Ie,destroy:De});var a=require("react"),Y=new Set,T={status:null,busy:!1,sidebarUi:"unknown",sidebarRegisterFailed:!1};function E(e){T=Object.assign({},T,e),Y.forEach(function(r){r()})}function je(e){return Y.add(e),function(){Y.delete(e)}}function ze(){return T}function Z(){return a.useSyncExternalStore(je,ze)}var Pe="/api",He="data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiB2aWV3Qm94PSIwIDAgMTQ3IDE0NyIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KICA8c3R5bGU+QG1lZGlhIChwcmVmZXJzLWNvbG9yLXNjaGVtZTogZGFyaykgeyogeyBmaWxsOiB3aGl0ZTsgfX08L3N0eWxlPgogIDxwYXRoIGQ9Im00Mi40MjE0LDM5LjY1NWMtMjQuNDA1NywwIC00Mi4xNTU0LDEzLjE3MjEgLTQyLjE1NTQsMzMuODQ1YzAsMjAuNTgxNCAxOC40ODkyLDMzLjg0NSA0Mi4xNTU0LDMzLjg0NWMyMy42NjYyLDAgMzguMTgwMywtMTEuNjE3MSAzOC43MzQ5LC0yOC43MjI1bC0yMS4wNzc3LC0wLjQ1NzRjLTAuOTI0NCw5LjMzMDMgLTkuMTA1OSwxNS4xODQ1IC0xNy42NTcyLDE1LjE4NDVjLTExLjc0MDYsMCAtMjAuNDMwNiwtNy41OTIyIC0yMC40MzA2LC0xOS44NDk2YzAsLTEyLjI1NzQgOC42OSwtMTkuOTg2OCAyMC40MzA2LC0yMC4yMTU1YzguNTUxMywtMC4xODMgMTYuOTE3Nyw1Ljk0NTcgMTcuNDcyMywxNS4yNzZsMjEuMDc3NywtMC42NDAzYy0wLjQ2MjIsLTE2LjgzMTEgLTE0LjE0NDIsLTI4LjI2NTIgLTM4LjU1LC0yOC4yNjUyem00OC44NDQ2LDJsNTUuNDY4LDBsMCw2NC4wMzExbC01NS40NjgsMGwwLC02NC4wMzExeiIgY2xpcC1ydWxlPSJldmVub2RkIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiLz4KPC9zdmc+Cg==";async function k(e,r){var n={method:r===void 0?"GET":"POST",headers:{}};r!==void 0&&(n.headers["content-type"]="application/json",n.body=JSON.stringify(r));var s=await fetch(Pe+e,n),l=await s.text(),i=null;try{i=l===""?null:JSON.parse(l)}catch(d){i=null}return s.ok?i!==null?i:{ok:!1,error:"invalid JSON response"}:{ok:!1,error:"HTTP "+s.status+(i!==null&&i.error!==void 0?": "+i.error:"")}}function pe(e,r){try{var n=e(function(v){return v}),s=r===null?null:typeof r=="function"?r(function(v){return v}):null,l=n!=null?n.current:void 0;if(l!==void 0&&n!=null&&n.byId!=null){var i=n.byId[l];if(i!=null&&typeof i.cwd=="string"&&i.cwd!=="")return i.cwd}var d=s!=null&&Array.isArray(s.items)?s.items:[];if(l!==void 0)for(var f=0;f<d.length;f++){var p=d[f];if(p.sessionIds!=null&&p.sessionIds.indexOf(l)!==-1&&typeof p.path=="string"&&p.path!=="")return p.path}var c=s!=null?s.recentWorkspaceId:void 0;if(c!==void 0){for(var u=0;u<d.length;u++)if(d[u].workspaceId===c&&typeof d[u].path=="string"&&d[u].path!=="")return d[u].path}if(d.length>0&&typeof d[0].path=="string"&&d[0].path!=="")return d[0].path}catch(v){}}function ve(e,r){if(e==null||typeof e.url!="string"||e.url==="")return null;var n=e.pid!=null?String(e.pid):e.startedAt!=null?String(e.startedAt):"0",s=e.url+"?s="+encodeURIComponent(n),l=typeof r=="string"&&r!==""?r:e!=null&&e.cwd!=null?e.cwd:null;if(l==null||l==="")return s;var i=l.replace(/\\/g,"/"),d=i;return(/^[A-Za-z]:\//.test(i)||i.charCodeAt(0)!==47)&&(d="/"+i),s+"&folder="+encodeURIComponent(d)}function Ue(e){var r=e.status,n=e.pageUrl,s=e.reloadTick,l=e.owner,i=a.useRef(null),d=r!=null&&r.ok===!0&&r.running===!0,f=r!=null&&r.status==="starting",p=r!=null&&r.ok===!1,c=r!=null&&r.serve==="dsh";if(a.useLayoutEffect(function(){if(!d||n===null){M(l);return}F({src:n,sameOrigin:c}),i.current!==null&&B(i.current,l)},[d,n,c,s,l]),a.useLayoutEffect(function(){return function(){M(l)}},[l]),d&&n!==null)return a.createElement("div",{ref:i,className:"dshcs-slot","data-code-server-slot":l!=null?l:"code-server"});if(f)return a.createElement("div",{className:"dshcs-loading"},"\u6B63\u5728\u542F\u52A8 code-server\u2026");var u=p&&r!=null&&r.error?r.error:"code-server \u672A\u8FD0\u884C",v=c?"\u5F53\u524D\u4EE5 DSH \u540C\u6E90\u8DEF\u5F84 "+(r!=null&&r.url||"/code-server/")+" \u63D0\u4F9B(\u65E0\u72EC\u7ACB\u7AEF\u53E3)\u3002":"\u5F53\u524D\u4EE5\u72EC\u7ACB\u56DE\u73AF\u7AEF\u53E3\u63D0\u4F9B(\u7AEF\u53E3 "+(r!=null&&r.port!=null?r.port:"8090")+" \u88AB\u5360\u7528\u65F6\u8BF7\u91CA\u653E\u6216\u4FEE\u6539 port \u914D\u7F6E)\u3002",S=A?"\u5E38\u9A7B\u9762:\u53EF\u7528(\u5207\u6807\u7B7E/\u6536\u8D77\u4FA7\u680F\u4E0D\u91CD\u8F7D)\u3002":"\u5E38\u9A7B\u9762:\u5F53\u524D\u6D4F\u89C8\u5668\u4E0D\u652F\u6301 Element.moveBefore \u2014\u2014 \u5207\u6807\u7B7E\u4F1A\u6574\u9875\u91CD\u8F7D(\u5347\u7EA7\u6D4F\u89C8\u5668\u540E\u81EA\u52A8\u53EF\u7528)\u3002";return a.createElement("div",{className:"dshcs-empty"},a.createElement("div",{className:"dshcs-emptybox"},a.createElement("div",null,p?"code-server \u542F\u52A8\u5931\u8D25":"code-server \u672A\u8FD0\u884C"),a.createElement("pre",{className:"dshcs-error"},u),a.createElement("p",{className:"dshcs-hint"},"VS Code \u6811\u968F\u63D2\u4EF6\u5305\u5185\u7F6E\u3001\u5C31\u5730\u8FD0\u884C(\u65E0\u9700\u5168\u5C40\u5B89\u88C5\u3001\u65E0\u9700\u8054\u7F51\u5B89\u88C5\u3001\u65E0\u300C\u5B89\u88C5\u73AF\u5883\u300D\u6B65\u9AA4);\u5185\u90E8\u4F9D\u8D56\u4E0E\u9884\u7F16\u8BD1\u539F\u751F\u6A21\u5757\u7531\u5305\u7BA1\u7406\u5668\u5728\u5B89\u88C5\u63D2\u4EF6\u65F6\u4E00\u5E76\u88C5\u597D(\u65E0\u9700 C++ \u5DE5\u5177\u94FE)\u3002\u82E5\u6B64\u5904\u957F\u671F\u672A\u8FD0\u884C,\u8BF7\u67E5\u770B DSH host \u65E5\u5FD7\u91CC\u7684 [code-server] \u8F93\u51FA(\u6216\u5728\u8BBE\u7F6E\u5361\u7247\u91CC\u5207\u6362\u300C\u540E\u53F0\u5E38\u9A7B\u300D\u89E6\u53D1\u4E00\u6B21\u542F\u52A8)\u3002"+v+S)))}function _e(e){var r=Z(),n=r.status,s=n!=null&&n.ok===!0&&n.running===!0,l=n!=null&&n.keepResident===!0,i=pe(e&&e.useSessions,e&&e.useWorkspaces),d=s?ve(n,i):null;return a.useEffect(function(){!l||!s||d===null||G({src:d,sameOrigin:n!=null&&n.serve==="dsh"})},[l,s,d,n!=null?n.serve:null]),null}var Fe=".dshcs-frame{display:block;position:absolute;inset:0;z-index:1;width:100%;height:100%;border:0;background:var(--dsw-alias-bg-base,#fff)}.dshcs-tabroot{position:relative;display:flex;flex-direction:column;width:100%;height:100%;min-width:0;min-height:0;background:var(--dsw-alias-bg-base,#fff)}.dshcs-slot{position:relative;display:block;width:100%;height:100%;min-width:0;min-height:0;overflow:hidden;background:var(--dsw-alias-bg-base,#fff)}.dshcs-park{position:fixed;left:-20000px;top:0;width:320px;height:200px;overflow:hidden;pointer-events:none;z-index:0;visibility:hidden;contain:strict}.dshcs-loading{position:absolute;inset:0;z-index:2;display:grid;place-items:center;background:var(--dsw-alias-bg-base,#fff);color:var(--dsw-alias-label-tertiary,#7d8798);font-size:13px}.dshcs-empty{position:relative;z-index:2;flex:1;display:flex;align-items:center;justify-content:center;padding:44px 24px 24px}.dshcs-emptybox{max-width:560px;text-align:left;background:var(--dsw-alias-bg-layer-2,#f7f8fb);border:1px solid var(--dsw-alias-border-l2,#dfe3eb);border-radius:12px;padding:16px 18px}.dshcs-error{color:var(--dsw-alias-label-error,#d92d20);white-space:pre-wrap;word-break:break-all;font-family:ui-monospace,Consolas,monospace;font-size:12px;margin:8px 0 0}.dshcs-hint{color:var(--dsw-alias-label-tertiary,#7d8798);font-size:12px;margin:6px 0 0}.dshcs-legacy{color:var(--dsw-alias-label-warning,#b54708);font-size:12px;font-weight:600;margin:0 0 6px}",ie="dsh-code-server/styles";typeof document!="undefined"&&document.querySelector("style[data-dshcs="+JSON.stringify(ie)+"]")===null&&(j=document.createElement("style"),j.setAttribute("data-dshcs",ie),j.textContent=Fe,document.head.appendChild(j));var j,de="code-server",ce="dsh-code-server-app",Be=2500,Ge=1e4,Qe=1500;function We(e){var r=e!=null&&typeof e.size=="number"?e.size:16;return a.createElement("img",{src:He,alt:"","aria-hidden":!0,draggable:!1,className:e!=null?e.className:void 0,style:{width:r,height:r,display:"block",objectFit:"contain",WebkitUserDrag:"none",userSelect:"none"}})}function Ye(){var e=T.status;return e!=null&&e.fileOpenScope==="all"?"all":X}function Ze(e,r){try{var n=e(function(l){return l});if(n!=null&&r!=null&&n.byId!=null){var s=n.byId[r];if(s!=null&&typeof s.cwd=="string"&&s.cwd!=="")return s.cwd}}catch(l){}}function Je(e){var r=e.useTabInfo(),n=r.tab,s=Z(),l=s.status,i=n.navigation,d=i!=null&&typeof i.revision=="number"?i.revision:0,f=i!=null&&typeof i.address=="string"?i.address:"",p=H(f)?null:D(f),c=Ze(e.useSessions,p!=null?p.sessionId:void 0),u=c!==void 0?c:pe(e.useSessions,null),v=$(p,u),S=i!=null&&i.params!=null&&typeof i.params.line=="number"?i.params.line:null,o=a.useRef(void 0),[m,h]=a.useState(0),w=a.useRef(null),N=a.useRef(!1),I=r.tab!=null&&r.tab.visible===!0,O=r.sidebar!=null&&r.sidebar.fullscreen===!0,z=l!=null&&l.fullscreenOnOpen!==!1;return a.useLayoutEffect(function(){if(!I){N.current=!1;return}if(!(!z||O||N.current)){N.current=!0;var x=re(w.current);x!=="clicked"&&console.warn("[code-server] \u672A\u80FD\u81EA\u52A8\u5207\u5230\u5168\u5C4F\u53F3\u4FA7\u680F("+x+");\u672C\u6B21\u6253\u5F00\u4FDD\u6301\u539F\u6A21\u5F0F")}},[I,O,z]),a.useEffect(function(){if(!(typeof u!="string"||u==="")&&o.current!==u){var x=o.current!==void 0;o.current=u;var g=!1;return k("/code-server/start",{cwd:u}).then(function(C){g||(E({status:C}),x&&C!=null&&C.ok===!0&&C.running===!0&&h(function(L){return L+1}))}).catch(function(){}),function(){g=!0}}},[u]),a.useEffect(function(){k("/code-server/status").then(function(g){g!=null&&E({status:g})}).catch(function(){});var x=window.setInterval(function(){k("/code-server/status").then(function(g){E({status:g})}).catch(function(){})},3e3);return function(){window.clearInterval(x)}},[]),a.useEffect(function(){v!==null&&k("/code-server/open-file",S===null?{file:v}:{file:v,line:S}).catch(function(){})},[d,v,S]),a.createElement("div",{className:"dshcs-tabroot","data-code-server-tab":"body",ref:w},a.createElement(Ue,{status:l,pageUrl:ve(l,u),reloadTick:m,owner:"tab:"+n.id}))}function Q(e,r){if(e==null)return null;var n=e[r];if(n!=null)return n;if(typeof e.get=="function"){var s=e.get(r);if(s!=null)return s}return null}function Ve(e){var r=Q(e,"sidebarRightTabs"),n=Q(e,"sidebarRight");if(r==null||n==null)return console.error("[code-server] \u53F3\u4FA7\u680F\u670D\u52A1\u4E0A\u4E0B\u6587\u4E0D\u53EF\u89C1(sidebarRightTabs="+(r!=null)+", sidebarRight="+(n!=null)+"):\u8DF3\u8FC7\u4FA7\u680F\u6CE8\u518C"),!1;var s=Q(e,"slots");if(e.effect(function(){return r.register({id:ce,kind:de,priority:"extension",patterns:["dsh-resource://file/**"],canOpen:function(l){return ee(D(l),Ye())},title:function(l){if(H(l)||l===void 0||l===null||l==="")return"Code Server";var i=K(l);return i===""?"Code Server":i},guide:[{order:20,title:function(){return"Code Server"},description:function(){return"\u5728\u53F3\u4FA7\u680F\u6807\u7B7E\u91CC\u8FD0\u884C VS Code \u7F51\u9875\u7248,\u8DDF\u968F\u5F53\u524D\u4F1A\u8BDD\u5DE5\u4F5C\u533A;\u4EA7\u7269/\u4EA4\u4ED8\u6587\u4EF6\u70B9\u51FB\u540E\u5728\u6B64\u6253\u5F00\u3002"},icon:We}]})},"code-server: sidebar tab type"),s!=null)e.effect(function(){return s.inject("sidebar.right.pane.tab",function(){return s.register({name:"sidebar.right.pane.tab",key:ce},Je)})},"code-server: sidebar tab body");else return console.error("[code-server] slots \u670D\u52A1\u4E0D\u53EF\u89C1:\u4FA7\u680F\u6807\u7B7E body \u672A\u6CE8\u518C"),!1;return e.effect(function(){return function(){E({sidebarUi:"unknown"})}},"code-server: sidebar mode reset"),console.log("[code-server] right-sidebar tab registered (kind="+de+")"),!0}var Xe=".dshcs-card{border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-3);border-radius:12px;list-style:none;transition:border-color .16s,background .16s}.dshcs-card:hover{border-color:var(--dsw-alias-label-dimmed,var(--dsw-alias-border-l2))}.dshcs-cardOpen{background:var(--dsw-alias-bg-layer-2);border-color:var(--dsw-alias-label-dimmed,var(--dsw-alias-border-l2))}.dshcs-cardHeader{appearance:none;width:100%;font:inherit;color:inherit;text-align:left;cursor:pointer;background:0 0;border:0;border-radius:12px;align-items:center;gap:12px;padding:14px 16px;display:flex}.dshcs-cardHeader:focus-visible{outline:2px solid var(--dsw-alias-brand-primary);outline-offset:-2px}.dshcs-cardHeadText{flex-direction:column;flex:1;gap:4px;min-width:0;display:flex}.dshcs-cardName{color:var(--dsw-alias-label-primary);font-size:15px;font-weight:600;line-height:1.4}.dshcs-cardDescription{color:var(--dsw-alias-label-tertiary,var(--dsw-alias-label-secondary));font-size:13px;line-height:1.5}.dshcs-cardChevron{color:var(--dsw-alias-label-tertiary,var(--dsw-alias-label-secondary));flex:none;transition:transform .16s;display:inline-flex}.dshcs-cardChevronOpen{transform:rotate(180deg)}.dshcs-cardBody{border-top:1px solid var(--dsw-alias-border-l2);margin:0 16px;padding-bottom:8px}.dshcs-cardReadOnly{color:var(--dsw-alias-label-tertiary,var(--dsw-alias-label-secondary));margin:12px 0 0;font-size:12px;line-height:1.5}.dshcs-pending{white-space:nowrap;background:var(--dsw-alias-bg-module-platform,var(--dsw-alias-bg-layer-2));color:var(--dsw-alias-label-secondary);border-radius:999px;flex:none;padding:1px 8px;font-size:11px;font-weight:500;line-height:17px}.dshcs-cardFooter{border-top:1px solid var(--dsw-alias-border-l2);justify-content:flex-end;align-items:center;gap:8px;padding:12px 0 4px;display:flex}.dshcs-cardFailed{min-width:0;color:var(--dsw-alias-label-error,var(--dsw-alias-state-error-primary));flex:1;margin:0;font-size:12px;line-height:1.5}.dshcs-cbtn{appearance:none;font:inherit;cursor:pointer;border-radius:8px;padding:5px 14px;font-size:13px;line-height:1.5;border:1px solid transparent;transition:color .12s ease,background .12s ease}.dshcs-cbtn:disabled{opacity:.4;cursor:default}.dshcs-cbtn:focus-visible{outline:2px solid var(--dsw-alias-brand-primary);outline-offset:1px}.dshcs-cbtnOutline{border-color:var(--dsw-alias-border-l2);color:var(--dsw-alias-label-secondary);background:0 0}.dshcs-cbtnOutline:hover:not(:disabled){color:var(--dsw-alias-label-primary);background:var(--dsw-alias-interactive-bg-hover,transparent)}.dshcs-cbtnPrimary{background:var(--dsw-alias-label-primary);color:var(--dsw-alias-bg-layer-3);border-color:var(--dsw-alias-label-primary);font-weight:600}.dshcs-cbtnPrimary:hover:not(:disabled){filter:brightness(.95)}.dshcs-cbtnPrimary:active:not(:disabled){filter:brightness(.9)}.dshcs-field{flex-direction:column;gap:6px;padding:12px 0;display:flex}.dshcs-field+.dshcs-field{border-top:1px solid var(--dsw-alias-border-l2)}.dshcs-fieldHead{align-items:center;gap:8px;display:flex}.dshcs-fieldLabel{min-width:0;color:var(--dsw-alias-label-primary);flex:1;font-size:13px;font-weight:500;line-height:1.5}.dshcs-card .dshcs-hint{color:var(--dsw-alias-label-tertiary,var(--dsw-alias-label-secondary));margin:0;font-size:12px;line-height:1.5}.dshcs-check{display:flex;align-items:center;gap:8px;cursor:pointer}.dshcs-check input{accent-color:var(--dsw-alias-brand-primary);width:15px;height:15px;margin:0;flex:none}.dshcs-check input:disabled{cursor:default}.dshcs-select{display:inline-flex;align-items:center}.dshcs-select select{font:inherit;color:var(--dsw-alias-label-primary);background:var(--dsw-alias-bg-layer-3,transparent);border:1px solid var(--dsw-alias-border-l2);border-radius:8px;padding:4px 8px;min-width:220px;cursor:pointer}.dshcs-select select:disabled{opacity:.5;cursor:default}.dshcs-badges{align-items:center;gap:8px;display:inline-flex}.dshcs-badge{white-space:nowrap;background:var(--dsw-alias-bg-module-platform,var(--dsw-alias-bg-layer-2));color:var(--dsw-alias-label-secondary);border-radius:999px;padding:1px 8px;font-size:11px;font-weight:500;line-height:17px}.dshcs-reset{font:inherit;color:var(--dsw-alias-label-secondary);cursor:pointer;background:0 0;border:none;padding:0;font-size:12px;line-height:1.5}.dshcs-reset:hover:not(:disabled){color:var(--dsw-alias-label-primary)}.dshcs-reset:disabled{cursor:default}",qe="dsh-code-server/Card.module.css";function Ke(e,r){if(typeof document!="undefined"&&document.querySelector("style[data-plugin-css="+JSON.stringify(e)+"]")===null){var n=document.createElement("style");n.dataset.plugin="dsh-code-server",n.dataset.pluginCss=e,n.textContent=r,document.head.appendChild(n)}}Ke(qe,Xe);function $e(e){return a.createElement("svg",{width:14,height:14,viewBox:"0 0 14 14",fill:"none","aria-hidden":!0,className:e.className},a.createElement("path",{d:"M3.5 5.25L7 8.75L10.5 5.25",stroke:"currentColor",strokeWidth:1.5,strokeLinecap:"round",strokeLinejoin:"round"}))}function oe(e){return a.createElement("button",{type:"button",className:"dshcs-cbtn "+(e.variant==="primary"?"dshcs-cbtnPrimary":"dshcs-cbtnOutline"),disabled:e.disabled===!0,onClick:e.onClick},e.children)}function ue(e){return a.createElement("label",{className:"dshcs-check"},a.createElement("input",{type:"checkbox",checked:e.checked===!0,disabled:e.disabled===!0,onChange:function(r){e.onChange(r.target.checked)}}),a.createElement("span",{className:"dshcs-hint"},e.children))}function er(e){var r=Array.isArray(e.options)?e.options:[];return a.createElement("label",{className:"dshcs-select"},a.createElement("select",{value:e.value,disabled:e.disabled===!0,onChange:function(n){e.onChange(n.target.value)}},r.map(function(n){return a.createElement("option",{key:n.value,value:n.value},n.label)})))}function W(e){var r=[];return e.overridden===!0&&(r.push(a.createElement("span",{className:"dshcs-badge"},e.overriddenLabel)),r.push(a.createElement("button",{type:"button",className:"dshcs-reset",disabled:e.disabled===!0,onClick:e.onReset},e.resetLabel))),r.length===0?null:a.createElement("span",{className:"dshcs-badges"},...r)}function fe(e){var[r,n]=a.useState(e.defaultOpen===!0),s=e.state;if(s==null||s.available!==!0)return null;var l=e.title,i=e.noticeOnly===!0,d=s.dirty!==!0||s.invalid===!0||s.saving===!0;return a.createElement("li",{className:"dshcs-card"+(r?" dshcs-cardOpen":"")},a.createElement("button",{type:"button",className:"dshcs-cardHeader","aria-expanded":r,onClick:function(){n(!r)}},a.createElement("span",{className:"dshcs-cardHeadText"},a.createElement("span",{className:"dshcs-cardName"},l),a.createElement("span",{className:"dshcs-cardDescription"},e.description)),s.dirty===!0?a.createElement("span",{className:"dshcs-pending"},e.unsavedLabel):null,a.createElement($e,{className:"dshcs-cardChevron"+(r?" dshcs-cardChevronOpen":"")})),r===!0?a.createElement("div",{className:"dshcs-cardBody"},i===!0?null:s.writable!==!0?a.createElement("p",{className:"dshcs-cardReadOnly",role:"status"},e.readOnlyLabel):null,e.children,i===!0?null:a.createElement("div",{className:"dshcs-cardFooter"},s.failed===!0?a.createElement("p",{className:"dshcs-cardFailed",role:"status"},e.saveFailedLabel):null,a.createElement(oe,{disabled:s.dirty!==!0||s.saving===!0,onClick:e.onDiscard},e.discardLabel),a.createElement(oe,{variant:"primary",disabled:d,onClick:e.onSave},s.saving===!0?e.savingLabel:e.saveLabel))):null)}function rr(e){try{let g=function(){k("/code-server/status").then(function(b){b!=null&&typeof b=="object"&&E({status:b})}).catch(function(){})};var r=e.scope,[n,s]=a.useState(function(){return r!==void 0?r.getSnapshot():null}),[l,i]=a.useState(null),[d,f]=a.useState(!1),[p,c]=a.useState(!1),u=Z(),[v,S]=a.useState(te());if(a.useEffect(function(){return ne(function(b){S(b)})},[]),a.useEffect(function(){if(r===void 0||typeof r.subscribe!="function")return;function b(){try{s(r.getSnapshot())}catch(ir){}}var y=r.subscribe(b);return function(){typeof y=="function"&&y()}},[r]),r===void 0)return console.error("[code-server] card scope missing"),null;if(n==null||n.status!=="ready")return n!=null&&n.status==="unavailable"&&console.warn("[code-server] settings scope unavailable:",n.status),null;var o=n.value!==void 0&&n.value!==null?n.value:{},m=n.user,h={keepResident:o.keepResident!==!1,fileOpenScope:o.fileOpenScope==="all"?"all":"session",fullscreenOnOpen:o.fullscreenOnOpen!==!1};if(u!=null&&u.sidebarUi==="legacy")return a.createElement(fe,{title:"Code Server",description:"\u5F53\u524D DSH \u7248\u672C\u4E0D\u53D7\u652F\u6301(\u7F3A\u5C11\u53F3\u4FA7\u680F\u670D\u52A1)",defaultOpen:!0,noticeOnly:!0,state:{available:!0,writable:!1,dirty:!1,invalid:!1,saving:!1,failed:!1}},a.createElement("div",{className:"dshcs-field"},a.createElement("div",{className:"dshcs-legacy"},"\u672C\u63D2\u4EF6\u81EA 0.2.3 \u8D77\u4E0D\u518D\u517C\u5BB9\u65E7\u7248 DSH\u3002"),a.createElement("div",{className:"dshcs-hint",style:{marginTop:0}},`\u672A\u68C0\u6D4B\u5230\u53F3\u4FA7\u680F\u63D2\u4EF6\u670D\u52A1 sidebarRightTabs / sidebarRight,\u56E0\u6B64\u63D2\u4EF6\u4E0D\u63D0\u4F9B\u4EFB\u4F55\u5165\u53E3(\u65E7\u7248\u7684\u60AC\u6D6E\u7403\u4E0E\u6D6E\u52A8\u7A97\u53E3\u5DF2\u79FB\u9664),\u4E5F\u4E0D\u4F1A\u540E\u53F0\u542F\u52A8 IDE\u3002
3
- \u5347\u7EA7 DSH \u5230\u5E26\u53F3\u4FA7\u680F\u7684\u7248\u672C(\u2265 0.1.5-alpha.1)\u540E,Code Server \u4F1A\u51FA\u73B0\u5728\u53F3\u4FA7\u680F\u6807\u7B7E\u91CC,\u672C\u9875\u540C\u65F6\u663E\u793A\u5B8C\u6574\u8BBE\u7F6E\u9879;\u5347\u7EA7\u540E\u65E0\u9700\u91CD\u88C5\u672C\u63D2\u4EF6,\u5237\u65B0\u9875\u9762\u5373\u53EF\u3002`)));var w=m!=null&&Object.prototype.hasOwnProperty.call(m,"keepResident"),N=m!=null&&Object.prototype.hasOwnProperty.call(m,"fileOpenScope"),I=m!=null&&Object.prototype.hasOwnProperty.call(m,"fullscreenOnOpen"),O=l!==null&&(l.keepResident!==h.keepResident||l.fileOpenScope!==h.fileOpenScope||l.fullscreenOnOpen!==h.fullscreenOnOpen),z=!O||d,x={available:!0,writable:n.writable,dirty:O,invalid:!1,saving:d,failed:p};async function C(){if(O&&!d){f(!0),c(!1);try{var b=l!==null?l:h;await e.scope.set("keepResident",b.keepResident===!0),await e.scope.set("fileOpenScope",b.fileOpenScope==="all"?"all":"session"),await e.scope.set("fullscreenOnOpen",b.fullscreenOnOpen===!0),i(null),g()}catch(y){c(!0)}f(!1)}}async function L(){if(!(d||n.writable!==!0)){f(!0),c(!1);try{typeof e.scope.unset=="function"?(await e.scope.unset("keepResident"),await e.scope.unset("fileOpenScope"),await e.scope.unset("fullscreenOnOpen")):(await e.scope.set("keepResident",o.keepResident===void 0||o.keepResident===null?!0:o.keepResident),await e.scope.set("fileOpenScope",o.fileOpenScope==="all"?"all":"session"),await e.scope.set("fullscreenOnOpen",o.fullscreenOnOpen===void 0||o.fullscreenOnOpen===null?!0:o.fullscreenOnOpen)),i(null),g()}catch(b){c(!0)}f(!1)}}return a.createElement(fe,{title:"Code Server",description:"\u5165\u53E3:\u53F3\u4FA7\u680F\u6807\u7B7E(DSH \u2265 0.1.5-alpha.1);\u8BA4\u9886\u8303\u56F4\u51B3\u5B9A\u54EA\u4E9B\u6587\u4EF6\u4EA4\u7ED9 Code Server \u6253\u5F00",state:x,unsavedLabel:"\u672A\u4FDD\u5B58",readOnlyLabel:"\u672C\u90E8\u7F72\u7684\u8BBE\u7F6E\u4E3A\u53EA\u8BFB\u3002",saveFailedLabel:"\u672C\u90E8\u7F72\u6CA1\u6709\u63A5\u53D7\u8FD9\u4E9B\u503C\uFF0C\u5DF2\u4FDD\u7559\u4F9B\u4F60\u4FEE\u6539\u3002",discardLabel:"\u653E\u5F03\u4FEE\u6539",saveLabel:"\u4FDD\u5B58",savingLabel:"\u4FDD\u5B58\u4E2D\u2026",onSave:C,onDiscard:function(){i(null),c(!1)}},a.createElement("div",{className:"dshcs-field"},a.createElement("div",{className:"dshcs-fieldHead"},a.createElement("span",{className:"dshcs-fieldLabel"},"\u8BA4\u9886\u8303\u56F4(\u54EA\u4E9B\u6587\u4EF6\u4EA4\u7ED9 Code Server)"),N===!0?a.createElement(W,{overridden:!0,disabled:n.writable!==!0,overriddenLabel:"\u5DF2\u8986\u76D6",resetLabel:"\u6062\u590D\u9ED8\u8BA4",onReset:function(){L()}}):null),a.createElement(er,{value:l!==null?l.fileOpenScope:h.fileOpenScope,disabled:n.writable!==!0,options:[{value:"session",label:"\u4EC5\u4F1A\u8BDD\u5185\u6587\u4EF6(\u63A8\u8350)"},{value:"all",label:"\u6240\u6709\u6587\u4EF6(\u542B\u5DE5\u4F5C\u533A\u5916\u7684\u7EDD\u5BF9\u8DEF\u5F84)"}],onChange:function(b){i(function(y){return Object.assign({},y!==null?y:h,{fileOpenScope:b==="all"?"all":"session"})}),c(!1)}}),a.createElement("div",{className:"dshcs-hint",style:{marginTop:4}},"\u4F1A\u8BDD\u5185\u6587\u4EF6 = DSH \u7528 `dsh-resource://file/session/\u2026` \u547D\u540D\u7684\u6587\u4EF6(\u4EA7\u7269\u3001\u4EA4\u4ED8\u3001\u6B63\u6587\u63D0\u53CA\u3001\u5DE5\u5177\u89C6\u56FE);\u201C\u6240\u6709\u6587\u4EF6\u201D\u8FD8\u4F1A\u8BA4\u9886\u4E0D\u5E26\u4F1A\u8BDD\u7684\u7EDD\u5BF9\u8DEF\u5F84 `dsh-resource://file/absolute/\u2026`\u3002\u672A\u88AB\u8BA4\u9886\u7684\u5730\u5740\u7531 DSH \u81EA\u5E26\u9884\u89C8\u515C\u5E95\u3002")),a.createElement("div",{className:"dshcs-field"},a.createElement("div",{className:"dshcs-fieldHead"},a.createElement("span",{className:"dshcs-fieldLabel"},"\u6253\u5F00\u5373\u5168\u5C4F(\u53F3\u4FA7\u680F\u94FA\u6EE1\u7A97\u53E3)"),I===!0?a.createElement(W,{overridden:!0,disabled:n.writable!==!0,overriddenLabel:"\u5DF2\u8986\u76D6",resetLabel:"\u6062\u590D\u9ED8\u8BA4",onReset:function(){L()}}):null),a.createElement(ue,{checked:l!==null?l.fullscreenOnOpen:h.fullscreenOnOpen,disabled:n.writable!==!0,onChange:function(b){i(function(y){return Object.assign({},y!==null?y:h,{fullscreenOnOpen:b===!0})}),c(!1)}},'\u6253\u5F00 Code Server \u6807\u7B7E(\u542B\u70B9\u5F00\u4EA7\u7269/\u4EA4\u4ED8\u6587\u4EF6)\u65F6,\u81EA\u52A8\u628A\u53F3\u4FA7\u680F\u4ECE"\u4E0E\u5BF9\u8BDD\u5E76\u6392"\u5207\u5230\u5168\u5C4F;\u60F3\u540C\u65F6\u770B\u5BF9\u8BDD\u5C31\u5173\u6389\u5B83,\u6216\u968F\u65F6\u70B9\u53F3\u4FA7\u680F\u7684\u300C\u9000\u51FA\u5168\u5C4F\u300D\u2014\u2014 \u672C\u6B21\u6253\u5F00\u4E0D\u4F1A\u88AB\u62A2\u56DE\u53BB'),a.createElement("div",{className:"dshcs-hint",style:{marginTop:4}},'\u53EA\u5F71\u54CD"\u6253\u5F00\u90A3\u4E00\u523B":\u5207\u8D70\u518D\u5207\u56DE\u3001\u518D\u6B21\u6253\u5F00\u6587\u4EF6 tab \u4F1A\u91CD\u65B0\u5207\u5168\u5C4F;DSH \u672A\u5411\u63D2\u4EF6\u5F00\u653E\u6A21\u5F0F\u63A5\u53E3,\u672C\u9879\u7531\u70B9\u51FB\u53F3\u4FA7\u680F\u81EA\u8EAB\u7684\u300C\u5168\u5C4F\u300D\u6309\u94AE\u5B9E\u73B0\u3002')),a.createElement("div",{className:"dshcs-field"},a.createElement("div",{className:"dshcs-fieldHead"},a.createElement("span",{className:"dshcs-fieldLabel"},"\u540E\u53F0\u5E38\u9A7B(\u5207\u6807\u7B7E\u4E0D\u91CD\u8F7D)"),w===!0?a.createElement(W,{overridden:!0,disabled:n.writable!==!0,overriddenLabel:"\u5DF2\u8986\u76D6",resetLabel:"\u6062\u590D\u9ED8\u8BA4",onReset:function(){L()}}):null),a.createElement(ue,{checked:l!==null?l.keepResident:h.keepResident,disabled:n.writable!==!0,onChange:function(b){i(function(y){return Object.assign({},y!==null?y:h,{keepResident:b===!0})}),c(!1)}},'\u5F00\u542F\u540E\u5BBF\u4E3B\u542F\u52A8\u5373\u628A IDE \u52A0\u8F7D\u5230\u540E\u53F0"\u505C\u653E\u533A":\u5207\u6362\u53F3\u4FA7\u680F\u6807\u7B7E\u3001\u6536\u8D77/\u5C55\u5F00\u4FA7\u680F\u3001\u62D6\u6210\u6D6E\u52A8\u7A97\u53E3\u90FD\u4E0D\u518D\u91CD\u8F7D,\u9996\u6B21\u6253\u5F00\u514D\u7B49\u5F85;\u5173\u95ED\u5219\u53EA\u5728\u6253\u5F00\u9762\u677F\u65F6\u52A0\u8F7D(\u7701\u5185\u5B58)'),a.createElement("div",{className:"dshcs-hint",style:{marginTop:4}},A?"\u5E38\u9A7B\u9762:"+(v.docked?"\u5DF2\u505C\u9760":v.ready?"\u5DF2\u505C\u653E(\u540E\u53F0\u8FD0\u884C\u4E2D)":"\u672A\u542F\u52A8")+(v.degraded?" \xB7 \u672C\u6B21\u53D1\u751F\u8FC7\u964D\u7EA7\u91CD\u8F7D":""):"\u5F53\u524D\u6D4F\u89C8\u5668\u4E0D\u652F\u6301 Element.moveBefore(Chromium <133)\u2192 \u5E38\u9A7B\u4E0D\u53EF\u7528,\u5207\u6807\u7B7E\u4ECD\u4F1A\u6574\u9875\u91CD\u8F7D(\u5347\u7EA7\u6D4F\u89C8\u5668\u540E\u81EA\u52A8\u751F\u6548)")))}catch(g){return console.error("[code-server] card render error:",g!=null&&g.message!==void 0?g.message:String(g)),null}}function nr(e){try{tr(e)}catch(r){console.error("[code-server] apply failed:",r&&r.stack?r.stack:String(r));try{document.title="CS-ERR "+(r&&r.message||String(r))}catch(n){}}}function tr(e){var r=e.get("slots");if(r===void 0){console.error("[code-server] slots service unavailable");return}var n=e.settingsScope,s=null;if(n!==void 0&&typeof n.bind=="function")s=n.bind({namespace:"code-server"});else{console.error("[code-server] settingsScope unavailable (inject missing?); settings card disabled");return}k("/code-server/status").then(function(o){E({status:o})}).catch(function(){}),r.inject("settings.plugin.item",()=>r.register({name:"settings.plugin.item",key:"code-server",label:"Code Server",inject:function(){return{scope:s}}},rr));var l=!1;function i(o,m){if(!l){l=!0,u();var h=!1;try{h=Ve(o)}catch(w){console.error("[code-server] sidebar tab registration failed:",w!=null&&w.message!=null?w.message:String(w))}T.sidebarUi==="legacy"&&(console.log("[code-server] \u53F3\u4FA7\u680F\u670D\u52A1\u665A\u5230(\u7ECF "+m+"):\u64A4\u9500\u65E7\u7248 DSH \u5224\u5B9A"),k("/code-server/ui-mode",{sidebar:!0}).catch(function(){})),E({sidebarUi:"modern",sidebarRegisterFailed:h!==!0}),r.inject("shell.overlay",()=>r.register({name:"shell.overlay",id:"code-server",order:70,label:"Code Server"},w=>a.createElement(_e,w))),console.log("[code-server] client registered via "+m+": sidebar tab="+h+"(claims dsh-resource://file/**) + resident preload + settings card")}}function d(o){E({sidebarUi:"legacy"}),console.warn("[code-server] \u672A\u63A2\u6D4B\u5230\u53F3\u4FA7\u680F\u670D\u52A1(sidebarRightTabs/sidebarRight): \u672C\u63D2\u4EF6\u81EA 0.2.3 \u8D77\u4E0D\u518D\u517C\u5BB9\u65E7\u7248 DSH \u2014\u2014 \u9664\u300C\u8BBE\u7F6E \u2192 \u63D2\u4EF6 \u2192 Code Server\u300D\u7684\u63D0\u793A\u5916\u4E0D\u63D0\u4F9B\u4EFB\u4F55\u5165\u53E3,\u4E5F\u4E0D\u9884\u70ED IDE\u3002\u8BF7\u5347\u7EA7 DSH\u3002"),o===!0&&k("/code-server/ui-mode",{sidebar:!1}).catch(function(){})}var f=null,p=null,c=null;function u(){f!==null&&(clearTimeout(f),f=null),p!==null&&(clearTimeout(p),p=null),c!==null&&(clearTimeout(c),c=null)}var v=!1;try{typeof e.inject=="function"&&(v=!0,e.inject(["sidebarRightTabs","sidebarRight"],function(o){i(o,"inject")}))}catch(o){console.warn("[code-server] sidebar inject failed:",o!=null&&o.message!=null?o.message:String(o))}var S=typeof e.get=="function"&&e.get("sidebarRightTabs")!==void 0&&e.get("sidebarRight")!==void 0;if(S){c=setTimeout(function(){l||(console.warn("[code-server] ctx.inject \u672A\u5728 1.5s \u5185\u56DE\u8C03,\u6539\u7528\u540C\u6B65\u670D\u52A1\u6CE8\u518C\u4FA7\u680F"),i(e,"sync-fallback"))},Qe);return}if(v!==!0){d(!0);return}f=setTimeout(function(){l||d(!1)},Be),p=setTimeout(function(){l||d(!0)},Ge)}var ar=["slots","settingsScope"],lr="code-server";
2
+ var H=Object.defineProperty;var ge=Object.getOwnPropertyDescriptor;var ye=Object.getOwnPropertyNames;var xe=Object.prototype.hasOwnProperty;var we=(e,r)=>{for(var n in r)H(e,n,{get:r[n],enumerable:!0})},Ee=(e,r,n,t)=>{if(r&&typeof r=="object"||typeof r=="function")for(let l of ye(r))!xe.call(e,l)&&l!==n&&H(e,l,{get:()=>r[l],enumerable:!(t=ge(r,l))||t.enumerable});return e};var ke=e=>Ee(H({},"__esModule",{value:!0}),e);var hr={};we(hr,{apply:()=>ur,inject:()=>pr,name:()=>vr});module.exports=ke(hr);var q="dsh-resource://file/",Se="sidebar://";function F(e){return typeof e=="string"&&e.startsWith(Se)}function D(e){if(typeof e!="string"||!e.startsWith(q))return null;for(var r=e.length,n=0;n<e.length;n+=1){var t=e.charAt(n);if(t==="?"||t==="#"){r=n;break}}var l=e.slice(q.length,r).split("/"),s=l.shift();try{if(s==="session"){var c=l.shift();return c===void 0||c===""||l.length===0?null:{scope:"session",sessionId:decodeURIComponent(c),path:K(l)}}if(s==="absolute"){var u=l[0]===""&&l.length>1,p=u?l.slice(1):l,o=K(p);return(o===""||o.charAt(0)==="/")&&!u?null:u?{scope:"absolute",path:"//"+o}:o===""?null:{scope:"absolute",path:$(o)?o:"/"+o}}}catch(f){return null}return null}function K(e){for(var r=[],n=0;n<e.length;n+=1)r.push(decodeURIComponent(e[n]));return r.join("/")}function $(e){return/^[A-Za-z]:($|\/)/.test(e)}function Ce(e){return typeof e!="string"||e===""?!1:e.charAt(0)==="/"?!0:$(e)}function ee(e){var r=D(e);if(r===null)return"";var n=r.path.replace(/[/\\]+$/,""),t=Math.max(n.lastIndexOf("/"),n.lastIndexOf("\\")),l=t===-1?n:n.slice(t+1);return l}function re(e,r){if(e===null||e==null)return null;var n=typeof e.path=="string"?e.path:"";if(n==="")return null;if(Ce(n))return n;if(typeof r!="string"||r==="")return null;var t=r.indexOf("\\")!==-1?"\\":"/",l=r.replace(/[\\/]+$/,"");return l+t+(t==="\\"?n.replace(/\//g,"\\"):n)}var T="*;!md;!markdown;!html;!htm;!png;!jpg;!jpeg;!gif;!webp;!bmp;!ico;!svg;!pdf",Ne=/[;,\s]+/;function Oe(e){return String(e).replace(/!\s+/g,"!").split(Ne)}function Le(e){var r=typeof e=="string"?e.trim():"";if(r==="")return"";var n=r.charAt(0)==="!",t=n?r.slice(1).trim():r;return t==="*"?n?"!*":"*":(t.slice(0,2)==="*."?t=t.slice(2):t.charAt(0)==="."&&(t=t.slice(1)),t=t.toLowerCase(),t===""?"":n?"!"+t:t)}function C(e){if(typeof e!="string")return"";for(var r=Oe(e),n=[],t=0;t<r.length;t+=1){var l=Le(r[t]);l===""||l==="!*"||n.indexOf(l)===-1&&n.push(l)}return n.join(";")}function P(e){for(var r=C(e),n=r===""?[]:r.split(";"),t=!1,l=[],s=[],c=0;c<n.length;c+=1){var u=n[c];if(u==="*"){t=!0;continue}u.charAt(0)==="!"?s.push(u.slice(1)):l.push(u)}return{all:t,allow:l,deny:s}}function Ae(e){if(typeof e!="string"||e==="")return"";var r=e.replace(/[/\\]+$/,""),n=Math.max(r.lastIndexOf("/"),r.lastIndexOf("\\"));n!==-1&&(r=r.slice(n+1));var t=r.lastIndexOf(".");return t<=0?"":r.slice(t+1).toLowerCase()}function Te(e,r){if(r==null)return!1;var n=Ae(e);return n!==""&&r.deny.indexOf(n)!==-1?!1:n!==""&&r.allow.indexOf(n)!==-1?!0:r.all===!0}function ne(e,r){return e===null||e==null?!1:Te(e.path,r)}function te(e){var r=P(e),n=[];return r.all&&n.push("\u5176\u4F59\u7C7B\u578B\u5168\u90E8\u8BA4\u9886"),r.allow.length>0&&n.push("\u6307\u5B9A\u8BA4\u9886 "+r.allow.length+" \u9879"),r.deny.length>0&&n.push("\u6392\u9664 "+r.deny.length+" \u9879"),n.length===0?"\u4E0D\u8BA4\u9886\u4EFB\u4F55\u6587\u4EF6(\u53EA\u6709\u9875\u9762\u6807\u7B7E)":n.join(" \xB7 ")}var Re="[data-sidebar-right-panel]",Me='[data-sidebar-right-mode="fullscreen"]';function ae(e){if(e==null||typeof e.closest!="function")return"no-root";var r,n;try{if(r=e.closest(Re),r==null||typeof r.querySelector!="function")return"no-panel";n=r.querySelector(Me)}catch(t){return"lookup-failed"}if(n==null||typeof n.click!="function")return"no-control";try{n.click()}catch(t){return"click-failed"}return"clicked"}var R=typeof Element!="undefined"&&typeof Element.prototype.moveBefore=="function",Ie=-2e4,a={park:null,frame:null,currentSrc:null,sameOrigin:null,owner:null,lastRect:null,parkStrategy:"offscreen",degraded:!1,preloaded:!1,nudgeCount:0,nudgeEnabled:!0,lastNudgeAt:0,listeners:new Set};function B(){return{ready:a.frame!==null,docked:a.owner!==null,owner:a.owner,src:a.currentSrc,sameOrigin:a.sameOrigin,parkStrategy:a.parkStrategy,degraded:a.degraded,preloaded:a.preloaded,supportsMoveBefore:R,nudgeCount:a.nudgeCount,lastNudgeAt:a.lastNudgeAt}}function M(){var e=B();a.listeners.forEach(function(r){try{r(e)}catch(n){}})}function le(e){return a.listeners.add(e),function(){a.listeners.delete(e)}}function ie(){return B()}function je(e){e!=="offscreen"&&e!=="behind"||a.parkStrategy!==e&&(a.parkStrategy=e,a.frame!==null&&a.owner===null&&G(),M())}function ze(){return a.parkStrategy}function De(){var e=a.lastRect;e!==null&&(a.park.style.width=Math.max(1,Math.round(e.width))+"px",a.park.style.height=Math.max(1,Math.round(e.height))+"px")}function G(){if(a.park!==null){if(De(),a.parkStrategy==="behind"&&a.lastRect!==null){a.park.style.left=Math.round(a.lastRect.left)+"px",a.park.style.top=Math.round(a.lastRect.top)+"px",a.park.style.visibility="visible",a.park.style.zIndex="0";return}a.park.style.left=Ie+"px",a.park.style.top="0px",a.park.style.visibility="hidden",a.park.style.zIndex="0"}}function se(){a.frame!==null&&(a.frame.setAttribute("inert",""),a.frame.setAttribute("aria-hidden","true"))}function Pe(){a.frame!==null&&(a.frame.removeAttribute("inert"),a.frame.removeAttribute("aria-hidden"))}function Ue(){var e=document.createElement("div");e.className="dshcs-park",e.setAttribute("data-dshcs-park",""),e.setAttribute("aria-hidden","true");var r=document.createElement("iframe");return r.className="dshcs-frame",r.setAttribute("title","code-server"),r.setAttribute("allow","clipboard-read; clipboard-write"),r.setAttribute("data-dshcs-resident",""),r.src="about:blank",e.appendChild(r),document.body.appendChild(e),a.park=e,a.frame=r,a.currentSrc="about:blank",a.owner=null,G(),se(),r}function _e(e){var r=a.frame;if(r!==null){var n=a.sameOrigin!==e;!n&&r.hasAttribute("data-dshcs-attrs")||(e===!0?r.removeAttribute("sandbox"):e===!1&&r.setAttribute("sandbox","allow-scripts allow-same-origin allow-forms allow-modals allow-popups allow-pointer-lock allow-clipboard-read allow-clipboard-write"),r.setAttribute("data-dshcs-attrs",e===!0?"same-origin":"cross-origin"),a.sameOrigin=e)}}function Q(e){var r=e||{};return a.frame===null&&Ue(),typeof r.sameOrigin=="boolean"&&_e(r.sameOrigin),typeof r.src=="string"&&r.src!==""&&r.src!==a.currentSrc&&He(r.src),a.frame}function He(e){a.frame===null||typeof e!="string"||e===""||e===a.currentSrc||(a.currentSrc=e,a.frame.src=e,M())}function ce(){var e=a.frame;if(a.nudgeEnabled!==!0||e===null||e.isConnected!==!0)return!1;var r=e.style.display;return e.style.display="none",e.offsetHeight,e.style.display=r,a.nudgeCount+=1,a.lastNudgeAt=Date.now(),!0}function Fe(e){return a.nudgeEnabled=e!==!1,a.nudgeEnabled}function oe(e){if(a.frame!==null){if(R)try{e.moveBefore(a.frame,null);return}catch(r){a.degraded=!0,a.lastMoveError=(r&&r.name?r.name+": ":"")+(r&&r.message?r.message:String(r))}else a.degraded=!0;e.appendChild(a.frame)}}function W(e,r){if(!(a.frame===null||e==null)){var n=a.owner===null,t=e.getBoundingClientRect();t.width>=1&&t.height>=1&&(a.lastRect={left:t.left,top:t.top,width:t.width,height:t.height}),a.owner=r===void 0?null:r,Pe(),a.park.setAttribute("aria-hidden","true"),oe(e),n&&ce(),M()}}function I(e){a.frame!==null&&(e!==void 0&&a.owner!==e||(a.owner=null,G(),se(),a.park.setAttribute("aria-hidden","true"),oe(a.park),M()))}function Y(e){var r=e||{};return Q(r),a.owner===null&&(typeof r.src=="string"&&r.src!==""&&(a.preloaded=!0),I()),a.frame}function Be(){a.park!==null&&a.park.parentNode!==null&&a.park.parentNode.removeChild(a.park),a.park=null,a.frame=null,a.currentSrc=null,a.sameOrigin=null,a.owner=null,a.lastRect=null,a.degraded=!1,a.preloaded=!1,a.nudgeCount=0,a.lastNudgeAt=0,M()}typeof window!="undefined"&&(window.__dshcsSurface={snapshot:B,setParkStrategy:je,getParkStrategy:ze,preload:Y,dock:W,park:I,nudge:ce,setNudgeEnabled:Fe,destroy:Be});var i=require("react"),X=new Set,j={status:null,busy:!1,sidebarUi:"unknown",sidebarRegisterFailed:!1};function S(e){j=Object.assign({},j,e),X.forEach(function(r){r()})}function Ge(e){return X.add(e),function(){X.delete(e)}}function Qe(){return j}function V(){return i.useSyncExternalStore(Ge,Qe)}var We="/api",Ye="data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiB2aWV3Qm94PSIwIDAgMTQ3IDE0NyIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KICA8c3R5bGU+QG1lZGlhIChwcmVmZXJzLWNvbG9yLXNjaGVtZTogZGFyaykgeyogeyBmaWxsOiB3aGl0ZTsgfX08L3N0eWxlPgogIDxwYXRoIGQ9Im00Mi40MjE0LDM5LjY1NWMtMjQuNDA1NywwIC00Mi4xNTU0LDEzLjE3MjEgLTQyLjE1NTQsMzMuODQ1YzAsMjAuNTgxNCAxOC40ODkyLDMzLjg0NSA0Mi4xNTU0LDMzLjg0NWMyMy42NjYyLDAgMzguMTgwMywtMTEuNjE3MSAzOC43MzQ5LC0yOC43MjI1bC0yMS4wNzc3LC0wLjQ1NzRjLTAuOTI0NCw5LjMzMDMgLTkuMTA1OSwxNS4xODQ1IC0xNy42NTcyLDE1LjE4NDVjLTExLjc0MDYsMCAtMjAuNDMwNiwtNy41OTIyIC0yMC40MzA2LC0xOS44NDk2YzAsLTEyLjI1NzQgOC42OSwtMTkuOTg2OCAyMC40MzA2LC0yMC4yMTU1YzguNTUxMywtMC4xODMgMTYuOTE3Nyw1Ljk0NTcgMTcuNDcyMywxNS4yNzZsMjEuMDc3NywtMC42NDAzYy0wLjQ2MjIsLTE2LjgzMTEgLTE0LjE0NDIsLTI4LjI2NTIgLTM4LjU1LC0yOC4yNjUyem00OC44NDQ2LDJsNTUuNDY4LDBsMCw2NC4wMzExbC01NS40NjgsMGwwLC02NC4wMzExeiIgY2xpcC1ydWxlPSJldmVub2RkIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiLz4KPC9zdmc+Cg==";async function k(e,r){var n={method:r===void 0?"GET":"POST",headers:{}};r!==void 0&&(n.headers["content-type"]="application/json",n.body=JSON.stringify(r));var t=await fetch(We+e,n),l=await t.text(),s=null;try{s=l===""?null:JSON.parse(l)}catch(c){s=null}return t.ok?s!==null?s:{ok:!1,error:"invalid JSON response"}:{ok:!1,error:"HTTP "+t.status+(s!==null&&s.error!==void 0?": "+s.error:"")}}function me(e,r){try{var n=e(function(h){return h}),t=r===null?null:typeof r=="function"?r(function(h){return h}):null,l=n!=null?n.current:void 0;if(l!==void 0&&n!=null&&n.byId!=null){var s=n.byId[l];if(s!=null&&typeof s.cwd=="string"&&s.cwd!=="")return s.cwd}var c=t!=null&&Array.isArray(t.items)?t.items:[];if(l!==void 0)for(var u=0;u<c.length;u++){var p=c[u];if(p.sessionIds!=null&&p.sessionIds.indexOf(l)!==-1&&typeof p.path=="string"&&p.path!=="")return p.path}var o=t!=null?t.recentWorkspaceId:void 0;if(o!==void 0){for(var f=0;f<c.length;f++)if(c[f].workspaceId===o&&typeof c[f].path=="string"&&c[f].path!=="")return c[f].path}if(c.length>0&&typeof c[0].path=="string"&&c[0].path!=="")return c[0].path}catch(h){}}function be(e,r){if(e==null||typeof e.url!="string"||e.url==="")return null;var n=e.pid!=null?String(e.pid):e.startedAt!=null?String(e.startedAt):"0",t=e.url+"?s="+encodeURIComponent(n),l=typeof r=="string"&&r!==""?r:e!=null&&e.cwd!=null?e.cwd:null;if(l==null||l==="")return t;var s=l.replace(/\\/g,"/"),c=s;return(/^[A-Za-z]:\//.test(s)||s.charCodeAt(0)!==47)&&(c="/"+s),t+"&folder="+encodeURIComponent(c)}function Ze(e){var r=e.status,n=e.pageUrl,t=e.reloadTick,l=e.owner,s=i.useRef(null),c=r!=null&&r.ok===!0&&r.running===!0,u=r!=null&&r.status==="starting",p=r!=null&&r.ok===!1,o=r!=null&&r.serve==="dsh";if(i.useLayoutEffect(function(){if(!c||n===null){I(l);return}Q({src:n,sameOrigin:o}),s.current!==null&&W(s.current,l)},[c,n,o,t,l]),i.useLayoutEffect(function(){return function(){I(l)}},[l]),c&&n!==null)return i.createElement("div",{ref:s,className:"dshcs-slot","data-code-server-slot":l!=null?l:"code-server"});if(u)return i.createElement("div",{className:"dshcs-loading"},"\u6B63\u5728\u542F\u52A8 code-server\u2026");var f=p&&r!=null&&r.error?r.error:"code-server \u672A\u8FD0\u884C",h=o?"\u5F53\u524D\u4EE5 DSH \u540C\u6E90\u8DEF\u5F84 "+(r!=null&&r.url||"/code-server/")+" \u63D0\u4F9B(\u65E0\u72EC\u7ACB\u7AEF\u53E3)\u3002":"\u5F53\u524D\u4EE5\u72EC\u7ACB\u56DE\u73AF\u7AEF\u53E3\u63D0\u4F9B(\u7AEF\u53E3 "+(r!=null&&r.port!=null?r.port:"8090")+" \u88AB\u5360\u7528\u65F6\u8BF7\u91CA\u653E\u6216\u4FEE\u6539 port \u914D\u7F6E)\u3002",w=R?"\u5E38\u9A7B\u9762:\u53EF\u7528(\u5207\u6807\u7B7E/\u6536\u8D77\u4FA7\u680F\u4E0D\u91CD\u8F7D)\u3002":"\u5E38\u9A7B\u9762:\u5F53\u524D\u6D4F\u89C8\u5668\u4E0D\u652F\u6301 Element.moveBefore \u2014\u2014 \u5207\u6807\u7B7E\u4F1A\u6574\u9875\u91CD\u8F7D(\u5347\u7EA7\u6D4F\u89C8\u5668\u540E\u81EA\u52A8\u53EF\u7528)\u3002";return i.createElement("div",{className:"dshcs-empty"},i.createElement("div",{className:"dshcs-emptybox"},i.createElement("div",null,p?"code-server \u542F\u52A8\u5931\u8D25":"code-server \u672A\u8FD0\u884C"),i.createElement("pre",{className:"dshcs-error"},f),i.createElement("p",{className:"dshcs-hint"},"VS Code \u6811\u968F\u63D2\u4EF6\u5305\u5185\u7F6E\u3001\u5C31\u5730\u8FD0\u884C(\u65E0\u9700\u5168\u5C40\u5B89\u88C5\u3001\u65E0\u9700\u8054\u7F51\u5B89\u88C5\u3001\u65E0\u300C\u5B89\u88C5\u73AF\u5883\u300D\u6B65\u9AA4);\u5185\u90E8\u4F9D\u8D56\u4E0E\u9884\u7F16\u8BD1\u539F\u751F\u6A21\u5757\u7531\u5305\u7BA1\u7406\u5668\u5728\u5B89\u88C5\u63D2\u4EF6\u65F6\u4E00\u5E76\u88C5\u597D(\u65E0\u9700 C++ \u5DE5\u5177\u94FE)\u3002\u82E5\u6B64\u5904\u957F\u671F\u672A\u8FD0\u884C,\u8BF7\u67E5\u770B DSH host \u65E5\u5FD7\u91CC\u7684 [code-server] \u8F93\u51FA(\u6216\u5728\u8BBE\u7F6E\u5361\u7247\u91CC\u5207\u6362\u300C\u540E\u53F0\u5E38\u9A7B\u300D\u89E6\u53D1\u4E00\u6B21\u542F\u52A8)\u3002"+h+w)))}function Je(e){var r=V(),n=r.status,t=n!=null&&n.ok===!0&&n.running===!0,l=n!=null&&n.keepResident===!0,s=me(e&&e.useSessions,e&&e.useWorkspaces),c=t?be(n,s):null;return i.useEffect(function(){!l||!t||c===null||Y({src:c,sameOrigin:n!=null&&n.serve==="dsh"})},[l,t,c,n!=null?n.serve:null]),null}var Xe=".dshcs-frame{display:block;position:absolute;inset:0;z-index:1;width:100%;height:100%;border:0;background:var(--dsw-alias-bg-base,#fff)}.dshcs-tabroot{position:relative;display:flex;flex-direction:column;width:100%;height:100%;min-width:0;min-height:0;background:var(--dsw-alias-bg-base,#fff)}.dshcs-slot{position:relative;display:block;width:100%;height:100%;min-width:0;min-height:0;overflow:hidden;background:var(--dsw-alias-bg-base,#fff)}.dshcs-park{position:fixed;left:-20000px;top:0;width:320px;height:200px;overflow:hidden;pointer-events:none;z-index:0;visibility:hidden;contain:strict}.dshcs-loading{position:absolute;inset:0;z-index:2;display:grid;place-items:center;background:var(--dsw-alias-bg-base,#fff);color:var(--dsw-alias-label-tertiary,#7d8798);font-size:13px}.dshcs-empty{position:relative;z-index:2;flex:1;display:flex;align-items:center;justify-content:center;padding:44px 24px 24px}.dshcs-emptybox{max-width:560px;text-align:left;background:var(--dsw-alias-bg-layer-2,#f7f8fb);border:1px solid var(--dsw-alias-border-l2,#dfe3eb);border-radius:12px;padding:16px 18px}.dshcs-error{color:var(--dsw-alias-label-error,#d92d20);white-space:pre-wrap;word-break:break-all;font-family:ui-monospace,Consolas,monospace;font-size:12px;margin:8px 0 0}.dshcs-hint{color:var(--dsw-alias-label-tertiary,#7d8798);font-size:12px;margin:6px 0 0}.dshcs-legacy{color:var(--dsw-alias-label-warning,#b54708);font-size:12px;font-weight:600;margin:0 0 6px}",de="dsh-code-server/styles";typeof document!="undefined"&&document.querySelector("style[data-dshcs="+JSON.stringify(de)+"]")===null&&(U=document.createElement("style"),U.setAttribute("data-dshcs",de),U.textContent=Xe,document.head.appendChild(U));var U,ue="code-server",fe="dsh-code-server-app",Ve=2500,qe=1e4,Ke=1500;function $e(e){var r=e!=null&&typeof e.size=="number"?e.size:16;return i.createElement("img",{src:Ye,alt:"","aria-hidden":!0,draggable:!1,className:e!=null?e.className:void 0,style:{width:r,height:r,display:"block",objectFit:"contain",WebkitUserDrag:"none",userSelect:"none"}})}var er=P("");function rr(){var e=j.status;return e==null||typeof e.claimExtensions!="string"?er:P(e.claimExtensions)}function nr(e,r){try{var n=e(function(l){return l});if(n!=null&&r!=null&&n.byId!=null){var t=n.byId[r];if(t!=null&&typeof t.cwd=="string"&&t.cwd!=="")return t.cwd}}catch(l){}}function tr(e){var r=e.useTabInfo(),n=r.tab,t=V(),l=t.status,s=n.navigation,c=s!=null&&typeof s.revision=="number"?s.revision:0,u=s!=null&&typeof s.address=="string"?s.address:"",p=F(u)?null:D(u),o=nr(e.useSessions,p!=null?p.sessionId:void 0),f=o!==void 0?o:me(e.useSessions,null),h=re(p,f),w=s!=null&&s.params!=null&&typeof s.params.line=="number"?s.params.line:null,d=i.useRef(void 0),[g,v]=i.useState(0),x=i.useRef(null),L=i.useRef(!1),z=r.tab!=null&&r.tab.visible===!0,N=r.sidebar!=null&&r.sidebar.fullscreen===!0,_=l!=null&&l.fullscreenOnOpen!==!1;return i.useLayoutEffect(function(){if(!z){L.current=!1;return}if(!(!_||N||L.current)){L.current=!0;var E=ae(x.current);E!=="clicked"&&console.warn("[code-server] \u672A\u80FD\u81EA\u52A8\u5207\u5230\u5168\u5C4F\u53F3\u4FA7\u680F("+E+");\u672C\u6B21\u6253\u5F00\u4FDD\u6301\u539F\u6A21\u5F0F")}},[z,N,_]),i.useEffect(function(){if(!(typeof f!="string"||f==="")&&d.current!==f){var E=d.current!==void 0;d.current=f;var b=!1;return k("/code-server/start",{cwd:f}).then(function(O){b||(S({status:O}),E&&O!=null&&O.ok===!0&&O.running===!0&&v(function(A){return A+1}))}).catch(function(){}),function(){b=!0}}},[f]),i.useEffect(function(){k("/code-server/status").then(function(b){b!=null&&S({status:b})}).catch(function(){});var E=window.setInterval(function(){k("/code-server/status").then(function(b){S({status:b})}).catch(function(){})},3e3);return function(){window.clearInterval(E)}},[]),i.useEffect(function(){h!==null&&k("/code-server/open-file",w===null?{file:h}:{file:h,line:w}).catch(function(){})},[c,h,w]),i.createElement("div",{className:"dshcs-tabroot","data-code-server-tab":"body",ref:x},i.createElement(Ze,{status:l,pageUrl:be(l,f),reloadTick:g,owner:"tab:"+n.id}))}function Z(e,r){if(e==null)return null;var n=e[r];if(n!=null)return n;if(typeof e.get=="function"){var t=e.get(r);if(t!=null)return t}return null}function ar(e){var r=Z(e,"sidebarRightTabs"),n=Z(e,"sidebarRight");if(r==null||n==null)return console.error("[code-server] \u53F3\u4FA7\u680F\u670D\u52A1\u4E0A\u4E0B\u6587\u4E0D\u53EF\u89C1(sidebarRightTabs="+(r!=null)+", sidebarRight="+(n!=null)+"):\u8DF3\u8FC7\u4FA7\u680F\u6CE8\u518C"),!1;var t=Z(e,"slots");if(e.effect(function(){return r.register({id:fe,kind:ue,priority:"extension",patterns:["dsh-resource://file/**"],canOpen:function(l){return ne(D(l),rr())},title:function(l){if(F(l)||l===void 0||l===null||l==="")return"Code Server";var s=ee(l);return s===""?"Code Server":s},guide:[{order:20,title:function(){return"Code Server"},description:function(){return"\u5728\u53F3\u4FA7\u680F\u6807\u7B7E\u91CC\u8FD0\u884C VS Code \u7F51\u9875\u7248,\u8DDF\u968F\u5F53\u524D\u4F1A\u8BDD\u5DE5\u4F5C\u533A;\u4EA7\u7269/\u4EA4\u4ED8\u6587\u4EF6\u70B9\u51FB\u540E\u5728\u6B64\u6253\u5F00\u3002"},icon:$e}]})},"code-server: sidebar tab type"),t!=null)e.effect(function(){return t.inject("sidebar.right.pane.tab",function(){return t.register({name:"sidebar.right.pane.tab",key:fe},tr)})},"code-server: sidebar tab body");else return console.error("[code-server] slots \u670D\u52A1\u4E0D\u53EF\u89C1:\u4FA7\u680F\u6807\u7B7E body \u672A\u6CE8\u518C"),!1;return e.effect(function(){return function(){S({sidebarUi:"unknown"})}},"code-server: sidebar mode reset"),console.log("[code-server] right-sidebar tab registered (kind="+ue+")"),!0}var lr=".dshcs-card{border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-3);border-radius:12px;list-style:none;transition:border-color .16s,background .16s}.dshcs-card:hover{border-color:var(--dsw-alias-label-dimmed,var(--dsw-alias-border-l2))}.dshcs-cardOpen{background:var(--dsw-alias-bg-layer-2);border-color:var(--dsw-alias-label-dimmed,var(--dsw-alias-border-l2))}.dshcs-cardHeader{appearance:none;width:100%;font:inherit;color:inherit;text-align:left;cursor:pointer;background:0 0;border:0;border-radius:12px;align-items:center;gap:12px;padding:14px 16px;display:flex}.dshcs-cardHeader:focus-visible{outline:2px solid var(--dsw-alias-brand-primary);outline-offset:-2px}.dshcs-cardHeadText{flex-direction:column;flex:1;gap:4px;min-width:0;display:flex}.dshcs-cardName{color:var(--dsw-alias-label-primary);font-size:15px;font-weight:600;line-height:1.4}.dshcs-cardDescription{color:var(--dsw-alias-label-tertiary,var(--dsw-alias-label-secondary));font-size:13px;line-height:1.5}.dshcs-cardChevron{color:var(--dsw-alias-label-tertiary,var(--dsw-alias-label-secondary));flex:none;transition:transform .16s;display:inline-flex}.dshcs-cardChevronOpen{transform:rotate(180deg)}.dshcs-cardBody{border-top:1px solid var(--dsw-alias-border-l2);margin:0 16px;padding-bottom:8px}.dshcs-cardReadOnly{color:var(--dsw-alias-label-tertiary,var(--dsw-alias-label-secondary));margin:12px 0 0;font-size:12px;line-height:1.5}.dshcs-pending{white-space:nowrap;background:var(--dsw-alias-bg-module-platform,var(--dsw-alias-bg-layer-2));color:var(--dsw-alias-label-secondary);border-radius:999px;flex:none;padding:1px 8px;font-size:11px;font-weight:500;line-height:17px}.dshcs-cardFooter{border-top:1px solid var(--dsw-alias-border-l2);justify-content:flex-end;align-items:center;gap:8px;padding:12px 0 4px;display:flex}.dshcs-cardFailed{min-width:0;color:var(--dsw-alias-label-error,var(--dsw-alias-state-error-primary));flex:1;margin:0;font-size:12px;line-height:1.5}.dshcs-cbtn{appearance:none;font:inherit;cursor:pointer;border-radius:8px;padding:5px 14px;font-size:13px;line-height:1.5;border:1px solid transparent;transition:color .12s ease,background .12s ease}.dshcs-cbtn:disabled{opacity:.4;cursor:default}.dshcs-cbtn:focus-visible{outline:2px solid var(--dsw-alias-brand-primary);outline-offset:1px}.dshcs-cbtnOutline{border-color:var(--dsw-alias-border-l2);color:var(--dsw-alias-label-secondary);background:0 0}.dshcs-cbtnOutline:hover:not(:disabled){color:var(--dsw-alias-label-primary);background:var(--dsw-alias-interactive-bg-hover,transparent)}.dshcs-cbtnPrimary{background:var(--dsw-alias-label-primary);color:var(--dsw-alias-bg-layer-3);border-color:var(--dsw-alias-label-primary);font-weight:600}.dshcs-cbtnPrimary:hover:not(:disabled){filter:brightness(.95)}.dshcs-cbtnPrimary:active:not(:disabled){filter:brightness(.9)}.dshcs-field{flex-direction:column;gap:6px;padding:12px 0;display:flex}.dshcs-field+.dshcs-field{border-top:1px solid var(--dsw-alias-border-l2)}.dshcs-fieldHead{align-items:center;gap:8px;display:flex}.dshcs-fieldLabel{min-width:0;color:var(--dsw-alias-label-primary);flex:1;font-size:13px;font-weight:500;line-height:1.5}.dshcs-card .dshcs-hint{color:var(--dsw-alias-label-tertiary,var(--dsw-alias-label-secondary));margin:0;font-size:12px;line-height:1.5}.dshcs-check{display:flex;align-items:center;gap:8px;cursor:pointer}.dshcs-check input{accent-color:var(--dsw-alias-brand-primary);width:15px;height:15px;margin:0;flex:none}.dshcs-check input:disabled{cursor:default}.dshcs-text{display:flex}.dshcs-text input{font:12px/1.5 ui-monospace,Consolas,monospace;color:var(--dsw-alias-label-primary);background:var(--dsw-alias-bg-layer-3,transparent);border:1px solid var(--dsw-alias-border-l2);border-radius:8px;padding:5px 8px;width:100%;min-width:0}.dshcs-text input:disabled{opacity:.5;cursor:default}.dshcs-text input:focus-visible{outline:2px solid var(--dsw-alias-brand-primary);outline-offset:-1px}.dshcs-badges{align-items:center;gap:8px;display:inline-flex}.dshcs-badge{white-space:nowrap;background:var(--dsw-alias-bg-module-platform,var(--dsw-alias-bg-layer-2));color:var(--dsw-alias-label-secondary);border-radius:999px;padding:1px 8px;font-size:11px;font-weight:500;line-height:17px}.dshcs-reset{font:inherit;color:var(--dsw-alias-label-secondary);cursor:pointer;background:0 0;border:none;padding:0;font-size:12px;line-height:1.5}.dshcs-reset:hover:not(:disabled){color:var(--dsw-alias-label-primary)}.dshcs-reset:disabled{cursor:default}",ir="dsh-code-server/Card.module.css";function sr(e,r){if(typeof document!="undefined"&&document.querySelector("style[data-plugin-css="+JSON.stringify(e)+"]")===null){var n=document.createElement("style");n.dataset.plugin="dsh-code-server",n.dataset.pluginCss=e,n.textContent=r,document.head.appendChild(n)}}sr(ir,lr);function cr(e){return i.createElement("svg",{width:14,height:14,viewBox:"0 0 14 14",fill:"none","aria-hidden":!0,className:e.className},i.createElement("path",{d:"M3.5 5.25L7 8.75L10.5 5.25",stroke:"currentColor",strokeWidth:1.5,strokeLinecap:"round",strokeLinejoin:"round"}))}function pe(e){return i.createElement("button",{type:"button",className:"dshcs-cbtn "+(e.variant==="primary"?"dshcs-cbtnPrimary":"dshcs-cbtnOutline"),disabled:e.disabled===!0,onClick:e.onClick},e.children)}function ve(e){return i.createElement("label",{className:"dshcs-check"},i.createElement("input",{type:"checkbox",checked:e.checked===!0,disabled:e.disabled===!0,onChange:function(r){e.onChange(r.target.checked)}}),i.createElement("span",{className:"dshcs-hint"},e.children))}function or(e){return i.createElement("label",{className:"dshcs-text"},i.createElement("input",{type:"text",value:e.value,disabled:e.disabled===!0,spellCheck:!1,autoComplete:"off",placeholder:e.placeholder,onChange:function(r){e.onChange(r.target.value)}}))}function J(e){var r=[];return e.overridden===!0&&(r.push(i.createElement("span",{className:"dshcs-badge"},e.overriddenLabel)),r.push(i.createElement("button",{type:"button",className:"dshcs-reset",disabled:e.disabled===!0,onClick:e.onReset},e.resetLabel))),r.length===0?null:i.createElement("span",{className:"dshcs-badges"},...r)}function he(e){var[r,n]=i.useState(e.defaultOpen===!0),t=e.state;if(t==null||t.available!==!0)return null;var l=e.title,s=e.noticeOnly===!0,c=t.dirty!==!0||t.invalid===!0||t.saving===!0;return i.createElement("li",{className:"dshcs-card"+(r?" dshcs-cardOpen":"")},i.createElement("button",{type:"button",className:"dshcs-cardHeader","aria-expanded":r,onClick:function(){n(!r)}},i.createElement("span",{className:"dshcs-cardHeadText"},i.createElement("span",{className:"dshcs-cardName"},l),i.createElement("span",{className:"dshcs-cardDescription"},e.description)),t.dirty===!0?i.createElement("span",{className:"dshcs-pending"},e.unsavedLabel):null,i.createElement(cr,{className:"dshcs-cardChevron"+(r?" dshcs-cardChevronOpen":"")})),r===!0?i.createElement("div",{className:"dshcs-cardBody"},s===!0?null:t.writable!==!0?i.createElement("p",{className:"dshcs-cardReadOnly",role:"status"},e.readOnlyLabel):null,e.children,s===!0?null:i.createElement("div",{className:"dshcs-cardFooter"},t.failed===!0?i.createElement("p",{className:"dshcs-cardFailed",role:"status"},e.saveFailedLabel):null,i.createElement(pe,{disabled:t.dirty!==!0||t.saving===!0,onClick:e.onDiscard},e.discardLabel),i.createElement(pe,{variant:"primary",disabled:c,onClick:e.onSave},t.saving===!0?e.savingLabel:e.saveLabel))):null)}function dr(e){try{let b=function(){k("/code-server/status").then(function(m){m!=null&&typeof m=="object"&&S({status:m})}).catch(function(){})};var r=e.scope,[n,t]=i.useState(function(){return r!==void 0?r.getSnapshot():null}),[l,s]=i.useState(null),[c,u]=i.useState(!1),[p,o]=i.useState(!1),f=V(),[h,w]=i.useState(ie());if(i.useEffect(function(){return le(function(m){w(m)})},[]),i.useEffect(function(){if(r===void 0||typeof r.subscribe!="function")return;function m(){try{t(r.getSnapshot())}catch(mr){}}var y=r.subscribe(m);return function(){typeof y=="function"&&y()}},[r]),r===void 0)return console.error("[code-server] card scope missing"),null;if(n==null||n.status!=="ready")return n!=null&&n.status==="unavailable"&&console.warn("[code-server] settings scope unavailable:",n.status),null;var d=n.value!==void 0&&n.value!==null?n.value:{},g=n.user,v={keepResident:d.keepResident!==!1,claimExtensions:typeof d.claimExtensions=="string"?d.claimExtensions:T,fullscreenOnOpen:d.fullscreenOnOpen!==!1};if(f!=null&&f.sidebarUi==="legacy")return i.createElement(he,{title:"Code Server",description:"\u5F53\u524D DSH \u7248\u672C\u4E0D\u53D7\u652F\u6301(\u7F3A\u5C11\u53F3\u4FA7\u680F\u670D\u52A1)",defaultOpen:!0,noticeOnly:!0,state:{available:!0,writable:!1,dirty:!1,invalid:!1,saving:!1,failed:!1}},i.createElement("div",{className:"dshcs-field"},i.createElement("div",{className:"dshcs-legacy"},"\u672C\u63D2\u4EF6\u81EA 0.2.3 \u8D77\u4E0D\u518D\u517C\u5BB9\u65E7\u7248 DSH\u3002"),i.createElement("div",{className:"dshcs-hint",style:{marginTop:0}},`\u672A\u68C0\u6D4B\u5230\u53F3\u4FA7\u680F\u63D2\u4EF6\u670D\u52A1 sidebarRightTabs / sidebarRight,\u56E0\u6B64\u63D2\u4EF6\u4E0D\u63D0\u4F9B\u4EFB\u4F55\u5165\u53E3(\u65E7\u7248\u7684\u60AC\u6D6E\u7403\u4E0E\u6D6E\u52A8\u7A97\u53E3\u5DF2\u79FB\u9664),\u4E5F\u4E0D\u4F1A\u540E\u53F0\u542F\u52A8 IDE\u3002
3
+ \u5347\u7EA7 DSH \u5230\u5E26\u53F3\u4FA7\u680F\u7684\u7248\u672C(\u2265 0.1.5-alpha.1)\u540E,Code Server \u4F1A\u51FA\u73B0\u5728\u53F3\u4FA7\u680F\u6807\u7B7E\u91CC,\u672C\u9875\u540C\u65F6\u663E\u793A\u5B8C\u6574\u8BBE\u7F6E\u9879;\u5347\u7EA7\u540E\u65E0\u9700\u91CD\u88C5\u672C\u63D2\u4EF6,\u5237\u65B0\u9875\u9762\u5373\u53EF\u3002`)));var x=g!=null&&Object.prototype.hasOwnProperty.call(g,"keepResident"),L=g!=null&&Object.prototype.hasOwnProperty.call(g,"claimExtensions"),z=g!=null&&Object.prototype.hasOwnProperty.call(g,"fullscreenOnOpen"),N=l!==null&&(l.keepResident!==v.keepResident||C(l.claimExtensions)!==C(v.claimExtensions)||l.fullscreenOnOpen!==v.fullscreenOnOpen),_=!N||c,E={available:!0,writable:n.writable,dirty:N,invalid:!1,saving:c,failed:p};async function O(){if(N&&!c){u(!0),o(!1);try{var m=l!==null?l:v;await e.scope.set("keepResident",m.keepResident===!0),await e.scope.set("claimExtensions",C(m.claimExtensions)),await e.scope.set("fullscreenOnOpen",m.fullscreenOnOpen===!0),s(null),b()}catch(y){o(!0)}u(!1)}}async function A(){if(!(c||n.writable!==!0)){u(!0),o(!1);try{typeof e.scope.unset=="function"?(await e.scope.unset("keepResident"),await e.scope.unset("claimExtensions"),await e.scope.unset("fullscreenOnOpen")):(await e.scope.set("keepResident",d.keepResident===void 0||d.keepResident===null?!0:d.keepResident),await e.scope.set("claimExtensions",typeof d.claimExtensions=="string"?C(d.claimExtensions):T),await e.scope.set("fullscreenOnOpen",d.fullscreenOnOpen===void 0||d.fullscreenOnOpen===null?!0:d.fullscreenOnOpen)),s(null),b()}catch(m){o(!0)}u(!1)}}return i.createElement(he,{title:"Code Server",description:"\u5165\u53E3:\u53F3\u4FA7\u680F\u6807\u7B7E(DSH \u2265 0.1.5-alpha.1);\u8BA4\u9886\u7C7B\u578B\u51B3\u5B9A\u54EA\u4E9B\u6587\u4EF6\u4EA4\u7ED9 Code Server \u6253\u5F00",state:E,unsavedLabel:"\u672A\u4FDD\u5B58",readOnlyLabel:"\u672C\u90E8\u7F72\u7684\u8BBE\u7F6E\u4E3A\u53EA\u8BFB\u3002",saveFailedLabel:"\u672C\u90E8\u7F72\u6CA1\u6709\u63A5\u53D7\u8FD9\u4E9B\u503C\uFF0C\u5DF2\u4FDD\u7559\u4F9B\u4F60\u4FEE\u6539\u3002",discardLabel:"\u653E\u5F03\u4FEE\u6539",saveLabel:"\u4FDD\u5B58",savingLabel:"\u4FDD\u5B58\u4E2D\u2026",onSave:O,onDiscard:function(){s(null),o(!1)}},i.createElement("div",{className:"dshcs-field"},i.createElement("div",{className:"dshcs-fieldHead"},i.createElement("span",{className:"dshcs-fieldLabel"},"\u8BA4\u9886\u7C7B\u578B(\u6309\u6269\u5C55\u540D,\u5206\u53F7\u5206\u9694)"),L===!0?i.createElement(J,{overridden:!0,disabled:n.writable!==!0,overriddenLabel:"\u5DF2\u8986\u76D6",resetLabel:"\u6062\u590D\u9ED8\u8BA4",onReset:function(){A()}}):null),i.createElement(or,{value:l!==null?l.claimExtensions:v.claimExtensions,disabled:n.writable!==!0,placeholder:T,onChange:function(m){s(function(y){return Object.assign({},y!==null?y:v,{claimExtensions:m})}),o(!1)}}),i.createElement("div",{className:"dshcs-hint",style:{marginTop:4}},"\u5199\u6269\u5C55\u540D(\u4E0D\u5E26\u70B9,\u5927\u5C0F\u5199\u968F\u610F);`*` = \u5176\u4F59\u7C7B\u578B\u4E5F\u8BA4\u9886;`!ext` = \u4E0D\u8BA4\u9886(\u6392\u9664\u4F18\u5148)\u3002\u4E0D\u518D\u533A\u5206\u4F1A\u8BDD\u5185/\u7EDD\u5BF9\u8DEF\u5F84 \u2014\u2014 \u6240\u6709 `dsh-resource://file/**` \u4E00\u89C6\u540C\u4EC1,\u672A\u8BA4\u9886\u7684\u843D\u56DE DSH \u81EA\u5E26\u9884\u89C8\u3002"),i.createElement("div",{className:"dshcs-hint",style:{marginTop:2}},"\u5B9E\u9645\u89C4\u5219:"+te(l!==null?l.claimExtensions:v.claimExtensions)+(C(l!==null?l.claimExtensions:v.claimExtensions)!==(l!==null?l.claimExtensions:v.claimExtensions)?"(\u4FDD\u5B58\u540E\u5F52\u4E00\u5316)":"")+" \xB7 \u9ED8\u8BA4 "+T)),i.createElement("div",{className:"dshcs-field"},i.createElement("div",{className:"dshcs-fieldHead"},i.createElement("span",{className:"dshcs-fieldLabel"},"\u6253\u5F00\u5373\u5168\u5C4F(\u53F3\u4FA7\u680F\u94FA\u6EE1\u7A97\u53E3)"),z===!0?i.createElement(J,{overridden:!0,disabled:n.writable!==!0,overriddenLabel:"\u5DF2\u8986\u76D6",resetLabel:"\u6062\u590D\u9ED8\u8BA4",onReset:function(){A()}}):null),i.createElement(ve,{checked:l!==null?l.fullscreenOnOpen:v.fullscreenOnOpen,disabled:n.writable!==!0,onChange:function(m){s(function(y){return Object.assign({},y!==null?y:v,{fullscreenOnOpen:m===!0})}),o(!1)}},'\u6253\u5F00 Code Server \u6807\u7B7E(\u542B\u70B9\u5F00\u4EA7\u7269/\u4EA4\u4ED8\u6587\u4EF6)\u65F6,\u81EA\u52A8\u628A\u53F3\u4FA7\u680F\u4ECE"\u4E0E\u5BF9\u8BDD\u5E76\u6392"\u5207\u5230\u5168\u5C4F;\u60F3\u540C\u65F6\u770B\u5BF9\u8BDD\u5C31\u5173\u6389\u5B83,\u6216\u968F\u65F6\u70B9\u53F3\u4FA7\u680F\u7684\u300C\u9000\u51FA\u5168\u5C4F\u300D\u2014\u2014 \u672C\u6B21\u6253\u5F00\u4E0D\u4F1A\u88AB\u62A2\u56DE\u53BB'),i.createElement("div",{className:"dshcs-hint",style:{marginTop:4}},'\u53EA\u5F71\u54CD"\u6253\u5F00\u90A3\u4E00\u523B":\u5207\u8D70\u518D\u5207\u56DE\u3001\u518D\u6B21\u6253\u5F00\u6587\u4EF6 tab \u4F1A\u91CD\u65B0\u5207\u5168\u5C4F;DSH \u672A\u5411\u63D2\u4EF6\u5F00\u653E\u6A21\u5F0F\u63A5\u53E3,\u672C\u9879\u7531\u70B9\u51FB\u53F3\u4FA7\u680F\u81EA\u8EAB\u7684\u300C\u5168\u5C4F\u300D\u6309\u94AE\u5B9E\u73B0\u3002')),i.createElement("div",{className:"dshcs-field"},i.createElement("div",{className:"dshcs-fieldHead"},i.createElement("span",{className:"dshcs-fieldLabel"},"\u540E\u53F0\u5E38\u9A7B(\u5207\u6807\u7B7E\u4E0D\u91CD\u8F7D)"),x===!0?i.createElement(J,{overridden:!0,disabled:n.writable!==!0,overriddenLabel:"\u5DF2\u8986\u76D6",resetLabel:"\u6062\u590D\u9ED8\u8BA4",onReset:function(){A()}}):null),i.createElement(ve,{checked:l!==null?l.keepResident:v.keepResident,disabled:n.writable!==!0,onChange:function(m){s(function(y){return Object.assign({},y!==null?y:v,{keepResident:m===!0})}),o(!1)}},'\u5F00\u542F\u540E\u5BBF\u4E3B\u542F\u52A8\u5373\u628A IDE \u52A0\u8F7D\u5230\u540E\u53F0"\u505C\u653E\u533A":\u5207\u6362\u53F3\u4FA7\u680F\u6807\u7B7E\u3001\u6536\u8D77/\u5C55\u5F00\u4FA7\u680F\u3001\u62D6\u6210\u6D6E\u52A8\u7A97\u53E3\u90FD\u4E0D\u518D\u91CD\u8F7D,\u9996\u6B21\u6253\u5F00\u514D\u7B49\u5F85;\u5173\u95ED\u5219\u53EA\u5728\u6253\u5F00\u9762\u677F\u65F6\u52A0\u8F7D(\u7701\u5185\u5B58)'),i.createElement("div",{className:"dshcs-hint",style:{marginTop:4}},R?"\u5E38\u9A7B\u9762:"+(h.docked?"\u5DF2\u505C\u9760":h.ready?"\u5DF2\u505C\u653E(\u540E\u53F0\u8FD0\u884C\u4E2D)":"\u672A\u542F\u52A8")+(h.degraded?" \xB7 \u672C\u6B21\u53D1\u751F\u8FC7\u964D\u7EA7\u91CD\u8F7D":""):"\u5F53\u524D\u6D4F\u89C8\u5668\u4E0D\u652F\u6301 Element.moveBefore(Chromium <133)\u2192 \u5E38\u9A7B\u4E0D\u53EF\u7528,\u5207\u6807\u7B7E\u4ECD\u4F1A\u6574\u9875\u91CD\u8F7D(\u5347\u7EA7\u6D4F\u89C8\u5668\u540E\u81EA\u52A8\u751F\u6548)")))}catch(b){return console.error("[code-server] card render error:",b!=null&&b.message!==void 0?b.message:String(b)),null}}function ur(e){try{fr(e)}catch(r){console.error("[code-server] apply failed:",r&&r.stack?r.stack:String(r));try{document.title="CS-ERR "+(r&&r.message||String(r))}catch(n){}}}function fr(e){var r=e.get("slots");if(r===void 0){console.error("[code-server] slots service unavailable");return}var n=e.settingsScope,t=null;if(n!==void 0&&typeof n.bind=="function")t=n.bind({namespace:"code-server"});else{console.error("[code-server] settingsScope unavailable (inject missing?); settings card disabled");return}k("/code-server/status").then(function(d){S({status:d})}).catch(function(){}),r.inject("settings.plugin.item",()=>r.register({name:"settings.plugin.item",key:"code-server",label:"Code Server",inject:function(){return{scope:t}}},dr));var l=!1;function s(d,g){if(!l){l=!0,f();var v=!1;try{v=ar(d)}catch(x){console.error("[code-server] sidebar tab registration failed:",x!=null&&x.message!=null?x.message:String(x))}j.sidebarUi==="legacy"&&(console.log("[code-server] \u53F3\u4FA7\u680F\u670D\u52A1\u665A\u5230(\u7ECF "+g+"):\u64A4\u9500\u65E7\u7248 DSH \u5224\u5B9A"),k("/code-server/ui-mode",{sidebar:!0}).catch(function(){})),S({sidebarUi:"modern",sidebarRegisterFailed:v!==!0}),r.inject("shell.overlay",()=>r.register({name:"shell.overlay",id:"code-server",order:70,label:"Code Server"},x=>i.createElement(Je,x))),console.log("[code-server] client registered via "+g+": sidebar tab="+v+"(claims dsh-resource://file/**) + resident preload + settings card")}}function c(d){S({sidebarUi:"legacy"}),console.warn("[code-server] \u672A\u63A2\u6D4B\u5230\u53F3\u4FA7\u680F\u670D\u52A1(sidebarRightTabs/sidebarRight): \u672C\u63D2\u4EF6\u81EA 0.2.3 \u8D77\u4E0D\u518D\u517C\u5BB9\u65E7\u7248 DSH \u2014\u2014 \u9664\u300C\u8BBE\u7F6E \u2192 \u63D2\u4EF6 \u2192 Code Server\u300D\u7684\u63D0\u793A\u5916\u4E0D\u63D0\u4F9B\u4EFB\u4F55\u5165\u53E3,\u4E5F\u4E0D\u9884\u70ED IDE\u3002\u8BF7\u5347\u7EA7 DSH\u3002"),d===!0&&k("/code-server/ui-mode",{sidebar:!1}).catch(function(){})}var u=null,p=null,o=null;function f(){u!==null&&(clearTimeout(u),u=null),p!==null&&(clearTimeout(p),p=null),o!==null&&(clearTimeout(o),o=null)}var h=!1;try{typeof e.inject=="function"&&(h=!0,e.inject(["sidebarRightTabs","sidebarRight"],function(d){s(d,"inject")}))}catch(d){console.warn("[code-server] sidebar inject failed:",d!=null&&d.message!=null?d.message:String(d))}var w=typeof e.get=="function"&&e.get("sidebarRightTabs")!==void 0&&e.get("sidebarRight")!==void 0;if(w){o=setTimeout(function(){l||(console.warn("[code-server] ctx.inject \u672A\u5728 1.5s \u5185\u56DE\u8C03,\u6539\u7528\u540C\u6B65\u670D\u52A1\u6CE8\u518C\u4FA7\u680F"),s(e,"sync-fallback"))},Ke);return}if(h!==!0){c(!0);return}u=setTimeout(function(){l||c(!1)},Ve),p=setTimeout(function(){l||c(!0)},qe)}var pr=["slots","settingsScope"],vr="code-server";
4
4
  return module.exports;}});
5
5
 
package/lib/index.js CHANGED
@@ -36,6 +36,7 @@ import {
36
36
  } from './vendor.js';
37
37
  import { aliasNodePathDirs, ensureRuntimeLayout, resolveRuntime, runtimePackageName, verifyNatives } from './native.js';
38
38
  import { MOUNT_PATH, mountOnWebServer } from './serve-dsh.mjs';
39
+ import { DEFAULT_CLAIM_EXTENSIONS, describeClaimPolicy, normalizeClaimExtensions } from './claim-types.js';
39
40
 
40
41
  // schemastery 由 DSH 部署自带(官方核心依赖),仿 auto-open-web 的解析策略:
41
42
  // 常规 import 优先,不可用时回退到全局 npm 布局的 DSH 部署副本。
@@ -66,9 +67,9 @@ export const inject = ['connection', 'settings'];
66
67
  /** 设置命名空间:卡片经官方 settings 域读写,持久化到官方 settings 文档。 */
67
68
  export const SETTINGS_NS = 'code-server';
68
69
 
69
- /** 设置卡片 schema(只留三个可改设置:keepResident / fileOpenScope / fullscreenOnOpen)。
70
- * 旧设置文档里残留的 reserveComposer / windowedOpen 不再出现在 schema 里 —— schemastery 的
71
- * object 非 strict 会把未知键原样 merge 进解析结果,既不报错也不影响取值,故无需迁移。 */
70
+ /** 设置卡片 schema(只留三个可改设置:claimExtensions / fullscreenOnOpen / keepResident)。
71
+ * 旧设置文档里残留的 reserveComposer / windowedOpen / fileOpenScope 不再出现在 schema 里 ——
72
+ * schemastery 的 object 非 strict 会把未知键原样 merge 进解析结果,既不报错也不影响取值,故无需迁移。 */
72
73
  export const Config = z.object({
73
74
  /** 服务方式:loopback(默认)独立回环端口;dsh 挂到 DSH webServer 的 /code-server
74
75
  * (同源、无额外端口、复用 DSH 的 Host/Origin + cookie 防护;需要 DSH 提供 webServer 服务,
@@ -78,11 +79,10 @@ export const Config = z.object({
78
79
  /** keepResident=true(默认)客户端在宿主 running 后把 IDE 预先加载到"停放区",
79
80
  * 切标签/收起侧栏不再重载;false 则只在打开面板时才加载(省内存)。 */
80
81
  keepResident: z.boolean().default(true),
81
- /** 客户端认领哪些文件地址(哪些文件的点击交给 Code Server 打开):
82
- * 'session'(默认)= 只认领会话作用域的 `dsh-resource://file/session/…`(产物、交付、
83
- * 正文提及、工具视图都走这条);'all' = 连不带会话的 `dsh-resource://file/absolute/…` 也认领。
84
- * 未认领的地址由 DSH 自带预览兜底。 */
85
- fileOpenScope: z.union([z.const('session'), z.const('all')]).default('session'),
82
+ /** 认领类型(0.2.11):按扩展名决定哪些文件交给 VS Code 打开(分号分隔,`*` = 其余类型也认领,
83
+ * `!ext` = 不认领,排除优先)。**不再区分 session/absolute 作用域** —— 所有
84
+ * `dsh-resource://file/**` 地址一视同仁。语法、默认值与解析见 lib/claim-types.js。 */
85
+ claimExtensions: z.string().default(DEFAULT_CLAIM_EXTENSIONS),
86
86
  /** fullscreenOnOpen=true(默认):打开 Code Server 标签(含点开产物/交付文件)时,
87
87
  * 客户端把右侧栏切到全屏(铺满窗口);false 则保持 DSH 默认的 push(与对话并排)。
88
88
  * 只影响"打开那一刻":之后用户点「退出全屏」不会被抢回去。 */
@@ -380,7 +380,7 @@ export async function apply(ctx, config) {
380
380
  }
381
381
  let serveSetting = 'loopback';
382
382
  let keepResident = true; // 客户端常驻预热(0.2.2)
383
- let fileOpenScope = 'session'; // 客户端认领的文件地址范围(0.2.5)
383
+ let claimExtensions = DEFAULT_CLAIM_EXTENSIONS; // 认领类型清单(0.2.11,取代 fileOpenScope)
384
384
  let fullscreenOnOpen = true; // 客户端"打开标签即全屏右侧栏"(0.2.9)
385
385
  if (settingsSvc !== undefined && typeof settingsSvc.register === 'function') {
386
386
  try {
@@ -390,7 +390,9 @@ export async function apply(ctx, config) {
390
390
  const resolved = scope.get();
391
391
  serveSetting = resolved && resolved.serve === 'dsh' ? 'dsh' : 'loopback';
392
392
  keepResident = resolved && typeof resolved.keepResident === 'boolean' ? resolved.keepResident : true;
393
- fileOpenScope = resolved && resolved.fileOpenScope === 'all' ? 'all' : 'session';
393
+ claimExtensions = resolved && typeof resolved.claimExtensions === 'string'
394
+ ? normalizeClaimExtensions(resolved.claimExtensions)
395
+ : DEFAULT_CLAIM_EXTENSIONS;
394
396
  fullscreenOnOpen = resolved && typeof resolved.fullscreenOnOpen === 'boolean' ? resolved.fullscreenOnOpen : true;
395
397
  }
396
398
  scope.watch((next) => {
@@ -404,10 +406,11 @@ export async function apply(ctx, config) {
404
406
  keepResident = next.keepResident;
405
407
  console.log(`[code-server] keepResident updated: ${keepResident}`);
406
408
  }
407
- if (next != null && (next.fileOpenScope === 'all' || next.fileOpenScope === 'session')) {
408
- if (next.fileOpenScope !== fileOpenScope) {
409
- fileOpenScope = next.fileOpenScope;
410
- console.log(`[code-server] fileOpenScope updated: ${fileOpenScope}`);
409
+ if (next != null && typeof next.claimExtensions === 'string') {
410
+ const normalized = normalizeClaimExtensions(next.claimExtensions);
411
+ if (normalized !== claimExtensions) {
412
+ claimExtensions = normalized;
413
+ console.log(`[code-server] claimExtensions updated: ${claimExtensions} (${describeClaimPolicy(claimExtensions)})`);
411
414
  }
412
415
  }
413
416
  if (next != null && typeof next.fullscreenOnOpen === 'boolean') {
@@ -418,7 +421,7 @@ export async function apply(ctx, config) {
418
421
  }
419
422
  });
420
423
  } catch (error) {
421
- console.error(`[code-server] settings unavailable; using defaults (keepResident=true, fileOpenScope=session, fullscreenOnOpen=true): ${error.message}`);
424
+ console.error(`[code-server] settings unavailable; using defaults (claimExtensions=${DEFAULT_CLAIM_EXTENSIONS}, fullscreenOnOpen=true, keepResident=true): ${error.message}`);
422
425
  }
423
426
  }
424
427
 
@@ -446,6 +449,8 @@ export async function apply(ctx, config) {
446
449
  pid: null,
447
450
  port: cfg.port,
448
451
  cwd: null,
452
+ /** 进程**启动时**的工作目录(诊断用):运行时切工作区只改 cwd,进程 cwd 保持这里不变。 */
453
+ launchCwd: null,
449
454
  version: null,
450
455
  error: null,
451
456
  logTail: '',
@@ -504,6 +509,7 @@ export async function apply(ctx, config) {
504
509
  host: dshMode ? null : cfg.host,
505
510
  pid: state.pid,
506
511
  cwd: state.cwd,
512
+ launchCwd: state.launchCwd,
507
513
  // dsh 模式:同源相对地址(由 DSH webServer 的 prefix 路由提供服务)
508
514
  url: running ? (dshMode ? '/code-server/' : `http://${cfg.host}:${state.port}/`) : null,
509
515
  productPath: state.env?.productPath ?? null,
@@ -512,7 +518,7 @@ export async function apply(ctx, config) {
512
518
  logTail: state.logTail.slice(-LOG_TAIL_MAX),
513
519
  adopted: state.adopted,
514
520
  keepResident,
515
- fileOpenScope, // 客户端据此决定认领哪些文件地址(0.2.5)
521
+ claimExtensions, // 客户端据此按扩展名决定认领哪些文件(0.2.11,取代 fileOpenScope)
516
522
  fullscreenOnOpen, // 客户端据此决定"打开标签即全屏右侧栏"(0.2.9)
517
523
  sidebarUi: state.sidebarUi,
518
524
  env: state.env,
@@ -614,6 +620,7 @@ export async function apply(ctx, config) {
614
620
  state.status = 'stopped';
615
621
  state.pid = null;
616
622
  state.cwd = null;
623
+ state.launchCwd = null;
617
624
  state.startedAt = null;
618
625
  state.adopted = false;
619
626
  if (reason) state.error = null;
@@ -660,13 +667,29 @@ export async function apply(ctx, config) {
660
667
  return run;
661
668
  }
662
669
 
670
+ /** 已运行实例切换工作区:**只改"当前 workbench 目录",不重启进程**。
671
+ *
672
+ * 为什么够用:工作区目录由客户端 URL 的 `&folder=<绝对路径>` 决定(见 src/factory.js 的
673
+ * buildPageUrl),服务进程自己的 cwd 只影响它 spawn 时对相对路径的解析;真正"换目录"是
674
+ * workbench 拿新 folder 重新导航(客户端导航 iframe)。
675
+ * 旧行为(0.2.11 及以前)在这里 stop('restart') + 重新 launch:切一次工作区就整进程重启,
676
+ * 编辑缓冲、终端、扩展宿主状态全丢,而且侧栏收起时是在后台悄悄发生。
677
+ * 进程 cwd 保持在 launchCwd 里,诊断时能看出"这个实例是哪个目录拉起来的"。 */
678
+ function adoptWorkspace(cwd) {
679
+ const previous = state.cwd;
680
+ state.cwd = cwd;
681
+ console.log(`[code-server] workspace switch: ${previous ?? '(none)'} -> ${cwd}`
682
+ + `(不重启进程,进程 cwd 仍是 ${state.launchCwd ?? '(none)'};workbench 用新的 folder 重新导航)`);
683
+ return snapshot();
684
+ }
685
+
663
686
  async function startInner(cwdArg) {
664
687
  const cwd = typeof cwdArg === 'string' && cwdArg.trim() !== '' ? cwdArg : undefined;
665
688
  if (state.status === 'running' && state.pid !== null) {
666
689
  if (cwd === undefined || cwd === state.cwd) return snapshot();
667
- await stop('restart');
690
+ return adoptWorkspace(cwd);
668
691
  }
669
- // 上一次启动仍在进行:等待它结算后再按本次 cwd 启动,避免 cwd 切换被吞
692
+ // 上一次启动仍在进行:等待它结算后再决定(运行中则同上面一样只换目录,不重启)
670
693
  if (state.status === 'starting') {
671
694
  const deadline = Date.now() + 10000;
672
695
  while (state.status === 'starting' && Date.now() < deadline) {
@@ -680,7 +703,7 @@ export async function apply(ctx, config) {
680
703
  }
681
704
  if (state.status === 'running') {
682
705
  if (cwd === undefined || cwd === state.cwd) return snapshot();
683
- await stop('restart');
706
+ return adoptWorkspace(cwd);
684
707
  }
685
708
  }
686
709
 
@@ -707,6 +730,7 @@ export async function apply(ctx, config) {
707
730
  state.status = 'running';
708
731
  state.pid = record.pid;
709
732
  state.cwd = cwd ?? record.cwd ?? null;
733
+ state.launchCwd = record.launchCwd ?? record.cwd ?? null;
710
734
  state.startedAt = record.startedAt ?? null;
711
735
  state.adopted = true;
712
736
  return snapshot();
@@ -760,6 +784,7 @@ export async function apply(ctx, config) {
760
784
  state.logTail = '';
761
785
  state.status = 'starting';
762
786
  state.cwd = cwd ?? null;
787
+ state.launchCwd = cwd ?? null;
763
788
  state.startedAt = Date.now();
764
789
  state.adopted = false;
765
790
 
@@ -806,6 +831,7 @@ export async function apply(ctx, config) {
806
831
  pid: proc.pid,
807
832
  startedAt: state.startedAt,
808
833
  cwd: cwd ?? null,
834
+ launchCwd: cwd ?? null,
809
835
  host: serve === 'dsh' ? null : cfg.host,
810
836
  port: serve === 'dsh' ? null : cfg.port,
811
837
  serve,
@@ -1077,6 +1103,7 @@ export async function apply(ctx, config) {
1077
1103
  state.status = 'running';
1078
1104
  state.pid = record.pid;
1079
1105
  state.cwd = record.cwd ?? null;
1106
+ state.launchCwd = record.launchCwd ?? record.cwd ?? null;
1080
1107
  state.startedAt = record.startedAt ?? null;
1081
1108
  state.adopted = true;
1082
1109
  console.log(`[code-server] adopted running instance pid=${record.pid} port=${cfg.port}`);
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "dsh-code-server-app",
3
- "version": "0.2.10",
4
- "description": "VS Code (from a code-server release) inside DSH: a right-sidebar tab driven by the plugin's own launcher over the in-process VS Code server (lib/launcher.mjs). The tab claims DSH file addresses (dsh-resource://file/**), so the product's own produced-file chips, delivered-file previews and inline prose mentions open in the workbench. The IDE is a resident surface moved with Element.moveBefore instead of being remounted, so switching sidebar tabs no longer reloads it. Opening the tab switches the right sidebar to fullscreen by default (setting fullscreenOnOpen). Requires a DSH with the right-sidebar services (sidebarRightTabs/sidebarRight, >= 0.1.5-alpha.1); older DSH versions get a single upgrade notice on the settings page and no other UI. Two serving modes: loopback port (default) or same-origin mount on DSH's own webServer (/code-server, protected by ctx.connection.requestRejection). No code-server Node layer, no argon2, no C++ toolchain.",
3
+ "version": "0.2.12",
4
+ "description": "VS Code (from a code-server release) inside DSH: a right-sidebar tab driven by the plugin's own launcher over the in-process VS Code server (lib/launcher.mjs). The tab claims DSH file addresses (dsh-resource://file/**) by file type (setting claimExtensions), so the product's own produced-file chips, delivered-file previews and inline prose mentions open in the workbench. The IDE is a resident surface moved with Element.moveBefore instead of being remounted, so switching sidebar tabs no longer reloads it. Opening the tab switches the right sidebar to fullscreen by default (setting fullscreenOnOpen). Following a workspace switch is lightweight: the workbench re-navigates with the new ?folder= and the IDE process is not restarted (since 0.2.12). Requires a DSH with the right-sidebar services (sidebarRightTabs/sidebarRight, >= 0.1.5-alpha.1); older DSH versions get a single upgrade notice on the settings page and no other UI. Two serving modes: loopback port (default) or same-origin mount on DSH's own webServer (/code-server, protected by ctx.connection.requestRejection). No code-server Node layer, no argon2, no C++ toolchain.",
5
5
  "homepage": "https://github.com/jinsiyu/dsh-code-server-app",
6
6
  "repository": {
7
7
  "type": "git",
@@ -40,6 +40,7 @@
40
40
  "files": [
41
41
  "lib/index.js",
42
42
  "lib/client.js",
43
+ "lib/claim-types.js",
43
44
  "lib/launcher.mjs",
44
45
  "lib/serve-dsh.mjs",
45
46
  "lib/vendor.js",
@@ -114,6 +115,8 @@
114
115
  "build:client": "node scripts/build-client.mjs",
115
116
  "test:apply": "node scripts/test-plugin-apply.mjs",
116
117
  "test:launcher-routes": "node scripts/test-launcher-routes.mjs",
117
- "test:fullscreen": "node scripts/test-sidebar-fullscreen.mjs"
118
+ "test:fullscreen": "node scripts/test-sidebar-fullscreen.mjs",
119
+ "test:claim-types": "node scripts/test-claim-types.mjs",
120
+ "test:workspace-switch": "node scripts/test-workspace-switch.mjs"
118
121
  }
119
122
  }
@@ -3,7 +3,7 @@
3
3
  "vscodeVersion": "1.136.1",
4
4
  "productPath": "stable-8d5f383f301ca20681f5b6606b8207d9dc87bdd8",
5
5
  "layout": "vscode-only",
6
- "preparedAt": "2026-09-11T12:34:21.276Z",
6
+ "preparedAt": "2026-09-11T13:53:46.670Z",
7
7
  "source": "registry",
8
8
  "node": "v24.13.1",
9
9
  "platform": "win32",