dsh-code-server-app 0.3.58 → 0.3.59
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 +122 -89
- package/README.md +117 -87
- package/assets/extensions/dshcs-editor-bridge/extension.js +43 -220
- package/assets/extensions/dshcs-editor-bridge/lib/bridge-client.js +5 -37
- package/assets/extensions/dshcs-editor-bridge/package.json +2 -2
- package/lib/bridge-session.mjs +55 -5
- package/lib/bridge.mjs +11 -7
- package/lib/client.js +922 -87
- package/lib/index.js +73 -205
- package/package.json +5 -28
- package/vendor/VENDOR.json +1 -1
- package/assets/extensions/dshcs-editor-bridge/lib/ask-panel.js +0 -416
- package/assets/extensions/dshcs-editor-bridge/webview/THIRD-PARTY.md +0 -22
- package/assets/extensions/dshcs-editor-bridge/webview/src/app.jsx +0 -242
- package/assets/extensions/dshcs-editor-bridge/webview/src/approval.jsx +0 -61
- package/assets/extensions/dshcs-editor-bridge/webview/src/official-tokens.css +0 -576
- package/assets/extensions/dshcs-editor-bridge/webview/src/panel.css +0 -380
- package/assets/extensions/dshcs-editor-bridge/webview/src/thread.jsx +0 -160
- package/assets/extensions/dshcs-editor-bridge/webview/thread.css +0 -1
- package/assets/extensions/dshcs-editor-bridge/webview/thread.js +0 -465
package/README.md
CHANGED
|
@@ -18,13 +18,14 @@
|
|
|
18
18
|
原生模块(node-pty / @vscode/sqlite3 / spdlog …)由 `@jinsiyu/dshcs-*` 子包按**真名直接挂在插件依赖上**、按 os/cpu 自动选中 ——
|
|
19
19
|
**无需全局 npm 安装、无需配置 `bin`、无需改 profile 配置、无需第二条安装命令、无需 argon2/C++ 工具链**。
|
|
20
20
|
|
|
21
|
-
>
|
|
22
|
-
>
|
|
23
|
-
>
|
|
21
|
+
> **打包形态**:插件**不随包分发** argon2 与 code-server 的 136 个运行时依赖
|
|
22
|
+
> (express / proxy-agent / js-yaml / pem / limiter …);IDE 由插件自己的 launcher 拉起内置的 VS Code 树,
|
|
23
|
+
> 服务方式见下方「服务方式(serve)」。依据与实测证据见 `docs/analysis-code-server-as-dsh-plugin.md`。
|
|
24
24
|
>
|
|
25
|
-
>
|
|
26
|
-
>
|
|
27
|
-
>
|
|
25
|
+
> **「问 DSH」对话框**:面板是 `lib/client.js` 里手写的 React 组件,渲染器直接 require DSH 页面模块表里的
|
|
26
|
+
> `react-dom/client` 与 `@deepseek-ai/dsh-client-ui-primitives`(与界面同一份实例 ⇒ 排版、代码高亮、
|
|
27
|
+
> 公式都一致,而且**不可能**版本错配),授权也在同一个对话框里就地处理 —— 详见
|
|
28
|
+
> 「与 DSH 的协同:编辑器桥」。整条链上**没有任何构建步骤**。
|
|
28
29
|
|
|
29
30
|
## UI 载体与 DSH 版本要求(0.2.3 起只支持带右侧栏的 DSH)
|
|
30
31
|
|
|
@@ -221,53 +222,57 @@ DSH 用**资源地址**命名文件,`openFile` 只负责把地址交给右侧栏
|
|
|
221
222
|
| 方向 | 能力 | 落地方式 |
|
|
222
223
|
|---|---|---|
|
|
223
224
|
| 编辑器 → agent | **未保存缓冲区**(磁盘内容 ≠ 用户所见)、活动文件与选区、**语言服务器诊断**(含 file:line、来源、code) | agent 工具 `editor_context` / `editor_diagnostics`;写脏文件前额外附一条提醒 |
|
|
224
|
-
| 编辑器 → DSH | 选中代码 → 右键「DSH: 针对选中内容提问」→
|
|
225
|
-
| DSH → 编辑器(授权) | agent 要**写工作区外的文件 / 执行命令**时的授权请求 →
|
|
225
|
+
| 编辑器 → DSH | 选中代码 → 右键「DSH: 针对选中内容提问」→ DSH 页面右下角弹出**提问对话框**(标题栏带 `文件:行`);提问以**用户输入**进当前会话,该会话的**新内容**用 DSH 官方 markdown 渲染器显示在对话框里 | 命令 `dsh-code-server.askAboutSelection`(编辑器右键菜单**最上面两条**之一)→ 桥 `POST /event {kind:'ask-open'}` → 客户端半部 `POST /api/code-server/ask/send` |
|
|
226
|
+
| DSH → 编辑器(授权) | agent 要**写工作区外的文件 / 执行命令**时的授权请求 → 对话框里就地弹卡片(工具名 + 原因 + 倒计时),点「允许一次 / 拒绝」立刻生效 | `/api/code-server/ask/state` 的 `approvals` + `POST /api/code-server/ask/approve`(全插件**唯一**的写口令,约束见「安全模型」) |
|
|
226
227
|
| agent → 编辑器 | agent 改了哪个文件 → 开**原生 diff** 审阅(左 = **写前的完整原文**,右 = 磁盘现状);缓冲区有未保存改动时**告警而不覆盖** | host 在 `tools/post-execute` 取 `result.value.before`(完整写前全文)存入有界快照缓存 → `tools/result` 的事件带不透明 key → 扩展轮询后取回原文并开 diff + 非模态告警 |
|
|
227
228
|
|
|
228
229
|
- 工具只在桥就绪时注册(IDE 没起来时模型看不到"有个用不了的工具");提示词段落也只在桥存活时渲染。
|
|
229
|
-
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
230
|
+
- **提问对话框**:右键命令只向宿主上报意图,真正的对话框由 DSH 页面里的插件客户端弹出 ——
|
|
231
|
+
**可拖动、可缩放**(右下角,✕ 关闭),不占编辑器版面;对话框开着的**同时**还能改选区再问。
|
|
232
|
+
宿主证明不了对话框活着(页面没开 / 浏览器还缓存着旧客户端)时只给一条
|
|
233
|
+
「请在 DSH 页面里打开(或刷新)Code Server 标签」的提示 —— 扩展里**没有第二套提问 UI**。
|
|
234
|
+
- **两个命令的意图分开记**:「针对选中内容提问」只有真的选了内容才带**行区间 + 选区正文**;
|
|
234
235
|
「针对当前文件提问」**永远不带行号、不带选区** —— 光标停在哪一行跟问题无关,行号只会误导 agent;
|
|
235
|
-
|
|
236
|
-
-
|
|
236
|
+
没选区时用选中命令提问也会退化成纯文件。上下文由宿主从它缓存的编辑器状态里取,扩展只上报意图。
|
|
237
|
+
- **追问跟着 DSH 自己的设置投递**:DSH 的 `ui-conversation.busyEnter`(设置 → 对话:「忙碌时按 Enter」)
|
|
238
|
+
取值只有 `queue`(默认)与 `steer`。面板里按 Enter 与主界面里按 Enter 是同一个手势,所以读同一个值:
|
|
239
|
+
`steer` ⇒ 宿主用 `agent.steer()`,追问在**当前轮的下一个步骤边界**被读到(当轮就能回应);
|
|
240
|
+
`queue` ⇒ 宿主用 `agent.followup()`,排到**下一轮**、不打扰当前轮。读不到这个设置(命名空间未注册 /
|
|
241
|
+
极简组合)· 老宿主上没有 `agent.steer` ⇒ 一律退回 `queue`,绝不因为设置而投不出去。
|
|
242
|
+
面板状态行会**说清用的是哪种**(「已插入当前轮…」/「已排入下一轮…」)—— 因为 `queue` 期间
|
|
243
|
+
**DSH 主界面看不到这条消息**:它进的是宿主侧待发队列(`next-turn`),而主界面客户端不渲染待发队列
|
|
244
|
+
(只有它成为自己那一轮时才进聊天流)。这不是消息丢了。
|
|
245
|
+
- **注入的上下文是折叠的**:桥拼进消息的位置行 + 选区代码块会被拆出来,显示成一行默认收起的
|
|
237
246
|
「上下文」(点开才看得到那段代码),气泡里只留你的原话 —— 与 DSH 界面处理注入上下文的方式一致。
|
|
238
|
-
-
|
|
239
|
-
(`@deepseek-ai/dsh-client-ui-primitives` 的 `MarkdownText`)
|
|
240
|
-
同一个增量流式解析器、同一个 shiki 高亮(
|
|
241
|
-
|
|
242
|
-
|
|
247
|
+
- **正文就是 DSH 的渲染结果**:正文交给 DSH 官方的 markdown 渲染器
|
|
248
|
+
(`@deepseek-ai/dsh-client-ui-primitives` 的 `MarkdownText`)—— 同一套 micromark/mdast 管线、
|
|
249
|
+
同一个增量流式解析器、同一个 shiki 高亮(走 DSH 自己的懒加载语法集)、KaTeX 公式、
|
|
250
|
+
同样的标题与表格排版。只渲染**新内容**(从对话框订阅那一刻起),**不重放历史**、没有"加载更早"。
|
|
251
|
+
官方部件取不到时降级成纯文本 `<pre>`,不白屏。
|
|
252
|
+
- **思考过程也照官方显示**:助手的 reasoning 以「思考」行出现 —— **默认收起**、收起时显示首行
|
|
243
253
|
(流式时显示最新一行)、点整行展开全文,用的就是官方 `DisclosureRow` + 官方的思考图标与排版语言。
|
|
244
|
-
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
它只能**回答**已经存在的授权请求(见「安全模型」第 2 条)。agent 的写操作仍然全部走它自己的 `fs` 工具,
|
|
254
|
-
桥只是"知道它写了什么"、并把你对授权的答复带回去。
|
|
254
|
+
- **授权就在对话框里处理**:对话框打开着的时候,该会话的授权请求**先问对话框**(5 分钟窗口),
|
|
255
|
+
点「允许一次」/「拒绝」立刻生效;**关掉对话框**或等满窗口就把请求**原样交回官方链路**(DSH 界面照旧弹卡)。
|
|
256
|
+
**永不自动放行** —— `allowed-once` 只能来自你的一次点击,对话框里没有"以后都允许"这种入口。
|
|
257
|
+
- 提问进 DSH 会话时是**普通用户消息**(`source: { kind: 'user' }`):来源信息靠正文首行
|
|
258
|
+
`From the editor: <file>[:<行>]` 保留,面板把它折成「上下文」行。
|
|
259
|
+
- **桥完全只读**:不写文件、不改文档、不执行命令 —— 四条路由(`/health`、`/sync`、`/old`、`/event`)都是读的。
|
|
260
|
+
唯一能改状态的是 DSH 同源的 `POST /api/code-server/ask/approve`,它只能**回答**已经存在的授权请求
|
|
261
|
+
(见「安全模型」第 2 条)。agent 的写操作仍然全部走它自己的 `fs` 工具,桥只是"知道它写了什么"、
|
|
262
|
+
并把你对授权的答复带回去。
|
|
255
263
|
- 编辑器侧的入口还有状态栏的 `$(plug) DSH`(连通时显示,点击打开日志),日志在输出面板
|
|
256
264
|
「DSH Editor Bridge」里 —— 出问题时先看它。
|
|
257
|
-
-
|
|
258
|
-
|
|
259
|
-
"在用户扩展目录里、不在任何 profile 清单里"的扩展标进 `.obsolete`(日志 `Marked extension as removed`)
|
|
260
|
-
并永远跳过它 —— 每一轮启动都再标一次,**桥因此从来没有上报过状态**。
|
|
265
|
+
- **扩展装在内置目录**:`dshcs-editor-bridge` 与 `dshcs-open-file` 一样装进 `<树>/lib/vscode/extensions/`
|
|
266
|
+
—— 用户级目录里那个会被 VS Code 服务端标进 `.obsolete`(日志 `Marked extension as removed`)并永久跳过。
|
|
261
267
|
要关掉桥请用插件设置 `editorBridge=false`(不挂桥、不注册工具),不要再指望在扩展视图里卸载它。
|
|
262
268
|
|
|
263
269
|
### 三条通道(0.3.13 起走**本机 IPC**:Windows 命名管道 / unix socket)
|
|
264
270
|
|
|
265
271
|
```
|
|
266
|
-
扩展 → host POST /code-server-bridge/sync 一趟来回:上报编辑器状态
|
|
267
|
-
扩展 → host POST /code-server-bridge/ask 把编辑器里的提问投进当前会话
|
|
268
|
-
扩展 → host POST /code-server-bridge/approve 回答一条**已经存在**的授权请求(唯一的非只读路由)
|
|
272
|
+
扩展 → host POST /code-server-bridge/sync 一趟来回:上报编辑器状态 + 取回待处理事件与能力位
|
|
269
273
|
扩展 → host GET /code-server-bridge/health 无鉴权探活(便于重启后一眼确认)
|
|
270
|
-
扩展 → host
|
|
274
|
+
扩展 → host GET /code-server-bridge/old 取一份"写前原文"快照(事件里只带不透明 key)
|
|
275
|
+
扩展 → host POST /code-server-bridge/event 上报意图:请宿主打开对话框 / 打开·关闭文件等(进 host 日志尾)
|
|
271
276
|
host → 扩展 <extensionsDir>/.dshcs-bridge/bridge.json 端点 + 令牌(扩展每 5s 重读)
|
|
272
277
|
(同一份内容还会写到**内置扩展旁边** `<树>/lib/vscode/extensions/.dshcs-bridge/` ——
|
|
273
278
|
环境变量只在 host spawn IDE 时注入,而被**接管**的 IDE 是上一次启动的进程、拿不到它,
|
|
@@ -275,14 +280,17 @@ host → 扩展 <extensionsDir>/.dshcs-bridge/bridge.json 端点 + 令牌(
|
|
|
275
280
|
```
|
|
276
281
|
|
|
277
282
|
请求走 `http.request({ socketPath })`(`fetch` 不支持 socket),**不开任何端口**。
|
|
283
|
+
这四条**全部只读**;提问与授权答复不走桥,而在 DSH 同源的 `/api/code-server/ask/*` 上
|
|
284
|
+
(调用方是 DSH 页面里的插件客户端,吃 DSH 自己的 cookie/Origin 校验)。
|
|
278
285
|
|
|
279
|
-
|
|
286
|
+
对话框真正用到的四段状态(`GET /api/code-server/ask/state?rev=N`;没变化只回一个数字):
|
|
280
287
|
|
|
281
288
|
| 字段 | 内容 | 面板怎么用 |
|
|
282
289
|
|---|---|---|
|
|
283
|
-
| `
|
|
284
|
-
| `approvals` | 待决授权请求 `[{id, toolName, reason, at}]`(≤4 条) | 弹卡片 + 倒计时;点按后 `POST /approve` |
|
|
285
|
-
| `approvalHoldMs`
|
|
290
|
+
| `entries` | 被对话框 `watch` 的会话的**新内容**条目(user / assistant / tool / approval),有界:每会话 ≤120 条、单条正文 ≤8000 字符、同时 watch ≤4 个会话 | 助手正文交给官方渲染器;工具与授权是紧凑摘要行 |
|
|
291
|
+
| `approvals` | 待决授权请求 `[{id, toolName, reason, at}]`(≤4 条) | 弹卡片 + 倒计时;点按后 `POST /ask/approve` |
|
|
292
|
+
| `approvalHoldMs` | 授权窗口长度(默认 300000ms = 5 分钟) | 倒计时基准 |
|
|
293
|
+
| `contextText` / `mode` | 标题栏那一行(来自宿主缓存的编辑器状态)+ 提问意图 | 标题栏文案;`mode` 决定发送时带不带行号/选区 |
|
|
286
294
|
|
|
287
295
|
> **为什么不是 HTTP(0.3.13 定论,三条都实测过)**
|
|
288
296
|
> 1. **desktop 根本没有 HTTP 面**:渲染进程经 Electron IPC 调 `host.fetch()`
|
|
@@ -331,7 +339,7 @@ seq,并且 `/sync` 回应里带 `lastSeq`(高水位),扩展据此自查游标是
|
|
|
331
339
|
(c) `outcome` 只接受 `allowed-once` / `rejected`,**没有"永久允许"**;
|
|
332
340
|
(d) 没有面板在看 / 面板关掉 / 窗口超时(默认 5 分钟)→ **交回官方链路**,绝不自动放行
|
|
333
341
|
(DSH 的 `approval/request` 本身 fail closed,这里只能把"没人答"保持成"没人答")。
|
|
334
|
-
`pnpm test:
|
|
342
|
+
`pnpm test:ask-dialog` 里有针对这四条与宿主侧白名单的断言。
|
|
335
343
|
3. **带 `Origin` 的请求一律 403。** 浏览器发起必带 Origin(含沙箱 iframe 的 `Origin: null`),
|
|
336
344
|
扩展宿主是 Node 进程、不带。判定顺序上 Origin **先于令牌** —— 否则等于给浏览器一个
|
|
337
345
|
"令牌猜对没有"的 oracle。
|
|
@@ -409,8 +417,9 @@ seq,并且 `/sync` 回应里带 `lastSeq`(高水位),扩展据此自查游标是
|
|
|
409
417
|
- process 生命周期由 host 插件管理:启动写 `$DSH_HOME/code-server/pid.json`,停止树级终止(taskkill /T 或进程组 SIGKILL),
|
|
410
418
|
崩溃/退出实时更新状态;DSH host 重启后自动 adopt 仍在运行的实例(校验 pid + /healthz),不重复启动、不误杀别的进程;
|
|
411
419
|
- `node_modules`、`vendor/` 与 `repack/` 已被 `.gitignore` 排除,推送/克隆仓库后按下方
|
|
412
|
-
"打包(如何出包)"执行 `pnpm install` → `pnpm run vendor:vscode` →
|
|
413
|
-
(发布预编译原生包)→ `pnpm pack` + `dsh plugin --profile web add` 即可
|
|
420
|
+
"打包(如何出包)"执行 `pnpm install` → `pnpm run vendor:vscode` →
|
|
421
|
+
(发布预编译原生包)→ `pnpm pack` + `dsh plugin --profile web add` 即可
|
|
422
|
+
(客户端半部与提问面板都是入库的手写源码 —— 整条链上**没有任何构建步骤**)。
|
|
414
423
|
|
|
415
424
|
> 本机(BM: Windows 11 ARM64)实测:树/依赖全链路是"平台子包直挂插件依赖"供给 ——
|
|
416
425
|
> 树包 `@jinsiyu/dshcs-vscode-server`(当前 4.137.0,50.8 MB tgz)、纯 JS 内部依赖与 8 个平台无关
|
|
@@ -423,23 +432,21 @@ seq,并且 `/sync` 回应里带 `lastSeq`(高水位),扩展据此自查游标是
|
|
|
423
432
|
|
|
424
433
|
```powershell
|
|
425
434
|
cd C:\Users\User\Desktop\dsh-code-server-app
|
|
426
|
-
pnpm install #
|
|
427
|
-
pnpm run build:webview # 「问 DSH」面板:官方 markdown 渲染器 + 面板外壳 → webview/thread.{js,css}(不入库,必须先构建)
|
|
435
|
+
pnpm install # 开发依赖只剩 1 个(@deepseek-ai/schemastery);allowBuilds 已显式声明 → 不执行任何 postinstall
|
|
428
436
|
pnpm run vendor:check # 可选:查看内置 VS Code 树版本 vs code-server 最新版
|
|
429
437
|
pnpm run vendor:vscode # ① 生成 vendor/vscode(精简 VS Code 树,≈197MB)
|
|
430
438
|
pnpm run repack:build -- --target win32-arm64,win32-x64 --pack # ② 统一脚本产出全部子包(见下表)
|
|
431
439
|
pnpm run publish:repacks # ③ 发布全部 @jinsiyu/* 子包(默认 dist-tag = next)
|
|
432
|
-
pnpm pack # ④ → dsh-code-server-app-<version>.tgz
|
|
440
|
+
pnpm pack # ④ → dsh-code-server-app-<version>.tgz
|
|
433
441
|
pnpm run publish:plugin # ⑤ 发布插件本体(默认 dist-tag = next)
|
|
434
442
|
# 用户重启 dsh web 确认无误后,再把 latest 推进到该版本:
|
|
435
443
|
pnpm run promote -- <version>
|
|
436
444
|
```
|
|
437
445
|
|
|
438
|
-
> `
|
|
439
|
-
>
|
|
440
|
-
>
|
|
441
|
-
>
|
|
442
|
-
> 细节(为什么不是 iframe、令牌从哪来、体积取舍)见 `docs/analysis-code-server-as-dsh-plugin.md` 第 21 节。
|
|
446
|
+
> **这条链上没有构建步骤**:`lib/client.js` —— 包含「问 DSH」对话框的面板 —— 就是入库的手写源码,
|
|
447
|
+
> 扩展也是纯 JS。所以 `prepack` 只剩 `vendor:vscode` 一步,发布包里没有任何前端产物,
|
|
448
|
+
> `devDependencies` 只剩一个(`@deepseek-ai/schemastery`,测试用)。
|
|
449
|
+
> 面板与 DSH 页面的历史分析(按版本分段)见 `docs/analysis-code-server-as-dsh-plugin.md`。
|
|
443
450
|
|
|
444
451
|
> **dist-tag 政策(必须遵守)**:发布一律发到 **`next`**,**不动 `latest`**;
|
|
445
452
|
> `latest` 只保留「最近一个确认无 bug 的版本」,由 `pnpm run promote -- <version>`
|
|
@@ -494,14 +501,15 @@ pnpm test:apply # 桩 ctx 下跑通 apply(回归:apply 期的 Refer
|
|
|
494
501
|
pnpm test:claim-types # 认领类型语法与默认值
|
|
495
502
|
pnpm test:bridge-routes # 编辑器桥:路由表白名单(只读 + /approve + /old)/ Origin 与令牌的判定顺序 / 令牌头三处一致
|
|
496
503
|
pnpm test:edit-snapshot # 写前原文快照:从 tools/post-execute 的 value 取完整 before / 路径按会话 cwd 绝对化 / 缓存三重有界 / /old 的 400-404-200
|
|
497
|
-
pnpm test:bridge-extension # 编辑器桥扩展侧纯逻辑:未保存缓冲区上报、诊断排序截断、diff 判据(old 侧优先级)
|
|
498
|
-
pnpm test:
|
|
504
|
+
pnpm test:bridge-extension # 编辑器桥扩展侧纯逻辑:未保存缓冲区上报、诊断排序截断、diff 判据(old 侧优先级)、投递降级、提问意图与"对话框不可用给提示"
|
|
505
|
+
pnpm test:ask-dialog # 「问 DSH」对话框的接线:没有产物/构建链了、宿主 4 条 ask 路由、扩展只上报编辑器状态、授权四条、桥的安全不变式
|
|
499
506
|
pnpm test:launcher-routes # launcher 的 HTTP 面(起真进程,较慢)
|
|
500
507
|
pnpm test:workspace-switch # 切工作区不重启进程
|
|
501
508
|
pnpm test:workspace-cwd # "当前工作区目录"解析:DSH 0.1.6-alpha.2(sessionId)与旧版(current)两套形状
|
|
502
509
|
pnpm test:client-cwd # 同一件事但直接对**客户端入口** lib/client.js 验(注册出来的 body 真发不发 cwd、URL 带不带 folder)
|
|
503
510
|
pnpm test:client-tabs # "DSH 侧只留一个 code-server 标签页":新标签挂载时收掉同窗格旧标签(跨窗格/不可见时不动)
|
|
504
|
-
pnpm test:client-entry # 客户端入口守卫:经典脚本+工厂包装、require
|
|
511
|
+
pnpm test:client-entry # 客户端入口守卫:经典脚本+工厂包装、require 白名单(= DSH 模块表种子词)、src/ 已消失、与 lib/claim-types.js 逐字一致
|
|
512
|
+
pnpm test:ask-panel # 「问 DSH」对话框面板(0.3.59 起手写):注入机制已下线、视图白名单、注入 CSS 的选择器/var() 安全、六种条目与授权卡片、三条消息落点、拿不到官方部件时的降级
|
|
505
513
|
pnpm test:client-seat # 设置卡住哪个座位:插件页 plugins.bundle.config(DSH ≥ 0.1.6-alpha.2)vs settings.plugin.item(≤ alpha.1;新版已退役)
|
|
506
514
|
pnpm test:fullscreen # 打开标签即全屏
|
|
507
515
|
pnpm test:vendored # 重打包表 ↔ 插件依赖表一致(无 npm: 别名 / 无聚合包 / vendored.json 进了 files)
|
|
@@ -536,8 +544,8 @@ pnpm test:installed # 安装冒烟:对**已装进 profile 的产物**
|
|
|
536
544
|
|
|
537
545
|
| 工作流 | 触发 | 做什么 |
|
|
538
546
|
|---|---|---|
|
|
539
|
-
| `ci.yml` | push `main` / PR / 手动 | `ubuntu-latest` + `windows-latest` 双平台:`pnpm install --frozen-lockfile` → `
|
|
540
|
-
| `release.yml` | 推 `v<version>` 标签 / 手动(演练,不发布) | 按 `dependencies` 钉的版本准备 `vendor/vscode` →
|
|
547
|
+
| `ci.yml` | push `main` / PR / 手动 | `ubuntu-latest` + `windows-latest` 双平台:`pnpm install --frozen-lockfile` → `pnpm test`(全套回归;0.3.59 起**前面没有任何构建步骤**)→ `vendor:check` 只报告版本差 |
|
|
548
|
+
| `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) |
|
|
541
549
|
| `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 通道真的可用 |
|
|
542
550
|
|
|
543
551
|
### Linux 适配(x64 / arm64):改了什么、还差什么
|
|
@@ -704,8 +712,6 @@ pnpm run promote -- 0.3.47 # 4) 确认无误后推 latest(手动
|
|
|
704
712
|
收尾:把暂存的探针版本**reject** 掉(`npm stage list` 看 id、`npm stage reject <id>`,需要你本机的 2FA;
|
|
705
713
|
npm 网页上也有对应的 staged 列表)——**不要 approve**,approve 才会让它变成正式版本。
|
|
706
714
|
验证完删掉哨兵文件,工作流就恢复"不自动巡检"。
|
|
707
|
-
- **可选**仓库 Variables `DSH_UI_VERSION` = 当前部署里 `@deepseek-ai/dsh-web-frontend` 的版本:设了之后
|
|
708
|
-
`release.yml` 会强制面板渲染器版本与部署一致(本机 `build:webview` 本来就会比,runner 上没有 DSH 部署)。
|
|
709
715
|
|
|
710
716
|
几条必须知道的:
|
|
711
717
|
|
|
@@ -716,7 +722,7 @@ pnpm run promote -- 0.3.47 # 4) 确认无误后推 latest(手动
|
|
|
716
722
|
树版本不同步(反而会把「树包精确钉版本」搞挂)。打包只在 `release.yml` 里做,且显式
|
|
717
723
|
`node scripts/vendor-vscode-server.mjs --version <pinned>`。
|
|
718
724
|
- **发布门禁**(任一不过即中止,`next` 不会被推进):tag ≠ `package.json.version`、该版本已存在于 npm、
|
|
719
|
-
树包版本不一致(`test:vendored` 的「树包精确钉版本」断言)
|
|
725
|
+
树包版本不一致(`test:vendored` 的「树包精确钉版本」断言)、回归失败、tarball 清单与两条真装腿的断言。
|
|
720
726
|
- 首次发布必须用一个**没发过的版本号**(npm 版本不可变);`release.yml` 支持 `workflow_dispatch` **演练**
|
|
721
727
|
(完整跑一遍但不发布、不建 Release),建议先演练一次再打真 tag。
|
|
722
728
|
- 锁文件 `pnpm-lock.yaml` **已入库**(CI 用 `--frozen-lockfile` 做可复现安装,缓存 key 也靠它);它不在
|
|
@@ -814,32 +820,59 @@ dsh plugin --profile web add C:\Users\User\Desktop\dsh-code-server-app\dsh-code-
|
|
|
814
820
|
|
|
815
821
|
> 安装/依赖变化后请**重启 `dsh web`**(静态插件行与 host 探测路径在启动时加载)。
|
|
816
822
|
|
|
817
|
-
###
|
|
823
|
+
### 客户端半部:为什么没有构建步骤
|
|
818
824
|
|
|
819
|
-
**`lib/client.js` 就是源码** ——
|
|
820
|
-
|
|
821
|
-
`build:client` 步骤。
|
|
825
|
+
**`lib/client.js` 就是源码** —— 手写、入库、不压缩。它同时是:右侧栏标签里的常驻 IDE 面、
|
|
826
|
+
「问 DSH」对话框的面板、设置卡/设置页。整条链上没有中间产物、没有构建器,也不会"忘了重建"。
|
|
822
827
|
|
|
823
|
-
|
|
828
|
+
为什么可以这样:DSH 用经典 `<script src>` 加载客户端入口(`/plugins/<包名>/client.js`),它**只能是**
|
|
824
829
|
一个文件、且必须是 `window.__ModuleLoader__.load({id, factory})` 形态(不能是 ES module;包内分块只能
|
|
825
|
-
`require.async('client.*.js')`,本插件用不到)
|
|
826
|
-
|
|
830
|
+
`require.async('client.*.js')`,本插件用不到),而它需要的一切(React、官方 UI 部件)都能从
|
|
831
|
+
DSH 自己的模块表里 `require` 到。
|
|
827
832
|
|
|
828
833
|
代价与约束(改 `lib/client.js` 前先读):
|
|
829
834
|
|
|
830
835
|
| 约束 | 为什么 | 谁守着 |
|
|
831
836
|
|---|---|---|
|
|
832
837
|
| 顶层不许 `import`/`export`/`await` | 经典脚本里它们是语法错误 ⇒ 整个客户端半部不加载(界面全空) | `pnpm test:client-entry` 的 E1 + harness 真加载(E3) |
|
|
833
|
-
| `require(...)`
|
|
834
|
-
| 各段落的顶层标识符共享同一作用域 |
|
|
838
|
+
| `require(...)` 只能是 DSH 模块表的种子词(`react` / `react/jsx-runtime` / `react-dom/client` / `@deepseek-ai/dsh-client-ui-primitives`) | DSH 冻结模块表,别的会抛"未知模块" | E1(有本机 DSH 安装时还会拿它真实的 `staticModules` 逐词核对) |
|
|
839
|
+
| 各段落的顶层标识符共享同一作用域 | `var`/`function` 撞名是**静默覆盖**(面板与常驻面都叫过 `state`,已改名 `surfaceState`) | 无自动守卫 ⇒ 新增顶层名字前先搜一遍 |
|
|
835
840
|
| `lib/claim-types.js` 的那份是**副本** | 客户端拿不到 host 模块(经典脚本 + 冻结模块表) | E2 逐字比对四组样例 |
|
|
841
|
+
| 面板段的额外约束(选择器、`var()` fallback、hook 组件写法、降级路径) | 见下一节 | `pnpm test:ask-panel` 的 P1–P6 |
|
|
836
842
|
|
|
837
|
-
体积:未压缩 ~
|
|
843
|
+
体积:未压缩 ~145 KB —— 一次下载,rev 机制与缓存策略不变。
|
|
838
844
|
测试钩子:入口在 `window.__dshcsTestHooks === true` 时额外导出 `__internals`(供
|
|
839
|
-
`test-workspace-cwd.mjs` / `test-sidebar-fullscreen.mjs`
|
|
845
|
+
`test-workspace-cwd.mjs` / `test-sidebar-fullscreen.mjs` / `test-ask-panel-inline.mjs` 直接调内部函数),
|
|
846
|
+
DSH 永不设置该标志。
|
|
840
847
|
|
|
841
|
-
|
|
842
|
-
|
|
848
|
+
### 「问 DSH」对话框:为什么没有构建步骤
|
|
849
|
+
|
|
850
|
+
对话框的面板(对话流 / 思考折叠行 / 授权卡片 / 输入框)就在 `lib/client.js` 里 —— 手写、入库、
|
|
851
|
+
没有产物、没有 `/ask/bundle`、不往页面注入 `<script>`、也不需要假的 `acquireVsCodeApi`。
|
|
852
|
+
|
|
853
|
+
它凭什么能不打包:对话框本来就跑在 **DSH 页面里**,而壳的模块表(`dsh-web-frontend` 的
|
|
854
|
+
`staticModules`)已经冻结了 `react` / `react/jsx-runtime` / `react-dom` / `react-dom/client` /
|
|
855
|
+
`@deepseek-ai/dsh-client-ui-primitives` / … —— 面板直接 `require` 它们:
|
|
856
|
+
|
|
857
|
+
- 渲染器、设计令牌、KaTeX 样式、shiki 语法集**全部由页面提供**(与 DSH 界面**同一份实例**)
|
|
858
|
+
⇒ 排版与界面一致,而且**不可能**版本错配;
|
|
859
|
+
- 面板用 `require('react-dom/client')` 给自己的容器建 React 根(容器是对话框自己的 div);
|
|
860
|
+
- 打开对话框没有"取文本 + 解析 + 执行"这一等 —— 没有产物可等。
|
|
861
|
+
|
|
862
|
+
代价与约束:
|
|
863
|
+
|
|
864
|
+
| 约束 | 为什么 | 谁守着 |
|
|
865
|
+
|---|---|---|
|
|
866
|
+
| 注入页面的 CSS **只能**挂 `.dshcs-*` 选择器 | 样式注入进的是 DSH 自己的文档,碰 `:root`/`body` 会改掉整个界面 | `pnpm test:ask-panel` 的 P3(逐条选择器 + 禁用 at 规则) |
|
|
867
|
+
| 每个 `var(--vscode-*)` 都要带 fallback | DSH 页面里没有 `--vscode-*`,裸 `var()` 是"计算值无效"⇒ 按钮/输入框透明 | P3 |
|
|
868
|
+
| 带 hook 的组件只能写成 `React.createElement(Name, …)` | 手写没有 JSX;`Name({…})` 会把子组件的 `useState` 算进父组件的 hook 链,分支一变就抛 "Rendered more hooks than during the previous render" | P4(源码级后顾正则) |
|
|
869
|
+
| 官方部件要按"函数**或** `{$$typeof}` 对象"取 | `MarkdownText` 是 `React.memo` 的产物(**对象**),按 `typeof === 'function'` 判可用性会让正文静默退成 `<pre>` | P4 的 `askComponent` 用例 |
|
|
870
|
+
| 取不到种子词/官方部件时必须降级 | 面板是主路径,白屏等于提问功能没了 | P5(正文退 `<pre>`、按钮退原生 `button`)+ 错误边界 |
|
|
871
|
+
| 通知/提问/授权三条消息的路由 | 面板与外壳在同一个 window(不走 postMessage),消息必须落到 `/ask/send|approve|close` | P6 |
|
|
872
|
+
|
|
873
|
+
编辑器侧同样没有构建步骤:扩展是纯 JS(`extension.js` + `lib/*.js`),提问只上报意图。
|
|
874
|
+
这两条"没有构建步骤"的守卫分别在 `pnpm test:client-entry` / `pnpm test:ask-panel`(面板本体)与
|
|
875
|
+
`pnpm test:ask-dialog`(接线 + "产物与构建链一处都不许残留")里。
|
|
843
876
|
|
|
844
877
|
### 开发期:源码目录安装(改动即时生效)
|
|
845
878
|
|
|
@@ -852,11 +885,11 @@ dsh plugin --profile web add C:\Users\User\Desktop\dsh-code-server-app
|
|
|
852
885
|
> 依赖(内部 JS 依赖 + 重打包子包)同样由 pnpm 安装 —— 本地未发布的 `@jinsiyu/*` 需先发布,
|
|
853
886
|
> 或把 `repack/tgz/*.tgz` 以 `file:` 依赖临时装进 profile(见 `.tmp-verify.mjs`)。
|
|
854
887
|
>
|
|
855
|
-
>
|
|
856
|
-
> 也没有 `src/**` 中间层;格式约束见该文件头部注释,`pnpm test:client-entry`
|
|
857
|
-
>
|
|
858
|
-
>
|
|
859
|
-
>
|
|
888
|
+
> **改动客户端半部 / 提问对话框**:直接编辑 `lib/client.js`(它是**手写源码**:没有构建步骤、
|
|
889
|
+
> 也没有 `src/**` 中间层;格式约束见该文件头部注释,`pnpm test:client-entry` 与 `pnpm test:ask-panel`
|
|
890
|
+
> 守着它们)。装进 profile 后浏览器硬刷即生效。
|
|
891
|
+
> **改动扩展**:编辑 `assets/extensions/dshcs-editor-bridge/{extension.js,lib/*.js}`(纯 JS、无构建);
|
|
892
|
+
> IDE 侧要重启一次才会加载新扩展代码 —— 扩展宿主会缓存已加载的扩展。
|
|
860
893
|
|
|
861
894
|
### 打包机环境要求(使用者机器什么都不需要)
|
|
862
895
|
|
|
@@ -1100,15 +1133,12 @@ desktop profile 由 `apps/desktop-host` 把 `/api/*` 交给同一个 `createShar
|
|
|
1100
1133
|
0.3.54 及以前只有"编辑器缓冲区 / 扩展自己的缓存"两条来源,都没命中时左栏是空文本 + 标题写"没有改动前的内容"。
|
|
1101
1134
|
仍然拿不到的情形有两种,标题会如实说明:`str_replace_editor` 这类 output 是纯字符串的工具(没有 `value`),
|
|
1102
1135
|
以及写前内容 >1MB(不塞进缓存)。**注意** `value` 是 execution-local:它不进会话日志,宿主重启后旧的 diff 不会重放。
|
|
1103
|
-
-
|
|
1136
|
+
- **对话框只渲染"新内容"**:订阅从对话框建立那一刻开始,`follow` 开帧里的历史 `records` 被丢弃,
|
|
1104
1137
|
面板里**没有"加载更早"**(历史分页 API `sessionController.page()` 在这个版本里刻意不调用)。
|
|
1105
1138
|
想看更早的内容请回 DSH 界面。
|
|
1106
|
-
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
- **面板产物与 DSH 版本绑定**:渲染器按构建时 DSH 部署的界面版本打包,DSH 升级后**要重打面板**
|
|
1110
|
-
(`pnpm run build:webview`;构建脚本会在版本不一致时直接报错)。运行期面板顶部也会提示版本不一致,
|
|
1111
|
-
不会悄悄用错版本的渲染器。
|
|
1139
|
+
- **代码高亮跟着 DSH 的懒加载语法集走**:面板用的是页面里那一份渲染器,所以不存在
|
|
1140
|
+
"产物里只带哪几套语法"的限制。
|
|
1141
|
+
- **渲染器版本不可能错配**:面板 `require` 的就是界面自己用的那一份实例。
|
|
1112
1142
|
- **面板里的授权窗口是 5 分钟**:面板打开着的时候授权先问面板(卡片上有倒计时);**关掉面板**或等满 5 分钟
|
|
1113
1143
|
就交回 DSH 界面 —— 交回之后这一条**只能**在 DSH 界面里处理(卡片从面板消失,对话流里留一行授权审计)。
|
|
1114
1144
|
|