dsh-code-server-app 0.3.56 → 0.3.58
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 +59 -14
- package/README.md +53 -14
- package/assets/extensions/dshcs-editor-bridge/webview/THIRD-PARTY.md +1 -1
- package/lib/claim-types.js +4 -2
- package/lib/client.js +2049 -4
- package/lib/index.js +2 -2
- package/package.json +3 -2
- package/vendor/VENDOR.json +1 -1
package/README.en.md
CHANGED
|
@@ -105,12 +105,24 @@ This plugin registers:
|
|
|
105
105
|
`canOpen` share that single file, shipped in the package, so the two cannot drift apart);
|
|
106
106
|
unit tests: `scripts/test-claim-types.mjs`.
|
|
107
107
|
- **How the tab body locates the file**: it parses `useTabInfo().tab.navigation.address`
|
|
108
|
-
(`
|
|
108
|
+
(`lib/client.js`, the "address grammar" section — same grammar as DSH's `parseFileAddress`), expands a workspace-relative path with that
|
|
109
109
|
session's cwd, and posts the absolute path (plus optional `line`) to the host's
|
|
110
110
|
`/api/code-server/open-file`; the bundled extension (`dshcs-open-file`) then calls `showTextDocument`
|
|
111
111
|
(positioned at the line when given).
|
|
112
|
-
- **
|
|
113
|
-
|
|
112
|
+
- **A single tab (since 0.3.57)**: DSH's own semantics are "one address = one tab" (`contentId` *is* the address —
|
|
113
|
+
same address is idempotent, a different one always opens a new tab), and `replaceTab` can only be passed by the
|
|
114
|
+
**opener** (the product's own `openFile`/`openResource`) — so the plugin instead closes the older code-server tab
|
|
115
|
+
in the same pane when a new tab's body mounts. Clicking a second file now changes the content of **the one tab**
|
|
116
|
+
(its chip title follows) instead of stacking tabs.
|
|
117
|
+
Two deliberate boundaries: (1) only **same-pane** tabs are closed — a split layout is the user's own doing, and
|
|
118
|
+
the product's convention is "one page per kind in each pane" (`SidebarRightTabDefinition.multiple`);
|
|
119
|
+
(2) only a tab that becomes visible for the first time consolidates — tab restoration/activation order is not
|
|
120
|
+
ours to control, and letting every visible tab close its siblings would ping-pong (a `ref` pins "once per mount").
|
|
121
|
+
These tabs always shared **one resident workbench** (the IDE is a single instance), so closing one never reloads
|
|
122
|
+
it: the resident iframe is owned by the "resident IDE surface" section of `lib/client.js`, and a tab is merely its docking host (`Element.moveBefore`).
|
|
123
|
+
Regression: `scripts/test-client-bundle-tabs.mjs` renders two tabs against the **entry file** and asserts the
|
|
124
|
+
old one is closed, the new one stays, other panes/hidden tabs are untouched, and an old DSH without `actions`
|
|
125
|
+
does not throw (negative control: dropping the consolidation call makes it FAIL).
|
|
114
126
|
- **Why the bundled extension stays**: VS Code Web has no official "open this file from outside" API (the only
|
|
115
127
|
entry is `?folder=`, which picks the workspace), so aiming the workbench at a file has to be done by an
|
|
116
128
|
extension inside the tree. The host writes a signal file, the extension polls it and calls
|
|
@@ -123,7 +135,7 @@ This plugin registers:
|
|
|
123
135
|
iframe out of the document and destroys its browsing context; switching back is a full VS Code reload (unsaved buffers
|
|
124
136
|
lost). Floating the tab into its own panel only worked around it.
|
|
125
137
|
|
|
126
|
-
**What it does now (
|
|
138
|
+
**What it does now (the resident-surface section of `lib/client.js`, 0.2.2)**: the plugin takes the iframe **away from React** and turns
|
|
127
139
|
it into a **singleton resident surface**:
|
|
128
140
|
|
|
129
141
|
| Situation | Action | Result |
|
|
@@ -392,8 +404,8 @@ Diagnostics: `GET /api/code-server/status` exposes
|
|
|
392
404
|
- 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
|
|
393
405
|
(resolution order: current session cwd → session's `workspace.path` → workspace of the most recently active session → first workspace.path;
|
|
394
406
|
**where "the current session" comes from depends on the DSH version**: ≥ 0.1.6-alpha.2 reads the session-scoped standard prop `sessionId`,
|
|
395
|
-
≤ 0.1.6-alpha.1 falls back to `current` on the session-list snapshot — see the 0.3.48 bullet below; the logic
|
|
396
|
-
and the contract for both shapes is pinned by `scripts/test-client-bundle-cwd.mjs` directly against the
|
|
407
|
+
≤ 0.1.6-alpha.1 falls back to `current` on the session-list snapshot — see the 0.3.48 bullet below; the logic is inlined in `lib/client.js`
|
|
408
|
+
(the "workspace resolution" section) and the contract for both shapes is pinned by `scripts/test-client-bundle-cwd.mjs` directly against the entry file);
|
|
397
409
|
the opened directory is shown inside code-server (`?folder=<cwd>`, the page reloads when following a switch);
|
|
398
410
|
implementation note: the iframe `src` must carry `?folder=<cwd>` — code-server's front-end remembers the "last workspace" and restores it by itself;
|
|
399
411
|
a bare root URL only shows the previously opened directory and does not follow switches (verified locally).
|
|
@@ -425,8 +437,8 @@ Diagnostics: `GET /api/code-server/status` exposes
|
|
|
425
437
|
- 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),
|
|
426
438
|
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;
|
|
427
439
|
- `node_modules` and the pack-time artifact `vendor/` are git-ignored; after cloning, follow
|
|
428
|
-
"Install the plugin (script-free install; code-server bundled)" below — `pnpm install` → `pnpm run
|
|
429
|
-
`pnpm run
|
|
440
|
+
"Install the plugin (script-free install; code-server bundled)" below — `pnpm install` → `pnpm run vendor:vscode` →
|
|
441
|
+
`pnpm run build:webview` → `pnpm pack` + `dsh plugin --profile web add` (the client half has no build step).
|
|
430
442
|
|
|
431
443
|
> Verified locally (BM: Windows 11 ARM64): the whole tree/dependency chain hangs directly off the plugin's
|
|
432
444
|
> dependency table — the tree package `@jinsiyu/dshcs-vscode-server` (currently 4.137.0, a 50.8 MB tarball),
|
|
@@ -441,7 +453,6 @@ Diagnostics: `GET /api/code-server/status` exposes
|
|
|
441
453
|
```powershell
|
|
442
454
|
cd C:\Users\User\Desktop\dsh-code-server-app
|
|
443
455
|
pnpm install # dev deps (esbuild + the official-renderer bundling deps); allowBuilds is explicit → no postinstall runs
|
|
444
|
-
pnpm run build:client # src/factory.js → lib/client.js (not committed; must be built first)
|
|
445
456
|
pnpm run build:webview # ask panel: official Markdown renderer + panel shell → webview/thread.{js,css} (not committed; must be built first)
|
|
446
457
|
pnpm run vendor:check # optional: show the bundled tree version vs the latest code-server release
|
|
447
458
|
pnpm run vendor:vscode # ① produce vendor/vscode (the trimmed VS Code tree, ~197MB)
|
|
@@ -502,7 +513,7 @@ Both workflows live in `.github/workflows/`, and the regression list exists exac
|
|
|
502
513
|
|
|
503
514
|
| Workflow | Trigger | What it does |
|
|
504
515
|
|---|---|---|
|
|
505
|
-
| `ci.yml` | push to `main` / PR / manual | `ubuntu-latest` + `windows-latest` matrix: `pnpm install --frozen-lockfile` → `build:
|
|
516
|
+
| `ci.yml` | push to `main` / PR / manual | `ubuntu-latest` + `windows-latest` matrix: `pnpm install --frozen-lockfile` → `build:webview` → `pnpm test` (the whole suite) → `vendor:check` (report only) → upload the panel assets |
|
|
506
517
|
| `release.yml` | push a `v<version>` tag / manual (rehearsal, never publishes) | prepares `vendor/vscode` **at the version pinned in `dependencies`** → builds → full suite → `pnpm pack` → verifies the tarball manifest → **really installs it twice** (windows-latest proves the 16 win32 sub-packages, ubuntu-latest the 10 Linux ones: each deploys a real DSH, installs via the official path `dsh plugin --profile web add <tgz>`, then runs the `test:installed` + `dump-config` assertions; both legs must pass before anything is published) → publishes to npm **`next`** → creates a GitHub Release with the tgz attached |
|
|
507
518
|
| `linux-repack-probe.yml` | push to this file / manual | **feasibility probe (never publishes; superseded by the Linux legs of `repacks.yml`)**: on Linux, builds the platform-specific repack packages per target (`linux-x64` → `ubuntu-latest`, `linux-arm64` → `ubuntu-24.04-arm`) and reports which modules really produce a `.node` and which are Windows-only. It runs the existing `vendor-repacks.mjs` itself; all writes happen in a copy of the repo under `$RUNNER_TEMP`. **Note**: it emits one notice per module, which hits GitHub's ~20-annotations-per-check-run cap and leaves only the tail; for the full verdict use the Linux legs of `repacks.yml` (one summary line per target) |
|
|
508
519
|
| `repacks.yml` | manual (`publish` and `probe_oidc` both default to **false**, the four `build_*` legs default to **true**) / push to this file / push `.github/oidc-probe.enabled` | **builds and publishes the platform-specific sub-packages** (`@jinsiyu/dshcs-*`): one host-architecture runner per target (`win32-x64` → `windows-latest`, `win32-arm64` → `windows-11-arm`, `linux-x64` → `ubuntu-latest`, `linux-arm64` → `ubuntu-24.04-arm`); by default it only builds and uploads `repack/tgz/*.tgz`, and only publishes to npm (default `next`) when `publish` is checked. Ownership and ordering (**five legs, disjoint sets**): the `independent` leg runs **first** (windows-latest; it produces the **VS Code tree package + the 8 platform-independent repacks**, which are the same artifact for all four targets and are therefore published only once); the four platform-specific legs `needs: independent`, build with `--skip-independent` and publish with `--only <their own target>` ⇒ a broken base layer blocks the rest (no half-published state) and no package name is ever published twice. **Auth**: with no `NPM_TOKEN` it uses OIDC (per-package trust entries, all with workflow `repacks.yml` — see below). The Linux legs additionally verify that the `lib/vendored.json` / `package.json` they generate match the committed ones (the platform policy is meant to be host-independent). A `probe-oidc` job additionally does a **staged-only** probe of that OIDC route, so the channel can be proven without publishing anything real |
|
|
@@ -605,6 +616,11 @@ pnpm test:bridge-extension # extension-side pure logic (dirty buffers, diagnos
|
|
|
605
616
|
pnpm test:webview # panel bundle: official renderer + tokens, version match, the four /approve constraints
|
|
606
617
|
pnpm test:launcher-routes # launcher HTTP surface (spawns a real process; slow)
|
|
607
618
|
pnpm test:workspace-switch # switching workspaces does not restart the process
|
|
619
|
+
pnpm test:workspace-cwd # "current workspace directory" resolution (DSH 0.1.6-alpha.2 sessionId vs. the older current)
|
|
620
|
+
pnpm test:client-cwd # the same contract, but asserted against the **client entry** lib/client.js
|
|
621
|
+
pnpm test:client-tabs # "one code-server tab on the DSH side": a new tab closes the old one in the same pane
|
|
622
|
+
pnpm test:client-entry # client-entry guard: classic script + factory wrapper, require whitelist, src/ gone, parity with lib/claim-types.js
|
|
623
|
+
pnpm test:client-seat # which seat the settings card uses: plugins.bundle.config (DSH ≥ 0.1.6-alpha.2) vs settings.plugin.item (≤ alpha.1)
|
|
608
624
|
pnpm test:fullscreen # opening the tab goes fullscreen
|
|
609
625
|
pnpm test:vendored # repack table ↔ plugin dependency table (no npm: aliases, no aggregator)
|
|
610
626
|
pnpm test:installed # install smoke: assert on what was **installed into a profile**
|
|
@@ -825,6 +841,33 @@ The main package is only **~110KB** (the plugin's own code plus the launcher); e
|
|
|
825
841
|
> `serve: loopback`, which behaves exactly like 0.1.43**; switch to `serve: dsh` for same-origin mounting. The install
|
|
826
842
|
> command is unchanged (`dsh plugin --profile web add dsh-code-server-app@<version>`), and pnpm drops the old
|
|
827
843
|
> `dshcs-code-server` sub-package.
|
|
844
|
+
### Why the client half has no build step (since 0.3.58)
|
|
845
|
+
|
|
846
|
+
**`lib/client.js` *is* the source** — hand-written, committed, not minified. What was removed: `src/**`
|
|
847
|
+
(five ES modules), `scripts/build-client.mjs`, `client.banner.js` / `client.footer.js`, and the
|
|
848
|
+
`build:client` step in `prepack`/CI/release.
|
|
849
|
+
|
|
850
|
+
Why it can go away: DSH loads the client entry as a classic `<script src>` (`/plugins/<pkg>/client.js`), so it
|
|
851
|
+
**must be one file** in the `window.__ModuleLoader__.load({id, factory})` shape (no ES modules; package-local
|
|
852
|
+
splitting would need `require.async('client.*.js')`, which this plugin does not use). If the artifact can only be
|
|
853
|
+
a single file, it may as well be the source: no intermediate artifact, no bundler, and no "I forgot to rebuild".
|
|
854
|
+
|
|
855
|
+
Costs and rules (read before editing `lib/client.js`):
|
|
856
|
+
|
|
857
|
+
| Rule | Why | Enforced by |
|
|
858
|
+
|---|---|---|
|
|
859
|
+
| No top-level `import`/`export`/`await` | syntax errors in a classic script ⇒ the whole client half fails to load (empty UI) | `pnpm test:client-entry` E1 + the harness really loading it (E3) |
|
|
860
|
+
| `require(...)` may only name `react` / `react/jsx-runtime` | the DSH module table is frozen; anything else throws "unknown module" | E1 |
|
|
861
|
+
| Every section's top-level identifiers share one scope | after inlining, a `var`/`function` collision is a **silent overwrite** (real hit: `state` existed in both the surface and the plugin body — the former is now `surfaceState`) | no automatic guard ⇒ grep before adding a top-level name |
|
|
862
|
+
| The claim-types section is a **copy** | a classic script cannot reach the host module `lib/claim-types.js` | E2 compares both over a sample table |
|
|
863
|
+
|
|
864
|
+
Size: ~114 KB uncompressed (was a 49.7 KB minified artifact) — a one-time download; the rev/caching mechanism is
|
|
865
|
+
unchanged. Test hook: the entry exports `__internals` only when `window.__dshcsTestHooks === true` (used by
|
|
866
|
+
`test-workspace-cwd.mjs` / `test-sidebar-fullscreen.mjs` to call pure functions); DSH never sets that flag.
|
|
867
|
+
|
|
868
|
+
> The ask-panel webview is **still a build artifact** (`thread.{js,css}` is untracked and produced by
|
|
869
|
+
> `pnpm run build:webview`); removing that build is the next phase.
|
|
870
|
+
|
|
828
871
|
### Development: install from source (changes take effect immediately)
|
|
829
872
|
|
|
830
873
|
```powershell
|
|
@@ -836,11 +879,13 @@ dsh plugin --profile web add C:\Users\User\Desktop\dsh-code-server-app
|
|
|
836
879
|
> too — but the not-yet-published local `@jinsiyu/*` packages must either be published first, or the
|
|
837
880
|
> `repack/tgz/*.tgz` files must be installed into the profile as `file:` dependencies.
|
|
838
881
|
>
|
|
839
|
-
> **Changing the client
|
|
840
|
-
>
|
|
882
|
+
> **Changing the client half**: edit `lib/client.js` directly (since 0.3.58 it is **hand-written source** —
|
|
883
|
+
> there is no build step and no `src/**` intermediate layer; the format rules are in that file's header and are
|
|
884
|
+
> enforced by `pnpm test:client-entry`). After installing into a profile a hard refresh picks it up
|
|
885
|
+
> (a host restart may be needed; the bundle rev is hashed at host start).
|
|
841
886
|
> **Changing the ask panel**: edit `assets/extensions/dshcs-editor-bridge/webview/src/*` then run
|
|
842
|
-
> `pnpm run build:webview` (
|
|
843
|
-
> because the extension host caches the webview resources).
|
|
887
|
+
> `pnpm run build:webview` (this half is still a generated artifact, not tracked; the IDE must be restarted once
|
|
888
|
+
> to pick it up, because the extension host caches the webview resources).
|
|
844
889
|
|
|
845
890
|
### Pack-machine environment (the user machine needs nothing)
|
|
846
891
|
|
package/README.md
CHANGED
|
@@ -116,11 +116,21 @@ DSH 用**资源地址**命名文件,`openFile` 只负责把地址交给右侧栏
|
|
|
116
116
|
- 语法、默认值与解析都在 `lib/claim-types.js`(host 的 `Config` 默认值与客户端 `canOpen` 共用同一份,
|
|
117
117
|
随包发布,不会两边漂移);单测 `scripts/test-claim-types.mjs`。
|
|
118
118
|
- **tab body 怎么定位文件**:从 `useTabInfo().tab.navigation.address` 解析出会话与路径
|
|
119
|
-
(`
|
|
119
|
+
(`lib/client.js` 的"地址语法"段,与 DSH `parseFileAddress` 同语义),相对路径按该会话 cwd 展开成绝对路径,
|
|
120
120
|
再把绝对路径 + 可选 `line` 交给 host 的 `/api/code-server/open-file`;内建扩展
|
|
121
121
|
(`dshcs-open-file`)在 workbench 里 `showTextDocument`(带行号时定位到该行)。
|
|
122
|
-
-
|
|
123
|
-
|
|
122
|
+
- **只留一个 tab(0.3.57 起)**:官方语义本是"一个地址 = 一个 tab"(`contentId` 就是地址:同址幂等、
|
|
123
|
+
异址必新开),而 `replaceTab` 只有**发起方**(产品自己的 `openFile`/`openResource`)能传 ——
|
|
124
|
+
所以插件改成:新 tab 的 body 挂载时**把同窗格里旧的 code-server tab 关掉**。
|
|
125
|
+
于是连点两个文件时,你看到的是**同一个 tab 在换内容**(chip 标题跟着变),而不是越开越多。
|
|
126
|
+
两条刻意留的边界:① 只收**同窗格**的 —— 多窗格是用户主动切分的布局,官方自己也是"每窗格一份"
|
|
127
|
+
(`SidebarRightTabDefinition.multiple` 的注释:"one page per kind in each pane");
|
|
128
|
+
② 只有"首次可见"的那个新 tab 负责收 —— 标签页恢复/激活顺序不可控,若每个可见的都收别人,
|
|
129
|
+
关掉一个会让下一个变可见,互相收成乒乓(用 ref 钉住"每次挂载只收一次")。
|
|
130
|
+
这些 tab 本来就共用**同一个常驻 workbench**(IDE 是单实例),关掉一个不会重载它:
|
|
131
|
+
常驻 iframe 由 `lib/client.js` 的"常驻 IDE 面"段持有,tab 只是它的停靠宿主(`Element.moveBefore`)。
|
|
132
|
+
回归:`scripts/test-client-bundle-tabs.mjs` —— 对**入口**渲染两个 tab,断言旧的被关、新的还在、
|
|
133
|
+
跨窗格不动、不可见时不动、缺 `actions` 的老 DSH 也不崩(负向对照:摘掉合并调用 → 该用例 FAIL)。
|
|
124
134
|
- **为什么还留着那个内建扩展**:VS Code Web 没有"从外部打开文件"的官方 API(唯一入口是
|
|
125
135
|
`?folder=` 指定工作区),所以"让 workbench 定位到某个文件"只能由树内的扩展完成;
|
|
126
136
|
host 写信号文件、扩展轮询并 `showTextDocument`,失败保留重试(实例尚未就绪时也不会丢)。
|
|
@@ -132,7 +142,7 @@ DSH 用**资源地址**命名文件,`openFile` 只负责把地址交给右侧栏
|
|
|
132
142
|
浏览上下文销毁,切回来就是一次完整的 VS Code 重载(未保存的缓冲区丢失)。把标签浮动成独立面板只是绕开它,
|
|
133
143
|
并没有解决。
|
|
134
144
|
|
|
135
|
-
**现在的做法(客户端 `
|
|
145
|
+
**现在的做法(客户端 `lib/client.js` 的常驻面段,0.2.2)**:插件把 iframe **从 React 手里接管**,做成**单例常驻面**:
|
|
136
146
|
|
|
137
147
|
| 场景 | 动作 | 结果 |
|
|
138
148
|
|---|---|---|
|
|
@@ -371,8 +381,8 @@ seq,并且 `/sync` 回应里带 `lastSeq`(高水位),扩展据此自查游标是
|
|
|
371
381
|
- code-server 服务目录**跟随活动工作区/会话**:打开期间切换 DSH 会话/工作区,code-server 自动切到新目录
|
|
372
382
|
(解析优先级:当前会话 cwd → 会话所属 `workspace.path` → 最近活跃会话所属 workspace → 首个 workspace.path;
|
|
373
383
|
**"当前会话"的信源随 DSH 版本而变**:≥ 0.1.6-alpha.2 读会话作用域标准 prop `sessionId`,
|
|
374
|
-
≤ 0.1.6-alpha.1 退回会话列表快照上的 `current` —— 详见下面 0.3.48
|
|
375
|
-
|
|
384
|
+
≤ 0.1.6-alpha.1 退回会话列表快照上的 `current` —— 详见下面 0.3.48 那条;纯逻辑内联在 `lib/client.js`
|
|
385
|
+
的"工作区解析"段,两版形状的契约由 `scripts/test-client-bundle-cwd.mjs` 直接对**入口**钉住);
|
|
376
386
|
打开目录显示在 code-server 页面内(`?folder=<cwd>`,跟随切换时页面自动重新加载);
|
|
377
387
|
实现要点:iframe src 必须带 `?folder=<cwd>`——code-server 前端会记住“最近工作区”并自行恢复,
|
|
378
388
|
仅用裸根 URL 只会显示上一次打开的目录、不会跟随切换(本机实测确认)。
|
|
@@ -399,8 +409,8 @@ seq,并且 `/sync` 回应里带 `lastSeq`(高水位),扩展据此自查游标是
|
|
|
399
409
|
- process 生命周期由 host 插件管理:启动写 `$DSH_HOME/code-server/pid.json`,停止树级终止(taskkill /T 或进程组 SIGKILL),
|
|
400
410
|
崩溃/退出实时更新状态;DSH host 重启后自动 adopt 仍在运行的实例(校验 pid + /healthz),不重复启动、不误杀别的进程;
|
|
401
411
|
- `node_modules`、`vendor/` 与 `repack/` 已被 `.gitignore` 排除,推送/克隆仓库后按下方
|
|
402
|
-
"打包(如何出包)"执行 `pnpm install` → `pnpm run
|
|
403
|
-
(发布预编译原生包)→ `pnpm pack` + `dsh plugin --profile web add`
|
|
412
|
+
"打包(如何出包)"执行 `pnpm install` → `pnpm run vendor:vscode` → `pnpm run build:webview` →
|
|
413
|
+
(发布预编译原生包)→ `pnpm pack` + `dsh plugin --profile web add` 即可(客户端半部不再有构建步骤)。
|
|
404
414
|
|
|
405
415
|
> 本机(BM: Windows 11 ARM64)实测:树/依赖全链路是"平台子包直挂插件依赖"供给 ——
|
|
406
416
|
> 树包 `@jinsiyu/dshcs-vscode-server`(当前 4.137.0,50.8 MB tgz)、纯 JS 内部依赖与 8 个平台无关
|
|
@@ -414,7 +424,6 @@ seq,并且 `/sync` 回应里带 `lastSeq`(高水位),扩展据此自查游标是
|
|
|
414
424
|
```powershell
|
|
415
425
|
cd C:\Users\User\Desktop\dsh-code-server-app
|
|
416
426
|
pnpm install # 开发依赖(esbuild + 官方渲染器打包依赖);allowBuilds 已显式声明 → 不执行任何 postinstall
|
|
417
|
-
pnpm run build:client # src/factory.js → lib/client.js(不入库,必须先构建)
|
|
418
427
|
pnpm run build:webview # 「问 DSH」面板:官方 markdown 渲染器 + 面板外壳 → webview/thread.{js,css}(不入库,必须先构建)
|
|
419
428
|
pnpm run vendor:check # 可选:查看内置 VS Code 树版本 vs code-server 最新版
|
|
420
429
|
pnpm run vendor:vscode # ① 生成 vendor/vscode(精简 VS Code 树,≈197MB)
|
|
@@ -490,7 +499,9 @@ pnpm test:webview # 面板 webview 产物:官方渲染器与令牌打
|
|
|
490
499
|
pnpm test:launcher-routes # launcher 的 HTTP 面(起真进程,较慢)
|
|
491
500
|
pnpm test:workspace-switch # 切工作区不重启进程
|
|
492
501
|
pnpm test:workspace-cwd # "当前工作区目录"解析:DSH 0.1.6-alpha.2(sessionId)与旧版(current)两套形状
|
|
493
|
-
pnpm test:client-cwd #
|
|
502
|
+
pnpm test:client-cwd # 同一件事但直接对**客户端入口** lib/client.js 验(注册出来的 body 真发不发 cwd、URL 带不带 folder)
|
|
503
|
+
pnpm test:client-tabs # "DSH 侧只留一个 code-server 标签页":新标签挂载时收掉同窗格旧标签(跨窗格/不可见时不动)
|
|
504
|
+
pnpm test:client-entry # 客户端入口守卫:经典脚本+工厂包装、require 白名单、src/ 已消失、与 lib/claim-types.js 逐字一致
|
|
494
505
|
pnpm test:client-seat # 设置卡住哪个座位:插件页 plugins.bundle.config(DSH ≥ 0.1.6-alpha.2)vs settings.plugin.item(≤ alpha.1;新版已退役)
|
|
495
506
|
pnpm test:fullscreen # 打开标签即全屏
|
|
496
507
|
pnpm test:vendored # 重打包表 ↔ 插件依赖表一致(无 npm: 别名 / 无聚合包 / vendored.json 进了 files)
|
|
@@ -525,7 +536,7 @@ pnpm test:installed # 安装冒烟:对**已装进 profile 的产物**
|
|
|
525
536
|
|
|
526
537
|
| 工作流 | 触发 | 做什么 |
|
|
527
538
|
|---|---|---|
|
|
528
|
-
| `ci.yml` | push `main` / PR / 手动 | `ubuntu-latest` + `windows-latest` 双平台:`pnpm install --frozen-lockfile` → `build:
|
|
539
|
+
| `ci.yml` | push `main` / PR / 手动 | `ubuntu-latest` + `windows-latest` 双平台:`pnpm install --frozen-lockfile` → `build:webview` → `pnpm test`(全套回归)→ `vendor:check` 只报告版本差 → 上传面板产物 |
|
|
529
540
|
| `release.yml` | 推 `v<version>` 标签 / 手动(演练,不发布) | 按 `dependencies` 钉的版本准备 `vendor/vscode` → 构建 → 全套回归 → `pnpm pack` → 校验 tarball 清单 → **真装两遍**(windows-latest 验 win32 的 16 个子包、ubuntu-latest 验 Linux 的 10 个:各部署一份真 DSH,走官方路径 `dsh plugin --profile web add <tgz>`,再跑 `test:installed` + `dump-config` 断言;两条腿都过才允许发布)→ 发 npm **`next`** → 建 GitHub Release(附 tgz) |
|
|
530
541
|
| `repacks.yml` | 手动(`publish` / `probe_oidc` 默认 **false**,四条腿的 `build_*` 默认 **true**)/ push 本文件 / push `.github/oidc-probe.enabled` | **平台专属子包(`@jinsiyu/dshcs-*`)的构建与发布**:同架构宿主 runner 各打一条(`win32-x64` → `windows-latest`、`win32-arm64` → `windows-11-arm`、`linux-x64` → `ubuntu-latest`、`linux-arm64` → `ubuntu-24.04-arm`),默认只构建 + 传 `repack/tgz/*.tgz`(**不发布**,所以它同时就是 Linux 可行性验证的正式位置);勾上 `publish` 才发 npm(默认 `next`)。发布归属与顺序(**五条腿、集合不相交**):**先跑** `independent`(windows-latest,产 **VS Code 树包 + 8 个平台无关重打包包** —— 它们在四个目标上是同一份产物,所以只发这一次);四条平台专属腿 `needs: independent`、构建带 `--skip-independent`、发布带 `--only <自己的目标>` ⇒ 基础层出问题时后面不会发出"半套"子包,也不会有人重复发同一个包名。**认证**:没配 `NPM_TOKEN` 就走 OIDC(per-package Trusted Publisher,workflow 都填 `repacks.yml`,见下)。Linux 腿还会顺带校验「Linux 上生成的 `lib/vendored.json` / `package.json` 与仓库里的一致」(平台政策应当宿主无关)。额外有一个 `probe-oidc` job:对几个真实子包名做**只暂存、不发正式版**的巡检,用来证明这条 OIDC 通道真的可用 |
|
|
531
542
|
|
|
@@ -803,6 +814,33 @@ dsh plugin --profile web add C:\Users\User\Desktop\dsh-code-server-app\dsh-code-
|
|
|
803
814
|
|
|
804
815
|
> 安装/依赖变化后请**重启 `dsh web`**(静态插件行与 host 探测路径在启动时加载)。
|
|
805
816
|
|
|
817
|
+
### 客户端半部为什么没有构建步骤(0.3.58 起)
|
|
818
|
+
|
|
819
|
+
**`lib/client.js` 就是源码** —— 手写、入库、不压缩。删掉的东西:`src/**`(5 个 ES 模块)、
|
|
820
|
+
`scripts/build-client.mjs`、`client.banner.js` / `client.footer.js`,以及 `prepack`/CI/release 里的
|
|
821
|
+
`build:client` 步骤。
|
|
822
|
+
|
|
823
|
+
为什么可以去构建:DSH 用经典 `<script src>` 加载客户端入口(`/plugins/<包名>/client.js`),它**只能是**
|
|
824
|
+
一个文件、且必须是 `window.__ModuleLoader__.load({id, factory})` 形态(不能是 ES module;包内分块只能
|
|
825
|
+
`require.async('client.*.js')`,本插件用不到)。既然产物只能是单文件,就把它当源码维护 ——
|
|
826
|
+
没有中间产物、没有构建器、也不会"忘了重建"。
|
|
827
|
+
|
|
828
|
+
代价与约束(改 `lib/client.js` 前先读):
|
|
829
|
+
|
|
830
|
+
| 约束 | 为什么 | 谁守着 |
|
|
831
|
+
|---|---|---|
|
|
832
|
+
| 顶层不许 `import`/`export`/`await` | 经典脚本里它们是语法错误 ⇒ 整个客户端半部不加载(界面全空) | `pnpm test:client-entry` 的 E1 + harness 真加载(E3) |
|
|
833
|
+
| `require(...)` 只允许 `react` / `react/jsx-runtime` | DSH 冻结模块表,别的会抛"未知模块" | E1 |
|
|
834
|
+
| 各段落的顶层标识符共享同一作用域 | 内联后 `var`/`function` 撞名是**静默覆盖**(实测:`surface.js` 与 `factory.js` 都叫 `state`,已把前者改名为 `surfaceState`) | 无自动守卫 ⇒ 新增顶层名字前先搜一遍 |
|
|
835
|
+
| `lib/claim-types.js` 的那份是**副本** | 客户端拿不到 host 模块(经典脚本 + 冻结模块表) | E2 逐字比对四组样例 |
|
|
836
|
+
|
|
837
|
+
体积:未压缩 ~114 KB(原压缩产物 49.7 KB)—— 一次下载、rev 机制与缓存策略不变。
|
|
838
|
+
测试钩子:入口在 `window.__dshcsTestHooks === true` 时额外导出 `__internals`(供
|
|
839
|
+
`test-workspace-cwd.mjs` / `test-sidebar-fullscreen.mjs` 直接调纯函数),DSH 永不设置该标志。
|
|
840
|
+
|
|
841
|
+
> 面板 webview 的产物**仍是构建产物**(`thread.{js,css}` 不入库、`pnpm run build:webview`),
|
|
842
|
+
> 它的"去构建"排在下一期。
|
|
843
|
+
|
|
806
844
|
### 开发期:源码目录安装(改动即时生效)
|
|
807
845
|
|
|
808
846
|
```powershell
|
|
@@ -814,10 +852,11 @@ dsh plugin --profile web add C:\Users\User\Desktop\dsh-code-server-app
|
|
|
814
852
|
> 依赖(内部 JS 依赖 + 重打包子包)同样由 pnpm 安装 —— 本地未发布的 `@jinsiyu/*` 需先发布,
|
|
815
853
|
> 或把 `repack/tgz/*.tgz` 以 `file:` 依赖临时装进 profile(见 `.tmp-verify.mjs`)。
|
|
816
854
|
>
|
|
817
|
-
>
|
|
818
|
-
>
|
|
855
|
+
> **改动客户端半部**:直接编辑 `lib/client.js`(0.3.58 起它是**手写源码**,不再有构建步骤、
|
|
856
|
+
> 也没有 `src/**` 中间层;格式约束见该文件头部注释,`pnpm test:client-entry` 守着它们)。
|
|
857
|
+
> 装进 profile 后浏览器硬刷即生效(必要时重启 host;产物 rev 在宿主启动时算好)。
|
|
819
858
|
> **改动提问面板**:编辑 `assets/extensions/dshcs-editor-bridge/webview/src/*` 后执行
|
|
820
|
-
> `pnpm run build:webview`(
|
|
859
|
+
> `pnpm run build:webview`(这一半仍是构建产物、不入库;IDE 需重启一次才会加载新产物,扩展宿主会缓存 webview 资源)。
|
|
821
860
|
|
|
822
861
|
### 打包机环境要求(使用者机器什么都不需要)
|
|
823
862
|
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
| react | 18.3.1 | MIT |
|
|
13
13
|
| react-dom | 18.3.1 | MIT |
|
|
14
14
|
|
|
15
|
-
生成时间:2026-09-
|
|
15
|
+
生成时间:2026-09-20T14:00:30.980Z
|
|
16
16
|
渲染器:@deepseek-ai/dsh-client-ui-primitives@0.1.6-alpha.1(DSH 部署的界面版本:未知)
|
|
17
17
|
设计令牌:@deepseek-ai/dsh-client-ui-theme@0.1.6-alpha.1(11 段)
|
|
18
18
|
KaTeX:已打包(公式排版与 DSH 界面一致)
|
package/lib/claim-types.js
CHANGED
|
@@ -12,8 +12,10 @@
|
|
|
12
12
|
* !md 不认领 .md(排除优先于认领)
|
|
13
13
|
* 空文本 = 不认领任何文件类型(只保留页面 tab,文件点击全部落回 DSH 预览)。
|
|
14
14
|
*
|
|
15
|
-
* 本模块是 host(`lib/index.js` 的 Config
|
|
16
|
-
*
|
|
15
|
+
* 本模块是 host(`lib/index.js` 的 Config 默认值与工具实现)的**事实来源**,随 npm 包一起发布
|
|
16
|
+
* (见 package.json 的 files),避免两边默认值漂移。
|
|
17
|
+
* 客户端半部 `lib/client.js` 里有一份**内联副本**(经典脚本拿不到 host 模块,见那个文件的
|
|
18
|
+
* "认领类型"段),两份逐字等价由 scripts/test-client-entry.mjs 的 E2 守卫钉住 —— 改这里必须同步改那边。
|
|
17
19
|
* 纯字符串逻辑,不碰文件系统 → 可离线单测(scripts/test-claim-types.mjs)。
|
|
18
20
|
*/
|
|
19
21
|
|