dsh-vscode-mode 0.4.5 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. package/README.md +591 -415
  2. package/lib/client.js +8854 -4025
  3. package/lib/client.js.map +1 -1
  4. package/lib/index.js +1842 -65
  5. package/lib/index.js.map +1 -1
  6. package/package.json +2 -2
  7. package/src/client/index.ts +3 -0
  8. package/src/client/monaco/lsp/providers.ts +28 -6
  9. package/src/client/navHighlight.ts +96 -0
  10. package/src/client/paths.ts +2 -0
  11. package/src/client/rpc.ts +32 -12
  12. package/src/client/sidebar/SidebarView.ts +6 -2
  13. package/src/client/sidebar/menuItems.ts +93 -2
  14. package/src/client/sidebar/panels/FileExplorer.ts +18 -3
  15. package/src/client/sidebar/panels/SvnPanel.ts +303 -0
  16. package/src/client/sidebar/panels/index.ts +44 -3
  17. package/src/client/sidebar/types.ts +20 -0
  18. package/src/client/styles/editor.css +177 -0
  19. package/src/client/svnActions.ts +153 -0
  20. package/src/client/svnLog.ts +356 -0
  21. package/src/client/svnStatus.ts +363 -0
  22. package/src/client/svnStore.ts +150 -0
  23. package/src/client/tabMenu.ts +51 -0
  24. package/src/client/ui/EditorView.ts +583 -24
  25. package/src/client/ui/LogDialog.ts +333 -0
  26. package/src/client/ui/McpSettings.ts +98 -0
  27. package/src/client/ui/ModalShell.ts +79 -0
  28. package/src/client/ui/SideBySideDiff.tsx +139 -0
  29. package/src/client/ui/SnippetsPicker.ts +70 -58
  30. package/src/client/ui/SvnDiffPanel.ts +50 -0
  31. package/src/client/ui/SvnLogDialog.ts +1141 -0
  32. package/src/client/ui/SvnLogStats.ts +243 -0
  33. package/src/client/ui/commandCatalog.ts +72 -0
  34. package/src/debugLog.ts +81 -12
  35. package/src/fileOpenSettings.ts +40 -3
  36. package/src/index.ts +5 -1
  37. package/src/rpc.ts +41 -4
  38. package/src/shared/rpc.ts +53 -1
  39. package/src/shared/svn.ts +377 -0
  40. package/src/shared/svnActions.ts +296 -0
  41. package/src/svn.ts +870 -0
  42. package/src/svnLog.ts +315 -0
  43. package/src/svnText.ts +175 -0
  44. package/src/svnXml.ts +110 -0
package/README.md CHANGED
@@ -1,205 +1,374 @@
1
1
  # dsh-vscode-mode
2
2
 
