dsh-vscode-mode 0.17.0 → 0.18.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 +6 -4
- package/lib/client.js +578 -49
- package/lib/client.js.map +1 -1
- package/lib/index.js +842 -244
- package/lib/index.js.map +1 -1
- package/package.json +1 -1
- package/skills/dsh-vscodemode-mcp/SKILL.md +24 -7
- package/src/client/index.ts +15 -0
- package/src/client/mcpSessionState.ts +108 -0
- package/src/client/monaco/lsp/providers.ts +32 -3
- package/src/client/state/modelWarmer.ts +198 -0
- package/src/client/styles/editor.css +5 -1
- package/src/client/ui/EditorPane.ts +16 -4
- package/src/client/ui/EditorView.ts +76 -18
- package/src/client/ui/McpSessionStatus.ts +75 -0
- package/src/client/ui/McpSettings.ts +47 -13
- package/src/mcp.ts +1 -0
- package/src/mcpBridge.ts +163 -0
- package/src/mcpDiscover.ts +38 -0
- package/src/mcpPool.ts +245 -0
- package/src/mcpProject.ts +15 -12
- package/src/mcpRuntime.ts +299 -254
- package/src/rpc.ts +13 -1
- package/src/shared/mcp.ts +47 -0
- package/src/shared/rpc.ts +5 -1
package/src/rpc.ts
CHANGED
|
@@ -33,6 +33,7 @@ import { newContentSearcher } from './search/content.js'
|
|
|
33
33
|
import { restoreFile, revertCall, revertHunk, revertHunks, type Result } from './revert.js'
|
|
34
34
|
import { rulesList, rulesRead, rulesRemove, rulesSave, rulesToggle } from './rules.js'
|
|
35
35
|
import { isSnippetFilePath, snippetsEntries, snippetsList, snippetsRead, snippetsRemove, snippetsSave } from './snippets.js'
|
|
36
|
+
import { runtimeOf } from './mcpRuntime.js'
|
|
36
37
|
import { listMcp, refreshMcp, removeMcp, saveMcp, toggleMcp } from './mcp.js'
|
|
37
38
|
import { listProjects, projectRefresh, projectRemove, projectSave, projectToggle, mcpSnapshot } from './mcpProject.js'
|
|
38
39
|
import { normalizeFileOpenTool, FILE_OPEN_DEFAULT, FILE_OPEN_SETTINGS_NS, sectionOf, updateSection } from './fileOpenSettings.js'
|
|
@@ -1170,6 +1171,7 @@ export function buildHandlers(
|
|
|
1170
1171
|
},
|
|
1171
1172
|
'mcp.list': async () => ({ ok: true, ...listMcp(ctx) }),
|
|
1172
1173
|
'mcp.snapshot': async () => ({ ok: true, ...mcpSnapshot(ctx) }),
|
|
1174
|
+
'mcp.sessionSnapshot': async () => ({ ok: true, ...runtimeOf(ctx).sessionSnapshot() }),
|
|
1173
1175
|
'mcp.save': async (args) => {
|
|
1174
1176
|
try { return { ok: true, server: await saveMcp(ctx, args.config) } }
|
|
1175
1177
|
catch (error) { return { ok: false, error: String(error) } }
|
|
@@ -1190,8 +1192,18 @@ export function buildHandlers(
|
|
|
1190
1192
|
try { return { ok: true, ...await listProjects(ctx) } }
|
|
1191
1193
|
catch (error) { return { ok: false, error: String(error) } }
|
|
1192
1194
|
},
|
|
1195
|
+
'mcp.projectConnect': async (args) => {
|
|
1196
|
+
const runtime = runtimeOf(ctx)
|
|
1197
|
+
const agent = [...runtime.agents.keys()].find((owner) => owner.session?.id === args.sessionId)
|
|
1198
|
+
if (!agent || runtime.workspace(agent) !== args.workspacePath) return { ok: false, error: '请先打开此项目的活跃会话;不会激活历史会话' }
|
|
1199
|
+
try {
|
|
1200
|
+
await runtime.connect(agent, args.serverName)
|
|
1201
|
+
const project = mcpSnapshot(ctx).projects.find((item) => item.workspacePath === args.workspacePath)!
|
|
1202
|
+
return { ok: true, project }
|
|
1203
|
+
} catch { return { ok: false, error: '项目 MCP 连接失败,请查看会话状态和 Host 日志' } }
|
|
1204
|
+
},
|
|
1193
1205
|
'mcp.projectSave': async (args) => {
|
|
1194
|
-
try { return { ok: true, project: await projectSave(ctx, args.workspacePath, args.serverName, args.config) } }
|
|
1206
|
+
try { return { ok: true, project: await projectSave(ctx, args.workspacePath, args.serverName, args.config, args.policy) } }
|
|
1195
1207
|
catch (error) { return { ok: false, error: String(error) } }
|
|
1196
1208
|
},
|
|
1197
1209
|
'mcp.projectRemove': async (args) => {
|
package/src/shared/mcp.ts
CHANGED
|
@@ -1,6 +1,50 @@
|
|
|
1
1
|
/** dsh-vscode-mode MCP 管理共享数据契约。作者 ddj 2026年08月22号 */
|
|
2
2
|
|
|
3
3
|
export type MpcTransport = 'stdio' | 'streamable-http'
|
|
4
|
+
/** Project initialization only; ready does not establish transport health. */
|
|
5
|
+
export type McpPhase = 'preparing' | 'idle' | 'queued' | 'loading' | 'starting' | 'stopping' | 'ready' | 'error' | 'none'
|
|
6
|
+
|
|
7
|
+
export interface McpPolicy {
|
|
8
|
+
startup: 'on-demand' | 'background'
|
|
9
|
+
sharing: 'agent' | 'workspace'
|
|
10
|
+
startupTimeoutMs: number
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
/** @public @author ddj 2026年10月20号 @param input Project-only policy. @returns Validated defaults. @throws Invalid explicit policy. */
|
|
14
|
+
export function parseMcpPolicy(input?: unknown): McpPolicy {
|
|
15
|
+
if (input !== undefined && (!input || typeof input !== 'object' || Array.isArray(input))) throw new Error('vscodeMode 必须是对象')
|
|
16
|
+
const policy = (input ?? {}) as Partial<McpPolicy>
|
|
17
|
+
const startup = policy.startup ?? 'on-demand'
|
|
18
|
+
const sharing = policy.sharing ?? 'agent'
|
|
19
|
+
const startupTimeoutMs = policy.startupTimeoutMs ?? 60000
|
|
20
|
+
if (!['on-demand', 'background'].includes(startup)) throw new Error('不支持的 MCP startup')
|
|
21
|
+
if (!['agent', 'workspace'].includes(sharing)) throw new Error('不支持的 MCP sharing')
|
|
22
|
+
if (!Number.isInteger(startupTimeoutMs) || startupTimeoutMs < 1000 || startupTimeoutMs > 300000) throw new Error('MCP startupTimeoutMs 必须为 1000–300000 的整数')
|
|
23
|
+
return { startup, sharing, startupTimeoutMs }
|
|
24
|
+
}
|
|
25
|
+
export interface McpSessionServer {
|
|
26
|
+
queuedMs?: number
|
|
27
|
+
connectMs?: number
|
|
28
|
+
firstCallMs?: number
|
|
29
|
+
reused?: boolean
|
|
30
|
+
serverName: string
|
|
31
|
+
phase: McpPhase
|
|
32
|
+
startedAt: number
|
|
33
|
+
phaseAt: number
|
|
34
|
+
finishedAt?: number
|
|
35
|
+
error?: string
|
|
36
|
+
}
|
|
37
|
+
export interface McpSessionStatus {
|
|
38
|
+
configMs?: number
|
|
39
|
+
sessionId: string
|
|
40
|
+
phase: McpPhase
|
|
41
|
+
startedAt: number
|
|
42
|
+
phaseAt: number
|
|
43
|
+
finishedAt?: number
|
|
44
|
+
error?: string
|
|
45
|
+
servers: McpSessionServer[]
|
|
46
|
+
}
|
|
47
|
+
|
|
4
48
|
export type MpcStatus = 'connected' | 'connecting' | 'error' | 'disabled' | 'configured' | 'unverified'
|
|
5
49
|
|
|
6
50
|
export interface MpcTool {
|
|
@@ -32,6 +76,8 @@ export interface MpcServer {
|
|
|
32
76
|
status: MpcStatus
|
|
33
77
|
/** Mounted official plugin fibers, not verified live connections. */
|
|
34
78
|
instanceCount?: number
|
|
79
|
+
sessionCount?: number
|
|
80
|
+
policy?: McpPolicy
|
|
35
81
|
toolCount: number
|
|
36
82
|
tools: MpcTool[]
|
|
37
83
|
error?: string
|
|
@@ -50,6 +96,7 @@ export interface MpcProject {
|
|
|
50
96
|
|
|
51
97
|
/** 项目级 MCP 保存入参:config 为该 serverName 的传输配置(不含归属信息)。 */
|
|
52
98
|
export interface MpcProjectSaveInput {
|
|
99
|
+
policy?: McpPolicy
|
|
53
100
|
workspacePath: string
|
|
54
101
|
serverName: string
|
|
55
102
|
config: MpcConfig
|
package/src/shared/rpc.ts
CHANGED
|
@@ -12,7 +12,7 @@ import type {
|
|
|
12
12
|
RecordView,
|
|
13
13
|
StaleHunk,
|
|
14
14
|
} from './types.js'
|
|
15
|
-
import type { MpcConfig, MpcProject, MpcProjectSaveInput, MpcServer } from './mcp.js'
|
|
15
|
+
import type { McpSessionStatus, MpcConfig, MpcProject, MpcProjectSaveInput, MpcServer } from './mcp.js'
|
|
16
16
|
import type { CompatReport, DevFormInfo } from './compat.js'
|
|
17
17
|
import type { ShellIntegrationStatus, UnityListPayload, UnityProjectEntry } from './integration.js'
|
|
18
18
|
import type { RuleInfo, RuleProject, RuleRefInput, RuleSaveInput } from './rules.js'
|
|
@@ -399,11 +399,13 @@ export interface RpcRequestMap {
|
|
|
399
399
|
'edrv.fsMove': { sessionId?: string; from: string; toDir: string }
|
|
400
400
|
'mcp.list': {}
|
|
401
401
|
'mcp.snapshot': {}
|
|
402
|
+
'mcp.sessionSnapshot': {}
|
|
402
403
|
'mcp.save': { config: MpcConfig }
|
|
403
404
|
'mcp.remove': { id: string }
|
|
404
405
|
'mcp.toggle': { id: string; enabled: boolean }
|
|
405
406
|
'mcp.refresh': { id: string }
|
|
406
407
|
'mcp.projects': {}
|
|
408
|
+
'mcp.projectConnect': { sessionId: string; serverName: string; workspacePath: string }
|
|
407
409
|
'mcp.projectSave': MpcProjectSaveInput
|
|
408
410
|
'mcp.projectRemove': { workspacePath: string; serverName: string }
|
|
409
411
|
'mcp.projectToggle': { workspacePath: string; serverName: string; enabled: boolean }
|
|
@@ -565,11 +567,13 @@ export interface RpcOkMap {
|
|
|
565
567
|
'edrv.fsMove': { from: string; to: string }
|
|
566
568
|
'mcp.list': { servers: MpcServer[] }
|
|
567
569
|
'mcp.snapshot': { servers: MpcServer[]; projects: MpcProject[] }
|
|
570
|
+
'mcp.sessionSnapshot': { sessions: McpSessionStatus[]; sampledAt: number }
|
|
568
571
|
'mcp.save': { server: MpcServer }
|
|
569
572
|
'mcp.remove': object
|
|
570
573
|
'mcp.toggle': { server: MpcServer }
|
|
571
574
|
'mcp.refresh': { server: MpcServer }
|
|
572
575
|
'mcp.projects': { projects: MpcProject[] }
|
|
576
|
+
'mcp.projectConnect': { project: MpcProject }
|
|
573
577
|
'mcp.projectSave': { project: MpcProject }
|
|
574
578
|
'mcp.projectRemove': { project: MpcProject }
|
|
575
579
|
'mcp.projectToggle': { project: MpcProject }
|