dsh-code-server-app 0.3.57 → 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 CHANGED
@@ -105,7 +105,7 @@ 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
- (`src/address.js`, same grammar as DSH's `parseFileAddress`), expands a workspace-relative path with that
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).
@@ -119,8 +119,8 @@ This plugin registers:
119
119
  (2) only a tab that becomes visible for the first time consolidates — tab restoration/activation order is not
120
120
  ours to control, and letting every visible tab close its siblings would ping-pong (a `ref` pins "once per mount").
121
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 `src/surface.js`, and a tab is merely its docking host (`Element.moveBefore`).
123
- Regression: `scripts/test-client-bundle-tabs.mjs` renders two tabs against the **built bundle** and asserts the
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
124
  old one is closed, the new one stays, other panes/hidden tabs are untouched, and an old DSH without `actions`
125
125
  does not throw (negative control: dropping the consolidation call makes it FAIL).
126
126
  - **Why the bundled extension stays**: VS Code Web has no official "open this file from outside" API (the only
@@ -135,7 +135,7 @@ This plugin registers:
135
135
  iframe out of the document and destroys its browsing context; switching back is a full VS Code reload (unsaved buffers
136
136
  lost). Floating the tab into its own panel only worked around it.
137
137
 
138
- **What it does now (`src/surface.js` in the client, 0.2.2)**: the plugin takes the iframe **away from React** and turns
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
139
139
  it into a **singleton resident surface**:
140
140
 
141
141
  | Situation | Action | Result |
@@ -404,8 +404,8 @@ Diagnostics: `GET /api/code-server/status` exposes
404
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
405
405
  (resolution order: current session cwd → session's `workspace.path` → workspace of the most recently active session → first workspace.path;
406
406
  **where "the current session" comes from depends on the DSH version**: ≥ 0.1.6-alpha.2 reads the session-scoped standard prop `sessionId`,
407
- ≤ 0.1.6-alpha.1 falls back to `current` on the session-list snapshot — see the 0.3.48 bullet below; the logic lives in `src/workspace.js`
408
- and the contract for both shapes is pinned by `scripts/test-client-bundle-cwd.mjs` directly against the built bundle);
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);
409
409
  the opened directory is shown inside code-server (`?folder=<cwd>`, the page reloads when following a switch);
410
410
  implementation note: the iframe `src` must carry `?folder=<cwd>` — code-server's front-end remembers the "last workspace" and restores it by itself;
411
411
  a bare root URL only shows the previously opened directory and does not follow switches (verified locally).
@@ -437,8 +437,8 @@ Diagnostics: `GET /api/code-server/status` exposes
437
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),
438
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;
439
439
  - `node_modules` and the pack-time artifact `vendor/` are git-ignored; after cloning, follow
440
- "Install the plugin (script-free install; code-server bundled)" below — `pnpm install` → `pnpm run build:client` →
441
- `pnpm run vendor:vscode` → `pnpm pack` + `dsh plugin --profile web add`.
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).
442
442
 
443
443
  > Verified locally (BM: Windows 11 ARM64): the whole tree/dependency chain hangs directly off the plugin's
444
444
  > dependency table — the tree package `@jinsiyu/dshcs-vscode-server` (currently 4.137.0, a 50.8 MB tarball),
@@ -453,7 +453,6 @@ Diagnostics: `GET /api/code-server/status` exposes
453
453
  ```powershell
454
454
  cd C:\Users\User\Desktop\dsh-code-server-app
455
455
  pnpm install # dev deps (esbuild + the official-renderer bundling deps); allowBuilds is explicit → no postinstall runs
456
- pnpm run build:client # src/factory.js → lib/client.js (not committed; must be built first)
457
456
  pnpm run build:webview # ask panel: official Markdown renderer + panel shell → webview/thread.{js,css} (not committed; must be built first)
458
457
  pnpm run vendor:check # optional: show the bundled tree version vs the latest code-server release
459
458
  pnpm run vendor:vscode # ① produce vendor/vscode (the trimmed VS Code tree, ~197MB)
@@ -514,7 +513,7 @@ Both workflows live in `.github/workflows/`, and the regression list exists exac
514
513
 
515
514
  | Workflow | Trigger | What it does |
516
515
  |---|---|---|
517
- | `ci.yml` | push to `main` / PR / manual | `ubuntu-latest` + `windows-latest` matrix: `pnpm install --frozen-lockfile` → `build:client` → `build:webview` → `pnpm test` (the whole suite) → `vendor:check` (report only) → upload `lib/client.js` and the panel assets |
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 |
518
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 |
519
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) |
520
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 |
@@ -617,6 +616,11 @@ pnpm test:bridge-extension # extension-side pure logic (dirty buffers, diagnos
617
616
  pnpm test:webview # panel bundle: official renderer + tokens, version match, the four /approve constraints
618
617
  pnpm test:launcher-routes # launcher HTTP surface (spawns a real process; slow)
619
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)
620
624
  pnpm test:fullscreen # opening the tab goes fullscreen
621
625
  pnpm test:vendored # repack table ↔ plugin dependency table (no npm: aliases, no aggregator)
622
626
  pnpm test:installed # install smoke: assert on what was **installed into a profile**
@@ -837,6 +841,33 @@ The main package is only **~110KB** (the plugin's own code plus the launcher); e
837
841
  > `serve: loopback`, which behaves exactly like 0.1.43**; switch to `serve: dsh` for same-origin mounting. The install
838
842
  > command is unchanged (`dsh plugin --profile web add dsh-code-server-app@<version>`), and pnpm drops the old
839
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
+
840
871
  ### Development: install from source (changes take effect immediately)
841
872
 
842
873
  ```powershell
