diff options
Diffstat (limited to 'packages/cli')
| -rw-r--r-- | packages/cli/src/config/config.test.ts | 128 | ||||
| -rw-r--r-- | packages/cli/src/config/config.ts | 17 | ||||
| -rw-r--r-- | packages/cli/src/config/extension.ts | 1 |
3 files changed, 145 insertions, 1 deletions
diff --git a/packages/cli/src/config/config.test.ts b/packages/cli/src/config/config.test.ts index 9808c407..d4820726 100644 --- a/packages/cli/src/config/config.test.ts +++ b/packages/cli/src/config/config.test.ts @@ -350,3 +350,131 @@ describe('mergeMcpServers', () => { expect(settings).toEqual(originalSettings); }); }); + +describe('mergeExcludeTools', () => { + it('should merge excludeTools from settings and extensions', async () => { + const settings: Settings = { excludeTools: ['tool1', 'tool2'] }; + const extensions: Extension[] = [ + { + config: { + name: 'ext1', + version: '1.0.0', + excludeTools: ['tool3', 'tool4'], + }, + contextFiles: [], + }, + { + config: { + name: 'ext2', + version: '1.0.0', + excludeTools: ['tool5'], + }, + contextFiles: [], + }, + ]; + const config = await loadCliConfig(settings, extensions, 'test-session'); + expect(config.getExcludeTools()).toEqual( + expect.arrayContaining(['tool1', 'tool2', 'tool3', 'tool4', 'tool5']), + ); + expect(config.getExcludeTools()).toHaveLength(5); + }); + + it('should handle overlapping excludeTools between settings and extensions', async () => { + const settings: Settings = { excludeTools: ['tool1', 'tool2'] }; + const extensions: Extension[] = [ + { + config: { + name: 'ext1', + version: '1.0.0', + excludeTools: ['tool2', 'tool3'], + }, + contextFiles: [], + }, + ]; + const config = await loadCliConfig(settings, extensions, 'test-session'); + expect(config.getExcludeTools()).toEqual( + expect.arrayContaining(['tool1', 'tool2', 'tool3']), + ); + expect(config.getExcludeTools()).toHaveLength(3); + }); + + it('should handle overlapping excludeTools between extensions', async () => { + const settings: Settings = { excludeTools: ['tool1'] }; + const extensions: Extension[] = [ + { + config: { + name: 'ext1', + version: '1.0.0', + excludeTools: ['tool2', 'tool3'], + }, + contextFiles: [], + }, + { + config: { + name: 'ext2', + version: '1.0.0', + excludeTools: ['tool3', 'tool4'], + }, + contextFiles: [], + }, + ]; + const config = await loadCliConfig(settings, extensions, 'test-session'); + expect(config.getExcludeTools()).toEqual( + expect.arrayContaining(['tool1', 'tool2', 'tool3', 'tool4']), + ); + expect(config.getExcludeTools()).toHaveLength(4); + }); + + it('should return an empty array when no excludeTools are specified', async () => { + const settings: Settings = {}; + const extensions: Extension[] = []; + const config = await loadCliConfig(settings, extensions, 'test-session'); + expect(config.getExcludeTools()).toEqual([]); + }); + + it('should handle settings with excludeTools but no extensions', async () => { + const settings: Settings = { excludeTools: ['tool1', 'tool2'] }; + const extensions: Extension[] = []; + const config = await loadCliConfig(settings, extensions, 'test-session'); + expect(config.getExcludeTools()).toEqual( + expect.arrayContaining(['tool1', 'tool2']), + ); + expect(config.getExcludeTools()).toHaveLength(2); + }); + + it('should handle extensions with excludeTools but no settings', async () => { + const settings: Settings = {}; + const extensions: Extension[] = [ + { + config: { + name: 'ext1', + version: '1.0.0', + excludeTools: ['tool1', 'tool2'], + }, + contextFiles: [], + }, + ]; + const config = await loadCliConfig(settings, extensions, 'test-session'); + expect(config.getExcludeTools()).toEqual( + expect.arrayContaining(['tool1', 'tool2']), + ); + expect(config.getExcludeTools()).toHaveLength(2); + }); + + it('should not modify the original settings object', async () => { + const settings: Settings = { excludeTools: ['tool1'] }; + const extensions: Extension[] = [ + { + config: { + name: 'ext1', + version: '1.0.0', + excludeTools: ['tool2'], + }, + contextFiles: [], + }, + ]; + const originalSettings = JSON.parse(JSON.stringify(settings)); + await loadCliConfig(settings, extensions, 'test-session'); + expect(settings).toEqual(originalSettings); + }); +}); diff --git a/packages/cli/src/config/config.ts b/packages/cli/src/config/config.ts index 552a8f67..cecf904b 100644 --- a/packages/cli/src/config/config.ts +++ b/packages/cli/src/config/config.ts @@ -194,6 +194,7 @@ export async function loadCliConfig( ); const mcpServers = mergeMcpServers(settings, extensions); + const excludeTools = mergeExcludeTools(settings, extensions); const sandboxConfig = await loadSandboxConfig(settings, argv); @@ -206,7 +207,7 @@ export async function loadCliConfig( question: argv.prompt || '', fullContext: argv.all_files || false, coreTools: settings.coreTools || undefined, - excludeTools: settings.excludeTools || undefined, + excludeTools, toolDiscoveryCommand: settings.toolDiscoveryCommand, toolCallCommand: settings.toolCallCommand, mcpServerCommand: settings.mcpServerCommand, @@ -265,6 +266,20 @@ function mergeMcpServers(settings: Settings, extensions: Extension[]) { } return mcpServers; } + +function mergeExcludeTools( + settings: Settings, + extensions: Extension[], +): string[] { + const allExcludeTools = new Set(settings.excludeTools || []); + for (const extension of extensions) { + for (const tool of extension.config.excludeTools || []) { + allExcludeTools.add(tool); + } + } + return [...allExcludeTools]; +} + function findEnvFile(startDir: string): string | null { let currentDir = path.resolve(startDir); while (true) { diff --git a/packages/cli/src/config/extension.ts b/packages/cli/src/config/extension.ts index 31a6111f..57e6632b 100644 --- a/packages/cli/src/config/extension.ts +++ b/packages/cli/src/config/extension.ts @@ -22,6 +22,7 @@ export interface ExtensionConfig { version: string; mcpServers?: Record<string, MCPServerConfig>; contextFileName?: string | string[]; + excludeTools?: string[]; } export function loadExtensions(workspaceDir: string): Extension[] { |