3
- > 原 `@dsh-external/dsh-edit-review`(编辑差异审查)重构而来——DSH 上的**类 VSCode 编码体验**。
4
-
5
- 仿 VSCode 的 **Agent 文件编辑器 + 差异审查** DSH 插件:
6
-
7
- - **侧边栏「文件编辑」Tab**(v0.1.60,推荐):检测到 **DSH 0.1.5+ 官方右侧 Sidebar**(`ctx.sidebarRightTabs` /
8
- `ctx.sidebarRight` 服务)时,编辑器注册为官方侧边栏 Tab——**AI 对话(中央)与文件编辑(右侧栏)同屏**,
9
- 类主流 Code Agent 布局;支持官方多标签/分栏/浮出/全屏,打开路由即开即展开;官方 Sidebar 引导页提供入口。
10
- **优先级**:官方侧边栏与 [dsh-better-sidebar](https://github.com/omdsh-dev/DSH-better-sidebar) 同时可用时**官方优先**
11
- (better-sidebar 桥已归档,仅作旧版 DSH 回退,不再新增能力)。旧版 DSH(< 0.1.5)沿用 better-sidebar 侧栏形态,
12
- 两者皆缺时回退旧「中央文件编辑页签」形态(插件零新依赖仍完整可用),
13
- 编辑器顶部与设置页「兼容性」子 Tab 会给出对应引导。
14
- **文件链接(DSH 0.1.5+)**:聊天/文件树的文件链接经官方 `ctx.sidebarRight.openResource` 直达右侧栏——
15
- 「文件链接使用工具」为 自动/VSCodeMode 时本插件以 extension 档认领 `dsh-resource://file/**`(链接在本插件
16
- Monaco 编辑器打开,含行号定位);为「官方侧边栏」档时走官方文本查看器(不认领);畸形地址自动回落官方查看器。
17
- 文件页签(脏点/关闭/「+」打开/**右键菜单/固定**)+ `Ctrl+P` 快速打开(QuickOpen,候选浮窗 `↑↓` 选择 /
18
- `Enter` 打开高亮项 / `Esc` 关闭,鼠标悬停与高亮同步)+ **Monaco Editor**
19
- (语法高亮/行号/`Ctrl+F`/`Ctrl+G`/`Ctrl+S`/700ms 防抖自动保存)+ 顶部工具栏(路径/语言/Ln,Col/保存状态/差异/侧边栏/刷新)
20
- + **导航历史**(后退/前进:跨文件恢复焦点位置,工具栏 `←`/`→` 按钮、键盘 `Alt+←/→` 与 `Ctrl+Alt+-`/`Ctrl+Shift+-`、
21
- 鼠标侧键 XButton 均可触发;后退后新导航自动清空前进栈)。
22
- **页签右键菜单**(对齐 VS Code 分组):添加到对话 / 关闭·关闭其他·关闭右侧标签页·关闭已保存·全部关闭
23
- (`Ctrl+F4` 关当前页签)/ 复制路径·复制相对路径 / 在文件资源管理器中显示·在资源管理器视图中显示 /
24
- 固定(📌 排到最前、隐藏 ×、随工作区持久化;**固定 = 保护**,批量关闭永不误关固定页签)。
25
- 关闭前对未保存页签静默落盘;浏览器无法实现的条目(向右拆分 / 移动到新窗口)不提供。
26
- **引用插入**:`Ctrl+U`(选区)/ 页签右键 / 文件树右键 都走同一条 `appendReference`,
27
- **detect 投影**坐标插入 chip,插入点跟随**输入框当前光标**(`caretSpan()`;无光标信息时回落文档末尾,
28
- 选中区域则插在选区右边界而不替换)(修掉「连续添加多个引用时既有 chip 被销毁并重复为纯文本」);
29
- 通道被拒时降级为就地纯文本(保留既有 chip 与正确分隔空格),两条通道都不可用则**不写任何内容**并提示重试。
30
- - **命令栏 + 指令系统**(v0.2.0):`Ctrl+Shift+P`(或 `F1`)唤出 VS Code 式命令面板——输入即过滤(中文/分类/命令 id
31
- 均可命中)、`↑↓` 选择、`Enter` 执行、`Esc` 关闭,每行显示命令名/分类/当前键位;候选按**可用性**过滤
32
- (需要打开文件的命令在空编辑器时自动隐藏)。命令目录即单一数据源(`ui/commandCatalog`):命令栏、快捷键设置页、
33
- 全局键位派发、Monaco 右键菜单全部从同一张表读取,**新增一条能力只需追加一条命令定义**。
34
- 注册表经 `window.__edrvCommands__` 对外暴露,第三方/控制台可 `register()` 注册命令、
35
- `addRuntimeKeybinding()` 绑运行时键位(不落设置 schema)。开箱 19 条命令:
36
- 保存 / 快速打开 / 在文件浏览器中打开 / 显示所有命令 / 切换侧边栏 / 工作区搜索 /
37
- 后退·前进 / 上下页签 / **关闭当前页签** / 上下编辑行 / 转到定义 / 查找引用 / 触发 AI 补全 /
38
- 配置代码片段 / 插入代码片段 / 选中内容加为引用。
39
- - **代码片段**(v0.3.0,VS Code 兼容 `.code-snippets`):`Ctrl+Shift+P` → 「代码片段:配置代码片段」
40
- 打开**居中浮窗**(现有片段文件列表 + 新建入口),选文件后在 Monaco 编辑器中按普通文件编辑
41
- (JSON 高亮 / 保存即生效 / 支持 `scope` 字段)。片段库分**全局**(`~/.dsh/snippets/`,所有项目生效)
42
- 与**项目**(`<工作区>/.dsh/snippets/`,随仓库共享)两处;文件名即语言
43
- (`lua.code-snippets` lua 文件生效,`global.code-snippets` → 全语言),
44
- 新建时可选生效语言。编辑 `.lua` 等文件时,前缀(`prefix`)经 **IntelliSense 补全**列出
45
- (片段图标 + `body` 预览,`Tab`/`Enter` 展开,`$1`/`${2:默认值}` 占位符与 `$TM_*` 变量可用);
46
- 也可 `Ctrl+Shift+P` 「代码片段:插入代码片段」按语言筛选后插入到光标处。
47
- 文件列表/读取/保存经 RPC `snippets.list/read/save/remove/entries`;保存后自动刷新补全缓存。
48
- - **快捷引用**(v0.3.0,v0.3.1 修复可用性判定):编辑器中选中内容后 `Ctrl+U` 把选中行范围加为**引用**
49
- (送入对话上下文,等价 VS Code 的「Add Selection to Chat」)。无编辑器/无选中时该键位**不吞键**,正常输入不受影响。
50
- ⚠️ v0.3.0 因编辑器可用性探测选择器 `textarea.inputarea` 被 Monaco 的 **EditContext** 输入通道取代
51
- (有该 API 的浏览器下 Monaco 不再创建 textarea),导致本命令与其它 12 条 `needsModel` 命令被静默隐藏、
52
- 按键被放行;v0.3.1 已改为与输入实现无关的判据(`.edrv-editor-row .monaco-editor`)。
53
- - **LSP 智能(编辑器内)**:`F12`/右键「转到定义」+ `Shift+F12`「查找所有引用」+ `Ctrl+点击` 引用导航
54
- (v0.4.2 起统一委托完整 Monaco 原生命令:**多结果弹 Peek 让用户选**,单结果直跳,
55
- 取不到定义时自动降级到「转到引用」)+ `Ctrl+hover` 可导航标识符下划线提示;
56
- 定义查找带降级链(definition → declaration → 引用推导),参数/局部变量(`this`、`pTarget` 这类)
57
- 同样能跳到声明,不再只有方法可用。
58
- ⚠️ v0.3.4 修复「LSP 一直显示未启动 / 重启后定义与引用失效」:根因是 host 侧**文档跟踪(tracker)与
59
- 服务器注册表(manager)是两套独立结构**——「重新检测 / 保存配置 / 运行时重装」只摘除 manager 条目、
60
- 保留 tracker 计数,此后 `tracker.open()` 对已打开文档恒返回 `false`(不再触发 acquire),
61
- `sync` 直接以「语言服务器未注册」失败且客户端反复重试也不收敛,该语言**永久不可用直到重启宿主**。
62
- 修复三处:①`sync` manager 缺条目时**自愈补建**(计数不重复增,见 `resolveServer`);
63
- ②重置类操作**同时清 tracker**(新增 `tracker.reset(root,lang)` 与 manager 同范围成对调用);
64
- ③设置页状态改为**反映真实运行相位**(原先 `edrv.lsp.detect` 硬编码 `idle`,卡片恒显「未启动」)。
65
- 另修客户端:定义/引用查询失败不再静默吞成空结果(改为上抛可见状态),会话 id EditorView 直写并广播,
66
- 不依赖服务订阅形状。附带回收宿主退出时残留的 LSP 子进程(原先 `ctx.effect` 清理不覆盖进程退出)。
67
- ⚠️ v0.4.0 修复「引用查找完全没反应」:该症状与上面的 tracker/manager 失步**无关**,根因在编辑器侧——
68
- 离线 Monaco 被裁剪掉 `gotoSymbol`/`peekView` 贡献,原生 References Peek 动作不存在。详见下方
69
- 「Monaco 离线分发」。现「多条引用 原生 Peek」已恢复可用。
70
- ⚠️ v0.4.1 修复「差异文件里引用/定义全空」:根因是**路径形态不一致**。差异记录 `rec.path` 取自工具参数
71
- `file_path`(**绝对路径**),而 LSP 文档键与 `server.sync()` 拼 `file://` URI 的口径都是**工作区相对路径**——
72
- 不归一化时绝对路径会被拼成 `<root>/<root>/Assets/...` 这种畸形 URI,服务器视其为不存在的文档,
73
- `didOpen` 静默落空,于是**引用/定义/hover/符号全部返回空且没有任何报错**。
74
- 实测同一文件:相对路径 `references=3 / symbols=37`,绝对路径 `0 / 0`——这正是「差异里点开的文件查引用没反应」的原因
75
- (差异入口传的就是绝对路径)。修复:新增 `toWorkspacePath()`(`src/lsp/uri.ts`)并在 `edrv.lsp.*` **入口统一归一化**
76
- (放入口而非 server 内,否则同一文件会因形态不同产生两条 tracker 记录、引用计数翻倍),
77
- `server.sync` 另加防御性兜底,杜绝畸形 URI。
78
- 同一根因还导致**行内差异标记不显示**(`EditorView` 用 `rec.path === active` 比较,绝对 vs 相对恒不相等),
79
- 已改为经 `relativeOf` 归一后比较,连同「差异 N 文件」导航一起去修复。
80
- ⚠️ v0.4.2 修复「Ctrl+点击多结果直接跳走、不给选择」:根因是**插件自研的 Ctrl+点击路径本身**——
81
- 它在「0 条其它引用」时降级为「查定义 → 跳 `defs[0]`」,于是遇到**有多个定义但无其它引用**的标识符
82
- (实测 `IsReady` 2 个定义)就硬跳第一个,用户没有选择余地;换用完整 Monaco 后原生 Ctrl+点击
83
- (`gotoDefinitionAtPosition`)同时激活,两套路径还互相竞争。
84
- 现**统一委托原生**:Ctrl+点击 / `F12` / `Shift+F12` 全部走 Monaco 原生命令
85
- (`editor.action.revealDefinition` / `editor.action.referenceSearch.trigger`),
86
- 多结果弹 Peek 让用户选(原生 `gotoLocation.multipleDefinitions` 默认 `peek`),
87
- 取不到定义时按 `alternativeDefinitionCommand` 自动降级为「转到引用」。
88
- 自研鼠标监听(`bindLspEditor`)与相关死代码已删除。实测:Ctrl+点击 2 定义 → `Definitions (2)`、
89
- 0 定义 3 引用 → `References (3)`、10 引用 → `References (10)`,均弹 Peek 可选。
90
- - **差异审查**:Host 捕获 agent 的 `edit`/`write`(`tools/result`),客户端统一使用**唯一一个挂在 DSH `conversation.input.dock` 的 DiffBox 实例**:
91
- 编辑器未打开时显示紧凑「差异 N 个文件 · 查看下一个」按钮(点击自动打开侧栏编辑器并聚焦差异);编辑器打开后 dock 切换为
92
- 完整操作条(Keep / Undo / 跳转 / 回滚 / 归档对比),不会再出现第二个差异栏。header 差异角标 +
93
- DiffLauncher 全局总览 + 归档/批次回滚;状态持久化到工作区旁车(`.dsh-edit-review.json`,重启不丢)。
94
- ⚠️ v0.4.3 修复「冲突差异可看不可点」:pending hunk 的 `newText` 已被后续修改覆盖(定位失败)时,host 会标记
95
- `conflict` 并保留在待处理列表供复核,但单文件 Keep/Undo 原先只认「可定位」差异 → 这类文件恒留在差异栏且按钮置灰,
96
- 而全局 Keep All / Undo All 却是亮的。现在单文件 Keep/Undo 覆盖冲突差异:Keep 记账后归档;Undo 对已不在文件中的
97
- 差异不改动文件、直接按不采纳归档(状态栏提示「其中 N 处已不存在于文件,未改动」)。
98
- - **Monaco 离线分发**:`assets/vendor/monaco` AMD 构建随包发布,经 `/edrv/vendor/*` 前缀路由提供,全离线可用。
99
- 版本锁定 `monaco-editor@0.42.0-dev-20230906`(commit `e7d7a5b0`),由 `node scripts/vendor-monaco.mjs [--force]`
100
- npm registry 复现铺入(内含版本+commit 双重断言,防静默换错构建)。
101
- ⚠️ v0.4.0 修复「查找引用完全没反应」:旧 vendor 是**被裁剪的**构建,缺 `gotoSymbol` / `peekView` 贡献模块,
102
- 于是 `editor.action.referenceSearch.trigger` 等动作在运行时根本不存在,`Ctrl+点击`(多条引用)与
103
- `Shift+F12` 走原生 Peek 的路径静默失败(`triggerReferencePeek` 取不到动作即 `return false`,无任何提示)。
104
- 现已换为**官方完整构建**(`referencesController` / `peekView` / `gotoSymbol` 齐备),并同步把该静默失败
105
- 改为状态栏明确提示。本地化按白名单只保留英文基线 + 简体中文(`KEEP_NLS`),其余 16 个语言包不随包分发;
106
- `sourceMappingURL` 在铺入时剥离(官方指向未分发的 `min-maps/`,不剥会持续 404)。
3
+ > DSH 上的**类 VSCode 编码体验**:Monaco 文件编辑器 + Agent 差异审查 + LSP 智能。
4
+ > 由 `@dsh-external/dsh-edit-review` 重构而来。
5
+
6
+ - 📝 **同屏编辑**:DSH 0.1.5+ 官方右侧 Sidebar,AI 对话与文件编辑同屏
7
+ - 🔍 **差异审查**:Keep / Undo / 回滚 / 归档,状态持久化重启不丢
8
+ - 🧠 **LSP 智能**:转到定义 / 查找引用 / Peek 多结果选择
9
+ - ⌨️ **命令面板**:`Ctrl+Shift+P`,19 条命令开箱即用,可编程扩展
10
+
11
+ ## 目录
12
+
13
+ - [特性](#特性)
14
+ - [安装](#安装)
15
+ - [使用指南](#使用指南)
16
+ - [配置](#配置)
17
+ - [截图](#截图)
18
+ - [开发](#开发)
19
+ - [常见问题](#常见问题)
20
+ - [更新日志](#更新日志)
21
+
22
+ ## 特性
23
+
24
+ ### 1. 侧边栏文件编辑(推荐形态)
25
+
26
+ 检测到 DSH 0.1.5+ 官方右侧 Sidebar(`ctx.sidebarRightTabs` / `ctx.sidebarRight`)时,
27
+ 编辑器注册为官方侧边栏 Tab,AI 对话(中央)与文件编辑(右侧)同屏,支持官方
28
+ 多标签 / 分栏 / 浮出 / 全屏,打开路由即开即展开,官方引导页提供入口。
29
+
30
+ - **形态优先级**:官方 Sidebar > [dsh-better-sidebar](https://github.com/omdsh-dev/DSH-better-sidebar)
31
+ (桥已归档,仅作旧版回退)> 中央文件编辑页签(零新依赖完整可用);
32
+ 编辑器顶部与设置页「兼容性」子 Tab 给出对应引导。
33
+ - **文件链接(DSH 0.1.5+)**:聊天 / 文件树链接经官方 `ctx.sidebarRight.openResource`
34
+ 直达右侧栏;「文件链接使用工具」为 自动 / VSCodeMode 时以 extension 档认领
35
+ `dsh-resource://file/**`(Monaco 打开,含行号定位),为「官方侧边栏」档时走
36
+ 官方文本查看器;畸形地址自动回落官方查看器。
37
+ - **文件页签**:脏点 / 关闭 / 「+」打开 / 右键菜单 / 固定(📌 排最前、隐藏 ×、
38
+ 随工作区持久化;**固定 = 保护**,批量关闭永不误关固定页签)。
39
+ - **页签右键菜单**(对齐 VS Code):添加到对话 / 关闭·关闭其他·关闭右侧·关闭已
40
+ 保存·全部关闭(`Ctrl+F4` 关当前)/ 复制路径·复制相对路径 / 在文件资源管理器
41
+ (视图)中显示。关闭前未保存页签静默落盘;浏览器无法实现的条目(向右拆分 /
42
+ 新窗口)不提供。
43
+ - **Monaco Editor**:语法高亮 / 行号 / `Ctrl+F` / `Ctrl+G` / `Ctrl+S` /
44
+ 700ms 防抖自动保存;顶部工具栏显示 路径 / 语言 / Ln,Col / 保存状态,提供
45
+ 差异 / 侧边栏 / 刷新入口。
46
+ - **导航历史**:后退 / 前进跨文件恢复焦点位置(工具栏 `←`/`→`、`Alt+←/→`、
47
+ `Ctrl+Alt+-` / `Ctrl+Shift+-`、鼠标侧键 XButton 均可触发);后退后新导航
48
+ 自动清空前进栈。
49
+
50
+ ### 2. 命令栏与指令系统(v0.2.0
51
+
52
+ `Ctrl+Shift+P`(或 `F1`)唤出 VS Code 式命令面板:输入即过滤(中文 / 分类 /
53
+ 命令 id 均可命中),`↑↓` 选择、`Enter` 执行、`Esc` 关闭,每行显示 命令名 /
54
+ 分类 / 当前键位;需要打开文件的命令在空编辑器时自动隐藏。
55
+
56
+ - **单一数据源**:命令目录(`ui/commandCatalog`)同时驱动命令栏、快捷键设置页、
57
+ 全局键位派发、Monaco 右键菜单——新增能力只需追加一条命令定义。
58
+ - **开放注册表**:`window.__edrvCommands__` 暴露 `register()` 注册命令、
59
+ `addRuntimeKeybinding()` 绑运行时键位(不落设置 schema)。
60
+ - **开箱 19 条命令**:保存 / 快速打开 / 在文件浏览器中打开 / 显示所有命令 /
61
+ 切换侧边栏 / 工作区搜索 / 后退·前进 / 上下页签 / 关闭当前页签 / 上下编辑行 /
62
+ 转到定义 / 查找引用 / 触发 AI 补全 / 配置代码片段 / 插入代码片段 /
63
+ 选中内容加为引用。
64
+
65
+ ### 3. 代码片段(v0.3.0,VS Code 兼容)
66
+
67
+ 支持 `.code-snippets`:`Ctrl+Shift+P` →「代码片段:配置代码片段」打开**居中浮窗**
68
+ (现有片段文件列表 + 新建入口),在 Monaco 中按普通文件编辑(JSON 高亮 /
69
+ 保存即生效 / 支持 `scope` 字段)。
70
+
71
+ - **两处片段库**:全局 `~/.dsh/snippets/`(所有项目)+ 项目
72
+ `<工作区>/.dsh/snippets/`(随仓库共享);文件名即生效语言
73
+ (`lua.code-snippets` → 仅 lua,`global.code-snippets` → 全语言),
74
+ 新建时可选生效语言。
75
+ - **IntelliSense 补全**:编辑 `.lua` 等文件时 `prefix` 自动列出(片段图标 +
76
+ `body` 预览,`Tab` / `Enter` 展开,`$1` / `${2:默认值}` 占位符与 `$TM_*`
77
+ 变量可用);也可「插入代码片段」按语言筛选插入光标处。
78
+ - RPC:`snippets.list/read/save/remove/entries`;保存后自动刷新补全缓存。
79
+
80
+ ### 4. 快捷引用(v0.3.0)
81
+
82
+ 选中内容后 `Ctrl+U` 把选中行范围加为**引用**(送入对话上下文,等价 VS Code
83
+ 「Add Selection to Chat」);无编辑器 / 无选中时该键位不吞键,正常输入不受影响。
84
+ (v0.3.1 修复可用性判定:改用与输入实现无关的 `.edrv-editor-row .monaco-editor`
85
+ 判据,替换被 Monaco EditContext 输入通道取代的 `textarea.inputarea` 探测。)
86
+
87
+ - **插入点跟随输入框光标**(`caretSpan()`;无光标信息回落文档末尾,选中区域插在
88
+ 选区右边界而不替换),修复「连续添加多个引用时既有 chip 被销毁并重复为纯文本」。
89
+ - 通道被拒时降级为就地纯文本(保留既有 chip 与正确分隔空格);两条通道都不可用
90
+ 则不写任何内容并提示重试。
91
+
92
+ ### 5. LSP 智能(编辑器内)
93
+
94
+ `F12` / 右键「转到定义」、`Shift+F12`「查找所有引用」、`Ctrl+点击` 引用导航、
95
+ `Ctrl+hover` 可导航标识符下划线提示。v0.4.2 起统一委托完整 Monaco 原生命令:
96
+ **多结果弹 Peek 让用户选**,单结果直跳,取不到定义自动降级「转到引用」。
97
+
98
+ - 定义查找带降级链(definition declaration 引用推导);参数 / 局部变量
99
+ (`this`、`pTarget` 这类)同样能跳到声明。
100
+ - 相关踩坑与修复见 [常见问题](#常见问题) 1–4 条。
101
+
102
+ ### 6. 差异审查(核心能力)
103
+
104
+ Host 捕获 agent 的 `edit` / `write`(`tools/result`),客户端统一使用**唯一一个**
105
+ 挂在 DSH `conversation.input.dock` DiffBox 实例:
106
+
107
+ - 编辑器未打开 → 紧凑「差异 N 个文件 · 查看下一个」按钮,点击自动打开侧栏编辑器
108
+ 并聚焦差异;编辑器打开后 → 完整操作条(Keep / Undo / 跳转 / 回滚 / 归档对比),
109
+ 不会再出现第二个差异栏。
110
+ - header 差异角标 + DiffLauncher 全局总览 + 归档 / 批次回滚;状态持久化到工作区
111
+ 旁车 `.dsh-edit-review.json`(重启不丢)。
112
+ - v0.4.3 起单文件 Keep / Undo 覆盖**冲突差异**(pending hunk 已被后续修改覆盖):
113
+ Keep 记账后归档;Undo 对已不在文件中的差异不改动文件、直接按不采纳归档
114
+ (状态栏提示「其中 N 处已不存在于文件,未改动」)。
115
+
116
+ ### 7. Monaco 离线分发
117
+
118
+ `assets/vendor/monaco` AMD 构建随包发布,经 `/edrv/vendor/*` 前缀路由全离线可用。
119
+ 版本锁定 `monaco-editor@0.42.0-dev-20230906`(commit `e7d7a5b0`),用
120
+ `node scripts/vendor-monaco.mjs [--force]` 从 npm registry 复现铺入
121
+ (版本 + commit 双重断言,防静默换错构建)。
122
+
123
+ - v0.4.0 起为**官方完整构建**(`referencesController` / `peekView` / `gotoSymbol`
124
+ 齐备),修复「查找引用完全没反应」;本地化只保留英文基线 + 简体中文
125
+ (`KEEP_NLS`),`sourceMappingURL` 铺入时剥离(官方指向未分发的 `min-maps/`);
107
126
  构建后 vendor 约 10.3MB(替换前 21.5MB)。
108
- - **PDF 浏览与编辑**(v0.1.55,借鉴开源 [pdf.js](https://github.com/mozilla/pdf.js),Apache-2.0):
109
- 打开 `.pdf` 文件在编辑区页签内直接浏览(连续滚动/翻页/缩放/文本选择,cmaps 支持中文渲染);
110
- 工具条进入注释编辑:✎ 文本框 / 🖌 画笔 / 🖍 高亮,`Ctrl+S` 或 💾 保存把批注写回原文件
111
- (`pdfDocument.saveDocument()` → `edrv.saveBinary` base64 回写,工作区边界 + 32MB 上限约束)。
112
- 引擎离线 vendor 于 `assets/vendor/pdfjs`(build + viewer 组件 + cmaps + standard_fonts,约 5MB),
113
- 与 Monaco 同模式经 `/edrv/vendor/pdfjs/*` 分发;升级版本用 `node scripts/vendor-pdfjs.mjs [版本]`。
114
- 能力边界:注释级编辑(浏览器开源方案不支持无损改写既有正文文字);加密 PDF 暂不支持。
115
- - **文件管理侧边栏**(类 VSCode 活动栏 + 面板):编辑器内嵌活动栏 + 可拖拽调宽的面板区;首期「资源管理器」= 懒加载目录树
116
- (展开目录实时读取、点文件在编辑器打开、差异角标、活动文件高亮、`edrv:refresh`/手动 ⟳ 刷新、`Ctrl+B` 显隐并持久化;
117
- 侧栏形态默认收起以节省面板宽度;拖拽调宽下限 = 最小宽度(默认 300,设置 → VSCodeMode → 通用「编辑器」可调 180–560),
118
- 拖拽低于最小宽度自动收起)。面板通过注册表装配(`ctx.provide('edrvSidebarPanels')`),新增面板只加一条注册,不改编辑器布局。
119
- - **规则管理**(v0.1.49 初版 / v0.1.50 交互优化,参考 Codebuddy):活动栏「规则」面板,管理 Cursor/Codebuddy 式 `.mdc` 规则文件——
120
- 「用户规则」(`~/.dsh/rules/`,全局生效)与「项目规则」(`<工作区>/.dsh/rules/`,随仓库共享)双 Tab;
121
- 每条规则显示文件名/相对路径,第二行类型徽标(总是=`alwaysApply`、自动=`globs`、手动=仅索引)与描述,
122
- 右侧常驻 编辑/删除 图标与滑动启用开关(行 hover 高亮;开关只改写 frontmatter `enabled` 行,即时生效无需重启);
123
- 描述随面板宽度自适应截断(保底 8 字),面板宽 < 420px 自动隐藏路径提示。
124
- 新建/编辑提供面包屑头部 + 规则类型下拉(总是/自动/手动)与 描述/globs 控件,与原始 `.mdc` 文本域双向同步
125
- (控件改写 frontmatter,文本域回读控件;`enabled` 与其余键原样保留)。启用的规则经 host `systemPrompt.section`(order 400)
126
- 注入每次装配:用户规则全局注入,项目规则按会话工作区注入(单条 16KB/单域 64KB 截断预算;旧版 DSH 无 systemPrompt
127
- 服务时自动降级为纯管理 UI)。RPC:`rules.list/read/save/remove/toggle`。
128
- - **MCP 可视化管理**(设置 → VSCodeMode):子 Tab「我的 MCP」(profile 全局)+「项目 MCP」(各项目根 `.mcp.json`)。
129
- 项目级 MCP 对齐 Claude Code/Cursor:配置存于项目根目录 `.mcp.json`(`mcpServers`),随仓库共享;
130
- 可查看各项目连接状态/工具、添加(stdio / streamable-http)、刷新、启用/禁用、删除。工具全局生效。
131
- - **插件自带技能组**(v0.3.3,随包 `skills/`):插件把一组 SKILL.md 随包分发并注册进 DSH 技能系统
132
- (自定义 skill provider,`ctx.skills.registerProvider`),**装了本插件即可用**,无需手工放文件到 `~/.dsh/skills`。
133
- 技能名统一前缀 `dsh-vscodemode-`,当前收录 **`dsh-vscodemode-mcp`**(MCP 配置与使用指南:
134
- 两种作用域 / `.mcp.json` 写法 / `mcp.*` RPC / 命名与冲突 / 工作区隔离 / 故障排查表)。
135
- 用户提出「加个 MCP / MCP 连不上 / 项目 MCP」时,agent 会加载该技能按图索骥。
136
- 装载状态见设置 → VSCodeMode →「兼容性」的「插件技能组」一行;编辑 SKILL.md 即时生效(fs.watch → invalidate)。
137
- - **会话性能管理**(设置 → VSCodeMode →「性能优化」):DSH 启动会回放 `~/.dsh/sessions` 全部会话
138
- (V8 展开约 10×,会话越多越吃内存,可能 OOM)。该子页提供
139
- ① 全工作区会话盘点(体积/活跃度/新旧);② 巨型/旧会话**移出到归档**(`~/.dsh/sessions-archive`,可逆、
140
- 免重启即从下次启动的回放中剔除)与恢复/清除;③ **DSH 内置压缩调优**:一键把更低的
141
- `compaction-basic`/`tool-result-pruner` 阈值写入 profile `cordis.patch.yml`(带备份与撤销,重启生效);
142
- ④ 侧车摘要接口指引。对话 header 另有**会话体积指示器**(`edrv-perf-size`,≥1MB 显示、超 2MB 琥珀、超 8MB 红),
143
- 引导"一次任务一个短会话"。
144
- - **外部改动自动同步**(未发布,待随下个版本发布):编辑器不再是「只信自己的缓冲」——磁盘文件被外部改动
145
- (其他编辑器 / Unity / 脚本 / agent 工具 / 同步盘)后自动跟进,不必再手点 ⟳。
146
- **观测**:客户端每 **1.5s** 把已打开页签路径批量交给 host `edrv.versions`(一次请求多条 `fs.stat`,
147
- 标签页隐藏时整轮跳过),与本地的磁盘版本基线比对;文件树对应目录同时在 host 侧失效、
148
- 客户端按 `edrv:file-changed` 事件去抖强制重列(外部新增/删除/改名都能看到)。
149
- **判定**:版本变化后**必须再比一次内容**——host 版本令牌含 `ctime`,格式化工具/同步盘的
150
- 「同字节重写」也会让它变化,只看版本会把没变的内容反复重载(打断光标与滚动)。
151
- 内容一致 → 只推进基线(不重载);内容不同且缓冲**干净** → 自动刷入并提示「已同步外部修改」;
152
- 内容不同且缓冲**有未保存编辑** → 绝不覆盖,编辑区上方出现提示条(重新加载 / 覆盖磁盘 / 保留本地),
153
- 状态栏同时出现「⚠ 外部已修改」;文件被外部删除 → 提示「已被外部删除」,缓冲保留。
154
- **保存护栏**:保存带回上次读取的版本令牌,host 用 `replaceIfVersion` 守卫写入——
155
- 磁盘被外部改过时**拒绝保存**并提示「文件已被外部修改」,由用户显式选择重新加载或用编辑器内容覆盖;
156
- 冲突未处理期间自动保存被抑制(避免用陈旧缓冲反复盖掉外部改动)。
157
- 老 host(无该 RPC)自动降级为无同步、无护栏,不报错。
158
- - **系统集成**(v0.1.53,设置 → VSCodeMode → 通用「系统集成」卡片):
159
- ① **文件管理器右键菜单**——一键把「在 DSH 文件编辑中打开」注册进系统(Windows 资源管理器三类入口 / Linux
160
- Nautilus+Dolphin / macOS Automator 配方),插件卸载自动清理、更新自动恢复;点击经 launcher 打开默认浏览器深链
161
- `?edrvOpen=1&edrvPaths=…`,编辑器直接打开所选文件;DSH 未运行时弹提示。
162
- ② **Unity 外部脚本编辑器**——内置 UPM 包 `com.dsh.editor`(参照 com.unity.ide.traeCN 机制实现
163
- `IExternalEditor` 虚拟安装,无需本地 exe),设置页**一键安装/更新**为 Unity 内嵌包
164
- (复制到 `<项目>/Packages/com.dsh.editor`,自动发现,不改 manifest.json),Unity Preferences →
165
- External Tools 下拉选「DSH 文件编辑」后,双击脚本/Console 报错跳转即在浏览器打开对应文件与行列。
166
-
167
- ## 界面截图
168
127
 
169
- ![侧边栏编辑形态:AI 对话与文件编辑同屏](docs/screenshots/img1.png)
128
+ ### 8. PDF 浏览与编辑(v0.1.55)
129
+
130
+ 打开 `.pdf` 在编辑区页签内直接浏览(连续滚动 / 翻页 / 缩放 / 文本选择,
131
+ cmaps 支持中文渲染);工具条进入注释编辑:✎ 文本框 / 🖌 画笔 / 🖍 高亮,
132
+ `Ctrl+S` 或 💾 保存把批注写回原文件(`pdfDocument.saveDocument()` →
133
+ `edrv.saveBinary` base64 回写,工作区边界 + 32MB 上限约束)。
134
+
135
+ - 引擎离线 vendor 于 `assets/vendor/pdfjs`(build + viewer + cmaps +
136
+ standard_fonts,约 5MB),经 `/edrv/vendor/pdfjs/*` 分发;升级用
137
+ `node scripts/vendor-pdfjs.mjs [版本]`。
138
+ - 借鉴开源 [pdf.js](https://github.com/mozilla/pdf.js)(Apache-2.0)。
139
+ - **能力边界**:注释级编辑(开源方案不支持无损改写既有正文文字);加密 PDF
140
+ 暂不支持。
141
+
142
+ ### 9. 文件管理侧边栏(类 VSCode 活动栏 + 面板)
143
+
144
+ 编辑器内嵌活动栏 + 可拖拽调宽面板区;首期「资源管理器」= 懒加载目录树
145
+ (展开实时读取、点文件打开、差异角标、活动文件高亮、`edrv:refresh` / 手动 ⟳、
146
+ `Ctrl+B` 显隐并持久化),侧栏形态默认收起以节省面板宽度。
147
+
148
+ - 拖拽调宽下限 = 最小宽度(默认 300,设置 → VSCodeMode → 通用「编辑器」
149
+ 可调 180–560),拖拽低于最小宽度自动收起。
150
+ - 面板经注册表装配(`ctx.provide('edrvSidebarPanels')`),新增面板只加一条注册,
151
+ 不改编辑器布局。
152
+
153
+ ### 10. 规则管理(v0.1.49 / v0.1.50,参考 Codebuddy)
154
+
155
+ 活动栏「规则」面板,管理 Cursor / Codebuddy 式 `.mdc` 规则文件:「用户规则」
156
+ (`~/.dsh/rules/`,全局生效)与「项目规则」(`<工作区>/.dsh/rules/`,随仓库
157
+ 共享)双 Tab。
158
+
159
+ - 每条规则显示 文件名 / 相对路径 / 类型徽标(总是 = `alwaysApply`、自动 =
160
+ `globs`、手动 = 仅索引)/ 描述;右侧常驻 编辑 / 删除 与滑动启用开关
161
+ (只改写 frontmatter `enabled` 行,即时生效无需重启)。
162
+ - 新建 / 编辑提供面包屑头部 + 类型下拉与描述 / globs 控件,与原始 `.mdc`
163
+ 文本域双向同步(控件改写 frontmatter,文本域回读控件;`enabled` 与其余键
164
+ 原样保留)。
165
+ - 启用的规则经 host `systemPrompt.section`(order 400)注入每次装配:用户规则
166
+ 全局注入,项目规则按会话工作区注入(单条 16KB / 单域 64KB 截断预算;旧版
167
+ DSH 无该服务时自动降级为纯管理 UI)。RPC:`rules.list/read/save/remove/toggle`。
168
+
169
+ ### 11. MCP 可视化管理(设置 → VSCodeMode)
170
+
171
+ 子 Tab「我的 MCP」(profile 全局)+「项目 MCP」(各项目根 `.mcp.json`,
172
+ 对齐 Claude Code / Cursor,随仓库共享):查看各项目连接状态 / 工具、添加
173
+ (stdio / streamable-http)、刷新、启用 / 禁用、删除。工具全局生效。
174
+
175
+ ### 12. 插件自带技能组(v0.3.3)
176
+
177
+ 一组 `SKILL.md` 随包分发并注册进 DSH 技能系统(自定义 skill provider,
178
+ `ctx.skills.registerProvider`)——**装了本插件即可用**,无需手工放到
179
+ `~/.dsh/skills`。当前收录 **`dsh-vscodemode-mcp`**(MCP 配置与使用指南:
180
+ 两种作用域 / `.mcp.json` 写法 / `mcp.*` RPC / 命名与冲突 / 工作区隔离 /
181
+ 故障排查表)。装载状态见 设置 → VSCodeMode →「兼容性」→「插件技能组」;
182
+ 编辑 SKILL.md 即时生效(fs.watch → invalidate)。
183
+
184
+ - **命名硬约束**:技能名必须 kebab-case(`/^[a-z0-9]+(?:-[a-z0-9]+)*$/`),
185
+ 下划线非法(`@deepseek-ai/dsh-skill` 直接拒绝);本插件另加前缀白名单
186
+ (不以 `dsh-vscodemode-` 开头跳过并告警,避免污染全局技能命名空间)。
187
+ - **frontmatter**:`name`(必填,kebab-case + 前缀)/ `description`(必填,
188
+ 模型靠它判断何时加载)/ `whenToUse`(可选)/ `disable-model-invocation`
189
+ (true = 不进模型目录,仅人工显式调用)/ `user-invocable`(false = 禁止
190
+ 人工显式调用);不接受遗留写法 `disableModelInvocation` / `modelInvocable` /
191
+ `userInvocable`。
192
+ - **装载与降级**:`ctx.inject(['skills'])` 惰性获取(不写进 `inject` 数组),
193
+ skills 服务缺失时插件其余功能不受影响;服务缺失 / 无 `registerProvider` /
194
+ 名冲突 → warn 跳过,不抛错、不影响装配;监听不可用时降级「改动需重载插件」。
195
+ - **为什么自研 provider**:开发形态(junction 安装)下官方
196
+ `@deepseek-ai/dsh-skill-filesystem` 按 realpath 解析 import 会
197
+ `ERR_MODULE_NOT_FOUND`(walk 不到 profile 的 node_modules),且每实例会
198
+ 多拉 chokidar watcher;自研零新依赖、开发 / 正式形态行为一致、可单测。
199
+
200
+ ### 13. 会话性能管理(设置 → VSCodeMode →「性能优化」)
201
+
202
+ DSH 启动回放 `~/.dsh/sessions` 全部会话(V8 展开约 10×,可能 OOM)。该子页
203
+ 提供四项治理手段:
204
+
205
+ - **盘点**:全工作区会话体积 / 活跃度 / 新旧一览(`edrv.perf.inventory`)。
206
+ - **移出归档(可逆)**:巨型 / 旧会话移到 `~/.dsh/sessions-archive`
207
+ (同卷 rename + `.manifest.json`),免重启即从下次启动回放剔除;支持恢复 /
208
+ 清除(`movePlan / moveOut / restore / purgeArchive`)。活跃会话一律拒绝移出。
209
+ - **压缩调优**:一键把更低 `compaction-basic`(0.6 / 0.12)与 `tool-result-pruner`
210
+ (4096)阈值写入 profile `cordis.patch.yml`(标记块 + 备份 `.bak-<ts>`,可撤销,
211
+ 重启生效);⚠️ 压缩只追加事件、**不重写**已持久化日志——**存量瘦身靠
212
+ 「移出到归档」**。
213
+ - **会话体积指示器**:对话 header `edrv-perf-size` ≥1MB 显示、≥2MB 琥珀、
214
+ ≥8MB 红,引导「一次任务一个短会话」。
215
+ - 治理原则:存量靠归档、增量靠压缩调优 + 短会话习惯 + 体积指示器;packChunks
216
+ (chunk 打包存储)为 DSH 默认开启,无需再配置。
217
+
218
+ ### 14. 外部改动自动同步(即将发布)
219
+
220
+ 磁盘文件被外部改动(其他编辑器 / Unity / 脚本 / agent 工具 / 同步盘)后自动
221
+ 跟进,不必手点 ⟳:
222
+
223
+ - **观测**:客户端每 1.5s 把已打开页签路径批量交给 host `edrv.versions`
224
+ (一次请求多条 `fs.stat`,标签页隐藏时整轮跳过),与本地版本基线比对;
225
+ 文件树对应目录同步失效,客户端按 `edrv:file-changed` 事件去抖强制重列。
226
+ - **判定**:版本变化后**必须再比一次内容**(版本令牌含 `ctime`,格式化工具 /
227
+ 同步盘的「同字节重写」也会让它变化);内容一致 → 只推进基线(不重载);
228
+ 内容不同且缓冲**干净** → 自动刷入并提示「已同步外部修改」;内容不同且有
229
+ 未保存编辑 → **绝不覆盖**,编辑区提示条三选一(重新加载 / 覆盖磁盘 /
230
+ 保留本地)+ 状态栏「⚠ 外部已修改」;文件被删 → 提示「已被外部删除」,
231
+ 缓冲保留。
232
+ - **保存护栏**:保存带回上次读取的版本令牌,host 用 `replaceIfVersion` 守卫
233
+ 写入——磁盘被外部改过时**拒绝保存**并提示「文件已被外部修改」,由用户显式
234
+ 选择重新加载或用编辑器内容覆盖;冲突未处理期间自动保存被抑制。
235
+ - 老 host(无该 RPC)自动降级为无同步、无护栏,不报错。
236
+
237
+ ### 15. 系统集成(v0.1.53)
238
+
239
+ 设置 → VSCodeMode → 通用 →「系统集成」卡片,两项能力:
240
+
241
+ **① 文件管理器右键菜单**——一键把「在 DSH 文件编辑中打开」注册进系统:
242
+ Windows 资源管理器三类入口 / Linux Nautilus + Dolphin / macOS Automator 配方;
243
+ 插件卸载自动清理、更新自动恢复;点击经 launcher 打开默认浏览器深链,编辑器
244
+ 直接打开所选文件;DSH 未运行时弹提示。
245
+
246
+ **② Unity 外部脚本编辑器**——内置 UPM 包 `com.dsh.editor`(参照
247
+ com.unity.ide.traeCN 机制实现 `IExternalEditor` 虚拟安装,无需本地 exe),
248
+ 设置页一键安装 / 更新为 Unity 内嵌包(复制到 `<项目>/Packages/com.dsh.editor`,
249
+ 自动发现、不改 manifest.json);Unity Preferences → External Tools 选
250
+ 「DSH 文件编辑」后,双击脚本 / Console 报错跳转即在浏览器打开对应文件与行列。
251
+
252
+ **深链契约**(launcher / Unity 包 / client 三端共用):
253
+
254
+ ```
255
+ http://127.0.0.1:3080/?edrvOpen=1&edrvPaths=<enc1>[,<enc2>…][&edrvLine=N][&edrvColumn=M]
256
+ ```
170
257
 
171
- > dsh-vscode-mode 侧边栏编辑形态:右侧栏(DSH 0.1.5+ 官方 Sidebar / 旧版 betterSidebar)内的
172
- > Monaco 文件编辑器与中央 AI 对话同屏,
173
- > 差异条统一挂在对话输入框上方的原生 dock(编辑器未打开=「差异 N 个文件 · 查看下一个」,
174
- > 打开后=完整 Keep / Undo 操作条)。
258
+ 每段路径独立 `encodeURIComponent`、逗号连接;client 解析后按下方「打开规则」
259
+ 路由,处理完剥离参数防刷新重开,跨源 referrer 守卫防外部网页诱导。
175
260
 
176
- ![文件编辑与差异审查界面](docs/screenshots/img2.png)
261
+ **打开规则(智能路由)**——按首路径类型分派(其余路径:文件进编辑器、
262
+ 文件夹补引用):
177
263
 
178
- ![文件编辑与差异审查界面](docs/screenshots/img3.png)
264
+ | 首路径 | 行为 |
265
+ |---|---|
266
+ | 文件夹,在已注册工作区内 | 弹窗二选一:**使用最近的工作区**(跳转 + 新增对话 + 文件夹引用 + 编辑页)/ **新建工作区**;取消则中止 |
267
+ | 文件夹,不在任何工作区 | 不弹窗,以该文件夹为根注册新工作区 + 新增对话 + 引用 + 编辑页 |
268
+ | 文件,在已注册工作区内 | 有会话 → 打开最近对话 + 编辑器展开(行列透传);无会话 → 新建对话 + 文件引用 + 展开 |
269
+ | 文件,不在任何工作区 | 打开最近一次对话 + 编辑器展开 |
270
+ | 文件,无任何工作区 / 对话 | 以文件父目录注册工作区 + 新建对话 + 引用 + 编辑器打开 |
271
+
272
+ **页面复用**:launcher 先向 host 投递待打开请求(`edrv.external.handoff`)——
273
+ 已打开的 DSH 页面(3s 移交轮询)就地执行打开规则,**不重复开新页**;2s 未领取
274
+ (页面刚关 / 后台节流)或无活跃页面时回退打开新页(URL 深链)。时序:等待会话 /
275
+ 工作区列表就绪(≤15s);`sessions.create / workspaces.create` 为 DSH 官方服务
276
+ 方法;引用插入轮询输入门面就绪(忙态自动降级纯文本)。
277
+
278
+ **各平台注册细节**:
279
+
280
+ - **Windows**:`assets/shell/dsh-open.cs` 复制到 `~/.dsh/dsh-vscode-mode/shell/`
281
+ 并用 .NET Framework 4.x `csc.exe` 编译为 `dsh-open.exe`(WinExe 无闪窗;
282
+ csc 缺失自动降级 `dsh-open.ps1`);写三类 HKCU 键
283
+ `HKCU\Software\Classes\{\*,Directory,Directory\Background}\shell\DSHEditor`
284
+ (显示名 + Icon `dsh-whale.ico` + command,首次注册前 `reg export` 备份)。
285
+ 全部 reg/csc 调用走 host `subprocess.spawn` argv 数组(stdio `inherit`,
286
+ 受管环境禁管道),无 shell 插值。
287
+ - **Linux**(纯文件写入,无需管理员):Nautilus 右键脚本(`NAUTILUS_SCRIPT_SELECTED_FILE_PATHS`
288
+ 多选)+ KDE Dolphin 服务菜单(`%F` 多选,兼容旧 `kservices5/ServiceMenus/`)。
289
+ - **macOS**:Finder 菜单不做自动生成——设置页「复制 Automator 配方」按步骤创建
290
+ 快速操作(约 1 分钟,脚本指向 `shell/dsh-open.sh`),创建后面板自动检测显示 ✓;
291
+ 「移除注册」仅删除引用本插件 launcher 的 workflow。
292
+ - **行为**:launcher 读同目录 `dsh-open.ini`(`base=` 深链基址,注册时按设置写入)
293
+ → 探测端口(Windows TcpClient / POSIX curl,1s)→ 未运行弹提示(MessageBox /
294
+ osascript / notify-send / zenity)→ 路径编码合并为一个 URL 交给默认浏览器
295
+ (POSIX 侧 `LC_ALL=C` 逐字节 percent-encode,中文 / 空格 / 任意字符安全);
296
+ 改「DSH 服务地址」后点「注册」刷新 ini。
297
+ - **生命周期**:注册成功写 marker(`shell/registered.json`)→ 插件卸载 / reload
298
+ 自动清理注册痕迹,重启 / 更新后自动恢复(开发态反复 reload 不丢注册);点
299
+ 「移除注册」删除 marker,此后不再自动恢复;强杀进程跳过清理时残留键由下一次
300
+ 启动的幂等重写与「移除注册」兜底。
301
+ - RPC:`edrv.integration.status / register / unregister`。
179
302
 
180
- ## 安装(官方 `dsh plugin` 方式,三选一)
303
+ **Unity 包细节**:包源随插件分发于 `unity/com.dsh.editor/`(`package.json` +
304
+ `Editor/DshCodeEditor.cs` + asmdef,`"unity": "2019.4"` 基线;虚拟安装
305
+ `dsh-editor://vscode-mode`,`OpenProject` → `Application.OpenURL(深链)`,不生成
306
+ csproj);**打开过滤**:仅文本 / 代码类扩展名(白名单 + `EditorSettings.projectGenerationUserExtensions`
307
+ 用户自定义扩展)交 DSH 打开,其余返回 `false` 交还 Unity 原生(双击预制体进
308
+ 预制体模式、双击场景开场景),对齐官方 `DefaultExternalCodeEditor` 行为;
309
+ 安装 / 更新 = 整目录复制 / 替换为 `<项目>/Packages/com.dsh.editor`(目标已存在
310
+ 且 name 不是 `com.dsh.editor` 时拒绝覆盖),Unity 已打开时切回窗口自动刷新;
311
+ 卸载 = 删除该目录;手动兜底:Package Manager → Add package from disk 选
312
+ `unity/com.dsh.editor`;登记清单存 `~/.dsh/dsh-vscode-mode/unity-projects.json`;
313
+ RPC:`edrv.unity.list / add / remove / install`。
314
+ 安全说明:深链可在编辑器中查看任意绝对路径文件(与用户手动打开等价);保存仍
315
+ 受会话沙箱 `policyOf` 约束,工作区外保存被拒是预期行为。
316
+
317
+ ### 16. SVN 集成(v0.5.0)
318
+
319
+ 底座是 **svn CLI**(跨平台,自动探测 `svn --version` / 工作副本根),
320
+ TortoiseSVN(`TortoiseProc.exe`)仅作 Windows 过渡增强:自研能力覆盖后对应官方项自动隐藏。
321
+
322
+ - **状态与变更**:侧栏「SVN」面板列出工作副本变更(`svn status --xml --no-ignore`),
323
+ 按状态着色与字母徽标、changelist 分组、未版本控制 / 忽略项开关、行内右键动作;
324
+ 文件树行尾同步显示状态徽标。
325
+ - **动作**:更新、刷新变更、与基线比较、加入版本控制、还原(**破坏性动作均带确认**)、
326
+ 清理工作副本(默认只清锁);未覆盖的项回落 TortoiseSVN。
327
+ - **日志弹窗**(对标 TortoiseSVN Revision Log Dialog):过滤语法(空格=AND / `-` 排除 /
328
+ `+` 纳入 / `!` 取反 / `"短语"` / 正则)、From-To 日期区间、列头排序 + 复位、
329
+ 上中下三段布局(列表 / 提交信息 / 变更路径,边界可拖拽)、Actions 徽标、
330
+ 受影响路径灰显或隐藏、Copy from 列、右键菜单、`F5` / `↑↓` 键盘、
331
+ 多选(Ctrl / Shift)与「比较两个修订」、**Stop on copy**、**Show Range 区间**、
332
+ **Include merged revisions**(`-g`,合并进来的修订灰字缩进)、
333
+ Show All(上限 5000 条,超出用区间取)、Statistics 统计窗(期间 / 按作者 / 按日期)、
334
+ 工作副本版号行加粗。
335
+ - **并排差异**:`与上一版本比较`(`cat -r REV` vs `REV-1`)、`比较两个修订`(`-r M:N` 方向按选中顺序)、
336
+ `与工作副本比较`、`某版本 ↔ 工作区`,均复用同一差异视图。
337
+ - **诊断日志**:统一日志器 + `edrv.dlog.*` RPC + 命令栏「查看诊断日志」,
338
+ 排查白屏 / 加载失败时先看它。
339
+ - **RPC**:`svn.status / changes / diffBase / revert / add / log / diffRev / diffPair /
340
+ diffWorking / wcRev / cleanup / update / tortoise`。
341
+
342
+ > 说明:`plans/`(含对标蓝图与实测结论)为本地开发资料,不入库。
343
+
344
+ ## 安装
345
+
346
+ 官方 `dsh plugin` 方式,三选一:
181
347
 
182
348
  ```bash
183
349
  # ① Git 安装(clone + prepare 构建;推荐打固定 tag)
184
- dsh plugin --profile web add github:Lenonss/DSH_VsCodeMode#v0.1.23
350
+ dsh plugin --profile web add github:Lenonss/DSH_VsCodeMode#v0.5.0
185
351
 
186
352
  # ② npm 注册表(发布到 npm 后)
187
353
  dsh plugin --profile web add dsh-vscode-mode
188
354
 
189
355
  # ③ GitHub Release tgz 直装
190
- dsh plugin --profile web add https://github.com/Lenonss/DSH_VsCodeMode/releases/download/v0.1.23/dsh-vscode-mode-0.1.23.tgz
356
+ dsh plugin --profile web add https://github.com/Lenonss/DSH_VsCodeMode/releases/download/v0.5.0/dsh-vscode-mode-0.5.0.tgz
191
357
  ```
192
358
 
193
- > `dsh plugin ...` 是 pnpm 转发器:git 安装会克隆仓库、执行该包 `prepare` 脚本(tsdown 双面构建)后安装,
194
- > 再按 `dsh.bundle` 声明自动加入 profile 的 bundles 层。若 pnpm 提示构建脚本需批准,按提示把 key
195
- > 加到 `~/.dsh/profiles/<profile>/pnpm-workspace.yaml` `allowBuilds` 后重跑。
359
+ > `dsh plugin ...` 是 pnpm 转发器:git 安装会克隆仓库、执行该包 `prepare` 脚本
360
+ > (tsdown 双面构建)后安装,再按 `dsh.bundle` 声明自动加入 profile 的 bundles
361
+ > 层。若 pnpm 提示构建脚本需批准,把 key 加到
362
+ > `~/.dsh/profiles/<profile>/pnpm-workspace.yaml` 的 `allowBuilds` 后重跑。
196
363
 
197
- **安装即生效,无需任何手动配置**:本包自带的 `cordis.patch.yml` 是标准 bundle 自挂载补丁
198
- (`- insert: { id: dsh-vscode-mode, name: dsh-vscode-mode }`),加入 bundles 层后重启
199
- DSH 即自动把插件行挂进 loader 树,**不要**再往 profile 用户层 `cordis.patch.yml` 手写
200
- `insert`(旧的非标准做法,会与本 bundle 行撞同一 id,触发 duplicate loader entry id 启动失败)。
364
+ **安装即生效,无需任何手动配置**:本包自带的 `cordis.patch.yml` 是标准 bundle
365
+ 自挂载补丁(`- insert: { id: dsh-vscode-mode, name: dsh-vscode-mode }`),加入
366
+ bundles 层后重启 DSH 即自动把插件行挂进 loader 树。**不要**再往 profile 用户层
367
+ `cordis.patch.yml` 手写 `insert`(旧的非标准做法,会与本 bundle 行撞同一 id
368
+ 触发 duplicate loader entry id 启动失败)。
201
369
 
202
- 自定义配置(如图标目录 `imageDir`)用 **id 定向覆盖**合并到 bundle 行上,而不是再 insert 一次:
370
+ 自定义配置(如图标目录 `imageDir`)用 **id 定向覆盖**合并到 bundle 行上,
371
+ 而不是再 insert 一次:
203
372
 
204
373
  ```yaml
205
374
  # ~/.dsh/profiles/<profile>/cordis.patch.yml(用户层,应用顺序在 bundle 层之后)
@@ -208,12 +377,85 @@ DSH 即自动把插件行挂进 loader 树,**不要**再往 profile 用户层
208
377
  imageDir: C:/Users/me/Pictures # 可选,默认读插件包内 assets/
209
378
  ```
210
379
 
211
- > 迁移提示:若你之前按旧版指引在 profile 用户层手写过 `insert`(id 恰为 `dsh-vscode-mode`),
212
- > 升级后请把那一段 `insert` 改成上面的 id 定向覆盖(或直接删除),避免与本 bundle 行重复装配。
380
+ > 迁移提示:若你之前按旧版指引在 profile 用户层手写过 `insert`(id 恰为
381
+ > `dsh-vscode-mode`),升级后请把那一段 `insert` 改成上面的 id 定向覆盖
382
+ > (或直接删除),避免与本 bundle 行重复装配。
213
383
 
214
- 更新:`dsh plugin --profile web update dsh-vscode-mode`;卸载:`dsh plugin --profile web remove dsh-vscode-mode`。
384
+ - 更新:`dsh plugin --profile web update dsh-vscode-mode`
385
+ - 卸载:`dsh plugin --profile web remove dsh-vscode-mode`
215
386
 
216
- ## 开发构建(自足,无需 DSH 源码 checkout)
387
+ ## 使用指南
388
+
389
+ ### 打开文件
390
+
391
+ - **文件树**:资源管理器面板点击打开;**文件链接**(DSH 0.1.5+):聊天 / 文件树
392
+ 里的文件链接直达右侧栏编辑器(含行号定位)。
393
+ - **快速打开**:`Ctrl+P`(QuickOpen)——`↑↓` 选择、`Enter` 打开高亮项、
394
+ `Esc` 关闭,鼠标悬停与高亮同步。
395
+ - **差异入口**:对话输入框上方 dock 的「差异 N 个文件 · 查看下一个」按钮。
396
+
397
+ ### 快捷键速查
398
+
399
+ | 快捷键 | 功能 |
400
+ |---|---|
401
+ | `Ctrl+P` | 快速打开文件(QuickOpen) |
402
+ | `Ctrl+Shift+P` / `F1` | 命令面板 |
403
+ | `Ctrl+U` | 选中内容加为引用(Add Selection to Chat) |
404
+ | `Ctrl+S` | 保存(另有 700ms 防抖自动保存) |
405
+ | `Ctrl+F` / `Ctrl+G` | 查找 / 跳转行 |
406
+ | `F12` / `Shift+F12` | 转到定义 / 查找所有引用 |
407
+ | `Ctrl+点击` / `Ctrl+hover` | 引用导航 / 可导航标识符提示 |
408
+ | `Ctrl+B` | 切换文件管理侧边栏 |
409
+ | `Ctrl+F4` | 关闭当前页签 |
410
+ | `Alt+←` / `Alt+→` | 后退 / 前进(跨文件恢复焦点位置) |
411
+ | `Ctrl+Alt+-` / `Ctrl+Shift+-` | 后退 / 前进(同导航历史) |
412
+ | 鼠标侧键 XButton | 后退 / 前进 |
413
+ | `Tab` / `Enter`(补全中) | 展开代码片段 |
414
+
415
+ ### 差异审查流程
416
+
417
+ 1. agent 执行 `edit` / `write` 后,对话输入框上方出现差异 dock。
418
+ 2. 点击「差异 N 个文件 · 查看下一个」打开侧栏编辑器并聚焦差异;编辑器打开后
419
+ dock 变为完整操作条:**Keep**(采纳)/ **Undo**(拒绝)/ 跳转 / 回滚 /
420
+ 归档对比。
421
+ 3. 每条差异处理完成立即归档;DiffLauncher 全局总览支持按批次浏览 + 回滚;
422
+ 状态持久化到 `.dsh-edit-review.json`,重启不丢。
423
+
424
+ ### 引用、片段与 LSP
425
+
426
+ - **快捷引用**:选中内容 `Ctrl+U`(或页签右键 / 文件树右键),插入点跟随输入框
427
+ 光标,送入对话上下文。
428
+ - **代码片段**:`Ctrl+Shift+P` →「配置代码片段」编辑 `.code-snippets`;编辑代码
429
+ 时 `prefix` 自动 IntelliSense 补全,`Tab` / `Enter` 展开。
430
+ - **LSP**:`F12` 转到定义(多结果弹 Peek 选择)、`Shift+F12` 查找引用、
431
+ `Ctrl+点击` 导航;取不到定义自动降级「转到引用」。
432
+
433
+ ## 配置
434
+
435
+ 设置 →「VSCodeMode」页:
436
+
437
+ | 分区 | 说明 |
438
+ |---|---|
439
+ | 通用 | 编辑器宽度(180–560)等 / 系统集成卡片 / 文件链接使用工具 / 开发形态开关 |
440
+ | 我的 MCP / 项目 MCP | MCP 服务器可视化管理(stdio / streamable-http) |
441
+ | 性能优化 | 会话盘点 / 移出归档 / 压缩调优 / 侧车摘要指引 |
442
+ | 兼容性 | 兼容性报告(外部插件探测、路由 / 重复装配护栏)、插件技能组装载状态、旧版形态引导 |
443
+
444
+ ## 截图
445
+
446
+ ![侧边栏编辑形态:AI 对话与文件编辑同屏](docs/screenshots/img1.png)
447
+
448
+ > 右侧栏(DSH 0.1.5+ 官方 Sidebar / 旧版 betterSidebar)内的 Monaco 文件编辑器
449
+ > 与中央 AI 对话同屏;差异条统一挂在对话输入框上方的原生 dock(编辑器未打开 =
450
+ > 「差异 N 个文件 · 查看下一个」,打开后 = 完整 Keep / Undo 操作条)。
451
+
452
+ ![文件编辑与差异审查界面(二)](docs/screenshots/img2.png)
453
+
454
+ ![文件编辑与差异审查界面(三)](docs/screenshots/img3.png)
455
+
456
+ ## 开发
457
+
458
+ ### 构建(自足,无需 DSH 源码 checkout)
217
459
 
218
460
  ```bash
219
461
  pnpm install # 安装 devDeps(typescript/tsdown/@types/node/@types/react/react/vitest)
@@ -223,75 +465,14 @@ pnpm test # vitest 纯函数用例
223
465
  npm pack # 产物 tgz(含 lib/assets/src/cordis.patch.yml)
224
466
  ```
225
467
 
226
- `scripts/build.sh` 已被 `dev_build_plugin` 等注入工具调用(本地标准构建)。
468
+ `scripts/build.sh` `dev_build_plugin` 等注入工具调用(本地标准构建)。
227
469
  `prepare` 脚本 = 构建,git 安装 / npm publish 都会自动执行。
228
470
 
229
- ## CI(GitHub Actions
471
+ ### 开发形态(devForm
230
472
 
231
- - `.github/workflows/ci.yml`:push/PR install typecheck test build `npm pack` 校验 + 上传 tgz。
232
- - `.github/workflows/release.yml`:打 `v*` tag → 同上构建 → GitHub Release(附 tgz)→
233
- **若配置了 `NPM_TOKEN` secret** 则同时 `npm publish`(npm 通道)。
234
- 未配 NPM_TOKEN 时仅 GitHub Release 通道,不影响安装。
235
-
236
- ## 源码结构
237
-
238
- ```
239
- src/
240
- ├── index.ts Host 入口:name/inject/apply(薄装配,含兼容性报告启动日志)
241
- ├── shared/ ★ 双面契约(禁 node/react):types.ts(记录/归档/摘要)+ rpc.ts(11 个方法类型化)
242
- │ + compat.ts(兼容性报告形状)+ mcp.ts(MCP 契约)
243
- ├── compat.ts ★ Host 兼容层:身份常量、外部插件探测、路由/重复装配护栏、依赖守卫、兼容性报告
244
- ├── devForm.ts Host 开发形态管理:link:/junction 安装切换(RPC vscode.devForm* + 设置页开关)
245
- ├── model.ts Host 纯域逻辑(可单测):normalize/markDecision/resolved/summary/reconstruct/批次/归档
246
- ├── store.ts Host 存储层:sidecar 读写合并 + 归档持久化 + stale 检测
247
- ├── workspace.ts Host 工作区文件扫描(TTL 缓存)+ 快速打开搜索
248
- ├── revert.ts Host 回滚/删除(fs + subprocess,fs.contains 边界校验)
249
- ├── registry.ts Host 每工作区记录桶注册表
250
- ├── tree.ts Host 目录树纯函数(normalizeRel/toTreeEntries,edrv.listDir 用,可单测)
251
- ├── rules.ts Host 规则管理:.mdc 解析/开关改写/注入渲染(纯函数可单测)+ IO + systemPrompt section 装配
252
- ├── skills.ts Host 插件技能组:随包 skills/ 的 SKILL.md 解析/扫描 + skill provider 注册(可单测)
253
- ├── fileVersions.ts Host 文件新鲜度观察:批查 ctx.fs 版本令牌(edrv.versions)+ 变化时失效目录树索引(可单测)
254
- ├── rpc.ts Host RPC 分发表(类型化 handler 表替代巨型 switch,含 compat)
255
- ├── routes.ts Host webServer 路由(/edrv/rpc、/edrv/assets/*、/edrv/vendor/*,带冲突护栏)
256
- └── client/
257
- ├── index.ts Client 入口:slot 注册(inject=['slots','timer']);官方/betterSidebar/中央页签三形态互斥分流(官方优先)
258
- ├── compat.ts ★ Client 兼容层:设置桥三级降级(webUiSettings→settingsScope)、slot 安全注册、openPath 链式补丁、外部插件常量
259
- ├── sidebarBridge.ts ★ 侧边栏编辑区桥(归档):可选探测 ctx.betterSidebar、注册「文件编辑」Tab、打开路由/角标计数(纯函数可单测)
260
- ├── officialSidebar.ts ★ 官方右侧 Sidebar 桥(DSH 0.1.5+,唯一维护面):探测 sidebarRightTabs/sidebarRight、
261
- │ 两段式注册(类型定义 + keyed slot 正文)、openTab 路由(纯函数可单测)
262
- ├── rpc.ts Client 类型化 fetch 包装 + 诊断日志
263
- ├── events.ts 窗口事件助手(edrv:refresh/open-editor/show-launcher/file-changed;侧栏路由优先、旧页签回退)
264
- ├── watchDecision.ts 外部改动同步纯逻辑(基线/已读版本台账/判定表,可单测)
265
- ├── state/ records.ts(摘要/计数/空差异)+ regions.ts(差异区域/行裁剪)纯函数
266
- ├── monaco/ loader.ts(AMD 加载/语言映射)+ diffRender.ts(差异自绘渲染器)
267
- ├── pdf/ pdfLoader.ts(pdf.js vendor 产物 module-script 加载)+ pdfPanel.ts(PDF 面板控制器:
268
- │ PDFViewer 接线/注释编辑模式/saveDocument 保存回写)
269
- ├── pdfPreview.ts PDF 判定与 base64 编解码纯函数(可单测)
270
- ├── imagePreview.ts 图片判定与 data URL 纯函数(可单测)
271
- ├── diffDock.ts 差异 dock 轮转/文案/形态纯函数(对话 dock 与 DiffBox 共用)
272
- ├── sidebar/ ★ 侧边栏面板系统:registry.ts(注册表,镜像 fileOpeners)+ SidebarView.ts(活动栏/面板区/拖拽调宽)
273
- │ + types.ts(SidebarPanelDef/SidebarCtx)+ panels/FileExplorer.ts(文件树面板 #1)
274
- │ + panels/SearchPanel.ts(搜索面板)+ panels/RulesPanel.ts(规则面板:用户/项目规则 + 开关)
275
- ├── styles/editor.css 编辑区样式(tsdown CSS-inline 注入;含侧栏形态/引导条)
276
- └── ui/ EditorView(编排,tab/side 双形态)/ OfficialSideTab(官方 Sidebar Tab 包装)
277
- / useFileWatch(外部改动轮询:批量版本比对 → 同步动作回调)
278
- / SideEditorTab(betterSidebar Tab 包装,归档)/ QuickOpen
279
- / DiffBox(chat/editor 双模式)/ ConversationDiffDock / DiffBarEmpty / DiffLauncher
280
- / DiffBadge / McpSettings(含「兼容性」子 Tab)
281
- ```
282
-
283
- 随包目录(`package.json` 的 `files`):`lib/`(构建产物)、`assets/`(Monaco/pdf.js vendor + 图标 + launcher)、
284
- `skills/`(插件技能组,见下节)、`src/`(随包发布,便于阅读实现)、`unity/`(内嵌 UPM 包)、`cordis.patch.yml`。
285
-
286
- **兼容层(`src/compat.ts` + `src/client/compat.ts`)**:集中处理与其他插件 / DSH 版本的适配——
287
- 运行时探测 `@deepseek-ai/dsh-mcp-client`、设置桥(`webUiSettings` → `settingsScope`)等外部依赖,
288
- 护栏检测 `/edrv` 路由前缀冲突与本插件重复装配(duplicate loader entry),
289
- `@deepseek-ai/dsh-settings` / `schemastery` 以动态加载引入(缺失时插件仍可加载,设置持久化降级)。
290
- 「VSCodeMode」设置页 →「兼容性」子 Tab 或 RPC `edrv.compat` 可查看完整报告。
291
-
292
- **开发形态(`src/devForm.ts`)**:开发 = profile 中以 `link:` 依赖 + junction 指向工作区的安装。
293
- 「VSCodeMode」设置页 → 通用 里在开发形态开启时显示「关闭开发形态」开关(切回正式版安装,重启生效);
294
- AI 后续开发时可通过 RPC 自动开启/关闭:
473
+ 开发 = profile 中以 `link:` 依赖 + junction 指向工作区的安装。设置通用在开发
474
+ 形态开启时显示「关闭开发形态」开关(切回正式版安装,重启生效);AI 后续开发时
475
+ 可经 RPC 自动开启 / 关闭:
295
476
 
296
477
  ```bash
297
478
  # 读取当前形态(compat 报告亦含 devForm 字段)
@@ -305,171 +486,166 @@ curl -s -X POST http://127.0.0.1:3080/edrv/rpc -H 'content-type: application/jso
305
486
  -d '{"method":"vscode.devFormSet","args":{"enabled":false}}'
306
487
  ```
307
488
 
308
- **扩展缝(VSCode 化后续迭代)**:新能力 = `shared/rpc.ts` 加方法 + `src/rpc.ts` 加 handler +
309
- `client/` 加组件,其余模块零改动;`monaco/*` 是可复用的编辑器服务(资源树/对比/诊断面板共用);
310
- 侧边栏面板系统(`edrvSidebarPanels` 注册表)可承载后续面板(搜索/差异/时间线),`edrv.listDir` 为通用目录树 API。
311
-
312
- ## 插件技能组(`skills/`)
313
-
314
- 插件把技能随包分发:安装本插件后,其技能自动出现在 DSH 技能目录里(模型侧 `<available_skills>`),
315
- 由 `skill` 工具按需加载。实现见 `src/skills.ts`,注册进 `ctx.skills`(自定义 provider,名为 `dsh-vscodemode`)。
489
+ ### 源码结构
316
490
 
317
- ### 目录约定
318
-
319
- ```
320
- skills/
321
- └── dsh-vscodemode-mcp/ ← 技能名(kebab-case,必须带 dsh-vscodemode- 前缀)
322
- └── SKILL.md ← YAML frontmatter + Markdown 正文
323
491
  ```
324
-
325
- - **两种布局都支持**:目录式 `skills/<名>/SKILL.md`(推荐,可放同目录的 references/ 等附属文件)与扁平式 `skills/<名>.md`。
326
- - ⚠️ **`skills/` 根目录不要放裸 `.md` 说明文档**(如 `README.md`):扁平 `.md` 会被当作单文件技能解析,
327
- frontmatter 时会在日志里产生 `技能已忽略…缺少合法 frontmatter` 告警。约定文档写在这里或 `docs/`。
328
- - **新增一个技能 = 新增一个目录**,不需要改任何代码。
329
-
330
- ### 命名硬约束(DSH 层)
331
-
332
- - **技能名必须 kebab-case**:`/^[a-z0-9]+(?:-[a-z0-9]+)*$/`(小写字母/数字,段间连字符)。
333
- **下划线非法**——`@deepseek-ai/dsh-skill` 会直接拒绝,`skill-filesystem` 把它记为
334
- `ignored: invalid skill name`。所以是 `dsh-vscodemode-mcp`,不是 `dsh_vscodemode_mcp`。
335
- - 本插件另加一层前缀白名单:名字不以 `dsh-vscodemode-` 开头的技能会被跳过并告警(避免污染全局技能命名空间)。
336
-
337
- ### frontmatter 字段
338
-
339
- ```yaml
340
- ---
341
- name: dsh-vscodemode-mcp # 必填;kebab-case + 前缀
342
- description: 一句话路由描述… # 必填;模型靠它判断何时加载
343
- whenToUse: 补充的触发条件… # 可选
344
- disable-model-invocation: false # 可选;true = 不进模型目录(仅人工显式调用)
345
- user-invocable: true # 可选;false = 禁止人工显式调用
346
- ---
492
+ src/
493
+ ├── index.ts Host 入口:name/inject/apply(薄装配,含兼容性报告启动日志)
494
+ ├── shared/ ★ 双面契约(禁 node/react):types/rpc/compat/mcp
495
+ ├── compat.ts ★ Host 兼容层:外部插件探测、路由/重复装配护栏、兼容性报告
496
+ ├── devForm.ts Host 开发形态管理:link:/junction 切换(RPC vscode.devForm*)
497
+ ├── model.ts Host 纯域逻辑(可单测):normalize/markDecision/summary/批次/归档
498
+ ├── store.ts Host 存储层:sidecar 读写合并 + 归档持久化 + stale 检测
499
+ ├── workspace.ts Host 工作区文件扫描(TTL 缓存)+ 快速打开搜索
500
+ ├── revert.ts Host 回滚/删除(fs + subprocess,fs.contains 边界校验)
501
+ ├── registry.ts Host 每工作区记录桶注册表
502
+ ├── tree.ts Host 目录树纯函数(normalizeRel/toTreeEntries,可单测)
503
+ ├── rules.ts Host 规则管理:.mdc 解析/开关改写/注入渲染 + systemPrompt 装配
504
+ ├── skills.ts Host 技能组:SKILL.md 解析/扫描 + skill provider 注册(可单测)
505
+ ├── fileVersions.ts Host 文件新鲜度观察:批查版本令牌 + 失效目录树索引(可单测)
506
+ ├── rpc.ts Host RPC 分发表(类型化 handler 表替代巨型 switch)
507
+ ├── routes.ts Host webServer 路由(/edrv/rpc、/edrv/assets/*、/edrv/vendor/*)
508
+ └── client/
509
+ ├── index.ts Client 入口:slot 注册;官方/betterSidebar/中央页签三形态互斥分流
510
+ ├── compat.ts ★ 设置桥三级降级(webUiSettings→settingsScope)、slot 安全注册
511
+ ├── officialSidebar.ts ★ 官方右侧 Sidebar 桥(DSH 0.1.5+,唯一维护面)
512
+ ├── sidebarBridge.ts betterSidebar 桥(归档,仅旧版回退)
513
+ ├── rpc.ts / events.ts / watchDecision.ts(外部改动同步纯逻辑)
514
+ ├── state/ records.ts(摘要/计数/空差异)+ regions.ts(差异区域/行裁剪)
515
+ ├── monaco/ loader.ts(AMD 加载/语言映射)+ diffRender.ts(差异自绘渲染)
516
+ ├── pdf/ pdfLoader.ts + pdfPanel.ts(PDFViewer 接线/注释/保存回写)
517
+ ├── pdfPreview.ts / imagePreview.ts / diffDock.ts(纯函数,可单测)
518
+ ├── sidebar/ ★ 面板系统:registry.ts + SidebarView.ts + panels/(文件树/搜索/规则)
519
+ ├── styles/editor.css 编辑区样式(tsdown CSS-inline 注入)
520
+ └── ui/ EditorView / OfficialSideTab / QuickOpen / DiffBox /
521
+ ConversationDiffDock / DiffLauncher / DiffBadge / McpSettings
347
522
  ```
348
523
 
349
- ⚠️ 不接受遗留写法 `disableModelInvocation` / `modelInvocable` / `userInvocable`(与官方一致,
350
- 写了会报「不受支持,请改用 …」,而不是静默失效)。
351
-
352
- ### 装载与降级
353
-
354
- - 经 `ctx.inject(['skills'], …)` 惰性获取服务,**不写进插件的 `inject` 数组** → skills 服务缺失时插件其余功能不受影响。
355
- - 服务缺失 / 版本无 `registerProvider` / provider 名冲突 记一条 warn 并跳过,不抛错、不影响装配。
356
- - 装载状态:设置 → VSCodeMode →「兼容性」→「插件技能组(`dsh-vscodemode-`*)」。
357
- - 编辑 SKILL.md **即时生效**(`fs.watch` `control.invalidate()` 清 registry 收集缓存);
358
- 监听不可用时降级为「改动需重载插件」,不影响正确性。
359
-
360
- ### 为什么自研 provider 而不用 `@deepseek-ai/dsh-skill-filesystem`
361
-
362
- 官方 provider 也能挂自定义目录(`customSkillDirs`,`@openviking/dsh-memory-plugin` 就是这么做的),
363
- 但本插件**开发形态**下不可用它:profile 以 junction 安装本插件,Node ESM 按 **realpath** 解析 import,
364
- 从工作区真实路径出发 walk 不到 profile 的 `node_modules`(实测 `import('@deepseek-ai/dsh-skill-filesystem')`
365
- `ERR_MODULE_NOT_FOUND`)。采用它需新增 dev + peer 依赖并跑 registry `pnpm install`,且每个实例会额外
366
- 拉起 chokidar watcher。自研 provider 零新依赖、开发/正式形态行为一致、节点环境可直接单测。
367
-
368
- ## 架构要点
369
-
370
- - **捕获**:Host 监听 `tools/result`,对 `edit`/`write` `result.value` + `result.meta.diffs` 落记录。
371
- - **持久化**:工作区旁车 `.dsh-edit-review.json`(version 2,按 cwd 分桶,写前合并,v1 自动迁移);
372
- 归档 `.dsh-edit-review-archive.json`(按 path+batch 合并批次,含每 hunk 决策与 before)。
373
- - **RPC**:静态包经 webServer 精确路由 `/edrv/rpc`,Client 同源 fetch;载荷形状由 `shared/rpc` 类型化。
374
- - **批次/融合/归档**:每次新 edit/write 递增文件 batch,早于最新批次的未归档差异自动"融合"归档;
375
- 每条差异处理完成(采纳/拒绝/被覆盖)立即单条归档;DiffLauncher「归档」页按批次浏览 + 回滚。
376
- - **Client 挂点**:官方右侧 Sidebar Tab(DSH 0.1.5+:类型定义 id `dsh-vscode-mode`、kind `edrvEditor`,
377
- 正文挂 keyed slot `sidebar.right.pane.tab`;优先级最高)> betterSidebar Tab `edrv-editor`(归档,仅旧版回退)
378
- > `conversation.view` 页签(id `edrv-editor`)+ `conversation.session.header.utilities`(id `edrv-diff-badge`)+ `conversation.input.dock`
379
- (id `edrv-diff-dock`,唯一差异栏:编辑器未打开=紧凑按钮,打开后=完整操作条)。内部路由/slot/事件/CSS 前缀沿用 `edrv-*`(防回归),包身份为 `dsh-vscode-mode`。
380
- - **⚠️ Host 改动需重启 DSH 应用**(Node ESM 模块缓存);Client 经 `dsh-client-hmr` 热重载。
381
-
382
- ## 会话性能(性能优化)
383
-
384
- DSH 每次启动都会回放 `~/.dsh/sessions` 下全部会话(`session-persistence-jsonl` 逐行 parse 并驻留为 JS 对象,
385
- V8 展开约 10×)。会话越多越大,启动内存越高,可能冲爆堆(OOM → bundle 加载失败)。本插件的「性能优化」子页
386
- (设置VSCodeMode)治理这个问题:
387
-
388
- - **盘点**:`edrv.perf.inventory` —— stat 全部工作区会话(不解压),按体积/工作区聚合,标记活跃会话。
389
- - **移出到归档(可逆)**:`edrv.perf.movePlan`(先规划)+ `edrv.perf.moveOut`(确认后执行,逐项失败回放)把会话目录
390
- `~/.dsh/sessions` 搬到 `~/.dsh/sessions-archive`(同卷 rename,写 `.manifest.json`);`edrv.perf.restore` 恢复;
391
- `edrv.perf.purgeArchive` 清除归档区早于 N 天的会话。活跃会话一律拒绝移出。移出即从下次启动回放中剔除——这是
392
- 对存量 95MB 级会话**立刻见效**的手段。
393
- - **压缩调优**:`edrv.perf.configApply` 把 `compaction-basic`(thresholdRatio 0.6 / retainRatio 0.12)与
394
- `tool-result-pruner`(thresholdChars 4096)写入 profile `cordis.patch.yml`(标记块 + 备份 `.bak-<ts>`,可撤销),
395
- 长循环会话更早压缩、降低模型上下文压力。⚠️ 压缩只追加 `compaction/*` 事件、**不重写**已持久化日志(append-only),
396
- 因此它不缩小会话文件——存量瘦身靠「移出到归档」。
397
- - **会话体积指示器**:对话 header 的 `edrv-perf-size` 每 5s stat 当前会话持久化体积(近零成本),≥1MB 显示、
398
- ≥2MB 琥珀、≥8MB 红,提示 `/compact` 或新开会话,从使用习惯上引导"一次任务一个短会话"。
399
- - **侧车摘要**:`edrv.perf.sidecarSummary` 返回 `.dsh-edit-review.json` 的关键字段(活跃记录数/每文件 pending/归档体积),
400
- agent/脚本取摘要即可,**不要**整份 read/write 该大 JSON 进对话。差异列表本身请走 `edrv.list`。
401
-
402
- > 治理原则:存量靠「移出到归档」;增量靠「压缩调优 + 短会话习惯 + 体积指示器」;packChunks(chunk 打包存储)为
403
- > DSH 默认开启,无需再配置。
404
-
405
- ## 系统集成(Windows 右键菜单 + Unity 外部脚本编辑器)
406
-
407
- 设置 → VSCodeMode → 通用 →「系统集成」卡片。深链契约(launcher / Unity 包 / client 三端共用):
408
- `http://127.0.0.1:3080/?edrvOpen=1&edrvPaths=<enc1>[,<enc2>…][&edrvLine=N][&edrvColumn=M]`
409
- (每段路径独立 `encodeURIComponent`,逗号连接;client 解析后按下方「打开规则」路由,处理完剥离参数防刷新重开,
410
- 跨源 referrer 守卫防外部网页诱导)。
411
-
412
- ### 打开规则(智能路由)
413
-
414
- 按首路径类型分派(其余路径:文件进编辑器、文件夹补引用):
415
-
416
- | 场景 | 行为 |
417
- |---|---|
418
- | **文件夹** 且位于某已注册工作区内 | 页面内弹窗二选一(同「添加 MCP」模态):**使用最近的工作区** = 跳转该工作区 + 新增对话 + 添加文件夹引用 + 打开文件编辑页;**新建工作区** = 以该文件夹注册新工作区 + 新增对话 + 引用 + 编辑页;取消则中止 |
419
- | **文件夹** 不在任何已注册工作区 | 不弹窗,直接以**该文件夹本身**为根注册新工作区 + 新增对话 + 文件夹引用 + 编辑页 |
420
- | **文件** 且位于某已注册工作区内(工作区亲和) | 该工作区**有会话** → 打开其最近一次对话 + 编辑器展开该文件(行列透传);**无会话** → 在该工作区**新建对话** + 添加文件引用 + 编辑器展开 |
421
- | **文件** 不在任何已注册工作区 | 打开最近一次对话 + 文件编辑器展开该文件 |
422
- | **文件** 且无任何工作区/对话 | 以文件父目录注册工作区 + 新增对话 + 添加文件引用到对话 + 编辑器打开该文件 |
423
-
424
- **页面复用**:launcher 先向 host 投递待打开请求(`edrv.external.handoff`)——已打开的 DSH 页面
425
- (3s 移交轮询)就地执行打开规则,**不重复开新页**;2s 未领取(页面刚关/后台节流)或无活跃页面时
426
- 回退打开新页(URL 深链)。
427
-
428
- 时序:等待会话/工作区列表就绪(≤15s);`sessions.create/workspaces.create` 为 DSH 官方服务方法
429
- (与 New Session 同路径);引用插入轮询输入门面就绪(忙态自动降级纯文本)。
430
-
431
- ### 文件管理器右键菜单(Windows / Linux / macOS)
432
-
433
- - **Windows**:launcher 源 `assets/shell/dsh-open.cs` 复制到 `~/.dsh/dsh-vscode-mode/shell/` 并用 .NET Framework 4.x
434
- `csc.exe` 编译为 `dsh-open.exe`(WinExe 无闪窗;csc 缺失自动降级 `dsh-open.ps1`);随后写三类 HKCU 键
435
- `HKCU\Software\Classes\{\*,Directory,Directory\Background}\shell\DSHEditor`(显示名 + Icon(DSH 小鲸鱼
436
- `dsh-whale.ico`)+ command,首次注册前 `reg export` 备份到安装目录)。全部 reg/csc 调用走 host
437
- `subprocess.spawn` argv 数组(stdio `inherit`,受管环境禁管道),无 shell 插值。
438
- - **Linux**(纯文件写入,无需管理员):GNOME Files(Nautilus)右键脚本
439
- `~/.local/share/nautilus/scripts/在 DSH 文件编辑中打开`(`NAUTILUS_SCRIPT_SELECTED_FILE_PATHS` 多选)+
440
- KDE Dolphin 服务菜单 `~/.local/share/kio/servicemenus/dsh-editor.desktop`(兼容旧 `kservices5/ServiceMenus/`,
441
- `%F` 多选);其他文件管理器暂未支持。
442
- - **macOS**:Finder 菜单不做自动生成——设置页「复制 Automator 配方」按步骤创建快速操作(约 1 分钟,脚本指向
443
- `~/.dsh/dsh-vscode-mode/shell/dsh-open.sh`),创建后面板自动检测显示 ✓;「移除注册」仅删除引用本插件
444
- launcher 的 workflow。
445
- - **行为**:launcher 读同目录 `dsh-open.ini`(`base=<深链基址>`,注册时按设置写入)→ 探测端口(Windows TcpClient /
446
- POSIX curl,1s)→ 未运行弹提示(MessageBox / osascript / notify-send / zenity)→ 把路径编码合并为一个 URL
447
- 交给默认浏览器(POSIX 侧 `LC_ALL=C` 逐字节 percent-encode,中文/空格/任意字符安全)。改「DSH 服务地址」后点「注册」刷新 ini。
448
- - **生命周期**:注册成功写 marker(`shell/registered.json`)→ 插件卸载/reload 自动清理注册痕迹,重启/更新后自动恢复
449
- (开发态反复 reload 不丢注册);点「移除注册」删除 marker,此后不再自动恢复;强杀进程跳过清理时残留键会被
450
- 下一次启动的幂等重写与「移除注册」兜底。
451
- - RPC:`edrv.integration.status / register / unregister`。
524
+ 随包目录(`package.json` `files`):`lib/`(构建产物)、`assets/`(Monaco /
525
+ pdf.js vendor + 图标 + launcher)、`skills/`(插件技能组)、`src/`(随包发布,
526
+ 便于阅读实现)、`unity/`(内嵌 UPM 包)、`cordis.patch.yml`。
527
+
528
+ ### 架构要点
529
+
530
+ - **捕获**:Host 监听 `tools/result`,对 `edit` / `write` `result.value` +
531
+ `result.meta.diffs` 落记录。
532
+ - **持久化**:工作区旁车 `.dsh-edit-review.json`(version 2,按 cwd 分桶,写前
533
+ 合并,v1 自动迁移);归档 `.dsh-edit-review-archive.json`(按 path+batch
534
+ 合并批次,含每 hunk 决策与 before)。
535
+ - **RPC**:静态包经 webServer 精确路由 `/edrv/rpc`,Client 同源 fetch,载荷形状
536
+ 由 `shared/rpc` 类型化。
537
+ - **批次 / 融合 / 归档**:每次新 edit/write 递增文件 batch,早于最新批次的未归档
538
+ 差异自动"融合"归档;每条差异处理完成立即单条归档;DiffLauncher「归档」页按
539
+ 批次浏览 + 回滚。
540
+ - **Client 挂点**:官方右侧 Sidebar Tab(DSH 0.1.5+:类型定义 id `dsh-vscode-mode`、
541
+ kind `edrvEditor`,正文挂 keyed slot `sidebar.right.pane.tab`;优先级最高)>
542
+ betterSidebar Tab `edrv-editor`(归档,仅旧版回退)> `conversation.view` 页签
543
+ (id `edrv-editor`)+ `conversation.session.header.utilities`(id `edrv-diff-badge`)
544
+ + `conversation.input.dock`(id `edrv-diff-dock`,唯一差异栏)。内部路由 / slot /
545
+ 事件 / CSS 前缀沿用 `edrv-*`(防回归),包身份 `dsh-vscode-mode`。
546
+ - **兼容层**(`src/compat.ts` + `src/client/compat.ts`):运行时探测
547
+ `@deepseek-ai/dsh-mcp-client`、设置桥(`webUiSettings` `settingsScope`)、
548
+ `/edrv` 路由前缀冲突与本插件重复装配(duplicate loader entry)护栏;
549
+ `@deepseek-ai/dsh-settings` / `schemastery` 动态加载(缺失时插件仍可加载,
550
+ 设置持久化降级)。「VSCodeMode」设置页 →「兼容性」子 Tab 或 RPC `edrv.compat`
551
+ 可查看完整报告。
552
+ - **扩展缝**:新能力 = `shared/rpc.ts` 加方法 + `src/rpc.ts` handler +
553
+ `client/` 加组件,其余模块零改动;`monaco/*` 是可复用的编辑器服务(资源树 /
554
+ 对比 / 诊断面板共用);`edrvSidebarPanels` 注册表承载后续面板(搜索 / 差异 /
555
+ 时间线),`edrv.listDir` 为通用目录树 API。
556
+ - ⚠️ **Host 改动需重启 DSH 应用**(Node ESM 模块缓存);Client 经
557
+ `dsh-client-hmr` 热重载。
558
+
559
+ ### CI(GitHub Actions)
560
+
561
+ - `.github/workflows/ci.yml`:push/PR install → typecheck → test → build →
562
+ `npm pack` 校验 + 上传 tgz。
563
+ - `.github/workflows/release.yml`:打 `v*` tag 同上构建 → GitHub Release
564
+ (附 tgz)→ **若配置了 `NPM_TOKEN` secret** 则同时 `npm publish`(npm 通道);
565
+ 未配 NPM_TOKEN 时仅 GitHub Release 通道,不影响安装。
452
566
 
453
- ### Unity 一键安装 / 更新(内嵌包)
454
-
455
- - 包源随插件分发于 `unity/com.dsh.editor/`(UPM 包:`package.json` + `Editor/DshCodeEditor.cs` +
456
- `Editor/com.dsh.editor.asmdef`,`"unity": "2019.4"` 基线;机制参照 com.unity.ide.traeCN 的
457
- `IExternalCodeEditor`:虚拟安装 `dsh-editor://vscode-mode`,`OpenProject` → `Application.OpenURL(深链)`,
458
- 不需要本地可执行文件,不生成 csproj)。
459
- - **打开过滤**:Unity 对双击的任何资产(含 prefab/scene)都会回调 `OpenProject`;仅文本/代码类扩展名
460
- (白名单 + Project Settings 用户自定义扩展 `EditorSettings.projectGenerationUserExtensions`)交 DSH
461
- 打开,其余返回 `false` 交还 Unity 原生处理(双击预制体进预制体模式、双击场景开场景),对齐官方
462
- `DefaultExternalCodeEditor` 行为。
463
- - **一键安装/更新**:设置页登记 Unity 项目根(校验 `Assets` + `ProjectSettings` 特征)后,点「安装/更新」把包源
464
- 整目录复制为 `<项目>/Packages/com.dsh.editor`(Unity **内嵌包**自动发现,无需改 manifest.json);更新 = 整目录
465
- 替换,列表显示已装版本与「可更新」徽标;目标已存在且 `package.json` name 不是 `com.dsh.editor` 时拒绝覆盖。
466
- Unity 已打开时切回窗口自动刷新生效。卸载 = 删除该目录。
467
- - 手动兜底:Package Manager Add package from disk 选 `unity/com.dsh.editor`(面板「复制包源路径」)。
468
- - RPC:`edrv.unity.list / add / remove / install`;登记清单存 `~/.dsh/dsh-vscode-mode/unity-projects.json`。
469
- - 安全说明:深链可在编辑器中查看任意绝对路径文件(与用户手动打开等价);保存仍受会话沙箱 `policyOf` 约束,
470
- 工作区外保存被拒是预期行为。
471
-
472
- ## 开发 / 卸载(超级模组注入器,开发期可选)
473
-
474
- - 热装配:`dev_install_package {dir: packages/dsh-edit-review}`;更新:`dev_reload_package {packageName: "dsh-vscode-mode"}`
475
- - 卸载:`dev_uninject_plugin {match: "dsh-vscode-mode"}`(生产环境用 `dsh plugin remove`)
567
+ ### 开发期注入(超级模组注入器,可选)
568
+
569
+ - 热装配:`dev_install_package {dir: packages/dsh-edit-review}`
570
+ - 更新:`dev_reload_package {packageName: "dsh-vscode-mode"}`
571
+ - 卸载:`dev_uninject_plugin {match: "dsh-vscode-mode"}`(生产环境用
572
+ `dsh plugin remove`)
573
+
574
+ ## 常见问题
575
+
576
+ **1. LSP 一直显示未启动 / 重启后定义与引用失效(v0.3.4 修复)**
577
+
578
+ 根因:host 侧文档跟踪(tracker)与服务器注册表(manager)是**两套独立结构**——
579
+ 「重新检测 / 保存配置 / 运行时重装」只摘除 manager 条目、保留 tracker 计数,
580
+ 此后 `tracker.open()` 对已打开文档恒返回 `false`,该语言**永久不可用直到重启
581
+ 宿主**。修复三处:① `sync` manager 缺条目时**自愈补建**(计数不重复增,
582
+ `resolveServer`);② 重置类操作**同时清 tracker**(`tracker.reset(root,lang)`
583
+ manager 同范围成对调用);③ 设置页状态改为**反映真实运行相位**(原先
584
+ `edrv.lsp.detect` 硬编码 `idle`,卡片恒显「未启动」)。另收尾宿主退出时残留的
585
+ LSP 子进程(原先 `ctx.effect` 清理不覆盖进程退出)。
586
+
587
+ **2. 引用查找完全没反应,无任何报错(v0.4.0 修复)**
588
+
589
+ 根因:离线 Monaco 是被**裁剪的构建**,缺 `gotoSymbol` / `peekView` 贡献模块,
590
+ `editor.action.referenceSearch.trigger` 等动作在运行时不存在,`Ctrl+点击` 与
591
+ `Shift+F12` 走原生 Peek 的路径静默失败。修复:换**官方完整构建**(
592
+ `referencesController` / `peekView` / `gotoSymbol` 齐备,见[特性 7](#7-monaco-离线分发)),
593
+ 静默失败同步改为状态栏明确提示。
594
+
595
+ **3. 差异文件里引用 / 定义 / hover 全空;行内差异标记不显示(v0.4.1 修复)**
596
+
597
+ 根因:**路径形态不一致**——差异记录 `rec.path` 取自工具参数 `file_path`
598
+ (**绝对路径**),而 LSP 文档键与 `server.sync()` 拼 `file://` URI 的口径都是
599
+ **工作区相对路径**,不归一化时绝对路径会被拼成 `<root>/<root>/Assets/...` 畸形
600
+ URI,服务器视其为不存在的文档。实测同一文件:相对路径 `references=3 /
601
+ symbols=37`,绝对路径 `0 / 0`。修复:新增 `toWorkspacePath()`(`src/lsp/uri.ts`)
602
+ 并在 `edrv.lsp.*` **入口统一归一化**(放入口而非 server 内,否则同一文件会因
603
+ 形态不同产生两条 tracker 记录、引用计数翻倍),`server.sync` 另加防御性兜底。
604
+ 行内差异标记改为经 `relativeOf` 归一后比较。
605
+
606
+ **4. Ctrl+点击多结果直接跳走、不给选择(v0.4.2 修复)**
607
+
608
+ 根因:插件**自研的 Ctrl+点击路径**在「0 条其它引用」时降级为「查定义 → 跳
609
+ `defs[0]`」,遇到**有多个定义但无其它引用**的标识符(实测 `IsReady` 有 2 个
610
+ 定义)就硬跳第一个;且与原生 `gotoDefinitionAtPosition` 互相竞争。修复:**统一
611
+ 委托原生**——`Ctrl+点击` / `F12` / `Shift+F12` 全部走 Monaco 原生命令
612
+ (`editor.action.revealDefinition` / `editor.action.referenceSearch.trigger`),
613
+ 多结果弹 Peek 让用户选,取不到定义按 `alternativeDefinitionCommand` 自动降级
614
+ 「转到引用」;自研鼠标监听(`bindLspEditor`)与相关死代码已删除。
615
+
616
+ **5. 冲突差异可看不可点,按钮置灰(v0.4.3 修复)**
617
+
618
+ 根因:pending hunk 的 `newText` 已被后续修改覆盖(定位失败)时 host 标记
619
+ `conflict` 并保留供复核,但单文件 Keep / Undo 原先只认「可定位」差异,而全局
620
+ Keep All / Undo All 却是亮的。修复:单文件 Keep / Undo 覆盖冲突差异——Keep
621
+ 记账后归档;Undo 对已不在文件中的差异不改动文件、直接按不采纳归档(状态栏提示
622
+ 「其中 N 处已不存在于文件,未改动」)。
623
+
624
+ **6. 快捷引用 / 部分命令被静默隐藏(v0.3.1 修复)**
625
+
626
+ 根因:编辑器可用性探测选择器 `textarea.inputarea` 被 Monaco 的 **EditContext**
627
+ 输入通道取代(有该 API 的浏览器下 Monaco 不再创建 textarea),导致本命令与其它
628
+ 12 条 `needsModel` 命令被静默隐藏、按键被放行。修复:改用与输入实现无关的判据
629
+ `.edrv-editor-row .monaco-editor`。
630
+
631
+ **7. 技能被忽略(日志「缺少合法 frontmatter」)**
632
+
633
+ 根因与约定:`skills/` 根目录**不要放裸 `.md` 说明文档**(如 README.md)——扁平
634
+ `.md` 会被当作单文件技能解析,缺 frontmatter 时产生告警;约定文档放 `docs/`。
635
+ 技能名必须 kebab-case + `dsh-vscodemode-` 前缀(下划线非法),frontmatter 用
636
+ 官方字段名(见[特性 12](#12-插件自带技能组v033))。
637
+
638
+ ## 更新日志
639
+
640
+ 完整变更见 [GitHub Releases](https://github.com/Lenonss/DSH_VsCodeMode/releases)。
641
+ 近期关键版本:
642
+
643
+ - **v0.5.0**:**SVN 集成**——侧栏变更面板与状态徽标、自研日志弹窗(过滤 / 排序 /
644
+ 多选比较 / 区间 / Stop on copy / Include merged revisions / Statistics)、
645
+ 并排差异(基线 / 版本间 / 与工作副本)、诊断日志查看器。
646
+ - **v0.4.x**:LSP 与 Monaco 系列修复(见[常见问题](#常见问题));外部改动自动
647
+ 同步即将发布。
648
+ - **v0.3.x**:命令栏(v0.2.0)→ 代码片段 / 快捷引用(v0.3.0)→ 插件技能组
649
+ (v0.3.3)。
650
+ - **v0.1.5x**:官方侧边栏形态(v0.1.60 推荐)、PDF 浏览编辑(v0.1.55)、
651
+ 系统集成(v0.1.53)、规则管理(v0.1.49 / 50)。