From 6dc857907b1310cc26154aba19d7f94d318042ea Mon Sep 17 00:00:00 2001 From: ryoppippi <1560508+ryoppippi@users.noreply.github.com> Date: Sun, 14 Dec 2025 13:03:43 +0000 Subject: [PATCH 1/3] refactor(toolsets): remove unused matchesFilter method Remove the private matchesFilter method from StackOneToolSet class as it was never called anywhere in the codebase. The filterTools method implements filtering directly using matchGlob without delegating to matchesFilter. Changes: - Remove matchesFilter method (lines 355-371) - Remove unused import of Arrayable from type-fest - Remove unused import of toArray from utils/array - Remove testMatchesFilter helper from test class - Remove associated test cases for matchesFilter - Rename describe block from 'glob and filter matching' to 'glob matching' --- src/toolsets.test.ts | 30 +----------------------------- src/toolsets.ts | 26 -------------------------- 2 files changed, 1 insertion(+), 55 deletions(-) diff --git a/src/toolsets.test.ts b/src/toolsets.test.ts index 2530a85..9aaad1d 100644 --- a/src/toolsets.test.ts +++ b/src/toolsets.test.ts @@ -17,11 +17,6 @@ import { StackOneToolSet, ToolSetConfigError } from './toolsets'; */ class TestableStackOneToolSet extends StackOneToolSet { // Expose private methods for testing - public testMatchesFilter(toolName: string, filterPattern: string | string[]): boolean { - // eslint-disable-next-line @typescript-eslint/no-explicit-any -- Accessing private method for testing - return (this as any).matchesFilter(toolName, filterPattern); - } - public testMatchGlob(str: string, pattern: string): boolean { // eslint-disable-next-line @typescript-eslint/no-explicit-any -- Accessing private method for testing return (this as any).matchGlob(str, pattern); @@ -174,7 +169,7 @@ describe('StackOneToolSet', () => { }); }); - describe('glob and filter matching', () => { + describe('glob matching', () => { it('should correctly match glob patterns', () => { const toolset = new TestableStackOneToolSet({ apiKey: 'test_key' }); @@ -184,29 +179,6 @@ describe('StackOneToolSet', () => { expect(toolset.testMatchGlob('bamboohr_get_employee', 'bamboohr_get_?mployee')).toBe(true); expect(toolset.testMatchGlob('bamboohr.get.employee', 'bamboohr.get.employee')).toBe(true); }); - - it('should correctly filter tools with a pattern', () => { - const toolset = new TestableStackOneToolSet({ apiKey: 'test_key' }); - - expect(toolset.testMatchesFilter('bamboohr_get_employee', 'bamboohr_*')).toBe(true); - expect(toolset.testMatchesFilter('salesforce_get_contact', 'bamboohr_*')).toBe(false); - expect( - toolset.testMatchesFilter('bamboohr_get_employee', ['bamboohr_*', 'salesforce_*']), - ).toBe(true); - expect( - toolset.testMatchesFilter('salesforce_get_contact', ['bamboohr_*', 'salesforce_*']), - ).toBe(true); - expect( - toolset.testMatchesFilter('workday_get_candidate', ['bamboohr_*', 'salesforce_*']), - ).toBe(false); - - // Test negative patterns - expect(toolset.testMatchesFilter('bamboohr_get_employee', ['*', '!salesforce_*'])).toBe(true); - expect(toolset.testMatchesFilter('salesforce_get_contact', ['*', '!salesforce_*'])).toBe( - false, - ); - expect(toolset.testMatchesFilter('bamboohr_get_employee', ['*', '!bamboohr_*'])).toBe(false); - }); }); describe('fetchTools (MCP integration)', () => { diff --git a/src/toolsets.ts b/src/toolsets.ts index b15d82d..9eba7d5 100644 --- a/src/toolsets.ts +++ b/src/toolsets.ts @@ -1,5 +1,4 @@ import { defu } from 'defu'; -import type { Arrayable } from 'type-fest'; import { DEFAULT_BASE_URL, UNIFIED_API_PREFIX } from './consts'; import { createFeedbackTool } from './feedback'; import { type StackOneHeaders, normaliseHeaders, stackOneHeadersSchema } from './headers'; @@ -13,7 +12,6 @@ import type { RpcExecuteConfig, ToolParameters, } from './types'; -import { toArray } from './utils/array'; import { StackOneError } from './utils/errors'; /** @@ -346,30 +344,6 @@ export class StackOneToolSet { return new Tools(filteredTools); } - /** - * Check if a tool name matches a filter pattern - * @param toolName Tool name to check - * @param filterPattern Filter pattern or array of patterns - * @returns True if the tool name matches the filter pattern - */ - private matchesFilter(toolName: string, filterPattern: Arrayable): boolean { - // Convert to array to handle both single string and array patterns - const patterns = toArray(filterPattern); - - // Split into positive and negative patterns - const positivePatterns = patterns.filter((p) => !p.startsWith('!')); - const negativePatterns = patterns.filter((p) => p.startsWith('!')).map((p) => p.substring(1)); - - // If no positive patterns, treat as match all - const matchesPositive = - positivePatterns.length === 0 || positivePatterns.some((p) => this.matchGlob(toolName, p)); - - // If any negative pattern matches, exclude the tool - const matchesNegative = negativePatterns.some((p) => this.matchGlob(toolName, p)); - - return matchesPositive && !matchesNegative; - } - /** * Check if a string matches a glob pattern * @param str String to check From ed8f883cca0245c4bd685e66694533940164774c Mon Sep 17 00:00:00 2001 From: ryoppippi <1560508+ryoppippi@users.noreply.github.com> Date: Sun, 14 Dec 2025 13:03:53 +0000 Subject: [PATCH 2/3] chore(deps): add typescript as devDependency Add typescript to enable vitest type checking during test runs. Previously vitest's typecheck feature would fail with 'spawn tsc ENOENT' because typescript was not installed as a dependency. - Add typescript ^5.8.3 to pnpm-workspace.yaml catalog - Add typescript: catalog:dev to package.json devDependencies --- package.json | 1 + pnpm-lock.yaml | 6 ++++++ pnpm-workspace.yaml | 1 + 3 files changed, 8 insertions(+) diff --git a/package.json b/package.json index 99464bb..69976e4 100644 --- a/package.json +++ b/package.json @@ -59,6 +59,7 @@ "publint": "catalog:dev", "tsdown": "catalog:dev", "type-fest": "catalog:dev", + "typescript": "catalog:dev", "unplugin-unused": "catalog:dev", "vitest": "catalog:dev" }, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index afdd528..d53dc7b 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -60,6 +60,9 @@ catalogs: type-fest: specifier: ^4.41.0 version: 4.41.0 + typescript: + specifier: ^5.8.3 + version: 5.9.3 unplugin-unused: specifier: ^0.5.4 version: 0.5.6 @@ -176,6 +179,9 @@ importers: type-fest: specifier: catalog:dev version: 4.41.0 + typescript: + specifier: catalog:dev + version: 5.9.3 unplugin-unused: specifier: catalog:dev version: 0.5.6 diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index f13557b..e86a9b3 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -24,6 +24,7 @@ catalogs: publint: ^0.3.12 tsdown: ^0.17.2 type-fest: ^4.41.0 + typescript: ^5.8.3 unplugin-unused: ^0.5.4 vitest: ^4.0.15 zod: ^4.1.13 From af110c9c0f9e6d64ced9f6e77a2d7e47241d69bb Mon Sep 17 00:00:00 2001 From: ryoppippi <1560508+ryoppippi@users.noreply.github.com> Date: Sun, 14 Dec 2025 13:10:29 +0000 Subject: [PATCH 3/3] test: remove useless test(it is test for msw lol) --- src/toolsets.test.ts | 23 ----------------------- 1 file changed, 23 deletions(-) diff --git a/src/toolsets.test.ts b/src/toolsets.test.ts index 9aaad1d..f905407 100644 --- a/src/toolsets.test.ts +++ b/src/toolsets.test.ts @@ -12,17 +12,6 @@ import { type McpToolDefinition, createMcpApp } from '../mocks/mcp-server'; import { server } from '../mocks/node'; import { StackOneToolSet, ToolSetConfigError } from './toolsets'; -/** - * Test helper: Extends StackOneToolSet to expose private methods for testing - */ -class TestableStackOneToolSet extends StackOneToolSet { - // Expose private methods for testing - public testMatchGlob(str: string, pattern: string): boolean { - // eslint-disable-next-line @typescript-eslint/no-explicit-any -- Accessing private method for testing - return (this as any).matchGlob(str, pattern); - } -} - describe('StackOneToolSet', () => { beforeEach(() => { vi.stubEnv('STACKONE_API_KEY', 'test_key'); @@ -169,18 +158,6 @@ describe('StackOneToolSet', () => { }); }); - describe('glob matching', () => { - it('should correctly match glob patterns', () => { - const toolset = new TestableStackOneToolSet({ apiKey: 'test_key' }); - - expect(toolset.testMatchGlob('bamboohr_get_employee', 'bamboohr_*')).toBe(true); - expect(toolset.testMatchGlob('bamboohr_get_employee', 'salesforce_*')).toBe(false); - expect(toolset.testMatchGlob('bamboohr_get_employee', '*_get_*')).toBe(true); - expect(toolset.testMatchGlob('bamboohr_get_employee', 'bamboohr_get_?mployee')).toBe(true); - expect(toolset.testMatchGlob('bamboohr.get.employee', 'bamboohr.get.employee')).toBe(true); - }); - }); - describe('fetchTools (MCP integration)', () => { it('creates tools from MCP catalog and wires RPC execution', async () => { const toolset = new StackOneToolSet({