mirror of
https://github.com/voideditor/void
synced 2026-05-24 09:58:23 +00:00
Merge remote-tracking branch 'origin/model-selection' into tools-in-plaintext
This commit is contained in:
commit
8b5dfa66d5
6 changed files with 54 additions and 35 deletions
|
|
@ -658,6 +658,7 @@ type ToolHeaderParams = {
|
||||||
numResults?: number;
|
numResults?: number;
|
||||||
hasNextPage?: boolean;
|
hasNextPage?: boolean;
|
||||||
children?: React.ReactNode;
|
children?: React.ReactNode;
|
||||||
|
bottomChildren?: React.ReactNode;
|
||||||
onClick?: () => void;
|
onClick?: () => void;
|
||||||
isOpen?: boolean,
|
isOpen?: boolean,
|
||||||
}
|
}
|
||||||
|
|
@ -1723,7 +1724,10 @@ const toolNameToComponent: { [T in ToolName]: { resultWrapper: ResultWrapper<T>,
|
||||||
|
|
||||||
// add children
|
// add children
|
||||||
if (toolMessage.type !== 'tool_error') {
|
if (toolMessage.type !== 'tool_error') {
|
||||||
const { params } = toolMessage
|
const { params, result } = toolMessage
|
||||||
|
|
||||||
|
// componentParams.bottomChildren = <EditToolLintErrors lintErrors={result?.lintErrors || []} />
|
||||||
|
|
||||||
componentParams.children = <ToolChildrenWrapper className='bg-void-bg-3'>
|
componentParams.children = <ToolChildrenWrapper className='bg-void-bg-3'>
|
||||||
<EditToolChildren
|
<EditToolChildren
|
||||||
uri={params.uri}
|
uri={params.uri}
|
||||||
|
|
@ -2150,7 +2154,7 @@ const CommandBarInChat = () => {
|
||||||
const acceptRejectButtons = <div
|
const acceptRejectButtons = <div
|
||||||
// do this with opacity so that the height remains the same at all times
|
// do this with opacity so that the height remains the same at all times
|
||||||
className={`flex items-center gap-0.5
|
className={`flex items-center gap-0.5
|
||||||
${isFinishedMakingThreadChanges ? '' : 'opacity-0 pointer-events-none'}
|
${isFinishedMakingFileChanges ? '' : 'opacity-0 pointer-events-none'}
|
||||||
`}
|
`}
|
||||||
>
|
>
|
||||||
<JumpToFileButton
|
<JumpToFileButton
|
||||||
|
|
|
||||||
|
|
@ -960,9 +960,9 @@ export const BlockCode = ({ initValue, language, maxHeight, showScrollbars }: Bl
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
export const VoidButtonBgDarken = ({ children, disabled, onClick }: { children: React.ReactNode; disabled?: boolean; onClick: () => void }) => {
|
export const VoidButtonBgDarken = ({ children, disabled, onClick, className }: { children: React.ReactNode; disabled?: boolean; onClick: () => void; className?: string }) => {
|
||||||
return <button disabled={disabled}
|
return <button disabled={disabled}
|
||||||
className='px-3 py-1 bg-black/10 dark:bg-white/10 rounded-sm overflow-hidden whitespace-nowrap flex items-center justify-center'
|
className={`px-3 py-1 bg-black/10 dark:bg-white/10 rounded-sm overflow-hidden whitespace-nowrap flex items-center justify-center ${className || ''}`}
|
||||||
onClick={onClick}
|
onClick={onClick}
|
||||||
>{children}</button>
|
>{children}</button>
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,7 @@ import { WarningBox } from './WarningBox.js'
|
||||||
import { os } from '../../../../common/helpers/systemInfo.js'
|
import { os } from '../../../../common/helpers/systemInfo.js'
|
||||||
import { IconLoading, IconX } from '../sidebar-tsx/SidebarChat.js'
|
import { IconLoading, IconX } from '../sidebar-tsx/SidebarChat.js'
|
||||||
import { getModelCapabilities, getProviderCapabilities, ollamaRecommendedModels, VoidStaticModelInfo } from '../../../../common/modelCapabilities.js'
|
import { getModelCapabilities, getProviderCapabilities, ollamaRecommendedModels, VoidStaticModelInfo } from '../../../../common/modelCapabilities.js'
|
||||||
|
import VoidImage from './VoidImage.js'
|
||||||
|
|
||||||
|
|
||||||
const ButtonLeftTextRightOption = ({ text, leftButton }: { text: string, leftButton?: React.ReactNode }) => {
|
const ButtonLeftTextRightOption = ({ text, leftButton }: { text: string, leftButton?: React.ReactNode }) => {
|
||||||
|
|
@ -544,7 +545,10 @@ export const FeaturesTab = () => {
|
||||||
{/* <h3 className={`opacity-50 mb-2`}>{`Instructions:`}</h3> */}
|
{/* <h3 className={`opacity-50 mb-2`}>{`Instructions:`}</h3> */}
|
||||||
{/* <h3 className={`mb-2`}>{`Void can access any model that you host locally. We automatically detect your local models by default.`}</h3> */}
|
{/* <h3 className={`mb-2`}>{`Void can access any model that you host locally. We automatically detect your local models by default.`}</h3> */}
|
||||||
<h3 className={`text-void-fg-3 mb-2`}>{`Void can access any model that you host locally. We automatically detect your local models by default.`}</h3>
|
<h3 className={`text-void-fg-3 mb-2`}>{`Void can access any model that you host locally. We automatically detect your local models by default.`}</h3>
|
||||||
{ollamaSetupInstructions}
|
|
||||||
|
<div className='opacity-80 mb-4'>
|
||||||
|
{ollamaSetupInstructions}
|
||||||
|
</div>
|
||||||
|
|
||||||
<ErrorBoundary>
|
<ErrorBoundary>
|
||||||
<VoidProviderSettings providerNames={localProviderNames} />
|
<VoidProviderSettings providerNames={localProviderNames} />
|
||||||
|
|
@ -805,7 +809,7 @@ const transferTheseFilesOfOS = (os: 'mac' | 'windows' | 'linux' | null, fromEdit
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const OneClickSwitchButton = ({ fromEditor = 'VS Code' }: { fromEditor?: TransferEditorType }) => {
|
const OneClickSwitchButton = ({ fromEditor = 'VS Code', className = '' }: { fromEditor?: TransferEditorType, className?: string }) => {
|
||||||
const accessor = useAccessor()
|
const accessor = useAccessor()
|
||||||
const fileService = accessor.get('IFileService')
|
const fileService = accessor.get('IFileService')
|
||||||
|
|
||||||
|
|
@ -866,7 +870,7 @@ const OneClickSwitchButton = ({ fromEditor = 'VS Code' }: { fromEditor?: Transfe
|
||||||
}
|
}
|
||||||
|
|
||||||
return <>
|
return <>
|
||||||
<VoidButtonBgDarken disabled={transferState.type !== 'done'} onClick={onClick}>
|
<VoidButtonBgDarken className={`max-w-48 p-4 ${className}`} disabled={transferState.type !== 'done'} onClick={onClick}>
|
||||||
{transferState.type === 'done' ? `Transfer from ${fromEditor}`
|
{transferState.type === 'done' ? `Transfer from ${fromEditor}`
|
||||||
: transferState.type === 'loading' ? <span className='text-nowrap flex flex-nowrap'>Transferring<IconLoading /></span>
|
: transferState.type === 'loading' ? <span className='text-nowrap flex flex-nowrap'>Transferring<IconLoading /></span>
|
||||||
: transferState.type === 'justfinished' ? <AnimatedCheckmarkButton text='Settings Transferred' className='bg-none' />
|
: transferState.type === 'justfinished' ? <AnimatedCheckmarkButton text='Settings Transferred' className='bg-none' />
|
||||||
|
|
@ -889,10 +893,10 @@ const GeneralTab = () => {
|
||||||
<h2 className={`text-3xl mb-2`}>One-Click Switch</h2>
|
<h2 className={`text-3xl mb-2`}>One-Click Switch</h2>
|
||||||
<h4 className={`text-void-fg-3 mb-2`}>{`Transfer your settings from another editor to Void in one click.`}</h4>
|
<h4 className={`text-void-fg-3 mb-2`}>{`Transfer your settings from another editor to Void in one click.`}</h4>
|
||||||
|
|
||||||
<div className='flex flex-col gap-3'>
|
<div className='flex flex-col gap-4'>
|
||||||
<OneClickSwitchButton fromEditor="VS Code" />
|
<OneClickSwitchButton className='w-48' fromEditor="VS Code" />
|
||||||
<OneClickSwitchButton fromEditor="Cursor" />
|
<OneClickSwitchButton className='w-48' fromEditor="Cursor" />
|
||||||
<OneClickSwitchButton fromEditor="Windsurf" />
|
<OneClickSwitchButton className='w-48' fromEditor="Windsurf" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
@ -903,29 +907,29 @@ const GeneralTab = () => {
|
||||||
<h4 className={`text-void-fg-3 mb-2`}>{`IDE settings, keyboard settings, and theme customization.`}</h4>
|
<h4 className={`text-void-fg-3 mb-2`}>{`IDE settings, keyboard settings, and theme customization.`}</h4>
|
||||||
|
|
||||||
<div className='my-4'>
|
<div className='my-4'>
|
||||||
<VoidButtonBgDarken onClick={() => { commandService.executeCommand('workbench.action.openSettings') }}>
|
<VoidButtonBgDarken className='px-4 py-2' onClick={() => { commandService.executeCommand('workbench.action.openSettings') }}>
|
||||||
General Settings
|
General Settings
|
||||||
</VoidButtonBgDarken>
|
</VoidButtonBgDarken>
|
||||||
</div>
|
</div>
|
||||||
<div className='my-4'>
|
<div className='my-4'>
|
||||||
<VoidButtonBgDarken onClick={() => { commandService.executeCommand('workbench.action.openGlobalKeybindings') }}>
|
<VoidButtonBgDarken className='px-4 py-2' onClick={() => { commandService.executeCommand('workbench.action.openGlobalKeybindings') }}>
|
||||||
Keyboard Settings
|
Keyboard Settings
|
||||||
</VoidButtonBgDarken>
|
</VoidButtonBgDarken>
|
||||||
</div>
|
</div>
|
||||||
<div className='my-4'>
|
<div className='my-4'>
|
||||||
<VoidButtonBgDarken onClick={() => { commandService.executeCommand('workbench.action.selectTheme') }}>
|
<VoidButtonBgDarken className='px-4 py-2' onClick={() => { commandService.executeCommand('workbench.action.selectTheme') }}>
|
||||||
Theme Settings
|
Theme Settings
|
||||||
</VoidButtonBgDarken>
|
</VoidButtonBgDarken>
|
||||||
</div>
|
</div>
|
||||||
<div className='my-4'>
|
<div className='my-4'>
|
||||||
<VoidButtonBgDarken onClick={() => { nativeHostService.showItemInFolder(environmentService.logsHome.fsPath) }}>
|
<VoidButtonBgDarken className='px-4 py-2' onClick={() => { nativeHostService.showItemInFolder(environmentService.logsHome.fsPath) }}>
|
||||||
Open Logs
|
Open Logs
|
||||||
</VoidButtonBgDarken>
|
</VoidButtonBgDarken>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
<div className='mt-12'>
|
<div className='mt-12 max-w-[600px]'>
|
||||||
<h2 className={`text-3xl mb-2`}>AI Instructions</h2>
|
<h2 className={`text-3xl mb-2`}>AI Instructions</h2>
|
||||||
<h4 className={`text-void-fg-3 mb-2`}>{`Instructions to include on all AI requests.`}</h4>
|
<h4 className={`text-void-fg-3 mb-2`}>{`Instructions to include on all AI requests.`}</h4>
|
||||||
<AIInstructionsBox />
|
<AIInstructionsBox />
|
||||||
|
|
@ -943,7 +947,7 @@ export const Settings = () => {
|
||||||
const [tab, setTab] = useState<TabName>('models')
|
const [tab, setTab] = useState<TabName>('models')
|
||||||
|
|
||||||
|
|
||||||
const deleteme = true
|
const deleteme = false
|
||||||
if (deleteme) {
|
if (deleteme) {
|
||||||
return <div className={`@@void-scope ${isDark ? 'dark' : ''}`} style={{ width: '100%', height: '100%' }}>
|
return <div className={`@@void-scope ${isDark ? 'dark' : ''}`} style={{ width: '100%', height: '100%' }}>
|
||||||
<VoidOnboarding />
|
<VoidOnboarding />
|
||||||
|
|
@ -964,10 +968,10 @@ export const Settings = () => {
|
||||||
|
|
||||||
{/* tabs */}
|
{/* tabs */}
|
||||||
<div className='flex flex-col w-full max-w-32'>
|
<div className='flex flex-col w-full max-w-32'>
|
||||||
<button className={`text-left p-1 px-3 my-0.5 rounded-full overflow-hidden ${tab === 'models' ? 'bg-[#0e70c0]/90 text-white font-medium' : 'bg-[#0e70c0]/10 text-void-fg-2'} hover:bg-[#0e70c0]/30 transition-colors duration-150`}
|
<button className={`text-left p-1 px-3 my-0.5 rounded-sm overflow-hidden ${tab === 'models' ? 'bg-black/10 dark:bg-gray-200/10' : ''} hover:bg-black/10 hover:dark:bg-gray-200/10 active:bg-black/10 active:dark:bg-gray-200/10 `}
|
||||||
onClick={() => { setTab('models') }}
|
onClick={() => { setTab('models') }}
|
||||||
>Models</button>
|
>Models</button>
|
||||||
<button className={`text-left p-1 px-3 my-0.5 rounded-full overflow-hidden ${tab === 'general' ? 'bg-[#0e70c0]/90 text-white font-medium' : 'bg-[#0e70c0]/10 text-void-fg-2'} hover:bg-[#0e70c0]/30 transition-colors duration-150`}
|
<button className={`text-left p-1 px-3 my-0.5 rounded-sm overflow-hidden ${tab === 'general' ? 'bg-black/10 dark:bg-gray-200/10' : ''} hover:bg-black/10 hover:dark:bg-gray-200/10 active:bg-black/10 active:dark:bg-gray-200/10 `}
|
||||||
onClick={() => { setTab('general') }}
|
onClick={() => { setTab('general') }}
|
||||||
>General</button>
|
>General</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -1100,7 +1104,7 @@ const PreviousButton = ({ onClick, ...props }: { onClick: () => void } & React.B
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const ollamaSetupInstructions = <div className='prose-p:my-0 prose-p:py-0 prose-ol:my-0 prose-ol:py-0 prose-span:my-0 prose-span:py-0 text-void-fg-3 text-sm font-light list-decimal select-text'>
|
const ollamaSetupInstructions = <div className='prose-p:my-0 prose-p:py-0 prose-ol:my-0 prose-ol:py-0 prose-span:my-0 prose-span:py-0 text-void-fg-3 text-sm font-light list-decimal select-text opacity-80'>
|
||||||
<div className=''><ChatMarkdownRender string={`Ollama Setup Instructions`} chatMessageLocation={undefined} /></div>
|
<div className=''><ChatMarkdownRender string={`Ollama Setup Instructions`} chatMessageLocation={undefined} /></div>
|
||||||
<div className=' pl-6'><ChatMarkdownRender string={`1. Download [Ollama](https://ollama.com/download).`} chatMessageLocation={undefined} /></div>
|
<div className=' pl-6'><ChatMarkdownRender string={`1. Download [Ollama](https://ollama.com/download).`} chatMessageLocation={undefined} /></div>
|
||||||
<div className=' pl-6'><ChatMarkdownRender string={`2. Open your terminal.`} chatMessageLocation={undefined} /></div>
|
<div className=' pl-6'><ChatMarkdownRender string={`2. Open your terminal.`} chatMessageLocation={undefined} /></div>
|
||||||
|
|
@ -1420,12 +1424,12 @@ const VoidOnboarding = () => {
|
||||||
// TODO add a description next to the skip button saying (you can always restart the onboarding in Settings)
|
// TODO add a description next to the skip button saying (you can always restart the onboarding in Settings)
|
||||||
const contentOfIdx: { [pageIndex: number]: React.ReactNode } = {
|
const contentOfIdx: { [pageIndex: number]: React.ReactNode } = {
|
||||||
0: <div className="max-w-[600px] w-full h-full text-left mx-auto flex flex-col items-center justify-between">
|
0: <div className="max-w-[600px] w-full h-full text-left mx-auto flex flex-col items-center justify-between">
|
||||||
<FadeIn className="text-5xl font-light mb-6 mt-12">
|
<FadeIn >
|
||||||
Welcome to Void
|
<div className="text-5xl font-light mb-6 mt-12 text-center">Welcome to Void</div>
|
||||||
|
|
||||||
|
|
||||||
Image
|
|
||||||
<div className="w-8 h-8 mb-2">
|
<div className="w-8 h-8 mb-2">
|
||||||
<img src="void-icon.png" alt="Void Logo" className="w-full h-full" />
|
<VoidImage className='h-full w-full' />
|
||||||
</div>
|
</div>
|
||||||
</FadeIn>
|
</FadeIn>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ import { QueryBuilder } from '../../../services/search/common/queryBuilder.js'
|
||||||
import { ISearchService } from '../../../services/search/common/search.js'
|
import { ISearchService } from '../../../services/search/common/search.js'
|
||||||
import { IEditCodeService } from './editCodeServiceInterface.js'
|
import { IEditCodeService } from './editCodeServiceInterface.js'
|
||||||
import { ITerminalToolService } from './terminalToolService.js'
|
import { ITerminalToolService } from './terminalToolService.js'
|
||||||
import { ToolCallParams, ToolResultType } from '../common/toolsServiceTypes.js'
|
import { LintErrorItem, ToolCallParams, ToolResultType } from '../common/toolsServiceTypes.js'
|
||||||
import { IVoidModelService } from '../common/voidModelService.js'
|
import { IVoidModelService } from '../common/voidModelService.js'
|
||||||
import { EndOfLinePreference } from '../../../../editor/common/model.js'
|
import { EndOfLinePreference } from '../../../../editor/common/model.js'
|
||||||
import { basename } from '../../../../base/common/path.js'
|
import { basename } from '../../../../base/common/path.js'
|
||||||
|
|
@ -359,13 +359,18 @@ export class ToolsService implements IToolsService {
|
||||||
|
|
||||||
const lintErrorsPromise = applyDonePromise.then(async () => {
|
const lintErrorsPromise = applyDonePromise.then(async () => {
|
||||||
await timeout(500)
|
await timeout(500)
|
||||||
const lintErrorsStr = this.markerService
|
|
||||||
.read({ resource: uri })
|
|
||||||
.map(l => l.message)
|
|
||||||
.join('\n')
|
|
||||||
|
|
||||||
if (!lintErrorsStr) return { lintErrorsStr: null }
|
const lintErrors = this.markerService
|
||||||
return { lintErrorsStr }
|
.read({ resource: uri })
|
||||||
|
.map(l => ({
|
||||||
|
code: typeof l.code === 'string' ? l.code : l.code?.value || '',
|
||||||
|
message: l.message,
|
||||||
|
startLineNumber: l.startLineNumber,
|
||||||
|
endLineNumber: l.endLineNumber,
|
||||||
|
} satisfies LintErrorItem))
|
||||||
|
|
||||||
|
if (!lintErrors.length) return { lintErrors: null }
|
||||||
|
return { lintErrors, }
|
||||||
})
|
})
|
||||||
|
|
||||||
return { result: lintErrorsPromise, interruptTool }
|
return { result: lintErrorsPromise, interruptTool }
|
||||||
|
|
@ -379,6 +384,8 @@ export class ToolsService implements IToolsService {
|
||||||
|
|
||||||
const nextPageStr = (hasNextPage: boolean) => hasNextPage ? '\n\n(more on next page...)' : ''
|
const nextPageStr = (hasNextPage: boolean) => hasNextPage ? '\n\n(more on next page...)' : ''
|
||||||
|
|
||||||
|
const lintErrorsStr = (lintErrors: LintErrorItem[]) => lintErrors.map((e, i) => `Error ${i + 1}:\nLines Affected: ${e.startLineNumber}-${e.endLineNumber}\nError message:${e.message}`).join('\n\n')
|
||||||
|
|
||||||
// given to the LLM after the call
|
// given to the LLM after the call
|
||||||
this.stringOfResult = {
|
this.stringOfResult = {
|
||||||
read_file: (params, result) => {
|
read_file: (params, result) => {
|
||||||
|
|
@ -405,8 +412,10 @@ export class ToolsService implements IToolsService {
|
||||||
return `URI ${params.uri.fsPath} successfully deleted.`
|
return `URI ${params.uri.fsPath} successfully deleted.`
|
||||||
},
|
},
|
||||||
edit_file: (params, result) => {
|
edit_file: (params, result) => {
|
||||||
const additionalStr = result.lintErrorsStr ? `Lint errors found after change:\n${result.lintErrorsStr}.\nIf this is related to a change made while calling this tool, you might want to fix the error.` : `No lint errors found.`
|
|
||||||
return `Change successfully made to ${params.uri.fsPath}. ${additionalStr}`
|
const additionalStr = result.lintErrors ? `Lint errors found after change:\n${lintErrorsStr(result.lintErrors)}.\nIf this is related to a change made while calling this tool, you might want to fix the error.` : `No lint errors found.`
|
||||||
|
|
||||||
|
return `Change successfully made to ${params.uri.fsPath}.${additionalStr}`
|
||||||
},
|
},
|
||||||
run_terminal_command: (params, result) => {
|
run_terminal_command: (params, result) => {
|
||||||
const {
|
const {
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,7 @@ export type ToolMessage<T extends ToolName> = {
|
||||||
| { type: 'running_now', result: null, name: T, params: ToolCallParams[T], }
|
| { type: 'running_now', result: null, name: T, params: ToolCallParams[T], }
|
||||||
|
|
||||||
| { type: 'tool_error', result: string, name: T, params: ToolCallParams[T], } // error when tool was running
|
| { type: 'tool_error', result: string, name: T, params: ToolCallParams[T], } // error when tool was running
|
||||||
| { type: 'success', result: ToolResultType[T], name: T, params: ToolCallParams[T], }
|
| { type: 'success', result: Awaited<ToolResultType[T]>, name: T, params: ToolCallParams[T], }
|
||||||
| { type: 'rejected', result: null, name: T, params: ToolCallParams[T], }
|
| { type: 'rejected', result: null, name: T, params: ToolCallParams[T], }
|
||||||
) // user rejected
|
) // user rejected
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,8 @@ import { ToolName } from './prompt/prompts.js';
|
||||||
|
|
||||||
export type TerminalResolveReason = { type: 'toofull' | 'timeout' | 'bgtask' } | { type: 'done', exitCode: number }
|
export type TerminalResolveReason = { type: 'toofull' | 'timeout' | 'bgtask' } | { type: 'done', exitCode: number }
|
||||||
|
|
||||||
|
export type LintErrorItem = { code: string, message: string, startLineNumber: number, endLineNumber: number }
|
||||||
|
|
||||||
// Partial of IFileStat
|
// Partial of IFileStat
|
||||||
export type ShallowDirectoryItem = {
|
export type ShallowDirectoryItem = {
|
||||||
uri: URI;
|
uri: URI;
|
||||||
|
|
@ -42,7 +44,7 @@ export type ToolResultType = {
|
||||||
'search_pathnames_only': { uris: URI[], hasNextPage: boolean },
|
'search_pathnames_only': { uris: URI[], hasNextPage: boolean },
|
||||||
'search_files': { uris: URI[], hasNextPage: boolean },
|
'search_files': { uris: URI[], hasNextPage: boolean },
|
||||||
// ---
|
// ---
|
||||||
'edit_file': Promise<{ lintErrorsStr: string | null }>,
|
'edit_file': Promise<{ lintErrors: LintErrorItem[] | null }>,
|
||||||
'create_file_or_folder': {},
|
'create_file_or_folder': {},
|
||||||
'delete_file_or_folder': {},
|
'delete_file_or_folder': {},
|
||||||
'run_terminal_command': { terminalId: string, didCreateTerminal: boolean, result: string; resolveReason: TerminalResolveReason; },
|
'run_terminal_command': { terminalId: string, didCreateTerminal: boolean, result: string; resolveReason: TerminalResolveReason; },
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue