feat: expose user actions to mcp

This commit is contained in:
purocean
2026-05-01 12:10:27 +08:00
parent 6c211ecbdc
commit ecc66e12c3
28 changed files with 78 additions and 2 deletions
@@ -45,6 +45,8 @@ registerAction({
name: 'control-center.toggle',
description: t('command-desc.control-center_toggle'),
forUser: true,
forMcp: true,
mcpDescription: 'Toggle control center. Args: [visible:boolean?]. No return.',
handler: toggle,
keys: [Alt, 'c']
})
@@ -263,7 +263,9 @@ onMounted(() => {
description: t('command-desc.view_refresh'),
handler: refresh,
keys: [CtrlCmd, 'r'],
forUser: true
forUser: true,
forMcp: true,
mcpDescription: 'Refresh preview. No args. No return.'
})
registerHook('SETTING_CHANGED', updateMarkdownBodyMaxWidth)
+2
View File
@@ -380,6 +380,8 @@ onMounted(() => {
handler: show,
keys: [Alt, 'h'],
forUser: true,
forMcp: true,
mcpDescription: 'Show document history panel. No args. No return.',
description: t('command-desc.doc_show-history'),
})
registerAction({ name: 'doc.hide-history', handler: hide })
+2
View File
@@ -104,6 +104,8 @@ onMounted(() => {
name: 'editor.rotate-custom-editors',
description: t('command-desc.editor_rotate-custom-editors'),
forUser: true,
forMcp: true,
mcpDescription: 'Rotate through custom editors. No args. No return.',
handler: () => {
if (availableEditors.value.length > 1) {
const index = availableEditors.value.findIndex(x => x.name === store.state.editor)
@@ -674,6 +674,8 @@ onMounted(() => {
description: t('command-desc.extension_show-manager'),
handler: show,
forUser: true,
forMcp: true,
mcpDescription: 'Show extension manager. No args. No return.',
})
})
+10
View File
@@ -234,6 +234,8 @@ export default defineComponent({
description: t('command-desc.file-tabs_switch-left'),
keys: [CtrlCmd, Alt, 'ArrowLeft'],
forUser: true,
forMcp: true,
mcpDescription: 'Switch to left tab. No args. No return.',
handler () {
const prev = findTab(-1)
prev && switchTab(prev)
@@ -244,6 +246,8 @@ export default defineComponent({
name: 'file-tabs.switch-right',
description: t('command-desc.file-tabs_switch-right'),
forUser: true,
forMcp: true,
mcpDescription: 'Switch to right tab. No args. No return.',
handler () {
const next = findTab(1)
next && switchTab(next)
@@ -256,6 +260,8 @@ export default defineComponent({
description: t('command-desc.file-tabs_close-current'),
handler: closeCurrent,
forUser: true,
forMcp: true,
mcpDescription: 'Close current tab. No args. No return.',
keys: isElectron ? [CtrlCmd, 'w'] : [CtrlCmd, Alt, 'w']
})
@@ -263,6 +269,8 @@ export default defineComponent({
name: 'file-tabs.search-tabs',
description: t('command-desc.file-tabs_search-tabs'),
forUser: true,
forMcp: true,
mcpDescription: 'Search tabs. No args. No return.',
handler () {
refTabs.value?.showQuickFilter()
},
@@ -273,6 +281,8 @@ export default defineComponent({
name: 'file-tabs.show-welcome',
description: t('command-desc.file-tabs_show-welcome'),
forUser: true,
forMcp: true,
mcpDescription: 'Show welcome page. No args. No return.',
handler () {
switchDoc(null)
},
+2
View File
@@ -105,6 +105,8 @@ export default defineComponent({
description: t('command-desc.workbench_show-quick-open'),
handler: showQuickOpen,
forUser: true,
forMcp: true,
mcpDescription: 'Show quick open dialog. No args. No return.',
keys: [CtrlCmd, 'p']
})
registerAction({ name: 'filter.choose-document', handler: chooseDocument })
@@ -200,6 +200,8 @@ registerAction({
keys: [CtrlCmd, 'f'],
handler: show,
forUser: true,
forMcp: true,
mcpDescription: 'Show find widget in preview. No args. No return.',
when: () => {
return !(getEditor()?.hasTextFocus()) && store.state.showView
}
@@ -369,7 +369,9 @@ registerAction({
name: 'keyboard-shortcuts.show-manager',
description: t('command-desc.keyboard-shortcuts_show-manager'),
handler: show,
forUser: true
forUser: true,
forMcp: true,
mcpDescription: 'Show keyboard shortcuts manager. No args. No return.'
})
onUnmounted(() => {
+2
View File
@@ -786,6 +786,8 @@ registerAction({
keys: [CtrlCmd, Shift, 'f'],
description: t('command-desc.base_find-in-repository'),
forUser: true,
forMcp: true,
mcpDescription: 'Find text in repository. Args: [query?:{pattern?:string, caseSensitive?:boolean, wholeWord?:boolean, regExp?:boolean, include?:string, exclude?:string}]. No return.',
handler: (query?: FindInRepositoryQuery) => {
visible.value = true
+2
View File
@@ -96,6 +96,8 @@ export default defineComponent({
name: 'tree.reveal-current-node',
description: t('command-desc.tree_reveal-current-node'),
forUser: true,
forMcp: true,
mcpDescription: 'Reveal current document in tree. No args. No return.',
handler: revealCurrentNode
})
+2
View File
@@ -142,6 +142,8 @@ export default {
description: ctx.i18n.t('command-desc.plugin_copy-content_copy-content'),
handler: copyContent,
forUser: true,
forMcp: true,
mcpDescription: 'Copy content in various formats. No args. No return.',
keys: [ctx.keybinding.CtrlCmd, ctx.keybinding.Shift, 'c'],
})
+2
View File
@@ -192,6 +192,8 @@ export default {
description: ctx.i18n.t('command-desc.plugin_editor_focus-editor'),
handler: focusEditor,
forUser: true,
forMcp: true,
mcpDescription: 'Focus editor. No args. No return.',
keys: [ctx.keybinding.Shift, ctx.keybinding.Alt, 'x']
})
}
+6
View File
@@ -34,6 +34,8 @@ export default {
keys: [ctx.keybinding.CtrlCmd, '='],
description: ctx.i18n.t('command-desc.plugin_electron-zoom_zoom-in'),
forUser: true,
forMcp: true,
mcpDescription: 'Zoom in. No args. No return.',
handler: () => changeZoomFactor(true)
})
@@ -42,6 +44,8 @@ export default {
keys: [ctx.keybinding.CtrlCmd, '-'],
description: ctx.i18n.t('command-desc.plugin_electron-zoom_zoom-out'),
forUser: true,
forMcp: true,
mcpDescription: 'Zoom out. No args. No return.',
handler: () => changeZoomFactor(false)
})
@@ -50,6 +54,8 @@ export default {
keys: [ctx.keybinding.CtrlCmd, '0'],
description: ctx.i18n.t('command-desc.plugin_electron-zoom_zoom-reset'),
forUser: true,
forMcp: true,
mcpDescription: 'Reset zoom. No args. No return.',
handler: () => setZoomFactor(1)
})
+4
View File
@@ -141,6 +141,8 @@ export default {
name: backId,
description: ctx.i18n.t('command-desc.plugin_document-history-stack_back'),
forUser: true,
forMcp: true,
mcpDescription: 'Go back in document history. No args. No return.',
handler: () => go(-1),
keys: [ctx.keybinding.Alt, ctx.keybinding.BracketLeft],
})
@@ -149,6 +151,8 @@ export default {
name: forwardId,
description: ctx.i18n.t('command-desc.plugin_document-history-stack_forward'),
forUser: true,
forMcp: true,
mcpDescription: 'Go forward in document history. No args. No return.',
handler: () => go(1),
keys: [ctx.keybinding.Alt, ctx.keybinding.BracketRight],
})
@@ -126,6 +126,8 @@ export default {
handler: transformAll,
description: ctx.i18n.t('command-desc.plugin_image-localization_all'),
forUser: true,
forMcp: true,
mcpDescription: 'Transform remote images to local. No args. No return.',
when,
})
@@ -111,6 +111,8 @@ export default {
ctx.action.registerAction({
name: actionName,
forUser: true,
forMcp: true,
mcpDescription: 'Insert table. No args. No return.',
description: ctx.i18n.t('insert-table.insert-table'),
handler: () => {
if (canInsertTable()) {
@@ -83,6 +83,8 @@ export default {
name: actionName,
description: ctx.i18n.t('premium.confetti'),
forUser: true,
forMcp: true,
mcpDescription: 'Show confetti celebration. No args. No return.',
handler
})
}
@@ -78,6 +78,8 @@ export default {
name: `base.switch-repository-${i}`,
description: i === 0 ? ctx.i18n.t('switch-the-last-repo') : ctx.i18n.t('switch-repo-n', String(i)),
forUser: true,
forMcp: true,
mcpDescription: `Switch to repository ${i === 0 ? 'last' : i}. No args. No return.`,
keys: [ctx.keybinding.Alt, String(i)],
handler: () => {
const repos = ctx.repo.getAllRepos()
+2
View File
@@ -50,6 +50,8 @@ export default {
handler,
description: ctx.i18n.t('command-desc.plugin_status-bar-theme_switch'),
forUser: true,
forMcp: true,
mcpDescription: 'Switch theme. No args. No return.',
})
}
} as Plugin
+2
View File
@@ -33,6 +33,8 @@ export default {
description: ctx.i18n.t('command-desc.plugin_switch-todo_switch'),
keys: [ctx.keybinding.Alt, 'o'],
forUser: true,
forMcp: true,
mcpDescription: 'Switch todo status. Args: [line:number?, checked:boolean?]. No return.',
handler: (line?: number, checked?: boolean) => {
if (line) {
switchTodo(line, checked)
+2
View File
@@ -39,6 +39,8 @@ export default {
ctx.action.registerAction({
name: actionName,
forUser: true,
forMcp: true,
mcpDescription: 'View document links. No args. No return.',
description: ctx.i18n.t('command-desc.plugin_view-links_view-document-links'),
handler: showLinks,
when,
+2
View File
@@ -579,8 +579,10 @@ export async function isDirty (): Promise<boolean> {
registerAction({
name: 'editor.toggle-wrap',
description: t('command-desc.editor_toggle-wrap'),
mcpDescription: 'Toggle word wrap. No args. No return.',
handler: toggleWrap,
forUser: true,
forMcp: true,
keys: [Alt, 'w']
})
+8
View File
@@ -117,31 +117,39 @@ export function toggleEditorPreviewExclusive (exclusive?: boolean) {
registerAction({
name: 'layout.toggle-side',
description: t('command-desc.layout_toggle-side'),
mcpDescription: 'Toggle side panel. Args: [visible:boolean?]. No return.',
handler: toggleSide,
forUser: true,
forMcp: true,
keys: [Alt, 'e']
})
registerAction({
name: 'layout.toggle-editor',
description: t('command-desc.layout_toggle-editor'),
mcpDescription: 'Toggle editor panel. Args: [visible:boolean?]. No return.',
handler: toggleEditor,
forUser: true,
forMcp: true,
keys: [Alt, 'x']
})
registerAction({
name: 'layout.toggle-view',
description: t('command-desc.layout_toggle-view'),
mcpDescription: 'Toggle preview panel. Args: [visible:boolean?]. No return.',
handler: toggleView,
forUser: true,
forMcp: true,
keys: [Alt, 'v']
})
registerAction({
name: 'layout.toggle-xterm',
description: t('command-desc.layout_toggle-xterm'),
mcpDescription: 'Toggle terminal panel. Args: [visible:boolean?]. No return.',
handler: toggleXterm,
forUser: true,
forMcp: true,
keys: [Alt, 't']
})
+2
View File
@@ -100,6 +100,8 @@ store.watch(() => store.state.treeSort, async () => {
registerAction({
name: 'tree.refresh',
description: t('command-desc.tree_refresh'),
mcpDescription: 'Refresh file tree. No args. No return.',
forUser: true,
forMcp: true,
handler: refreshTree,
})
+2
View File
@@ -542,7 +542,9 @@ registerHook('VIEW_RENDER_IFRAME_READY', ({ iframe }) => {
registerAction({
name: 'view.enter-presentation',
forUser: true,
forMcp: true,
description: t('command-desc.view_enter-presentation'),
mcpDescription: 'Enter presentation mode. No args. No return.',
handler: () => present(true),
keys: ['F5']
})
+2
View File
@@ -18,7 +18,9 @@ export function toggleOutline (visible?: boolean) {
registerAction({
name: 'workbench.toggle-outline',
description: t('command-desc.workbench_toggle-outline'),
mcpDescription: 'Toggle outline panel. Args: [visible:boolean?]. No return.',
forUser: true,
forMcp: true,
handler: toggleOutline,
keys: [Shift, Alt, 'o']
})
+2
View File
@@ -299,8 +299,10 @@ registerHook('RIGHT_SIDE_PANEL_CHANGE', ({ type }) => {
registerAction({
name: 'layout.toggle-content-right-side',
description: t('command-desc.layout_toggle-content-right-side'),
mcpDescription: 'Toggle content right panel. Args: [visible:boolean?]. No return.',
handler: ctx.layout.toggleContentRightSide,
forUser: true,
forMcp: true,
when () {
return ctx.workbench.ContentRightSide.getAllPanels().length > 0
},