dsh-vscode-mode 0.11.0 → 0.13.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 (76) hide show
  1. package/README.md +158 -111
  2. package/assets/shell/dsh-open.cs +65 -149
  3. package/assets/shell/dsh-open.mjs +241 -0
  4. package/assets/shell/dsh-open.ps1 +28 -47
  5. package/assets/shell/dsh-open.sh +25 -66
  6. package/lib/client.js +13362 -11806
  7. package/lib/client.js.map +1 -1
  8. package/lib/index.js +4110 -2507
  9. package/lib/index.js.map +1 -1
  10. package/package.json +9 -8
  11. package/skills/dsh-vscodemode-mcp/SKILL.md +94 -132
  12. package/src/childEnv.ts +19 -0
  13. package/src/client/activePathStore.ts +28 -0
  14. package/src/client/addToConversation.ts +4 -2
  15. package/src/client/ai/inlineProvider.ts +1 -8
  16. package/src/client/commandBridge.ts +14 -42
  17. package/src/client/externalOpen.ts +40 -19
  18. package/src/client/index.ts +101 -18
  19. package/src/client/keybindings.ts +36 -73
  20. package/src/client/monaco/loader.ts +3 -1
  21. package/src/client/openFlow.ts +36 -28
  22. package/src/client/openReceipt.ts +64 -0
  23. package/src/client/panelCommands.ts +101 -0
  24. package/src/client/pdf/pdfLoader.ts +4 -2
  25. package/src/client/receiptState.ts +120 -0
  26. package/src/client/rpc.ts +30 -4
  27. package/src/client/shortcutRecorder.ts +161 -0
  28. package/src/client/shortcutsOfficial.ts +460 -0
  29. package/src/client/sidebar/panels/RulesPanel.ts +15 -11
  30. package/src/client/sidebarBridge.ts +7 -0
  31. package/src/client/ui/DiffBadge.ts +2 -1
  32. package/src/client/ui/EditorView.ts +246 -137
  33. package/src/client/ui/McpSettings.ts +10 -8
  34. package/src/client/ui/OfficialSideTab.ts +5 -2
  35. package/src/client/ui/QuickOpen.ts +16 -16
  36. package/src/client/ui/ShortcutSettings.ts +274 -0
  37. package/src/client/ui/commandCatalog.ts +39 -43
  38. package/src/client/useOpenReceipt.ts +128 -0
  39. package/src/compat.ts +5 -3
  40. package/src/dap/manager.ts +46 -13
  41. package/src/devForm.ts +252 -92
  42. package/src/externalHandoff.ts +93 -52
  43. package/src/fileOpenSettings.ts +4 -24
  44. package/src/hostImport.ts +19 -0
  45. package/src/httpGuard.ts +101 -0
  46. package/src/index.ts +106 -97
  47. package/src/integrate.ts +56 -50
  48. package/src/lsp/transport.ts +84 -127
  49. package/src/mcp.ts +58 -9
  50. package/src/mcpIsolation.ts +211 -102
  51. package/src/mcpProject.ts +220 -133
  52. package/src/mcpRuntime.ts +343 -0
  53. package/src/openBridge.ts +69 -0
  54. package/src/openInbox.ts +207 -0
  55. package/src/paths.ts +8 -5
  56. package/src/processTree.ts +63 -0
  57. package/src/reveal.ts +5 -3
  58. package/src/routes.ts +156 -154
  59. package/src/rpc.ts +14 -13
  60. package/src/rules.ts +100 -44
  61. package/src/shared/appUrl.ts +19 -0
  62. package/src/shared/externalOpen.ts +71 -0
  63. package/src/shared/integration.ts +2 -0
  64. package/src/shared/keybindings.ts +256 -0
  65. package/src/shared/mcp.ts +4 -1
  66. package/src/shared/rpc.ts +7 -4
  67. package/src/shared/rules.ts +9 -1
  68. package/src/shared/svn.ts +6 -8
  69. package/src/svnPlanTool.ts +51 -0
  70. package/src/unityBridge.ts +26 -3
  71. package/unity/com.dsh.editor/Editor/DshCodeEditor.cs +99 -203
  72. package/unity/com.dsh.editor/Editor/DshOpenWorker.cs +166 -0
  73. package/unity/com.dsh.editor/Editor/DshOpenWorker.cs.meta +2 -0
  74. package/unity/com.dsh.editor/README.md +16 -25
  75. package/unity/com.dsh.editor/package.json +2 -2
  76. package/src/client/ui/KeybindingsPanel.ts +0 -190
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "com.dsh.editor",
3
3
  "displayName": "DSH 文件编辑",