@@ -848,11 +879,13 @@ dsh plugin --profile web add C:\Users\User\Desktop\dsh-code-server-app
848
879
  > too — but the not-yet-published local `@jinsiyu/*` packages must either be published first, or the
849
880
  > `repack/tgz/*.tgz` files must be installed into the profile as `file:` dependencies.
850
881
  >
851
- > **Changing the client bundle**: edit `src/factory.js` then run `pnpm run build:client`
852
- > to regenerate `lib/client.js` (that artifact is not tracked; a browser refresh picks it up — no host restart needed).
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).
853
886
  > **Changing the ask panel**: edit `assets/extensions/dshcs-editor-bridge/webview/src/*` then run
854
- > `pnpm run build:webview` (same convention: generated, not tracked; the IDE must be restarted once to pick it up,
855
- > 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).
856
889
 
857
890
  ### Pack-machine environment (the user machine needs nothing)
858
891
 
package/README.md CHANGED
@@ -116,7 +116,7 @@ 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
- (`src/address.js`,与 DSH `parseFileAddress` 同语义),相对路径按该会话 cwd 展开成绝对路径,
119
+ (`lib/client.js` 的"地址语法"段,与 DSH `parseFileAddress` 同语义),相对路径按该会话 cwd 展开成绝对路径,
120
120
  再把绝对路径 + 可选 `line` 交给 host 的 `/api/code-server/open-file`;内建扩展
121
121
  (`dshcs-open-file`)在 workbench 里 `showTextDocument`(带行号时定位到该行)。
