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.
- package/README.md +158 -111
- package/assets/shell/dsh-open.cs +65 -149
- package/assets/shell/dsh-open.mjs +241 -0
- package/assets/shell/dsh-open.ps1 +28 -47
- package/assets/shell/dsh-open.sh +25 -66
- package/lib/client.js +13362 -11806
- package/lib/client.js.map +1 -1
- package/lib/index.js +4110 -2507
- package/lib/index.js.map +1 -1
- package/package.json +9 -8
- package/skills/dsh-vscodemode-mcp/SKILL.md +94 -132
- package/src/childEnv.ts +19 -0
- package/src/client/activePathStore.ts +28 -0
- package/src/client/addToConversation.ts +4 -2
- package/src/client/ai/inlineProvider.ts +1 -8
- package/src/client/commandBridge.ts +14 -42
- package/src/client/externalOpen.ts +40 -19
- package/src/client/index.ts +101 -18
- package/src/client/keybindings.ts +36 -73
- package/src/client/monaco/loader.ts +3 -1
- package/src/client/openFlow.ts +36 -28
- package/src/client/openReceipt.ts +64 -0
- package/src/client/panelCommands.ts +101 -0
- package/src/client/pdf/pdfLoader.ts +4 -2
- package/src/client/receiptState.ts +120 -0
- package/src/client/rpc.ts +30 -4
- package/src/client/shortcutRecorder.ts +161 -0
- package/src/client/shortcutsOfficial.ts +460 -0
- package/src/client/sidebar/panels/RulesPanel.ts +15 -11
- package/src/client/sidebarBridge.ts +7 -0
- package/src/client/ui/DiffBadge.ts +2 -1
- package/src/client/ui/EditorView.ts +246 -137
- package/src/client/ui/McpSettings.ts +10 -8
- package/src/client/ui/OfficialSideTab.ts +5 -2
- package/src/client/ui/QuickOpen.ts +16 -16
- package/src/client/ui/ShortcutSettings.ts +274 -0
- package/src/client/ui/commandCatalog.ts +39 -43
- package/src/client/useOpenReceipt.ts +128 -0
- package/src/compat.ts +5 -3
- package/src/dap/manager.ts +46 -13
- package/src/devForm.ts +252 -92
- package/src/externalHandoff.ts +93 -52
- package/src/fileOpenSettings.ts +4 -24
- package/src/hostImport.ts +19 -0
- package/src/httpGuard.ts +101 -0
- package/src/index.ts +106 -97
- package/src/integrate.ts +56 -50
- package/src/lsp/transport.ts +84 -127
- package/src/mcp.ts +58 -9
- package/src/mcpIsolation.ts +211 -102
- package/src/mcpProject.ts +220 -133
- package/src/mcpRuntime.ts +343 -0
- package/src/openBridge.ts +69 -0
- package/src/openInbox.ts +207 -0
- package/src/paths.ts +8 -5
- package/src/processTree.ts +63 -0
- package/src/reveal.ts +5 -3
- package/src/routes.ts +156 -154
- package/src/rpc.ts +14 -13
- package/src/rules.ts +100 -44
- package/src/shared/appUrl.ts +19 -0
- package/src/shared/externalOpen.ts +71 -0
- package/src/shared/integration.ts +2 -0
- package/src/shared/keybindings.ts +256 -0
- package/src/shared/mcp.ts +4 -1
- package/src/shared/rpc.ts +7 -4
- package/src/shared/rules.ts +9 -1
- package/src/shared/svn.ts +6 -8
- package/src/svnPlanTool.ts +51 -0
- package/src/unityBridge.ts +26 -3
- package/unity/com.dsh.editor/Editor/DshCodeEditor.cs +99 -203
- package/unity/com.dsh.editor/Editor/DshOpenWorker.cs +166 -0
- package/unity/com.dsh.editor/Editor/DshOpenWorker.cs.meta +2 -0
- package/unity/com.dsh.editor/README.md +16 -25
- package/unity/com.dsh.editor/package.json +2 -2
- 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
|
|
5
|
-
"version": "0.
|
|
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
|
-
}
|