4
- "description": "DSH(dsh-vscode-mode)编辑器集成:把「DSH 文件编辑」注册为 Unity 外部脚本编辑器,双击脚本或 Console 报错跳转时,优先把打开请求移交已打开的 DSH 页面就地执行(不重复开新页),无活跃页面时回退经默认浏览器深链打开对应文件与行列。支持从 DSH 设置页一键安装/更新(内嵌包方式,无需手动改 manifest.json)。",
5
- "version": "0.2.4",
4
+ "description": "DSH(dsh-vscode-mode)外部脚本编辑器:通过当前用户私有 OPEN REQUEST/ACK 文件队列打开脚本、Console 行列或项目;确认匹配 ACK 后才报告成功,支持官方桌面与所选 Web profile。",
5
+ "version": "0.3.0",
6
6
  "unity": "2019.4"
7
7
  }
@@ -1,190 +0,0 @@
1
- // @ts-nocheck
2
- /**
3
- * dsh-vscode-mode client — VSCodeMode 设置区「快捷键」管理页。
4
- * 命令目录来自 client/keybindings 的 COMMANDS;当前键位读 SettingsContext scope;
5
- * 编辑:行内录制(捕获下一次组合键),Esc 取消、Backspace/Delete 清空(未绑定);
6
- * 草稿 + 显式保存(scope.set('keybindings', draft));行级恢复 + 页级「恢复默认」;
7
- * 冲突键位(两命令同键位)标红警告;scope 外部变更且无未保存修改时回同步草稿。
8
- * 作者 ddj 2026-08-26
9
- */
10
- import React from 'react'
11
- import { SettingsContext } from '../settingsContext.js'
12
- import { COMMANDS, chordFromEvent, parseChords } from '../keybindings.js'
13
- import { defaultKeybindings, KEYBINDING_DEFAULTS, normalizeKeybindings } from '../../shared/keybindings.js'
14
-
15
- /**
16
- * 草稿化:默认值 + 设置值合并,空串归一为 null(未绑定)。
17
- * @param raw 设置 scope 的 keybindings 字段
18
- * @returns 草稿映射(id → 键位弦或 null)
19
- */
20
- export function draftOf(raw) {
21
- const merged = { ...defaultKeybindings(), ...normalizeKeybindings(raw) }
22
- const out = {}
23
- for (const [id, chord] of Object.entries(merged)) out[id] = chord === '' ? null : chord
24
- return out
25
- }
26
-
27
- /**
28
- * 存库化:null(未绑定)转空串。
29
- * @param draft 草稿映射
30
- * @returns 可存储的键位映射
31
- */
32
- export function storeOf(draft) {
33
- const out = {}
34
- for (const [id, chord] of Object.entries(draft)) out[id] = chord === null ? '' : chord
35
- return out
36
- }
37
-
38
- /**
39
- * 冲突检测:同一键位被多个命令占用 → 返回冲突命令 id 集合。
40
- * @param draft 草稿映射
41
- * @returns 冲突命令 id 集合
42
- */
43
- export function conflictsOf(draft) {
44
- const byChord = new Map()
45
- for (const [id, chord] of Object.entries(draft)) {
46
- if (!chord) continue
47
- const list = byChord.get(chord) ?? []
48
- list.push(id)
49
- byChord.set(chord, list)
50
- }
51
- const out = new Set()
52
- for (const list of byChord.values()) {
53
- if (list.length > 1) for (const id of list) out.add(id)
54
- }
55
- return out
56
- }
57
-
58
- /**
59
- * 快捷键管理页主体。
60
- */
61
- export function KeybindingsPanel() {
62
- const settings = React.useContext(SettingsContext)
63
- const snapshot = settings?.getSnapshot?.()
64
- const unavailable = !settings || snapshot?.status === 'unavailable'
65
- const notReady = snapshot?.status !== 'ready'
66
- const [draft, setDraft] = React.useState(() => draftOf(snapshot?.value?.keybindings))
67
- const [recording, setRecording] = React.useState(null) // 正在录制的命令 id
68
- const [dirty, setDirty] = React.useState(false)
69
- const [busy, setBusy] = React.useState(false)
70
- const [error, setError] = React.useState('')
71
- const [message, setMessage] = React.useState('')
72
- const dirtyRef = React.useRef(false)
73
- dirtyRef.current = dirty
74
- const lastKeyRef = React.useRef(JSON.stringify(draft)) // 草稿内容指纹(内容未变不 setState,防外部快照引用不稳导致循环)
75
- const snapshotValue = snapshot?.value?.keybindings
76
-
77
- // scope 外部变更(如重置/其他端写入)且无未保存修改时回同步草稿
78
- React.useEffect(() => {
79
- if (dirtyRef.current) return
80
- const next = draftOf(snapshotValue)
81
- const key = JSON.stringify(next)
82
- if (key === lastKeyRef.current) return
83
- lastKeyRef.current = key
84
- setDraft(next)
85
- // eslint-disable-next-line react-hooks/exhaustive-deps
86
- }, [snapshotValue])
87
-
88
- // 录制态:窗口捕获下一次组合键(preventDefault 防浏览器默认动作)
89
- React.useEffect(() => {
90
- if (!recording) return
91
- const onKey = (e) => {
92
- e.preventDefault()
93
- e.stopPropagation()
94
- if (e.key === 'Escape') { setRecording(null); return }
95
- if (e.key === 'Backspace' || e.key === 'Delete') {
96
- setDraft((prev) => Object.assign({}, prev, { [recording]: null }))
97
- setRecording(null)
98
- setDirty(true)
99
- return
100
- }
101
- const chord = chordFromEvent(e)
102
- if (!chord) return
103
- setDraft((prev) => Object.assign({}, prev, { [recording]: chord }))
104
- setRecording(null)
105
- setDirty(true)
106
- }
107
- window.addEventListener('keydown', onKey, true)
108
- return () => window.removeEventListener('keydown', onKey, true)
109
- }, [recording])
110
-
111
- const conflicts = conflictsOf(draft)
112
- const save = () => {
113
- if (!settings?.set) { setError('设置服务不可用'); return }
114
- setBusy(true)
115
- setError('')
116
- setMessage('')
117
- settings.set('keybindings', storeOf(draft)).then(() => {
118
- setDirty(false)
119
- lastKeyRef.current = JSON.stringify(draft)
120
- setMessage('已保存')
121
- }).catch((e) => setError(String(e))).finally(() => setBusy(false))
122
- }
123
-
124
- /**
125
- * 恢复全部默认(确认后直接保存,一步到位)。
126
- */
127
- const resetAll = () => {
128
- if (!settings?.set) { setError('设置服务不可用'); return }
129
- if (!window.confirm('恢复全部快捷键为默认值?')) return
130
- setBusy(true)
131
- setError('')
132
- setMessage('')
133
- settings.set('keybindings', { ...defaultKeybindings() }).then(() => {
134
- const next = draftOf({})
135
- setDraft(next)
136
- lastKeyRef.current = JSON.stringify(next)
137
- setDirty(false)
138
- setMessage('已恢复默认')
139
- }).catch((e) => setError(String(e))).finally(() => setBusy(false))
140
- }
141
-
142
- /** 行级恢复该项默认值(进草稿,随保存提交)。 */
143
- const resetRow = (id) => {
144
- setDraft((prev) => Object.assign({}, prev, { [id]: KEYBINDING_DEFAULTS[id] ?? null }))
145
- setDirty(true)
146
- }
147
-
148
- const rows = COMMANDS.map((command) => {
149
- const chord = draft[command.id] ?? null
150
- const conflict = chord !== null && conflicts.has(command.id)
151
- const invalid = chord !== null && parseChords(chord).length === 0
152
- const recordingRow = recording === command.id
153
- let display
154
- if (recordingRow) {
155
- display = React.createElement('span', { className: 'vsm-kb-rec' }, '按下组合键…(Esc 取消 / Backspace 清除)')
156
- } else {
157
- display = React.createElement('kbd', { className: 'vsm-kb-key' + (conflict ? ' warn' : '') + (invalid ? ' invalid' : '') },
158
- chord ?? '未绑定')
159
- }
160
- return React.createElement('div', { key: command.id, className: 'vsm-kb-row' + (recordingRow ? ' rec' : '') },
161
- React.createElement('div', { className: 'vsm-kb-label' },
162
- React.createElement('span', null, command.label),
163
- conflict && React.createElement('small', { className: 'vsm-kb-warn' }, '与另一命令冲突'),
164
- invalid && React.createElement('small', { className: 'vsm-kb-warn' }, '键位格式无效')),
165
- display,
166
- React.createElement('div', { className: 'vsm-kb-actions' },
167
- recordingRow
168
- ? React.createElement('button', { onClick: () => setRecording(null) }, '取消')
169
- : React.createElement(React.Fragment, null,
170
- React.createElement('button', { disabled: unavailable || notReady || busy || snapshot?.writable === false, onClick: () => { setRecording(command.id); setMessage('') } }, '编辑'),
171
- React.createElement('button', { disabled: busy, onClick: () => resetRow(command.id) }, '恢复')),
172
- ))
173
- })
174
-
175
- return React.createElement('section', { className: 'vsm-general-page' },
176
- React.createElement('h2', null, '快捷键'),
177
- React.createElement('p', null, '配置编辑器视图的快捷键(命令栏 / 保存 / 快速打开 / 侧边栏 / 搜索 / 后退前进 / 页签与编辑行导航)。修改即时写入配置,重新聚焦编辑器后生效;命令栏(默认 Ctrl+Shift+P 或 F1)可搜索并执行下列全部命令。'),
178
- unavailable && React.createElement('div', { className: 'vsm-mcp-error vsm-mcp-banner' }, '设置服务暂不可用,当前使用默认键位。'),
179
- error && React.createElement('div', { className: 'vsm-mcp-error vsm-mcp-banner' }, error),
180
- message && React.createElement('div', { className: 'vsm-kb-message' }, message),
181
- React.createElement('section', { className: 'vsm-panel' },
182
- React.createElement('h3', { className: 'vsm-panel-title' }, '编辑器键位'),
183
- React.createElement('div', { className: 'vsm-panel-body' }, React.createElement('div', { className: 'vsm-kb-list' }, rows)),
184
- React.createElement('div', { className: 'vsm-panel-body vsm-kb-actionsbar' },
185
- React.createElement('span', { className: 'vsm-kb-dirty' }, dirty ? '有未保存的修改' : ''),
186
- React.createElement('button', { className: 'vsm-primary vsm-small', disabled: unavailable || notReady || busy || snapshot?.writable === false || !dirty, onClick: save }, busy ? '保存中…' : '保存'),
187
- React.createElement('button', { className: 'vsm-small', disabled: unavailable || notReady || busy || snapshot?.writable === false, onClick: resetAll }, '恢复默认')),
188
- ),
189
- )
190
- }