122
122
  - **只留一个 tab(0.3.57 起)**:官方语义本是"一个地址 = 一个 tab"(`contentId` 就是地址:同址幂等、
@@ -128,8 +128,8 @@ DSH 用**资源地址**命名文件,`openFile` 只负责把地址交给右侧栏
128
128
  ② 只有"首次可见"的那个新 tab 负责收 —— 标签页恢复/激活顺序不可控,若每个可见的都收别人,
129
129
  关掉一个会让下一个变可见,互相收成乒乓(用 ref 钉住"每次挂载只收一次")。
130
130
  这些 tab 本来就共用**同一个常驻 workbench**(IDE 是单实例),关掉一个不会重载它:
131
- 常驻 iframe 由 `src/surface.js` 持有,tab 只是它的停靠宿主(`Element.moveBefore`)。
132
- 回归:`scripts/test-client-bundle-tabs.mjs` —— 对**构建产物**渲染两个 tab,断言旧的被关、新的还在、
131
+ 常驻 iframe 由 `lib/client.js` 的"常驻 IDE 面"段持有,tab 只是它的停靠宿主(`Element.moveBefore`)。
132
+ 回归:`scripts/test-client-bundle-tabs.mjs` —— 对**入口**渲染两个 tab,断言旧的被关、新的还在、
133
133
  跨窗格不动、不可见时不动、缺 `actions` 的老 DSH 也不崩(负向对照:摘掉合并调用 → 该用例 FAIL)。
134
134
  - **为什么还留着那个内建扩展**:VS Code Web 没有"从外部打开文件"的官方 API(唯一入口是
135
135
  `?folder=` 指定工作区),所以"让 workbench 定位到某个文件"只能由树内的扩展完成;
@@ -142,7 +142,7 @@ DSH 用**资源地址**命名文件,`openFile` 只负责把地址交给右侧栏
142
142
  浏览上下文销毁,切回来就是一次完整的 VS Code 重载(未保存的缓冲区丢失)。把标签浮动成独立面板只是绕开它,
143
143
  并没有解决。
144
144
 
145
- **现在的做法(客户端 `src/surface.js`,0.2.2)**:插件把 iframe **从 React 手里接管**,做成**单例常驻面**:
145
+ **现在的做法(客户端 `lib/client.js` 的常驻面段,0.2.2)**:插件把 iframe **从 React 手里接管**,做成**单例常驻面**:
146
146
 
147
147
  | 场景 | 动作 | 结果 |
148
148
  |---|---|---|
@@ -381,8 +381,8 @@ seq,并且 `/sync` 回应里带 `lastSeq`(高水位),扩展据此自查游标是
381
381
  - code-server 服务目录**跟随活动工作区/会话**:打开期间切换 DSH 会话/工作区,code-server 自动切到新目录
382
382
  (解析优先级:当前会话 cwd → 会话所属 `workspace.path` → 最近活跃会话所属 workspace → 首个 workspace.path;
383
383
  **"当前会话"的信源随 DSH 版本而变**:≥ 0.1.6-alpha.2 读会话作用域标准 prop `sessionId`,
384
- ≤ 0.1.6-alpha.1 退回会话列表快照上的 `current` —— 详见下面 0.3.48 那条;纯逻辑在 `src/workspace.js`,
385
- 两版形状的契约由 `scripts/test-client-bundle-cwd.mjs` 直接对构建产物钉住);
384
+ ≤ 0.1.6-alpha.1 退回会话列表快照上的 `current` —— 详见下面 0.3.48 那条;纯逻辑内联在 `lib/client.js`
385
+ 的"工作区解析"段,两版形状的契约由 `scripts/test-client-bundle-cwd.mjs` 直接对**入口**钉住);
386
386
  打开目录显示在 code-server 页面内(`?folder=<cwd>`,跟随切换时页面自动重新加载);
387
387
  实现要点:iframe src 必须带 `?folder=<cwd>`——code-server 前端会记住“最近工作区”并自行恢复,
388
388
  仅用裸根 URL 只会显示上一次打开的目录、不会跟随切换(本机实测确认)。
@@ -409,8 +409,8 @@ seq,并且 `/sync` 回应里带 `lastSeq`(高水位),扩展据此自查游标是
409
409
  - process 生命周期由 host 插件管理:启动写 `$DSH_HOME/code-server/pid.json`,停止树级终止(taskkill /T 或进程组 SIGKILL),
410
410
  崩溃/退出实时更新状态;DSH host 重启后自动 adopt 仍在运行的实例(校验 pid + /healthz),不重复启动、不误杀别的进程;
411
411
  - `node_modules`、`vendor/` 与 `repack/` 已被 `.gitignore` 排除,推送/克隆仓库后按下方
412
- "打包(如何出包)"执行 `pnpm install` → `pnpm run build:client` → `pnpm run vendor:vscode` →
413
- (发布预编译原生包)→ `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` 即可(客户端半部不再有构建步骤)。
414
414
 
415
415
  > 本机(BM: Windows 11 ARM64)实测:树/依赖全链路是"平台子包直挂插件依赖"供给 ——
416
416
  > 树包 `@jinsiyu/dshcs-vscode-server`(当前 4.137.0,50.8 MB tgz)、纯 JS 内部依赖与 8 个平台无关
@@ -424,7 +424,6 @@ seq,并且 `/sync` 回应里带 `lastSeq`(高水位),扩展据此自查游标是
424
424
  ```powershell
425
425
  cd C:\Users\User\Desktop\dsh-code-server-app
426
426
  pnpm install # 开发依赖(esbuild + 官方渲染器打包依赖);allowBuilds 已显式声明 → 不执行任何 postinstall
427
- pnpm run build:client # src/factory.js → lib/client.js(不入库,必须先构建)
428
427
  pnpm run build:webview # 「问 DSH」面板:官方 markdown 渲染器 + 面板外壳 → webview/thread.{js,css}(不入库,必须先构建)
429
428
  pnpm run vendor:check # 可选:查看内置 VS Code 树版本 vs code-server 最新版
430
429
  pnpm run vendor:vscode # ① 生成 vendor/vscode(精简 VS Code 树,≈197MB)
@@ -500,7 +499,9 @@ pnpm test:webview # 面板 webview 产物:官方渲染器与令牌打
500
499
  pnpm test:launcher-routes # launcher 的 HTTP 面(起真进程,较慢)
501
500
  pnpm test:workspace-switch # 切工作区不重启进程
502
501
  pnpm test:workspace-cwd # "当前工作区目录"解析:DSH 0.1.6-alpha.2(sessionId)与旧版(current)两套形状
503
- pnpm test:client-cwd # 同一件事但直接对**构建产物** lib/client.js 验(注册出来的 body 真发不发 cwd、URL 带不带 folder;先跑 build:client)
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 逐字一致
504
505
  pnpm test:client-seat # 设置卡住哪个座位:插件页 plugins.bundle.config(DSH ≥ 0.1.6-alpha.2)vs settings.plugin.item(≤ alpha.1;新版已退役)
505
506
  pnpm test:fullscreen # 打开标签即全屏
506
507
  pnpm test:vendored # 重打包表 ↔ 插件依赖表一致(无 npm: 别名 / 无聚合包 / vendored.json 进了 files)
@@ -535,7 +536,7 @@ pnpm test:installed # 安装冒烟:对**已装进 profile 的产物**
535
536
 
536
537
  | 工作流 | 触发 | 做什么 |
537
538
  |---|---|---|
538
- | `ci.yml` | push `main` / PR / 手动 | `ubuntu-latest` + `windows-latest` 双平台:`pnpm install --frozen-lockfile` → `build:client` → `build:webview` → `pnpm test`(全套回归)→ `vendor:check` 只报告版本差 → 上传 `lib/client.js` 与面板产物 |
539
+ | `ci.yml` | push `main` / PR / 手动 | `ubuntu-latest` + `windows-latest` 双平台:`pnpm install --frozen-lockfile` → `build:webview` → `pnpm test`(全套回归)→ `vendor:check` 只报告版本差 → 上传面板产物 |
539
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) |
540
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 通道真的可用 |
541
542
 
@@ -813,6 +814,33 @@ dsh plugin --profile web add C:\Users\User\Desktop\dsh-code-server-app\dsh-code-
813
814
 
814
815
  > 安装/依赖变化后请**重启 `dsh web`**(静态插件行与 host 探测路径在启动时加载)。
815
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
+
816
844
  ### 开发期:源码目录安装(改动即时生效)
817
845
 
818
846
  ```powershell
@@ -824,10 +852,11 @@ dsh plugin --profile web add C:\Users\User\Desktop\dsh-code-server-app
824
852
  > 依赖(内部 JS 依赖 + 重打包子包)同样由 pnpm 安装 —— 本地未发布的 `@jinsiyu/*` 需先发布,
825
853
  > 或把 `repack/tgz/*.tgz` 以 `file:` 依赖临时装进 profile(见 `.tmp-verify.mjs`)。
826
854
  >
827
- > **改动 client bundle**:编辑 `src/factory.js` 后执行 `pnpm run build:client`
828
- > 重新生成 `lib/client.js`(仓库不跟踪该产物;浏览器刷新即生效,host 无需重启)。
855
+ > **改动客户端半部**:直接编辑 `lib/client.js`(0.3.58 起它是**手写源码**,不再有构建步骤、
856
+ > 也没有 `src/**` 中间层;格式约束见该文件头部注释,`pnpm test:client-entry` 守着它们)。
857
+ > 装进 profile 后浏览器硬刷即生效(必要时重启 host;产物 rev 在宿主启动时算好)。
829
858
  > **改动提问面板**:编辑 `assets/extensions/dshcs-editor-bridge/webview/src/*` 后执行
830
- > `pnpm run build:webview`(同一约定:产物不入库;IDE 需重启一次才会加载新产物,扩展宿主会缓存 webview 资源)。
859
+ > `pnpm run build:webview`(这一半仍是构建产物、不入库;IDE 需重启一次才会加载新产物,扩展宿主会缓存 webview 资源)。
831
860
 
832
861
  ### 打包机环境要求(使用者机器什么都不需要)
833
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-19T12:45:33.924Z
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 界面一致)
@@ -12,8 +12,10 @@
12
12
  * !md 不认领 .md(排除优先于认领)
13
13
  * 空文本 = 不认领任何文件类型(只保留页面 tab,文件点击全部落回 DSH 预览)。
14
14
  *
15
- * 本模块是 host(`lib/index.js` 的 Config 默认值)与 client(`src/factory.js` 的 canOpen)的
16
- * **同一份** 事实来源,随 npm 包一起发布(见 package.json 的 files),避免两边默认值漂移。
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