From 1ab1aba52839429cb7411d49cf053da575041fd1 Mon Sep 17 00:00:00 2001 From: Ashwin Bhat Date: Fri, 20 Dec 2024 15:20:54 -0800 Subject: [PATCH 1/5] test: move component tests to __tests__ directory --- client/package.json | 10 +- .../src/__tests__/components/History.test.tsx | 40 + .../__tests__/components/ListPane.test.tsx | 84 ++ .../src/__tests__/components/PingTab.test.tsx | 47 + .../__tests__/components/PromptsTab.test.tsx | 96 ++ .../components/ResourcesTab.test.tsx | 132 ++ .../__tests__/components/RootsTab.test.tsx | 80 ++ .../__tests__/components/SamplingTab.test.tsx | 85 ++ client/src/__tests__/setup/setup.ts | 11 + client/src/components/RootsTab.tsx | 1 + client/vitest.config.ts | 19 + package-lock.json | 1062 ++++++++++++++++- 12 files changed, 1659 insertions(+), 8 deletions(-) create mode 100644 client/src/__tests__/components/History.test.tsx create mode 100644 client/src/__tests__/components/ListPane.test.tsx create mode 100644 client/src/__tests__/components/PingTab.test.tsx create mode 100644 client/src/__tests__/components/PromptsTab.test.tsx create mode 100644 client/src/__tests__/components/ResourcesTab.test.tsx create mode 100644 client/src/__tests__/components/RootsTab.test.tsx create mode 100644 client/src/__tests__/components/SamplingTab.test.tsx create mode 100644 client/src/__tests__/setup/setup.ts create mode 100644 client/vitest.config.ts diff --git a/client/package.json b/client/package.json index 888495c565..8f5c66b9cb 100644 --- a/client/package.json +++ b/client/package.json @@ -18,7 +18,9 @@ "dev": "vite", "build": "tsc -b && vite build", "lint": "eslint .", - "preview": "vite preview" + "preview": "vite preview", + "test": "vitest", + "test:coverage": "vitest run --coverage" }, "dependencies": { "@modelcontextprotocol/sdk": "^1.0.3", @@ -40,6 +42,8 @@ }, "devDependencies": { "@eslint/js": "^9.11.1", + "@testing-library/jest-dom": "^6.6.3", + "@testing-library/react": "^16.1.0", "@types/node": "^22.7.5", "@types/react": "^18.3.10", "@types/react-dom": "^18.3.0", @@ -50,10 +54,12 @@ "eslint-plugin-react-hooks": "^5.1.0-rc.0", "eslint-plugin-react-refresh": "^0.4.12", "globals": "^15.9.0", + "jsdom": "^25.0.1", "postcss": "^8.4.47", "tailwindcss": "^3.4.13", "typescript": "^5.5.3", "typescript-eslint": "^8.7.0", - "vite": "^5.4.8" + "vite": "^5.4.8", + "vitest": "^2.1.8" } } diff --git a/client/src/__tests__/components/History.test.tsx b/client/src/__tests__/components/History.test.tsx new file mode 100644 index 0000000000..594b73ebf0 --- /dev/null +++ b/client/src/__tests__/components/History.test.tsx @@ -0,0 +1,40 @@ +import { describe, it, expect } from 'vitest' +import { render, screen, fireEvent } from '@testing-library/react' +import HistoryAndNotifications from '../../components/History' + +describe('HistoryAndNotifications', () => { + const mockHistory = [ + { request: JSON.stringify({ method: 'test1' }), response: JSON.stringify({ result: 'output1' }) }, + { request: JSON.stringify({ method: 'test2' }), response: JSON.stringify({ result: 'output2' }) } + ] + + it('renders history items', () => { + render() + const items = screen.getAllByText(/test[12]/, { exact: false }) + expect(items).toHaveLength(2) + }) + + it('expands history item when clicked', () => { + render() + + const firstItem = screen.getByText(/test1/, { exact: false }) + fireEvent.click(firstItem) + expect(screen.getByText('Request:')).toBeInTheDocument() + expect(screen.getByText(/output1/, { exact: false })).toBeInTheDocument() + }) + + it('renders and expands server notifications', () => { + const notifications = [ + { method: 'notify1', params: { data: 'test data 1' } }, + { method: 'notify2', params: { data: 'test data 2' } } + ] + render() + + const items = screen.getAllByText(/notify[12]/, { exact: false }) + expect(items).toHaveLength(2) + + fireEvent.click(items[0]) + expect(screen.getByText('Details:')).toBeInTheDocument() + expect(screen.getByText(/test data/, { exact: false })).toBeInTheDocument() + }) +}) \ No newline at end of file diff --git a/client/src/__tests__/components/ListPane.test.tsx b/client/src/__tests__/components/ListPane.test.tsx new file mode 100644 index 0000000000..081cfb1362 --- /dev/null +++ b/client/src/__tests__/components/ListPane.test.tsx @@ -0,0 +1,84 @@ +import { describe, it, expect, vi } from 'vitest' +import { render, screen, fireEvent } from '@testing-library/react' +import ListPane from '../../components/ListPane' + +describe('ListPane', () => { + type TestItem = { + id: number; + name: string; + } + + const mockItems: TestItem[] = [ + { id: 1, name: 'Item 1' }, + { id: 2, name: 'Item 2' } + ] + + const defaultProps = { + items: mockItems, + listItems: vi.fn(), + clearItems: vi.fn(), + setSelectedItem: vi.fn(), + renderItem: (item: TestItem) => ( + <> + {item.name} + ID: {item.id} + + ), + title: 'Test Items', + buttonText: 'List Items' + } + + it('renders title and buttons', () => { + render() + expect(screen.getByText('Test Items')).toBeInTheDocument() + expect(screen.getByText('List Items')).toBeInTheDocument() + expect(screen.getByText('Clear')).toBeInTheDocument() + }) + + it('renders list of items using renderItem prop', () => { + render() + expect(screen.getByText('Item 1')).toBeInTheDocument() + expect(screen.getByText('Item 2')).toBeInTheDocument() + expect(screen.getByText('ID: 1')).toBeInTheDocument() + expect(screen.getByText('ID: 2')).toBeInTheDocument() + }) + + it('calls listItems when List Items button is clicked', () => { + const listItems = vi.fn() + render() + + fireEvent.click(screen.getByText('List Items')) + expect(listItems).toHaveBeenCalled() + }) + + it('calls clearItems when Clear button is clicked', () => { + const clearItems = vi.fn() + render() + + fireEvent.click(screen.getByText('Clear')) + expect(clearItems).toHaveBeenCalled() + }) + + it('calls setSelectedItem when an item is clicked', () => { + const setSelectedItem = vi.fn() + render() + + fireEvent.click(screen.getByText('Item 1')) + expect(setSelectedItem).toHaveBeenCalledWith(mockItems[0]) + }) + + it('disables Clear button when items array is empty', () => { + render() + expect(screen.getByText('Clear')).toBeDisabled() + }) + + it('disables List Items button when isButtonDisabled is true', () => { + render() + expect(screen.getByText('List Items')).toBeDisabled() + }) + + it('enables List Items button when isButtonDisabled is false', () => { + render() + expect(screen.getByText('List Items')).not.toBeDisabled() + }) +}) \ No newline at end of file diff --git a/client/src/__tests__/components/PingTab.test.tsx b/client/src/__tests__/components/PingTab.test.tsx new file mode 100644 index 0000000000..603cb03cb8 --- /dev/null +++ b/client/src/__tests__/components/PingTab.test.tsx @@ -0,0 +1,47 @@ +import { describe, it, expect, vi } from 'vitest' +import { render, screen, fireEvent } from '@testing-library/react' +import PingTab from '../../components/PingTab' +import { Tabs } from '@/components/ui/tabs' + +describe('PingTab', () => { + const renderWithTabs = (component: React.ReactElement) => { + return render( + + {component} + + ) + } + + it('renders the MEGA PING button', () => { + renderWithTabs( {}} />) + const button = screen.getByRole('button', { name: /mega ping/i }) + expect(button).toBeInTheDocument() + expect(button).toHaveClass('bg-gradient-to-r', 'from-purple-500', 'to-pink-500') + }) + + it('includes rocket and explosion emojis', () => { + renderWithTabs( {}} />) + expect(screen.getByText('🚀')).toBeInTheDocument() + expect(screen.getByText('💥')).toBeInTheDocument() + }) + + it('calls onPingClick when button is clicked', () => { + const onPingClick = vi.fn() + renderWithTabs() + + fireEvent.click(screen.getByRole('button', { name: /mega ping/i })) + expect(onPingClick).toHaveBeenCalledTimes(1) + }) + + it('has animation classes for visual feedback', () => { + renderWithTabs( {}} />) + const button = screen.getByRole('button', { name: /mega ping/i }) + expect(button).toHaveClass('animate-pulse', 'hover:scale-110', 'transition') + }) + + it('has focus styles for accessibility', () => { + renderWithTabs( {}} />) + const button = screen.getByRole('button', { name: /mega ping/i }) + expect(button).toHaveClass('focus:outline-none', 'focus:ring-4') + }) +}) \ No newline at end of file diff --git a/client/src/__tests__/components/PromptsTab.test.tsx b/client/src/__tests__/components/PromptsTab.test.tsx new file mode 100644 index 0000000000..62f69efbbb --- /dev/null +++ b/client/src/__tests__/components/PromptsTab.test.tsx @@ -0,0 +1,96 @@ +import { describe, it, expect, vi } from 'vitest' +import { render, screen, fireEvent } from '@testing-library/react' +import PromptsTab from '../../components/PromptsTab' +import type { Prompt } from '../../components/PromptsTab' +import { Tabs } from '@/components/ui/tabs' + +describe('PromptsTab', () => { + const mockPrompts: Prompt[] = [ + { + name: 'test-prompt-1', + description: 'Test prompt 1 description', + arguments: [ + { name: 'arg1', description: 'Argument 1', required: true }, + { name: 'arg2', description: 'Argument 2' } + ] + }, + { + name: 'test-prompt-2', + description: 'Test prompt 2 description' + } + ] + + const defaultProps = { + prompts: mockPrompts, + listPrompts: vi.fn(), + clearPrompts: vi.fn(), + getPrompt: vi.fn(), + selectedPrompt: null, + setSelectedPrompt: vi.fn(), + promptContent: '', + nextCursor: null, + error: null + } + + const renderWithTabs = (component: React.ReactElement) => { + return render( + + {component} + + ) + } + + it('renders list of prompts', () => { + renderWithTabs() + expect(screen.getByText('test-prompt-1')).toBeInTheDocument() + expect(screen.getByText('test-prompt-2')).toBeInTheDocument() + }) + + it('shows prompt details when selected', () => { + const props = { + ...defaultProps, + selectedPrompt: mockPrompts[0] + } + renderWithTabs() + expect(screen.getByText('Test prompt 1 description', { selector: 'p.text-sm.text-gray-600' })).toBeInTheDocument() + expect(screen.getByText('arg1')).toBeInTheDocument() + expect(screen.getByText('arg2')).toBeInTheDocument() + }) + + it('handles argument input', () => { + const getPrompt = vi.fn() + const props = { + ...defaultProps, + selectedPrompt: mockPrompts[0], + getPrompt + } + renderWithTabs() + + const arg1Input = screen.getByPlaceholderText('Enter arg1') + fireEvent.change(arg1Input, { target: { value: 'test value' } }) + + const getPromptButton = screen.getByText('Get Prompt') + fireEvent.click(getPromptButton) + + expect(getPrompt).toHaveBeenCalledWith('test-prompt-1', { arg1: 'test value' }) + }) + + it('shows error message when error prop is provided', () => { + const props = { + ...defaultProps, + error: 'Test error message' + } + renderWithTabs() + expect(screen.getByText('Test error message')).toBeInTheDocument() + }) + + it('shows prompt content when provided', () => { + const props = { + ...defaultProps, + selectedPrompt: mockPrompts[0], + promptContent: 'Test prompt content' + } + renderWithTabs() + expect(screen.getByText('Test prompt content')).toBeInTheDocument() + }) +}) \ No newline at end of file diff --git a/client/src/__tests__/components/ResourcesTab.test.tsx b/client/src/__tests__/components/ResourcesTab.test.tsx new file mode 100644 index 0000000000..df88bd343b --- /dev/null +++ b/client/src/__tests__/components/ResourcesTab.test.tsx @@ -0,0 +1,132 @@ +import { describe, it, expect, vi } from 'vitest' +import { render, screen, fireEvent } from '@testing-library/react' +import ResourcesTab from '../../components/ResourcesTab' +import { Tabs } from '@/components/ui/tabs' +import type { Resource, ResourceTemplate } from '@modelcontextprotocol/sdk/types.js' + +describe('ResourcesTab', () => { + const mockResources: Resource[] = [ + { uri: 'file:///test1.txt', name: 'Test 1' }, + { uri: 'file:///test2.txt', name: 'Test 2' } + ] + + const mockTemplates: ResourceTemplate[] = [ + { + name: 'Template 1', + description: 'Test template 1', + uriTemplate: 'file:///test/{param1}/{param2}.txt' + }, + { + name: 'Template 2', + description: 'Test template 2', + uriTemplate: 'file:///other/{name}.txt' + } + ] + + const defaultProps = { + resources: mockResources, + resourceTemplates: mockTemplates, + listResources: vi.fn(), + clearResources: vi.fn(), + listResourceTemplates: vi.fn(), + clearResourceTemplates: vi.fn(), + readResource: vi.fn(), + selectedResource: null, + setSelectedResource: vi.fn(), + resourceContent: '', + nextCursor: null, + nextTemplateCursor: null, + error: null + } + + const renderWithTabs = (component: React.ReactElement) => { + return render( + + {component} + + ) + } + + it('renders resources list', () => { + renderWithTabs() + expect(screen.getByText('Test 1')).toBeInTheDocument() + expect(screen.getByText('Test 2')).toBeInTheDocument() + }) + + it('renders templates list', () => { + renderWithTabs() + expect(screen.getByText('Template 1')).toBeInTheDocument() + expect(screen.getByText('Template 2')).toBeInTheDocument() + }) + + it('shows resource content when resource is selected', () => { + const props = { + ...defaultProps, + selectedResource: mockResources[0], + resourceContent: 'Test content' + } + renderWithTabs() + expect(screen.getByText('Test content')).toBeInTheDocument() + }) + + it('shows template form when template is selected', () => { + renderWithTabs() + + fireEvent.click(screen.getByText('Template 1')) + expect(screen.getByText('Test template 1')).toBeInTheDocument() + expect(screen.getByLabelText('param1')).toBeInTheDocument() + expect(screen.getByLabelText('param2')).toBeInTheDocument() + }) + + it('fills template and reads resource', () => { + const readResource = vi.fn() + const setSelectedResource = vi.fn() + renderWithTabs( + + ) + + // Select template + fireEvent.click(screen.getByText('Template 1')) + + // Fill in template parameters + fireEvent.change(screen.getByLabelText('param1'), { target: { value: 'value1' } }) + fireEvent.change(screen.getByLabelText('param2'), { target: { value: 'value2' } }) + + // Submit form + fireEvent.click(screen.getByText('Read Resource')) + + expect(readResource).toHaveBeenCalledWith('file:///test/value1/value2.txt') + expect(setSelectedResource).toHaveBeenCalledWith( + expect.objectContaining({ + uri: 'file:///test/value1/value2.txt', + name: 'file:///test/value1/value2.txt' + }) + ) + }) + + it('shows error message when error prop is provided', () => { + const props = { + ...defaultProps, + error: 'Test error message' + } + renderWithTabs() + expect(screen.getByText('Test error message')).toBeInTheDocument() + }) + + it('refreshes resource content when refresh button is clicked', () => { + const readResource = vi.fn() + const props = { + ...defaultProps, + selectedResource: mockResources[0], + readResource + } + renderWithTabs() + + fireEvent.click(screen.getByText('Refresh')) + expect(readResource).toHaveBeenCalledWith(mockResources[0].uri) + }) +}) \ No newline at end of file diff --git a/client/src/__tests__/components/RootsTab.test.tsx b/client/src/__tests__/components/RootsTab.test.tsx new file mode 100644 index 0000000000..ab5cd79965 --- /dev/null +++ b/client/src/__tests__/components/RootsTab.test.tsx @@ -0,0 +1,80 @@ +import { describe, it, expect, vi } from 'vitest' +import { render, screen, fireEvent } from '@testing-library/react' +import RootsTab from '../../components/RootsTab' +import { Tabs } from '@/components/ui/tabs' +import type { Root } from '@modelcontextprotocol/sdk/types.js' + +describe('RootsTab', () => { + const mockRoots: Root[] = [ + { uri: 'file:///test/path1', name: 'test1' }, + { uri: 'file:///test/path2', name: 'test2' } + ] + + const defaultProps = { + roots: mockRoots, + setRoots: vi.fn(), + onRootsChange: vi.fn() + } + + const renderWithTabs = (component: React.ReactElement) => { + return render( + + {component} + + ) + } + + it('renders list of roots', () => { + renderWithTabs() + expect(screen.getByDisplayValue('file:///test/path1')).toBeInTheDocument() + expect(screen.getByDisplayValue('file:///test/path2')).toBeInTheDocument() + }) + + it('adds a new root when Add Root button is clicked', () => { + const setRoots = vi.fn() + renderWithTabs() + + fireEvent.click(screen.getByText('Add Root')) + + expect(setRoots).toHaveBeenCalled() + const updateFn = setRoots.mock.calls[0][0] + const result = updateFn(mockRoots) + expect(result).toEqual([...mockRoots, { uri: 'file://', name: '' }]) + }) + + it('removes a root when remove button is clicked', () => { + const setRoots = vi.fn() + renderWithTabs() + + const removeButtons = screen.getAllByRole('button', { name: /remove root/i }) + fireEvent.click(removeButtons[0]) + + expect(setRoots).toHaveBeenCalled() + const updateFn = setRoots.mock.calls[0][0] + const result = updateFn(mockRoots) + expect(result).toEqual([mockRoots[1]]) + }) + + it('updates root URI when input changes', () => { + const setRoots = vi.fn() + renderWithTabs() + + const firstInput = screen.getByDisplayValue('file:///test/path1') + fireEvent.change(firstInput, { target: { value: 'file:///new/path' } }) + + expect(setRoots).toHaveBeenCalled() + const updateFn = setRoots.mock.calls[0][0] + const result = updateFn(mockRoots) + expect(result[0].uri).toBe('file:///new/path') + expect(result[1]).toEqual(mockRoots[1]) + }) + + it('calls onRootsChange when Save Changes is clicked', () => { + const onRootsChange = vi.fn() + renderWithTabs() + + fireEvent.click(screen.getByText('Save Changes')) + + expect(onRootsChange).toHaveBeenCalled() + }) +}) \ No newline at end of file diff --git a/client/src/__tests__/components/SamplingTab.test.tsx b/client/src/__tests__/components/SamplingTab.test.tsx new file mode 100644 index 0000000000..28c0e899d7 --- /dev/null +++ b/client/src/__tests__/components/SamplingTab.test.tsx @@ -0,0 +1,85 @@ +import { describe, it, expect, vi } from 'vitest' +import { render, screen, fireEvent } from '@testing-library/react' +import SamplingTab from '../../components/SamplingTab' +import { Tabs } from '@/components/ui/tabs' +import type { CreateMessageRequest } from '@modelcontextprotocol/sdk/types.js' + +describe('SamplingTab', () => { + const mockRequest: CreateMessageRequest = { + model: 'test-model', + role: 'user', + content: { + type: 'text', + text: 'Test message' + } + } + + const mockPendingRequests = [ + { id: 1, request: mockRequest }, + { id: 2, request: { ...mockRequest, content: { type: 'text', text: 'Another test' } } } + ] + + const defaultProps = { + pendingRequests: mockPendingRequests, + onApprove: vi.fn(), + onReject: vi.fn() + } + + const renderWithTabs = (component: React.ReactElement) => { + return render( + + {component} + + ) + } + + it('renders empty state when no requests', () => { + renderWithTabs() + expect(screen.getByText('No pending requests')).toBeInTheDocument() + }) + + it('renders list of pending requests', () => { + renderWithTabs() + expect(screen.getByText(/Test message/)).toBeInTheDocument() + expect(screen.getByText(/Another test/)).toBeInTheDocument() + }) + + it('shows request details in JSON format', () => { + renderWithTabs() + const requestJson = screen.getAllByText((content) => content.includes('"model": "test-model"')) + expect(requestJson).toHaveLength(2) + }) + + it('calls onApprove with stub response when Approve is clicked', () => { + const onApprove = vi.fn() + renderWithTabs() + + const approveButtons = screen.getAllByText('Approve') + fireEvent.click(approveButtons[0]) + + expect(onApprove).toHaveBeenCalledWith(1, { + model: 'stub-model', + stopReason: 'endTurn', + role: 'assistant', + content: { + type: 'text', + text: 'This is a stub response.' + } + }) + }) + + it('calls onReject when Reject is clicked', () => { + const onReject = vi.fn() + renderWithTabs() + + const rejectButtons = screen.getAllByText('Reject') + fireEvent.click(rejectButtons[0]) + + expect(onReject).toHaveBeenCalledWith(1) + }) + + it('shows informational alert about sampling requests', () => { + renderWithTabs() + expect(screen.getByText(/When the server requests LLM sampling/)).toBeInTheDocument() + }) +}) \ No newline at end of file diff --git a/client/src/__tests__/setup/setup.ts b/client/src/__tests__/setup/setup.ts new file mode 100644 index 0000000000..ff5206100d --- /dev/null +++ b/client/src/__tests__/setup/setup.ts @@ -0,0 +1,11 @@ +import '@testing-library/jest-dom' +import { expect, afterEach } from 'vitest' +import { cleanup } from '@testing-library/react' +import * as matchers from '@testing-library/jest-dom/matchers' + +// @ts-ignore +expect.extend(matchers) + +afterEach(() => { + cleanup() +}) \ No newline at end of file diff --git a/client/src/components/RootsTab.tsx b/client/src/components/RootsTab.tsx index 33f60d5d96..b6e145fa6e 100644 --- a/client/src/components/RootsTab.tsx +++ b/client/src/components/RootsTab.tsx @@ -54,6 +54,7 @@ const RootsTab = ({ variant="destructive" size="sm" onClick={() => removeRoot(index)} + aria-label="Remove root" > diff --git a/client/vitest.config.ts b/client/vitest.config.ts new file mode 100644 index 0000000000..87395e3521 --- /dev/null +++ b/client/vitest.config.ts @@ -0,0 +1,19 @@ +/// +import { defineConfig } from 'vite' +import react from '@vitejs/plugin-react' +import path from 'path' + +export default defineConfig({ + plugins: [react()], + resolve: { + alias: { + '@': path.resolve(__dirname, './src'), + }, + }, + test: { + environment: 'jsdom', + globals: true, + setupFiles: ['./src/__tests__/setup/setup.ts'], + include: ['src/__tests__/**/*.{test,spec}.{js,mjs,cjs,ts,mts,cts,jsx,tsx}'], + }, +}) \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 13f4248b9a..d6fe08ccdb 100644 --- a/package-lock.json +++ b/package-lock.json @@ -56,6 +56,8 @@ }, "devDependencies": { "@eslint/js": "^9.11.1", + "@testing-library/jest-dom": "^6.6.3", + "@testing-library/react": "^16.1.0", "@types/node": "^22.7.5", "@types/react": "^18.3.10", "@types/react-dom": "^18.3.0", @@ -66,13 +68,22 @@ "eslint-plugin-react-hooks": "^5.1.0-rc.0", "eslint-plugin-react-refresh": "^0.4.12", "globals": "^15.9.0", + "jsdom": "^25.0.1", "postcss": "^8.4.47", "tailwindcss": "^3.4.13", "typescript": "^5.5.3", "typescript-eslint": "^8.7.0", - "vite": "^5.4.8" + "vite": "^5.4.8", + "vitest": "^2.1.8" } }, + "node_modules/@adobe/css-tools": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/@adobe/css-tools/-/css-tools-4.4.1.tgz", + "integrity": "sha512-12WGKBQzjUAI4ayyF4IAtfw2QR/IDoqk6jTddXDhtYTJF9ASmoE1zst7cVtP0aL/F1jUJL5r+JxKXKEgHNbEUQ==", + "dev": true, + "license": "MIT" + }, "node_modules/@alloc/quick-lru": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/@alloc/quick-lru/-/quick-lru-5.2.0.tgz", @@ -323,6 +334,19 @@ "@babel/core": "^7.0.0-0" } }, + "node_modules/@babel/runtime": { + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.26.0.tgz", + "integrity": "sha512-FDSOghenHTiToteC/QRlv2q3DhPZ/oOXTBoirfWNx1Cx3TMVcGWQtMMmQcSvb/JjpNeGzx8Pq/b4fKEJuWm1sw==", + "dev": true, + "license": "MIT", + "dependencies": { + "regenerator-runtime": "^0.14.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, "node_modules/@babel/template": { "version": "7.25.9", "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.25.9.tgz", @@ -2150,6 +2174,110 @@ "win32" ] }, + "node_modules/@testing-library/dom": { + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-10.4.0.tgz", + "integrity": "sha512-pemlzrSESWbdAloYml3bAJMEfNh1Z7EduzqPKprCH5S341frlpYnUEW0H72dLxa6IsYr+mPno20GiSm+h9dEdQ==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@babel/code-frame": "^7.10.4", + "@babel/runtime": "^7.12.5", + "@types/aria-query": "^5.0.1", + "aria-query": "5.3.0", + "chalk": "^4.1.0", + "dom-accessibility-api": "^0.5.9", + "lz-string": "^1.5.0", + "pretty-format": "^27.0.2" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@testing-library/jest-dom": { + "version": "6.6.3", + "resolved": "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-6.6.3.tgz", + "integrity": "sha512-IteBhl4XqYNkM54f4ejhLRJiZNqcSCoXUOG2CPK7qbD322KjQozM4kHQOfkG2oln9b9HTYqs+Sae8vBATubxxA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@adobe/css-tools": "^4.4.0", + "aria-query": "^5.0.0", + "chalk": "^3.0.0", + "css.escape": "^1.5.1", + "dom-accessibility-api": "^0.6.3", + "lodash": "^4.17.21", + "redent": "^3.0.0" + }, + "engines": { + "node": ">=14", + "npm": ">=6", + "yarn": ">=1" + } + }, + "node_modules/@testing-library/jest-dom/node_modules/chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@testing-library/jest-dom/node_modules/dom-accessibility-api": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.6.3.tgz", + "integrity": "sha512-7ZgogeTnjuHbo+ct10G9Ffp0mif17idi0IyWNVA/wcwcm7NPOD/WEHVP3n7n3MhXqxoIYm8d6MuZohYWIZ4T3w==", + "dev": true, + "license": "MIT" + }, + "node_modules/@testing-library/jest-dom/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@testing-library/react": { + "version": "16.1.0", + "resolved": "https://registry.npmjs.org/@testing-library/react/-/react-16.1.0.tgz", + "integrity": "sha512-Q2ToPvg0KsVL0ohND9A3zLJWcOXXcO8IDu3fj11KhNt0UlCWyFyvnCIBkd12tidB2lkiVRG8VFqdhcqhqnAQtg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.12.5" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@testing-library/dom": "^10.0.0", + "@types/react": "^18.0.0 || ^19.0.0", + "@types/react-dom": "^18.0.0 || ^19.0.0", + "react": "^18.0.0 || ^19.0.0", + "react-dom": "^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, "node_modules/@tsconfig/node10": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.11.tgz", @@ -2174,6 +2302,14 @@ "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==", "license": "MIT" }, + "node_modules/@types/aria-query": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/@types/aria-query/-/aria-query-5.0.4.tgz", + "integrity": "sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw==", + "dev": true, + "license": "MIT", + "peer": true + }, "node_modules/@types/babel__core": { "version": "7.20.5", "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", @@ -2669,6 +2805,119 @@ "vite": "^4.2.0 || ^5.0.0 || ^6.0.0" } }, + "node_modules/@vitest/expect": { + "version": "2.1.8", + "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-2.1.8.tgz", + "integrity": "sha512-8ytZ/fFHq2g4PJVAtDX57mayemKgDR6X3Oa2Foro+EygiOJHUXhCqBAAKQYYajZpFoIfvBCF1j6R6IYRSIUFuw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/spy": "2.1.8", + "@vitest/utils": "2.1.8", + "chai": "^5.1.2", + "tinyrainbow": "^1.2.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/mocker": { + "version": "2.1.8", + "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-2.1.8.tgz", + "integrity": "sha512-7guJ/47I6uqfttp33mgo6ga5Gr1VnL58rcqYKyShoRK9ebu8T5Rs6HN3s1NABiBeVTdWNrwUMcHH54uXZBN4zA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/spy": "2.1.8", + "estree-walker": "^3.0.3", + "magic-string": "^0.30.12" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "msw": "^2.4.9", + "vite": "^5.0.0" + }, + "peerDependenciesMeta": { + "msw": { + "optional": true + }, + "vite": { + "optional": true + } + } + }, + "node_modules/@vitest/pretty-format": { + "version": "2.1.8", + "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-2.1.8.tgz", + "integrity": "sha512-9HiSZ9zpqNLKlbIDRWOnAWqgcA7xu+8YxXSekhr0Ykab7PAYFkhkwoqVArPOtJhPmYeE2YHgKZlj3CP36z2AJQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "tinyrainbow": "^1.2.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/runner": { + "version": "2.1.8", + "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-2.1.8.tgz", + "integrity": "sha512-17ub8vQstRnRlIU5k50bG+QOMLHRhYPAna5tw8tYbj+jzjcspnwnwtPtiOlkuKC4+ixDPTuLZiqiWWQ2PSXHVg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/utils": "2.1.8", + "pathe": "^1.1.2" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/snapshot": { + "version": "2.1.8", + "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-2.1.8.tgz", + "integrity": "sha512-20T7xRFbmnkfcmgVEz+z3AU/3b0cEzZOt/zmnvZEctg64/QZbSDJEVm9fLnnlSi74KibmRsO9/Qabi+t0vCRPg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/pretty-format": "2.1.8", + "magic-string": "^0.30.12", + "pathe": "^1.1.2" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/spy": { + "version": "2.1.8", + "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-2.1.8.tgz", + "integrity": "sha512-5swjf2q95gXeYPevtW0BLk6H8+bPlMb4Vw/9Em4hFxDcaOxS+e0LOX4yqNxoHzMR2akEB2xfpnWUzkZokmgWDg==", + "dev": true, + "license": "MIT", + "dependencies": { + "tinyspy": "^3.0.2" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/utils": { + "version": "2.1.8", + "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-2.1.8.tgz", + "integrity": "sha512-dwSoui6djdwbfFmIgbIjX2ZhIoG7Ex/+xpxyiEgIGzjliY8xGkcpITKTlp6B4MgtGkF2ilvm97cPM96XZaAgcA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/pretty-format": "2.1.8", + "loupe": "^3.1.2", + "tinyrainbow": "^1.2.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, "node_modules/accepts": { "version": "1.3.8", "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", @@ -2716,6 +2965,16 @@ "node": ">=0.4.0" } }, + "node_modules/agent-base": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.3.tgz", + "integrity": "sha512-jRR5wdylq8CkOe6hei19GGZnxM6rBGwFl3Bg0YItGDimvjGtAvdZk4Pu6Cl4u4Igsws4a1fd1Vq3ezrhn4KmFw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 14" + } + }, "node_modules/ajv": { "version": "6.12.6", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", @@ -2801,12 +3060,39 @@ "node": ">=10" } }, + "node_modules/aria-query": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.0.tgz", + "integrity": "sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "dequal": "^2.0.3" + } + }, "node_modules/array-flatten": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==", "license": "MIT" }, + "node_modules/assertion-error": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz", + "integrity": "sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + } + }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", + "dev": true, + "license": "MIT" + }, "node_modules/autoprefixer": { "version": "10.4.20", "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.20.tgz", @@ -2981,6 +3267,16 @@ "node": ">= 0.8" } }, + "node_modules/cac": { + "version": "6.7.14", + "resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz", + "integrity": "sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/call-bind": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", @@ -3040,6 +3336,23 @@ ], "license": "CC-BY-4.0" }, + "node_modules/chai": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/chai/-/chai-5.1.2.tgz", + "integrity": "sha512-aGtmf24DW6MLHHG5gCx4zaI3uBq3KRtxeVs0DjFH6Z0rDNbsvTxFASFvdj79pxjxZ8/5u3PIiN3IwEIQkiiuPw==", + "dev": true, + "license": "MIT", + "dependencies": { + "assertion-error": "^2.0.1", + "check-error": "^2.1.1", + "deep-eql": "^5.0.1", + "loupe": "^3.1.0", + "pathval": "^2.0.0" + }, + "engines": { + "node": ">=12" + } + }, "node_modules/chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", @@ -3068,6 +3381,16 @@ "node": ">=8" } }, + "node_modules/check-error": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-2.1.1.tgz", + "integrity": "sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 16" + } + }, "node_modules/chokidar": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", @@ -3157,6 +3480,19 @@ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "license": "MIT" }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dev": true, + "license": "MIT", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, "node_modules/commander": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", @@ -3273,6 +3609,13 @@ "node": ">= 8" } }, + "node_modules/css.escape": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/css.escape/-/css.escape-1.5.1.tgz", + "integrity": "sha512-YUifsXXuknHlUsmlgyY0PKzgPOr7/FjCePfHNt0jxm83wHZi44VDMQ7/fGNkjY3/jV1MC+1CmZbaHzugyeRtpg==", + "dev": true, + "license": "MIT" + }, "node_modules/cssesc": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", @@ -3285,6 +3628,19 @@ "node": ">=4" } }, + "node_modules/cssstyle": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-4.1.0.tgz", + "integrity": "sha512-h66W1URKpBS5YMI/V8PyXvTMFT8SupJ1IzoIV8IeBC/ji8WVmrO8dGlTi+2dh6whmdk6BiKJLD/ZBkhWbcg6nA==", + "dev": true, + "license": "MIT", + "dependencies": { + "rrweb-cssom": "^0.7.1" + }, + "engines": { + "node": ">=18" + } + }, "node_modules/csstype": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", @@ -3292,6 +3648,20 @@ "devOptional": true, "license": "MIT" }, + "node_modules/data-urls": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-5.0.0.tgz", + "integrity": "sha512-ZYP5VBHshaDAiVZxjbRVcFJpc+4xGgT0bK3vzy1HLN8jTO975HEbuYzZJcHoQEY5K1a0z8YayJkyVETa08eNTg==", + "dev": true, + "license": "MIT", + "dependencies": { + "whatwg-mimetype": "^4.0.0", + "whatwg-url": "^14.0.0" + }, + "engines": { + "node": ">=18" + } + }, "node_modules/debug": { "version": "4.3.7", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", @@ -3309,6 +3679,23 @@ } } }, + "node_modules/decimal.js": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.4.3.tgz", + "integrity": "sha512-VBBaLc1MgL5XpzgIP7ny5Z6Nx3UrRkIViUkPUdtl9aya5amy3De1gsUUSB1g3+3sExYNjCAsAznmukyxCb1GRA==", + "dev": true, + "license": "MIT" + }, + "node_modules/deep-eql": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-5.0.2.tgz", + "integrity": "sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, "node_modules/deep-is": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", @@ -3333,6 +3720,16 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.4.0" + } + }, "node_modules/depd": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", @@ -3342,6 +3739,16 @@ "node": ">= 0.8" } }, + "node_modules/dequal": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", + "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, "node_modules/destroy": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", @@ -3379,6 +3786,14 @@ "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==", "license": "MIT" }, + "node_modules/dom-accessibility-api": { + "version": "0.5.16", + "resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.5.16.tgz", + "integrity": "sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg==", + "dev": true, + "license": "MIT", + "peer": true + }, "node_modules/eastasianwidth": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", @@ -3413,6 +3828,19 @@ "node": ">= 0.8" } }, + "node_modules/entities": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, "node_modules/es-define-property": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", @@ -3434,6 +3862,13 @@ "node": ">= 0.4" } }, + "node_modules/es-module-lexer": { + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.5.4.tgz", + "integrity": "sha512-MVNK56NiMrOwitFB7cqDwq0CQutbw+0BvLshJSse0MUNU+y1FC3bUS/AQg7oUng+/wKrrki7JfmwtVHkVfPLlw==", + "dev": true, + "license": "MIT" + }, "node_modules/esbuild": { "version": "0.23.1", "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.23.1.tgz", @@ -3669,6 +4104,16 @@ "node": ">=4.0" } }, + "node_modules/estree-walker": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", + "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0" + } + }, "node_modules/esutils": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", @@ -3697,11 +4142,21 @@ "node": ">=12.0.0" } }, - "node_modules/express": { - "version": "4.21.1", - "resolved": "https://registry.npmjs.org/express/-/express-4.21.1.tgz", - "integrity": "sha512-YSFlK1Ee0/GC8QaO91tHcDxJiE/X4FbpAyQWkxAvG6AXCuR65YzK8ua6D9hvi/TzUfZMpc+BwuM1IPw8fmQBiQ==", - "license": "MIT", + "node_modules/expect-type": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/expect-type/-/expect-type-1.1.0.tgz", + "integrity": "sha512-bFi65yM+xZgk+u/KRIpekdSYkTB5W1pEf0Lt8Q8Msh7b+eQ7LXVtIB1Bkm4fvclDEL1b2CZkMhv2mOeF8tMdkA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/express": { + "version": "4.21.1", + "resolved": "https://registry.npmjs.org/express/-/express-4.21.1.tgz", + "integrity": "sha512-YSFlK1Ee0/GC8QaO91tHcDxJiE/X4FbpAyQWkxAvG6AXCuR65YzK8ua6D9hvi/TzUfZMpc+BwuM1IPw8fmQBiQ==", + "license": "MIT", "dependencies": { "accepts": "~1.3.8", "array-flatten": "1.1.1", @@ -3924,6 +4379,21 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/form-data": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.1.tgz", + "integrity": "sha512-tzN8e4TX8+kkxGPK8D5u0FNmjPUjw3lwC9lSLxxoB/+GtsJG91CO8bSWy73APlgAZzZbXEYZJuxjkHH2w+Ezhw==", + "dev": true, + "license": "MIT", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/forwarded": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", @@ -4184,6 +4654,19 @@ "node": ">= 0.4" } }, + "node_modules/html-encoding-sniffer": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-4.0.0.tgz", + "integrity": "sha512-Y22oTqIU4uuPgEemfz7NDJz6OeKf12Lsu+QC+s3BVpda64lTiMYCyGwg5ki4vFxkMwQdeZDl2adZoqUgdFuTgQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "whatwg-encoding": "^3.1.1" + }, + "engines": { + "node": ">=18" + } + }, "node_modules/http-errors": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", @@ -4200,6 +4683,34 @@ "node": ">= 0.8" } }, + "node_modules/http-proxy-agent": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz", + "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==", + "dev": true, + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.0", + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/https-proxy-agent": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz", + "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==", + "dev": true, + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.2", + "debug": "4" + }, + "engines": { + "node": ">= 14" + } + }, "node_modules/iconv-lite": { "version": "0.4.24", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", @@ -4249,6 +4760,16 @@ "node": ">=0.8.19" } }, + "node_modules/indent-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/inherits": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", @@ -4339,6 +4860,13 @@ "node": ">=0.12.0" } }, + "node_modules/is-potential-custom-element-name": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz", + "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==", + "dev": true, + "license": "MIT" + }, "node_modules/isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", @@ -4388,6 +4916,47 @@ "js-yaml": "bin/js-yaml.js" } }, + "node_modules/jsdom": { + "version": "25.0.1", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-25.0.1.tgz", + "integrity": "sha512-8i7LzZj7BF8uplX+ZyOlIz86V6TAsSs+np6m1kpW9u0JWi4z/1t+FzcK1aek+ybTnAC4KhBL4uXCNT0wcUIeCw==", + "dev": true, + "license": "MIT", + "dependencies": { + "cssstyle": "^4.1.0", + "data-urls": "^5.0.0", + "decimal.js": "^10.4.3", + "form-data": "^4.0.0", + "html-encoding-sniffer": "^4.0.0", + "http-proxy-agent": "^7.0.2", + "https-proxy-agent": "^7.0.5", + "is-potential-custom-element-name": "^1.0.1", + "nwsapi": "^2.2.12", + "parse5": "^7.1.2", + "rrweb-cssom": "^0.7.1", + "saxes": "^6.0.0", + "symbol-tree": "^3.2.4", + "tough-cookie": "^5.0.0", + "w3c-xmlserializer": "^5.0.0", + "webidl-conversions": "^7.0.0", + "whatwg-encoding": "^3.1.1", + "whatwg-mimetype": "^4.0.0", + "whatwg-url": "^14.0.0", + "ws": "^8.18.0", + "xml-name-validator": "^5.0.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "canvas": "^2.11.2" + }, + "peerDependenciesMeta": { + "canvas": { + "optional": true + } + } + }, "node_modules/jsesc": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.0.2.tgz", @@ -4515,6 +5084,13 @@ "loose-envify": "cli.js" } }, + "node_modules/loupe": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/loupe/-/loupe-3.1.2.tgz", + "integrity": "sha512-23I4pFZHmAemUnz8WZXbYRSKYj801VDaNv9ETuMh7IrMc7VuVVSo+Z9iLE3ni30+U48iDWfi30d3twAXBYmnCg==", + "dev": true, + "license": "MIT" + }, "node_modules/lru-cache": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", @@ -4534,6 +5110,27 @@ "react": "^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0-rc" } }, + "node_modules/lz-string": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/lz-string/-/lz-string-1.5.0.tgz", + "integrity": "sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==", + "dev": true, + "license": "MIT", + "peer": true, + "bin": { + "lz-string": "bin/bin.js" + } + }, + "node_modules/magic-string": { + "version": "0.30.17", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.17.tgz", + "integrity": "sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0" + } + }, "node_modules/make-error": { "version": "1.3.6", "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", @@ -4622,6 +5219,16 @@ "node": ">= 0.6" } }, + "node_modules/min-indent": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", + "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, "node_modules/minimatch": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", @@ -4720,6 +5327,13 @@ "node": ">=0.10.0" } }, + "node_modules/nwsapi": { + "version": "2.2.16", + "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.16.tgz", + "integrity": "sha512-F1I/bimDpj3ncaNDhfyMWuFqmQDBwDB0Fogc2qpL3BWvkQteFD/8BzWuIRl83rq0DXfm8SGt/HFhLXZyljTXcQ==", + "dev": true, + "license": "MIT" + }, "node_modules/object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", @@ -4831,6 +5445,19 @@ "node": ">=6" } }, + "node_modules/parse5": { + "version": "7.2.1", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.2.1.tgz", + "integrity": "sha512-BuBYQYlv1ckiPdQi/ohiivi9Sagc9JG+Ozs0r7b/0iK3sKmrb0b9FdWdBbOdx6hBCM/F9Ir82ofnBhtZOjCRPQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "entities": "^4.5.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, "node_modules/parseurl": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", @@ -4899,6 +5526,23 @@ "integrity": "sha512-7lf7qcQidTku0Gu3YDPc8DJ1q7OOucfa/BSsIwjuh56VU7katFvuM8hULfkwB3Fns/rsVF7PwPKVw1sl5KQS9w==", "license": "MIT" }, + "node_modules/pathe": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/pathe/-/pathe-1.1.2.tgz", + "integrity": "sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/pathval": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/pathval/-/pathval-2.0.0.tgz", + "integrity": "sha512-vE7JKRyES09KiunauX7nd2Q9/L7lhok4smP9RZTDeD4MVs72Dp2qNFVz39Nz5a0FVEW0BJR6C0DYrq6unoziZA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 14.16" + } + }, "node_modules/picocolors": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", @@ -5116,6 +5760,36 @@ "url": "https://github.com/prettier/prettier?sponsor=1" } }, + "node_modules/pretty-format": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.5.1.tgz", + "integrity": "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "ansi-regex": "^5.0.1", + "ansi-styles": "^5.0.0", + "react-is": "^17.0.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/pretty-format/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, "node_modules/proxy-addr": { "version": "2.0.7", "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", @@ -5235,6 +5909,14 @@ "react": "^18.3.1" } }, + "node_modules/react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", + "dev": true, + "license": "MIT", + "peer": true + }, "node_modules/react-refresh": { "version": "0.14.2", "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.14.2.tgz", @@ -5349,6 +6031,27 @@ "node": ">=8.10.0" } }, + "node_modules/redent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz", + "integrity": "sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==", + "dev": true, + "license": "MIT", + "dependencies": { + "indent-string": "^4.0.0", + "strip-indent": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/regenerator-runtime": { + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", + "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==", + "dev": true, + "license": "MIT" + }, "node_modules/require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", @@ -5443,6 +6146,13 @@ "fsevents": "~2.3.2" } }, + "node_modules/rrweb-cssom": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/rrweb-cssom/-/rrweb-cssom-0.7.1.tgz", + "integrity": "sha512-TrEMa7JGdVm0UThDJSx7ddw5nVm3UJS9o9CCIZ72B1vSyEZoziDqBYP3XIoi/12lKrJR8rE3jeFHMok2F/Mnsg==", + "dev": true, + "license": "MIT" + }, "node_modules/run-parallel": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", @@ -5501,6 +6211,19 @@ "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", "license": "MIT" }, + "node_modules/saxes": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/saxes/-/saxes-6.0.0.tgz", + "integrity": "sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==", + "dev": true, + "license": "ISC", + "dependencies": { + "xmlchars": "^2.2.0" + }, + "engines": { + "node": ">=v12.22.7" + } + }, "node_modules/scheduler": { "version": "0.23.2", "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz", @@ -5726,6 +6449,13 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/siginfo": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/siginfo/-/siginfo-2.0.0.tgz", + "integrity": "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==", + "dev": true, + "license": "ISC" + }, "node_modules/signal-exit": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", @@ -5757,6 +6487,13 @@ "rxjs": "^7.8.1" } }, + "node_modules/stackback": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz", + "integrity": "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==", + "dev": true, + "license": "MIT" + }, "node_modules/statuses": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", @@ -5766,6 +6503,13 @@ "node": ">= 0.8" } }, + "node_modules/std-env": { + "version": "3.8.0", + "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.8.0.tgz", + "integrity": "sha512-Bc3YwwCB+OzldMxOXJIIvC6cPRWr/LxOp48CdQTOkPyk/t4JWWJbrilwBd7RJzKV8QW7tJkcgAmeuLLJugl5/w==", + "dev": true, + "license": "MIT" + }, "node_modules/string-width": { "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", @@ -5820,6 +6564,19 @@ "node": ">=8" } }, + "node_modules/strip-indent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz", + "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "min-indent": "^1.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/strip-json-comments": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", @@ -5882,6 +6639,13 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/symbol-tree": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", + "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==", + "dev": true, + "license": "MIT" + }, "node_modules/tailwind-merge": { "version": "2.5.5", "resolved": "https://registry.npmjs.org/tailwind-merge/-/tailwind-merge-2.5.5.tgz", @@ -5959,6 +6723,70 @@ "node": ">=0.8" } }, + "node_modules/tinybench": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.9.0.tgz", + "integrity": "sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==", + "dev": true, + "license": "MIT" + }, + "node_modules/tinyexec": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-0.3.1.tgz", + "integrity": "sha512-WiCJLEECkO18gwqIp6+hJg0//p23HXp4S+gGtAKu3mI2F2/sXC4FvHvXvB0zJVVaTPhx1/tOwdbRsa1sOBIKqQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/tinypool": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-1.0.2.tgz", + "integrity": "sha512-al6n+QEANGFOMf/dmUMsuS5/r9B06uwlyNjZZql/zv8J7ybHCgoihBNORZCY2mzUuAnomQa2JdhyHKzZxPCrFA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.0.0 || >=20.0.0" + } + }, + "node_modules/tinyrainbow": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/tinyrainbow/-/tinyrainbow-1.2.0.tgz", + "integrity": "sha512-weEDEq7Z5eTHPDh4xjX789+fHfF+P8boiFB+0vbWzpbnbsEr/GRaohi/uMKxg8RZMXnl1ItAi/IUHWMsjDV7kQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/tinyspy": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-3.0.2.tgz", + "integrity": "sha512-n1cw8k1k0x4pgA2+9XrOkFydTerNcJ1zWCO5Nn9scWHTD+5tp8dghT2x1uduQePZTZgd3Tupf+x9BxJjeJi77Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/tldts": { + "version": "6.1.69", + "resolved": "https://registry.npmjs.org/tldts/-/tldts-6.1.69.tgz", + "integrity": "sha512-Oh/CqRQ1NXNY7cy9NkTPUauOWiTro0jEYZTioGbOmcQh6EC45oribyIMJp0OJO3677r13tO6SKdWoGZUx2BDFw==", + "dev": true, + "license": "MIT", + "dependencies": { + "tldts-core": "^6.1.69" + }, + "bin": { + "tldts": "bin/cli.js" + } + }, + "node_modules/tldts-core": { + "version": "6.1.69", + "resolved": "https://registry.npmjs.org/tldts-core/-/tldts-core-6.1.69.tgz", + "integrity": "sha512-nygxy9n2PBUFQUtAXAc122gGo+04/j5qr5TGQFZTHafTKYvmARVXt2cA5rgero2/dnXUfkdPtiJoKmrd3T+wdA==", + "dev": true, + "license": "MIT" + }, "node_modules/to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", @@ -5980,6 +6808,32 @@ "node": ">=0.6" } }, + "node_modules/tough-cookie": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-5.0.0.tgz", + "integrity": "sha512-FRKsF7cz96xIIeMZ82ehjC3xW2E+O2+v11udrDYewUbszngYhsGa8z6YUMMzO9QJZzzyd0nGGXnML/TReX6W8Q==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "tldts": "^6.1.32" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/tr46": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-5.0.0.tgz", + "integrity": "sha512-tk2G5R2KRwBd+ZN0zaEXpmzdKyOYksXwywulIX95MBODjSzMIuQnQ3m8JxgbhnL1LeVo7lqQKsYa1O3Htl7K5g==", + "dev": true, + "license": "MIT", + "dependencies": { + "punycode": "^2.3.1" + }, + "engines": { + "node": ">=18" + } + }, "node_modules/tree-kill": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz", @@ -6338,6 +7192,29 @@ } } }, + "node_modules/vite-node": { + "version": "2.1.8", + "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-2.1.8.tgz", + "integrity": "sha512-uPAwSr57kYjAUux+8E2j0q0Fxpn8M9VoyfGiRI8Kfktz9NcYMCenwY5RnZxnF1WTu3TGiYipirIzacLL3VVGFg==", + "dev": true, + "license": "MIT", + "dependencies": { + "cac": "^6.7.14", + "debug": "^4.3.7", + "es-module-lexer": "^1.5.4", + "pathe": "^1.1.2", + "vite": "^5.0.0" + }, + "bin": { + "vite-node": "vite-node.mjs" + }, + "engines": { + "node": "^18.0.0 || >=20.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, "node_modules/vite/node_modules/@esbuild/aix-ppc64": { "version": "0.21.5", "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz", @@ -6768,6 +7645,145 @@ "@esbuild/win32-x64": "0.21.5" } }, + "node_modules/vitest": { + "version": "2.1.8", + "resolved": "https://registry.npmjs.org/vitest/-/vitest-2.1.8.tgz", + "integrity": "sha512-1vBKTZskHw/aosXqQUlVWWlGUxSJR8YtiyZDJAFeW2kPAeX6S3Sool0mjspO+kXLuxVWlEDDowBAeqeAQefqLQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/expect": "2.1.8", + "@vitest/mocker": "2.1.8", + "@vitest/pretty-format": "^2.1.8", + "@vitest/runner": "2.1.8", + "@vitest/snapshot": "2.1.8", + "@vitest/spy": "2.1.8", + "@vitest/utils": "2.1.8", + "chai": "^5.1.2", + "debug": "^4.3.7", + "expect-type": "^1.1.0", + "magic-string": "^0.30.12", + "pathe": "^1.1.2", + "std-env": "^3.8.0", + "tinybench": "^2.9.0", + "tinyexec": "^0.3.1", + "tinypool": "^1.0.1", + "tinyrainbow": "^1.2.0", + "vite": "^5.0.0", + "vite-node": "2.1.8", + "why-is-node-running": "^2.3.0" + }, + "bin": { + "vitest": "vitest.mjs" + }, + "engines": { + "node": "^18.0.0 || >=20.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "@edge-runtime/vm": "*", + "@types/node": "^18.0.0 || >=20.0.0", + "@vitest/browser": "2.1.8", + "@vitest/ui": "2.1.8", + "happy-dom": "*", + "jsdom": "*" + }, + "peerDependenciesMeta": { + "@edge-runtime/vm": { + "optional": true + }, + "@types/node": { + "optional": true + }, + "@vitest/browser": { + "optional": true + }, + "@vitest/ui": { + "optional": true + }, + "happy-dom": { + "optional": true + }, + "jsdom": { + "optional": true + } + } + }, + "node_modules/w3c-xmlserializer": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-5.0.0.tgz", + "integrity": "sha512-o8qghlI8NZHU1lLPrpi2+Uq7abh4GGPpYANlalzWxyWteJOCsr/P+oPBA49TOLu5FTZO4d3F9MnWJfiMo4BkmA==", + "dev": true, + "license": "MIT", + "dependencies": { + "xml-name-validator": "^5.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/webidl-conversions": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz", + "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=12" + } + }, + "node_modules/whatwg-encoding": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-3.1.1.tgz", + "integrity": "sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "iconv-lite": "0.6.3" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/whatwg-encoding/node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "dev": true, + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/whatwg-mimetype": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-4.0.0.tgz", + "integrity": "sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/whatwg-url": { + "version": "14.1.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-14.1.0.tgz", + "integrity": "sha512-jlf/foYIKywAt3x/XWKZ/3rz8OSJPiWktjmk891alJUEjiVxKX9LEO92qH3hv4aJ0mN3MWPvGMCy8jQi95xK4w==", + "dev": true, + "license": "MIT", + "dependencies": { + "tr46": "^5.0.0", + "webidl-conversions": "^7.0.0" + }, + "engines": { + "node": ">=18" + } + }, "node_modules/which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", @@ -6783,6 +7799,23 @@ "node": ">= 8" } }, + "node_modules/why-is-node-running": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/why-is-node-running/-/why-is-node-running-2.3.0.tgz", + "integrity": "sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==", + "dev": true, + "license": "MIT", + "dependencies": { + "siginfo": "^2.0.0", + "stackback": "0.0.2" + }, + "bin": { + "why-is-node-running": "cli.js" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/word-wrap": { "version": "1.2.5", "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", @@ -6849,6 +7882,23 @@ } } }, + "node_modules/xml-name-validator": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-5.0.0.tgz", + "integrity": "sha512-EvGK8EJ3DhaHfbRlETOWAS5pO9MZITeauHKJyb8wyajUfQUenkIg2MvLDTZ4T/TgIcm3HU0TFBgWWboAZ30UHg==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18" + } + }, + "node_modules/xmlchars": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", + "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==", + "dev": true, + "license": "MIT" + }, "node_modules/y18n": { "version": "5.0.8", "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", From 579dd42c46caf611d8db9f7ec2836b7bb1682d22 Mon Sep 17 00:00:00 2001 From: Ashwin Bhat Date: Fri, 20 Dec 2024 15:36:15 -0800 Subject: [PATCH 2/5] test: add tests for App component - Add comprehensive tests for App.tsx - Fix test setup to handle window.matchMedia and URL params - Wrap state updates in act() - Use more specific selectors for finding elements - Fix sampling tab test to properly simulate pending requests --- client/src/__tests__/App.test.tsx | 213 ++++++++++++++++++++++++++++ client/src/__tests__/setup/setup.ts | 25 +++- 2 files changed, 237 insertions(+), 1 deletion(-) create mode 100644 client/src/__tests__/App.test.tsx diff --git a/client/src/__tests__/App.test.tsx b/client/src/__tests__/App.test.tsx new file mode 100644 index 0000000000..f215280309 --- /dev/null +++ b/client/src/__tests__/App.test.tsx @@ -0,0 +1,213 @@ +import { describe, it, expect, vi, beforeEach } from 'vitest' +import { render, screen, fireEvent, act } from '@testing-library/react' +import App from '../App' +import { useConnection } from '../lib/hooks/useConnection' +import { useDraggablePane } from '../lib/hooks/useDraggablePane' + +// Mock URL params +const mockURLSearchParams = vi.fn() +vi.stubGlobal('URLSearchParams', mockURLSearchParams) + +// Mock the hooks +vi.mock('../lib/hooks/useConnection', () => ({ + useConnection: vi.fn() +})) + +vi.mock('../lib/hooks/useDraggablePane', () => ({ + useDraggablePane: vi.fn() +})) + +// Mock fetch for config +const mockFetch = vi.fn() +global.fetch = mockFetch + +describe('App', () => { + beforeEach(() => { + // Reset all mocks + vi.clearAllMocks() + + // Mock URL params + mockURLSearchParams.mockReturnValue({ + get: () => '3000' + }) + + // Mock fetch response + mockFetch.mockResolvedValue({ + json: () => Promise.resolve({ + defaultEnvironment: {}, + defaultCommand: 'test-command', + defaultArgs: '--test' + }) + }) + + // Mock useConnection hook + const mockUseConnection = useConnection as jest.Mock + mockUseConnection.mockReturnValue({ + connectionStatus: 'disconnected', + serverCapabilities: null, + mcpClient: null, + requestHistory: [], + makeRequest: vi.fn(), + sendNotification: vi.fn(), + connect: vi.fn() + }) + + // Mock useDraggablePane hook + const mockUseDraggablePane = useDraggablePane as jest.Mock + mockUseDraggablePane.mockReturnValue({ + height: 300, + handleDragStart: vi.fn() + }) + }) + + it('renders initial disconnected state', async () => { + await act(async () => { + render() + }) + expect(screen.getByText('Connect to an MCP server to start inspecting')).toBeInTheDocument() + }) + + it('loads config on mount', async () => { + await act(async () => { + render() + }) + expect(mockFetch).toHaveBeenCalledWith('http://localhost:3000/config') + }) + + it('shows connected interface when mcpClient is available', async () => { + const mockUseConnection = useConnection as jest.Mock + mockUseConnection.mockReturnValue({ + connectionStatus: 'connected', + serverCapabilities: { + resources: true, + prompts: true, + tools: true + }, + mcpClient: {}, + requestHistory: [], + makeRequest: vi.fn(), + sendNotification: vi.fn(), + connect: vi.fn() + }) + + await act(async () => { + render() + }) + + // Use more specific selectors + const resourcesTab = screen.getByRole('tab', { name: /resources/i }) + const promptsTab = screen.getByRole('tab', { name: /prompts/i }) + const toolsTab = screen.getByRole('tab', { name: /tools/i }) + + expect(resourcesTab).toBeInTheDocument() + expect(promptsTab).toBeInTheDocument() + expect(toolsTab).toBeInTheDocument() + }) + + it('disables tabs based on server capabilities', async () => { + const mockUseConnection = useConnection as jest.Mock + mockUseConnection.mockReturnValue({ + connectionStatus: 'connected', + serverCapabilities: { + resources: false, + prompts: true, + tools: false + }, + mcpClient: {}, + requestHistory: [], + makeRequest: vi.fn(), + sendNotification: vi.fn(), + connect: vi.fn() + }) + + await act(async () => { + render() + }) + + // Resources tab should be disabled + const resourcesTab = screen.getByRole('tab', { name: /resources/i }) + expect(resourcesTab).toHaveAttribute('disabled') + + // Prompts tab should be enabled + const promptsTab = screen.getByRole('tab', { name: /prompts/i }) + expect(promptsTab).not.toHaveAttribute('disabled') + + // Tools tab should be disabled + const toolsTab = screen.getByRole('tab', { name: /tools/i }) + expect(toolsTab).toHaveAttribute('disabled') + }) + + it('shows notification count in sampling tab', async () => { + const mockUseConnection = useConnection as jest.Mock + mockUseConnection.mockReturnValue({ + connectionStatus: 'connected', + serverCapabilities: { sampling: true }, + mcpClient: {}, + requestHistory: [], + makeRequest: vi.fn(), + sendNotification: vi.fn(), + connect: vi.fn(), + onPendingRequest: (request, resolve, reject) => { + // Simulate a pending request + setPendingSampleRequests(prev => [ + ...prev, + { id: 1, request, resolve, reject } + ]) + } + }) + + await act(async () => { + render() + }) + + // Initially no notification count + const samplingTab = screen.getByRole('tab', { name: /sampling/i }) + expect(samplingTab.querySelector('.bg-red-500')).not.toBeInTheDocument() + + // Simulate a pending request + await act(async () => { + mockUseConnection.mock.calls[0][0].onPendingRequest( + { method: 'test', params: {} }, + () => {}, + () => {} + ) + }) + + // Should show notification count + expect(samplingTab.querySelector('.bg-red-500')).toBeInTheDocument() + }) + + it('persists command and args to localStorage', async () => { + const setItemSpy = vi.spyOn(Storage.prototype, 'setItem') + + await act(async () => { + render() + }) + + // Simulate command change + await act(async () => { + const commandInput = screen.getByPlaceholderText(/command/i) + fireEvent.change(commandInput, { target: { value: 'new-command' } }) + }) + + expect(setItemSpy).toHaveBeenCalledWith('lastCommand', 'new-command') + }) + + it('shows error message when server has no capabilities', async () => { + const mockUseConnection = useConnection as jest.Mock + mockUseConnection.mockReturnValue({ + connectionStatus: 'connected', + serverCapabilities: {}, + mcpClient: {}, + requestHistory: [], + makeRequest: vi.fn(), + sendNotification: vi.fn(), + connect: vi.fn() + }) + + await act(async () => { + render() + }) + expect(screen.getByText('The connected server does not support any MCP capabilities')).toBeInTheDocument() + }) +}) \ No newline at end of file diff --git a/client/src/__tests__/setup/setup.ts b/client/src/__tests__/setup/setup.ts index ff5206100d..dcba7c2f0d 100644 --- a/client/src/__tests__/setup/setup.ts +++ b/client/src/__tests__/setup/setup.ts @@ -1,11 +1,34 @@ import '@testing-library/jest-dom' -import { expect, afterEach } from 'vitest' +import { expect, afterEach, vi } from 'vitest' import { cleanup } from '@testing-library/react' import * as matchers from '@testing-library/jest-dom/matchers' // @ts-ignore expect.extend(matchers) +// Mock window.matchMedia +Object.defineProperty(window, 'matchMedia', { + writable: true, + value: vi.fn().mockImplementation(query => ({ + matches: false, + media: query, + onchange: null, + addListener: vi.fn(), // Deprecated + removeListener: vi.fn(), // Deprecated + addEventListener: vi.fn(), + removeEventListener: vi.fn(), + dispatchEvent: vi.fn(), + })), +}) + +// Mock window.location.hash +Object.defineProperty(window, 'location', { + writable: true, + value: { hash: '' } +}) + afterEach(() => { cleanup() + vi.clearAllMocks() + window.location.hash = '' }) \ No newline at end of file From c2c2043d051b599940acbdfcf22acc626952404b Mon Sep 17 00:00:00 2001 From: Ashwin Bhat Date: Fri, 20 Dec 2024 15:42:24 -0800 Subject: [PATCH 3/5] test: add test coverage reporting - Add @vitest/coverage-v8 for test coverage reporting - Current coverage: 65.59% statements, 83.83% branches, 42.7% functions - Components like ConsoleTab, ListPane, PingTab, RootsTab, SamplingTab at 100% - Identified areas needing more coverage: ToolsTab, Sidebar, hooks --- client/coverage/base.css | 224 ++ client/coverage/block-navigation.js | 87 + client/coverage/client/bin/cli.js.html | 133 + client/coverage/client/bin/index.html | 116 + client/coverage/client/index.html | 131 + client/coverage/client/postcss.config.js.html | 103 + client/coverage/client/src/App.tsx.html | 1693 +++++++++++++ .../client/src/components/ConsoleTab.tsx.html | 121 + .../client/src/components/History.tsx.html | 574 +++++ .../client/src/components/ListPane.tsx.html | 265 ++ .../client/src/components/PingTab.tsx.html | 148 ++ .../client/src/components/PromptsTab.tsx.html | 508 ++++ .../src/components/ResourcesTab.tsx.html | 700 ++++++ .../client/src/components/RootsTab.tsx.html | 319 +++ .../src/components/SamplingTab.tsx.html | 280 +++ .../client/src/components/Sidebar.tsx.html | 889 +++++++ .../client/src/components/ToolsTab.tsx.html | 823 +++++++ .../coverage/client/src/components/index.html | 251 ++ .../client/src/components/ui/alert.tsx.html | 262 ++ .../client/src/components/ui/button.tsx.html | 256 ++ .../client/src/components/ui/index.html | 206 ++ .../client/src/components/ui/input.tsx.html | 160 ++ .../client/src/components/ui/label.tsx.html | 157 ++ .../client/src/components/ui/select.tsx.html | 571 +++++ .../client/src/components/ui/tabs.tsx.html | 244 ++ .../src/components/ui/textarea.tsx.html | 157 ++ client/coverage/client/src/index.html | 131 + .../coverage/client/src/lib/hooks/index.html | 131 + .../src/lib/hooks/useConnection.ts.html | 646 +++++ .../src/lib/hooks/useDraggablePane.ts.html | 214 ++ client/coverage/client/src/lib/index.html | 146 ++ .../client/src/lib/notificationTypes.ts.html | 142 ++ .../coverage/client/src/lib/useTheme.ts.html | 238 ++ client/coverage/client/src/lib/utils.ts.html | 103 + client/coverage/client/src/main.tsx.html | 124 + .../coverage/client/tailwind.config.js.html | 259 ++ client/coverage/clover.xml | 2137 +++++++++++++++++ client/coverage/coverage-final.json | 28 + client/coverage/favicon.png | Bin 0 -> 445 bytes client/coverage/index.html | 206 ++ client/coverage/prettify.css | 1 + client/coverage/prettify.js | 2 + client/coverage/sort-arrow-sprite.png | Bin 0 -> 138 bytes client/coverage/sorter.js | 196 ++ client/package.json | 1 + package-lock.json | 207 ++ 46 files changed, 14290 insertions(+) create mode 100644 client/coverage/base.css create mode 100644 client/coverage/block-navigation.js create mode 100644 client/coverage/client/bin/cli.js.html create mode 100644 client/coverage/client/bin/index.html create mode 100644 client/coverage/client/index.html create mode 100644 client/coverage/client/postcss.config.js.html create mode 100644 client/coverage/client/src/App.tsx.html create mode 100644 client/coverage/client/src/components/ConsoleTab.tsx.html create mode 100644 client/coverage/client/src/components/History.tsx.html create mode 100644 client/coverage/client/src/components/ListPane.tsx.html create mode 100644 client/coverage/client/src/components/PingTab.tsx.html create mode 100644 client/coverage/client/src/components/PromptsTab.tsx.html create mode 100644 client/coverage/client/src/components/ResourcesTab.tsx.html create mode 100644 client/coverage/client/src/components/RootsTab.tsx.html create mode 100644 client/coverage/client/src/components/SamplingTab.tsx.html create mode 100644 client/coverage/client/src/components/Sidebar.tsx.html create mode 100644 client/coverage/client/src/components/ToolsTab.tsx.html create mode 100644 client/coverage/client/src/components/index.html create mode 100644 client/coverage/client/src/components/ui/alert.tsx.html create mode 100644 client/coverage/client/src/components/ui/button.tsx.html create mode 100644 client/coverage/client/src/components/ui/index.html create mode 100644 client/coverage/client/src/components/ui/input.tsx.html create mode 100644 client/coverage/client/src/components/ui/label.tsx.html create mode 100644 client/coverage/client/src/components/ui/select.tsx.html create mode 100644 client/coverage/client/src/components/ui/tabs.tsx.html create mode 100644 client/coverage/client/src/components/ui/textarea.tsx.html create mode 100644 client/coverage/client/src/index.html create mode 100644 client/coverage/client/src/lib/hooks/index.html create mode 100644 client/coverage/client/src/lib/hooks/useConnection.ts.html create mode 100644 client/coverage/client/src/lib/hooks/useDraggablePane.ts.html create mode 100644 client/coverage/client/src/lib/index.html create mode 100644 client/coverage/client/src/lib/notificationTypes.ts.html create mode 100644 client/coverage/client/src/lib/useTheme.ts.html create mode 100644 client/coverage/client/src/lib/utils.ts.html create mode 100644 client/coverage/client/src/main.tsx.html create mode 100644 client/coverage/client/tailwind.config.js.html create mode 100644 client/coverage/clover.xml create mode 100644 client/coverage/coverage-final.json create mode 100644 client/coverage/favicon.png create mode 100644 client/coverage/index.html create mode 100644 client/coverage/prettify.css create mode 100644 client/coverage/prettify.js create mode 100644 client/coverage/sort-arrow-sprite.png create mode 100644 client/coverage/sorter.js diff --git a/client/coverage/base.css b/client/coverage/base.css new file mode 100644 index 0000000000..f418035b46 --- /dev/null +++ b/client/coverage/base.css @@ -0,0 +1,224 @@ +body, html { + margin:0; padding: 0; + height: 100%; +} +body { + font-family: Helvetica Neue, Helvetica, Arial; + font-size: 14px; + color:#333; +} +.small { font-size: 12px; } +*, *:after, *:before { + -webkit-box-sizing:border-box; + -moz-box-sizing:border-box; + box-sizing:border-box; + } +h1 { font-size: 20px; margin: 0;} +h2 { font-size: 14px; } +pre { + font: 12px/1.4 Consolas, "Liberation Mono", Menlo, Courier, monospace; + margin: 0; + padding: 0; + -moz-tab-size: 2; + -o-tab-size: 2; + tab-size: 2; +} +a { color:#0074D9; text-decoration:none; } +a:hover { text-decoration:underline; } +.strong { font-weight: bold; } +.space-top1 { padding: 10px 0 0 0; } +.pad2y { padding: 20px 0; } +.pad1y { padding: 10px 0; } +.pad2x { padding: 0 20px; } +.pad2 { padding: 20px; } +.pad1 { padding: 10px; } +.space-left2 { padding-left:55px; } +.space-right2 { padding-right:20px; } +.center { text-align:center; } +.clearfix { display:block; } +.clearfix:after { + content:''; + display:block; + height:0; + clear:both; + visibility:hidden; + } +.fl { float: left; } +@media only screen and (max-width:640px) { + .col3 { width:100%; max-width:100%; } + .hide-mobile { display:none!important; } +} + +.quiet { + color: #7f7f7f; + color: rgba(0,0,0,0.5); +} +.quiet a { opacity: 0.7; } + +.fraction { + font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; + font-size: 10px; + color: #555; + background: #E8E8E8; + padding: 4px 5px; + border-radius: 3px; + vertical-align: middle; +} + +div.path a:link, div.path a:visited { color: #333; } +table.coverage { + border-collapse: collapse; + margin: 10px 0 0 0; + padding: 0; +} + +table.coverage td { + margin: 0; + padding: 0; + vertical-align: top; +} +table.coverage td.line-count { + text-align: right; + padding: 0 5px 0 20px; +} +table.coverage td.line-coverage { + text-align: right; + padding-right: 10px; + min-width:20px; +} + +table.coverage td span.cline-any { + display: inline-block; + padding: 0 5px; + width: 100%; +} +.missing-if-branch { + display: inline-block; + margin-right: 5px; + border-radius: 3px; + position: relative; + padding: 0 4px; + background: #333; + color: yellow; +} + +.skip-if-branch { + display: none; + margin-right: 10px; + position: relative; + padding: 0 4px; + background: #ccc; + color: white; +} +.missing-if-branch .typ, .skip-if-branch .typ { + color: inherit !important; +} +.coverage-summary { + border-collapse: collapse; + width: 100%; +} +.coverage-summary tr { border-bottom: 1px solid #bbb; } +.keyline-all { border: 1px solid #ddd; } +.coverage-summary td, .coverage-summary th { padding: 10px; } +.coverage-summary tbody { border: 1px solid #bbb; } +.coverage-summary td { border-right: 1px solid #bbb; } +.coverage-summary td:last-child { border-right: none; } +.coverage-summary th { + text-align: left; + font-weight: normal; + white-space: nowrap; +} +.coverage-summary th.file { border-right: none !important; } +.coverage-summary th.pct { } +.coverage-summary th.pic, +.coverage-summary th.abs, +.coverage-summary td.pct, +.coverage-summary td.abs { text-align: right; } +.coverage-summary td.file { white-space: nowrap; } +.coverage-summary td.pic { min-width: 120px !important; } +.coverage-summary tfoot td { } + +.coverage-summary .sorter { + height: 10px; + width: 7px; + display: inline-block; + margin-left: 0.5em; + background: url(sort-arrow-sprite.png) no-repeat scroll 0 0 transparent; +} +.coverage-summary .sorted .sorter { + background-position: 0 -20px; +} +.coverage-summary .sorted-desc .sorter { + background-position: 0 -10px; +} +.status-line { height: 10px; } +/* yellow */ +.cbranch-no { background: yellow !important; color: #111; } +/* dark red */ +.red.solid, .status-line.low, .low .cover-fill { background:#C21F39 } +.low .chart { border:1px solid #C21F39 } +.highlighted, +.highlighted .cstat-no, .highlighted .fstat-no, .highlighted .cbranch-no{ + background: #C21F39 !important; +} +/* medium red */ +.cstat-no, .fstat-no, .cbranch-no, .cbranch-no { background:#F6C6CE } +/* light red */ +.low, .cline-no { background:#FCE1E5 } +/* light green */ +.high, .cline-yes { background:rgb(230,245,208) } +/* medium green */ +.cstat-yes { background:rgb(161,215,106) } +/* dark green */ +.status-line.high, .high .cover-fill { background:rgb(77,146,33) } +.high .chart { border:1px solid rgb(77,146,33) } +/* dark yellow (gold) */ +.status-line.medium, .medium .cover-fill { background: #f9cd0b; } +.medium .chart { border:1px solid #f9cd0b; } +/* light yellow */ +.medium { background: #fff4c2; } + +.cstat-skip { background: #ddd; color: #111; } +.fstat-skip { background: #ddd; color: #111 !important; } +.cbranch-skip { background: #ddd !important; color: #111; } + +span.cline-neutral { background: #eaeaea; } + +.coverage-summary td.empty { + opacity: .5; + padding-top: 4px; + padding-bottom: 4px; + line-height: 1; + color: #888; +} + +.cover-fill, .cover-empty { + display:inline-block; + height: 12px; +} +.chart { + line-height: 0; +} +.cover-empty { + background: white; +} +.cover-full { + border-right: none !important; +} +pre.prettyprint { + border: none !important; + padding: 0 !important; + margin: 0 !important; +} +.com { color: #999 !important; } +.ignore-none { color: #999; font-weight: normal; } + +.wrapper { + min-height: 100%; + height: auto !important; + height: 100%; + margin: 0 auto -48px; +} +.footer, .push { + height: 48px; +} diff --git a/client/coverage/block-navigation.js b/client/coverage/block-navigation.js new file mode 100644 index 0000000000..cc12130231 --- /dev/null +++ b/client/coverage/block-navigation.js @@ -0,0 +1,87 @@ +/* eslint-disable */ +var jumpToCode = (function init() { + // Classes of code we would like to highlight in the file view + var missingCoverageClasses = ['.cbranch-no', '.cstat-no', '.fstat-no']; + + // Elements to highlight in the file listing view + var fileListingElements = ['td.pct.low']; + + // We don't want to select elements that are direct descendants of another match + var notSelector = ':not(' + missingCoverageClasses.join('):not(') + ') > '; // becomes `:not(a):not(b) > ` + + // Selecter that finds elements on the page to which we can jump + var selector = + fileListingElements.join(', ') + + ', ' + + notSelector + + missingCoverageClasses.join(', ' + notSelector); // becomes `:not(a):not(b) > a, :not(a):not(b) > b` + + // The NodeList of matching elements + var missingCoverageElements = document.querySelectorAll(selector); + + var currentIndex; + + function toggleClass(index) { + missingCoverageElements + .item(currentIndex) + .classList.remove('highlighted'); + missingCoverageElements.item(index).classList.add('highlighted'); + } + + function makeCurrent(index) { + toggleClass(index); + currentIndex = index; + missingCoverageElements.item(index).scrollIntoView({ + behavior: 'smooth', + block: 'center', + inline: 'center' + }); + } + + function goToPrevious() { + var nextIndex = 0; + if (typeof currentIndex !== 'number' || currentIndex === 0) { + nextIndex = missingCoverageElements.length - 1; + } else if (missingCoverageElements.length > 1) { + nextIndex = currentIndex - 1; + } + + makeCurrent(nextIndex); + } + + function goToNext() { + var nextIndex = 0; + + if ( + typeof currentIndex === 'number' && + currentIndex < missingCoverageElements.length - 1 + ) { + nextIndex = currentIndex + 1; + } + + makeCurrent(nextIndex); + } + + return function jump(event) { + if ( + document.getElementById('fileSearch') === document.activeElement && + document.activeElement != null + ) { + // if we're currently focused on the search input, we don't want to navigate + return; + } + + switch (event.which) { + case 78: // n + case 74: // j + goToNext(); + break; + case 66: // b + case 75: // k + case 80: // p + goToPrevious(); + break; + } + }; +})(); +window.addEventListener('keydown', jumpToCode); diff --git a/client/coverage/client/bin/cli.js.html b/client/coverage/client/bin/cli.js.html new file mode 100644 index 0000000000..29aaeb346e --- /dev/null +++ b/client/coverage/client/bin/cli.js.html @@ -0,0 +1,133 @@ + + + + + + Code coverage report for client/bin/cli.js + + + + + + + + + +
+
+

All files / client/bin cli.js

+
+ +
+ 0% + Statements + 0/16 +
+ + +
+ 0% + Branches + 0/1 +
+ + +
+ 0% + Functions + 0/1 +
+ + +
+ 0% + Lines + 0/16 +
+ + +
+

+ Press n or j to go to the next uncovered block, b, p or k for the previous block. +

+ +
+
+

+
1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 +12 +13 +14 +15 +16 +17  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  + 
#!/usr/bin/env node
+
+import { join, dirname } from "path";
+import { fileURLToPath } from "url";
+import handler from "serve-handler";
+import http from "http";
+
+const __dirname = dirname(fileURLToPath(import.meta.url));
+const distPath = join(__dirname, "../dist");
+
+const server = http.createServer((request, response) => {
+  return handler(request, response, { public: distPath });
+});
+
+const port = process.env.PORT || 5173;
+server.listen(port, () => {});
+ 
+ +
+
+ + + + + + + + \ No newline at end of file diff --git a/client/coverage/client/bin/index.html b/client/coverage/client/bin/index.html new file mode 100644 index 0000000000..a2fea793c9 --- /dev/null +++ b/client/coverage/client/bin/index.html @@ -0,0 +1,116 @@ + + + + + + Code coverage report for client/bin + + + + + + + + + +
+
+

All files client/bin

+
+ +
+ 0% + Statements + 0/16 +
+ + +
+ 0% + Branches + 0/1 +
+ + +
+ 0% + Functions + 0/1 +
+ + +
+ 0% + Lines + 0/16 +
+ + +
+

+ Press n or j to go to the next uncovered block, b, p or k for the previous block. +

+ +
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FileStatementsBranchesFunctionsLines
cli.js +
+
0%0/160%0/10%0/10%0/16
+
+
+
+ + + + + + + + \ No newline at end of file diff --git a/client/coverage/client/index.html b/client/coverage/client/index.html new file mode 100644 index 0000000000..0aa7351392 --- /dev/null +++ b/client/coverage/client/index.html @@ -0,0 +1,131 @@ + + + + + + Code coverage report for client + + + + + + + + + +
+
+

All files client

+
+ +
+ 0% + Statements + 0/64 +
+ + +
+ 0% + Branches + 0/2 +
+ + +
+ 0% + Functions + 0/2 +
+ + +
+ 0% + Lines + 0/64 +
+ + +
+

+ Press n or j to go to the next uncovered block, b, p or k for the previous block. +

+ +
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FileStatementsBranchesFunctionsLines
postcss.config.js +
+
0%0/60%0/10%0/10%0/6
tailwind.config.js +
+
0%0/580%0/10%0/10%0/58
+
+
+
+ + + + + + + + \ No newline at end of file diff --git a/client/coverage/client/postcss.config.js.html b/client/coverage/client/postcss.config.js.html new file mode 100644 index 0000000000..f8bd75cd23 --- /dev/null +++ b/client/coverage/client/postcss.config.js.html @@ -0,0 +1,103 @@ + + + + + + Code coverage report for client/postcss.config.js + + + + + + + + + +
+
+

All files / client postcss.config.js

+
+ +
+ 0% + Statements + 0/6 +
+ + +
+ 0% + Branches + 0/1 +
+ + +
+ 0% + Functions + 0/1 +
+ + +
+ 0% + Lines + 0/6 +
+ + +
+

+ Press n or j to go to the next uncovered block, b, p or k for the previous block. +

+ +
+
+

+
1 +2 +3 +4 +5 +6 +7  +  +  +  +  +  + 
export default {
+  plugins: {
+    tailwindcss: {},
+    autoprefixer: {},
+  },
+};
+ 
+ +
+
+ + + + + + + + \ No newline at end of file diff --git a/client/coverage/client/src/App.tsx.html b/client/coverage/client/src/App.tsx.html new file mode 100644 index 0000000000..af989bc7ba --- /dev/null +++ b/client/coverage/client/src/App.tsx.html @@ -0,0 +1,1693 @@ + + + + + + Code coverage report for client/src/App.tsx + + + + + + + + + +
+
+

All files / client/src App.tsx

+
+ +
+ 60.75% + Statements + 274/451 +
+ + +
+ 89.28% + Branches + 25/28 +
+ + +
+ 6.06% + Functions + 2/33 +
+ + +
+ 60.75% + Lines + 274/451 +
+ + +
+

+ Press n or j to go to the next uncovered block, b, p or k for the previous block. +

+ +
+
+

+
1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 +12 +13 +14 +15 +16 +17 +18 +19 +20 +21 +22 +23 +24 +25 +26 +27 +28 +29 +30 +31 +32 +33 +34 +35 +36 +37 +38 +39 +40 +41 +42 +43 +44 +45 +46 +47 +48 +49 +50 +51 +52 +53 +54 +55 +56 +57 +58 +59 +60 +61 +62 +63 +64 +65 +66 +67 +68 +69 +70 +71 +72 +73 +74 +75 +76 +77 +78 +79 +80 +81 +82 +83 +84 +85 +86 +87 +88 +89 +90 +91 +92 +93 +94 +95 +96 +97 +98 +99 +100 +101 +102 +103 +104 +105 +106 +107 +108 +109 +110 +111 +112 +113 +114 +115 +116 +117 +118 +119 +120 +121 +122 +123 +124 +125 +126 +127 +128 +129 +130 +131 +132 +133 +134 +135 +136 +137 +138 +139 +140 +141 +142 +143 +144 +145 +146 +147 +148 +149 +150 +151 +152 +153 +154 +155 +156 +157 +158 +159 +160 +161 +162 +163 +164 +165 +166 +167 +168 +169 +170 +171 +172 +173 +174 +175 +176 +177 +178 +179 +180 +181 +182 +183 +184 +185 +186 +187 +188 +189 +190 +191 +192 +193 +194 +195 +196 +197 +198 +199 +200 +201 +202 +203 +204 +205 +206 +207 +208 +209 +210 +211 +212 +213 +214 +215 +216 +217 +218 +219 +220 +221 +222 +223 +224 +225 +226 +227 +228 +229 +230 +231 +232 +233 +234 +235 +236 +237 +238 +239 +240 +241 +242 +243 +244 +245 +246 +247 +248 +249 +250 +251 +252 +253 +254 +255 +256 +257 +258 +259 +260 +261 +262 +263 +264 +265 +266 +267 +268 +269 +270 +271 +272 +273 +274 +275 +276 +277 +278 +279 +280 +281 +282 +283 +284 +285 +286 +287 +288 +289 +290 +291 +292 +293 +294 +295 +296 +297 +298 +299 +300 +301 +302 +303 +304 +305 +306 +307 +308 +309 +310 +311 +312 +313 +314 +315 +316 +317 +318 +319 +320 +321 +322 +323 +324 +325 +326 +327 +328 +329 +330 +331 +332 +333 +334 +335 +336 +337 +338 +339 +340 +341 +342 +343 +344 +345 +346 +347 +348 +349 +350 +351 +352 +353 +354 +355 +356 +357 +358 +359 +360 +361 +362 +363 +364 +365 +366 +367 +368 +369 +370 +371 +372 +373 +374 +375 +376 +377 +378 +379 +380 +381 +382 +383 +384 +385 +386 +387 +388 +389 +390 +391 +392 +393 +394 +395 +396 +397 +398 +399 +400 +401 +402 +403 +404 +405 +406 +407 +408 +409 +410 +411 +412 +413 +414 +415 +416 +417 +418 +419 +420 +421 +422 +423 +424 +425 +426 +427 +428 +429 +430 +431 +432 +433 +434 +435 +436 +437 +438 +439 +440 +441 +442 +443 +444 +445 +446 +447 +448 +449 +450 +451 +452 +453 +454 +455 +456 +457 +458 +459 +460 +461 +462 +463 +464 +465 +466 +467 +468 +469 +470 +471 +472 +473 +474 +475 +476 +477 +478 +479 +480 +481 +482 +483 +484 +485 +486 +487 +488 +489 +490 +491 +492 +493 +494 +495 +496 +497 +498 +499 +500 +501 +502 +503 +504 +505 +506 +507 +508 +509 +510 +511 +512 +513 +514 +515 +516 +517 +518 +519 +520 +521 +522 +523 +524 +525 +526 +527 +528 +529 +530 +531 +532 +533 +534 +535 +536 +5371x +1x +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +1x +1x +  +  +  +1x +  +  +  +  +  +  +  +1x +  +  +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +  +1x +1x +1x +  +1x +16x +16x +  +16x +16x +16x +16x +16x +16x +16x +16x +16x +16x +16x +16x +16x +7x +16x +16x +7x +16x +  +16x +16x +16x +16x +  +16x +16x +16x +  +16x +  +  +  +  +  +  +16x +16x +16x +  +16x +  +  +  +  +  +  +  +16x +  +  +  +  +  +  +  +16x +16x +16x +16x +16x +16x +  +16x +16x +  +16x +16x +  +16x +16x +16x +  +16x +16x +16x +16x +  +16x +16x +16x +16x +16x +16x +16x +16x +16x +16x +16x +16x +16x +16x +16x +16x +  +  +16x +  +  +16x +1x +1x +1x +1x +1x +16x +16x +  +16x +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +16x +10x +16x +  +16x +8x +16x +  +16x +7x +7x +7x +7x +7x +7x +7x +7x +7x +7x +7x +7x +  +7x +16x +  +16x +7x +16x +  +16x +7x +7x +7x +16x +  +16x +  +  +  +16x +  +  +  +  +  +  +  +  +  +  +  +  +16x +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +16x +  +  +  +  +  +  +  +  +  +  +  +16x +  +  +  +  +  +  +  +  +  +  +  +  +16x +  +  +  +  +  +  +  +  +  +  +  +16x +  +  +  +  +  +  +  +  +  +  +  +  +16x +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +16x +  +  +  +16x +16x +16x +16x +16x +16x +16x +16x +16x +16x +16x +16x +16x +16x +16x +16x +16x +16x +16x +16x +9x +9x +9x +  +9x +7x +5x +5x +  +9x +9x +  +9x +9x +9x +  +9x +9x +9x +  +9x +9x +9x +  +9x +9x +9x +  +9x +9x +9x +  +9x +1x +1x +1x +  +9x +9x +9x +  +9x +9x +  +9x +9x +5x +5x +  +5x +5x +  +4x +4x +4x +4x +4x +  +  +  +4x +  +  +  +4x +  +  +  +4x +  +  +  +4x +  +  +  +4x +4x +  +  +  +4x +4x +4x +4x +4x +4x +4x +4x +  +  +  +4x +  +  +  +4x +  +  +  +4x +4x +  +  +  +4x +4x +4x +4x +4x +4x +4x +  +  +  +4x +  +  +  +4x +  +  +  +4x +4x +  +  +  +  +4x +4x +4x +4x +4x +4x +4x +  +  +  +  +  +  +  +4x +4x +4x +4x +4x +4x +4x +4x +4x +4x +4x +4x +  +9x +9x +  +7x +7x +  +7x +7x +  +16x +16x +16x +16x +16x +16x +  +16x +16x +16x +  +16x +16x +16x +16x +16x +16x +16x +16x +16x +16x +16x +  +16x +  +1x + 
import { useDraggablePane } from "./lib/hooks/useDraggablePane";
+import { useConnection } from "./lib/hooks/useConnection";
+import {
+  ClientRequest,
+  CompatibilityCallToolResult,
+  CompatibilityCallToolResultSchema,
+  CreateMessageResult,
+  EmptyResultSchema,
+  GetPromptResultSchema,
+  ListPromptsResultSchema,
+  ListResourcesResultSchema,
+  ListResourceTemplatesResultSchema,
+  ReadResourceResultSchema,
+  ListToolsResultSchema,
+  Resource,
+  ResourceTemplate,
+  Root,
+  ServerNotification,
+  Tool
+} from "@modelcontextprotocol/sdk/types.js";
+import { useEffect, useRef, useState } from "react";
+ 
+import { StdErrNotification } from "./lib/notificationTypes";
+ 
+import { Tabs, TabsList, TabsTrigger } from "@/components/ui/tabs";
+import {
+  Bell,
+  Files,
+  FolderTree,
+  Hammer,
+  Hash,
+  MessageSquare,
+} from "lucide-react";
+ 
+import { z } from "zod";
+import "./App.css";
+import ConsoleTab from "./components/ConsoleTab";
+import HistoryAndNotifications from "./components/History";
+import PingTab from "./components/PingTab";
+import PromptsTab, { Prompt } from "./components/PromptsTab";
+import ResourcesTab from "./components/ResourcesTab";
+import RootsTab from "./components/RootsTab";
+import SamplingTab, { PendingRequest } from "./components/SamplingTab";
+import Sidebar from "./components/Sidebar";
+import ToolsTab from "./components/ToolsTab";
+ 
+const params = new URLSearchParams(window.location.search);
+const PROXY_PORT = params.get("proxyPort") ?? "3000";
+const PROXY_SERVER_URL = `http://localhost:${PROXY_PORT}`;
+ 
+const App = () => {
+  const [resources, setResources] = useState<Resource[]>([]);
+  const [resourceTemplates, setResourceTemplates] = useState<
+    ResourceTemplate[]
+  >([]);
+  const [resourceContent, setResourceContent] = useState<string>("");
+  const [prompts, setPrompts] = useState<Prompt[]>([]);
+  const [promptContent, setPromptContent] = useState<string>("");
+  const [tools, setTools] = useState<Tool[]>([]);
+  const [toolResult, setToolResult] =
+    useState<CompatibilityCallToolResult | null>(null);
+  const [errors, setErrors] = useState<Record<string, string | null>>({
+    resources: null,
+    prompts: null,
+    tools: null,
+  });
+  const [command, setCommand] = useState<string>(() => {
+    return localStorage.getItem("lastCommand") || "mcp-server-everything";
+  });
+  const [args, setArgs] = useState<string>(() => {
+    return localStorage.getItem("lastArgs") || "";
+  });
+ 
+  const [sseUrl, setSseUrl] = useState<string>("http://localhost:3001/sse");
+  const [transportType, setTransportType] = useState<"stdio" | "sse">("stdio");
+  const [notifications, setNotifications] = useState<ServerNotification[]>([]);
+  const [stdErrNotifications, setStdErrNotifications] = useState<
+    StdErrNotification[]
+  >([]);
+  const [roots, setRoots] = useState<Root[]>([]);
+  const [env, setEnv] = useState<Record<string, string>>({});
+ 
+  const [pendingSampleRequests, setPendingSampleRequests] = useState<
+    Array<
+      PendingRequest & {
+        resolve: (result: CreateMessageResult) => void;
+        reject: (error: Error) => void;
+      }
+    >
+  >([]);
+  const nextRequestId = useRef(0);
+  const rootsRef = useRef<Root[]>([]);
+ 
+  const handleApproveSampling = (id: number, result: CreateMessageResult) => {
+    setPendingSampleRequests((prev) => {
+      const request = prev.find((r) => r.id === id);
+      request?.resolve(result);
+      return prev.filter((r) => r.id !== id);
+    });
+  };
+ 
+  const handleRejectSampling = (id: number) => {
+    setPendingSampleRequests((prev) => {
+      const request = prev.find((r) => r.id === id);
+      request?.reject(new Error("Sampling request rejected"));
+      return prev.filter((r) => r.id !== id);
+    });
+  };
+ 
+  const [selectedResource, setSelectedResource] = useState<Resource | null>(
+    null,
+  );
+  const [selectedPrompt, setSelectedPrompt] = useState<Prompt | null>(null);
+  const [selectedTool, setSelectedTool] = useState<Tool | null>(null);
+  const [nextResourceCursor, setNextResourceCursor] = useState<
+    string | undefined
+  >();
+  const [nextResourceTemplateCursor, setNextResourceTemplateCursor] = useState<
+    string | undefined
+  >();
+  const [nextPromptCursor, setNextPromptCursor] = useState<
+    string | undefined
+  >();
+  const [nextToolCursor, setNextToolCursor] = useState<string | undefined>();
+  const progressTokenRef = useRef(0);
+ 
+  const {
+    height: historyPaneHeight,
+    handleDragStart
+  } = useDraggablePane(300);
+ 
+  const {
+    connectionStatus,
+    serverCapabilities,
+    mcpClient,
+    requestHistory,
+    makeRequest: makeConnectionRequest,
+    sendNotification,
+    connect: connectMcpServer
+  } = useConnection({
+    transportType,
+    command,
+    args,
+    sseUrl,
+    env,
+    proxyServerUrl: PROXY_SERVER_URL,
+    onNotification: (notification) => {
+      setNotifications(prev => [...prev, notification as ServerNotification]);
+    },
+    onStdErrNotification: (notification) => {
+      setStdErrNotifications(prev => [...prev, notification as StdErrNotification]);
+    },
+    onPendingRequest: (request, resolve, reject) => {
+      setPendingSampleRequests(prev => [
+        ...prev,
+        { id: nextRequestId.current++, request, resolve, reject }
+      ]);
+    },
+    getRoots: () => rootsRef.current
+  });
+ 
+  const makeRequest = async <T extends z.ZodType>(
+    request: ClientRequest,
+    schema: T,
+    tabKey?: keyof typeof errors,
+  ) => {
+    try {
+      const response = await makeConnectionRequest(request, schema);
+      if (tabKey !== undefined) {
+        clearError(tabKey);
+      }
+      return response;
+    } catch (e) {
+      const errorString = (e as Error).message ?? String(e);
+      if (tabKey !== undefined) {
+        setErrors((prev) => ({
+          ...prev,
+          [tabKey]: errorString,
+        }));
+      }
+      throw e;
+    }
+  };
+ 
+  useEffect(() => {
+    localStorage.setItem("lastCommand", command);
+  }, [command]);
+ 
+  useEffect(() => {
+    localStorage.setItem("lastArgs", args);
+  }, [args]);
+ 
+  useEffect(() => {
+    fetch(`${PROXY_SERVER_URL}/config`)
+      .then((response) => response.json())
+      .then((data) => {
+        setEnv(data.defaultEnvironment);
+        if (data.defaultCommand) {
+          setCommand(data.defaultCommand);
+        }
+        if (data.defaultArgs) {
+          setArgs(data.defaultArgs);
+        }
+      })
+      .catch((error) =>
+        console.error("Error fetching default environment:", error),
+      );
+  }, []);
+ 
+  useEffect(() => {
+    rootsRef.current = roots;
+  }, [roots]);
+ 
+  useEffect(() => {
+    if (!window.location.hash) {
+      window.location.hash = "resources";
+    }
+  }, []);
+ 
+  const clearError = (tabKey: keyof typeof errors) => {
+    setErrors((prev) => ({ ...prev, [tabKey]: null }));
+  };
+ 
+  const listResources = async () => {
+    const response = await makeRequest(
+      {
+        method: "resources/list" as const,
+        params: nextResourceCursor ? { cursor: nextResourceCursor } : {},
+      },
+      ListResourcesResultSchema,
+      "resources",
+    );
+    setResources(resources.concat(response.resources ?? []));
+    setNextResourceCursor(response.nextCursor);
+  };
+ 
+  const listResourceTemplates = async () => {
+    const response = await makeRequest(
+      {
+        method: "resources/templates/list" as const,
+        params: nextResourceTemplateCursor
+          ? { cursor: nextResourceTemplateCursor }
+          : {},
+      },
+      ListResourceTemplatesResultSchema,
+      "resources",
+    );
+    setResourceTemplates(
+      resourceTemplates.concat(response.resourceTemplates ?? []),
+    );
+    setNextResourceTemplateCursor(response.nextCursor);
+  };
+ 
+  const readResource = async (uri: string) => {
+    const response = await makeRequest(
+      {
+        method: "resources/read" as const,
+        params: { uri },
+      },
+      ReadResourceResultSchema,
+      "resources",
+    );
+    setResourceContent(JSON.stringify(response, null, 2));
+  };
+ 
+  const listPrompts = async () => {
+    const response = await makeRequest(
+      {
+        method: "prompts/list" as const,
+        params: nextPromptCursor ? { cursor: nextPromptCursor } : {},
+      },
+      ListPromptsResultSchema,
+      "prompts",
+    );
+    setPrompts(response.prompts);
+    setNextPromptCursor(response.nextCursor);
+  };
+ 
+  const getPrompt = async (name: string, args: Record<string, string> = {}) => {
+    const response = await makeRequest(
+      {
+        method: "prompts/get" as const,
+        params: { name, arguments: args },
+      },
+      GetPromptResultSchema,
+      "prompts",
+    );
+    setPromptContent(JSON.stringify(response, null, 2));
+  };
+ 
+  const listTools = async () => {
+    const response = await makeRequest(
+      {
+        method: "tools/list" as const,
+        params: nextToolCursor ? { cursor: nextToolCursor } : {},
+      },
+      ListToolsResultSchema,
+      "tools",
+    );
+    setTools(response.tools);
+    setNextToolCursor(response.nextCursor);
+  };
+ 
+  const callTool = async (name: string, params: Record<string, unknown>) => {
+    const response = await makeRequest(
+      {
+        method: "tools/call" as const,
+        params: {
+          name,
+          arguments: params,
+          _meta: {
+            progressToken: progressTokenRef.current++,
+          },
+        },
+      },
+      CompatibilityCallToolResultSchema,
+      "tools",
+    );
+    setToolResult(response);
+  };
+ 
+  const handleRootsChange = async () => {
+    await sendNotification({ method: "notifications/roots/list_changed" });
+  };
+ 
+  return (
+    <div className="flex h-screen bg-background">
+      <Sidebar
+        connectionStatus={connectionStatus}
+        transportType={transportType}
+        setTransportType={setTransportType}
+        command={command}
+        setCommand={setCommand}
+        args={args}
+        setArgs={setArgs}
+        sseUrl={sseUrl}
+        setSseUrl={setSseUrl}
+        env={env}
+        setEnv={setEnv}
+        onConnect={connectMcpServer}
+        stdErrNotifications={stdErrNotifications}
+      />
+      <div className="flex-1 flex flex-col overflow-hidden">
+        <div className="flex-1 overflow-auto">
+          {mcpClient ? (
+            <Tabs
+              defaultValue={
+                Object.keys(serverCapabilities ?? {}).includes(window.location.hash.slice(1)) ?
+                window.location.hash.slice(1) :
+                serverCapabilities?.resources ? "resources" :
+                serverCapabilities?.prompts ? "prompts" :
+                serverCapabilities?.tools ? "tools" :
+                "ping"
+              }
+              className="w-full p-4"
+              onValueChange={(value) => (window.location.hash = value)}
+            >
+              <TabsList className="mb-4 p-0">
+                <TabsTrigger value="resources" disabled={!serverCapabilities?.resources}>
+                  <Files className="w-4 h-4 mr-2" />
+                  Resources
+                </TabsTrigger>
+                <TabsTrigger value="prompts" disabled={!serverCapabilities?.prompts}>
+                  <MessageSquare className="w-4 h-4 mr-2" />
+                  Prompts
+                </TabsTrigger>
+                <TabsTrigger value="tools" disabled={!serverCapabilities?.tools}>
+                  <Hammer className="w-4 h-4 mr-2" />
+                  Tools
+                </TabsTrigger>
+                <TabsTrigger value="ping">
+                  <Bell className="w-4 h-4 mr-2" />
+                  Ping
+                </TabsTrigger>
+                <TabsTrigger value="sampling" className="relative">
+                  <Hash className="w-4 h-4 mr-2" />
+                  Sampling
+                  {pendingSampleRequests.length > 0 && (
+                    <span className="absolute -top-1 -right-1 bg-red-500 text-white text-xs rounded-full h-4 w-4 flex items-center justify-center">
+                      {pendingSampleRequests.length}
+                    </span>
+                  )}
+                </TabsTrigger>
+                <TabsTrigger value="roots">
+                  <FolderTree className="w-4 h-4 mr-2" />
+                  Roots
+                </TabsTrigger>
+              </TabsList>
+ 
+              <div className="w-full">
+                {!serverCapabilities?.resources && !serverCapabilities?.prompts && !serverCapabilities?.tools ? (
+                  <div className="flex items-center justify-center p-4">
+                    <p className="text-lg text-gray-500">
+                      The connected server does not support any MCP capabilities
+                    </p>
+                  </div>
+                ) : (
+                  <>
+                    <ResourcesTab
+                      resources={resources}
+                      resourceTemplates={resourceTemplates}
+                      listResources={() => {
+                        clearError("resources");
+                        listResources();
+                      }}
+                      clearResources={() => {
+                        setResources([]);
+                        setNextResourceCursor(undefined);
+                      }}
+                      listResourceTemplates={() => {
+                        clearError("resources");
+                        listResourceTemplates();
+                      }}
+                      clearResourceTemplates={() => {
+                        setResourceTemplates([]);
+                        setNextResourceTemplateCursor(undefined);
+                      }}
+                      readResource={(uri) => {
+                        clearError("resources");
+                        readResource(uri);
+                      }}
+                      selectedResource={selectedResource}
+                      setSelectedResource={(resource) => {
+                        clearError("resources");
+                        setSelectedResource(resource);
+                      }}
+                      resourceContent={resourceContent}
+                      nextCursor={nextResourceCursor}
+                      nextTemplateCursor={nextResourceTemplateCursor}
+                      error={errors.resources}
+                    />
+                    <PromptsTab
+                      prompts={prompts}
+                      listPrompts={() => {
+                        clearError("prompts");
+                        listPrompts();
+                      }}
+                      clearPrompts={() => {
+                        setPrompts([]);
+                        setNextPromptCursor(undefined);
+                      }}
+                      getPrompt={(name, args) => {
+                        clearError("prompts");
+                        getPrompt(name, args);
+                      }}
+                      selectedPrompt={selectedPrompt}
+                      setSelectedPrompt={(prompt) => {
+                        clearError("prompts");
+                        setSelectedPrompt(prompt);
+                      }}
+                      promptContent={promptContent}
+                      nextCursor={nextPromptCursor}
+                      error={errors.prompts}
+                    />
+                    <ToolsTab
+                      tools={tools}
+                      listTools={() => {
+                        clearError("tools");
+                        listTools();
+                      }}
+                      clearTools={() => {
+                        setTools([]);
+                        setNextToolCursor(undefined);
+                      }}
+                      callTool={(name, params) => {
+                        clearError("tools");
+                        callTool(name, params);
+                      }}
+                      selectedTool={selectedTool}
+                      setSelectedTool={(tool) => {
+                        clearError("tools");
+                        setSelectedTool(tool);
+                        setToolResult(null);
+                      }}
+                      toolResult={toolResult}
+                      nextCursor={nextToolCursor}
+                      error={errors.tools}
+                    />
+                    <ConsoleTab />
+                    <PingTab
+                      onPingClick={() => {
+                        void makeRequest(
+                          {
+                            method: "ping" as const,
+                          },
+                          EmptyResultSchema,
+                        );
+                      }}
+                    />
+                    <SamplingTab
+                      pendingRequests={pendingSampleRequests}
+                      onApprove={handleApproveSampling}
+                      onReject={handleRejectSampling}
+                    />
+                    <RootsTab
+                      roots={roots}
+                      setRoots={setRoots}
+                      onRootsChange={handleRootsChange}
+                    />
+                  </>
+                )}
+              </div>
+            </Tabs>
+          ) : (
+            <div className="flex items-center justify-center h-full">
+              <p className="text-lg text-gray-500">
+                Connect to an MCP server to start inspecting
+              </p>
+            </div>
+          )}
+        </div>
+        <div
+          className="relative border-t border-border"
+          style={{
+            height: `${historyPaneHeight}px`,
+          }}
+        >
+          <div
+            className="absolute w-full h-4 -top-2 cursor-row-resize flex items-center justify-center hover:bg-accent/50"
+            onMouseDown={handleDragStart}
+          >
+            <div className="w-8 h-1 rounded-full bg-border" />
+          </div>
+          <div className="h-full overflow-auto">
+            <HistoryAndNotifications
+              requestHistory={requestHistory}
+              serverNotifications={notifications}
+            />
+          </div>
+        </div>
+      </div>
+    </div>
+  );
+};
+ 
+export default App;
+ 
+ +
+
+ + + + + + + + \ No newline at end of file diff --git a/client/coverage/client/src/components/ConsoleTab.tsx.html b/client/coverage/client/src/components/ConsoleTab.tsx.html new file mode 100644 index 0000000000..dc98c61d82 --- /dev/null +++ b/client/coverage/client/src/components/ConsoleTab.tsx.html @@ -0,0 +1,121 @@ + + + + + + Code coverage report for client/src/components/ConsoleTab.tsx + + + + + + + + + +
+
+

All files / client/src/components ConsoleTab.tsx

+
+ +
+ 100% + Statements + 8/8 +
+ + +
+ 100% + Branches + 1/1 +
+ + +
+ 100% + Functions + 1/1 +
+ + +
+ 100% + Lines + 8/8 +
+ + +
+

+ Press n or j to go to the next uncovered block, b, p or k for the previous block. +

+ +
+
+

+
1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 +12 +131x +  +1x +4x +4x +4x +  +4x +4x +  +  +1x + 
import { TabsContent } from "@/components/ui/tabs";
+ 
+const ConsoleTab = () => (
+  <TabsContent value="console" className="h-96">
+    <div className="bg-gray-900 text-gray-100 p-4 rounded-lg h-full font-mono text-sm overflow-auto">
+      <div className="opacity-50">Welcome to MCP Client Console</div>
+      {/* Console output would go here */}
+    </div>
+  </TabsContent>
+);
+ 
+export default ConsoleTab;
+ 
+ +
+
+ + + + + + + + \ No newline at end of file diff --git a/client/coverage/client/src/components/History.tsx.html b/client/coverage/client/src/components/History.tsx.html new file mode 100644 index 0000000000..06da80b514 --- /dev/null +++ b/client/coverage/client/src/components/History.tsx.html @@ -0,0 +1,574 @@ + + + + + + Code coverage report for client/src/components/History.tsx + + + + + + + + + +
+
+

All files / client/src/components History.tsx

+
+ +
+ 97.74% + Statements + 130/133 +
+ + +
+ 100% + Branches + 19/19 +
+ + +
+ 55.55% + Functions + 5/9 +
+ + +
+ 97.74% + Lines + 130/133 +
+ + +
+

+ Press n or j to go to the next uncovered block, b, p or k for the previous block. +

+ +
+
+

+
1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 +12 +13 +14 +15 +16 +17 +18 +19 +20 +21 +22 +23 +24 +25 +26 +27 +28 +29 +30 +31 +32 +33 +34 +35 +36 +37 +38 +39 +40 +41 +42 +43 +44 +45 +46 +47 +48 +49 +50 +51 +52 +53 +54 +55 +56 +57 +58 +59 +60 +61 +62 +63 +64 +65 +66 +67 +68 +69 +70 +71 +72 +73 +74 +75 +76 +77 +78 +79 +80 +81 +82 +83 +84 +85 +86 +87 +88 +89 +90 +91 +92 +93 +94 +95 +96 +97 +98 +99 +100 +101 +102 +103 +104 +105 +106 +107 +108 +109 +110 +111 +112 +113 +114 +115 +116 +117 +118 +119 +120 +121 +122 +123 +124 +125 +126 +127 +128 +129 +130 +131 +132 +133 +134 +135 +136 +137 +138 +139 +140 +141 +142 +143 +144 +145 +146 +147 +148 +149 +150 +151 +152 +153 +154 +155 +156 +157 +158 +159 +160 +161 +162 +163 +1641x +1x +1x +  +1x +21x +21x +21x +  +  +21x +21x +  +21x +21x +  +21x +  +21x +1x +1x +  +21x +1x +1x +  +21x +  +  +  +21x +21x +21x +21x +21x +18x +  +3x +3x +3x +3x +3x +6x +6x +6x +  +6x +6x +6x +1x +  +  +6x +6x +6x +6x +6x +6x +1x +5x +6x +6x +6x +1x +1x +1x +1x +  +1x +1x +1x +1x +  +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +  +1x +1x +1x +1x +  +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +  +1x +  +6x +3x +3x +  +21x +21x +21x +21x +19x +  +2x +2x +2x +2x +2x +4x +4x +4x +  +4x +4x +4x +  +4x +4x +4x +4x +4x +4x +4x +1x +1x +1x +  +1x +1x +1x +  +  +1x +  +1x +1x +1x +1x +1x +1x +1x +  +4x +2x +2x +  +21x +21x +  +21x +  +1x + 
import { ServerNotification } from "@modelcontextprotocol/sdk/types.js";
+import { Copy } from "lucide-react";
+import { useState } from "react";
+ 
+const HistoryAndNotifications = ({
+  requestHistory,
+  serverNotifications,
+}: {
+  requestHistory: Array<{ request: string; response?: string }>;
+  serverNotifications: ServerNotification[];
+}) => {
+  const [expandedRequests, setExpandedRequests] = useState<{
+    [key: number]: boolean;
+  }>({});
+  const [expandedNotifications, setExpandedNotifications] = useState<{
+    [key: number]: boolean;
+  }>({});
+ 
+  const toggleRequestExpansion = (index: number) => {
+    setExpandedRequests((prev) => ({ ...prev, [index]: !prev[index] }));
+  };
+ 
+  const toggleNotificationExpansion = (index: number) => {
+    setExpandedNotifications((prev) => ({ ...prev, [index]: !prev[index] }));
+  };
+ 
+  const copyToClipboard = (text: string) => {
+    navigator.clipboard.writeText(text);
+  };
+ 
+  return (
+    <div className="bg-card overflow-hidden flex h-full">
+      <div className="flex-1 overflow-y-auto p-4 border-r">
+        <h2 className="text-lg font-semibold mb-4">History</h2>
+        {requestHistory.length === 0 ? (
+          <p className="text-sm text-gray-500 italic">No history yet</p>
+        ) : (
+          <ul className="space-y-3">
+            {requestHistory
+              .slice()
+              .reverse()
+              .map((request, index) => (
+                <li
+                  key={index}
+                  className="text-sm text-foreground bg-secondary p-2 rounded"
+                >
+                  <div
+                    className="flex justify-between items-center cursor-pointer"
+                    onClick={() =>
+                      toggleRequestExpansion(requestHistory.length - 1 - index)
+                    }
+                  >
+                    <span className="font-mono">
+                      {requestHistory.length - index}.{" "}
+                      {JSON.parse(request.request).method}
+                    </span>
+                    <span>
+                      {expandedRequests[requestHistory.length - 1 - index]
+                        ? "â–¼"
+                        : "â–¶"}
+                    </span>
+                  </div>
+                  {expandedRequests[requestHistory.length - 1 - index] && (
+                    <>
+                      <div className="mt-2">
+                        <div className="flex justify-between items-center mb-1">
+                          <span className="font-semibold text-blue-600">
+                            Request:
+                          </span>
+                          <button
+                            onClick={() => copyToClipboard(request.request)}
+                            className="text-blue-500 hover:text-blue-700"
+                          >
+                            <Copy size={16} />
+                          </button>
+                        </div>
+                        <pre className="whitespace-pre-wrap break-words bg-background p-2 rounded">
+                          {JSON.stringify(JSON.parse(request.request), null, 2)}
+                        </pre>
+                      </div>
+                      {request.response && (
+                        <div className="mt-2">
+                          <div className="flex justify-between items-center mb-1">
+                            <span className="font-semibold text-green-600">
+                              Response:
+                            </span>
+                            <button
+                              onClick={() => copyToClipboard(request.response!)}
+                              className="text-blue-500 hover:text-blue-700"
+                            >
+                              <Copy size={16} />
+                            </button>
+                          </div>
+                          <pre className="whitespace-pre-wrap break-words bg-background p-2 rounded">
+                            {JSON.stringify(
+                              JSON.parse(request.response),
+                              null,
+                              2,
+                            )}
+                          </pre>
+                        </div>
+                      )}
+                    </>
+                  )}
+                </li>
+              ))}
+          </ul>
+        )}
+      </div>
+      <div className="flex-1 overflow-y-auto p-4">
+        <h2 className="text-lg font-semibold mb-4">Server Notifications</h2>
+        {serverNotifications.length === 0 ? (
+          <p className="text-sm text-gray-500 italic">No notifications yet</p>
+        ) : (
+          <ul className="space-y-3">
+            {serverNotifications
+              .slice()
+              .reverse()
+              .map((notification, index) => (
+                <li
+                  key={index}
+                  className="text-sm text-foreground bg-secondary p-2 rounded"
+                >
+                  <div
+                    className="flex justify-between items-center cursor-pointer"
+                    onClick={() => toggleNotificationExpansion(index)}
+                  >
+                    <span className="font-mono">
+                      {serverNotifications.length - index}.{" "}
+                      {notification.method}
+                    </span>
+                    <span>{expandedNotifications[index] ? "â–¼" : "â–¶"}</span>
+                  </div>
+                  {expandedNotifications[index] && (
+                    <div className="mt-2">
+                      <div className="flex justify-between items-center mb-1">
+                        <span className="font-semibold text-purple-600">
+                          Details:
+                        </span>
+                        <button
+                          onClick={() =>
+                            copyToClipboard(JSON.stringify(notification))
+                          }
+                          className="text-blue-500 hover:text-blue-700"
+                        >
+                          <Copy size={16} />
+                        </button>
+                      </div>
+                      <pre className="whitespace-pre-wrap break-words bg-background p-2 rounded">
+                        {JSON.stringify(notification, null, 2)}
+                      </pre>
+                    </div>
+                  )}
+                </li>
+              ))}
+          </ul>
+        )}
+      </div>
+    </div>
+  );
+};
+ 
+export default HistoryAndNotifications;
+ 
+ +
+
+ + + + + + + + \ No newline at end of file diff --git a/client/coverage/client/src/components/ListPane.tsx.html b/client/coverage/client/src/components/ListPane.tsx.html new file mode 100644 index 0000000000..f47cd82261 --- /dev/null +++ b/client/coverage/client/src/components/ListPane.tsx.html @@ -0,0 +1,265 @@ + + + + + + Code coverage report for client/src/components/ListPane.tsx + + + + + + + + + +
+
+

All files / client/src/components ListPane.tsx

+
+ +
+ 100% + Statements + 43/43 +
+ + +
+ 100% + Branches + 3/3 +
+ + +
+ 100% + Functions + 2/2 +
+ + +
+ 100% + Lines + 43/43 +
+ + +
+

+ Press n or j to go to the next uncovered block, b, p or k for the previous block. +

+ +
+
+

+
1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 +12 +13 +14 +15 +16 +17 +18 +19 +20 +21 +22 +23 +24 +25 +26 +27 +28 +29 +30 +31 +32 +33 +34 +35 +36 +37 +38 +39 +40 +41 +42 +43 +44 +45 +46 +47 +48 +49 +50 +51 +52 +53 +54 +55 +56 +57 +58 +59 +60 +611x +  +  +  +  +  +  +  +  +  +  +  +  +1x +44x +44x +44x +44x +44x +44x +44x +44x +44x +44x +44x +44x +44x +44x +44x +44x +44x +44x +44x +  +44x +44x +44x +44x +44x +44x +44x +44x +  +44x +44x +44x +74x +74x +74x +74x +  +74x +74x +44x +44x +44x +44x +  +  +1x + 
import { Button } from "./ui/button";
+ 
+type ListPaneProps<T> = {
+  items: T[];
+  listItems: () => void;
+  clearItems: () => void;
+  setSelectedItem: (item: T) => void;
+  renderItem: (item: T) => React.ReactNode;
+  title: string;
+  buttonText: string;
+  isButtonDisabled?: boolean;
+};
+ 
+const ListPane = <T extends object>({
+  items,
+  listItems,
+  clearItems,
+  setSelectedItem,
+  renderItem,
+  title,
+  buttonText,
+  isButtonDisabled,
+}: ListPaneProps<T>) => (
+  <div className="bg-card rounded-lg shadow">
+    <div className="p-4 border-b border-gray-200 dark:border-gray-700">
+      <h3 className="font-semibold dark:text-white">{title}</h3>
+    </div>
+    <div className="p-4">
+      <Button
+        variant="outline"
+        className="w-full mb-4"
+        onClick={listItems}
+        disabled={isButtonDisabled}
+      >
+        {buttonText}
+      </Button>
+      <Button
+        variant="outline"
+        className="w-full mb-4"
+        onClick={clearItems}
+        disabled={items.length === 0}
+      >
+        Clear
+      </Button>
+      <div className="space-y-2 overflow-y-auto max-h-96">
+        {items.map((item, index) => (
+          <div
+            key={index}
+            className="flex items-center p-2 rounded hover:bg-gray-50 dark:hover:bg-gray-700 cursor-pointer"
+            onClick={() => setSelectedItem(item)}
+          >
+            {renderItem(item)}
+          </div>
+        ))}
+      </div>
+    </div>
+  </div>
+);
+ 
+export default ListPane;
+ 
+ +
+
+ + + + + + + + \ No newline at end of file diff --git a/client/coverage/client/src/components/PingTab.tsx.html b/client/coverage/client/src/components/PingTab.tsx.html new file mode 100644 index 0000000000..018f37b60f --- /dev/null +++ b/client/coverage/client/src/components/PingTab.tsx.html @@ -0,0 +1,148 @@ + + + + + + Code coverage report for client/src/components/PingTab.tsx + + + + + + + + + +
+
+

All files / client/src/components PingTab.tsx

+
+ +
+ 100% + Statements + 16/16 +
+ + +
+ 100% + Branches + 1/1 +
+ + +
+ 100% + Functions + 1/1 +
+ + +
+ 100% + Lines + 16/16 +
+ + +
+

+ Press n or j to go to the next uncovered block, b, p or k for the previous block. +

+ +
+
+

+
1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 +12 +13 +14 +15 +16 +17 +18 +19 +20 +21 +221x +1x +  +1x +9x +9x +9x +9x +9x +9x +  +9x +  +9x +9x +9x +9x +  +9x +  +1x + 
import { TabsContent } from "@/components/ui/tabs";
+import { Button } from "@/components/ui/button";
+ 
+const PingTab = ({ onPingClick }: { onPingClick: () => void }) => {
+  return (
+    <TabsContent value="ping" className="grid grid-cols-2 gap-4">
+      <div className="col-span-2 flex justify-center items-center">
+        <Button
+          onClick={onPingClick}
+          className="bg-gradient-to-r from-purple-500 to-pink-500 hover:from-purple-600 hover:to-pink-600 text-white font-bold py-6 px-12 rounded-full shadow-lg transform transition duration-300 hover:scale-110 focus:outline-none focus:ring-4 focus:ring-purple-300 animate-pulse"
+        >
+          <span className="text-3xl mr-2">🚀</span>
+          MEGA PING
+          <span className="text-3xl ml-2">💥</span>
+        </Button>
+      </div>
+    </TabsContent>
+  );
+};
+ 
+export default PingTab;
+ 
+ +
+
+ + + + + + + + \ No newline at end of file diff --git a/client/coverage/client/src/components/PromptsTab.tsx.html b/client/coverage/client/src/components/PromptsTab.tsx.html new file mode 100644 index 0000000000..8bbe69973c --- /dev/null +++ b/client/coverage/client/src/components/PromptsTab.tsx.html @@ -0,0 +1,508 @@ + + + + + + Code coverage report for client/src/components/PromptsTab.tsx + + + + + + + + + +
+
+

All files / client/src/components PromptsTab.tsx

+
+ +
+ 97.11% + Statements + 101/104 +
+ + +
+ 94.11% + Branches + 16/17 +
+ + +
+ 83.33% + Functions + 5/6 +
+ + +
+ 97.11% + Lines + 101/104 +
+ + +
+

+ Press n or j to go to the next uncovered block, b, p or k for the previous block. +

+ +
+
+

+
1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 +12 +13 +14 +15 +16 +17 +18 +19 +20 +21 +22 +23 +24 +25 +26 +27 +28 +29 +30 +31 +32 +33 +34 +35 +36 +37 +38 +39 +40 +41 +42 +43 +44 +45 +46 +47 +48 +49 +50 +51 +52 +53 +54 +55 +56 +57 +58 +59 +60 +61 +62 +63 +64 +65 +66 +67 +68 +69 +70 +71 +72 +73 +74 +75 +76 +77 +78 +79 +80 +81 +82 +83 +84 +85 +86 +87 +88 +89 +90 +91 +92 +93 +94 +95 +96 +97 +98 +99 +100 +101 +102 +103 +104 +105 +106 +107 +108 +109 +110 +111 +112 +113 +114 +115 +116 +117 +118 +119 +120 +121 +122 +123 +124 +125 +126 +127 +128 +129 +130 +131 +132 +133 +134 +135 +136 +137 +138 +139 +140 +141 +1421x +1x +1x +1x +1x +1x +  +1x +1x +1x +  +  +  +  +  +  +  +  +  +  +  +1x +10x +10x +10x +10x +10x +10x +10x +10x +10x +10x +  +  +  +  +  +  +  +  +  +10x +10x +  +10x +1x +1x +  +10x +1x +1x +1x +1x +  +10x +10x +10x +10x +10x +10x +10x +  +  +  +10x +12x +12x +12x +12x +  +10x +10x +10x +10x +  +10x +10x +10x +10x +10x +10x +10x +10x +1x +1x +1x +1x +1x +9x +4x +4x +4x +4x +4x +  +4x +8x +8x +8x +8x +8x +8x +8x +1x +  +8x +8x +8x +8x +8x +4x +  +8x +  +8x +4x +4x +  +4x +4x +1x +1x +1x +1x +1x +  +4x +  +5x +5x +  +5x +5x +  +10x +10x +10x +  +10x +  +1x + 
import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert";
+import { Button } from "@/components/ui/button";
+import { Input } from "@/components/ui/input";
+import { Label } from "@/components/ui/label";
+import { TabsContent } from "@/components/ui/tabs";
+import { Textarea } from "@/components/ui/textarea";
+import { ListPromptsResult } from "@modelcontextprotocol/sdk/types.js";
+import { AlertCircle } from "lucide-react";
+import { useState } from "react";
+import ListPane from "./ListPane";
+ 
+export type Prompt = {
+  name: string;
+  description?: string;
+  arguments?: {
+    name: string;
+    description?: string;
+    required?: boolean;
+  }[];
+};
+ 
+const PromptsTab = ({
+  prompts,
+  listPrompts,
+  clearPrompts,
+  getPrompt,
+  selectedPrompt,
+  setSelectedPrompt,
+  promptContent,
+  nextCursor,
+  error,
+}: {
+  prompts: Prompt[];
+  listPrompts: () => void;
+  clearPrompts: () => void;
+  getPrompt: (name: string, args: Record<string, string>) => void;
+  selectedPrompt: Prompt | null;
+  setSelectedPrompt: (prompt: Prompt) => void;
+  promptContent: string;
+  nextCursor: ListPromptsResult["nextCursor"];
+  error: string | null;
+}) => {
+  const [promptArgs, setPromptArgs] = useState<Record<string, string>>({});
+ 
+  const handleInputChange = (argName: string, value: string) => {
+    setPromptArgs((prev) => ({ ...prev, [argName]: value }));
+  };
+ 
+  const handleGetPrompt = () => {
+    if (selectedPrompt) {
+      getPrompt(selectedPrompt.name, promptArgs);
+    }
+  };
+ 
+  return (
+    <TabsContent value="prompts" className="grid grid-cols-2 gap-4">
+      <ListPane
+        items={prompts}
+        listItems={listPrompts}
+        clearItems={clearPrompts}
+        setSelectedItem={(prompt) => {
+          setSelectedPrompt(prompt);
+          setPromptArgs({});
+        }}
+        renderItem={(prompt) => (
+          <>
+            <span className="flex-1">{prompt.name}</span>
+            <span className="text-sm text-gray-500">{prompt.description}</span>
+          </>
+        )}
+        title="Prompts"
+        buttonText={nextCursor ? "List More Prompts" : "List Prompts"}
+        isButtonDisabled={!nextCursor && prompts.length > 0}
+      />
+ 
+      <div className="bg-card rounded-lg shadow">
+        <div className="p-4 border-b border-gray-200">
+          <h3 className="font-semibold">
+            {selectedPrompt ? selectedPrompt.name : "Select a prompt"}
+          </h3>
+        </div>
+        <div className="p-4">
+          {error ? (
+            <Alert variant="destructive">
+              <AlertCircle className="h-4 w-4" />
+              <AlertTitle>Error</AlertTitle>
+              <AlertDescription>{error}</AlertDescription>
+            </Alert>
+          ) : selectedPrompt ? (
+            <div className="space-y-4">
+              {selectedPrompt.description && (
+                <p className="text-sm text-gray-600">
+                  {selectedPrompt.description}
+                </p>
+              )}
+              {selectedPrompt.arguments?.map((arg) => (
+                <div key={arg.name}>
+                  <Label htmlFor={arg.name}>{arg.name}</Label>
+                  <Input
+                    id={arg.name}
+                    placeholder={`Enter ${arg.name}`}
+                    value={promptArgs[arg.name] || ""}
+                    onChange={(e) =>
+                      handleInputChange(arg.name, e.target.value)
+                    }
+                  />
+                  {arg.description && (
+                    <p className="text-xs text-gray-500 mt-1">
+                      {arg.description}
+                      {arg.required && (
+                        <span className="text-xs mt-1 ml-1">(Required)</span>
+                      )}
+                    </p>
+                  )}
+                </div>
+              ))}
+              <Button onClick={handleGetPrompt} className="w-full">
+                Get Prompt
+              </Button>
+              {promptContent && (
+                <Textarea
+                  value={promptContent}
+                  readOnly
+                  className="h-64 font-mono"
+                />
+              )}
+            </div>
+          ) : (
+            <Alert>
+              <AlertDescription>
+                Select a prompt from the list to view and use it
+              </AlertDescription>
+            </Alert>
+          )}
+        </div>
+      </div>
+    </TabsContent>
+  );
+};
+ 
+export default PromptsTab;
+ 
+ +
+
+ + + + + + + + \ No newline at end of file diff --git a/client/coverage/client/src/components/ResourcesTab.tsx.html b/client/coverage/client/src/components/ResourcesTab.tsx.html new file mode 100644 index 0000000000..c6d5e5d39c --- /dev/null +++ b/client/coverage/client/src/components/ResourcesTab.tsx.html @@ -0,0 +1,700 @@ + + + + + + Code coverage report for client/src/components/ResourcesTab.tsx + + + + + + + + + +
+
+

All files / client/src/components ResourcesTab.tsx

+
+ +
+ 97.54% + Statements + 159/163 +
+ + +
+ 89.28% + Branches + 25/28 +
+ + +
+ 88.88% + Functions + 8/9 +
+ + +
+ 97.54% + Lines + 159/163 +
+ + +
+

+ Press n or j to go to the next uncovered block, b, p or k for the previous block. +

+ +
+
+

+
1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 +12 +13 +14 +15 +16 +17 +18 +19 +20 +21 +22 +23 +24 +25 +26 +27 +28 +29 +30 +31 +32 +33 +34 +35 +36 +37 +38 +39 +40 +41 +42 +43 +44 +45 +46 +47 +48 +49 +50 +51 +52 +53 +54 +55 +56 +57 +58 +59 +60 +61 +62 +63 +64 +65 +66 +67 +68 +69 +70 +71 +72 +73 +74 +75 +76 +77 +78 +79 +80 +81 +82 +83 +84 +85 +86 +87 +88 +89 +90 +91 +92 +93 +94 +95 +96 +97 +98 +99 +100 +101 +102 +103 +104 +105 +106 +107 +108 +109 +110 +111 +112 +113 +114 +115 +116 +117 +118 +119 +120 +121 +122 +123 +124 +125 +126 +127 +128 +129 +130 +131 +132 +133 +134 +135 +136 +137 +138 +139 +140 +141 +142 +143 +144 +145 +146 +147 +148 +149 +150 +151 +152 +153 +154 +155 +156 +157 +158 +159 +160 +161 +162 +163 +164 +165 +166 +167 +168 +169 +170 +171 +172 +173 +174 +175 +176 +177 +178 +179 +180 +181 +182 +183 +184 +185 +186 +187 +188 +189 +190 +191 +192 +193 +194 +195 +196 +197 +198 +199 +200 +201 +202 +203 +204 +205 +2061x +1x +1x +1x +  +  +  +  +  +  +1x +1x +1x +  +1x +16x +16x +16x +16x +16x +16x +16x +16x +16x +16x +16x +16x +16x +16x +  +  +  +  +  +  +  +  +  +  +  +  +  +16x +16x +16x +16x +16x +16x +  +16x +1x +1x +1x +1x +1x +1x +1x +1x +  +16x +1x +1x +1x +1x +  +1x +1x +1x +  +16x +16x +16x +16x +16x +16x +16x +  +  +  +  +16x +24x +24x +24x +24x +24x +24x +24x +  +16x +16x +16x +16x +  +16x +16x +16x +16x +16x +2x +2x +2x +2x +16x +24x +24x +24x +24x +24x +24x +24x +  +16x +16x +16x +  +16x +16x +  +16x +16x +16x +16x +16x +  +16x +2x +14x +4x +10x +16x +16x +2x +2x +2x +2x +  +2x +  +2x +  +16x +16x +16x +1x +1x +1x +1x +1x +15x +2x +2x +2x +13x +4x +4x +4x +4x +4x +4x +4x +8x +8x +8x +8x +8x +8x +  +8x +8x +8x +8x +8x +8x +2x +2x +2x +2x +  +8x +8x +8x +  +4x +4x +4x +4x +4x +  +4x +4x +  +9x +9x +  +9x +9x +  +16x +16x +16x +  +16x +  +1x + 
import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert";
+import { Button } from "@/components/ui/button";
+import { Input } from "@/components/ui/input";
+import { TabsContent } from "@/components/ui/tabs";
+import {
+  ListResourcesResult,
+  Resource,
+  ResourceTemplate,
+  ListResourceTemplatesResult,
+} from "@modelcontextprotocol/sdk/types.js";
+import { AlertCircle, ChevronRight, FileText, RefreshCw } from "lucide-react";
+import ListPane from "./ListPane";
+import { useState } from "react";
+ 
+const ResourcesTab = ({
+  resources,
+  resourceTemplates,
+  listResources,
+  clearResources,
+  listResourceTemplates,
+  clearResourceTemplates,
+  readResource,
+  selectedResource,
+  setSelectedResource,
+  resourceContent,
+  nextCursor,
+  nextTemplateCursor,
+  error,
+}: {
+  resources: Resource[];
+  resourceTemplates: ResourceTemplate[];
+  listResources: () => void;
+  clearResources: () => void;
+  listResourceTemplates: () => void;
+  clearResourceTemplates: () => void;
+  readResource: (uri: string) => void;
+  selectedResource: Resource | null;
+  setSelectedResource: (resource: Resource | null) => void;
+  resourceContent: string;
+  nextCursor: ListResourcesResult["nextCursor"];
+  nextTemplateCursor: ListResourceTemplatesResult["nextCursor"];
+  error: string | null;
+}) => {
+  const [selectedTemplate, setSelectedTemplate] =
+    useState<ResourceTemplate | null>(null);
+  const [templateValues, setTemplateValues] = useState<Record<string, string>>(
+    {},
+  );
+ 
+  const fillTemplate = (
+    template: string,
+    values: Record<string, string>,
+  ): string => {
+    return template.replace(
+      /{([^}]+)}/g,
+      (_, key) => values[key] || `{${key}}`,
+    );
+  };
+ 
+  const handleReadTemplateResource = () => {
+    if (selectedTemplate) {
+      const uri = fillTemplate(selectedTemplate.uriTemplate, templateValues);
+      readResource(uri);
+      setSelectedTemplate(null);
+      // We don't have the full Resource object here, so we create a partial one
+      setSelectedResource({ uri, name: uri } as Resource);
+    }
+  };
+ 
+  return (
+    <TabsContent value="resources" className="grid grid-cols-3 gap-4">
+      <ListPane
+        items={resources}
+        listItems={listResources}
+        clearItems={clearResources}
+        setSelectedItem={(resource) => {
+          setSelectedResource(resource);
+          readResource(resource.uri);
+          setSelectedTemplate(null);
+        }}
+        renderItem={(resource) => (
+          <div className="flex items-center w-full">
+            <FileText className="w-4 h-4 mr-2 flex-shrink-0 text-gray-500" />
+            <span className="flex-1 truncate" title={resource.uri.toString()}>
+              {resource.name}
+            </span>
+            <ChevronRight className="w-4 h-4 flex-shrink-0 text-gray-400" />
+          </div>
+        )}
+        title="Resources"
+        buttonText={nextCursor ? "List More Resources" : "List Resources"}
+        isButtonDisabled={!nextCursor && resources.length > 0}
+      />
+ 
+      <ListPane
+        items={resourceTemplates}
+        listItems={listResourceTemplates}
+        clearItems={clearResourceTemplates}
+        setSelectedItem={(template) => {
+          setSelectedTemplate(template);
+          setSelectedResource(null);
+          setTemplateValues({});
+        }}
+        renderItem={(template) => (
+          <div className="flex items-center w-full">
+            <FileText className="w-4 h-4 mr-2 flex-shrink-0 text-gray-500" />
+            <span className="flex-1 truncate" title={template.uriTemplate}>
+              {template.name}
+            </span>
+            <ChevronRight className="w-4 h-4 flex-shrink-0 text-gray-400" />
+          </div>
+        )}
+        title="Resource Templates"
+        buttonText={
+          nextTemplateCursor ? "List More Templates" : "List Templates"
+        }
+        isButtonDisabled={!nextTemplateCursor && resourceTemplates.length > 0}
+      />
+ 
+      <div className="bg-card rounded-lg shadow">
+        <div className="p-4 border-b border-gray-200 flex justify-between items-center">
+          <h3
+            className="font-semibold truncate"
+            title={selectedResource?.name || selectedTemplate?.name}
+          >
+            {selectedResource
+              ? selectedResource.name
+              : selectedTemplate
+                ? selectedTemplate.name
+                : "Select a resource or template"}
+          </h3>
+          {selectedResource && (
+            <Button
+              variant="outline"
+              size="sm"
+              onClick={() => readResource(selectedResource.uri)}
+            >
+              <RefreshCw className="w-4 h-4 mr-2" />
+              Refresh
+            </Button>
+          )}
+        </div>
+        <div className="p-4">
+          {error ? (
+            <Alert variant="destructive">
+              <AlertCircle className="h-4 w-4" />
+              <AlertTitle>Error</AlertTitle>
+              <AlertDescription>{error}</AlertDescription>
+            </Alert>
+          ) : selectedResource ? (
+            <pre className="bg-gray-50 dark:bg-gray-800 p-4 rounded text-sm overflow-auto max-h-96 whitespace-pre-wrap break-words text-gray-900 dark:text-gray-100">
+              {resourceContent}
+            </pre>
+          ) : selectedTemplate ? (
+            <div className="space-y-4">
+              <p className="text-sm text-gray-600">
+                {selectedTemplate.description}
+              </p>
+              {selectedTemplate.uriTemplate
+                .match(/{([^}]+)}/g)
+                ?.map((param) => {
+                  const key = param.slice(1, -1);
+                  return (
+                    <div key={key}>
+                      <label
+                        htmlFor={key}
+                        className="block text-sm font-medium text-gray-700"
+                      >
+                        {key}
+                      </label>
+                      <Input
+                        id={key}
+                        value={templateValues[key] || ""}
+                        onChange={(e) =>
+                          setTemplateValues({
+                            ...templateValues,
+                            [key]: e.target.value,
+                          })
+                        }
+                        className="mt-1"
+                      />
+                    </div>
+                  );
+                })}
+              <Button
+                onClick={handleReadTemplateResource}
+                disabled={Object.keys(templateValues).length === 0}
+              >
+                Read Resource
+              </Button>
+            </div>
+          ) : (
+            <Alert>
+              <AlertDescription>
+                Select a resource or template from the list to view its contents
+              </AlertDescription>
+            </Alert>
+          )}
+        </div>
+      </div>
+    </TabsContent>
+  );
+};
+ 
+export default ResourcesTab;
+ 
+ +
+
+ + + + + + + + \ No newline at end of file diff --git a/client/coverage/client/src/components/RootsTab.tsx.html b/client/coverage/client/src/components/RootsTab.tsx.html new file mode 100644 index 0000000000..eefc3656d7 --- /dev/null +++ b/client/coverage/client/src/components/RootsTab.tsx.html @@ -0,0 +1,319 @@ + + + + + + Code coverage report for client/src/components/RootsTab.tsx + + + + + + + + + +
+
+

All files / client/src/components RootsTab.tsx

+
+ +
+ 100% + Statements + 61/61 +
+ + +
+ 100% + Branches + 15/15 +
+ + +
+ 100% + Functions + 7/7 +
+ + +
+ 100% + Lines + 61/61 +
+ + +
+

+ Press n or j to go to the next uncovered block, b, p or k for the previous block. +

+ +
+
+

+
1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 +12 +13 +14 +15 +16 +17 +18 +19 +20 +21 +22 +23 +24 +25 +26 +27 +28 +29 +30 +31 +32 +33 +34 +35 +36 +37 +38 +39 +40 +41 +42 +43 +44 +45 +46 +47 +48 +49 +50 +51 +52 +53 +54 +55 +56 +57 +58 +59 +60 +61 +62 +63 +64 +65 +66 +67 +68 +69 +70 +71 +72 +73 +74 +75 +76 +77 +78 +791x +1x +1x +1x +  +1x +  +1x +9x +9x +9x +9x +  +  +  +9x +9x +1x +1x +  +9x +1x +1x +  +9x +1x +1x +2x +1x +1x +1x +  +9x +1x +1x +  +9x +9x +9x +9x +  +9x +9x +  +9x +10x +10x +10x +10x +10x +10x +10x +10x +10x +10x +10x +10x +  +10x +10x +10x +9x +  +9x +9x +9x +  +9x +9x +9x +  +9x +9x +9x +  +9x +  +1x + 
import { Alert, AlertDescription } from "@/components/ui/alert";
+import { Button } from "@/components/ui/button";
+import { Input } from "@/components/ui/input";
+import { TabsContent } from "@/components/ui/tabs";
+import { Root } from "@modelcontextprotocol/sdk/types.js";
+import { Plus, Minus, Save } from "lucide-react";
+ 
+const RootsTab = ({
+  roots,
+  setRoots,
+  onRootsChange,
+}: {
+  roots: Root[];
+  setRoots: React.Dispatch<React.SetStateAction<Root[]>>;
+  onRootsChange: () => void;
+}) => {
+  const addRoot = () => {
+    setRoots((currentRoots) => [...currentRoots, { uri: "file://", name: "" }]);
+  };
+ 
+  const removeRoot = (index: number) => {
+    setRoots((currentRoots) => currentRoots.filter((_, i) => i !== index));
+  };
+ 
+  const updateRoot = (index: number, field: keyof Root, value: string) => {
+    setRoots((currentRoots) =>
+      currentRoots.map((root, i) =>
+        i === index ? { ...root, [field]: value } : root,
+      ),
+    );
+  };
+ 
+  const handleSave = () => {
+    onRootsChange();
+  };
+ 
+  return (
+    <TabsContent value="roots" className="space-y-4">
+      <Alert>
+        <AlertDescription>
+          Configure the root directories that the server can access
+        </AlertDescription>
+      </Alert>
+ 
+      {roots.map((root, index) => (
+        <div key={index} className="flex gap-2 items-center">
+          <Input
+            placeholder="file:// URI"
+            value={root.uri}
+            onChange={(e) => updateRoot(index, "uri", e.target.value)}
+            className="flex-1"
+          />
+          <Button
+            variant="destructive"
+            size="sm"
+            onClick={() => removeRoot(index)}
+            aria-label="Remove root"
+          >
+            <Minus className="h-4 w-4" />
+          </Button>
+        </div>
+      ))}
+ 
+      <div className="flex gap-2">
+        <Button variant="outline" onClick={addRoot}>
+          <Plus className="h-4 w-4 mr-2" />
+          Add Root
+        </Button>
+        <Button onClick={handleSave}>
+          <Save className="h-4 w-4 mr-2" />
+          Save Changes
+        </Button>
+      </div>
+    </TabsContent>
+  );
+};
+ 
+export default RootsTab;
+ 
+ +
+
+ + + + + + + + \ No newline at end of file diff --git a/client/coverage/client/src/components/SamplingTab.tsx.html b/client/coverage/client/src/components/SamplingTab.tsx.html new file mode 100644 index 0000000000..6750d9a9f7 --- /dev/null +++ b/client/coverage/client/src/components/SamplingTab.tsx.html @@ -0,0 +1,280 @@ + + + + + + Code coverage report for client/src/components/SamplingTab.tsx + + + + + + + + + +
+
+

All files / client/src/components SamplingTab.tsx

+
+ +
+ 100% + Statements + 41/41 +
+ + +
+ 100% + Branches + 6/6 +
+ + +
+ 100% + Functions + 4/4 +
+ + +
+ 100% + Lines + 41/41 +
+ + +
+

+ Press n or j to go to the next uncovered block, b, p or k for the previous block. +

+ +
+
+

+
1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 +12 +13 +14 +15 +16 +17 +18 +19 +20 +21 +22 +23 +24 +25 +26 +27 +28 +29 +30 +31 +32 +33 +34 +35 +36 +37 +38 +39 +40 +41 +42 +43 +44 +45 +46 +47 +48 +49 +50 +51 +52 +53 +54 +55 +56 +57 +58 +59 +60 +61 +62 +63 +64 +65 +661x +1x +1x +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +1x +10x +  +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +  +10x +10x +10x +10x +  +  +10x +10x +10x +10x +10x +10x +10x +10x +10x +10x +10x +10x +  +10x +10x +10x +10x +10x +5x +  +10x +10x +  +10x +  +1x + 
import { Alert, AlertDescription } from "@/components/ui/alert";
+import { Button } from "@/components/ui/button";
+import { TabsContent } from "@/components/ui/tabs";
+import {
+  CreateMessageRequest,
+  CreateMessageResult,
+} from "@modelcontextprotocol/sdk/types.js";
+ 
+export type PendingRequest = {
+  id: number;
+  request: CreateMessageRequest;
+};
+ 
+export type Props = {
+  pendingRequests: PendingRequest[];
+  onApprove: (id: number, result: CreateMessageResult) => void;
+  onReject: (id: number) => void;
+};
+ 
+const SamplingTab = ({ pendingRequests, onApprove, onReject }: Props) => {
+  const handleApprove = (id: number) => {
+    // For now, just return a stub response
+    onApprove(id, {
+      model: "stub-model",
+      stopReason: "endTurn",
+      role: "assistant",
+      content: {
+        type: "text",
+        text: "This is a stub response.",
+      },
+    });
+  };
+ 
+  return (
+    <TabsContent value="sampling" className="h-96">
+      <Alert>
+        <AlertDescription>
+          When the server requests LLM sampling, requests will appear here for
+          approval.
+        </AlertDescription>
+      </Alert>
+      <div className="mt-4 space-y-4">
+        <h3 className="text-lg font-semibold">Recent Requests</h3>
+        {pendingRequests.map((request) => (
+          <div key={request.id} className="p-4 border rounded-lg space-y-4">
+            <pre className="bg-gray-50 p-2 rounded">
+              {JSON.stringify(request.request, null, 2)}
+            </pre>
+            <div className="flex space-x-2">
+              <Button onClick={() => handleApprove(request.id)}>Approve</Button>
+              <Button variant="outline" onClick={() => onReject(request.id)}>
+                Reject
+              </Button>
+            </div>
+          </div>
+        ))}
+        {pendingRequests.length === 0 && (
+          <p className="text-gray-500">No pending requests</p>
+        )}
+      </div>
+    </TabsContent>
+  );
+};
+ 
+export default SamplingTab;
+ 
+ +
+
+ + + + + + + + \ No newline at end of file diff --git a/client/coverage/client/src/components/Sidebar.tsx.html b/client/coverage/client/src/components/Sidebar.tsx.html new file mode 100644 index 0000000000..870bebb5f9 --- /dev/null +++ b/client/coverage/client/src/components/Sidebar.tsx.html @@ -0,0 +1,889 @@ + + + + + + Code coverage report for client/src/components/Sidebar.tsx + + + + + + + + + +
+
+

All files / client/src/components Sidebar.tsx

+
+ +
+ 65.43% + Statements + 142/217 +
+ + +
+ 50% + Branches + 6/12 +
+ + +
+ 25% + Functions + 2/8 +
+ + +
+ 65.43% + Lines + 142/217 +
+ + +
+

+ Press n or j to go to the next uncovered block, b, p or k for the previous block. +

+ +
+
+

+
1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 +12 +13 +14 +15 +16 +17 +18 +19 +20 +21 +22 +23 +24 +25 +26 +27 +28 +29 +30 +31 +32 +33 +34 +35 +36 +37 +38 +39 +40 +41 +42 +43 +44 +45 +46 +47 +48 +49 +50 +51 +52 +53 +54 +55 +56 +57 +58 +59 +60 +61 +62 +63 +64 +65 +66 +67 +68 +69 +70 +71 +72 +73 +74 +75 +76 +77 +78 +79 +80 +81 +82 +83 +84 +85 +86 +87 +88 +89 +90 +91 +92 +93 +94 +95 +96 +97 +98 +99 +100 +101 +102 +103 +104 +105 +106 +107 +108 +109 +110 +111 +112 +113 +114 +115 +116 +117 +118 +119 +120 +121 +122 +123 +124 +125 +126 +127 +128 +129 +130 +131 +132 +133 +134 +135 +136 +137 +138 +139 +140 +141 +142 +143 +144 +145 +146 +147 +148 +149 +150 +151 +152 +153 +154 +155 +156 +157 +158 +159 +160 +161 +162 +163 +164 +165 +166 +167 +168 +169 +170 +171 +172 +173 +174 +175 +176 +177 +178 +179 +180 +181 +182 +183 +184 +185 +186 +187 +188 +189 +190 +191 +192 +193 +194 +195 +196 +197 +198 +199 +200 +201 +202 +203 +204 +205 +206 +207 +208 +209 +210 +211 +212 +213 +214 +215 +216 +217 +218 +219 +220 +221 +222 +223 +224 +225 +226 +227 +228 +229 +230 +231 +232 +233 +234 +235 +236 +237 +238 +239 +240 +241 +242 +243 +244 +245 +246 +247 +248 +249 +250 +251 +252 +253 +254 +255 +256 +257 +258 +259 +260 +261 +262 +263 +264 +265 +266 +267 +268 +2691x +1x +1x +1x +  +  +  +  +  +  +1x +  +  +1x +1x +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +1x +16x +16x +16x +16x +16x +16x +16x +16x +16x +16x +16x +16x +16x +16x +16x +16x +  +16x +16x +16x +16x +16x +16x +16x +16x +16x +  +16x +16x +16x +16x +16x +16x +16x +  +  +  +16x +16x +16x +16x +16x +16x +16x +16x +16x +  +16x +16x +16x +16x +16x +16x +16x +16x +16x +16x +16x +16x +16x +16x +16x +16x +16x +16x +16x +16x +16x +  +  +  +  +  +  +  +  +  +  +  +16x +16x +16x +16x +16x +16x +  +16x +  +  +16x +16x +  +16x +16x +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +16x +  +  +16x +16x +16x +  +16x +  +16x +16x +16x +16x +9x +7x +  +7x +16x +16x +16x +16x +9x +7x +  +7x +16x +16x +16x +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +16x +16x +16x +16x +16x +16x +16x +16x +  +  +  +16x +16x +16x +16x +16x +16x +16x +16x +16x +  +16x +16x +16x +16x +16x +16x +16x +16x +16x +16x +16x +16x +16x +16x +16x +16x +16x +16x +16x +16x +  +16x +  +1x + 
import { useState } from "react";
+import { Play, ChevronDown, ChevronRight, CircleHelp, Bug, Github } from "lucide-react";
+import { Button } from "@/components/ui/button";
+import { Input } from "@/components/ui/input";
+import {
+  Select,
+  SelectContent,
+  SelectItem,
+  SelectTrigger,
+  SelectValue,
+} from "@/components/ui/select";
+import { StdErrNotification } from "@/lib/notificationTypes";
+ 
+import useTheme from "../lib/useTheme";
+import { version } from "../../../package.json";
+ 
+interface SidebarProps {
+  connectionStatus: "disconnected" | "connected" | "error";
+  transportType: "stdio" | "sse";
+  setTransportType: (type: "stdio" | "sse") => void;
+  command: string;
+  setCommand: (command: string) => void;
+  args: string;
+  setArgs: (args: string) => void;
+  sseUrl: string;
+  setSseUrl: (url: string) => void;
+  env: Record<string, string>;
+  setEnv: (env: Record<string, string>) => void;
+  onConnect: () => void;
+  stdErrNotifications: StdErrNotification[];
+}
+ 
+const Sidebar = ({
+  connectionStatus,
+  transportType,
+  setTransportType,
+  command,
+  setCommand,
+  args,
+  setArgs,
+  sseUrl,
+  setSseUrl,
+  env,
+  setEnv,
+  onConnect,
+  stdErrNotifications,
+}: SidebarProps) => {
+  const [theme, setTheme] = useTheme();
+  const [showEnvVars, setShowEnvVars] = useState(false);
+ 
+  return (
+    <div className="w-80 bg-card border-r border-border flex flex-col h-full">
+      <div className="flex items-center justify-between p-4 border-b border-gray-200">
+        <div className="flex items-center">
+          <h1 className="ml-2 text-lg font-semibold">
+            MCP Inspector v{version}
+          </h1>
+        </div>
+      </div>
+ 
+      <div className="p-4 flex-1 overflow-auto">
+        <div className="space-y-4">
+          <div className="space-y-2">
+            <label className="text-sm font-medium">Transport Type</label>
+            <Select
+              value={transportType}
+              onValueChange={(value: "stdio" | "sse") =>
+                setTransportType(value)
+              }
+            >
+              <SelectTrigger>
+                <SelectValue placeholder="Select transport type" />
+              </SelectTrigger>
+              <SelectContent>
+                <SelectItem value="stdio">STDIO</SelectItem>
+                <SelectItem value="sse">SSE</SelectItem>
+              </SelectContent>
+            </Select>
+          </div>
+ 
+          {transportType === "stdio" ? (
+            <>
+              <div className="space-y-2">
+                <label className="text-sm font-medium">Command</label>
+                <Input
+                  placeholder="Command"
+                  value={command}
+                  onChange={(e) => setCommand(e.target.value)}
+                  className="font-mono"
+                />
+              </div>
+              <div className="space-y-2">
+                <label className="text-sm font-medium">Arguments</label>
+                <Input
+                  placeholder="Arguments (space-separated)"
+                  value={args}
+                  onChange={(e) => setArgs(e.target.value)}
+                  className="font-mono"
+                />
+              </div>
+            </>
+          ) : (
+            <div className="space-y-2">
+              <label className="text-sm font-medium">URL</label>
+              <Input
+                placeholder="URL"
+                value={sseUrl}
+                onChange={(e) => setSseUrl(e.target.value)}
+                className="font-mono"
+              />
+            </div>
+          )}
+          {transportType === "stdio" && (
+            <div className="space-y-2">
+              <Button
+                variant="outline"
+                onClick={() => setShowEnvVars(!showEnvVars)}
+                className="flex items-center w-full"
+              >
+                {showEnvVars ? (
+                  <ChevronDown className="w-4 h-4 mr-2" />
+                ) : (
+                  <ChevronRight className="w-4 h-4 mr-2" />
+                )}
+                Environment Variables
+              </Button>
+              {showEnvVars && (
+                <div className="space-y-2">
+                  {Object.entries(env).map(([key, value], idx) => (
+                    <div key={idx} className="grid grid-cols-[1fr,auto] gap-2">
+                      <div className="space-y-1">
+                        <Input
+                          placeholder="Key"
+                          value={key}
+                          onChange={(e) => {
+                            const newEnv = { ...env };
+                            delete newEnv[key];
+                            newEnv[e.target.value] = value;
+                            setEnv(newEnv);
+                          }}
+                          className="font-mono"
+                        />
+                        <Input
+                          placeholder="Value"
+                          value={value}
+                          onChange={(e) => {
+                            const newEnv = { ...env };
+                            newEnv[key] = e.target.value;
+                            setEnv(newEnv);
+                          }}
+                          className="font-mono"
+                        />
+                      </div>
+                      <Button
+                        variant="destructive"
+                        onClick={() => {
+                          // eslint-disable-next-line @typescript-eslint/no-unused-vars
+                          const { [key]: removed, ...rest } = env;
+                          setEnv(rest);
+                        }}
+                      >
+                        Remove
+                      </Button>
+                    </div>
+                  ))}
+                  <Button
+                    variant="outline"
+                    onClick={() => {
+                      const newEnv = { ...env };
+                      newEnv[""] = "";
+                      setEnv(newEnv);
+                    }}
+                  >
+                    Add Environment Variable
+                  </Button>
+                </div>
+              )}
+            </div>
+          )}
+ 
+          <div className="space-y-2">
+            <Button className="w-full" onClick={onConnect}>
+              <Play className="w-4 h-4 mr-2" />
+              Connect
+            </Button>
+ 
+            <div className="flex items-center justify-center space-x-2 mb-4">
+              <div
+                className={`w-2 h-2 rounded-full ${
+                  connectionStatus === "connected"
+                    ? "bg-green-500"
+                    : connectionStatus === "error"
+                      ? "bg-red-500"
+                      : "bg-gray-500"
+                }`}
+              />
+              <span className="text-sm text-gray-600">
+                {connectionStatus === "connected"
+                  ? "Connected"
+                  : connectionStatus === "error"
+                    ? "Connection Error"
+                    : "Disconnected"}
+              </span>
+            </div>
+            {stdErrNotifications.length > 0 && (
+              <>
+                <div className="mt-4 border-t border-gray-200 pt-4">
+                  <h3 className="text-sm font-medium">
+                    Error output from MCP server
+                  </h3>
+                  <div className="mt-2 max-h-80 overflow-y-auto">
+                    {stdErrNotifications.map((notification, index) => (
+                      <div
+                        key={index}
+                        className="text-sm text-red-500 font-mono py-2 border-b border-gray-200 last:border-b-0"
+                      >
+                        {notification.params.content}
+                      </div>
+                    ))}
+                  </div>
+                </div>
+              </>
+            )}
+          </div>
+        </div>
+      </div>
+      <div className="p-4 border-t">
+        <div className="flex items-center justify-between">
+          <Select
+            value={theme}
+            onValueChange={(value: string) =>
+              setTheme(value as "system" | "light" | "dark")
+            }
+          >
+            <SelectTrigger className="w-[100px]" id="theme-select">
+              <SelectValue />
+            </SelectTrigger>
+            <SelectContent>
+              <SelectItem value="system">System</SelectItem>
+              <SelectItem value="light">Light</SelectItem>
+              <SelectItem value="dark">Dark</SelectItem>
+            </SelectContent>
+          </Select>
+ 
+          <div className="flex items-center space-x-2">
+            <a href="https://modelcontextprotocol.io/docs/tools/inspector" target="_blank" rel="noopener noreferrer">
+              <Button variant="ghost" title="Inspector Documentation">
+                <CircleHelp className="w-4 h-4 text-gray-800" />
+              </Button>
+            </a>
+            <a href="https://modelcontextprotocol.io/docs/tools/debugging" target="_blank" rel="noopener noreferrer">
+              <Button variant="ghost" title="Debugging Guide">
+                <Bug className="w-4 h-4 text-gray-800" />
+              </Button>
+            </a>
+            <a href="https://github.com/modelcontextprotocol/inspector" target="_blank" rel="noopener noreferrer">
+              <Button variant="ghost" title="Report bugs or contribute on GitHub">
+                <Github className="w-4 h-4 text-gray-800" />
+              </Button>
+            </a>
+          </div>
+        </div>
+      </div>
+    </div>
+  );
+};
+ 
+export default Sidebar;
+ 
+ +
+
+ + + + + + + + \ No newline at end of file diff --git a/client/coverage/client/src/components/ToolsTab.tsx.html b/client/coverage/client/src/components/ToolsTab.tsx.html new file mode 100644 index 0000000000..e61a5e4468 --- /dev/null +++ b/client/coverage/client/src/components/ToolsTab.tsx.html @@ -0,0 +1,823 @@ + + + + + + Code coverage report for client/src/components/ToolsTab.tsx + + + + + + + + + +
+
+

All files / client/src/components ToolsTab.tsx

+
+ +
+ 29.38% + Statements + 57/194 +
+ + +
+ 33.33% + Branches + 2/6 +
+ + +
+ 20% + Functions + 1/5 +
+ + +
+ 29.38% + Lines + 57/194 +
+ + +
+

+ Press n or j to go to the next uncovered block, b, p or k for the previous block. +

+ +
+
+

+
1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 +12 +13 +14 +15 +16 +17 +18 +19 +20 +21 +22 +23 +24 +25 +26 +27 +28 +29 +30 +31 +32 +33 +34 +35 +36 +37 +38 +39 +40 +41 +42 +43 +44 +45 +46 +47 +48 +49 +50 +51 +52 +53 +54 +55 +56 +57 +58 +59 +60 +61 +62 +63 +64 +65 +66 +67 +68 +69 +70 +71 +72 +73 +74 +75 +76 +77 +78 +79 +80 +81 +82 +83 +84 +85 +86 +87 +88 +89 +90 +91 +92 +93 +94 +95 +96 +97 +98 +99 +100 +101 +102 +103 +104 +105 +106 +107 +108 +109 +110 +111 +112 +113 +114 +115 +116 +117 +118 +119 +120 +121 +122 +123 +124 +125 +126 +127 +128 +129 +130 +131 +132 +133 +134 +135 +136 +137 +138 +139 +140 +141 +142 +143 +144 +145 +146 +147 +148 +149 +150 +151 +152 +153 +154 +155 +156 +157 +158 +159 +160 +161 +162 +163 +164 +165 +166 +167 +168 +169 +170 +171 +172 +173 +174 +175 +176 +177 +178 +179 +180 +181 +182 +183 +184 +185 +186 +187 +188 +189 +190 +191 +192 +193 +194 +195 +196 +197 +198 +199 +200 +201 +202 +203 +204 +205 +206 +207 +208 +209 +210 +211 +212 +213 +214 +215 +216 +217 +218 +219 +220 +221 +222 +223 +224 +225 +226 +227 +228 +229 +230 +231 +232 +233 +234 +235 +236 +237 +238 +239 +240 +241 +242 +243 +244 +245 +246 +2471x +1x +1x +1x +1x +1x +  +  +  +  +1x +1x +1x +1x +  +  +  +1x +6x +6x +6x +6x +6x +6x +6x +6x +6x +6x +  +  +  +  +  +  +  +  +  +6x +6x +6x +2x +6x +  +6x +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +6x +6x +6x +6x +6x +6x +  +  +  +6x +6x +  +  +  +  +  +  +  +6x +6x +6x +6x +  +6x +6x +6x +6x +6x +6x +6x +6x +  +  +  +  +  +6x +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +6x +6x +  +6x +6x +  +6x +6x +6x +  +6x +  +1x + 
import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert";
+import { Button } from "@/components/ui/button";
+import { Input } from "@/components/ui/input";
+import { Label } from "@/components/ui/label";
+import { TabsContent } from "@/components/ui/tabs";
+import { Textarea } from "@/components/ui/textarea";
+import {
+  ListToolsResult,
+  Tool,
+  CallToolResultSchema,
+} from "@modelcontextprotocol/sdk/types.js";
+import { AlertCircle, Send } from "lucide-react";
+import { useEffect, useState } from "react";
+import ListPane from "./ListPane";
+ 
+import { CompatibilityCallToolResult } from "@modelcontextprotocol/sdk/types.js";
+ 
+const ToolsTab = ({
+  tools,
+  listTools,
+  clearTools,
+  callTool,
+  selectedTool,
+  setSelectedTool,
+  toolResult,
+  nextCursor,
+  error,
+}: {
+  tools: Tool[];
+  listTools: () => void;
+  clearTools: () => void;
+  callTool: (name: string, params: Record<string, unknown>) => void;
+  selectedTool: Tool | null;
+  setSelectedTool: (tool: Tool | null) => void;
+  toolResult: CompatibilityCallToolResult | null;
+  nextCursor: ListToolsResult["nextCursor"];
+  error: string | null;
+}) => {
+  const [params, setParams] = useState<Record<string, unknown>>({});
+  useEffect(() => {
+    setParams({});
+  }, [selectedTool]);
+ 
+  const renderToolResult = () => {
+    if (!toolResult) return null;
+ 
+    if ("content" in toolResult) {
+      const parsedResult = CallToolResultSchema.safeParse(toolResult);
+      if (!parsedResult.success) {
+        return (
+          <>
+            <h4 className="font-semibold mb-2">Invalid Tool Result:</h4>
+            <pre className="bg-gray-50 dark:bg-gray-800 dark:text-gray-100 p-4 rounded text-sm overflow-auto max-h-64">
+              {JSON.stringify(toolResult, null, 2)}
+            </pre>
+            <h4 className="font-semibold mb-2">Errors:</h4>
+            {parsedResult.error.errors.map((error, idx) => (
+              <pre
+                key={idx}
+                className="bg-gray-50 dark:bg-gray-800 dark:text-gray-100 p-4 rounded text-sm overflow-auto max-h-64"
+              >
+                {JSON.stringify(error, null, 2)}
+              </pre>
+            ))}
+          </>
+        );
+      }
+      const structuredResult = parsedResult.data;
+      const isError = structuredResult.isError ?? false;
+ 
+      return (
+        <>
+          <h4 className="font-semibold mb-2">
+            Tool Result: {isError ? "Error" : "Success"}
+          </h4>
+          {structuredResult.content.map((item, index) => (
+            <div key={index} className="mb-2">
+              {item.type === "text" && (
+                <pre className="bg-gray-50 dark:bg-gray-800 dark:text-gray-100 p-4 rounded text-sm overflow-auto max-h-64">
+                  {item.text}
+                </pre>
+              )}
+              {item.type === "image" && (
+                <img
+                  src={`data:${item.mimeType};base64,${item.data}`}
+                  alt="Tool result image"
+                  className="max-w-full h-auto"
+                />
+              )}
+              {item.type === "resource" && (
+                <pre className="bg-gray-50  dark:bg-gray-800 dark:text-gray-100 whitespace-pre-wrap break-words p-4 rounded text-sm overflow-auto max-h-64">
+                  {JSON.stringify(item.resource, null, 2)}
+                </pre>
+              )}
+            </div>
+          ))}
+        </>
+      );
+    } else if ("toolResult" in toolResult) {
+      return (
+        <>
+          <h4 className="font-semibold mb-2">Tool Result (Legacy):</h4>
+          <pre className="bg-gray-50 dark:bg-gray-800 dark:text-gray-100 p-4 rounded text-sm overflow-auto max-h-64">
+            {JSON.stringify(toolResult.toolResult, null, 2)}
+          </pre>
+        </>
+      );
+    }
+  };
+ 
+  return (
+    <TabsContent value="tools" className="grid grid-cols-2 gap-4">
+      <ListPane
+        items={tools}
+        listItems={listTools}
+        clearItems={() => {
+          clearTools();
+          setSelectedTool(null);
+        }}
+        setSelectedItem={setSelectedTool}
+        renderItem={(tool) => (
+          <>
+            <span className="flex-1">{tool.name}</span>
+            <span className="text-sm text-gray-500 text-right">
+              {tool.description}
+            </span>
+          </>
+        )}
+        title="Tools"
+        buttonText={nextCursor ? "List More Tools" : "List Tools"}
+        isButtonDisabled={!nextCursor && tools.length > 0}
+      />
+ 
+      <div className="bg-card rounded-lg shadow">
+        <div className="p-4 border-b border-gray-200">
+          <h3 className="font-semibold">
+            {selectedTool ? selectedTool.name : "Select a tool"}
+          </h3>
+        </div>
+        <div className="p-4">
+          {error ? (
+            <Alert variant="destructive">
+              <AlertCircle className="h-4 w-4" />
+              <AlertTitle>Error</AlertTitle>
+              <AlertDescription>{error}</AlertDescription>
+            </Alert>
+          ) : selectedTool ? (
+            <div className="space-y-4">
+              <p className="text-sm text-gray-600">
+                {selectedTool.description}
+              </p>
+              {Object.entries(selectedTool.inputSchema.properties ?? []).map(
+                ([key, value]) => (
+                  <div key={key}>
+                    <Label
+                      htmlFor={key}
+                      className="block text-sm font-medium text-gray-700"
+                    >
+                      {key}
+                    </Label>
+                    {
+                      /* @ts-expect-error value type is currently unknown */
+                      value.type === "string" ? (
+                        <Textarea
+                          id={key}
+                          name={key}
+                          // @ts-expect-error value type is currently unknown
+                          placeholder={value.description}
+                          onChange={(e) =>
+                            setParams({
+                              ...params,
+                              [key]: e.target.value,
+                            })
+                          }
+                          className="mt-1"
+                        />
+                      ) :
+                      /* @ts-expect-error value type is currently unknown */
+                      value.type === "object" ? (
+                        <Textarea
+                          id={key}
+                          name={key}
+                          // @ts-expect-error value type is currently unknown
+                          placeholder={value.description}
+                          onChange={(e) => {
+                            try {
+                              const parsed = JSON.parse(e.target.value);
+                              setParams({
+                                ...params,
+                                [key]: parsed,
+                              });
+                            } catch (err) {
+                              // If invalid JSON, store as string - will be validated on submit
+                              setParams({
+                                ...params,
+                                [key]: e.target.value,
+                              });
+                            }
+                          }}
+                          className="mt-1"
+                        />
+                      ) : (
+                        <Input
+                          // @ts-expect-error value type is currently unknown
+                          type={value.type === "number" ? "number" : "text"}
+                          id={key}
+                          name={key}
+                          // @ts-expect-error value type is currently unknown
+                          placeholder={value.description}
+                          onChange={(e) =>
+                            setParams({
+                              ...params,
+                              [key]:
+                                // @ts-expect-error value type is currently unknown
+                                value.type === "number"
+                                  ? Number(e.target.value)
+                                  : e.target.value,
+                            })
+                          }
+                          className="mt-1"
+                        />
+                      )
+                    }
+                  </div>
+                ),
+              )}
+              <Button onClick={() => callTool(selectedTool.name, params)}>
+                <Send className="w-4 h-4 mr-2" />
+                Run Tool
+              </Button>
+              {toolResult && renderToolResult()}
+            </div>
+          ) : (
+            <Alert>
+              <AlertDescription>
+                Select a tool from the list to view its details and run it
+              </AlertDescription>
+            </Alert>
+          )}
+        </div>
+      </div>
+    </TabsContent>
+  );
+};
+ 
+export default ToolsTab;
+ 
+ +
+
+ + + + + + + + \ No newline at end of file diff --git a/client/coverage/client/src/components/index.html b/client/coverage/client/src/components/index.html new file mode 100644 index 0000000000..c3d3c4f54f --- /dev/null +++ b/client/coverage/client/src/components/index.html @@ -0,0 +1,251 @@ + + + + + + Code coverage report for client/src/components + + + + + + + + + +
+
+

All files client/src/components

+
+ +
+ 77.34% + Statements + 758/980 +
+ + +
+ 87.03% + Branches + 94/108 +
+ + +
+ 69.23% + Functions + 36/52 +
+ + +
+ 77.34% + Lines + 758/980 +
+ + +
+

+ Press n or j to go to the next uncovered block, b, p or k for the previous block. +

+ +
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FileStatementsBranchesFunctionsLines
ConsoleTab.tsx +
+
100%8/8100%1/1100%1/1100%8/8
History.tsx +
+
97.74%130/133100%19/1955.55%5/997.74%130/133
ListPane.tsx +
+
100%43/43100%3/3100%2/2100%43/43
PingTab.tsx +
+
100%16/16100%1/1100%1/1100%16/16
PromptsTab.tsx +
+
97.11%101/10494.11%16/1783.33%5/697.11%101/104
ResourcesTab.tsx +
+
97.54%159/16389.28%25/2888.88%8/997.54%159/163
RootsTab.tsx +
+
100%61/61100%15/15100%7/7100%61/61
SamplingTab.tsx +
+
100%41/41100%6/6100%4/4100%41/41
Sidebar.tsx +
+
65.43%142/21750%6/1225%2/865.43%142/217
ToolsTab.tsx +
+
29.38%57/19433.33%2/620%1/529.38%57/194
+
+
+
+ + + + + + + + \ No newline at end of file diff --git a/client/coverage/client/src/components/ui/alert.tsx.html b/client/coverage/client/src/components/ui/alert.tsx.html new file mode 100644 index 0000000000..30e9aa9e6b --- /dev/null +++ b/client/coverage/client/src/components/ui/alert.tsx.html @@ -0,0 +1,262 @@ + + + + + + Code coverage report for client/src/components/ui/alert.tsx + + + + + + + + + +
+
+

All files / client/src/components/ui alert.tsx

+
+ +
+ 100% + Statements + 44/44 +
+ + +
+ 100% + Branches + 3/3 +
+ + +
+ 100% + Functions + 0/0 +
+ + +
+ 100% + Lines + 44/44 +
+ + +
+

+ Press n or j to go to the next uncovered block, b, p or k for the previous block. +

+ +
+
+

+
1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 +12 +13 +14 +15 +16 +17 +18 +19 +20 +21 +22 +23 +24 +25 +26 +27 +28 +29 +30 +31 +32 +33 +34 +35 +36 +37 +38 +39 +40 +41 +42 +43 +44 +45 +46 +47 +48 +49 +50 +51 +52 +53 +54 +55 +56 +57 +58 +59 +601x +  +  +  +  +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +  +1x +  +  +1x +23x +23x +23x +23x +23x +23x +23x +1x +  +1x +  +  +1x +2x +2x +2x +2x +2x +2x +1x +  +1x +  +  +1x +23x +23x +23x +23x +23x +23x +1x +  +  + 
import * as React from "react";
+import { cva, type VariantProps } from "class-variance-authority";
+ 
+import { cn } from "@/lib/utils";
+ 
+const alertVariants = cva(
+  "relative w-full rounded-lg border px-4 py-3 text-sm [&>svg+div]:translate-y-[-3px] [&>svg]:absolute [&>svg]:left-4 [&>svg]:top-4 [&>svg]:text-foreground [&>svg~*]:pl-7",
+  {
+    variants: {
+      variant: {
+        default: "bg-background text-foreground",
+        destructive:
+          "border-destructive/50 text-destructive dark:border-destructive [&>svg]:text-destructive",
+      },
+    },
+    defaultVariants: {
+      variant: "default",
+    },
+  },
+);
+ 
+const Alert = React.forwardRef<
+  HTMLDivElement,
+  React.HTMLAttributes<HTMLDivElement> & VariantProps<typeof alertVariants>
+>(({ className, variant, ...props }, ref) => (
+  <div
+    ref={ref}
+    role="alert"
+    className={cn(alertVariants({ variant }), className)}
+    {...props}
+  />
+));
+Alert.displayName = "Alert";
+ 
+const AlertTitle = React.forwardRef<
+  HTMLParagraphElement,
+  React.HTMLAttributes<HTMLHeadingElement>
+>(({ className, ...props }, ref) => (
+  <h5
+    ref={ref}
+    className={cn("mb-1 font-medium leading-none tracking-tight", className)}
+    {...props}
+  />
+));
+AlertTitle.displayName = "AlertTitle";
+ 
+const AlertDescription = React.forwardRef<
+  HTMLParagraphElement,
+  React.HTMLAttributes<HTMLParagraphElement>
+>(({ className, ...props }, ref) => (
+  <div
+    ref={ref}
+    className={cn("text-sm [&_p]:leading-relaxed", className)}
+    {...props}
+  />
+));
+AlertDescription.displayName = "AlertDescription";
+ 
+export { Alert, AlertTitle, AlertDescription };
+ 
+ +
+
+ + + + + + + + \ No newline at end of file diff --git a/client/coverage/client/src/components/ui/button.tsx.html b/client/coverage/client/src/components/ui/button.tsx.html new file mode 100644 index 0000000000..a268448399 --- /dev/null +++ b/client/coverage/client/src/components/ui/button.tsx.html @@ -0,0 +1,256 @@ + + + + + + Code coverage report for client/src/components/ui/button.tsx + + + + + + + + + +
+
+

All files / client/src/components/ui button.tsx

+
+ +
+ 100% + Statements + 42/42 +
+ + +
+ 50% + Branches + 1/2 +
+ + +
+ 100% + Functions + 0/0 +
+ + +
+ 100% + Lines + 42/42 +
+ + +
+

+ Press n or j to go to the next uncovered block, b, p or k for the previous block. +

+ +
+
+

+
1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 +12 +13 +14 +15 +16 +17 +18 +19 +20 +21 +22 +23 +24 +25 +26 +27 +28 +29 +30 +31 +32 +33 +34 +35 +36 +37 +38 +39 +40 +41 +42 +43 +44 +45 +46 +47 +48 +49 +50 +51 +52 +53 +54 +55 +56 +57 +581x +  +  +  +  +  +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +  +  +  +  +  +  +  +1x +1x +223x +223x +223x +223x +223x +223x +223x +  +223x +1x +1x +  +  + 
import * as React from "react";
+import { Slot } from "@radix-ui/react-slot";
+import { cva, type VariantProps } from "class-variance-authority";
+ 
+import { cn } from "@/lib/utils";
+ 
+const buttonVariants = cva(
+  "inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50",
+  {
+    variants: {
+      variant: {
+        default:
+          "bg-primary text-primary-foreground shadow hover:bg-primary/90 dark:bg-gray-800 dark:text-white dark:hover:bg-gray-700",
+        destructive:
+          "bg-destructive text-destructive-foreground shadow-sm hover:bg-destructive/90",
+        outline:
+          "border border-input bg-background shadow-sm hover:bg-accent hover:text-accent-foreground",
+        secondary:
+          "bg-secondary text-secondary-foreground shadow-sm hover:bg-secondary/80",
+        ghost: "hover:bg-accent hover:text-accent-foreground",
+        link: "text-primary underline-offset-4 hover:underline",
+      },
+      size: {
+        default: "h-9 px-4 py-2",
+        sm: "h-8 rounded-md px-3 text-xs",
+        lg: "h-10 rounded-md px-8",
+        icon: "h-9 w-9",
+      },
+    },
+    defaultVariants: {
+      variant: "default",
+      size: "default",
+    },
+  },
+);
+ 
+export interface ButtonProps
+  extends React.ButtonHTMLAttributes<HTMLButtonElement>,
+    VariantProps<typeof buttonVariants> {
+  asChild?: boolean;
+}
+ 
+const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
+  ({ className, variant, size, asChild = false, ...props }, ref) => {
+    const Comp = asChild ? Slot : "button";
+    return (
+      <Comp
+        className={cn(buttonVariants({ variant, size, className }))}
+        ref={ref}
+        {...props}
+      />
+    );
+  },
+);
+Button.displayName = "Button";
+ 
+export { Button, buttonVariants };
+ 
+ +
+
+ + + + + + + + \ No newline at end of file diff --git a/client/coverage/client/src/components/ui/index.html b/client/coverage/client/src/components/ui/index.html new file mode 100644 index 0000000000..fca4d61509 --- /dev/null +++ b/client/coverage/client/src/components/ui/index.html @@ -0,0 +1,206 @@ + + + + + + Code coverage report for client/src/components/ui + + + + + + + + + +
+
+

All files client/src/components/ui

+
+ +
+ 95.68% + Statements + 266/278 +
+ + +
+ 93.75% + Branches + 15/16 +
+ + +
+ 100% + Functions + 0/0 +
+ + +
+ 95.68% + Lines + 266/278 +
+ + +
+

+ Press n or j to go to the next uncovered block, b, p or k for the previous block. +

+ +
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FileStatementsBranchesFunctionsLines
alert.tsx +
+
100%44/44100%3/3100%0/0100%44/44
button.tsx +
+
100%42/4250%1/2100%0/0100%42/42
input.tsx +
+
100%16/16100%1/1100%0/0100%16/16
label.tsx +
+
100%13/13100%1/1100%0/0100%13/13
select.tsx +
+
89.09%98/110100%5/5100%0/089.09%98/110
tabs.tsx +
+
100%38/38100%3/3100%0/0100%38/38
textarea.tsx +
+
100%15/15100%1/1100%0/0100%15/15
+
+
+
+ + + + + + + + \ No newline at end of file diff --git a/client/coverage/client/src/components/ui/input.tsx.html b/client/coverage/client/src/components/ui/input.tsx.html new file mode 100644 index 0000000000..b973316bb4 --- /dev/null +++ b/client/coverage/client/src/components/ui/input.tsx.html @@ -0,0 +1,160 @@ + + + + + + Code coverage report for client/src/components/ui/input.tsx + + + + + + + + + +
+
+

All files / client/src/components/ui input.tsx

+
+ +
+ 100% + Statements + 16/16 +
+ + +
+ 100% + Branches + 1/1 +
+ + +
+ 100% + Functions + 0/0 +
+ + +
+ 100% + Lines + 16/16 +
+ + +
+

+ Press n or j to go to the next uncovered block, b, p or k for the previous block. +

+ +
+
+

+
1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 +12 +13 +14 +15 +16 +17 +18 +19 +20 +21 +22 +23 +24 +25 +261x +  +  +  +  +  +  +1x +1x +58x +58x +58x +58x +58x +58x +58x +58x +58x +58x +  +58x +1x +1x +  +  + 
import * as React from "react";
+ 
+import { cn } from "@/lib/utils";
+ 
+export interface InputProps
+  extends React.InputHTMLAttributes<HTMLInputElement> {}
+ 
+const Input = React.forwardRef<HTMLInputElement, InputProps>(
+  ({ className, type, ...props }, ref) => {
+    return (
+      <input
+        type={type}
+        className={cn(
+          "flex h-9 w-full rounded-md border border-input bg-transparent px-3 py-1 text-sm shadow-sm transition-colors file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50",
+          className,
+        )}
+        ref={ref}
+        {...props}
+      />
+    );
+  },
+);
+Input.displayName = "Input";
+ 
+export { Input };
+ 
+ +
+
+ + + + + + + + \ No newline at end of file diff --git a/client/coverage/client/src/components/ui/label.tsx.html b/client/coverage/client/src/components/ui/label.tsx.html new file mode 100644 index 0000000000..deab1a200b --- /dev/null +++ b/client/coverage/client/src/components/ui/label.tsx.html @@ -0,0 +1,157 @@ + + + + + + Code coverage report for client/src/components/ui/label.tsx + + + + + + + + + +
+
+

All files / client/src/components/ui label.tsx

+
+ +
+ 100% + Statements + 13/13 +
+ + +
+ 100% + Branches + 1/1 +
+ + +
+ 100% + Functions + 0/0 +
+ + +
+ 100% + Lines + 13/13 +
+ + +
+

+ Press n or j to go to the next uncovered block, b, p or k for the previous block. +

+ +
+
+

+
1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 +12 +13 +14 +15 +16 +17 +18 +19 +20 +21 +22 +23 +24 +251x +  +  +  +  +  +1x +1x +1x +  +1x +  +  +  +1x +8x +8x +8x +8x +8x +8x +1x +  +  + 
import * as React from "react";
+import * as LabelPrimitive from "@radix-ui/react-label";
+import { cva, type VariantProps } from "class-variance-authority";
+ 
+import { cn } from "@/lib/utils";
+ 
+const labelVariants = cva(
+  "text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70",
+);
+ 
+const Label = React.forwardRef<
+  React.ElementRef<typeof LabelPrimitive.Root>,
+  React.ComponentPropsWithoutRef<typeof LabelPrimitive.Root> &
+    VariantProps<typeof labelVariants>
+>(({ className, ...props }, ref) => (
+  <LabelPrimitive.Root
+    ref={ref}
+    className={cn(labelVariants(), className)}
+    {...props}
+  />
+));
+Label.displayName = LabelPrimitive.Root.displayName;
+ 
+export { Label };
+ 
+ +
+
+ + + + + + + + \ No newline at end of file diff --git a/client/coverage/client/src/components/ui/select.tsx.html b/client/coverage/client/src/components/ui/select.tsx.html new file mode 100644 index 0000000000..edde919281 --- /dev/null +++ b/client/coverage/client/src/components/ui/select.tsx.html @@ -0,0 +1,571 @@ + + + + + + Code coverage report for client/src/components/ui/select.tsx + + + + + + + + + +
+
+

All files / client/src/components/ui select.tsx

+
+ +
+ 89.09% + Statements + 98/110 +
+ + +
+ 100% + Branches + 5/5 +
+ + +
+ 100% + Functions + 0/0 +
+ + +
+ 89.09% + Lines + 98/110 +
+ + +
+

+ Press n or j to go to the next uncovered block, b, p or k for the previous block. +

+ +
+
+

+
1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 +12 +13 +14 +15 +16 +17 +18 +19 +20 +21 +22 +23 +24 +25 +26 +27 +28 +29 +30 +31 +32 +33 +34 +35 +36 +37 +38 +39 +40 +41 +42 +43 +44 +45 +46 +47 +48 +49 +50 +51 +52 +53 +54 +55 +56 +57 +58 +59 +60 +61 +62 +63 +64 +65 +66 +67 +68 +69 +70 +71 +72 +73 +74 +75 +76 +77 +78 +79 +80 +81 +82 +83 +84 +85 +86 +87 +88 +89 +90 +91 +92 +93 +94 +95 +96 +97 +98 +99 +100 +101 +102 +103 +104 +105 +106 +107 +108 +109 +110 +111 +112 +113 +114 +115 +116 +117 +118 +119 +120 +121 +122 +123 +124 +125 +126 +127 +128 +129 +130 +131 +132 +133 +134 +135 +136 +137 +138 +139 +140 +141 +142 +143 +144 +145 +146 +147 +148 +149 +150 +151 +152 +153 +154 +155 +156 +157 +158 +159 +160 +161 +162 +1631x +  +  +  +  +  +  +  +  +  +  +1x +  +1x +  +1x +  +1x +  +  +1x +32x +32x +32x +32x +32x +32x +32x +  +32x +32x +32x +32x +32x +32x +1x +  +1x +  +  +1x +32x +32x +32x +32x +32x +32x +32x +  +32x +32x +32x +1x +  +1x +  +  +1x +32x +32x +32x +32x +32x +32x +32x +  +32x +32x +32x +1x +1x +  +1x +  +  +1x +32x +32x +32x +32x +32x +32x +32x +32x +32x +32x +32x +  +32x +32x +32x +32x +32x +32x +32x +  +32x +32x +32x +32x +32x +1x +1x +  +1x +  +  +1x +  +  +  +  +  +  +1x +  +1x +  +  +1x +80x +80x +80x +80x +80x +80x +80x +  +80x +80x +80x +80x +80x +80x +80x +80x +1x +  +1x +  +  +1x +  +  +  +  +  +  +1x +  +  +  +  +  +  +  +  +  +  +  +  +  + 
import * as React from "react";
+import {
+  CaretSortIcon,
+  CheckIcon,
+  ChevronDownIcon,
+  ChevronUpIcon,
+} from "@radix-ui/react-icons";
+import * as SelectPrimitive from "@radix-ui/react-select";
+ 
+import { cn } from "@/lib/utils";
+ 
+const Select = SelectPrimitive.Root;
+ 
+const SelectGroup = SelectPrimitive.Group;
+ 
+const SelectValue = SelectPrimitive.Value;
+ 
+const SelectTrigger = React.forwardRef<
+  React.ElementRef<typeof SelectPrimitive.Trigger>,
+  React.ComponentPropsWithoutRef<typeof SelectPrimitive.Trigger>
+>(({ className, children, ...props }, ref) => (
+  <SelectPrimitive.Trigger
+    ref={ref}
+    className={cn(
+      "flex h-9 w-full items-center justify-between whitespace-nowrap rounded-md border border-input bg-transparent px-3 py-2 text-sm shadow-sm ring-offset-background placeholder:text-muted-foreground focus:outline-none focus:ring-1 focus:ring-ring disabled:cursor-not-allowed disabled:opacity-50 [&>span]:line-clamp-1",
+      className,
+    )}
+    {...props}
+  >
+    {children}
+    <SelectPrimitive.Icon asChild>
+      <CaretSortIcon className="h-4 w-4 opacity-50" />
+    </SelectPrimitive.Icon>
+  </SelectPrimitive.Trigger>
+));
+SelectTrigger.displayName = SelectPrimitive.Trigger.displayName;
+ 
+const SelectScrollUpButton = React.forwardRef<
+  React.ElementRef<typeof SelectPrimitive.ScrollUpButton>,
+  React.ComponentPropsWithoutRef<typeof SelectPrimitive.ScrollUpButton>
+>(({ className, ...props }, ref) => (
+  <SelectPrimitive.ScrollUpButton
+    ref={ref}
+    className={cn(
+      "flex cursor-default items-center justify-center py-1",
+      className,
+    )}
+    {...props}
+  >
+    <ChevronUpIcon />
+  </SelectPrimitive.ScrollUpButton>
+));
+SelectScrollUpButton.displayName = SelectPrimitive.ScrollUpButton.displayName;
+ 
+const SelectScrollDownButton = React.forwardRef<
+  React.ElementRef<typeof SelectPrimitive.ScrollDownButton>,
+  React.ComponentPropsWithoutRef<typeof SelectPrimitive.ScrollDownButton>
+>(({ className, ...props }, ref) => (
+  <SelectPrimitive.ScrollDownButton
+    ref={ref}
+    className={cn(
+      "flex cursor-default items-center justify-center py-1",
+      className,
+    )}
+    {...props}
+  >
+    <ChevronDownIcon />
+  </SelectPrimitive.ScrollDownButton>
+));
+SelectScrollDownButton.displayName =
+  SelectPrimitive.ScrollDownButton.displayName;
+ 
+const SelectContent = React.forwardRef<
+  React.ElementRef<typeof SelectPrimitive.Content>,
+  React.ComponentPropsWithoutRef<typeof SelectPrimitive.Content>
+>(({ className, children, position = "popper", ...props }, ref) => (
+  <SelectPrimitive.Portal>
+    <SelectPrimitive.Content
+      ref={ref}
+      className={cn(
+        "relative z-50 max-h-96 min-w-[8rem] overflow-hidden rounded-md border bg-popover text-popover-foreground shadow-md data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
+        position === "popper" &&
+          "data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1",
+        className,
+      )}
+      position={position}
+      {...props}
+    >
+      <SelectScrollUpButton />
+      <SelectPrimitive.Viewport
+        className={cn(
+          "p-1",
+          position === "popper" &&
+            "h-[var(--radix-select-trigger-height)] w-full min-w-[var(--radix-select-trigger-width)]",
+        )}
+      >
+        {children}
+      </SelectPrimitive.Viewport>
+      <SelectScrollDownButton />
+    </SelectPrimitive.Content>
+  </SelectPrimitive.Portal>
+));
+SelectContent.displayName = SelectPrimitive.Content.displayName;
+ 
+const SelectLabel = React.forwardRef<
+  React.ElementRef<typeof SelectPrimitive.Label>,
+  React.ComponentPropsWithoutRef<typeof SelectPrimitive.Label>
+>(({ className, ...props }, ref) => (
+  <SelectPrimitive.Label
+    ref={ref}
+    className={cn("px-2 py-1.5 text-sm font-semibold", className)}
+    {...props}
+  />
+));
+SelectLabel.displayName = SelectPrimitive.Label.displayName;
+ 
+const SelectItem = React.forwardRef<
+  React.ElementRef<typeof SelectPrimitive.Item>,
+  React.ComponentPropsWithoutRef<typeof SelectPrimitive.Item>
+>(({ className, children, ...props }, ref) => (
+  <SelectPrimitive.Item
+    ref={ref}
+    className={cn(
+      "relative flex w-full cursor-default select-none items-center rounded-sm py-1.5 pl-2 pr-8 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
+      className,
+    )}
+    {...props}
+  >
+    <span className="absolute right-2 flex h-3.5 w-3.5 items-center justify-center">
+      <SelectPrimitive.ItemIndicator>
+        <CheckIcon className="h-4 w-4" />
+      </SelectPrimitive.ItemIndicator>
+    </span>
+    <SelectPrimitive.ItemText>{children}</SelectPrimitive.ItemText>
+  </SelectPrimitive.Item>
+));
+SelectItem.displayName = SelectPrimitive.Item.displayName;
+ 
+const SelectSeparator = React.forwardRef<
+  React.ElementRef<typeof SelectPrimitive.Separator>,
+  React.ComponentPropsWithoutRef<typeof SelectPrimitive.Separator>
+>(({ className, ...props }, ref) => (
+  <SelectPrimitive.Separator
+    ref={ref}
+    className={cn("-mx-1 my-1 h-px bg-muted", className)}
+    {...props}
+  />
+));
+SelectSeparator.displayName = SelectPrimitive.Separator.displayName;
+ 
+export {
+  Select,
+  SelectGroup,
+  SelectValue,
+  SelectTrigger,
+  SelectContent,
+  SelectLabel,
+  SelectItem,
+  SelectSeparator,
+  SelectScrollUpButton,
+  SelectScrollDownButton,
+};
+ 
+ +
+
+ + + + + + + + \ No newline at end of file diff --git a/client/coverage/client/src/components/ui/tabs.tsx.html b/client/coverage/client/src/components/ui/tabs.tsx.html new file mode 100644 index 0000000000..0a88987756 --- /dev/null +++ b/client/coverage/client/src/components/ui/tabs.tsx.html @@ -0,0 +1,244 @@ + + + + + + Code coverage report for client/src/components/ui/tabs.tsx + + + + + + + + + +
+
+

All files / client/src/components/ui tabs.tsx

+
+ +
+ 100% + Statements + 38/38 +
+ + +
+ 100% + Branches + 3/3 +
+ + +
+ 100% + Functions + 0/0 +
+ + +
+ 100% + Lines + 38/38 +
+ + +
+

+ Press n or j to go to the next uncovered block, b, p or k for the previous block. +

+ +
+
+

+
1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 +12 +13 +14 +15 +16 +17 +18 +19 +20 +21 +22 +23 +24 +25 +26 +27 +28 +29 +30 +31 +32 +33 +34 +35 +36 +37 +38 +39 +40 +41 +42 +43 +44 +45 +46 +47 +48 +49 +50 +51 +52 +53 +541x +  +  +  +  +1x +  +1x +  +  +1x +9x +9x +9x +9x +9x +9x +9x +9x +9x +1x +  +1x +  +  +1x +54x +54x +54x +54x +54x +54x +54x +54x +54x +1x +  +1x +  +  +1x +64x +64x +64x +64x +64x +64x +64x +64x +64x +1x +  +  + 
import * as React from "react";
+import * as TabsPrimitive from "@radix-ui/react-tabs";
+ 
+import { cn } from "@/lib/utils";
+ 
+const Tabs = TabsPrimitive.Root;
+ 
+const TabsList = React.forwardRef<
+  React.ElementRef<typeof TabsPrimitive.List>,
+  React.ComponentPropsWithoutRef<typeof TabsPrimitive.List>
+>(({ className, ...props }, ref) => (
+  <TabsPrimitive.List
+    ref={ref}
+    className={cn(
+      "inline-flex h-9 items-center justify-center rounded-lg bg-muted p-1 text-muted-foreground",
+      className,
+    )}
+    {...props}
+  />
+));
+TabsList.displayName = TabsPrimitive.List.displayName;
+ 
+const TabsTrigger = React.forwardRef<
+  React.ElementRef<typeof TabsPrimitive.Trigger>,
+  React.ComponentPropsWithoutRef<typeof TabsPrimitive.Trigger>
+>(({ className, ...props }, ref) => (
+  <TabsPrimitive.Trigger
+    ref={ref}
+    className={cn(
+      "inline-flex items-center justify-center whitespace-nowrap rounded-md px-3 py-1 text-sm font-medium ring-offset-background transition-all focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 bg-muted data-[state=active]:bg-background data-[state=active]:text-foreground data-[state=active]:shadow",
+      className,
+    )}
+    {...props}
+  />
+));
+TabsTrigger.displayName = TabsPrimitive.Trigger.displayName;
+ 
+const TabsContent = React.forwardRef<
+  React.ElementRef<typeof TabsPrimitive.Content>,
+  React.ComponentPropsWithoutRef<typeof TabsPrimitive.Content>
+>(({ className, ...props }, ref) => (
+  <TabsPrimitive.Content
+    ref={ref}
+    className={cn(
+      "mt-2 ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
+      className,
+    )}
+    {...props}
+  />
+));
+TabsContent.displayName = TabsPrimitive.Content.displayName;
+ 
+export { Tabs, TabsList, TabsTrigger, TabsContent };
+ 
+ +
+
+ + + + + + + + \ No newline at end of file diff --git a/client/coverage/client/src/components/ui/textarea.tsx.html b/client/coverage/client/src/components/ui/textarea.tsx.html new file mode 100644 index 0000000000..fffa6ebff2 --- /dev/null +++ b/client/coverage/client/src/components/ui/textarea.tsx.html @@ -0,0 +1,157 @@ + + + + + + Code coverage report for client/src/components/ui/textarea.tsx + + + + + + + + + +
+
+

All files / client/src/components/ui textarea.tsx

+
+ +
+ 100% + Statements + 15/15 +
+ + +
+ 100% + Branches + 1/1 +
+ + +
+ 100% + Functions + 0/0 +
+ + +
+ 100% + Lines + 15/15 +
+ + +
+

+ Press n or j to go to the next uncovered block, b, p or k for the previous block. +

+ +
+
+

+
1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 +12 +13 +14 +15 +16 +17 +18 +19 +20 +21 +22 +23 +24 +251x +  +  +  +  +  +  +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +  +1x +1x +1x +  +  + 
import * as React from "react";
+ 
+import { cn } from "@/lib/utils";
+ 
+export interface TextareaProps
+  extends React.TextareaHTMLAttributes<HTMLTextAreaElement> {}
+ 
+const Textarea = React.forwardRef<HTMLTextAreaElement, TextareaProps>(
+  ({ className, ...props }, ref) => {
+    return (
+      <textarea
+        className={cn(
+          "flex min-h-[60px] w-full rounded-md border border-input bg-transparent px-3 py-2 text-sm shadow-sm placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50",
+          className,
+        )}
+        ref={ref}
+        {...props}
+      />
+    );
+  },
+);
+Textarea.displayName = "Textarea";
+ 
+export { Textarea };
+ 
+ +
+
+ + + + + + + + \ No newline at end of file diff --git a/client/coverage/client/src/index.html b/client/coverage/client/src/index.html new file mode 100644 index 0000000000..c3f0a8343c --- /dev/null +++ b/client/coverage/client/src/index.html @@ -0,0 +1,131 @@ + + + + + + Code coverage report for client/src + + + + + + + + + +
+
+

All files client/src

+
+ +
+ 59.17% + Statements + 274/463 +
+ + +
+ 86.2% + Branches + 25/29 +
+ + +
+ 5.88% + Functions + 2/34 +
+ + +
+ 59.17% + Lines + 274/463 +
+ + +
+

+ Press n or j to go to the next uncovered block, b, p or k for the previous block. +

+ +
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FileStatementsBranchesFunctionsLines
App.tsx +
+
60.75%274/45189.28%25/286.06%2/3360.75%274/451
main.tsx +
+
0%0/120%0/10%0/10%0/12
+
+
+
+ + + + + + + + \ No newline at end of file diff --git a/client/coverage/client/src/lib/hooks/index.html b/client/coverage/client/src/lib/hooks/index.html new file mode 100644 index 0000000000..7e58a25dd0 --- /dev/null +++ b/client/coverage/client/src/lib/hooks/index.html @@ -0,0 +1,131 @@ + + + + + + Code coverage report for client/src/lib/hooks + + + + + + + + + +
+
+

All files client/src/lib/hooks

+
+ +
+ 0% + Statements + 0/174 +
+ + +
+ 0% + Branches + 0/2 +
+ + +
+ 0% + Functions + 0/2 +
+ + +
+ 0% + Lines + 0/174 +
+ + +
+

+ Press n or j to go to the next uncovered block, b, p or k for the previous block. +

+ +
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FileStatementsBranchesFunctionsLines
useConnection.ts +
+
0%0/1360%0/10%0/10%0/136
useDraggablePane.ts +
+
0%0/380%0/10%0/10%0/38
+
+
+
+ + + + + + + + \ No newline at end of file diff --git a/client/coverage/client/src/lib/hooks/useConnection.ts.html b/client/coverage/client/src/lib/hooks/useConnection.ts.html new file mode 100644 index 0000000000..531049bf0f --- /dev/null +++ b/client/coverage/client/src/lib/hooks/useConnection.ts.html @@ -0,0 +1,646 @@ + + + + + + Code coverage report for client/src/lib/hooks/useConnection.ts + + + + + + + + + +
+
+

All files / client/src/lib/hooks useConnection.ts

+
+ +
+ 0% + Statements + 0/136 +
+ + +
+ 0% + Branches + 0/1 +
+ + +
+ 0% + Functions + 0/1 +
+ + +
+ 0% + Lines + 0/136 +
+ + +
+

+ Press n or j to go to the next uncovered block, b, p or k for the previous block. +

+ +
+
+

+
1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 +12 +13 +14 +15 +16 +17 +18 +19 +20 +21 +22 +23 +24 +25 +26 +27 +28 +29 +30 +31 +32 +33 +34 +35 +36 +37 +38 +39 +40 +41 +42 +43 +44 +45 +46 +47 +48 +49 +50 +51 +52 +53 +54 +55 +56 +57 +58 +59 +60 +61 +62 +63 +64 +65 +66 +67 +68 +69 +70 +71 +72 +73 +74 +75 +76 +77 +78 +79 +80 +81 +82 +83 +84 +85 +86 +87 +88 +89 +90 +91 +92 +93 +94 +95 +96 +97 +98 +99 +100 +101 +102 +103 +104 +105 +106 +107 +108 +109 +110 +111 +112 +113 +114 +115 +116 +117 +118 +119 +120 +121 +122 +123 +124 +125 +126 +127 +128 +129 +130 +131 +132 +133 +134 +135 +136 +137 +138 +139 +140 +141 +142 +143 +144 +145 +146 +147 +148 +149 +150 +151 +152 +153 +154 +155 +156 +157 +158 +159 +160 +161 +162 +163 +164 +165 +166 +167 +168 +169 +170 +171 +172 +173 +174 +175 +176 +177 +178 +179 +180 +181 +182 +183 +184 +185 +186 +187 +188  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  + 
import { Client } from "@modelcontextprotocol/sdk/client/index.js";
+import { SSEClientTransport } from "@modelcontextprotocol/sdk/client/sse.js";
+import {
+  ClientNotification,
+  ClientRequest,
+  CreateMessageRequestSchema,
+  ListRootsRequestSchema,
+  ProgressNotificationSchema,
+  Request,
+  Result,
+  ServerCapabilities,
+} from "@modelcontextprotocol/sdk/types.js";
+import { useState } from "react";
+import { toast } from "react-toastify";
+import { Notification, StdErrNotificationSchema } from "../notificationTypes";
+import { z } from "zod";
+ 
+const DEFAULT_REQUEST_TIMEOUT_MSEC = 10000;
+ 
+interface UseConnectionOptions {
+  transportType: "stdio" | "sse";
+  command: string;
+  args: string;
+  sseUrl: string;
+  env: Record<string, string>;
+  proxyServerUrl: string;
+  requestTimeout?: number;
+  onNotification?: (notification: Notification) => void;
+  onStdErrNotification?: (notification: Notification) => void;
+  onPendingRequest?: (request: any, resolve: any, reject: any) => void;
+  getRoots?: () => any[];
+}
+ 
+export function useConnection({
+  transportType,
+  command,
+  args,
+  sseUrl,
+  env,
+  proxyServerUrl,
+  requestTimeout = DEFAULT_REQUEST_TIMEOUT_MSEC,
+  onNotification,
+  onStdErrNotification,
+  onPendingRequest,
+  getRoots,
+}: UseConnectionOptions) {
+  const [connectionStatus, setConnectionStatus] = useState<"disconnected" | "connected" | "error">("disconnected");
+  const [serverCapabilities, setServerCapabilities] = useState<ServerCapabilities | null>(null);
+  const [mcpClient, setMcpClient] = useState<Client | null>(null);
+  const [requestHistory, setRequestHistory] = useState<{ request: string; response?: string }[]>([]);
+ 
+  const pushHistory = (request: object, response?: object) => {
+    setRequestHistory((prev) => [
+      ...prev,
+      {
+        request: JSON.stringify(request),
+        response: response !== undefined ? JSON.stringify(response) : undefined,
+      },
+    ]);
+  };
+ 
+  const makeRequest = async <T extends z.ZodType>(
+    request: ClientRequest,
+    schema: T
+  ) => {
+    if (!mcpClient) {
+      throw new Error("MCP client not connected");
+    }
+ 
+    try {
+      const abortController = new AbortController();
+      const timeoutId = setTimeout(() => {
+        abortController.abort("Request timed out");
+      }, requestTimeout);
+ 
+      let response;
+      try {
+        response = await mcpClient.request(request, schema, {
+          signal: abortController.signal,
+        });
+        pushHistory(request, response);
+      } catch (error) {
+        const errorMessage = error instanceof Error ? error.message : String(error);
+        pushHistory(request, { error: errorMessage });
+        throw error;
+      } finally {
+        clearTimeout(timeoutId);
+      }
+ 
+ 
+      return response;
+    } catch (e: unknown) {
+      const errorString = (e as Error).message ?? String(e);
+      toast.error(errorString);
+ 
+      throw e;
+    }
+  };
+ 
+  const sendNotification = async (notification: ClientNotification) => {
+    if (!mcpClient) {
+      throw new Error("MCP client not connected");
+    }
+ 
+    try {
+      await mcpClient.notification(notification);
+      pushHistory(notification);
+    } catch (e: unknown) {
+      toast.error((e as Error).message ?? String(e));
+      throw e;
+    }
+  };
+ 
+  const connect = async () => {
+    try {
+      const client = new Client<Request, Notification, Result>(
+        {
+          name: "mcp-inspector",
+          version: "0.0.1",
+        },
+        {
+          capabilities: {
+            sampling: {},
+            roots: {
+              listChanged: true,
+            },
+          },
+        },
+      );
+ 
+      const backendUrl = new URL(`${proxyServerUrl}/sse`);
+ 
+      backendUrl.searchParams.append("transportType", transportType);
+      if (transportType === "stdio") {
+        backendUrl.searchParams.append("command", command);
+        backendUrl.searchParams.append("args", args);
+        backendUrl.searchParams.append("env", JSON.stringify(env));
+      } else {
+        backendUrl.searchParams.append("url", sseUrl);
+      }
+ 
+      const clientTransport = new SSEClientTransport(backendUrl);
+      
+      if (onNotification) {
+        client.setNotificationHandler(ProgressNotificationSchema, onNotification);
+      }
+ 
+      if (onStdErrNotification) {
+        client.setNotificationHandler(StdErrNotificationSchema, onStdErrNotification);
+      }
+ 
+      await client.connect(clientTransport);
+ 
+      const capabilities = client.getServerCapabilities();
+      setServerCapabilities(capabilities ?? null);
+ 
+      if (onPendingRequest) {
+        client.setRequestHandler(CreateMessageRequestSchema, (request) => {
+          return new Promise((resolve, reject) => {
+            onPendingRequest(request, resolve, reject);
+          });
+        });
+      }
+ 
+      if (getRoots) {
+        client.setRequestHandler(ListRootsRequestSchema, async () => {
+          return { roots: getRoots() };
+        });
+      }
+ 
+      setMcpClient(client);
+      setConnectionStatus("connected");
+    } catch (e) {
+      console.error(e);
+      setConnectionStatus("error");
+    }
+  };
+ 
+  return {
+    connectionStatus,
+    serverCapabilities,
+    mcpClient,
+    requestHistory,
+    makeRequest,
+    sendNotification,
+    connect
+  };
+}
+ +
+
+ + + + + + + + \ No newline at end of file diff --git a/client/coverage/client/src/lib/hooks/useDraggablePane.ts.html b/client/coverage/client/src/lib/hooks/useDraggablePane.ts.html new file mode 100644 index 0000000000..909259b89b --- /dev/null +++ b/client/coverage/client/src/lib/hooks/useDraggablePane.ts.html @@ -0,0 +1,214 @@ + + + + + + Code coverage report for client/src/lib/hooks/useDraggablePane.ts + + + + + + + + + +
+
+

All files / client/src/lib/hooks useDraggablePane.ts

+
+ +
+ 0% + Statements + 0/38 +
+ + +
+ 0% + Branches + 0/1 +
+ + +
+ 0% + Functions + 0/1 +
+ + +
+ 0% + Lines + 0/38 +
+ + +
+

+ Press n or j to go to the next uncovered block, b, p or k for the previous block. +

+ +
+
+

+
1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 +12 +13 +14 +15 +16 +17 +18 +19 +20 +21 +22 +23 +24 +25 +26 +27 +28 +29 +30 +31 +32 +33 +34 +35 +36 +37 +38 +39 +40 +41 +42 +43 +44  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  + 
import { useCallback, useEffect, useRef, useState } from "react";
+ 
+export function useDraggablePane(initialHeight: number) {
+  const [height, setHeight] = useState(initialHeight);
+  const [isDragging, setIsDragging] = useState(false);
+  const dragStartY = useRef<number>(0);
+  const dragStartHeight = useRef<number>(0);
+ 
+  const handleDragStart = useCallback((e: React.MouseEvent) => {
+    setIsDragging(true);
+    dragStartY.current = e.clientY;
+    dragStartHeight.current = height;
+    document.body.style.userSelect = "none";
+  }, [height]);
+ 
+  const handleDragMove = useCallback((e: MouseEvent) => {
+    if (!isDragging) return;
+    const deltaY = dragStartY.current - e.clientY;
+    const newHeight = Math.max(100, Math.min(800, dragStartHeight.current + deltaY));
+    setHeight(newHeight);
+  }, [isDragging]);
+ 
+  const handleDragEnd = useCallback(() => {
+    setIsDragging(false);
+    document.body.style.userSelect = "";
+  }, []);
+ 
+  useEffect(() => {
+    if (isDragging) {
+      window.addEventListener("mousemove", handleDragMove);
+      window.addEventListener("mouseup", handleDragEnd);
+      return () => {
+        window.removeEventListener("mousemove", handleDragMove);
+        window.removeEventListener("mouseup", handleDragEnd);
+      };
+    }
+  }, [isDragging, handleDragMove, handleDragEnd]);
+ 
+  return {
+    height,
+    isDragging,
+    handleDragStart
+  };
+}
+ +
+
+ + + + + + + + \ No newline at end of file diff --git a/client/coverage/client/src/lib/index.html b/client/coverage/client/src/lib/index.html new file mode 100644 index 0000000000..9f7697b078 --- /dev/null +++ b/client/coverage/client/src/lib/index.html @@ -0,0 +1,146 @@ + + + + + + Code coverage report for client/src/lib + + + + + + + + + +
+
+

All files client/src/lib

+
+ +
+ 61.11% + Statements + 33/54 +
+ + +
+ 66.66% + Branches + 6/9 +
+ + +
+ 60% + Functions + 3/5 +
+ + +
+ 61.11% + Lines + 33/54 +
+ + +
+

+ Press n or j to go to the next uncovered block, b, p or k for the previous block. +

+ +
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FileStatementsBranchesFunctionsLines
notificationTypes.ts +
+
0%0/100%0/10%0/10%0/10
useTheme.ts +
+
72.5%29/4071.42%5/766.66%2/372.5%29/40
utils.ts +
+
100%4/4100%1/1100%1/1100%4/4
+
+
+
+ + + + + + + + \ No newline at end of file diff --git a/client/coverage/client/src/lib/notificationTypes.ts.html b/client/coverage/client/src/lib/notificationTypes.ts.html new file mode 100644 index 0000000000..db007c847e --- /dev/null +++ b/client/coverage/client/src/lib/notificationTypes.ts.html @@ -0,0 +1,142 @@ + + + + + + Code coverage report for client/src/lib/notificationTypes.ts + + + + + + + + + +
+
+

All files / client/src/lib notificationTypes.ts

+
+ +
+ 0% + Statements + 0/10 +
+ + +
+ 0% + Branches + 0/1 +
+ + +
+ 0% + Functions + 0/1 +
+ + +
+ 0% + Lines + 0/10 +
+ + +
+

+ Press n or j to go to the next uncovered block, b, p or k for the previous block. +

+ +
+
+

+
1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 +12 +13 +14 +15 +16 +17 +18 +19 +20  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  + 
import {
+  NotificationSchema as BaseNotificationSchema,
+  ClientNotificationSchema,
+} from "@modelcontextprotocol/sdk/types.js";
+import { z } from "zod";
+ 
+export const StdErrNotificationSchema = BaseNotificationSchema.extend({
+  method: z.literal("notifications/stderr"),
+  params: z.object({
+    content: z.string(),
+  }),
+});
+ 
+export const NotificationSchema = ClientNotificationSchema.or(
+  StdErrNotificationSchema,
+);
+ 
+export type StdErrNotification = z.infer<typeof StdErrNotificationSchema>;
+export type Notification = z.infer<typeof NotificationSchema>;
+ 
+ +
+
+ + + + + + + + \ No newline at end of file diff --git a/client/coverage/client/src/lib/useTheme.ts.html b/client/coverage/client/src/lib/useTheme.ts.html new file mode 100644 index 0000000000..0488baa5b1 --- /dev/null +++ b/client/coverage/client/src/lib/useTheme.ts.html @@ -0,0 +1,238 @@ + + + + + + Code coverage report for client/src/lib/useTheme.ts + + + + + + + + + +
+
+

All files / client/src/lib useTheme.ts

+
+ +
+ 72.5% + Statements + 29/40 +
+ + +
+ 71.42% + Branches + 5/7 +
+ + +
+ 66.66% + Functions + 2/3 +
+ + +
+ 72.5% + Lines + 29/40 +
+ + +
+

+ Press n or j to go to the next uncovered block, b, p or k for the previous block. +

+ +
+
+

+
1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 +12 +13 +14 +15 +16 +17 +18 +19 +20 +21 +22 +23 +24 +25 +26 +27 +28 +29 +30 +31 +32 +33 +34 +35 +36 +37 +38 +39 +40 +41 +42 +43 +44 +45 +46 +47 +48 +49 +50 +51 +521x +  +  +  +1x +16x +7x +7x +16x +  +16x +7x +7x +7x +7x +  +  +  +  +  +7x +7x +7x +  +  +7x +7x +7x +  +  +  +7x +  +7x +7x +7x +16x +  +16x +16x +16x +  +  +  +  +  +16x +16x +16x +  +1x + 
import { useCallback, useEffect, useState } from "react";
+ 
+type Theme = "light" | "dark" | "system";
+ 
+const useTheme = (): [Theme, (mode: Theme) => void] => {
+  const [theme, setTheme] = useState<Theme>(() => {
+    const savedTheme = localStorage.getItem("theme") as Theme;
+    return savedTheme || "system";
+  });
+ 
+  useEffect(() => {
+    const darkModeMediaQuery = window.matchMedia(
+      "(prefers-color-scheme: dark)",
+    );
+    const handleDarkModeChange = (e: MediaQueryListEvent) => {
+      if (theme === "system") {
+        updateDocumentTheme(e.matches ? "dark" : "light");
+      }
+    };
+ 
+    const updateDocumentTheme = (newTheme: "light" | "dark") => {
+      document.documentElement.classList.toggle("dark", newTheme === "dark");
+    };
+ 
+    // Set initial theme based on current mode
+    if (theme === "system") {
+      updateDocumentTheme(darkModeMediaQuery.matches ? "dark" : "light");
+    } else {
+      updateDocumentTheme(theme);
+    }
+ 
+    darkModeMediaQuery.addEventListener("change", handleDarkModeChange);
+ 
+    return () => {
+      darkModeMediaQuery.removeEventListener("change", handleDarkModeChange);
+    };
+  }, [theme]);
+ 
+  return [
+    theme,
+    useCallback((newTheme: Theme) => {
+      setTheme(newTheme);
+      localStorage.setItem("theme", newTheme);
+      if (newTheme !== "system") {
+        document.documentElement.classList.toggle("dark", newTheme === "dark");
+      }
+    }, []),
+  ];
+};
+ 
+export default useTheme;
+ 
+ +
+
+ + + + + + + + \ No newline at end of file diff --git a/client/coverage/client/src/lib/utils.ts.html b/client/coverage/client/src/lib/utils.ts.html new file mode 100644 index 0000000000..a5490646c4 --- /dev/null +++ b/client/coverage/client/src/lib/utils.ts.html @@ -0,0 +1,103 @@ + + + + + + Code coverage report for client/src/lib/utils.ts + + + + + + + + + +
+
+

All files / client/src/lib utils.ts

+
+ +
+ 100% + Statements + 4/4 +
+ + +
+ 100% + Branches + 1/1 +
+ + +
+ 100% + Functions + 1/1 +
+ + +
+ 100% + Lines + 4/4 +
+ + +
+

+ Press n or j to go to the next uncovered block, b, p or k for the previous block. +

+ +
+
+

+
1 +2 +3 +4 +5 +6 +71x +  +  +1x +705x +705x + 
import { clsx, type ClassValue } from "clsx";
+import { twMerge } from "tailwind-merge";
+ 
+export function cn(...inputs: ClassValue[]) {
+  return twMerge(clsx(inputs));
+}
+ 
+ +
+
+ + + + + + + + \ No newline at end of file diff --git a/client/coverage/client/src/main.tsx.html b/client/coverage/client/src/main.tsx.html new file mode 100644 index 0000000000..ecfda5d404 --- /dev/null +++ b/client/coverage/client/src/main.tsx.html @@ -0,0 +1,124 @@ + + + + + + Code coverage report for client/src/main.tsx + + + + + + + + + +
+
+

All files / client/src main.tsx

+
+ +
+ 0% + Statements + 0/12 +
+ + +
+ 0% + Branches + 0/1 +
+ + +
+ 0% + Functions + 0/1 +
+ + +
+ 0% + Lines + 0/12 +
+ + +
+

+ Press n or j to go to the next uncovered block, b, p or k for the previous block. +

+ +
+
+

+
1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 +12 +13 +14  +  +  +  +  +  +  +  +  +  +  +  +  + 
import { StrictMode } from "react";
+import { createRoot } from "react-dom/client";
+import { ToastContainer } from 'react-toastify';
+import 'react-toastify/dist/ReactToastify.css';
+import App from "./App.tsx";
+import "./index.css";
+ 
+createRoot(document.getElementById("root")!).render(
+  <StrictMode>
+    <App />
+    <ToastContainer />
+  </StrictMode>,
+);
+ 
+ +
+
+ + + + + + + + \ No newline at end of file diff --git a/client/coverage/client/tailwind.config.js.html b/client/coverage/client/tailwind.config.js.html new file mode 100644 index 0000000000..387ca4149c --- /dev/null +++ b/client/coverage/client/tailwind.config.js.html @@ -0,0 +1,259 @@ + + + + + + Code coverage report for client/tailwind.config.js + + + + + + + + + +
+
+

All files / client tailwind.config.js

+
+ +
+ 0% + Statements + 0/58 +
+ + +
+ 0% + Branches + 0/1 +
+ + +
+ 0% + Functions + 0/1 +
+ + +
+ 0% + Lines + 0/58 +
+ + +
+

+ Press n or j to go to the next uncovered block, b, p or k for the previous block. +

+ +
+
+

+
1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 +12 +13 +14 +15 +16 +17 +18 +19 +20 +21 +22 +23 +24 +25 +26 +27 +28 +29 +30 +31 +32 +33 +34 +35 +36 +37 +38 +39 +40 +41 +42 +43 +44 +45 +46 +47 +48 +49 +50 +51 +52 +53 +54 +55 +56 +57 +58 +59  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  + 
/** @type {import('tailwindcss').Config} */
+import animate from "tailwindcss-animate";
+export default {
+  darkMode: ["class"],
+  content: ["./index.html", "./src/**/*.{js,ts,jsx,tsx}"],
+  theme: {
+    extend: {
+      borderRadius: {
+        lg: "var(--radius)",
+        md: "calc(var(--radius) - 2px)",
+        sm: "calc(var(--radius) - 4px)",
+      },
+      colors: {
+        background: "hsl(var(--background))",
+        foreground: "hsl(var(--foreground))",
+        card: {
+          DEFAULT: "hsl(var(--card))",
+          foreground: "hsl(var(--card-foreground))",
+        },
+        popover: {
+          DEFAULT: "hsl(var(--popover))",
+          foreground: "hsl(var(--popover-foreground))",
+        },
+        primary: {
+          DEFAULT: "hsl(var(--primary))",
+          foreground: "hsl(var(--primary-foreground))",
+        },
+        secondary: {
+          DEFAULT: "hsl(var(--secondary))",
+          foreground: "hsl(var(--secondary-foreground))",
+        },
+        muted: {
+          DEFAULT: "hsl(var(--muted))",
+          foreground: "hsl(var(--muted-foreground))",
+        },
+        accent: {
+          DEFAULT: "hsl(var(--accent))",
+          foreground: "hsl(var(--accent-foreground))",
+        },
+        destructive: {
+          DEFAULT: "hsl(var(--destructive))",
+          foreground: "hsl(var(--destructive-foreground))",
+        },
+        border: "hsl(var(--border))",
+        input: "hsl(var(--input))",
+        ring: "hsl(var(--ring))",
+        chart: {
+          1: "hsl(var(--chart-1))",
+          2: "hsl(var(--chart-2))",
+          3: "hsl(var(--chart-3))",
+          4: "hsl(var(--chart-4))",
+          5: "hsl(var(--chart-5))",
+        },
+      },
+    },
+  },
+  plugins: [animate],
+};
+ 
+ +
+
+ + + + + + + + \ No newline at end of file diff --git a/client/coverage/clover.xml b/client/coverage/clover.xml new file mode 100644 index 0000000000..5194fe3ba6 --- /dev/null +++ b/client/coverage/clover.xml @@ -0,0 +1,2137 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/client/coverage/coverage-final.json b/client/coverage/coverage-final.json new file mode 100644 index 0000000000..05869d7ef2 --- /dev/null +++ b/client/coverage/coverage-final.json @@ -0,0 +1,28 @@ +{"/Users/ashwin/code/mcp/inspector/client/postcss.config.js": {"path":"/Users/ashwin/code/mcp/inspector/client/postcss.config.js","all":true,"statementMap":{"0":{"start":{"line":1,"column":0},"end":{"line":1,"column":16}},"1":{"start":{"line":2,"column":0},"end":{"line":2,"column":12}},"2":{"start":{"line":3,"column":0},"end":{"line":3,"column":20}},"3":{"start":{"line":4,"column":0},"end":{"line":4,"column":21}},"4":{"start":{"line":5,"column":0},"end":{"line":5,"column":4}},"5":{"start":{"line":6,"column":0},"end":{"line":6,"column":2}}},"s":{"0":0,"1":0,"2":0,"3":0,"4":0,"5":0},"branchMap":{"0":{"type":"branch","line":1,"loc":{"start":{"line":1,"column":0},"end":{"line":6,"column":-11}},"locations":[{"start":{"line":1,"column":0},"end":{"line":6,"column":-11}}]}},"b":{"0":[0]},"fnMap":{"0":{"name":"(empty-report)","decl":{"start":{"line":1,"column":0},"end":{"line":6,"column":-11}},"loc":{"start":{"line":1,"column":0},"end":{"line":6,"column":-11}},"line":1}},"f":{"0":0}} +,"/Users/ashwin/code/mcp/inspector/client/tailwind.config.js": {"path":"/Users/ashwin/code/mcp/inspector/client/tailwind.config.js","all":true,"statementMap":{"0":{"start":{"line":1,"column":0},"end":{"line":1,"column":43}},"1":{"start":{"line":2,"column":0},"end":{"line":2,"column":42}},"2":{"start":{"line":3,"column":0},"end":{"line":3,"column":16}},"3":{"start":{"line":4,"column":0},"end":{"line":4,"column":22}},"4":{"start":{"line":5,"column":0},"end":{"line":5,"column":58}},"5":{"start":{"line":6,"column":0},"end":{"line":6,"column":10}},"6":{"start":{"line":7,"column":0},"end":{"line":7,"column":13}},"7":{"start":{"line":8,"column":0},"end":{"line":8,"column":21}},"8":{"start":{"line":9,"column":0},"end":{"line":9,"column":28}},"9":{"start":{"line":10,"column":0},"end":{"line":10,"column":40}},"10":{"start":{"line":11,"column":0},"end":{"line":11,"column":40}},"11":{"start":{"line":12,"column":0},"end":{"line":12,"column":8}},"12":{"start":{"line":13,"column":0},"end":{"line":13,"column":15}},"13":{"start":{"line":14,"column":0},"end":{"line":14,"column":45}},"14":{"start":{"line":15,"column":0},"end":{"line":15,"column":45}},"15":{"start":{"line":16,"column":0},"end":{"line":16,"column":15}},"16":{"start":{"line":17,"column":0},"end":{"line":17,"column":38}},"17":{"start":{"line":18,"column":0},"end":{"line":18,"column":52}},"18":{"start":{"line":19,"column":0},"end":{"line":19,"column":10}},"19":{"start":{"line":20,"column":0},"end":{"line":20,"column":18}},"20":{"start":{"line":21,"column":0},"end":{"line":21,"column":41}},"21":{"start":{"line":22,"column":0},"end":{"line":22,"column":55}},"22":{"start":{"line":23,"column":0},"end":{"line":23,"column":10}},"23":{"start":{"line":24,"column":0},"end":{"line":24,"column":18}},"24":{"start":{"line":25,"column":0},"end":{"line":25,"column":41}},"25":{"start":{"line":26,"column":0},"end":{"line":26,"column":55}},"26":{"start":{"line":27,"column":0},"end":{"line":27,"column":10}},"27":{"start":{"line":28,"column":0},"end":{"line":28,"column":20}},"28":{"start":{"line":29,"column":0},"end":{"line":29,"column":43}},"29":{"start":{"line":30,"column":0},"end":{"line":30,"column":57}},"30":{"start":{"line":31,"column":0},"end":{"line":31,"column":10}},"31":{"start":{"line":32,"column":0},"end":{"line":32,"column":16}},"32":{"start":{"line":33,"column":0},"end":{"line":33,"column":39}},"33":{"start":{"line":34,"column":0},"end":{"line":34,"column":53}},"34":{"start":{"line":35,"column":0},"end":{"line":35,"column":10}},"35":{"start":{"line":36,"column":0},"end":{"line":36,"column":17}},"36":{"start":{"line":37,"column":0},"end":{"line":37,"column":40}},"37":{"start":{"line":38,"column":0},"end":{"line":38,"column":54}},"38":{"start":{"line":39,"column":0},"end":{"line":39,"column":10}},"39":{"start":{"line":40,"column":0},"end":{"line":40,"column":22}},"40":{"start":{"line":41,"column":0},"end":{"line":41,"column":45}},"41":{"start":{"line":42,"column":0},"end":{"line":42,"column":59}},"42":{"start":{"line":43,"column":0},"end":{"line":43,"column":10}},"43":{"start":{"line":44,"column":0},"end":{"line":44,"column":37}},"44":{"start":{"line":45,"column":0},"end":{"line":45,"column":35}},"45":{"start":{"line":46,"column":0},"end":{"line":46,"column":33}},"46":{"start":{"line":47,"column":0},"end":{"line":47,"column":16}},"47":{"start":{"line":48,"column":0},"end":{"line":48,"column":35}},"48":{"start":{"line":49,"column":0},"end":{"line":49,"column":35}},"49":{"start":{"line":50,"column":0},"end":{"line":50,"column":35}},"50":{"start":{"line":51,"column":0},"end":{"line":51,"column":35}},"51":{"start":{"line":52,"column":0},"end":{"line":52,"column":35}},"52":{"start":{"line":53,"column":0},"end":{"line":53,"column":10}},"53":{"start":{"line":54,"column":0},"end":{"line":54,"column":8}},"54":{"start":{"line":55,"column":0},"end":{"line":55,"column":6}},"55":{"start":{"line":56,"column":0},"end":{"line":56,"column":4}},"56":{"start":{"line":57,"column":0},"end":{"line":57,"column":21}},"57":{"start":{"line":58,"column":0},"end":{"line":58,"column":2}}},"s":{"0":0,"1":0,"2":0,"3":0,"4":0,"5":0,"6":0,"7":0,"8":0,"9":0,"10":0,"11":0,"12":0,"13":0,"14":0,"15":0,"16":0,"17":0,"18":0,"19":0,"20":0,"21":0,"22":0,"23":0,"24":0,"25":0,"26":0,"27":0,"28":0,"29":0,"30":0,"31":0,"32":0,"33":0,"34":0,"35":0,"36":0,"37":0,"38":0,"39":0,"40":0,"41":0,"42":0,"43":0,"44":0,"45":0,"46":0,"47":0,"48":0,"49":0,"50":0,"51":0,"52":0,"53":0,"54":0,"55":0,"56":0,"57":0},"branchMap":{"0":{"type":"branch","line":1,"loc":{"start":{"line":1,"column":0},"end":{"line":58,"column":-82}},"locations":[{"start":{"line":1,"column":0},"end":{"line":58,"column":-82}}]}},"b":{"0":[0]},"fnMap":{"0":{"name":"(empty-report)","decl":{"start":{"line":1,"column":0},"end":{"line":58,"column":-82}},"loc":{"start":{"line":1,"column":0},"end":{"line":58,"column":-82}},"line":1}},"f":{"0":0}} +,"/Users/ashwin/code/mcp/inspector/client/bin/cli.js": {"path":"/Users/ashwin/code/mcp/inspector/client/bin/cli.js","all":true,"statementMap":{"0":{"start":{"line":1,"column":0},"end":{"line":1,"column":19}},"1":{"start":{"line":2,"column":0},"end":{"line":2,"column":0}},"2":{"start":{"line":3,"column":0},"end":{"line":3,"column":37}},"3":{"start":{"line":4,"column":0},"end":{"line":4,"column":36}},"4":{"start":{"line":5,"column":0},"end":{"line":5,"column":36}},"5":{"start":{"line":6,"column":0},"end":{"line":6,"column":24}},"6":{"start":{"line":7,"column":0},"end":{"line":7,"column":0}},"7":{"start":{"line":8,"column":0},"end":{"line":8,"column":58}},"8":{"start":{"line":9,"column":0},"end":{"line":9,"column":44}},"9":{"start":{"line":10,"column":0},"end":{"line":10,"column":0}},"10":{"start":{"line":11,"column":0},"end":{"line":11,"column":57}},"11":{"start":{"line":12,"column":0},"end":{"line":12,"column":58}},"12":{"start":{"line":13,"column":0},"end":{"line":13,"column":3}},"13":{"start":{"line":14,"column":0},"end":{"line":14,"column":0}},"14":{"start":{"line":15,"column":0},"end":{"line":15,"column":38}},"15":{"start":{"line":16,"column":0},"end":{"line":16,"column":30}}},"s":{"0":0,"1":0,"2":0,"3":0,"4":0,"5":0,"6":0,"7":0,"8":0,"9":0,"10":0,"11":0,"12":0,"13":0,"14":0,"15":0},"branchMap":{"0":{"type":"branch","line":1,"loc":{"start":{"line":1,"column":0},"end":{"line":16,"column":-241}},"locations":[{"start":{"line":1,"column":0},"end":{"line":16,"column":-241}}]}},"b":{"0":[0]},"fnMap":{"0":{"name":"(empty-report)","decl":{"start":{"line":1,"column":0},"end":{"line":16,"column":-241}},"loc":{"start":{"line":1,"column":0},"end":{"line":16,"column":-241}},"line":1}},"f":{"0":0}} +,"/Users/ashwin/code/mcp/inspector/client/src/App.tsx": {"path":"/Users/ashwin/code/mcp/inspector/client/src/App.tsx","all":false,"statementMap":{"0":{"start":{"line":1,"column":0},"end":{"line":1,"column":64}},"1":{"start":{"line":2,"column":0},"end":{"line":2,"column":58}},"19":{"start":{"line":20,"column":0},"end":{"line":20,"column":44}},"20":{"start":{"line":21,"column":0},"end":{"line":21,"column":52}},"24":{"start":{"line":25,"column":0},"end":{"line":25,"column":67}},"32":{"start":{"line":33,"column":0},"end":{"line":33,"column":22}},"35":{"start":{"line":36,"column":0},"end":{"line":36,"column":19}},"36":{"start":{"line":37,"column":0},"end":{"line":37,"column":49}},"37":{"start":{"line":38,"column":0},"end":{"line":38,"column":59}},"38":{"start":{"line":39,"column":0},"end":{"line":39,"column":43}},"39":{"start":{"line":40,"column":0},"end":{"line":40,"column":61}},"40":{"start":{"line":41,"column":0},"end":{"line":41,"column":53}},"41":{"start":{"line":42,"column":0},"end":{"line":42,"column":45}},"42":{"start":{"line":43,"column":0},"end":{"line":43,"column":71}},"43":{"start":{"line":44,"column":0},"end":{"line":44,"column":43}},"44":{"start":{"line":45,"column":0},"end":{"line":45,"column":45}},"46":{"start":{"line":47,"column":0},"end":{"line":47,"column":59}},"47":{"start":{"line":48,"column":0},"end":{"line":48,"column":53}},"48":{"start":{"line":49,"column":0},"end":{"line":49,"column":58}},"50":{"start":{"line":51,"column":0},"end":{"line":51,"column":19}},"51":{"start":{"line":52,"column":0},"end":{"line":52,"column":61}},"52":{"start":{"line":53,"column":0},"end":{"line":53,"column":61}},"54":{"start":{"line":55,"column":0},"end":{"line":55,"column":8}},"55":{"start":{"line":56,"column":0},"end":{"line":56,"column":69}},"56":{"start":{"line":57,"column":0},"end":{"line":57,"column":55}},"57":{"start":{"line":58,"column":0},"end":{"line":58,"column":65}},"58":{"start":{"line":59,"column":0},"end":{"line":59,"column":49}},"59":{"start":{"line":60,"column":0},"end":{"line":60,"column":37}},"60":{"start":{"line":61,"column":0},"end":{"line":61,"column":55}},"61":{"start":{"line":62,"column":0},"end":{"line":62,"column":71}},"62":{"start":{"line":63,"column":0},"end":{"line":63,"column":20}},"63":{"start":{"line":64,"column":0},"end":{"line":64,"column":18}},"64":{"start":{"line":65,"column":0},"end":{"line":65,"column":16}},"65":{"start":{"line":66,"column":0},"end":{"line":66,"column":5}},"66":{"start":{"line":67,"column":0},"end":{"line":67,"column":56}},"67":{"start":{"line":68,"column":0},"end":{"line":68,"column":74}},"68":{"start":{"line":69,"column":0},"end":{"line":69,"column":5}},"69":{"start":{"line":70,"column":0},"end":{"line":70,"column":50}},"70":{"start":{"line":71,"column":0},"end":{"line":71,"column":50}},"71":{"start":{"line":72,"column":0},"end":{"line":72,"column":5}},"73":{"start":{"line":74,"column":0},"end":{"line":74,"column":76}},"74":{"start":{"line":75,"column":0},"end":{"line":75,"column":79}},"75":{"start":{"line":76,"column":0},"end":{"line":76,"column":79}},"76":{"start":{"line":77,"column":0},"end":{"line":77,"column":65}},"78":{"start":{"line":79,"column":0},"end":{"line":79,"column":8}},"79":{"start":{"line":80,"column":0},"end":{"line":80,"column":49}},"80":{"start":{"line":81,"column":0},"end":{"line":81,"column":61}},"82":{"start":{"line":83,"column":0},"end":{"line":83,"column":69}},"89":{"start":{"line":90,"column":0},"end":{"line":90,"column":8}},"90":{"start":{"line":91,"column":0},"end":{"line":91,"column":34}},"91":{"start":{"line":92,"column":0},"end":{"line":92,"column":38}},"93":{"start":{"line":94,"column":0},"end":{"line":94,"column":78}},"94":{"start":{"line":95,"column":0},"end":{"line":95,"column":40}},"95":{"start":{"line":96,"column":0},"end":{"line":96,"column":52}},"96":{"start":{"line":97,"column":0},"end":{"line":97,"column":31}},"97":{"start":{"line":98,"column":0},"end":{"line":98,"column":45}},"98":{"start":{"line":99,"column":0},"end":{"line":99,"column":7}},"99":{"start":{"line":100,"column":0},"end":{"line":100,"column":4}},"101":{"start":{"line":102,"column":0},"end":{"line":102,"column":48}},"102":{"start":{"line":103,"column":0},"end":{"line":103,"column":40}},"103":{"start":{"line":104,"column":0},"end":{"line":104,"column":52}},"104":{"start":{"line":105,"column":0},"end":{"line":105,"column":62}},"105":{"start":{"line":106,"column":0},"end":{"line":106,"column":45}},"106":{"start":{"line":107,"column":0},"end":{"line":107,"column":7}},"107":{"start":{"line":108,"column":0},"end":{"line":108,"column":4}},"109":{"start":{"line":110,"column":0},"end":{"line":110,"column":76}},"110":{"start":{"line":111,"column":0},"end":{"line":111,"column":9}},"111":{"start":{"line":112,"column":0},"end":{"line":112,"column":4}},"112":{"start":{"line":113,"column":0},"end":{"line":113,"column":76}},"113":{"start":{"line":114,"column":0},"end":{"line":114,"column":70}},"114":{"start":{"line":115,"column":0},"end":{"line":115,"column":63}},"116":{"start":{"line":117,"column":0},"end":{"line":117,"column":6}},"117":{"start":{"line":118,"column":0},"end":{"line":118,"column":79}},"119":{"start":{"line":120,"column":0},"end":{"line":120,"column":6}},"120":{"start":{"line":121,"column":0},"end":{"line":121,"column":59}},"122":{"start":{"line":123,"column":0},"end":{"line":123,"column":6}},"123":{"start":{"line":124,"column":0},"end":{"line":124,"column":77}},"124":{"start":{"line":125,"column":0},"end":{"line":125,"column":37}},"126":{"start":{"line":127,"column":0},"end":{"line":127,"column":9}},"127":{"start":{"line":128,"column":0},"end":{"line":128,"column":30}},"128":{"start":{"line":129,"column":0},"end":{"line":129,"column":19}},"129":{"start":{"line":130,"column":0},"end":{"line":130,"column":28}},"131":{"start":{"line":132,"column":0},"end":{"line":132,"column":9}},"132":{"start":{"line":133,"column":0},"end":{"line":133,"column":21}},"133":{"start":{"line":134,"column":0},"end":{"line":134,"column":23}},"134":{"start":{"line":135,"column":0},"end":{"line":135,"column":14}},"135":{"start":{"line":136,"column":0},"end":{"line":136,"column":19}},"136":{"start":{"line":137,"column":0},"end":{"line":137,"column":39}},"137":{"start":{"line":138,"column":0},"end":{"line":138,"column":21}},"138":{"start":{"line":139,"column":0},"end":{"line":139,"column":29}},"139":{"start":{"line":140,"column":0},"end":{"line":140,"column":21}},"140":{"start":{"line":141,"column":0},"end":{"line":141,"column":18}},"141":{"start":{"line":142,"column":0},"end":{"line":142,"column":12}},"142":{"start":{"line":143,"column":0},"end":{"line":143,"column":9}},"143":{"start":{"line":144,"column":0},"end":{"line":144,"column":11}},"144":{"start":{"line":145,"column":0},"end":{"line":145,"column":8}},"145":{"start":{"line":146,"column":0},"end":{"line":146,"column":37}},"146":{"start":{"line":147,"column":0},"end":{"line":147,"column":39}},"147":{"start":{"line":148,"column":0},"end":{"line":148,"column":78}},"148":{"start":{"line":149,"column":0},"end":{"line":149,"column":6}},"149":{"start":{"line":150,"column":0},"end":{"line":150,"column":45}},"150":{"start":{"line":151,"column":0},"end":{"line":151,"column":84}},"151":{"start":{"line":152,"column":0},"end":{"line":152,"column":6}},"152":{"start":{"line":153,"column":0},"end":{"line":153,"column":53}},"153":{"start":{"line":154,"column":0},"end":{"line":154,"column":40}},"154":{"start":{"line":155,"column":0},"end":{"line":155,"column":16}},"155":{"start":{"line":156,"column":0},"end":{"line":156,"column":65}},"156":{"start":{"line":157,"column":0},"end":{"line":157,"column":9}},"157":{"start":{"line":158,"column":0},"end":{"line":158,"column":6}},"158":{"start":{"line":159,"column":0},"end":{"line":159,"column":36}},"159":{"start":{"line":160,"column":0},"end":{"line":160,"column":5}},"161":{"start":{"line":162,"column":0},"end":{"line":162,"column":50}},"162":{"start":{"line":163,"column":0},"end":{"line":163,"column":27}},"163":{"start":{"line":164,"column":0},"end":{"line":164,"column":14}},"164":{"start":{"line":165,"column":0},"end":{"line":165,"column":33}},"165":{"start":{"line":166,"column":0},"end":{"line":166,"column":8}},"166":{"start":{"line":167,"column":0},"end":{"line":167,"column":9}},"167":{"start":{"line":168,"column":0},"end":{"line":168,"column":68}},"168":{"start":{"line":169,"column":0},"end":{"line":169,"column":33}},"169":{"start":{"line":170,"column":0},"end":{"line":170,"column":27}},"170":{"start":{"line":171,"column":0},"end":{"line":171,"column":7}},"171":{"start":{"line":172,"column":0},"end":{"line":172,"column":22}},"172":{"start":{"line":173,"column":0},"end":{"line":173,"column":17}},"173":{"start":{"line":174,"column":0},"end":{"line":174,"column":60}},"174":{"start":{"line":175,"column":0},"end":{"line":175,"column":33}},"175":{"start":{"line":176,"column":0},"end":{"line":176,"column":30}},"176":{"start":{"line":177,"column":0},"end":{"line":177,"column":18}},"177":{"start":{"line":178,"column":0},"end":{"line":178,"column":32}},"178":{"start":{"line":179,"column":0},"end":{"line":179,"column":12}},"179":{"start":{"line":180,"column":0},"end":{"line":180,"column":7}},"180":{"start":{"line":181,"column":0},"end":{"line":181,"column":14}},"181":{"start":{"line":182,"column":0},"end":{"line":182,"column":5}},"182":{"start":{"line":183,"column":0},"end":{"line":183,"column":4}},"184":{"start":{"line":185,"column":0},"end":{"line":185,"column":19}},"185":{"start":{"line":186,"column":0},"end":{"line":186,"column":49}},"186":{"start":{"line":187,"column":0},"end":{"line":187,"column":16}},"188":{"start":{"line":189,"column":0},"end":{"line":189,"column":19}},"189":{"start":{"line":190,"column":0},"end":{"line":190,"column":43}},"190":{"start":{"line":191,"column":0},"end":{"line":191,"column":13}},"192":{"start":{"line":193,"column":0},"end":{"line":193,"column":19}},"193":{"start":{"line":194,"column":0},"end":{"line":194,"column":39}},"194":{"start":{"line":195,"column":0},"end":{"line":195,"column":42}},"195":{"start":{"line":196,"column":0},"end":{"line":196,"column":23}},"196":{"start":{"line":197,"column":0},"end":{"line":197,"column":40}},"197":{"start":{"line":198,"column":0},"end":{"line":198,"column":34}},"198":{"start":{"line":199,"column":0},"end":{"line":199,"column":42}},"199":{"start":{"line":200,"column":0},"end":{"line":200,"column":9}},"200":{"start":{"line":201,"column":0},"end":{"line":201,"column":31}},"201":{"start":{"line":202,"column":0},"end":{"line":202,"column":36}},"202":{"start":{"line":203,"column":0},"end":{"line":203,"column":9}},"203":{"start":{"line":204,"column":0},"end":{"line":204,"column":8}},"204":{"start":{"line":205,"column":0},"end":{"line":205,"column":23}},"205":{"start":{"line":206,"column":0},"end":{"line":206,"column":68}},"206":{"start":{"line":207,"column":0},"end":{"line":207,"column":8}},"207":{"start":{"line":208,"column":0},"end":{"line":208,"column":9}},"209":{"start":{"line":210,"column":0},"end":{"line":210,"column":19}},"210":{"start":{"line":211,"column":0},"end":{"line":211,"column":29}},"211":{"start":{"line":212,"column":0},"end":{"line":212,"column":14}},"213":{"start":{"line":214,"column":0},"end":{"line":214,"column":19}},"214":{"start":{"line":215,"column":0},"end":{"line":215,"column":32}},"215":{"start":{"line":216,"column":0},"end":{"line":216,"column":41}},"216":{"start":{"line":217,"column":0},"end":{"line":217,"column":5}},"217":{"start":{"line":218,"column":0},"end":{"line":218,"column":9}},"219":{"start":{"line":220,"column":0},"end":{"line":220,"column":55}},"220":{"start":{"line":221,"column":0},"end":{"line":221,"column":55}},"221":{"start":{"line":222,"column":0},"end":{"line":222,"column":4}},"223":{"start":{"line":224,"column":0},"end":{"line":224,"column":37}},"224":{"start":{"line":225,"column":0},"end":{"line":225,"column":39}},"225":{"start":{"line":226,"column":0},"end":{"line":226,"column":7}},"226":{"start":{"line":227,"column":0},"end":{"line":227,"column":42}},"227":{"start":{"line":228,"column":0},"end":{"line":228,"column":73}},"228":{"start":{"line":229,"column":0},"end":{"line":229,"column":8}},"229":{"start":{"line":230,"column":0},"end":{"line":230,"column":32}},"230":{"start":{"line":231,"column":0},"end":{"line":231,"column":18}},"231":{"start":{"line":232,"column":0},"end":{"line":232,"column":6}},"232":{"start":{"line":233,"column":0},"end":{"line":233,"column":61}},"233":{"start":{"line":234,"column":0},"end":{"line":234,"column":47}},"234":{"start":{"line":235,"column":0},"end":{"line":235,"column":4}},"236":{"start":{"line":237,"column":0},"end":{"line":237,"column":45}},"237":{"start":{"line":238,"column":0},"end":{"line":238,"column":39}},"238":{"start":{"line":239,"column":0},"end":{"line":239,"column":7}},"239":{"start":{"line":240,"column":0},"end":{"line":240,"column":52}},"240":{"start":{"line":241,"column":0},"end":{"line":241,"column":42}},"241":{"start":{"line":242,"column":0},"end":{"line":242,"column":50}},"242":{"start":{"line":243,"column":0},"end":{"line":243,"column":15}},"243":{"start":{"line":244,"column":0},"end":{"line":244,"column":8}},"244":{"start":{"line":245,"column":0},"end":{"line":245,"column":40}},"245":{"start":{"line":246,"column":0},"end":{"line":246,"column":18}},"246":{"start":{"line":247,"column":0},"end":{"line":247,"column":6}},"247":{"start":{"line":248,"column":0},"end":{"line":248,"column":25}},"248":{"start":{"line":249,"column":0},"end":{"line":249,"column":65}},"249":{"start":{"line":250,"column":0},"end":{"line":250,"column":6}},"250":{"start":{"line":251,"column":0},"end":{"line":251,"column":55}},"251":{"start":{"line":252,"column":0},"end":{"line":252,"column":4}},"253":{"start":{"line":254,"column":0},"end":{"line":254,"column":47}},"254":{"start":{"line":255,"column":0},"end":{"line":255,"column":39}},"255":{"start":{"line":256,"column":0},"end":{"line":256,"column":7}},"256":{"start":{"line":257,"column":0},"end":{"line":257,"column":42}},"257":{"start":{"line":258,"column":0},"end":{"line":258,"column":24}},"258":{"start":{"line":259,"column":0},"end":{"line":259,"column":8}},"259":{"start":{"line":260,"column":0},"end":{"line":260,"column":31}},"260":{"start":{"line":261,"column":0},"end":{"line":261,"column":18}},"261":{"start":{"line":262,"column":0},"end":{"line":262,"column":6}},"262":{"start":{"line":263,"column":0},"end":{"line":263,"column":58}},"263":{"start":{"line":264,"column":0},"end":{"line":264,"column":4}},"265":{"start":{"line":266,"column":0},"end":{"line":266,"column":35}},"266":{"start":{"line":267,"column":0},"end":{"line":267,"column":39}},"267":{"start":{"line":268,"column":0},"end":{"line":268,"column":7}},"268":{"start":{"line":269,"column":0},"end":{"line":269,"column":40}},"269":{"start":{"line":270,"column":0},"end":{"line":270,"column":69}},"270":{"start":{"line":271,"column":0},"end":{"line":271,"column":8}},"271":{"start":{"line":272,"column":0},"end":{"line":272,"column":30}},"272":{"start":{"line":273,"column":0},"end":{"line":273,"column":16}},"273":{"start":{"line":274,"column":0},"end":{"line":274,"column":6}},"274":{"start":{"line":275,"column":0},"end":{"line":275,"column":33}},"275":{"start":{"line":276,"column":0},"end":{"line":276,"column":45}},"276":{"start":{"line":277,"column":0},"end":{"line":277,"column":4}},"278":{"start":{"line":279,"column":0},"end":{"line":279,"column":80}},"279":{"start":{"line":280,"column":0},"end":{"line":280,"column":39}},"280":{"start":{"line":281,"column":0},"end":{"line":281,"column":7}},"281":{"start":{"line":282,"column":0},"end":{"line":282,"column":39}},"282":{"start":{"line":283,"column":0},"end":{"line":283,"column":42}},"283":{"start":{"line":284,"column":0},"end":{"line":284,"column":8}},"284":{"start":{"line":285,"column":0},"end":{"line":285,"column":28}},"285":{"start":{"line":286,"column":0},"end":{"line":286,"column":16}},"286":{"start":{"line":287,"column":0},"end":{"line":287,"column":6}},"287":{"start":{"line":288,"column":0},"end":{"line":288,"column":56}},"288":{"start":{"line":289,"column":0},"end":{"line":289,"column":4}},"290":{"start":{"line":291,"column":0},"end":{"line":291,"column":33}},"291":{"start":{"line":292,"column":0},"end":{"line":292,"column":39}},"292":{"start":{"line":293,"column":0},"end":{"line":293,"column":7}},"293":{"start":{"line":294,"column":0},"end":{"line":294,"column":38}},"294":{"start":{"line":295,"column":0},"end":{"line":295,"column":65}},"295":{"start":{"line":296,"column":0},"end":{"line":296,"column":8}},"296":{"start":{"line":297,"column":0},"end":{"line":297,"column":28}},"297":{"start":{"line":298,"column":0},"end":{"line":298,"column":14}},"298":{"start":{"line":299,"column":0},"end":{"line":299,"column":6}},"299":{"start":{"line":300,"column":0},"end":{"line":300,"column":29}},"300":{"start":{"line":301,"column":0},"end":{"line":301,"column":43}},"301":{"start":{"line":302,"column":0},"end":{"line":302,"column":4}},"303":{"start":{"line":304,"column":0},"end":{"line":304,"column":77}},"304":{"start":{"line":305,"column":0},"end":{"line":305,"column":39}},"305":{"start":{"line":306,"column":0},"end":{"line":306,"column":7}},"306":{"start":{"line":307,"column":0},"end":{"line":307,"column":38}},"307":{"start":{"line":308,"column":0},"end":{"line":308,"column":17}},"308":{"start":{"line":309,"column":0},"end":{"line":309,"column":15}},"309":{"start":{"line":310,"column":0},"end":{"line":310,"column":28}},"310":{"start":{"line":311,"column":0},"end":{"line":311,"column":18}},"311":{"start":{"line":312,"column":0},"end":{"line":312,"column":54}},"312":{"start":{"line":313,"column":0},"end":{"line":313,"column":12}},"313":{"start":{"line":314,"column":0},"end":{"line":314,"column":10}},"314":{"start":{"line":315,"column":0},"end":{"line":315,"column":8}},"315":{"start":{"line":316,"column":0},"end":{"line":316,"column":40}},"316":{"start":{"line":317,"column":0},"end":{"line":317,"column":14}},"317":{"start":{"line":318,"column":0},"end":{"line":318,"column":6}},"318":{"start":{"line":319,"column":0},"end":{"line":319,"column":28}},"319":{"start":{"line":320,"column":0},"end":{"line":320,"column":4}},"321":{"start":{"line":322,"column":0},"end":{"line":322,"column":41}},"322":{"start":{"line":323,"column":0},"end":{"line":323,"column":75}},"323":{"start":{"line":324,"column":0},"end":{"line":324,"column":4}},"325":{"start":{"line":326,"column":0},"end":{"line":326,"column":10}},"326":{"start":{"line":327,"column":0},"end":{"line":327,"column":49}},"327":{"start":{"line":328,"column":0},"end":{"line":328,"column":14}},"328":{"start":{"line":329,"column":0},"end":{"line":329,"column":43}},"329":{"start":{"line":330,"column":0},"end":{"line":330,"column":37}},"330":{"start":{"line":331,"column":0},"end":{"line":331,"column":43}},"331":{"start":{"line":332,"column":0},"end":{"line":332,"column":25}},"332":{"start":{"line":333,"column":0},"end":{"line":333,"column":31}},"333":{"start":{"line":334,"column":0},"end":{"line":334,"column":19}},"334":{"start":{"line":335,"column":0},"end":{"line":335,"column":25}},"335":{"start":{"line":336,"column":0},"end":{"line":336,"column":23}},"336":{"start":{"line":337,"column":0},"end":{"line":337,"column":29}},"337":{"start":{"line":338,"column":0},"end":{"line":338,"column":17}},"338":{"start":{"line":339,"column":0},"end":{"line":339,"column":23}},"339":{"start":{"line":340,"column":0},"end":{"line":340,"column":36}},"340":{"start":{"line":341,"column":0},"end":{"line":341,"column":49}},"341":{"start":{"line":342,"column":0},"end":{"line":342,"column":8}},"342":{"start":{"line":343,"column":0},"end":{"line":343,"column":60}},"343":{"start":{"line":344,"column":0},"end":{"line":344,"column":46}},"344":{"start":{"line":345,"column":0},"end":{"line":345,"column":24}},"345":{"start":{"line":346,"column":0},"end":{"line":346,"column":17}},"346":{"start":{"line":347,"column":0},"end":{"line":347,"column":28}},"347":{"start":{"line":348,"column":0},"end":{"line":348,"column":95}},"348":{"start":{"line":349,"column":0},"end":{"line":349,"column":47}},"349":{"start":{"line":350,"column":0},"end":{"line":350,"column":61}},"350":{"start":{"line":351,"column":0},"end":{"line":351,"column":57}},"351":{"start":{"line":352,"column":0},"end":{"line":352,"column":53}},"352":{"start":{"line":353,"column":0},"end":{"line":353,"column":22}},"354":{"start":{"line":355,"column":0},"end":{"line":355,"column":36}},"355":{"start":{"line":356,"column":0},"end":{"line":356,"column":71}},"357":{"start":{"line":358,"column":0},"end":{"line":358,"column":45}},"358":{"start":{"line":359,"column":0},"end":{"line":359,"column":89}},"359":{"start":{"line":360,"column":0},"end":{"line":360,"column":52}},"361":{"start":{"line":362,"column":0},"end":{"line":362,"column":30}},"362":{"start":{"line":363,"column":0},"end":{"line":363,"column":85}},"363":{"start":{"line":364,"column":0},"end":{"line":364,"column":60}},"365":{"start":{"line":366,"column":0},"end":{"line":366,"column":30}},"366":{"start":{"line":367,"column":0},"end":{"line":367,"column":81}},"367":{"start":{"line":368,"column":0},"end":{"line":368,"column":53}},"369":{"start":{"line":370,"column":0},"end":{"line":370,"column":30}},"370":{"start":{"line":371,"column":0},"end":{"line":371,"column":42}},"371":{"start":{"line":372,"column":0},"end":{"line":372,"column":51}},"373":{"start":{"line":374,"column":0},"end":{"line":374,"column":30}},"374":{"start":{"line":375,"column":0},"end":{"line":375,"column":67}},"375":{"start":{"line":376,"column":0},"end":{"line":376,"column":51}},"377":{"start":{"line":378,"column":0},"end":{"line":378,"column":56}},"378":{"start":{"line":379,"column":0},"end":{"line":379,"column":147}},"379":{"start":{"line":380,"column":0},"end":{"line":380,"column":52}},"380":{"start":{"line":381,"column":0},"end":{"line":381,"column":27}},"382":{"start":{"line":383,"column":0},"end":{"line":383,"column":30}},"383":{"start":{"line":384,"column":0},"end":{"line":384,"column":43}},"384":{"start":{"line":385,"column":0},"end":{"line":385,"column":57}},"386":{"start":{"line":387,"column":0},"end":{"line":387,"column":30}},"387":{"start":{"line":388,"column":0},"end":{"line":388,"column":25}},"389":{"start":{"line":390,"column":0},"end":{"line":390,"column":38}},"390":{"start":{"line":391,"column":0},"end":{"line":391,"column":113}},"391":{"start":{"line":392,"column":0},"end":{"line":392,"column":72}},"392":{"start":{"line":393,"column":0},"end":{"line":393,"column":57}},"394":{"start":{"line":395,"column":0},"end":{"line":395,"column":24}},"395":{"start":{"line":396,"column":0},"end":{"line":396,"column":24}},"397":{"start":{"line":398,"column":0},"end":{"line":398,"column":20}},"398":{"start":{"line":399,"column":0},"end":{"line":399,"column":33}},"399":{"start":{"line":400,"column":0},"end":{"line":400,"column":43}},"400":{"start":{"line":401,"column":0},"end":{"line":401,"column":59}},"401":{"start":{"line":402,"column":0},"end":{"line":402,"column":44}},"402":{"start":{"line":403,"column":0},"end":{"line":403,"column":48}},"403":{"start":{"line":404,"column":0},"end":{"line":404,"column":40}},"404":{"start":{"line":405,"column":0},"end":{"line":405,"column":24}},"405":{"start":{"line":406,"column":0},"end":{"line":406,"column":45}},"406":{"start":{"line":407,"column":0},"end":{"line":407,"column":41}},"407":{"start":{"line":408,"column":0},"end":{"line":408,"column":57}},"408":{"start":{"line":409,"column":0},"end":{"line":409,"column":24}},"409":{"start":{"line":410,"column":0},"end":{"line":410,"column":52}},"410":{"start":{"line":411,"column":0},"end":{"line":411,"column":48}},"411":{"start":{"line":412,"column":0},"end":{"line":412,"column":48}},"412":{"start":{"line":413,"column":0},"end":{"line":413,"column":24}},"413":{"start":{"line":414,"column":0},"end":{"line":414,"column":53}},"414":{"start":{"line":415,"column":0},"end":{"line":415,"column":49}},"415":{"start":{"line":416,"column":0},"end":{"line":416,"column":65}},"416":{"start":{"line":417,"column":0},"end":{"line":417,"column":24}},"417":{"start":{"line":418,"column":0},"end":{"line":418,"column":46}},"418":{"start":{"line":419,"column":0},"end":{"line":419,"column":48}},"419":{"start":{"line":420,"column":0},"end":{"line":420,"column":42}},"420":{"start":{"line":421,"column":0},"end":{"line":421,"column":24}},"421":{"start":{"line":422,"column":0},"end":{"line":422,"column":57}},"422":{"start":{"line":423,"column":0},"end":{"line":423,"column":58}},"423":{"start":{"line":424,"column":0},"end":{"line":424,"column":48}},"424":{"start":{"line":425,"column":0},"end":{"line":425,"column":54}},"425":{"start":{"line":426,"column":0},"end":{"line":426,"column":24}},"426":{"start":{"line":427,"column":0},"end":{"line":427,"column":55}},"427":{"start":{"line":428,"column":0},"end":{"line":428,"column":53}},"428":{"start":{"line":429,"column":0},"end":{"line":429,"column":69}},"429":{"start":{"line":430,"column":0},"end":{"line":430,"column":46}},"430":{"start":{"line":431,"column":0},"end":{"line":431,"column":22}},"431":{"start":{"line":432,"column":0},"end":{"line":432,"column":31}},"432":{"start":{"line":433,"column":0},"end":{"line":433,"column":39}},"433":{"start":{"line":434,"column":0},"end":{"line":434,"column":42}},"434":{"start":{"line":435,"column":0},"end":{"line":435,"column":46}},"435":{"start":{"line":436,"column":0},"end":{"line":436,"column":38}},"436":{"start":{"line":437,"column":0},"end":{"line":437,"column":24}},"437":{"start":{"line":438,"column":0},"end":{"line":438,"column":43}},"438":{"start":{"line":439,"column":0},"end":{"line":439,"column":39}},"439":{"start":{"line":440,"column":0},"end":{"line":440,"column":55}},"440":{"start":{"line":441,"column":0},"end":{"line":441,"column":24}},"441":{"start":{"line":442,"column":0},"end":{"line":442,"column":50}},"442":{"start":{"line":443,"column":0},"end":{"line":443,"column":46}},"443":{"start":{"line":444,"column":0},"end":{"line":444,"column":46}},"444":{"start":{"line":445,"column":0},"end":{"line":445,"column":24}},"445":{"start":{"line":446,"column":0},"end":{"line":446,"column":53}},"446":{"start":{"line":447,"column":0},"end":{"line":447,"column":54}},"447":{"start":{"line":448,"column":0},"end":{"line":448,"column":46}},"448":{"start":{"line":449,"column":0},"end":{"line":449,"column":50}},"449":{"start":{"line":450,"column":0},"end":{"line":450,"column":24}},"450":{"start":{"line":451,"column":0},"end":{"line":451,"column":51}},"451":{"start":{"line":452,"column":0},"end":{"line":452,"column":51}},"452":{"start":{"line":453,"column":0},"end":{"line":453,"column":44}},"453":{"start":{"line":454,"column":0},"end":{"line":454,"column":22}},"454":{"start":{"line":455,"column":0},"end":{"line":455,"column":29}},"455":{"start":{"line":456,"column":0},"end":{"line":456,"column":35}},"456":{"start":{"line":457,"column":0},"end":{"line":457,"column":40}},"457":{"start":{"line":458,"column":0},"end":{"line":458,"column":44}},"458":{"start":{"line":459,"column":0},"end":{"line":459,"column":36}},"459":{"start":{"line":460,"column":0},"end":{"line":460,"column":24}},"460":{"start":{"line":461,"column":0},"end":{"line":461,"column":41}},"461":{"start":{"line":462,"column":0},"end":{"line":462,"column":37}},"462":{"start":{"line":463,"column":0},"end":{"line":463,"column":53}},"463":{"start":{"line":464,"column":0},"end":{"line":464,"column":24}},"464":{"start":{"line":465,"column":0},"end":{"line":465,"column":51}},"465":{"start":{"line":466,"column":0},"end":{"line":466,"column":44}},"466":{"start":{"line":467,"column":0},"end":{"line":467,"column":47}},"467":{"start":{"line":468,"column":0},"end":{"line":468,"column":24}},"468":{"start":{"line":469,"column":0},"end":{"line":469,"column":49}},"469":{"start":{"line":470,"column":0},"end":{"line":470,"column":50}},"470":{"start":{"line":471,"column":0},"end":{"line":471,"column":44}},"471":{"start":{"line":472,"column":0},"end":{"line":472,"column":46}},"472":{"start":{"line":473,"column":0},"end":{"line":473,"column":44}},"473":{"start":{"line":474,"column":0},"end":{"line":474,"column":24}},"474":{"start":{"line":475,"column":0},"end":{"line":475,"column":45}},"475":{"start":{"line":476,"column":0},"end":{"line":476,"column":49}},"476":{"start":{"line":477,"column":0},"end":{"line":477,"column":42}},"477":{"start":{"line":478,"column":0},"end":{"line":478,"column":22}},"478":{"start":{"line":479,"column":0},"end":{"line":479,"column":34}},"479":{"start":{"line":480,"column":0},"end":{"line":480,"column":28}},"480":{"start":{"line":481,"column":0},"end":{"line":481,"column":42}},"481":{"start":{"line":482,"column":0},"end":{"line":482,"column":41}},"482":{"start":{"line":483,"column":0},"end":{"line":483,"column":27}},"483":{"start":{"line":484,"column":0},"end":{"line":484,"column":52}},"484":{"start":{"line":485,"column":0},"end":{"line":485,"column":28}},"485":{"start":{"line":486,"column":0},"end":{"line":486,"column":44}},"486":{"start":{"line":487,"column":0},"end":{"line":487,"column":26}},"487":{"start":{"line":488,"column":0},"end":{"line":488,"column":24}},"488":{"start":{"line":489,"column":0},"end":{"line":489,"column":22}},"489":{"start":{"line":490,"column":0},"end":{"line":490,"column":32}},"490":{"start":{"line":491,"column":0},"end":{"line":491,"column":61}},"491":{"start":{"line":492,"column":0},"end":{"line":492,"column":55}},"492":{"start":{"line":493,"column":0},"end":{"line":493,"column":53}},"493":{"start":{"line":494,"column":0},"end":{"line":494,"column":22}},"494":{"start":{"line":495,"column":0},"end":{"line":495,"column":29}},"495":{"start":{"line":496,"column":0},"end":{"line":496,"column":35}},"496":{"start":{"line":497,"column":0},"end":{"line":497,"column":41}},"497":{"start":{"line":498,"column":0},"end":{"line":498,"column":55}},"498":{"start":{"line":499,"column":0},"end":{"line":499,"column":22}},"499":{"start":{"line":500,"column":0},"end":{"line":500,"column":21}},"501":{"start":{"line":502,"column":0},"end":{"line":502,"column":20}},"502":{"start":{"line":503,"column":0},"end":{"line":503,"column":19}},"504":{"start":{"line":505,"column":0},"end":{"line":505,"column":69}},"505":{"start":{"line":506,"column":0},"end":{"line":506,"column":51}},"507":{"start":{"line":508,"column":0},"end":{"line":508,"column":18}},"508":{"start":{"line":509,"column":0},"end":{"line":509,"column":18}},"510":{"start":{"line":511,"column":0},"end":{"line":511,"column":14}},"511":{"start":{"line":512,"column":0},"end":{"line":512,"column":12}},"512":{"start":{"line":513,"column":0},"end":{"line":513,"column":53}},"513":{"start":{"line":514,"column":0},"end":{"line":514,"column":18}},"514":{"start":{"line":515,"column":0},"end":{"line":515,"column":45}},"515":{"start":{"line":516,"column":0},"end":{"line":516,"column":12}},"517":{"start":{"line":518,"column":0},"end":{"line":518,"column":14}},"518":{"start":{"line":519,"column":0},"end":{"line":519,"column":120}},"519":{"start":{"line":520,"column":0},"end":{"line":520,"column":41}},"521":{"start":{"line":522,"column":0},"end":{"line":522,"column":62}},"522":{"start":{"line":523,"column":0},"end":{"line":523,"column":16}},"523":{"start":{"line":524,"column":0},"end":{"line":524,"column":48}},"524":{"start":{"line":525,"column":0},"end":{"line":525,"column":36}},"525":{"start":{"line":526,"column":0},"end":{"line":526,"column":45}},"526":{"start":{"line":527,"column":0},"end":{"line":527,"column":49}},"527":{"start":{"line":528,"column":0},"end":{"line":528,"column":14}},"528":{"start":{"line":529,"column":0},"end":{"line":529,"column":16}},"529":{"start":{"line":530,"column":0},"end":{"line":530,"column":14}},"530":{"start":{"line":531,"column":0},"end":{"line":531,"column":12}},"531":{"start":{"line":532,"column":0},"end":{"line":532,"column":10}},"533":{"start":{"line":534,"column":0},"end":{"line":534,"column":2}},"535":{"start":{"line":536,"column":0},"end":{"line":536,"column":19}}},"s":{"0":1,"1":1,"19":1,"20":1,"24":1,"32":1,"35":1,"36":1,"37":1,"38":1,"39":1,"40":1,"41":1,"42":1,"43":1,"44":1,"46":1,"47":1,"48":1,"50":1,"51":16,"52":16,"54":16,"55":16,"56":16,"57":16,"58":16,"59":16,"60":16,"61":16,"62":16,"63":16,"64":16,"65":16,"66":16,"67":7,"68":16,"69":16,"70":7,"71":16,"73":16,"74":16,"75":16,"76":16,"78":16,"79":16,"80":16,"82":16,"89":16,"90":16,"91":16,"93":16,"94":0,"95":0,"96":0,"97":0,"98":0,"99":0,"101":16,"102":0,"103":0,"104":0,"105":0,"106":0,"107":0,"109":16,"110":16,"111":16,"112":16,"113":16,"114":16,"116":16,"117":16,"119":16,"120":16,"122":16,"123":16,"124":16,"126":16,"127":16,"128":16,"129":16,"131":16,"132":16,"133":16,"134":16,"135":16,"136":16,"137":16,"138":16,"139":16,"140":16,"141":16,"142":16,"143":16,"144":16,"145":16,"146":16,"147":0,"148":0,"149":16,"150":0,"151":0,"152":16,"153":1,"154":1,"155":1,"156":1,"157":1,"158":16,"159":16,"161":16,"162":0,"163":0,"164":0,"165":0,"166":0,"167":0,"168":0,"169":0,"170":0,"171":0,"172":0,"173":0,"174":0,"175":0,"176":0,"177":0,"178":0,"179":0,"180":0,"181":0,"182":0,"184":16,"185":10,"186":16,"188":16,"189":8,"190":16,"192":16,"193":7,"194":7,"195":7,"196":7,"197":7,"198":7,"199":7,"200":7,"201":7,"202":7,"203":7,"204":7,"205":0,"206":7,"207":16,"209":16,"210":7,"211":16,"213":16,"214":7,"215":7,"216":7,"217":16,"219":16,"220":0,"221":0,"223":16,"224":0,"225":0,"226":0,"227":0,"228":0,"229":0,"230":0,"231":0,"232":0,"233":0,"234":0,"236":16,"237":0,"238":0,"239":0,"240":0,"241":0,"242":0,"243":0,"244":0,"245":0,"246":0,"247":0,"248":0,"249":0,"250":0,"251":0,"253":16,"254":0,"255":0,"256":0,"257":0,"258":0,"259":0,"260":0,"261":0,"262":0,"263":0,"265":16,"266":0,"267":0,"268":0,"269":0,"270":0,"271":0,"272":0,"273":0,"274":0,"275":0,"276":0,"278":16,"279":0,"280":0,"281":0,"282":0,"283":0,"284":0,"285":0,"286":0,"287":0,"288":0,"290":16,"291":0,"292":0,"293":0,"294":0,"295":0,"296":0,"297":0,"298":0,"299":0,"300":0,"301":0,"303":16,"304":0,"305":0,"306":0,"307":0,"308":0,"309":0,"310":0,"311":0,"312":0,"313":0,"314":0,"315":0,"316":0,"317":0,"318":0,"319":0,"321":16,"322":0,"323":0,"325":16,"326":16,"327":16,"328":16,"329":16,"330":16,"331":16,"332":16,"333":16,"334":16,"335":16,"336":16,"337":16,"338":16,"339":16,"340":16,"341":16,"342":16,"343":16,"344":16,"345":9,"346":9,"347":9,"348":0,"349":9,"350":7,"351":5,"352":5,"354":9,"355":9,"357":9,"358":9,"359":9,"361":9,"362":9,"363":9,"365":9,"366":9,"367":9,"369":9,"370":9,"371":9,"373":9,"374":9,"375":9,"377":9,"378":1,"379":1,"380":1,"382":9,"383":9,"384":9,"386":9,"387":9,"389":9,"390":9,"391":5,"392":5,"394":5,"395":5,"397":4,"398":4,"399":4,"400":4,"401":4,"402":0,"403":0,"404":0,"405":4,"406":0,"407":0,"408":0,"409":4,"410":0,"411":0,"412":0,"413":4,"414":0,"415":0,"416":0,"417":4,"418":0,"419":0,"420":0,"421":4,"422":4,"423":0,"424":0,"425":0,"426":4,"427":4,"428":4,"429":4,"430":4,"431":4,"432":4,"433":4,"434":0,"435":0,"436":0,"437":4,"438":0,"439":0,"440":0,"441":4,"442":0,"443":0,"444":0,"445":4,"446":4,"447":0,"448":0,"449":0,"450":4,"451":4,"452":4,"453":4,"454":4,"455":4,"456":4,"457":0,"458":0,"459":0,"460":4,"461":0,"462":0,"463":0,"464":4,"465":0,"466":0,"467":0,"468":4,"469":4,"470":0,"471":0,"472":0,"473":0,"474":4,"475":4,"476":4,"477":4,"478":4,"479":4,"480":4,"481":0,"482":0,"483":0,"484":0,"485":0,"486":0,"487":0,"488":4,"489":4,"490":4,"491":4,"492":4,"493":4,"494":4,"495":4,"496":4,"497":4,"498":4,"499":4,"501":9,"502":9,"504":7,"505":7,"507":7,"508":7,"510":16,"511":16,"512":16,"513":16,"514":16,"515":16,"517":16,"518":16,"519":16,"521":16,"522":16,"523":16,"524":16,"525":16,"526":16,"527":16,"528":16,"529":16,"530":16,"531":16,"533":16,"535":1},"branchMap":{"0":{"type":"branch","line":51,"loc":{"start":{"line":51,"column":12},"end":{"line":534,"column":2}},"locations":[{"start":{"line":51,"column":12},"end":{"line":534,"column":2}}]},"1":{"type":"branch","line":345,"loc":{"start":{"line":345,"column":11},"end":{"line":503,"column":19}},"locations":[{"start":{"line":345,"column":11},"end":{"line":503,"column":19}}]},"2":{"type":"branch","line":348,"loc":{"start":{"line":348,"column":28},"end":{"line":348,"column":52}},"locations":[{"start":{"line":348,"column":28},"end":{"line":348,"column":52}}]},"3":{"type":"branch","line":348,"loc":{"start":{"line":348,"column":92},"end":{"line":349,"column":47}},"locations":[{"start":{"line":348,"column":92},"end":{"line":349,"column":47}}]},"4":{"type":"branch","line":350,"loc":{"start":{"line":350,"column":36},"end":{"line":350,"column":61}},"locations":[{"start":{"line":350,"column":36},"end":{"line":350,"column":61}}]},"5":{"type":"branch","line":350,"loc":{"start":{"line":350,"column":48},"end":{"line":353,"column":22}},"locations":[{"start":{"line":350,"column":48},"end":{"line":353,"column":22}}]},"6":{"type":"branch","line":351,"loc":{"start":{"line":351,"column":36},"end":{"line":351,"column":57}},"locations":[{"start":{"line":351,"column":36},"end":{"line":351,"column":57}}]},"7":{"type":"branch","line":351,"loc":{"start":{"line":351,"column":46},"end":{"line":353,"column":22}},"locations":[{"start":{"line":351,"column":46},"end":{"line":353,"column":22}}]},"8":{"type":"branch","line":352,"loc":{"start":{"line":352,"column":36},"end":{"line":352,"column":53}},"locations":[{"start":{"line":352,"column":36},"end":{"line":352,"column":53}}]},"9":{"type":"branch","line":378,"loc":{"start":{"line":378,"column":50},"end":{"line":381,"column":27}},"locations":[{"start":{"line":378,"column":50},"end":{"line":381,"column":27}}]},"10":{"type":"branch","line":391,"loc":{"start":{"line":391,"column":38},"end":{"line":391,"column":83}},"locations":[{"start":{"line":391,"column":38},"end":{"line":391,"column":83}}]},"11":{"type":"branch","line":391,"loc":{"start":{"line":391,"column":72},"end":{"line":391,"column":113}},"locations":[{"start":{"line":391,"column":72},"end":{"line":391,"column":113}}]},"12":{"type":"branch","line":391,"loc":{"start":{"line":391,"column":104},"end":{"line":396,"column":24}},"locations":[{"start":{"line":391,"column":104},"end":{"line":396,"column":24}}]},"13":{"type":"branch","line":396,"loc":{"start":{"line":396,"column":18},"end":{"line":500,"column":21}},"locations":[{"start":{"line":396,"column":18},"end":{"line":500,"column":21}}]},"14":{"type":"branch","line":503,"loc":{"start":{"line":503,"column":12},"end":{"line":509,"column":18}},"locations":[{"start":{"line":503,"column":12},"end":{"line":509,"column":18}}]},"15":{"type":"branch","line":67,"loc":{"start":{"line":67,"column":49},"end":{"line":69,"column":3}},"locations":[{"start":{"line":67,"column":49},"end":{"line":69,"column":3}}]},"16":{"type":"branch","line":68,"loc":{"start":{"line":68,"column":45},"end":{"line":68,"column":74}},"locations":[{"start":{"line":68,"column":45},"end":{"line":68,"column":74}}]},"17":{"type":"branch","line":70,"loc":{"start":{"line":70,"column":43},"end":{"line":72,"column":3}},"locations":[{"start":{"line":70,"column":43},"end":{"line":72,"column":3}}]},"18":{"type":"branch","line":71,"loc":{"start":{"line":71,"column":42},"end":{"line":71,"column":50}},"locations":[{"start":{"line":71,"column":42},"end":{"line":71,"column":50}}]},"19":{"type":"branch","line":153,"loc":{"start":{"line":153,"column":22},"end":{"line":158,"column":6}},"locations":[{"start":{"line":153,"column":22},"end":{"line":158,"column":6}}]},"20":{"type":"branch","line":154,"loc":{"start":{"line":154,"column":31},"end":{"line":157,"column":7}},"locations":[{"start":{"line":154,"column":31},"end":{"line":157,"column":7}}]},"21":{"type":"branch","line":185,"loc":{"start":{"line":185,"column":12},"end":{"line":187,"column":5}},"locations":[{"start":{"line":185,"column":12},"end":{"line":187,"column":5}}]},"22":{"type":"branch","line":189,"loc":{"start":{"line":189,"column":12},"end":{"line":191,"column":5}},"locations":[{"start":{"line":189,"column":12},"end":{"line":191,"column":5}}]},"23":{"type":"branch","line":193,"loc":{"start":{"line":193,"column":12},"end":{"line":208,"column":5}},"locations":[{"start":{"line":193,"column":12},"end":{"line":208,"column":5}}]},"24":{"type":"branch","line":195,"loc":{"start":{"line":195,"column":12},"end":{"line":195,"column":41}},"locations":[{"start":{"line":195,"column":12},"end":{"line":195,"column":41}}]},"25":{"type":"branch","line":196,"loc":{"start":{"line":196,"column":12},"end":{"line":204,"column":7}},"locations":[{"start":{"line":196,"column":12},"end":{"line":204,"column":7}}]},"26":{"type":"branch","line":210,"loc":{"start":{"line":210,"column":12},"end":{"line":212,"column":5}},"locations":[{"start":{"line":210,"column":12},"end":{"line":212,"column":5}}]},"27":{"type":"branch","line":214,"loc":{"start":{"line":214,"column":12},"end":{"line":218,"column":5}},"locations":[{"start":{"line":214,"column":12},"end":{"line":218,"column":5}}]}},"b":{"0":[16],"1":[9],"2":[0],"3":[0],"4":[2],"5":[7],"6":[2],"7":[5],"8":[0],"9":[1],"10":[7],"11":[5],"12":[5],"13":[4],"14":[7],"15":[7],"16":[1],"17":[7],"18":[1],"19":[1],"20":[1],"21":[10],"22":[8],"23":[7],"24":[7],"25":[7],"26":[7],"27":[7]},"fnMap":{"0":{"name":"App","decl":{"start":{"line":51,"column":12},"end":{"line":534,"column":2}},"loc":{"start":{"line":51,"column":12},"end":{"line":534,"column":2}},"line":51},"1":{"name":"handleApproveSampling","decl":{"start":{"line":94,"column":32},"end":{"line":100,"column":4}},"loc":{"start":{"line":94,"column":32},"end":{"line":100,"column":4}},"line":94},"2":{"name":"handleRejectSampling","decl":{"start":{"line":102,"column":31},"end":{"line":108,"column":4}},"loc":{"start":{"line":102,"column":31},"end":{"line":108,"column":4}},"line":102},"3":{"name":"onNotification","decl":{"start":{"line":147,"column":20},"end":{"line":149,"column":6}},"loc":{"start":{"line":147,"column":20},"end":{"line":149,"column":6}},"line":147},"4":{"name":"onStdErrNotification","decl":{"start":{"line":150,"column":26},"end":{"line":152,"column":6}},"loc":{"start":{"line":150,"column":26},"end":{"line":152,"column":6}},"line":150},"5":{"name":"onPendingRequest","decl":{"start":{"line":153,"column":22},"end":{"line":158,"column":6}},"loc":{"start":{"line":153,"column":22},"end":{"line":158,"column":6}},"line":153},"6":{"name":"getRoots","decl":{"start":{"line":159,"column":14},"end":{"line":159,"column":36}},"loc":{"start":{"line":159,"column":14},"end":{"line":159,"column":36}},"line":159},"7":{"name":"makeRequest","decl":{"start":{"line":162,"column":22},"end":{"line":183,"column":4}},"loc":{"start":{"line":162,"column":22},"end":{"line":183,"column":4}},"line":162},"8":{"name":"clearError","decl":{"start":{"line":220,"column":21},"end":{"line":222,"column":4}},"loc":{"start":{"line":220,"column":21},"end":{"line":222,"column":4}},"line":220},"9":{"name":"listResources","decl":{"start":{"line":224,"column":24},"end":{"line":235,"column":4}},"loc":{"start":{"line":224,"column":24},"end":{"line":235,"column":4}},"line":224},"10":{"name":"listResourceTemplates","decl":{"start":{"line":237,"column":32},"end":{"line":252,"column":4}},"loc":{"start":{"line":237,"column":32},"end":{"line":252,"column":4}},"line":237},"11":{"name":"readResource","decl":{"start":{"line":254,"column":23},"end":{"line":264,"column":4}},"loc":{"start":{"line":254,"column":23},"end":{"line":264,"column":4}},"line":254},"12":{"name":"listPrompts","decl":{"start":{"line":266,"column":22},"end":{"line":277,"column":4}},"loc":{"start":{"line":266,"column":22},"end":{"line":277,"column":4}},"line":266},"13":{"name":"getPrompt","decl":{"start":{"line":279,"column":20},"end":{"line":289,"column":4}},"loc":{"start":{"line":279,"column":20},"end":{"line":289,"column":4}},"line":279},"14":{"name":"listTools","decl":{"start":{"line":291,"column":20},"end":{"line":302,"column":4}},"loc":{"start":{"line":291,"column":20},"end":{"line":302,"column":4}},"line":291},"15":{"name":"callTool","decl":{"start":{"line":304,"column":19},"end":{"line":320,"column":4}},"loc":{"start":{"line":304,"column":19},"end":{"line":320,"column":4}},"line":304},"16":{"name":"handleRootsChange","decl":{"start":{"line":322,"column":28},"end":{"line":324,"column":4}},"loc":{"start":{"line":322,"column":28},"end":{"line":324,"column":4}},"line":322},"17":{"name":"onValueChange","decl":{"start":{"line":356,"column":29},"end":{"line":356,"column":71}},"loc":{"start":{"line":356,"column":29},"end":{"line":356,"column":71}},"line":356},"18":{"name":"listResources","decl":{"start":{"line":402,"column":37},"end":{"line":405,"column":24}},"loc":{"start":{"line":402,"column":37},"end":{"line":405,"column":24}},"line":402},"19":{"name":"clearResources","decl":{"start":{"line":406,"column":38},"end":{"line":409,"column":24}},"loc":{"start":{"line":406,"column":38},"end":{"line":409,"column":24}},"line":406},"20":{"name":"listResourceTemplates","decl":{"start":{"line":410,"column":45},"end":{"line":413,"column":24}},"loc":{"start":{"line":410,"column":45},"end":{"line":413,"column":24}},"line":410},"21":{"name":"clearResourceTemplates","decl":{"start":{"line":414,"column":46},"end":{"line":417,"column":24}},"loc":{"start":{"line":414,"column":46},"end":{"line":417,"column":24}},"line":414},"22":{"name":"readResource","decl":{"start":{"line":418,"column":36},"end":{"line":421,"column":24}},"loc":{"start":{"line":418,"column":36},"end":{"line":421,"column":24}},"line":418},"23":{"name":"setSelectedResource","decl":{"start":{"line":423,"column":43},"end":{"line":426,"column":24}},"loc":{"start":{"line":423,"column":43},"end":{"line":426,"column":24}},"line":423},"24":{"name":"listPrompts","decl":{"start":{"line":434,"column":35},"end":{"line":437,"column":24}},"loc":{"start":{"line":434,"column":35},"end":{"line":437,"column":24}},"line":434},"25":{"name":"clearPrompts","decl":{"start":{"line":438,"column":36},"end":{"line":441,"column":24}},"loc":{"start":{"line":438,"column":36},"end":{"line":441,"column":24}},"line":438},"26":{"name":"getPrompt","decl":{"start":{"line":442,"column":33},"end":{"line":445,"column":24}},"loc":{"start":{"line":442,"column":33},"end":{"line":445,"column":24}},"line":442},"27":{"name":"setSelectedPrompt","decl":{"start":{"line":447,"column":41},"end":{"line":450,"column":24}},"loc":{"start":{"line":447,"column":41},"end":{"line":450,"column":24}},"line":447},"28":{"name":"listTools","decl":{"start":{"line":457,"column":33},"end":{"line":460,"column":24}},"loc":{"start":{"line":457,"column":33},"end":{"line":460,"column":24}},"line":457},"29":{"name":"clearTools","decl":{"start":{"line":461,"column":34},"end":{"line":464,"column":24}},"loc":{"start":{"line":461,"column":34},"end":{"line":464,"column":24}},"line":461},"30":{"name":"callTool","decl":{"start":{"line":465,"column":32},"end":{"line":468,"column":24}},"loc":{"start":{"line":465,"column":32},"end":{"line":468,"column":24}},"line":465},"31":{"name":"setSelectedTool","decl":{"start":{"line":470,"column":39},"end":{"line":474,"column":24}},"loc":{"start":{"line":470,"column":39},"end":{"line":474,"column":24}},"line":470},"32":{"name":"onPingClick","decl":{"start":{"line":481,"column":35},"end":{"line":488,"column":24}},"loc":{"start":{"line":481,"column":35},"end":{"line":488,"column":24}},"line":481}},"f":{"0":16,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":0,"11":0,"12":0,"13":0,"14":0,"15":0,"16":0,"17":0,"18":0,"19":0,"20":0,"21":0,"22":0,"23":0,"24":0,"25":0,"26":0,"27":0,"28":0,"29":0,"30":0,"31":0,"32":0}} +,"/Users/ashwin/code/mcp/inspector/client/src/main.tsx": {"path":"/Users/ashwin/code/mcp/inspector/client/src/main.tsx","all":true,"statementMap":{"0":{"start":{"line":1,"column":0},"end":{"line":1,"column":35}},"1":{"start":{"line":2,"column":0},"end":{"line":2,"column":46}},"2":{"start":{"line":3,"column":0},"end":{"line":3,"column":48}},"3":{"start":{"line":4,"column":0},"end":{"line":4,"column":47}},"4":{"start":{"line":5,"column":0},"end":{"line":5,"column":28}},"5":{"start":{"line":6,"column":0},"end":{"line":6,"column":21}},"7":{"start":{"line":8,"column":0},"end":{"line":8,"column":52}},"8":{"start":{"line":9,"column":0},"end":{"line":9,"column":14}},"9":{"start":{"line":10,"column":0},"end":{"line":10,"column":11}},"10":{"start":{"line":11,"column":0},"end":{"line":11,"column":22}},"11":{"start":{"line":12,"column":0},"end":{"line":12,"column":16}},"12":{"start":{"line":13,"column":0},"end":{"line":13,"column":2}}},"s":{"0":0,"1":0,"2":0,"3":0,"4":0,"5":0,"7":0,"8":0,"9":0,"10":0,"11":0,"12":0},"branchMap":{"0":{"type":"branch","line":1,"loc":{"start":{"line":1,"column":354},"end":{"line":13,"column":2}},"locations":[{"start":{"line":1,"column":354},"end":{"line":13,"column":2}}]}},"b":{"0":[0]},"fnMap":{"0":{"name":"(empty-report)","decl":{"start":{"line":1,"column":354},"end":{"line":13,"column":2}},"loc":{"start":{"line":1,"column":354},"end":{"line":13,"column":2}},"line":1}},"f":{"0":0}} +,"/Users/ashwin/code/mcp/inspector/client/src/components/ConsoleTab.tsx": {"path":"/Users/ashwin/code/mcp/inspector/client/src/components/ConsoleTab.tsx","all":false,"statementMap":{"0":{"start":{"line":1,"column":0},"end":{"line":1,"column":51}},"2":{"start":{"line":3,"column":0},"end":{"line":3,"column":26}},"3":{"start":{"line":4,"column":0},"end":{"line":4,"column":48}},"4":{"start":{"line":5,"column":0},"end":{"line":5,"column":101}},"5":{"start":{"line":6,"column":0},"end":{"line":6,"column":69}},"7":{"start":{"line":8,"column":0},"end":{"line":8,"column":10}},"8":{"start":{"line":9,"column":0},"end":{"line":9,"column":16}},"11":{"start":{"line":12,"column":0},"end":{"line":12,"column":26}}},"s":{"0":1,"2":1,"3":4,"4":4,"5":4,"7":4,"8":4,"11":1},"branchMap":{"0":{"type":"branch","line":3,"loc":{"start":{"line":3,"column":19},"end":{"line":9,"column":16}},"locations":[{"start":{"line":3,"column":19},"end":{"line":9,"column":16}}]}},"b":{"0":[4]},"fnMap":{"0":{"name":"ConsoleTab","decl":{"start":{"line":3,"column":19},"end":{"line":9,"column":16}},"loc":{"start":{"line":3,"column":19},"end":{"line":9,"column":16}},"line":3}},"f":{"0":4}} +,"/Users/ashwin/code/mcp/inspector/client/src/components/History.tsx": {"path":"/Users/ashwin/code/mcp/inspector/client/src/components/History.tsx","all":false,"statementMap":{"0":{"start":{"line":1,"column":0},"end":{"line":1,"column":72}},"1":{"start":{"line":2,"column":0},"end":{"line":2,"column":36}},"2":{"start":{"line":3,"column":0},"end":{"line":3,"column":33}},"4":{"start":{"line":5,"column":0},"end":{"line":5,"column":34}},"5":{"start":{"line":6,"column":0},"end":{"line":6,"column":17}},"6":{"start":{"line":7,"column":0},"end":{"line":7,"column":22}},"7":{"start":{"line":8,"column":0},"end":{"line":8,"column":4}},"10":{"start":{"line":11,"column":0},"end":{"line":11,"column":7}},"11":{"start":{"line":12,"column":0},"end":{"line":12,"column":60}},"13":{"start":{"line":14,"column":0},"end":{"line":14,"column":9}},"14":{"start":{"line":15,"column":0},"end":{"line":15,"column":70}},"16":{"start":{"line":17,"column":0},"end":{"line":17,"column":9}},"18":{"start":{"line":19,"column":0},"end":{"line":19,"column":53}},"19":{"start":{"line":20,"column":0},"end":{"line":20,"column":72}},"20":{"start":{"line":21,"column":0},"end":{"line":21,"column":4}},"22":{"start":{"line":23,"column":0},"end":{"line":23,"column":58}},"23":{"start":{"line":24,"column":0},"end":{"line":24,"column":77}},"24":{"start":{"line":25,"column":0},"end":{"line":25,"column":4}},"26":{"start":{"line":27,"column":0},"end":{"line":27,"column":45}},"27":{"start":{"line":28,"column":0},"end":{"line":28,"column":40}},"28":{"start":{"line":29,"column":0},"end":{"line":29,"column":4}},"30":{"start":{"line":31,"column":0},"end":{"line":31,"column":10}},"31":{"start":{"line":32,"column":0},"end":{"line":32,"column":57}},"32":{"start":{"line":33,"column":0},"end":{"line":33,"column":59}},"33":{"start":{"line":34,"column":0},"end":{"line":34,"column":63}},"34":{"start":{"line":35,"column":0},"end":{"line":35,"column":40}},"35":{"start":{"line":36,"column":0},"end":{"line":36,"column":72}},"37":{"start":{"line":38,"column":0},"end":{"line":38,"column":36}},"38":{"start":{"line":39,"column":0},"end":{"line":39,"column":27}},"39":{"start":{"line":40,"column":0},"end":{"line":40,"column":22}},"40":{"start":{"line":41,"column":0},"end":{"line":41,"column":24}},"41":{"start":{"line":42,"column":0},"end":{"line":42,"column":40}},"42":{"start":{"line":43,"column":0},"end":{"line":43,"column":19}},"43":{"start":{"line":44,"column":0},"end":{"line":44,"column":29}},"44":{"start":{"line":45,"column":0},"end":{"line":45,"column":78}},"46":{"start":{"line":47,"column":0},"end":{"line":47,"column":22}},"47":{"start":{"line":48,"column":0},"end":{"line":48,"column":80}},"48":{"start":{"line":49,"column":0},"end":{"line":49,"column":34}},"49":{"start":{"line":50,"column":0},"end":{"line":50,"column":79}},"52":{"start":{"line":53,"column":0},"end":{"line":53,"column":48}},"53":{"start":{"line":54,"column":0},"end":{"line":54,"column":59}},"54":{"start":{"line":55,"column":0},"end":{"line":55,"column":58}},"55":{"start":{"line":56,"column":0},"end":{"line":56,"column":27}},"56":{"start":{"line":57,"column":0},"end":{"line":57,"column":26}},"57":{"start":{"line":58,"column":0},"end":{"line":58,"column":74}},"58":{"start":{"line":59,"column":0},"end":{"line":59,"column":29}},"59":{"start":{"line":60,"column":0},"end":{"line":60,"column":30}},"60":{"start":{"line":61,"column":0},"end":{"line":61,"column":27}},"61":{"start":{"line":62,"column":0},"end":{"line":62,"column":24}},"62":{"start":{"line":63,"column":0},"end":{"line":63,"column":75}},"63":{"start":{"line":64,"column":0},"end":{"line":64,"column":22}},"64":{"start":{"line":65,"column":0},"end":{"line":65,"column":44}},"65":{"start":{"line":66,"column":0},"end":{"line":66,"column":80}},"66":{"start":{"line":67,"column":0},"end":{"line":67,"column":72}},"68":{"start":{"line":69,"column":0},"end":{"line":69,"column":33}},"69":{"start":{"line":70,"column":0},"end":{"line":70,"column":33}},"70":{"start":{"line":71,"column":0},"end":{"line":71,"column":76}},"71":{"start":{"line":72,"column":0},"end":{"line":72,"column":73}},"73":{"start":{"line":74,"column":0},"end":{"line":74,"column":46}},"74":{"start":{"line":75,"column":0},"end":{"line":75,"column":35}},"75":{"start":{"line":76,"column":0},"end":{"line":76,"column":30}},"76":{"start":{"line":77,"column":0},"end":{"line":77,"column":99}},"77":{"start":{"line":78,"column":0},"end":{"line":78,"column":80}},"78":{"start":{"line":79,"column":0},"end":{"line":79,"column":30}},"79":{"start":{"line":80,"column":0},"end":{"line":80,"column":28}},"80":{"start":{"line":81,"column":0},"end":{"line":81,"column":44}},"81":{"start":{"line":82,"column":0},"end":{"line":82,"column":46}},"82":{"start":{"line":83,"column":0},"end":{"line":83,"column":82}},"83":{"start":{"line":84,"column":0},"end":{"line":84,"column":75}},"85":{"start":{"line":86,"column":0},"end":{"line":86,"column":35}},"86":{"start":{"line":87,"column":0},"end":{"line":87,"column":35}},"87":{"start":{"line":88,"column":0},"end":{"line":88,"column":80}},"88":{"start":{"line":89,"column":0},"end":{"line":89,"column":75}},"90":{"start":{"line":91,"column":0},"end":{"line":91,"column":48}},"91":{"start":{"line":92,"column":0},"end":{"line":92,"column":37}},"92":{"start":{"line":93,"column":0},"end":{"line":93,"column":32}},"93":{"start":{"line":94,"column":0},"end":{"line":94,"column":101}},"94":{"start":{"line":95,"column":0},"end":{"line":95,"column":44}},"95":{"start":{"line":96,"column":0},"end":{"line":96,"column":59}},"96":{"start":{"line":97,"column":0},"end":{"line":97,"column":35}},"97":{"start":{"line":98,"column":0},"end":{"line":98,"column":32}},"98":{"start":{"line":99,"column":0},"end":{"line":99,"column":30}},"99":{"start":{"line":100,"column":0},"end":{"line":100,"column":32}},"100":{"start":{"line":101,"column":0},"end":{"line":101,"column":30}},"102":{"start":{"line":103,"column":0},"end":{"line":103,"column":23}},"104":{"start":{"line":105,"column":0},"end":{"line":105,"column":21}},"105":{"start":{"line":106,"column":0},"end":{"line":106,"column":17}},"106":{"start":{"line":107,"column":0},"end":{"line":107,"column":15}},"108":{"start":{"line":109,"column":0},"end":{"line":109,"column":12}},"109":{"start":{"line":110,"column":0},"end":{"line":110,"column":50}},"110":{"start":{"line":111,"column":0},"end":{"line":111,"column":76}},"111":{"start":{"line":112,"column":0},"end":{"line":112,"column":45}},"112":{"start":{"line":113,"column":0},"end":{"line":113,"column":78}},"114":{"start":{"line":115,"column":0},"end":{"line":115,"column":36}},"115":{"start":{"line":116,"column":0},"end":{"line":116,"column":32}},"116":{"start":{"line":117,"column":0},"end":{"line":117,"column":22}},"117":{"start":{"line":118,"column":0},"end":{"line":118,"column":24}},"118":{"start":{"line":119,"column":0},"end":{"line":119,"column":45}},"119":{"start":{"line":120,"column":0},"end":{"line":120,"column":19}},"120":{"start":{"line":121,"column":0},"end":{"line":121,"column":29}},"121":{"start":{"line":122,"column":0},"end":{"line":122,"column":78}},"123":{"start":{"line":124,"column":0},"end":{"line":124,"column":22}},"124":{"start":{"line":125,"column":0},"end":{"line":125,"column":80}},"125":{"start":{"line":126,"column":0},"end":{"line":126,"column":70}},"127":{"start":{"line":128,"column":0},"end":{"line":128,"column":48}},"128":{"start":{"line":129,"column":0},"end":{"line":129,"column":64}},"129":{"start":{"line":130,"column":0},"end":{"line":130,"column":43}},"130":{"start":{"line":131,"column":0},"end":{"line":131,"column":27}},"131":{"start":{"line":132,"column":0},"end":{"line":132,"column":75}},"132":{"start":{"line":133,"column":0},"end":{"line":133,"column":24}},"133":{"start":{"line":134,"column":0},"end":{"line":134,"column":52}},"134":{"start":{"line":135,"column":0},"end":{"line":135,"column":42}},"135":{"start":{"line":136,"column":0},"end":{"line":136,"column":78}},"136":{"start":{"line":137,"column":0},"end":{"line":137,"column":72}},"138":{"start":{"line":139,"column":0},"end":{"line":139,"column":31}},"139":{"start":{"line":140,"column":0},"end":{"line":140,"column":31}},"140":{"start":{"line":141,"column":0},"end":{"line":141,"column":40}},"141":{"start":{"line":142,"column":0},"end":{"line":142,"column":73}},"143":{"start":{"line":144,"column":0},"end":{"line":144,"column":71}},"145":{"start":{"line":146,"column":0},"end":{"line":146,"column":44}},"146":{"start":{"line":147,"column":0},"end":{"line":147,"column":33}},"147":{"start":{"line":148,"column":0},"end":{"line":148,"column":28}},"148":{"start":{"line":149,"column":0},"end":{"line":149,"column":97}},"149":{"start":{"line":150,"column":0},"end":{"line":150,"column":63}},"150":{"start":{"line":151,"column":0},"end":{"line":151,"column":28}},"151":{"start":{"line":152,"column":0},"end":{"line":152,"column":26}},"153":{"start":{"line":154,"column":0},"end":{"line":154,"column":21}},"154":{"start":{"line":155,"column":0},"end":{"line":155,"column":17}},"155":{"start":{"line":156,"column":0},"end":{"line":156,"column":15}},"157":{"start":{"line":158,"column":0},"end":{"line":158,"column":12}},"158":{"start":{"line":159,"column":0},"end":{"line":159,"column":10}},"160":{"start":{"line":161,"column":0},"end":{"line":161,"column":2}},"162":{"start":{"line":163,"column":0},"end":{"line":163,"column":39}}},"s":{"0":1,"1":1,"2":1,"4":1,"5":21,"6":21,"7":21,"10":21,"11":21,"13":21,"14":21,"16":21,"18":21,"19":1,"20":1,"22":21,"23":1,"24":1,"26":21,"27":0,"28":0,"30":21,"31":21,"32":21,"33":21,"34":21,"35":18,"37":3,"38":3,"39":3,"40":3,"41":3,"42":6,"43":6,"44":6,"46":6,"47":6,"48":6,"49":1,"52":6,"53":6,"54":6,"55":6,"56":6,"57":6,"58":1,"59":5,"60":6,"61":6,"62":6,"63":1,"64":1,"65":1,"66":1,"68":1,"69":1,"70":1,"71":1,"73":1,"74":1,"75":1,"76":1,"77":1,"78":1,"79":1,"80":1,"81":1,"82":1,"83":1,"85":1,"86":1,"87":1,"88":1,"90":1,"91":1,"92":1,"93":1,"94":1,"95":1,"96":1,"97":1,"98":1,"99":1,"100":1,"102":1,"104":6,"105":3,"106":3,"108":21,"109":21,"110":21,"111":21,"112":19,"114":2,"115":2,"116":2,"117":2,"118":2,"119":4,"120":4,"121":4,"123":4,"124":4,"125":4,"127":4,"128":4,"129":4,"130":4,"131":4,"132":4,"133":4,"134":1,"135":1,"136":1,"138":1,"139":1,"140":1,"141":0,"143":1,"145":1,"146":1,"147":1,"148":1,"149":1,"150":1,"151":1,"153":4,"154":2,"155":2,"157":21,"158":21,"160":21,"162":1},"branchMap":{"0":{"type":"branch","line":5,"loc":{"start":{"line":5,"column":32},"end":{"line":161,"column":2}},"locations":[{"start":{"line":5,"column":32},"end":{"line":161,"column":2}}]},"1":{"type":"branch","line":35,"loc":{"start":{"line":35,"column":35},"end":{"line":36,"column":72}},"locations":[{"start":{"line":35,"column":35},"end":{"line":36,"column":72}}]},"2":{"type":"branch","line":36,"loc":{"start":{"line":36,"column":68},"end":{"line":107,"column":15}},"locations":[{"start":{"line":36,"column":68},"end":{"line":107,"column":15}}]},"3":{"type":"branch","line":112,"loc":{"start":{"line":112,"column":40},"end":{"line":113,"column":78}},"locations":[{"start":{"line":112,"column":40},"end":{"line":113,"column":78}}]},"4":{"type":"branch","line":113,"loc":{"start":{"line":113,"column":74},"end":{"line":156,"column":15}},"locations":[{"start":{"line":113,"column":74},"end":{"line":156,"column":15}}]},"5":{"type":"branch","line":19,"loc":{"start":{"line":19,"column":33},"end":{"line":21,"column":4}},"locations":[{"start":{"line":19,"column":33},"end":{"line":21,"column":4}}]},"6":{"type":"branch","line":20,"loc":{"start":{"line":20,"column":24},"end":{"line":20,"column":70}},"locations":[{"start":{"line":20,"column":24},"end":{"line":20,"column":70}}]},"7":{"type":"branch","line":23,"loc":{"start":{"line":23,"column":38},"end":{"line":25,"column":4}},"locations":[{"start":{"line":23,"column":38},"end":{"line":25,"column":4}}]},"8":{"type":"branch","line":24,"loc":{"start":{"line":24,"column":29},"end":{"line":24,"column":75}},"locations":[{"start":{"line":24,"column":29},"end":{"line":24,"column":75}}]},"9":{"type":"branch","line":42,"loc":{"start":{"line":42,"column":19},"end":{"line":105,"column":21}},"locations":[{"start":{"line":42,"column":19},"end":{"line":105,"column":21}}]},"10":{"type":"branch","line":58,"loc":{"start":{"line":58,"column":73},"end":{"line":59,"column":29}},"locations":[{"start":{"line":58,"column":73},"end":{"line":59,"column":29}}]},"11":{"type":"branch","line":59,"loc":{"start":{"line":59,"column":26},"end":{"line":60,"column":30}},"locations":[{"start":{"line":59,"column":26},"end":{"line":60,"column":30}}]},"12":{"type":"branch","line":63,"loc":{"start":{"line":63,"column":69},"end":{"line":103,"column":23}},"locations":[{"start":{"line":63,"column":69},"end":{"line":103,"column":23}}]},"13":{"type":"branch","line":49,"loc":{"start":{"line":49,"column":29},"end":{"line":50,"column":79}},"locations":[{"start":{"line":49,"column":29},"end":{"line":50,"column":79}}]},"14":{"type":"branch","line":119,"loc":{"start":{"line":119,"column":19},"end":{"line":154,"column":21}},"locations":[{"start":{"line":119,"column":19},"end":{"line":154,"column":21}}]},"15":{"type":"branch","line":132,"loc":{"start":{"line":132,"column":54},"end":{"line":132,"column":64}},"locations":[{"start":{"line":132,"column":54},"end":{"line":132,"column":64}}]},"16":{"type":"branch","line":132,"loc":{"start":{"line":132,"column":58},"end":{"line":132,"column":68}},"locations":[{"start":{"line":132,"column":58},"end":{"line":132,"column":68}}]},"17":{"type":"branch","line":134,"loc":{"start":{"line":134,"column":46},"end":{"line":152,"column":26}},"locations":[{"start":{"line":134,"column":46},"end":{"line":152,"column":26}}]},"18":{"type":"branch","line":126,"loc":{"start":{"line":126,"column":29},"end":{"line":126,"column":70}},"locations":[{"start":{"line":126,"column":29},"end":{"line":126,"column":70}}]}},"b":{"0":[21],"1":[18],"2":[3],"3":[19],"4":[2],"5":[1],"6":[1],"7":[1],"8":[1],"9":[6],"10":[1],"11":[5],"12":[1],"13":[1],"14":[4],"15":[1],"16":[3],"17":[1],"18":[1]},"fnMap":{"0":{"name":"HistoryAndNotifications","decl":{"start":{"line":5,"column":32},"end":{"line":161,"column":2}},"loc":{"start":{"line":5,"column":32},"end":{"line":161,"column":2}},"line":5},"1":{"name":"toggleRequestExpansion","decl":{"start":{"line":19,"column":33},"end":{"line":21,"column":4}},"loc":{"start":{"line":19,"column":33},"end":{"line":21,"column":4}},"line":19},"2":{"name":"toggleNotificationExpansion","decl":{"start":{"line":23,"column":38},"end":{"line":25,"column":4}},"loc":{"start":{"line":23,"column":38},"end":{"line":25,"column":4}},"line":23},"3":{"name":"copyToClipboard","decl":{"start":{"line":27,"column":26},"end":{"line":29,"column":4}},"loc":{"start":{"line":27,"column":26},"end":{"line":29,"column":4}},"line":27},"4":{"name":"onClick","decl":{"start":{"line":49,"column":29},"end":{"line":50,"column":79}},"loc":{"start":{"line":49,"column":29},"end":{"line":50,"column":79}},"line":49},"5":{"name":"onClick","decl":{"start":{"line":71,"column":37},"end":{"line":71,"column":76}},"loc":{"start":{"line":71,"column":37},"end":{"line":71,"column":76}},"line":71},"6":{"name":"onClick","decl":{"start":{"line":88,"column":39},"end":{"line":88,"column":80}},"loc":{"start":{"line":88,"column":39},"end":{"line":88,"column":80}},"line":88},"7":{"name":"onClick","decl":{"start":{"line":126,"column":29},"end":{"line":126,"column":70}},"loc":{"start":{"line":126,"column":29},"end":{"line":126,"column":70}},"line":126},"8":{"name":"onClick","decl":{"start":{"line":141,"column":35},"end":{"line":142,"column":73}},"loc":{"start":{"line":141,"column":35},"end":{"line":142,"column":73}},"line":141}},"f":{"0":21,"1":1,"2":1,"3":0,"4":1,"5":0,"6":0,"7":1,"8":0}} +,"/Users/ashwin/code/mcp/inspector/client/src/components/ListPane.tsx": {"path":"/Users/ashwin/code/mcp/inspector/client/src/components/ListPane.tsx","all":false,"statementMap":{"0":{"start":{"line":1,"column":0},"end":{"line":1,"column":37}},"13":{"start":{"line":14,"column":0},"end":{"line":14,"column":37}},"14":{"start":{"line":15,"column":0},"end":{"line":15,"column":8}},"15":{"start":{"line":16,"column":0},"end":{"line":16,"column":12}},"16":{"start":{"line":17,"column":0},"end":{"line":17,"column":13}},"17":{"start":{"line":18,"column":0},"end":{"line":18,"column":18}},"18":{"start":{"line":19,"column":0},"end":{"line":19,"column":13}},"19":{"start":{"line":20,"column":0},"end":{"line":20,"column":8}},"20":{"start":{"line":21,"column":0},"end":{"line":21,"column":13}},"21":{"start":{"line":22,"column":0},"end":{"line":22,"column":19}},"22":{"start":{"line":23,"column":0},"end":{"line":23,"column":25}},"23":{"start":{"line":24,"column":0},"end":{"line":24,"column":45}},"24":{"start":{"line":25,"column":0},"end":{"line":25,"column":71}},"25":{"start":{"line":26,"column":0},"end":{"line":26,"column":64}},"26":{"start":{"line":27,"column":0},"end":{"line":27,"column":10}},"27":{"start":{"line":28,"column":0},"end":{"line":28,"column":25}},"28":{"start":{"line":29,"column":0},"end":{"line":29,"column":13}},"29":{"start":{"line":30,"column":0},"end":{"line":30,"column":25}},"30":{"start":{"line":31,"column":0},"end":{"line":31,"column":31}},"31":{"start":{"line":32,"column":0},"end":{"line":32,"column":27}},"32":{"start":{"line":33,"column":0},"end":{"line":33,"column":35}},"34":{"start":{"line":35,"column":0},"end":{"line":35,"column":20}},"35":{"start":{"line":36,"column":0},"end":{"line":36,"column":15}},"36":{"start":{"line":37,"column":0},"end":{"line":37,"column":13}},"37":{"start":{"line":38,"column":0},"end":{"line":38,"column":25}},"38":{"start":{"line":39,"column":0},"end":{"line":39,"column":31}},"39":{"start":{"line":40,"column":0},"end":{"line":40,"column":28}},"40":{"start":{"line":41,"column":0},"end":{"line":41,"column":37}},"41":{"start":{"line":42,"column":0},"end":{"line":42,"column":7}},"43":{"start":{"line":44,"column":0},"end":{"line":44,"column":15}},"44":{"start":{"line":45,"column":0},"end":{"line":45,"column":58}},"45":{"start":{"line":46,"column":0},"end":{"line":46,"column":37}},"46":{"start":{"line":47,"column":0},"end":{"line":47,"column":14}},"47":{"start":{"line":48,"column":0},"end":{"line":48,"column":23}},"48":{"start":{"line":49,"column":0},"end":{"line":49,"column":108}},"49":{"start":{"line":50,"column":0},"end":{"line":50,"column":49}},"51":{"start":{"line":52,"column":0},"end":{"line":52,"column":30}},"52":{"start":{"line":53,"column":0},"end":{"line":53,"column":16}},"53":{"start":{"line":54,"column":0},"end":{"line":54,"column":11}},"54":{"start":{"line":55,"column":0},"end":{"line":55,"column":12}},"55":{"start":{"line":56,"column":0},"end":{"line":56,"column":10}},"56":{"start":{"line":57,"column":0},"end":{"line":57,"column":8}},"59":{"start":{"line":60,"column":0},"end":{"line":60,"column":24}}},"s":{"0":1,"13":1,"14":44,"15":44,"16":44,"17":44,"18":44,"19":44,"20":44,"21":44,"22":44,"23":44,"24":44,"25":44,"26":44,"27":44,"28":44,"29":44,"30":44,"31":44,"32":44,"34":44,"35":44,"36":44,"37":44,"38":44,"39":44,"40":44,"41":44,"43":44,"44":44,"45":44,"46":74,"47":74,"48":74,"49":74,"51":74,"52":74,"53":44,"54":44,"55":44,"56":44,"59":1},"branchMap":{"0":{"type":"branch","line":14,"loc":{"start":{"line":14,"column":17},"end":{"line":57,"column":8}},"locations":[{"start":{"line":14,"column":17},"end":{"line":57,"column":8}}]},"1":{"type":"branch","line":46,"loc":{"start":{"line":46,"column":19},"end":{"line":53,"column":16}},"locations":[{"start":{"line":46,"column":19},"end":{"line":53,"column":16}}]},"2":{"type":"branch","line":50,"loc":{"start":{"line":50,"column":21},"end":{"line":50,"column":49}},"locations":[{"start":{"line":50,"column":21},"end":{"line":50,"column":49}}]}},"b":{"0":[44],"1":[74],"2":[3]},"fnMap":{"0":{"name":"ListPane","decl":{"start":{"line":14,"column":17},"end":{"line":57,"column":8}},"loc":{"start":{"line":14,"column":17},"end":{"line":57,"column":8}},"line":14},"1":{"name":"onClick","decl":{"start":{"line":50,"column":21},"end":{"line":50,"column":49}},"loc":{"start":{"line":50,"column":21},"end":{"line":50,"column":49}},"line":50}},"f":{"0":44,"1":3}} +,"/Users/ashwin/code/mcp/inspector/client/src/components/PingTab.tsx": {"path":"/Users/ashwin/code/mcp/inspector/client/src/components/PingTab.tsx","all":false,"statementMap":{"0":{"start":{"line":1,"column":0},"end":{"line":1,"column":51}},"1":{"start":{"line":2,"column":0},"end":{"line":2,"column":48}},"3":{"start":{"line":4,"column":0},"end":{"line":4,"column":67}},"4":{"start":{"line":5,"column":0},"end":{"line":5,"column":10}},"5":{"start":{"line":6,"column":0},"end":{"line":6,"column":65}},"6":{"start":{"line":7,"column":0},"end":{"line":7,"column":67}},"7":{"start":{"line":8,"column":0},"end":{"line":8,"column":15}},"8":{"start":{"line":9,"column":0},"end":{"line":9,"column":31}},"9":{"start":{"line":10,"column":0},"end":{"line":10,"column":279}},"11":{"start":{"line":12,"column":0},"end":{"line":12,"column":51}},"13":{"start":{"line":14,"column":0},"end":{"line":14,"column":51}},"14":{"start":{"line":15,"column":0},"end":{"line":15,"column":17}},"15":{"start":{"line":16,"column":0},"end":{"line":16,"column":12}},"16":{"start":{"line":17,"column":0},"end":{"line":17,"column":18}},"18":{"start":{"line":19,"column":0},"end":{"line":19,"column":2}},"20":{"start":{"line":21,"column":0},"end":{"line":21,"column":23}}},"s":{"0":1,"1":1,"3":1,"4":9,"5":9,"6":9,"7":9,"8":9,"9":9,"11":9,"13":9,"14":9,"15":9,"16":9,"18":9,"20":1},"branchMap":{"0":{"type":"branch","line":4,"loc":{"start":{"line":4,"column":16},"end":{"line":19,"column":2}},"locations":[{"start":{"line":4,"column":16},"end":{"line":19,"column":2}}]}},"b":{"0":[9]},"fnMap":{"0":{"name":"PingTab","decl":{"start":{"line":4,"column":16},"end":{"line":19,"column":2}},"loc":{"start":{"line":4,"column":16},"end":{"line":19,"column":2}},"line":4}},"f":{"0":9}} +,"/Users/ashwin/code/mcp/inspector/client/src/components/PromptsTab.tsx": {"path":"/Users/ashwin/code/mcp/inspector/client/src/components/PromptsTab.tsx","all":false,"statementMap":{"0":{"start":{"line":1,"column":0},"end":{"line":1,"column":76}},"1":{"start":{"line":2,"column":0},"end":{"line":2,"column":48}},"2":{"start":{"line":3,"column":0},"end":{"line":3,"column":46}},"3":{"start":{"line":4,"column":0},"end":{"line":4,"column":46}},"4":{"start":{"line":5,"column":0},"end":{"line":5,"column":51}},"5":{"start":{"line":6,"column":0},"end":{"line":6,"column":52}},"7":{"start":{"line":8,"column":0},"end":{"line":8,"column":43}},"8":{"start":{"line":9,"column":0},"end":{"line":9,"column":33}},"9":{"start":{"line":10,"column":0},"end":{"line":10,"column":34}},"21":{"start":{"line":22,"column":0},"end":{"line":22,"column":21}},"22":{"start":{"line":23,"column":0},"end":{"line":23,"column":10}},"23":{"start":{"line":24,"column":0},"end":{"line":24,"column":14}},"24":{"start":{"line":25,"column":0},"end":{"line":25,"column":15}},"25":{"start":{"line":26,"column":0},"end":{"line":26,"column":12}},"26":{"start":{"line":27,"column":0},"end":{"line":27,"column":17}},"27":{"start":{"line":28,"column":0},"end":{"line":28,"column":20}},"28":{"start":{"line":29,"column":0},"end":{"line":29,"column":16}},"29":{"start":{"line":30,"column":0},"end":{"line":30,"column":13}},"30":{"start":{"line":31,"column":0},"end":{"line":31,"column":8}},"31":{"start":{"line":32,"column":0},"end":{"line":32,"column":4}},"41":{"start":{"line":42,"column":0},"end":{"line":42,"column":7}},"42":{"start":{"line":43,"column":0},"end":{"line":43,"column":75}},"44":{"start":{"line":45,"column":0},"end":{"line":45,"column":65}},"45":{"start":{"line":46,"column":0},"end":{"line":46,"column":61}},"46":{"start":{"line":47,"column":0},"end":{"line":47,"column":4}},"48":{"start":{"line":49,"column":0},"end":{"line":49,"column":33}},"49":{"start":{"line":50,"column":0},"end":{"line":50,"column":25}},"50":{"start":{"line":51,"column":0},"end":{"line":51,"column":49}},"51":{"start":{"line":52,"column":0},"end":{"line":52,"column":5}},"52":{"start":{"line":53,"column":0},"end":{"line":53,"column":4}},"54":{"start":{"line":55,"column":0},"end":{"line":55,"column":10}},"55":{"start":{"line":56,"column":0},"end":{"line":56,"column":68}},"56":{"start":{"line":57,"column":0},"end":{"line":57,"column":15}},"57":{"start":{"line":58,"column":0},"end":{"line":58,"column":23}},"58":{"start":{"line":59,"column":0},"end":{"line":59,"column":31}},"59":{"start":{"line":60,"column":0},"end":{"line":60,"column":33}},"60":{"start":{"line":61,"column":0},"end":{"line":61,"column":38}},"61":{"start":{"line":62,"column":0},"end":{"line":62,"column":36}},"62":{"start":{"line":63,"column":0},"end":{"line":63,"column":28}},"63":{"start":{"line":64,"column":0},"end":{"line":64,"column":10}},"64":{"start":{"line":65,"column":0},"end":{"line":65,"column":33}},"65":{"start":{"line":66,"column":0},"end":{"line":66,"column":12}},"66":{"start":{"line":67,"column":0},"end":{"line":67,"column":57}},"67":{"start":{"line":68,"column":0},"end":{"line":68,"column":79}},"68":{"start":{"line":69,"column":0},"end":{"line":69,"column":13}},"70":{"start":{"line":71,"column":0},"end":{"line":71,"column":23}},"71":{"start":{"line":72,"column":0},"end":{"line":72,"column":70}},"72":{"start":{"line":73,"column":0},"end":{"line":73,"column":60}},"73":{"start":{"line":74,"column":0},"end":{"line":74,"column":8}},"75":{"start":{"line":76,"column":0},"end":{"line":76,"column":49}},"76":{"start":{"line":77,"column":0},"end":{"line":77,"column":54}},"77":{"start":{"line":78,"column":0},"end":{"line":78,"column":40}},"78":{"start":{"line":79,"column":0},"end":{"line":79,"column":70}},"79":{"start":{"line":80,"column":0},"end":{"line":80,"column":15}},"80":{"start":{"line":81,"column":0},"end":{"line":81,"column":14}},"81":{"start":{"line":82,"column":0},"end":{"line":82,"column":29}},"82":{"start":{"line":83,"column":0},"end":{"line":83,"column":20}},"83":{"start":{"line":84,"column":0},"end":{"line":84,"column":41}},"84":{"start":{"line":85,"column":0},"end":{"line":85,"column":49}},"85":{"start":{"line":86,"column":0},"end":{"line":86,"column":44}},"86":{"start":{"line":87,"column":0},"end":{"line":87,"column":58}},"87":{"start":{"line":88,"column":0},"end":{"line":88,"column":20}},"88":{"start":{"line":89,"column":0},"end":{"line":89,"column":32}},"89":{"start":{"line":90,"column":0},"end":{"line":90,"column":39}},"90":{"start":{"line":91,"column":0},"end":{"line":91,"column":46}},"91":{"start":{"line":92,"column":0},"end":{"line":92,"column":53}},"92":{"start":{"line":93,"column":0},"end":{"line":93,"column":46}},"93":{"start":{"line":94,"column":0},"end":{"line":94,"column":20}},"95":{"start":{"line":96,"column":0},"end":{"line":96,"column":55}},"96":{"start":{"line":97,"column":0},"end":{"line":97,"column":36}},"97":{"start":{"line":98,"column":0},"end":{"line":98,"column":62}},"98":{"start":{"line":99,"column":0},"end":{"line":99,"column":24}},"99":{"start":{"line":100,"column":0},"end":{"line":100,"column":33}},"100":{"start":{"line":101,"column":0},"end":{"line":101,"column":53}},"101":{"start":{"line":102,"column":0},"end":{"line":102,"column":54}},"102":{"start":{"line":103,"column":0},"end":{"line":103,"column":36}},"103":{"start":{"line":104,"column":0},"end":{"line":104,"column":65}},"105":{"start":{"line":106,"column":0},"end":{"line":106,"column":20}},"106":{"start":{"line":107,"column":0},"end":{"line":107,"column":39}},"107":{"start":{"line":108,"column":0},"end":{"line":108,"column":62}},"108":{"start":{"line":109,"column":0},"end":{"line":109,"column":39}},"109":{"start":{"line":110,"column":0},"end":{"line":110,"column":40}},"110":{"start":{"line":111,"column":0},"end":{"line":111,"column":77}},"112":{"start":{"line":113,"column":0},"end":{"line":113,"column":24}},"114":{"start":{"line":115,"column":0},"end":{"line":115,"column":22}},"115":{"start":{"line":116,"column":0},"end":{"line":116,"column":17}},"116":{"start":{"line":117,"column":0},"end":{"line":117,"column":67}},"118":{"start":{"line":119,"column":0},"end":{"line":119,"column":23}},"119":{"start":{"line":120,"column":0},"end":{"line":120,"column":33}},"120":{"start":{"line":121,"column":0},"end":{"line":121,"column":25}},"121":{"start":{"line":122,"column":0},"end":{"line":122,"column":39}},"122":{"start":{"line":123,"column":0},"end":{"line":123,"column":26}},"123":{"start":{"line":124,"column":0},"end":{"line":124,"column":44}},"124":{"start":{"line":125,"column":0},"end":{"line":125,"column":18}},"126":{"start":{"line":127,"column":0},"end":{"line":127,"column":18}},"128":{"start":{"line":129,"column":0},"end":{"line":129,"column":19}},"129":{"start":{"line":130,"column":0},"end":{"line":130,"column":32}},"131":{"start":{"line":132,"column":0},"end":{"line":132,"column":33}},"132":{"start":{"line":133,"column":0},"end":{"line":133,"column":20}},"134":{"start":{"line":135,"column":0},"end":{"line":135,"column":14}},"135":{"start":{"line":136,"column":0},"end":{"line":136,"column":12}},"136":{"start":{"line":137,"column":0},"end":{"line":137,"column":18}},"138":{"start":{"line":139,"column":0},"end":{"line":139,"column":2}},"140":{"start":{"line":141,"column":0},"end":{"line":141,"column":26}}},"s":{"0":1,"1":1,"2":1,"3":1,"4":1,"5":1,"7":1,"8":1,"9":1,"21":1,"22":10,"23":10,"24":10,"25":10,"26":10,"27":10,"28":10,"29":10,"30":10,"31":10,"41":10,"42":10,"44":10,"45":1,"46":1,"48":10,"49":1,"50":1,"51":1,"52":1,"54":10,"55":10,"56":10,"57":10,"58":10,"59":10,"60":10,"61":0,"62":0,"63":0,"64":10,"65":12,"66":12,"67":12,"68":12,"70":10,"71":10,"72":10,"73":10,"75":10,"76":10,"77":10,"78":10,"79":10,"80":10,"81":10,"82":10,"83":1,"84":1,"85":1,"86":1,"87":1,"88":9,"89":4,"90":4,"91":4,"92":4,"93":4,"95":4,"96":8,"97":8,"98":8,"99":8,"100":8,"101":8,"102":8,"103":1,"105":8,"106":8,"107":8,"108":8,"109":8,"110":4,"112":8,"114":8,"115":4,"116":4,"118":4,"119":4,"120":1,"121":1,"122":1,"123":1,"124":1,"126":4,"128":5,"129":5,"131":5,"132":5,"134":10,"135":10,"136":10,"138":10,"140":1},"branchMap":{"0":{"type":"branch","line":22,"loc":{"start":{"line":22,"column":19},"end":{"line":139,"column":2}},"locations":[{"start":{"line":22,"column":19},"end":{"line":139,"column":2}}]},"1":{"type":"branch","line":72,"loc":{"start":{"line":72,"column":20},"end":{"line":72,"column":55}},"locations":[{"start":{"line":72,"column":20},"end":{"line":72,"column":55}}]},"2":{"type":"branch","line":79,"loc":{"start":{"line":79,"column":13},"end":{"line":79,"column":52}},"locations":[{"start":{"line":79,"column":13},"end":{"line":79,"column":52}}]},"3":{"type":"branch","line":79,"loc":{"start":{"line":79,"column":45},"end":{"line":79,"column":70}},"locations":[{"start":{"line":79,"column":45},"end":{"line":79,"column":70}}]},"4":{"type":"branch","line":83,"loc":{"start":{"line":83,"column":11},"end":{"line":88,"column":20}},"locations":[{"start":{"line":83,"column":11},"end":{"line":88,"column":20}}]},"5":{"type":"branch","line":88,"loc":{"start":{"line":88,"column":12},"end":{"line":133,"column":20}},"locations":[{"start":{"line":88,"column":12},"end":{"line":133,"column":20}}]},"6":{"type":"branch","line":89,"loc":{"start":{"line":89,"column":14},"end":{"line":127,"column":18}},"locations":[{"start":{"line":89,"column":14},"end":{"line":127,"column":18}}]},"7":{"type":"branch","line":120,"loc":{"start":{"line":120,"column":15},"end":{"line":125,"column":18}},"locations":[{"start":{"line":120,"column":15},"end":{"line":125,"column":18}}]},"8":{"type":"branch","line":127,"loc":{"start":{"line":127,"column":12},"end":{"line":133,"column":20}},"locations":[{"start":{"line":127,"column":12},"end":{"line":133,"column":20}}]},"9":{"type":"branch","line":45,"loc":{"start":{"line":45,"column":28},"end":{"line":47,"column":4}},"locations":[{"start":{"line":45,"column":28},"end":{"line":47,"column":4}}]},"10":{"type":"branch","line":46,"loc":{"start":{"line":46,"column":18},"end":{"line":46,"column":59}},"locations":[{"start":{"line":46,"column":18},"end":{"line":46,"column":59}}]},"11":{"type":"branch","line":49,"loc":{"start":{"line":49,"column":26},"end":{"line":53,"column":4}},"locations":[{"start":{"line":49,"column":26},"end":{"line":53,"column":4}}]},"12":{"type":"branch","line":65,"loc":{"start":{"line":65,"column":20},"end":{"line":69,"column":13}},"locations":[{"start":{"line":65,"column":20},"end":{"line":69,"column":13}}]},"13":{"type":"branch","line":96,"loc":{"start":{"line":96,"column":45},"end":{"line":115,"column":22}},"locations":[{"start":{"line":96,"column":45},"end":{"line":115,"column":22}}]},"14":{"type":"branch","line":102,"loc":{"start":{"line":102,"column":46},"end":{"line":102,"column":54}},"locations":[{"start":{"line":102,"column":46},"end":{"line":102,"column":54}}]},"15":{"type":"branch","line":110,"loc":{"start":{"line":110,"column":27},"end":{"line":111,"column":77}},"locations":[{"start":{"line":110,"column":27},"end":{"line":111,"column":77}}]},"16":{"type":"branch","line":103,"loc":{"start":{"line":103,"column":30},"end":{"line":104,"column":65}},"locations":[{"start":{"line":103,"column":30},"end":{"line":104,"column":65}}]}},"b":{"0":[10],"1":[0],"2":[4],"3":[6],"4":[1],"5":[9],"6":[4],"7":[1],"8":[5],"9":[1],"10":[1],"11":[1],"12":[12],"13":[8],"14":[7],"15":[4],"16":[1]},"fnMap":{"0":{"name":"PromptsTab","decl":{"start":{"line":22,"column":19},"end":{"line":139,"column":2}},"loc":{"start":{"line":22,"column":19},"end":{"line":139,"column":2}},"line":22},"1":{"name":"handleInputChange","decl":{"start":{"line":45,"column":28},"end":{"line":47,"column":4}},"loc":{"start":{"line":45,"column":28},"end":{"line":47,"column":4}},"line":45},"2":{"name":"handleGetPrompt","decl":{"start":{"line":49,"column":26},"end":{"line":53,"column":4}},"loc":{"start":{"line":49,"column":26},"end":{"line":53,"column":4}},"line":49},"3":{"name":"setSelectedItem","decl":{"start":{"line":61,"column":25},"end":{"line":64,"column":10}},"loc":{"start":{"line":61,"column":25},"end":{"line":64,"column":10}},"line":61},"4":{"name":"renderItem","decl":{"start":{"line":65,"column":20},"end":{"line":69,"column":13}},"loc":{"start":{"line":65,"column":20},"end":{"line":69,"column":13}},"line":65},"5":{"name":"onChange","decl":{"start":{"line":103,"column":30},"end":{"line":104,"column":65}},"loc":{"start":{"line":103,"column":30},"end":{"line":104,"column":65}},"line":103}},"f":{"0":10,"1":1,"2":1,"3":0,"4":12,"5":1}} +,"/Users/ashwin/code/mcp/inspector/client/src/components/ResourcesTab.tsx": {"path":"/Users/ashwin/code/mcp/inspector/client/src/components/ResourcesTab.tsx","all":false,"statementMap":{"0":{"start":{"line":1,"column":0},"end":{"line":1,"column":76}},"1":{"start":{"line":2,"column":0},"end":{"line":2,"column":48}},"2":{"start":{"line":3,"column":0},"end":{"line":3,"column":46}},"3":{"start":{"line":4,"column":0},"end":{"line":4,"column":51}},"10":{"start":{"line":11,"column":0},"end":{"line":11,"column":78}},"11":{"start":{"line":12,"column":0},"end":{"line":12,"column":34}},"12":{"start":{"line":13,"column":0},"end":{"line":13,"column":33}},"14":{"start":{"line":15,"column":0},"end":{"line":15,"column":23}},"15":{"start":{"line":16,"column":0},"end":{"line":16,"column":12}},"16":{"start":{"line":17,"column":0},"end":{"line":17,"column":20}},"17":{"start":{"line":18,"column":0},"end":{"line":18,"column":16}},"18":{"start":{"line":19,"column":0},"end":{"line":19,"column":17}},"19":{"start":{"line":20,"column":0},"end":{"line":20,"column":24}},"20":{"start":{"line":21,"column":0},"end":{"line":21,"column":25}},"21":{"start":{"line":22,"column":0},"end":{"line":22,"column":15}},"22":{"start":{"line":23,"column":0},"end":{"line":23,"column":19}},"23":{"start":{"line":24,"column":0},"end":{"line":24,"column":22}},"24":{"start":{"line":25,"column":0},"end":{"line":25,"column":18}},"25":{"start":{"line":26,"column":0},"end":{"line":26,"column":13}},"26":{"start":{"line":27,"column":0},"end":{"line":27,"column":21}},"27":{"start":{"line":28,"column":0},"end":{"line":28,"column":8}},"28":{"start":{"line":29,"column":0},"end":{"line":29,"column":4}},"42":{"start":{"line":43,"column":0},"end":{"line":43,"column":7}},"43":{"start":{"line":44,"column":0},"end":{"line":44,"column":49}},"44":{"start":{"line":45,"column":0},"end":{"line":45,"column":44}},"45":{"start":{"line":46,"column":0},"end":{"line":46,"column":79}},"46":{"start":{"line":47,"column":0},"end":{"line":47,"column":7}},"47":{"start":{"line":48,"column":0},"end":{"line":48,"column":4}},"49":{"start":{"line":50,"column":0},"end":{"line":50,"column":24}},"50":{"start":{"line":51,"column":0},"end":{"line":51,"column":21}},"51":{"start":{"line":52,"column":0},"end":{"line":52,"column":35}},"52":{"start":{"line":53,"column":0},"end":{"line":53,"column":16}},"53":{"start":{"line":54,"column":0},"end":{"line":54,"column":28}},"54":{"start":{"line":55,"column":0},"end":{"line":55,"column":19}},"55":{"start":{"line":56,"column":0},"end":{"line":56,"column":44}},"56":{"start":{"line":57,"column":0},"end":{"line":57,"column":6}},"57":{"start":{"line":58,"column":0},"end":{"line":58,"column":4}},"59":{"start":{"line":60,"column":0},"end":{"line":60,"column":44}},"60":{"start":{"line":61,"column":0},"end":{"line":61,"column":27}},"61":{"start":{"line":62,"column":0},"end":{"line":62,"column":77}},"62":{"start":{"line":63,"column":0},"end":{"line":63,"column":24}},"63":{"start":{"line":64,"column":0},"end":{"line":64,"column":32}},"65":{"start":{"line":66,"column":0},"end":{"line":66,"column":58}},"66":{"start":{"line":67,"column":0},"end":{"line":67,"column":5}},"67":{"start":{"line":68,"column":0},"end":{"line":68,"column":4}},"69":{"start":{"line":70,"column":0},"end":{"line":70,"column":10}},"70":{"start":{"line":71,"column":0},"end":{"line":71,"column":70}},"71":{"start":{"line":72,"column":0},"end":{"line":72,"column":15}},"72":{"start":{"line":73,"column":0},"end":{"line":73,"column":25}},"73":{"start":{"line":74,"column":0},"end":{"line":74,"column":33}},"74":{"start":{"line":75,"column":0},"end":{"line":75,"column":35}},"75":{"start":{"line":76,"column":0},"end":{"line":76,"column":40}},"76":{"start":{"line":77,"column":0},"end":{"line":77,"column":40}},"77":{"start":{"line":78,"column":0},"end":{"line":78,"column":37}},"78":{"start":{"line":79,"column":0},"end":{"line":79,"column":36}},"79":{"start":{"line":80,"column":0},"end":{"line":80,"column":10}},"80":{"start":{"line":81,"column":0},"end":{"line":81,"column":35}},"81":{"start":{"line":82,"column":0},"end":{"line":82,"column":52}},"82":{"start":{"line":83,"column":0},"end":{"line":83,"column":77}},"83":{"start":{"line":84,"column":0},"end":{"line":84,"column":78}},"84":{"start":{"line":85,"column":0},"end":{"line":85,"column":29}},"85":{"start":{"line":86,"column":0},"end":{"line":86,"column":19}},"86":{"start":{"line":87,"column":0},"end":{"line":87,"column":76}},"87":{"start":{"line":88,"column":0},"end":{"line":88,"column":16}},"89":{"start":{"line":90,"column":0},"end":{"line":90,"column":25}},"90":{"start":{"line":91,"column":0},"end":{"line":91,"column":74}},"91":{"start":{"line":92,"column":0},"end":{"line":92,"column":62}},"92":{"start":{"line":93,"column":0},"end":{"line":93,"column":8}},"94":{"start":{"line":95,"column":0},"end":{"line":95,"column":15}},"95":{"start":{"line":96,"column":0},"end":{"line":96,"column":33}},"96":{"start":{"line":97,"column":0},"end":{"line":97,"column":41}},"97":{"start":{"line":98,"column":0},"end":{"line":98,"column":43}},"98":{"start":{"line":99,"column":0},"end":{"line":99,"column":40}},"99":{"start":{"line":100,"column":0},"end":{"line":100,"column":40}},"100":{"start":{"line":101,"column":0},"end":{"line":101,"column":36}},"101":{"start":{"line":102,"column":0},"end":{"line":102,"column":32}},"102":{"start":{"line":103,"column":0},"end":{"line":103,"column":10}},"103":{"start":{"line":104,"column":0},"end":{"line":104,"column":35}},"104":{"start":{"line":105,"column":0},"end":{"line":105,"column":52}},"105":{"start":{"line":106,"column":0},"end":{"line":106,"column":77}},"106":{"start":{"line":107,"column":0},"end":{"line":107,"column":75}},"107":{"start":{"line":108,"column":0},"end":{"line":108,"column":29}},"108":{"start":{"line":109,"column":0},"end":{"line":109,"column":19}},"109":{"start":{"line":110,"column":0},"end":{"line":110,"column":76}},"110":{"start":{"line":111,"column":0},"end":{"line":111,"column":16}},"112":{"start":{"line":113,"column":0},"end":{"line":113,"column":34}},"113":{"start":{"line":114,"column":0},"end":{"line":114,"column":20}},"114":{"start":{"line":115,"column":0},"end":{"line":115,"column":71}},"116":{"start":{"line":117,"column":0},"end":{"line":117,"column":78}},"117":{"start":{"line":118,"column":0},"end":{"line":118,"column":8}},"119":{"start":{"line":120,"column":0},"end":{"line":120,"column":49}},"120":{"start":{"line":121,"column":0},"end":{"line":121,"column":88}},"121":{"start":{"line":122,"column":0},"end":{"line":122,"column":13}},"122":{"start":{"line":123,"column":0},"end":{"line":123,"column":46}},"123":{"start":{"line":124,"column":0},"end":{"line":124,"column":68}},"125":{"start":{"line":126,"column":0},"end":{"line":126,"column":29}},"126":{"start":{"line":127,"column":0},"end":{"line":127,"column":37}},"127":{"start":{"line":128,"column":0},"end":{"line":128,"column":32}},"128":{"start":{"line":129,"column":0},"end":{"line":129,"column":39}},"129":{"start":{"line":130,"column":0},"end":{"line":130,"column":50}},"130":{"start":{"line":131,"column":0},"end":{"line":131,"column":15}},"131":{"start":{"line":132,"column":0},"end":{"line":132,"column":32}},"132":{"start":{"line":133,"column":0},"end":{"line":133,"column":19}},"133":{"start":{"line":134,"column":0},"end":{"line":134,"column":31}},"134":{"start":{"line":135,"column":0},"end":{"line":135,"column":23}},"135":{"start":{"line":136,"column":0},"end":{"line":136,"column":64}},"137":{"start":{"line":138,"column":0},"end":{"line":138,"column":52}},"139":{"start":{"line":140,"column":0},"end":{"line":140,"column":21}},"141":{"start":{"line":142,"column":0},"end":{"line":142,"column":14}},"142":{"start":{"line":143,"column":0},"end":{"line":143,"column":29}},"143":{"start":{"line":144,"column":0},"end":{"line":144,"column":20}},"144":{"start":{"line":145,"column":0},"end":{"line":145,"column":41}},"145":{"start":{"line":146,"column":0},"end":{"line":146,"column":49}},"146":{"start":{"line":147,"column":0},"end":{"line":147,"column":44}},"147":{"start":{"line":148,"column":0},"end":{"line":148,"column":58}},"148":{"start":{"line":149,"column":0},"end":{"line":149,"column":20}},"149":{"start":{"line":150,"column":0},"end":{"line":150,"column":34}},"150":{"start":{"line":151,"column":0},"end":{"line":151,"column":165}},"151":{"start":{"line":152,"column":0},"end":{"line":152,"column":31}},"152":{"start":{"line":153,"column":0},"end":{"line":153,"column":18}},"153":{"start":{"line":154,"column":0},"end":{"line":154,"column":34}},"154":{"start":{"line":155,"column":0},"end":{"line":155,"column":39}},"155":{"start":{"line":156,"column":0},"end":{"line":156,"column":51}},"156":{"start":{"line":157,"column":0},"end":{"line":157,"column":46}},"157":{"start":{"line":158,"column":0},"end":{"line":158,"column":18}},"158":{"start":{"line":159,"column":0},"end":{"line":159,"column":43}},"159":{"start":{"line":160,"column":0},"end":{"line":160,"column":36}},"160":{"start":{"line":161,"column":0},"end":{"line":161,"column":34}},"161":{"start":{"line":162,"column":0},"end":{"line":162,"column":49}},"162":{"start":{"line":163,"column":0},"end":{"line":163,"column":26}},"163":{"start":{"line":164,"column":0},"end":{"line":164,"column":35}},"164":{"start":{"line":165,"column":0},"end":{"line":165,"column":28}},"165":{"start":{"line":166,"column":0},"end":{"line":166,"column":37}},"166":{"start":{"line":167,"column":0},"end":{"line":167,"column":75}},"168":{"start":{"line":169,"column":0},"end":{"line":169,"column":29}},"169":{"start":{"line":170,"column":0},"end":{"line":170,"column":30}},"170":{"start":{"line":171,"column":0},"end":{"line":171,"column":28}},"171":{"start":{"line":172,"column":0},"end":{"line":172,"column":32}},"172":{"start":{"line":173,"column":0},"end":{"line":173,"column":57}},"173":{"start":{"line":174,"column":0},"end":{"line":174,"column":40}},"174":{"start":{"line":175,"column":0},"end":{"line":175,"column":45}},"175":{"start":{"line":176,"column":0},"end":{"line":176,"column":46}},"176":{"start":{"line":177,"column":0},"end":{"line":177,"column":50}},"177":{"start":{"line":178,"column":0},"end":{"line":178,"column":28}},"179":{"start":{"line":180,"column":0},"end":{"line":180,"column":40}},"180":{"start":{"line":181,"column":0},"end":{"line":181,"column":24}},"181":{"start":{"line":182,"column":0},"end":{"line":182,"column":26}},"183":{"start":{"line":184,"column":0},"end":{"line":184,"column":19}},"184":{"start":{"line":185,"column":0},"end":{"line":185,"column":21}},"185":{"start":{"line":186,"column":0},"end":{"line":186,"column":52}},"186":{"start":{"line":187,"column":0},"end":{"line":187,"column":67}},"187":{"start":{"line":188,"column":0},"end":{"line":188,"column":15}},"189":{"start":{"line":190,"column":0},"end":{"line":190,"column":23}},"190":{"start":{"line":191,"column":0},"end":{"line":191,"column":18}},"192":{"start":{"line":193,"column":0},"end":{"line":193,"column":19}},"193":{"start":{"line":194,"column":0},"end":{"line":194,"column":32}},"195":{"start":{"line":196,"column":0},"end":{"line":196,"column":33}},"196":{"start":{"line":197,"column":0},"end":{"line":197,"column":20}},"198":{"start":{"line":199,"column":0},"end":{"line":199,"column":14}},"199":{"start":{"line":200,"column":0},"end":{"line":200,"column":12}},"200":{"start":{"line":201,"column":0},"end":{"line":201,"column":18}},"202":{"start":{"line":203,"column":0},"end":{"line":203,"column":2}},"204":{"start":{"line":205,"column":0},"end":{"line":205,"column":28}}},"s":{"0":1,"1":1,"2":1,"3":1,"10":1,"11":1,"12":1,"14":1,"15":16,"16":16,"17":16,"18":16,"19":16,"20":16,"21":16,"22":16,"23":16,"24":16,"25":16,"26":16,"27":16,"28":16,"42":16,"43":16,"44":16,"45":16,"46":16,"47":16,"49":16,"50":1,"51":1,"52":1,"53":1,"54":1,"55":1,"56":1,"57":1,"59":16,"60":1,"61":1,"62":1,"63":1,"65":1,"66":1,"67":1,"69":16,"70":16,"71":16,"72":16,"73":16,"74":16,"75":16,"76":0,"77":0,"78":0,"79":0,"80":16,"81":24,"82":24,"83":24,"84":24,"85":24,"86":24,"87":24,"89":16,"90":16,"91":16,"92":16,"94":16,"95":16,"96":16,"97":16,"98":16,"99":2,"100":2,"101":2,"102":2,"103":16,"104":24,"105":24,"106":24,"107":24,"108":24,"109":24,"110":24,"112":16,"113":16,"114":16,"116":16,"117":16,"119":16,"120":16,"121":16,"122":16,"123":16,"125":16,"126":2,"127":14,"128":4,"129":10,"130":16,"131":16,"132":2,"133":2,"134":2,"135":2,"137":2,"139":2,"141":16,"142":16,"143":16,"144":1,"145":1,"146":1,"147":1,"148":1,"149":15,"150":2,"151":2,"152":2,"153":13,"154":4,"155":4,"156":4,"157":4,"158":4,"159":4,"160":4,"161":8,"162":8,"163":8,"164":8,"165":8,"166":8,"168":8,"169":8,"170":8,"171":8,"172":8,"173":8,"174":2,"175":2,"176":2,"177":2,"179":8,"180":8,"181":8,"183":4,"184":4,"185":4,"186":4,"187":4,"189":4,"190":4,"192":9,"193":9,"195":9,"196":9,"198":16,"199":16,"200":16,"202":16,"204":1},"branchMap":{"0":{"type":"branch","line":15,"loc":{"start":{"line":15,"column":21},"end":{"line":203,"column":2}},"locations":[{"start":{"line":15,"column":21},"end":{"line":203,"column":2}}]},"1":{"type":"branch","line":91,"loc":{"start":{"line":91,"column":20},"end":{"line":91,"column":57}},"locations":[{"start":{"line":91,"column":20},"end":{"line":91,"column":57}}]},"2":{"type":"branch","line":115,"loc":{"start":{"line":115,"column":10},"end":{"line":115,"column":55}},"locations":[{"start":{"line":115,"column":10},"end":{"line":115,"column":55}}]},"3":{"type":"branch","line":124,"loc":{"start":{"line":124,"column":19},"end":{"line":124,"column":45}},"locations":[{"start":{"line":124,"column":19},"end":{"line":124,"column":45}}]},"4":{"type":"branch","line":124,"loc":{"start":{"line":124,"column":37},"end":{"line":124,"column":68}},"locations":[{"start":{"line":124,"column":37},"end":{"line":124,"column":68}}]},"5":{"type":"branch","line":124,"loc":{"start":{"line":124,"column":45},"end":{"line":124,"column":68}},"locations":[{"start":{"line":124,"column":45},"end":{"line":124,"column":68}}]},"6":{"type":"branch","line":126,"loc":{"start":{"line":126,"column":13},"end":{"line":127,"column":37}},"locations":[{"start":{"line":126,"column":13},"end":{"line":127,"column":37}}]},"7":{"type":"branch","line":127,"loc":{"start":{"line":127,"column":33},"end":{"line":130,"column":50}},"locations":[{"start":{"line":127,"column":33},"end":{"line":130,"column":50}}]},"8":{"type":"branch","line":128,"loc":{"start":{"line":128,"column":16},"end":{"line":129,"column":39}},"locations":[{"start":{"line":128,"column":16},"end":{"line":129,"column":39}}]},"9":{"type":"branch","line":129,"loc":{"start":{"line":129,"column":35},"end":{"line":130,"column":50}},"locations":[{"start":{"line":129,"column":35},"end":{"line":130,"column":50}}]},"10":{"type":"branch","line":132,"loc":{"start":{"line":132,"column":11},"end":{"line":140,"column":21}},"locations":[{"start":{"line":132,"column":11},"end":{"line":140,"column":21}}]},"11":{"type":"branch","line":144,"loc":{"start":{"line":144,"column":11},"end":{"line":149,"column":20}},"locations":[{"start":{"line":144,"column":11},"end":{"line":149,"column":20}}]},"12":{"type":"branch","line":149,"loc":{"start":{"line":149,"column":12},"end":{"line":197,"column":20}},"locations":[{"start":{"line":149,"column":12},"end":{"line":197,"column":20}}]},"13":{"type":"branch","line":150,"loc":{"start":{"line":150,"column":14},"end":{"line":153,"column":18}},"locations":[{"start":{"line":150,"column":14},"end":{"line":153,"column":18}}]},"14":{"type":"branch","line":153,"loc":{"start":{"line":153,"column":12},"end":{"line":197,"column":20}},"locations":[{"start":{"line":153,"column":12},"end":{"line":197,"column":20}}]},"15":{"type":"branch","line":154,"loc":{"start":{"line":154,"column":14},"end":{"line":191,"column":18}},"locations":[{"start":{"line":154,"column":14},"end":{"line":191,"column":18}}]},"16":{"type":"branch","line":191,"loc":{"start":{"line":191,"column":12},"end":{"line":197,"column":20}},"locations":[{"start":{"line":191,"column":12},"end":{"line":197,"column":20}}]},"17":{"type":"branch","line":50,"loc":{"start":{"line":50,"column":23},"end":{"line":58,"column":4}},"locations":[{"start":{"line":50,"column":23},"end":{"line":58,"column":4}}]},"18":{"type":"branch","line":56,"loc":{"start":{"line":56,"column":6},"end":{"line":56,"column":44}},"locations":[{"start":{"line":56,"column":6},"end":{"line":56,"column":44}}]},"19":{"type":"branch","line":56,"loc":{"start":{"line":56,"column":28},"end":{"line":56,"column":44}},"locations":[{"start":{"line":56,"column":28},"end":{"line":56,"column":44}}]},"20":{"type":"branch","line":60,"loc":{"start":{"line":60,"column":37},"end":{"line":68,"column":4}},"locations":[{"start":{"line":60,"column":37},"end":{"line":68,"column":4}}]},"21":{"type":"branch","line":81,"loc":{"start":{"line":81,"column":20},"end":{"line":88,"column":16}},"locations":[{"start":{"line":81,"column":20},"end":{"line":88,"column":16}}]},"22":{"type":"branch","line":99,"loc":{"start":{"line":99,"column":25},"end":{"line":103,"column":10}},"locations":[{"start":{"line":99,"column":25},"end":{"line":103,"column":10}}]},"23":{"type":"branch","line":104,"loc":{"start":{"line":104,"column":20},"end":{"line":111,"column":16}},"locations":[{"start":{"line":104,"column":20},"end":{"line":111,"column":16}}]},"24":{"type":"branch","line":136,"loc":{"start":{"line":136,"column":23},"end":{"line":136,"column":64}},"locations":[{"start":{"line":136,"column":23},"end":{"line":136,"column":64}}]},"25":{"type":"branch","line":161,"loc":{"start":{"line":161,"column":22},"end":{"line":184,"column":17}},"locations":[{"start":{"line":161,"column":22},"end":{"line":184,"column":17}}]},"26":{"type":"branch","line":173,"loc":{"start":{"line":173,"column":49},"end":{"line":173,"column":57}},"locations":[{"start":{"line":173,"column":49},"end":{"line":173,"column":57}}]},"27":{"type":"branch","line":174,"loc":{"start":{"line":174,"column":34},"end":{"line":178,"column":28}},"locations":[{"start":{"line":174,"column":34},"end":{"line":178,"column":28}}]}},"b":{"0":[16],"1":[0],"2":[0],"3":[2],"4":[14],"5":[4],"6":[2],"7":[14],"8":[4],"9":[10],"10":[2],"11":[1],"12":[15],"13":[2],"14":[13],"15":[4],"16":[9],"17":[1],"18":[2],"19":[0],"20":[1],"21":[24],"22":[2],"23":[24],"24":[1],"25":[8],"26":[5],"27":[2]},"fnMap":{"0":{"name":"ResourcesTab","decl":{"start":{"line":15,"column":21},"end":{"line":203,"column":2}},"loc":{"start":{"line":15,"column":21},"end":{"line":203,"column":2}},"line":15},"1":{"name":"fillTemplate","decl":{"start":{"line":50,"column":23},"end":{"line":58,"column":4}},"loc":{"start":{"line":50,"column":23},"end":{"line":58,"column":4}},"line":50},"2":{"name":"handleReadTemplateResource","decl":{"start":{"line":60,"column":37},"end":{"line":68,"column":4}},"loc":{"start":{"line":60,"column":37},"end":{"line":68,"column":4}},"line":60},"3":{"name":"setSelectedItem","decl":{"start":{"line":76,"column":25},"end":{"line":80,"column":10}},"loc":{"start":{"line":76,"column":25},"end":{"line":80,"column":10}},"line":76},"4":{"name":"renderItem","decl":{"start":{"line":81,"column":20},"end":{"line":88,"column":16}},"loc":{"start":{"line":81,"column":20},"end":{"line":88,"column":16}},"line":81},"5":{"name":"setSelectedItem","decl":{"start":{"line":99,"column":25},"end":{"line":103,"column":10}},"loc":{"start":{"line":99,"column":25},"end":{"line":103,"column":10}},"line":99},"6":{"name":"renderItem","decl":{"start":{"line":104,"column":20},"end":{"line":111,"column":16}},"loc":{"start":{"line":104,"column":20},"end":{"line":111,"column":16}},"line":104},"7":{"name":"onClick","decl":{"start":{"line":136,"column":23},"end":{"line":136,"column":64}},"loc":{"start":{"line":136,"column":23},"end":{"line":136,"column":64}},"line":136},"8":{"name":"onChange","decl":{"start":{"line":174,"column":34},"end":{"line":178,"column":28}},"loc":{"start":{"line":174,"column":34},"end":{"line":178,"column":28}},"line":174}},"f":{"0":16,"1":1,"2":1,"3":0,"4":24,"5":2,"6":24,"7":1,"8":2}} +,"/Users/ashwin/code/mcp/inspector/client/src/components/RootsTab.tsx": {"path":"/Users/ashwin/code/mcp/inspector/client/src/components/RootsTab.tsx","all":false,"statementMap":{"0":{"start":{"line":1,"column":0},"end":{"line":1,"column":64}},"1":{"start":{"line":2,"column":0},"end":{"line":2,"column":48}},"2":{"start":{"line":3,"column":0},"end":{"line":3,"column":46}},"3":{"start":{"line":4,"column":0},"end":{"line":4,"column":51}},"5":{"start":{"line":6,"column":0},"end":{"line":6,"column":49}},"7":{"start":{"line":8,"column":0},"end":{"line":8,"column":19}},"8":{"start":{"line":9,"column":0},"end":{"line":9,"column":8}},"9":{"start":{"line":10,"column":0},"end":{"line":10,"column":11}},"10":{"start":{"line":11,"column":0},"end":{"line":11,"column":16}},"11":{"start":{"line":12,"column":0},"end":{"line":12,"column":4}},"15":{"start":{"line":16,"column":0},"end":{"line":16,"column":7}},"16":{"start":{"line":17,"column":0},"end":{"line":17,"column":25}},"17":{"start":{"line":18,"column":0},"end":{"line":18,"column":80}},"18":{"start":{"line":19,"column":0},"end":{"line":19,"column":4}},"20":{"start":{"line":21,"column":0},"end":{"line":21,"column":41}},"21":{"start":{"line":22,"column":0},"end":{"line":22,"column":75}},"22":{"start":{"line":23,"column":0},"end":{"line":23,"column":4}},"24":{"start":{"line":25,"column":0},"end":{"line":25,"column":75}},"25":{"start":{"line":26,"column":0},"end":{"line":26,"column":30}},"26":{"start":{"line":27,"column":0},"end":{"line":27,"column":35}},"27":{"start":{"line":28,"column":0},"end":{"line":28,"column":57}},"28":{"start":{"line":29,"column":0},"end":{"line":29,"column":8}},"29":{"start":{"line":30,"column":0},"end":{"line":30,"column":6}},"30":{"start":{"line":31,"column":0},"end":{"line":31,"column":4}},"32":{"start":{"line":33,"column":0},"end":{"line":33,"column":28}},"33":{"start":{"line":34,"column":0},"end":{"line":34,"column":20}},"34":{"start":{"line":35,"column":0},"end":{"line":35,"column":4}},"36":{"start":{"line":37,"column":0},"end":{"line":37,"column":10}},"37":{"start":{"line":38,"column":0},"end":{"line":38,"column":53}},"38":{"start":{"line":39,"column":0},"end":{"line":39,"column":13}},"39":{"start":{"line":40,"column":0},"end":{"line":40,"column":26}},"41":{"start":{"line":42,"column":0},"end":{"line":42,"column":27}},"42":{"start":{"line":43,"column":0},"end":{"line":43,"column":14}},"44":{"start":{"line":45,"column":0},"end":{"line":45,"column":35}},"45":{"start":{"line":46,"column":0},"end":{"line":46,"column":61}},"46":{"start":{"line":47,"column":0},"end":{"line":47,"column":16}},"47":{"start":{"line":48,"column":0},"end":{"line":48,"column":37}},"48":{"start":{"line":49,"column":0},"end":{"line":49,"column":28}},"49":{"start":{"line":50,"column":0},"end":{"line":50,"column":70}},"50":{"start":{"line":51,"column":0},"end":{"line":51,"column":30}},"51":{"start":{"line":52,"column":0},"end":{"line":52,"column":12}},"52":{"start":{"line":53,"column":0},"end":{"line":53,"column":17}},"53":{"start":{"line":54,"column":0},"end":{"line":54,"column":33}},"54":{"start":{"line":55,"column":0},"end":{"line":55,"column":21}},"55":{"start":{"line":56,"column":0},"end":{"line":56,"column":45}},"56":{"start":{"line":57,"column":0},"end":{"line":57,"column":36}},"58":{"start":{"line":59,"column":0},"end":{"line":59,"column":41}},"59":{"start":{"line":60,"column":0},"end":{"line":60,"column":19}},"60":{"start":{"line":61,"column":0},"end":{"line":61,"column":14}},"61":{"start":{"line":62,"column":0},"end":{"line":62,"column":9}},"63":{"start":{"line":64,"column":0},"end":{"line":64,"column":34}},"64":{"start":{"line":65,"column":0},"end":{"line":65,"column":52}},"65":{"start":{"line":66,"column":0},"end":{"line":66,"column":43}},"67":{"start":{"line":68,"column":0},"end":{"line":68,"column":17}},"68":{"start":{"line":69,"column":0},"end":{"line":69,"column":37}},"69":{"start":{"line":70,"column":0},"end":{"line":70,"column":43}},"71":{"start":{"line":72,"column":0},"end":{"line":72,"column":17}},"72":{"start":{"line":73,"column":0},"end":{"line":73,"column":12}},"73":{"start":{"line":74,"column":0},"end":{"line":74,"column":18}},"75":{"start":{"line":76,"column":0},"end":{"line":76,"column":2}},"77":{"start":{"line":78,"column":0},"end":{"line":78,"column":24}}},"s":{"0":1,"1":1,"2":1,"3":1,"5":1,"7":1,"8":9,"9":9,"10":9,"11":9,"15":9,"16":9,"17":1,"18":1,"20":9,"21":1,"22":1,"24":9,"25":1,"26":1,"27":2,"28":1,"29":1,"30":1,"32":9,"33":1,"34":1,"36":9,"37":9,"38":9,"39":9,"41":9,"42":9,"44":9,"45":10,"46":10,"47":10,"48":10,"49":10,"50":10,"51":10,"52":10,"53":10,"54":10,"55":10,"56":10,"58":10,"59":10,"60":10,"61":9,"63":9,"64":9,"65":9,"67":9,"68":9,"69":9,"71":9,"72":9,"73":9,"75":9,"77":1},"branchMap":{"0":{"type":"branch","line":8,"loc":{"start":{"line":8,"column":17},"end":{"line":76,"column":2}},"locations":[{"start":{"line":8,"column":17},"end":{"line":76,"column":2}}]},"1":{"type":"branch","line":17,"loc":{"start":{"line":17,"column":18},"end":{"line":19,"column":4}},"locations":[{"start":{"line":17,"column":18},"end":{"line":19,"column":4}}]},"2":{"type":"branch","line":18,"loc":{"start":{"line":18,"column":13},"end":{"line":18,"column":78}},"locations":[{"start":{"line":18,"column":13},"end":{"line":18,"column":78}}]},"3":{"type":"branch","line":21,"loc":{"start":{"line":21,"column":21},"end":{"line":23,"column":4}},"locations":[{"start":{"line":21,"column":21},"end":{"line":23,"column":4}}]},"4":{"type":"branch","line":22,"loc":{"start":{"line":22,"column":13},"end":{"line":22,"column":73}},"locations":[{"start":{"line":22,"column":13},"end":{"line":22,"column":73}}]},"5":{"type":"branch","line":22,"loc":{"start":{"line":22,"column":51},"end":{"line":22,"column":72}},"locations":[{"start":{"line":22,"column":51},"end":{"line":22,"column":72}}]},"6":{"type":"branch","line":25,"loc":{"start":{"line":25,"column":21},"end":{"line":31,"column":4}},"locations":[{"start":{"line":25,"column":21},"end":{"line":31,"column":4}}]},"7":{"type":"branch","line":26,"loc":{"start":{"line":26,"column":13},"end":{"line":29,"column":8}},"locations":[{"start":{"line":26,"column":13},"end":{"line":29,"column":8}}]},"8":{"type":"branch","line":27,"loc":{"start":{"line":27,"column":23},"end":{"line":28,"column":57}},"locations":[{"start":{"line":27,"column":23},"end":{"line":28,"column":57}}]},"9":{"type":"branch","line":28,"loc":{"start":{"line":28,"column":14},"end":{"line":28,"column":52}},"locations":[{"start":{"line":28,"column":14},"end":{"line":28,"column":52}}]},"10":{"type":"branch","line":28,"loc":{"start":{"line":28,"column":48},"end":{"line":28,"column":57}},"locations":[{"start":{"line":28,"column":48},"end":{"line":28,"column":57}}]},"11":{"type":"branch","line":33,"loc":{"start":{"line":33,"column":21},"end":{"line":35,"column":4}},"locations":[{"start":{"line":33,"column":21},"end":{"line":35,"column":4}}]},"12":{"type":"branch","line":45,"loc":{"start":{"line":45,"column":17},"end":{"line":61,"column":14}},"locations":[{"start":{"line":45,"column":17},"end":{"line":61,"column":14}}]},"13":{"type":"branch","line":50,"loc":{"start":{"line":50,"column":22},"end":{"line":50,"column":70}},"locations":[{"start":{"line":50,"column":22},"end":{"line":50,"column":70}}]},"14":{"type":"branch","line":56,"loc":{"start":{"line":56,"column":21},"end":{"line":56,"column":45}},"locations":[{"start":{"line":56,"column":21},"end":{"line":56,"column":45}}]}},"b":{"0":[9],"1":[1],"2":[1],"3":[1],"4":[1],"5":[2],"6":[1],"7":[1],"8":[2],"9":[1],"10":[1],"11":[1],"12":[10],"13":[1],"14":[1]},"fnMap":{"0":{"name":"RootsTab","decl":{"start":{"line":8,"column":17},"end":{"line":76,"column":2}},"loc":{"start":{"line":8,"column":17},"end":{"line":76,"column":2}},"line":8},"1":{"name":"addRoot","decl":{"start":{"line":17,"column":18},"end":{"line":19,"column":4}},"loc":{"start":{"line":17,"column":18},"end":{"line":19,"column":4}},"line":17},"2":{"name":"removeRoot","decl":{"start":{"line":21,"column":21},"end":{"line":23,"column":4}},"loc":{"start":{"line":21,"column":21},"end":{"line":23,"column":4}},"line":21},"3":{"name":"updateRoot","decl":{"start":{"line":25,"column":21},"end":{"line":31,"column":4}},"loc":{"start":{"line":25,"column":21},"end":{"line":31,"column":4}},"line":25},"4":{"name":"handleSave","decl":{"start":{"line":33,"column":21},"end":{"line":35,"column":4}},"loc":{"start":{"line":33,"column":21},"end":{"line":35,"column":4}},"line":33},"5":{"name":"onChange","decl":{"start":{"line":50,"column":22},"end":{"line":50,"column":70}},"loc":{"start":{"line":50,"column":22},"end":{"line":50,"column":70}},"line":50},"6":{"name":"onClick","decl":{"start":{"line":56,"column":21},"end":{"line":56,"column":45}},"loc":{"start":{"line":56,"column":21},"end":{"line":56,"column":45}},"line":56}},"f":{"0":9,"1":1,"2":1,"3":1,"4":1,"5":1,"6":1}} +,"/Users/ashwin/code/mcp/inspector/client/src/components/SamplingTab.tsx": {"path":"/Users/ashwin/code/mcp/inspector/client/src/components/SamplingTab.tsx","all":false,"statementMap":{"0":{"start":{"line":1,"column":0},"end":{"line":1,"column":64}},"1":{"start":{"line":2,"column":0},"end":{"line":2,"column":48}},"2":{"start":{"line":3,"column":0},"end":{"line":3,"column":51}},"19":{"start":{"line":20,"column":0},"end":{"line":20,"column":74}},"20":{"start":{"line":21,"column":0},"end":{"line":21,"column":41}},"22":{"start":{"line":23,"column":0},"end":{"line":23,"column":19}},"23":{"start":{"line":24,"column":0},"end":{"line":24,"column":26}},"24":{"start":{"line":25,"column":0},"end":{"line":25,"column":28}},"25":{"start":{"line":26,"column":0},"end":{"line":26,"column":24}},"26":{"start":{"line":27,"column":0},"end":{"line":27,"column":16}},"27":{"start":{"line":28,"column":0},"end":{"line":28,"column":21}},"28":{"start":{"line":29,"column":0},"end":{"line":29,"column":41}},"29":{"start":{"line":30,"column":0},"end":{"line":30,"column":8}},"30":{"start":{"line":31,"column":0},"end":{"line":31,"column":7}},"31":{"start":{"line":32,"column":0},"end":{"line":32,"column":4}},"33":{"start":{"line":34,"column":0},"end":{"line":34,"column":10}},"34":{"start":{"line":35,"column":0},"end":{"line":35,"column":51}},"35":{"start":{"line":36,"column":0},"end":{"line":36,"column":13}},"36":{"start":{"line":37,"column":0},"end":{"line":37,"column":26}},"39":{"start":{"line":40,"column":0},"end":{"line":40,"column":27}},"40":{"start":{"line":41,"column":0},"end":{"line":41,"column":14}},"41":{"start":{"line":42,"column":0},"end":{"line":42,"column":38}},"42":{"start":{"line":43,"column":0},"end":{"line":43,"column":66}},"43":{"start":{"line":44,"column":0},"end":{"line":44,"column":43}},"44":{"start":{"line":45,"column":0},"end":{"line":45,"column":76}},"45":{"start":{"line":46,"column":0},"end":{"line":46,"column":52}},"46":{"start":{"line":47,"column":0},"end":{"line":47,"column":56}},"47":{"start":{"line":48,"column":0},"end":{"line":48,"column":18}},"48":{"start":{"line":49,"column":0},"end":{"line":49,"column":44}},"49":{"start":{"line":50,"column":0},"end":{"line":50,"column":80}},"50":{"start":{"line":51,"column":0},"end":{"line":51,"column":77}},"52":{"start":{"line":53,"column":0},"end":{"line":53,"column":23}},"53":{"start":{"line":54,"column":0},"end":{"line":54,"column":18}},"54":{"start":{"line":55,"column":0},"end":{"line":55,"column":16}},"55":{"start":{"line":56,"column":0},"end":{"line":56,"column":11}},"56":{"start":{"line":57,"column":0},"end":{"line":57,"column":42}},"57":{"start":{"line":58,"column":0},"end":{"line":58,"column":62}},"59":{"start":{"line":60,"column":0},"end":{"line":60,"column":12}},"60":{"start":{"line":61,"column":0},"end":{"line":61,"column":18}},"62":{"start":{"line":63,"column":0},"end":{"line":63,"column":2}},"64":{"start":{"line":65,"column":0},"end":{"line":65,"column":27}}},"s":{"0":1,"1":1,"2":1,"19":1,"20":10,"22":1,"23":1,"24":1,"25":1,"26":1,"27":1,"28":1,"29":1,"30":1,"31":1,"33":10,"34":10,"35":10,"36":10,"39":10,"40":10,"41":10,"42":10,"43":10,"44":10,"45":10,"46":10,"47":10,"48":10,"49":10,"50":10,"52":10,"53":10,"54":10,"55":10,"56":10,"57":5,"59":10,"60":10,"62":10,"64":1},"branchMap":{"0":{"type":"branch","line":20,"loc":{"start":{"line":20,"column":20},"end":{"line":63,"column":2}},"locations":[{"start":{"line":20,"column":20},"end":{"line":63,"column":2}}]},"1":{"type":"branch","line":57,"loc":{"start":{"line":57,"column":36},"end":{"line":58,"column":62}},"locations":[{"start":{"line":57,"column":36},"end":{"line":58,"column":62}}]},"2":{"type":"branch","line":21,"loc":{"start":{"line":21,"column":24},"end":{"line":32,"column":4}},"locations":[{"start":{"line":21,"column":24},"end":{"line":32,"column":4}}]},"3":{"type":"branch","line":44,"loc":{"start":{"line":44,"column":29},"end":{"line":55,"column":16}},"locations":[{"start":{"line":44,"column":29},"end":{"line":55,"column":16}}]},"4":{"type":"branch","line":50,"loc":{"start":{"line":50,"column":31},"end":{"line":50,"column":64}},"locations":[{"start":{"line":50,"column":31},"end":{"line":50,"column":64}}]},"5":{"type":"branch","line":51,"loc":{"start":{"line":51,"column":49},"end":{"line":51,"column":77}},"locations":[{"start":{"line":51,"column":49},"end":{"line":51,"column":77}}]}},"b":{"0":[10],"1":[5],"2":[1],"3":[10],"4":[1],"5":[1]},"fnMap":{"0":{"name":"SamplingTab","decl":{"start":{"line":20,"column":20},"end":{"line":63,"column":2}},"loc":{"start":{"line":20,"column":20},"end":{"line":63,"column":2}},"line":20},"1":{"name":"handleApprove","decl":{"start":{"line":21,"column":24},"end":{"line":32,"column":4}},"loc":{"start":{"line":21,"column":24},"end":{"line":32,"column":4}},"line":21},"2":{"name":"onClick","decl":{"start":{"line":50,"column":31},"end":{"line":50,"column":64}},"loc":{"start":{"line":50,"column":31},"end":{"line":50,"column":64}},"line":50},"3":{"name":"onClick","decl":{"start":{"line":51,"column":49},"end":{"line":51,"column":77}},"loc":{"start":{"line":51,"column":49},"end":{"line":51,"column":77}},"line":51}},"f":{"0":10,"1":1,"2":1,"3":1}} +,"/Users/ashwin/code/mcp/inspector/client/src/components/Sidebar.tsx": {"path":"/Users/ashwin/code/mcp/inspector/client/src/components/Sidebar.tsx","all":false,"statementMap":{"0":{"start":{"line":1,"column":0},"end":{"line":1,"column":33}},"1":{"start":{"line":2,"column":0},"end":{"line":2,"column":88}},"2":{"start":{"line":3,"column":0},"end":{"line":3,"column":48}},"3":{"start":{"line":4,"column":0},"end":{"line":4,"column":46}},"10":{"start":{"line":11,"column":0},"end":{"line":11,"column":32}},"13":{"start":{"line":14,"column":0},"end":{"line":14,"column":39}},"14":{"start":{"line":15,"column":0},"end":{"line":15,"column":48}},"32":{"start":{"line":33,"column":0},"end":{"line":33,"column":18}},"33":{"start":{"line":34,"column":0},"end":{"line":34,"column":19}},"34":{"start":{"line":35,"column":0},"end":{"line":35,"column":16}},"35":{"start":{"line":36,"column":0},"end":{"line":36,"column":19}},"36":{"start":{"line":37,"column":0},"end":{"line":37,"column":10}},"37":{"start":{"line":38,"column":0},"end":{"line":38,"column":13}},"38":{"start":{"line":39,"column":0},"end":{"line":39,"column":7}},"39":{"start":{"line":40,"column":0},"end":{"line":40,"column":10}},"40":{"start":{"line":41,"column":0},"end":{"line":41,"column":9}},"41":{"start":{"line":42,"column":0},"end":{"line":42,"column":12}},"42":{"start":{"line":43,"column":0},"end":{"line":43,"column":6}},"43":{"start":{"line":44,"column":0},"end":{"line":44,"column":9}},"44":{"start":{"line":45,"column":0},"end":{"line":45,"column":12}},"45":{"start":{"line":46,"column":0},"end":{"line":46,"column":22}},"46":{"start":{"line":47,"column":0},"end":{"line":47,"column":21}},"47":{"start":{"line":48,"column":0},"end":{"line":48,"column":39}},"48":{"start":{"line":49,"column":0},"end":{"line":49,"column":56}},"50":{"start":{"line":51,"column":0},"end":{"line":51,"column":10}},"51":{"start":{"line":52,"column":0},"end":{"line":52,"column":78}},"52":{"start":{"line":53,"column":0},"end":{"line":53,"column":86}},"53":{"start":{"line":54,"column":0},"end":{"line":54,"column":43}},"54":{"start":{"line":55,"column":0},"end":{"line":55,"column":53}},"55":{"start":{"line":56,"column":0},"end":{"line":56,"column":36}},"56":{"start":{"line":57,"column":0},"end":{"line":57,"column":15}},"57":{"start":{"line":58,"column":0},"end":{"line":58,"column":14}},"58":{"start":{"line":59,"column":0},"end":{"line":59,"column":12}},"60":{"start":{"line":61,"column":0},"end":{"line":61,"column":48}},"61":{"start":{"line":62,"column":0},"end":{"line":62,"column":35}},"62":{"start":{"line":63,"column":0},"end":{"line":63,"column":37}},"63":{"start":{"line":64,"column":0},"end":{"line":64,"column":73}},"64":{"start":{"line":65,"column":0},"end":{"line":65,"column":19}},"65":{"start":{"line":66,"column":0},"end":{"line":66,"column":35}},"66":{"start":{"line":67,"column":0},"end":{"line":67,"column":56}},"67":{"start":{"line":68,"column":0},"end":{"line":68,"column":39}},"70":{"start":{"line":71,"column":0},"end":{"line":71,"column":29}},"71":{"start":{"line":72,"column":0},"end":{"line":72,"column":67}},"72":{"start":{"line":73,"column":0},"end":{"line":73,"column":30}},"73":{"start":{"line":74,"column":0},"end":{"line":74,"column":29}},"74":{"start":{"line":75,"column":0},"end":{"line":75,"column":60}},"75":{"start":{"line":76,"column":0},"end":{"line":76,"column":56}},"76":{"start":{"line":77,"column":0},"end":{"line":77,"column":30}},"77":{"start":{"line":78,"column":0},"end":{"line":78,"column":21}},"78":{"start":{"line":79,"column":0},"end":{"line":79,"column":16}},"80":{"start":{"line":81,"column":0},"end":{"line":81,"column":40}},"81":{"start":{"line":82,"column":0},"end":{"line":82,"column":14}},"82":{"start":{"line":83,"column":0},"end":{"line":83,"column":41}},"83":{"start":{"line":84,"column":0},"end":{"line":84,"column":70}},"84":{"start":{"line":85,"column":0},"end":{"line":85,"column":22}},"85":{"start":{"line":86,"column":0},"end":{"line":86,"column":39}},"86":{"start":{"line":87,"column":0},"end":{"line":87,"column":33}},"87":{"start":{"line":88,"column":0},"end":{"line":88,"column":62}},"88":{"start":{"line":89,"column":0},"end":{"line":89,"column":39}},"89":{"start":{"line":90,"column":0},"end":{"line":90,"column":18}},"90":{"start":{"line":91,"column":0},"end":{"line":91,"column":20}},"91":{"start":{"line":92,"column":0},"end":{"line":92,"column":41}},"92":{"start":{"line":93,"column":0},"end":{"line":93,"column":72}},"93":{"start":{"line":94,"column":0},"end":{"line":94,"column":22}},"94":{"start":{"line":95,"column":0},"end":{"line":95,"column":59}},"95":{"start":{"line":96,"column":0},"end":{"line":96,"column":30}},"96":{"start":{"line":97,"column":0},"end":{"line":97,"column":59}},"97":{"start":{"line":98,"column":0},"end":{"line":98,"column":39}},"98":{"start":{"line":99,"column":0},"end":{"line":99,"column":18}},"99":{"start":{"line":100,"column":0},"end":{"line":100,"column":20}},"100":{"start":{"line":101,"column":0},"end":{"line":101,"column":15}},"102":{"start":{"line":103,"column":0},"end":{"line":103,"column":39}},"103":{"start":{"line":104,"column":0},"end":{"line":104,"column":64}},"104":{"start":{"line":105,"column":0},"end":{"line":105,"column":20}},"105":{"start":{"line":106,"column":0},"end":{"line":106,"column":33}},"106":{"start":{"line":107,"column":0},"end":{"line":107,"column":30}},"107":{"start":{"line":108,"column":0},"end":{"line":108,"column":59}},"108":{"start":{"line":109,"column":0},"end":{"line":109,"column":37}},"109":{"start":{"line":110,"column":0},"end":{"line":110,"column":16}},"110":{"start":{"line":111,"column":0},"end":{"line":111,"column":18}},"112":{"start":{"line":113,"column":0},"end":{"line":113,"column":41}},"113":{"start":{"line":114,"column":0},"end":{"line":114,"column":39}},"114":{"start":{"line":115,"column":0},"end":{"line":115,"column":21}},"115":{"start":{"line":116,"column":0},"end":{"line":116,"column":33}},"116":{"start":{"line":117,"column":0},"end":{"line":117,"column":60}},"117":{"start":{"line":118,"column":0},"end":{"line":118,"column":52}},"119":{"start":{"line":120,"column":0},"end":{"line":120,"column":32}},"120":{"start":{"line":121,"column":0},"end":{"line":121,"column":58}},"122":{"start":{"line":123,"column":0},"end":{"line":123,"column":59}},"123":{"start":{"line":124,"column":0},"end":{"line":124,"column":18}},"125":{"start":{"line":126,"column":0},"end":{"line":126,"column":23}},"126":{"start":{"line":127,"column":0},"end":{"line":127,"column":31}},"127":{"start":{"line":128,"column":0},"end":{"line":128,"column":43}},"128":{"start":{"line":129,"column":0},"end":{"line":129,"column":67}},"129":{"start":{"line":130,"column":0},"end":{"line":130,"column":79}},"130":{"start":{"line":131,"column":0},"end":{"line":131,"column":49}},"131":{"start":{"line":132,"column":0},"end":{"line":132,"column":30}},"132":{"start":{"line":133,"column":0},"end":{"line":133,"column":43}},"133":{"start":{"line":134,"column":0},"end":{"line":134,"column":37}},"134":{"start":{"line":135,"column":0},"end":{"line":135,"column":44}},"135":{"start":{"line":136,"column":0},"end":{"line":136,"column":54}},"136":{"start":{"line":137,"column":0},"end":{"line":137,"column":47}},"137":{"start":{"line":138,"column":0},"end":{"line":138,"column":59}},"138":{"start":{"line":139,"column":0},"end":{"line":139,"column":43}},"139":{"start":{"line":140,"column":0},"end":{"line":140,"column":28}},"140":{"start":{"line":141,"column":0},"end":{"line":141,"column":47}},"141":{"start":{"line":142,"column":0},"end":{"line":142,"column":26}},"142":{"start":{"line":143,"column":0},"end":{"line":143,"column":30}},"143":{"start":{"line":144,"column":0},"end":{"line":144,"column":45}},"144":{"start":{"line":145,"column":0},"end":{"line":145,"column":39}},"145":{"start":{"line":146,"column":0},"end":{"line":146,"column":44}},"146":{"start":{"line":147,"column":0},"end":{"line":147,"column":54}},"147":{"start":{"line":148,"column":0},"end":{"line":148,"column":57}},"148":{"start":{"line":149,"column":0},"end":{"line":149,"column":43}},"149":{"start":{"line":150,"column":0},"end":{"line":150,"column":28}},"150":{"start":{"line":151,"column":0},"end":{"line":151,"column":47}},"151":{"start":{"line":152,"column":0},"end":{"line":152,"column":26}},"152":{"start":{"line":153,"column":0},"end":{"line":153,"column":28}},"153":{"start":{"line":154,"column":0},"end":{"line":154,"column":29}},"154":{"start":{"line":155,"column":0},"end":{"line":155,"column":45}},"155":{"start":{"line":156,"column":0},"end":{"line":156,"column":40}},"157":{"start":{"line":158,"column":0},"end":{"line":158,"column":66}},"158":{"start":{"line":159,"column":0},"end":{"line":159,"column":39}},"159":{"start":{"line":160,"column":0},"end":{"line":160,"column":26}},"160":{"start":{"line":161,"column":0},"end":{"line":161,"column":23}},"162":{"start":{"line":163,"column":0},"end":{"line":163,"column":31}},"163":{"start":{"line":164,"column":0},"end":{"line":164,"column":26}},"164":{"start":{"line":165,"column":0},"end":{"line":165,"column":21}},"165":{"start":{"line":166,"column":0},"end":{"line":166,"column":25}},"166":{"start":{"line":167,"column":0},"end":{"line":167,"column":37}},"167":{"start":{"line":168,"column":0},"end":{"line":168,"column":36}},"168":{"start":{"line":169,"column":0},"end":{"line":169,"column":48}},"169":{"start":{"line":170,"column":0},"end":{"line":170,"column":38}},"170":{"start":{"line":171,"column":0},"end":{"line":171,"column":37}},"171":{"start":{"line":172,"column":0},"end":{"line":172,"column":22}},"172":{"start":{"line":173,"column":0},"end":{"line":173,"column":19}},"174":{"start":{"line":175,"column":0},"end":{"line":175,"column":27}},"175":{"start":{"line":176,"column":0},"end":{"line":176,"column":22}},"177":{"start":{"line":178,"column":0},"end":{"line":178,"column":18}},"180":{"start":{"line":181,"column":0},"end":{"line":181,"column":37}},"181":{"start":{"line":182,"column":0},"end":{"line":182,"column":59}},"182":{"start":{"line":183,"column":0},"end":{"line":183,"column":47}},"184":{"start":{"line":185,"column":0},"end":{"line":185,"column":21}},"186":{"start":{"line":187,"column":0},"end":{"line":187,"column":77}},"187":{"start":{"line":188,"column":0},"end":{"line":188,"column":18}},"188":{"start":{"line":189,"column":0},"end":{"line":189,"column":51}},"189":{"start":{"line":190,"column":0},"end":{"line":190,"column":50}},"190":{"start":{"line":191,"column":0},"end":{"line":191,"column":36}},"191":{"start":{"line":192,"column":0},"end":{"line":192,"column":50}},"192":{"start":{"line":193,"column":0},"end":{"line":193,"column":36}},"193":{"start":{"line":194,"column":0},"end":{"line":194,"column":37}},"194":{"start":{"line":195,"column":0},"end":{"line":195,"column":19}},"195":{"start":{"line":196,"column":0},"end":{"line":196,"column":16}},"196":{"start":{"line":197,"column":0},"end":{"line":197,"column":54}},"197":{"start":{"line":198,"column":0},"end":{"line":198,"column":49}},"198":{"start":{"line":199,"column":0},"end":{"line":199,"column":31}},"199":{"start":{"line":200,"column":0},"end":{"line":200,"column":48}},"200":{"start":{"line":201,"column":0},"end":{"line":201,"column":40}},"201":{"start":{"line":202,"column":0},"end":{"line":202,"column":37}},"202":{"start":{"line":203,"column":0},"end":{"line":203,"column":21}},"203":{"start":{"line":204,"column":0},"end":{"line":204,"column":18}},"204":{"start":{"line":205,"column":0},"end":{"line":205,"column":48}},"205":{"start":{"line":206,"column":0},"end":{"line":206,"column":16}},"206":{"start":{"line":207,"column":0},"end":{"line":207,"column":68}},"207":{"start":{"line":208,"column":0},"end":{"line":208,"column":54}},"209":{"start":{"line":210,"column":0},"end":{"line":210,"column":23}},"210":{"start":{"line":211,"column":0},"end":{"line":211,"column":65}},"211":{"start":{"line":212,"column":0},"end":{"line":212,"column":71}},"212":{"start":{"line":213,"column":0},"end":{"line":213,"column":26}},"213":{"start":{"line":214,"column":0},"end":{"line":214,"column":35}},"214":{"start":{"line":215,"column":0},"end":{"line":215,"column":112}},"216":{"start":{"line":217,"column":0},"end":{"line":217,"column":53}},"217":{"start":{"line":218,"column":0},"end":{"line":218,"column":28}},"218":{"start":{"line":219,"column":0},"end":{"line":219,"column":23}},"219":{"start":{"line":220,"column":0},"end":{"line":220,"column":24}},"220":{"start":{"line":221,"column":0},"end":{"line":221,"column":22}},"221":{"start":{"line":222,"column":0},"end":{"line":222,"column":17}},"223":{"start":{"line":224,"column":0},"end":{"line":224,"column":16}},"224":{"start":{"line":225,"column":0},"end":{"line":225,"column":14}},"225":{"start":{"line":226,"column":0},"end":{"line":226,"column":12}},"226":{"start":{"line":227,"column":0},"end":{"line":227,"column":36}},"227":{"start":{"line":228,"column":0},"end":{"line":228,"column":59}},"228":{"start":{"line":229,"column":0},"end":{"line":229,"column":17}},"229":{"start":{"line":230,"column":0},"end":{"line":230,"column":25}},"230":{"start":{"line":231,"column":0},"end":{"line":231,"column":45}},"231":{"start":{"line":232,"column":0},"end":{"line":232,"column":60}},"234":{"start":{"line":235,"column":0},"end":{"line":235,"column":67}},"235":{"start":{"line":236,"column":0},"end":{"line":236,"column":29}},"236":{"start":{"line":237,"column":0},"end":{"line":237,"column":28}},"237":{"start":{"line":238,"column":0},"end":{"line":238,"column":27}},"238":{"start":{"line":239,"column":0},"end":{"line":239,"column":60}},"239":{"start":{"line":240,"column":0},"end":{"line":240,"column":58}},"240":{"start":{"line":241,"column":0},"end":{"line":241,"column":56}},"241":{"start":{"line":242,"column":0},"end":{"line":242,"column":28}},"242":{"start":{"line":243,"column":0},"end":{"line":243,"column":19}},"244":{"start":{"line":245,"column":0},"end":{"line":245,"column":55}},"245":{"start":{"line":246,"column":0},"end":{"line":246,"column":117}},"246":{"start":{"line":247,"column":0},"end":{"line":247,"column":70}},"247":{"start":{"line":248,"column":0},"end":{"line":248,"column":64}},"248":{"start":{"line":249,"column":0},"end":{"line":249,"column":23}},"249":{"start":{"line":250,"column":0},"end":{"line":250,"column":16}},"250":{"start":{"line":251,"column":0},"end":{"line":251,"column":117}},"251":{"start":{"line":252,"column":0},"end":{"line":252,"column":62}},"252":{"start":{"line":253,"column":0},"end":{"line":253,"column":57}},"253":{"start":{"line":254,"column":0},"end":{"line":254,"column":23}},"254":{"start":{"line":255,"column":0},"end":{"line":255,"column":16}},"255":{"start":{"line":256,"column":0},"end":{"line":256,"column":114}},"256":{"start":{"line":257,"column":0},"end":{"line":257,"column":82}},"257":{"start":{"line":258,"column":0},"end":{"line":258,"column":60}},"258":{"start":{"line":259,"column":0},"end":{"line":259,"column":23}},"259":{"start":{"line":260,"column":0},"end":{"line":260,"column":16}},"260":{"start":{"line":261,"column":0},"end":{"line":261,"column":16}},"261":{"start":{"line":262,"column":0},"end":{"line":262,"column":14}},"262":{"start":{"line":263,"column":0},"end":{"line":263,"column":12}},"263":{"start":{"line":264,"column":0},"end":{"line":264,"column":10}},"265":{"start":{"line":266,"column":0},"end":{"line":266,"column":2}},"267":{"start":{"line":268,"column":0},"end":{"line":268,"column":23}}},"s":{"0":1,"1":1,"2":1,"3":1,"10":1,"13":1,"14":1,"32":1,"33":16,"34":16,"35":16,"36":16,"37":16,"38":16,"39":16,"40":16,"41":16,"42":16,"43":16,"44":16,"45":16,"46":16,"47":16,"48":16,"50":16,"51":16,"52":16,"53":16,"54":16,"55":16,"56":16,"57":16,"58":16,"60":16,"61":16,"62":16,"63":16,"64":16,"65":16,"66":16,"67":0,"70":16,"71":16,"72":16,"73":16,"74":16,"75":16,"76":16,"77":16,"78":16,"80":16,"81":16,"82":16,"83":16,"84":16,"85":16,"86":16,"87":16,"88":16,"89":16,"90":16,"91":16,"92":16,"93":16,"94":16,"95":16,"96":16,"97":16,"98":16,"99":16,"100":16,"102":0,"103":0,"104":0,"105":0,"106":0,"107":0,"108":0,"109":0,"110":0,"112":16,"113":16,"114":16,"115":16,"116":16,"117":16,"119":16,"120":0,"122":16,"123":16,"125":16,"126":16,"127":0,"128":0,"129":0,"130":0,"131":0,"132":0,"133":0,"134":0,"135":0,"136":0,"137":0,"138":0,"139":0,"140":0,"141":0,"142":0,"143":0,"144":0,"145":0,"146":0,"147":0,"148":0,"149":0,"150":0,"151":0,"152":0,"153":0,"154":0,"155":0,"157":0,"158":0,"159":0,"160":0,"162":0,"163":0,"164":0,"165":0,"166":0,"167":0,"168":0,"169":0,"170":0,"171":0,"172":0,"174":0,"175":0,"177":16,"180":16,"181":16,"182":16,"184":16,"186":16,"187":16,"188":16,"189":16,"190":9,"191":7,"192":0,"193":7,"194":16,"195":16,"196":16,"197":16,"198":9,"199":7,"200":0,"201":7,"202":16,"203":16,"204":16,"205":0,"206":0,"207":0,"209":0,"210":0,"211":0,"212":0,"213":0,"214":0,"216":0,"217":0,"218":0,"219":0,"220":0,"221":0,"223":16,"224":16,"225":16,"226":16,"227":16,"228":16,"229":16,"230":16,"231":0,"234":16,"235":16,"236":16,"237":16,"238":16,"239":16,"240":16,"241":16,"242":16,"244":16,"245":16,"246":16,"247":16,"248":16,"249":16,"250":16,"251":16,"252":16,"253":16,"254":16,"255":16,"256":16,"257":16,"258":16,"259":16,"260":16,"261":16,"262":16,"263":16,"265":16,"267":1},"branchMap":{"0":{"type":"branch","line":33,"loc":{"start":{"line":33,"column":16},"end":{"line":266,"column":2}},"locations":[{"start":{"line":33,"column":16},"end":{"line":266,"column":2}}]},"1":{"type":"branch","line":101,"loc":{"start":{"line":101,"column":12},"end":{"line":111,"column":18}},"locations":[{"start":{"line":101,"column":12},"end":{"line":111,"column":18}}]},"2":{"type":"branch","line":120,"loc":{"start":{"line":120,"column":17},"end":{"line":121,"column":58}},"locations":[{"start":{"line":120,"column":17},"end":{"line":121,"column":58}}]},"3":{"type":"branch","line":127,"loc":{"start":{"line":127,"column":15},"end":{"line":176,"column":22}},"locations":[{"start":{"line":127,"column":15},"end":{"line":176,"column":22}}]},"4":{"type":"branch","line":190,"loc":{"start":{"line":190,"column":39},"end":{"line":191,"column":36}},"locations":[{"start":{"line":190,"column":39},"end":{"line":191,"column":36}}]},"5":{"type":"branch","line":191,"loc":{"start":{"line":191,"column":22},"end":{"line":194,"column":37}},"locations":[{"start":{"line":191,"column":22},"end":{"line":194,"column":37}}]},"6":{"type":"branch","line":192,"loc":{"start":{"line":192,"column":43},"end":{"line":193,"column":36}},"locations":[{"start":{"line":192,"column":43},"end":{"line":193,"column":36}}]},"7":{"type":"branch","line":198,"loc":{"start":{"line":198,"column":38},"end":{"line":199,"column":31}},"locations":[{"start":{"line":198,"column":38},"end":{"line":199,"column":31}}]},"8":{"type":"branch","line":199,"loc":{"start":{"line":199,"column":20},"end":{"line":202,"column":37}},"locations":[{"start":{"line":199,"column":20},"end":{"line":202,"column":37}}]},"9":{"type":"branch","line":200,"loc":{"start":{"line":200,"column":41},"end":{"line":201,"column":40}},"locations":[{"start":{"line":200,"column":41},"end":{"line":201,"column":40}}]},"10":{"type":"branch","line":205,"loc":{"start":{"line":205,"column":42},"end":{"line":222,"column":17}},"locations":[{"start":{"line":205,"column":42},"end":{"line":222,"column":17}}]},"11":{"type":"branch","line":88,"loc":{"start":{"line":88,"column":28},"end":{"line":88,"column":62}},"locations":[{"start":{"line":88,"column":28},"end":{"line":88,"column":62}}]}},"b":{"0":[16],"1":[0],"2":[0],"3":[0],"4":[9],"5":[7],"6":[0],"7":[9],"8":[7],"9":[0],"10":[0],"11":[1]},"fnMap":{"0":{"name":"Sidebar","decl":{"start":{"line":33,"column":16},"end":{"line":266,"column":2}},"loc":{"start":{"line":33,"column":16},"end":{"line":266,"column":2}},"line":33},"1":{"name":"onValueChange","decl":{"start":{"line":67,"column":29},"end":{"line":68,"column":39}},"loc":{"start":{"line":67,"column":29},"end":{"line":68,"column":39}},"line":67},"2":{"name":"onChange","decl":{"start":{"line":88,"column":28},"end":{"line":88,"column":62}},"loc":{"start":{"line":88,"column":28},"end":{"line":88,"column":62}},"line":88},"3":{"name":"onChange","decl":{"start":{"line":97,"column":28},"end":{"line":97,"column":59}},"loc":{"start":{"line":97,"column":28},"end":{"line":97,"column":59}},"line":97},"4":{"name":"onChange","decl":{"start":{"line":108,"column":26},"end":{"line":108,"column":59}},"loc":{"start":{"line":108,"column":26},"end":{"line":108,"column":59}},"line":108},"5":{"name":"onClick","decl":{"start":{"line":117,"column":25},"end":{"line":117,"column":60}},"loc":{"start":{"line":117,"column":25},"end":{"line":117,"column":60}},"line":117},"6":{"name":"onClick","decl":{"start":{"line":168,"column":29},"end":{"line":172,"column":22}},"loc":{"start":{"line":168,"column":29},"end":{"line":172,"column":22}},"line":168},"7":{"name":"onValueChange","decl":{"start":{"line":231,"column":27},"end":{"line":232,"column":60}},"loc":{"start":{"line":231,"column":27},"end":{"line":232,"column":60}},"line":231}},"f":{"0":16,"1":0,"2":1,"3":0,"4":0,"5":0,"6":0,"7":0}} +,"/Users/ashwin/code/mcp/inspector/client/src/components/ToolsTab.tsx": {"path":"/Users/ashwin/code/mcp/inspector/client/src/components/ToolsTab.tsx","all":false,"statementMap":{"0":{"start":{"line":1,"column":0},"end":{"line":1,"column":76}},"1":{"start":{"line":2,"column":0},"end":{"line":2,"column":48}},"2":{"start":{"line":3,"column":0},"end":{"line":3,"column":46}},"3":{"start":{"line":4,"column":0},"end":{"line":4,"column":46}},"4":{"start":{"line":5,"column":0},"end":{"line":5,"column":51}},"5":{"start":{"line":6,"column":0},"end":{"line":6,"column":52}},"10":{"start":{"line":11,"column":0},"end":{"line":11,"column":44}},"11":{"start":{"line":12,"column":0},"end":{"line":12,"column":49}},"12":{"start":{"line":13,"column":0},"end":{"line":13,"column":44}},"13":{"start":{"line":14,"column":0},"end":{"line":14,"column":34}},"17":{"start":{"line":18,"column":0},"end":{"line":18,"column":19}},"18":{"start":{"line":19,"column":0},"end":{"line":19,"column":8}},"19":{"start":{"line":20,"column":0},"end":{"line":20,"column":12}},"20":{"start":{"line":21,"column":0},"end":{"line":21,"column":13}},"21":{"start":{"line":22,"column":0},"end":{"line":22,"column":11}},"22":{"start":{"line":23,"column":0},"end":{"line":23,"column":15}},"23":{"start":{"line":24,"column":0},"end":{"line":24,"column":18}},"24":{"start":{"line":25,"column":0},"end":{"line":25,"column":13}},"25":{"start":{"line":26,"column":0},"end":{"line":26,"column":13}},"26":{"start":{"line":27,"column":0},"end":{"line":27,"column":8}},"27":{"start":{"line":28,"column":0},"end":{"line":28,"column":4}},"37":{"start":{"line":38,"column":0},"end":{"line":38,"column":7}},"38":{"start":{"line":39,"column":0},"end":{"line":39,"column":68}},"39":{"start":{"line":40,"column":0},"end":{"line":40,"column":19}},"40":{"start":{"line":41,"column":0},"end":{"line":41,"column":18}},"41":{"start":{"line":42,"column":0},"end":{"line":42,"column":21}},"43":{"start":{"line":44,"column":0},"end":{"line":44,"column":34}},"44":{"start":{"line":45,"column":0},"end":{"line":45,"column":33}},"46":{"start":{"line":47,"column":0},"end":{"line":47,"column":34}},"47":{"start":{"line":48,"column":0},"end":{"line":48,"column":70}},"48":{"start":{"line":49,"column":0},"end":{"line":49,"column":34}},"49":{"start":{"line":50,"column":0},"end":{"line":50,"column":16}},"50":{"start":{"line":51,"column":0},"end":{"line":51,"column":12}},"51":{"start":{"line":52,"column":0},"end":{"line":52,"column":72}},"52":{"start":{"line":53,"column":0},"end":{"line":53,"column":119}},"53":{"start":{"line":54,"column":0},"end":{"line":54,"column":51}},"54":{"start":{"line":55,"column":0},"end":{"line":55,"column":18}},"55":{"start":{"line":56,"column":0},"end":{"line":56,"column":59}},"56":{"start":{"line":57,"column":0},"end":{"line":57,"column":60}},"57":{"start":{"line":58,"column":0},"end":{"line":58,"column":18}},"58":{"start":{"line":59,"column":0},"end":{"line":59,"column":25}},"59":{"start":{"line":60,"column":0},"end":{"line":60,"column":117}},"61":{"start":{"line":62,"column":0},"end":{"line":62,"column":48}},"62":{"start":{"line":63,"column":0},"end":{"line":63,"column":20}},"63":{"start":{"line":64,"column":0},"end":{"line":64,"column":15}},"64":{"start":{"line":65,"column":0},"end":{"line":65,"column":13}},"66":{"start":{"line":67,"column":0},"end":{"line":67,"column":7}},"67":{"start":{"line":68,"column":0},"end":{"line":68,"column":49}},"68":{"start":{"line":69,"column":0},"end":{"line":69,"column":56}},"70":{"start":{"line":71,"column":0},"end":{"line":71,"column":14}},"71":{"start":{"line":72,"column":0},"end":{"line":72,"column":10}},"72":{"start":{"line":73,"column":0},"end":{"line":73,"column":45}},"73":{"start":{"line":74,"column":0},"end":{"line":74,"column":56}},"74":{"start":{"line":75,"column":0},"end":{"line":75,"column":15}},"75":{"start":{"line":76,"column":0},"end":{"line":76,"column":58}},"76":{"start":{"line":77,"column":0},"end":{"line":77,"column":46}},"77":{"start":{"line":78,"column":0},"end":{"line":78,"column":40}},"78":{"start":{"line":79,"column":0},"end":{"line":79,"column":123}},"79":{"start":{"line":80,"column":0},"end":{"line":80,"column":29}},"80":{"start":{"line":81,"column":0},"end":{"line":81,"column":22}},"82":{"start":{"line":83,"column":0},"end":{"line":83,"column":41}},"83":{"start":{"line":84,"column":0},"end":{"line":84,"column":20}},"84":{"start":{"line":85,"column":0},"end":{"line":85,"column":67}},"85":{"start":{"line":86,"column":0},"end":{"line":86,"column":41}},"86":{"start":{"line":87,"column":0},"end":{"line":87,"column":47}},"87":{"start":{"line":88,"column":0},"end":{"line":88,"column":18}},"89":{"start":{"line":90,"column":0},"end":{"line":90,"column":44}},"90":{"start":{"line":91,"column":0},"end":{"line":91,"column":156}},"91":{"start":{"line":92,"column":0},"end":{"line":92,"column":58}},"92":{"start":{"line":93,"column":0},"end":{"line":93,"column":22}},"94":{"start":{"line":95,"column":0},"end":{"line":95,"column":18}},"95":{"start":{"line":96,"column":0},"end":{"line":96,"column":13}},"96":{"start":{"line":97,"column":0},"end":{"line":97,"column":11}},"98":{"start":{"line":99,"column":0},"end":{"line":99,"column":44}},"99":{"start":{"line":100,"column":0},"end":{"line":100,"column":14}},"100":{"start":{"line":101,"column":0},"end":{"line":101,"column":10}},"101":{"start":{"line":102,"column":0},"end":{"line":102,"column":71}},"102":{"start":{"line":103,"column":0},"end":{"line":103,"column":117}},"103":{"start":{"line":104,"column":0},"end":{"line":104,"column":60}},"104":{"start":{"line":105,"column":0},"end":{"line":105,"column":16}},"105":{"start":{"line":106,"column":0},"end":{"line":106,"column":11}},"107":{"start":{"line":108,"column":0},"end":{"line":108,"column":5}},"108":{"start":{"line":109,"column":0},"end":{"line":109,"column":4}},"110":{"start":{"line":111,"column":0},"end":{"line":111,"column":10}},"111":{"start":{"line":112,"column":0},"end":{"line":112,"column":66}},"112":{"start":{"line":113,"column":0},"end":{"line":113,"column":15}},"113":{"start":{"line":114,"column":0},"end":{"line":114,"column":21}},"114":{"start":{"line":115,"column":0},"end":{"line":115,"column":29}},"115":{"start":{"line":116,"column":0},"end":{"line":116,"column":27}},"116":{"start":{"line":117,"column":0},"end":{"line":117,"column":23}},"117":{"start":{"line":118,"column":0},"end":{"line":118,"column":32}},"118":{"start":{"line":119,"column":0},"end":{"line":119,"column":10}},"119":{"start":{"line":120,"column":0},"end":{"line":120,"column":41}},"120":{"start":{"line":121,"column":0},"end":{"line":121,"column":31}},"121":{"start":{"line":122,"column":0},"end":{"line":122,"column":12}},"122":{"start":{"line":123,"column":0},"end":{"line":123,"column":55}},"123":{"start":{"line":124,"column":0},"end":{"line":124,"column":63}},"124":{"start":{"line":125,"column":0},"end":{"line":125,"column":32}},"125":{"start":{"line":126,"column":0},"end":{"line":126,"column":19}},"126":{"start":{"line":127,"column":0},"end":{"line":127,"column":13}},"128":{"start":{"line":129,"column":0},"end":{"line":129,"column":21}},"129":{"start":{"line":130,"column":0},"end":{"line":130,"column":66}},"130":{"start":{"line":131,"column":0},"end":{"line":131,"column":58}},"131":{"start":{"line":132,"column":0},"end":{"line":132,"column":8}},"133":{"start":{"line":134,"column":0},"end":{"line":134,"column":49}},"134":{"start":{"line":135,"column":0},"end":{"line":135,"column":54}},"135":{"start":{"line":136,"column":0},"end":{"line":136,"column":40}},"136":{"start":{"line":137,"column":0},"end":{"line":137,"column":64}},"137":{"start":{"line":138,"column":0},"end":{"line":138,"column":15}},"138":{"start":{"line":139,"column":0},"end":{"line":139,"column":14}},"139":{"start":{"line":140,"column":0},"end":{"line":140,"column":29}},"140":{"start":{"line":141,"column":0},"end":{"line":141,"column":20}},"141":{"start":{"line":142,"column":0},"end":{"line":142,"column":41}},"142":{"start":{"line":143,"column":0},"end":{"line":143,"column":49}},"143":{"start":{"line":144,"column":0},"end":{"line":144,"column":44}},"144":{"start":{"line":145,"column":0},"end":{"line":145,"column":58}},"145":{"start":{"line":146,"column":0},"end":{"line":146,"column":20}},"146":{"start":{"line":147,"column":0},"end":{"line":147,"column":30}},"147":{"start":{"line":148,"column":0},"end":{"line":148,"column":39}},"148":{"start":{"line":149,"column":0},"end":{"line":149,"column":51}},"149":{"start":{"line":150,"column":0},"end":{"line":150,"column":42}},"150":{"start":{"line":151,"column":0},"end":{"line":151,"column":18}},"151":{"start":{"line":152,"column":0},"end":{"line":152,"column":77}},"152":{"start":{"line":153,"column":0},"end":{"line":153,"column":35}},"153":{"start":{"line":154,"column":0},"end":{"line":154,"column":33}},"154":{"start":{"line":155,"column":0},"end":{"line":155,"column":26}},"155":{"start":{"line":156,"column":0},"end":{"line":156,"column":35}},"156":{"start":{"line":157,"column":0},"end":{"line":157,"column":73}},"158":{"start":{"line":159,"column":0},"end":{"line":159,"column":27}},"159":{"start":{"line":160,"column":0},"end":{"line":160,"column":28}},"162":{"start":{"line":163,"column":0},"end":{"line":163,"column":49}},"163":{"start":{"line":164,"column":0},"end":{"line":164,"column":33}},"164":{"start":{"line":165,"column":0},"end":{"line":165,"column":34}},"165":{"start":{"line":166,"column":0},"end":{"line":166,"column":36}},"167":{"start":{"line":168,"column":0},"end":{"line":168,"column":57}},"168":{"start":{"line":169,"column":0},"end":{"line":169,"column":42}},"169":{"start":{"line":170,"column":0},"end":{"line":170,"column":39}},"170":{"start":{"line":171,"column":0},"end":{"line":171,"column":40}},"171":{"start":{"line":172,"column":0},"end":{"line":172,"column":52}},"172":{"start":{"line":173,"column":0},"end":{"line":173,"column":30}},"174":{"start":{"line":175,"column":0},"end":{"line":175,"column":42}},"175":{"start":{"line":176,"column":0},"end":{"line":176,"column":26}},"178":{"start":{"line":179,"column":0},"end":{"line":179,"column":49}},"179":{"start":{"line":180,"column":0},"end":{"line":180,"column":33}},"180":{"start":{"line":181,"column":0},"end":{"line":181,"column":34}},"181":{"start":{"line":182,"column":0},"end":{"line":182,"column":36}},"183":{"start":{"line":184,"column":0},"end":{"line":184,"column":57}},"184":{"start":{"line":185,"column":0},"end":{"line":185,"column":44}},"185":{"start":{"line":186,"column":0},"end":{"line":186,"column":33}},"186":{"start":{"line":187,"column":0},"end":{"line":187,"column":72}},"187":{"start":{"line":188,"column":0},"end":{"line":188,"column":41}},"188":{"start":{"line":189,"column":0},"end":{"line":189,"column":42}},"189":{"start":{"line":190,"column":0},"end":{"line":190,"column":46}},"190":{"start":{"line":191,"column":0},"end":{"line":191,"column":33}},"191":{"start":{"line":192,"column":0},"end":{"line":192,"column":43}},"193":{"start":{"line":194,"column":0},"end":{"line":194,"column":41}},"194":{"start":{"line":195,"column":0},"end":{"line":195,"column":42}},"195":{"start":{"line":196,"column":0},"end":{"line":196,"column":54}},"196":{"start":{"line":197,"column":0},"end":{"line":197,"column":33}},"197":{"start":{"line":198,"column":0},"end":{"line":198,"column":29}},"198":{"start":{"line":199,"column":0},"end":{"line":199,"column":28}},"199":{"start":{"line":200,"column":0},"end":{"line":200,"column":42}},"200":{"start":{"line":201,"column":0},"end":{"line":201,"column":26}},"202":{"start":{"line":203,"column":0},"end":{"line":203,"column":30}},"204":{"start":{"line":205,"column":0},"end":{"line":205,"column":76}},"205":{"start":{"line":206,"column":0},"end":{"line":206,"column":34}},"206":{"start":{"line":207,"column":0},"end":{"line":207,"column":36}},"208":{"start":{"line":209,"column":0},"end":{"line":209,"column":57}},"209":{"start":{"line":210,"column":0},"end":{"line":210,"column":42}},"210":{"start":{"line":211,"column":0},"end":{"line":211,"column":39}},"211":{"start":{"line":212,"column":0},"end":{"line":212,"column":40}},"212":{"start":{"line":213,"column":0},"end":{"line":213,"column":36}},"214":{"start":{"line":215,"column":0},"end":{"line":215,"column":55}},"215":{"start":{"line":216,"column":0},"end":{"line":216,"column":58}},"216":{"start":{"line":217,"column":0},"end":{"line":217,"column":51}},"217":{"start":{"line":218,"column":0},"end":{"line":218,"column":30}},"219":{"start":{"line":220,"column":0},"end":{"line":220,"column":42}},"220":{"start":{"line":221,"column":0},"end":{"line":221,"column":26}},"223":{"start":{"line":224,"column":0},"end":{"line":224,"column":24}},"225":{"start":{"line":226,"column":0},"end":{"line":226,"column":16}},"226":{"start":{"line":227,"column":0},"end":{"line":227,"column":74}},"227":{"start":{"line":228,"column":0},"end":{"line":228,"column":49}},"229":{"start":{"line":230,"column":0},"end":{"line":230,"column":23}},"230":{"start":{"line":231,"column":0},"end":{"line":231,"column":48}},"231":{"start":{"line":232,"column":0},"end":{"line":232,"column":18}},"233":{"start":{"line":234,"column":0},"end":{"line":234,"column":19}},"234":{"start":{"line":235,"column":0},"end":{"line":235,"column":32}},"236":{"start":{"line":237,"column":0},"end":{"line":237,"column":33}},"237":{"start":{"line":238,"column":0},"end":{"line":238,"column":20}},"239":{"start":{"line":240,"column":0},"end":{"line":240,"column":14}},"240":{"start":{"line":241,"column":0},"end":{"line":241,"column":12}},"241":{"start":{"line":242,"column":0},"end":{"line":242,"column":18}},"243":{"start":{"line":244,"column":0},"end":{"line":244,"column":2}},"245":{"start":{"line":246,"column":0},"end":{"line":246,"column":24}}},"s":{"0":1,"1":1,"2":1,"3":1,"4":1,"5":1,"10":1,"11":1,"12":1,"13":1,"17":1,"18":6,"19":6,"20":6,"21":6,"22":6,"23":6,"24":6,"25":6,"26":6,"27":6,"37":6,"38":6,"39":6,"40":2,"41":6,"43":6,"44":0,"46":0,"47":0,"48":0,"49":0,"50":0,"51":0,"52":0,"53":0,"54":0,"55":0,"56":0,"57":0,"58":0,"59":0,"61":0,"62":0,"63":0,"64":0,"66":0,"67":0,"68":0,"70":0,"71":0,"72":0,"73":0,"74":0,"75":0,"76":0,"77":0,"78":0,"79":0,"80":0,"82":0,"83":0,"84":0,"85":0,"86":0,"87":0,"89":0,"90":0,"91":0,"92":0,"94":0,"95":0,"96":0,"98":0,"99":0,"100":0,"101":0,"102":0,"103":0,"104":0,"105":0,"107":0,"108":0,"110":6,"111":6,"112":6,"113":6,"114":6,"115":6,"116":0,"117":0,"118":0,"119":6,"120":6,"121":0,"122":0,"123":0,"124":0,"125":0,"126":0,"128":6,"129":6,"130":6,"131":6,"133":6,"134":6,"135":6,"136":6,"137":6,"138":6,"139":6,"140":6,"141":0,"142":0,"143":0,"144":0,"145":0,"146":6,"147":0,"148":0,"149":0,"150":0,"151":0,"152":0,"153":0,"154":0,"155":0,"156":0,"158":0,"159":0,"162":0,"163":0,"164":0,"165":0,"167":0,"168":0,"169":0,"170":0,"171":0,"172":0,"174":0,"175":0,"178":0,"179":0,"180":0,"181":0,"183":0,"184":0,"185":0,"186":0,"187":0,"188":0,"189":0,"190":0,"191":0,"193":0,"194":0,"195":0,"196":0,"197":0,"198":0,"199":0,"200":0,"202":0,"204":0,"205":0,"206":0,"208":0,"209":0,"210":0,"211":0,"212":0,"214":0,"215":0,"216":0,"217":0,"219":0,"220":0,"223":0,"225":0,"226":0,"227":0,"229":0,"230":0,"231":0,"233":6,"234":6,"236":6,"237":6,"239":6,"240":6,"241":6,"243":6,"245":1},"branchMap":{"0":{"type":"branch","line":18,"loc":{"start":{"line":18,"column":17},"end":{"line":244,"column":2}},"locations":[{"start":{"line":18,"column":17},"end":{"line":244,"column":2}}]},"1":{"type":"branch","line":130,"loc":{"start":{"line":130,"column":20},"end":{"line":130,"column":53}},"locations":[{"start":{"line":130,"column":20},"end":{"line":130,"column":53}}]},"2":{"type":"branch","line":137,"loc":{"start":{"line":137,"column":13},"end":{"line":137,"column":48}},"locations":[{"start":{"line":137,"column":13},"end":{"line":137,"column":48}}]},"3":{"type":"branch","line":141,"loc":{"start":{"line":141,"column":11},"end":{"line":146,"column":20}},"locations":[{"start":{"line":141,"column":11},"end":{"line":146,"column":20}}]},"4":{"type":"branch","line":147,"loc":{"start":{"line":147,"column":14},"end":{"line":232,"column":18}},"locations":[{"start":{"line":147,"column":14},"end":{"line":232,"column":18}}]},"5":{"type":"branch","line":40,"loc":{"start":{"line":40,"column":12},"end":{"line":42,"column":5}},"locations":[{"start":{"line":40,"column":12},"end":{"line":42,"column":5}}]}},"b":{"0":[6],"1":[0],"2":[0],"3":[0],"4":[0],"5":[2]},"fnMap":{"0":{"name":"ToolsTab","decl":{"start":{"line":18,"column":17},"end":{"line":244,"column":2}},"loc":{"start":{"line":18,"column":17},"end":{"line":244,"column":2}},"line":18},"1":{"name":"renderToolResult","decl":{"start":{"line":44,"column":27},"end":{"line":109,"column":4}},"loc":{"start":{"line":44,"column":27},"end":{"line":109,"column":4}},"line":44},"2":{"name":"clearItems","decl":{"start":{"line":116,"column":20},"end":{"line":119,"column":10}},"loc":{"start":{"line":116,"column":20},"end":{"line":119,"column":10}},"line":116},"3":{"name":"renderItem","decl":{"start":{"line":121,"column":20},"end":{"line":127,"column":13}},"loc":{"start":{"line":121,"column":20},"end":{"line":127,"column":13}},"line":121},"4":{"name":"onClick","decl":{"start":{"line":227,"column":31},"end":{"line":227,"column":74}},"loc":{"start":{"line":227,"column":31},"end":{"line":227,"column":74}},"line":227}},"f":{"0":6,"1":0,"2":0,"3":0,"4":0}} +,"/Users/ashwin/code/mcp/inspector/client/src/components/ui/alert.tsx": {"path":"/Users/ashwin/code/mcp/inspector/client/src/components/ui/alert.tsx","all":false,"statementMap":{"0":{"start":{"line":1,"column":0},"end":{"line":1,"column":31}},"5":{"start":{"line":6,"column":0},"end":{"line":6,"column":26}},"6":{"start":{"line":7,"column":0},"end":{"line":7,"column":172}},"7":{"start":{"line":8,"column":0},"end":{"line":8,"column":3}},"8":{"start":{"line":9,"column":0},"end":{"line":9,"column":15}},"9":{"start":{"line":10,"column":0},"end":{"line":10,"column":16}},"10":{"start":{"line":11,"column":0},"end":{"line":11,"column":49}},"11":{"start":{"line":12,"column":0},"end":{"line":12,"column":20}},"12":{"start":{"line":13,"column":0},"end":{"line":13,"column":100}},"13":{"start":{"line":14,"column":0},"end":{"line":14,"column":8}},"14":{"start":{"line":15,"column":0},"end":{"line":15,"column":6}},"15":{"start":{"line":16,"column":0},"end":{"line":16,"column":22}},"16":{"start":{"line":17,"column":0},"end":{"line":17,"column":25}},"17":{"start":{"line":18,"column":0},"end":{"line":18,"column":6}},"18":{"start":{"line":19,"column":0},"end":{"line":19,"column":4}},"19":{"start":{"line":20,"column":0},"end":{"line":20,"column":2}},"21":{"start":{"line":22,"column":0},"end":{"line":22,"column":31}},"24":{"start":{"line":25,"column":0},"end":{"line":25,"column":46}},"25":{"start":{"line":26,"column":0},"end":{"line":26,"column":6}},"26":{"start":{"line":27,"column":0},"end":{"line":27,"column":13}},"27":{"start":{"line":28,"column":0},"end":{"line":28,"column":16}},"28":{"start":{"line":29,"column":0},"end":{"line":29,"column":57}},"29":{"start":{"line":30,"column":0},"end":{"line":30,"column":14}},"30":{"start":{"line":31,"column":0},"end":{"line":31,"column":4}},"31":{"start":{"line":32,"column":0},"end":{"line":32,"column":3}},"32":{"start":{"line":33,"column":0},"end":{"line":33,"column":28}},"34":{"start":{"line":35,"column":0},"end":{"line":35,"column":36}},"37":{"start":{"line":38,"column":0},"end":{"line":38,"column":37}},"38":{"start":{"line":39,"column":0},"end":{"line":39,"column":5}},"39":{"start":{"line":40,"column":0},"end":{"line":40,"column":13}},"40":{"start":{"line":41,"column":0},"end":{"line":41,"column":77}},"41":{"start":{"line":42,"column":0},"end":{"line":42,"column":14}},"42":{"start":{"line":43,"column":0},"end":{"line":43,"column":4}},"43":{"start":{"line":44,"column":0},"end":{"line":44,"column":3}},"44":{"start":{"line":45,"column":0},"end":{"line":45,"column":38}},"46":{"start":{"line":47,"column":0},"end":{"line":47,"column":42}},"49":{"start":{"line":50,"column":0},"end":{"line":50,"column":37}},"50":{"start":{"line":51,"column":0},"end":{"line":51,"column":6}},"51":{"start":{"line":52,"column":0},"end":{"line":52,"column":13}},"52":{"start":{"line":53,"column":0},"end":{"line":53,"column":62}},"53":{"start":{"line":54,"column":0},"end":{"line":54,"column":14}},"54":{"start":{"line":55,"column":0},"end":{"line":55,"column":4}},"55":{"start":{"line":56,"column":0},"end":{"line":56,"column":3}},"56":{"start":{"line":57,"column":0},"end":{"line":57,"column":50}}},"s":{"0":1,"5":1,"6":1,"7":1,"8":1,"9":1,"10":1,"11":1,"12":1,"13":1,"14":1,"15":1,"16":1,"17":1,"18":1,"19":1,"21":1,"24":1,"25":23,"26":23,"27":23,"28":23,"29":23,"30":23,"31":23,"32":1,"34":1,"37":1,"38":2,"39":2,"40":2,"41":2,"42":2,"43":2,"44":1,"46":1,"49":1,"50":23,"51":23,"52":23,"53":23,"54":23,"55":23,"56":1},"branchMap":{"0":{"type":"branch","line":25,"loc":{"start":{"line":25,"column":2},"end":{"line":32,"column":3}},"locations":[{"start":{"line":25,"column":2},"end":{"line":32,"column":3}}]},"1":{"type":"branch","line":38,"loc":{"start":{"line":38,"column":2},"end":{"line":44,"column":3}},"locations":[{"start":{"line":38,"column":2},"end":{"line":44,"column":3}}]},"2":{"type":"branch","line":50,"loc":{"start":{"line":50,"column":2},"end":{"line":56,"column":3}},"locations":[{"start":{"line":50,"column":2},"end":{"line":56,"column":3}}]}},"b":{"0":[23],"1":[2],"2":[23]},"fnMap":{},"f":{}} +,"/Users/ashwin/code/mcp/inspector/client/src/components/ui/button.tsx": {"path":"/Users/ashwin/code/mcp/inspector/client/src/components/ui/button.tsx","all":false,"statementMap":{"0":{"start":{"line":1,"column":0},"end":{"line":1,"column":31}},"6":{"start":{"line":7,"column":0},"end":{"line":7,"column":27}},"7":{"start":{"line":8,"column":0},"end":{"line":8,"column":232}},"8":{"start":{"line":9,"column":0},"end":{"line":9,"column":3}},"9":{"start":{"line":10,"column":0},"end":{"line":10,"column":15}},"10":{"start":{"line":11,"column":0},"end":{"line":11,"column":16}},"11":{"start":{"line":12,"column":0},"end":{"line":12,"column":16}},"12":{"start":{"line":13,"column":0},"end":{"line":13,"column":130}},"13":{"start":{"line":14,"column":0},"end":{"line":14,"column":20}},"14":{"start":{"line":15,"column":0},"end":{"line":15,"column":89}},"15":{"start":{"line":16,"column":0},"end":{"line":16,"column":16}},"16":{"start":{"line":17,"column":0},"end":{"line":17,"column":101}},"17":{"start":{"line":18,"column":0},"end":{"line":18,"column":18}},"18":{"start":{"line":19,"column":0},"end":{"line":19,"column":83}},"19":{"start":{"line":20,"column":0},"end":{"line":20,"column":62}},"20":{"start":{"line":21,"column":0},"end":{"line":21,"column":64}},"21":{"start":{"line":22,"column":0},"end":{"line":22,"column":8}},"22":{"start":{"line":23,"column":0},"end":{"line":23,"column":13}},"23":{"start":{"line":24,"column":0},"end":{"line":24,"column":33}},"24":{"start":{"line":25,"column":0},"end":{"line":25,"column":42}},"25":{"start":{"line":26,"column":0},"end":{"line":26,"column":35}},"26":{"start":{"line":27,"column":0},"end":{"line":27,"column":24}},"27":{"start":{"line":28,"column":0},"end":{"line":28,"column":8}},"28":{"start":{"line":29,"column":0},"end":{"line":29,"column":6}},"29":{"start":{"line":30,"column":0},"end":{"line":30,"column":22}},"30":{"start":{"line":31,"column":0},"end":{"line":31,"column":25}},"31":{"start":{"line":32,"column":0},"end":{"line":32,"column":22}},"32":{"start":{"line":33,"column":0},"end":{"line":33,"column":6}},"33":{"start":{"line":34,"column":0},"end":{"line":34,"column":4}},"34":{"start":{"line":35,"column":0},"end":{"line":35,"column":2}},"42":{"start":{"line":43,"column":0},"end":{"line":43,"column":64}},"43":{"start":{"line":44,"column":0},"end":{"line":44,"column":69}},"44":{"start":{"line":45,"column":0},"end":{"line":45,"column":43}},"45":{"start":{"line":46,"column":0},"end":{"line":46,"column":12}},"46":{"start":{"line":47,"column":0},"end":{"line":47,"column":11}},"47":{"start":{"line":48,"column":0},"end":{"line":48,"column":68}},"48":{"start":{"line":49,"column":0},"end":{"line":49,"column":17}},"49":{"start":{"line":50,"column":0},"end":{"line":50,"column":18}},"50":{"start":{"line":51,"column":0},"end":{"line":51,"column":8}},"52":{"start":{"line":53,"column":0},"end":{"line":53,"column":4}},"53":{"start":{"line":54,"column":0},"end":{"line":54,"column":2}},"54":{"start":{"line":55,"column":0},"end":{"line":55,"column":30}}},"s":{"0":1,"6":1,"7":1,"8":1,"9":1,"10":1,"11":1,"12":1,"13":1,"14":1,"15":1,"16":1,"17":1,"18":1,"19":1,"20":1,"21":1,"22":1,"23":1,"24":1,"25":1,"26":1,"27":1,"28":1,"29":1,"30":1,"31":1,"32":1,"33":1,"34":1,"42":1,"43":1,"44":223,"45":223,"46":223,"47":223,"48":223,"49":223,"50":223,"52":223,"53":1,"54":1},"branchMap":{"0":{"type":"branch","line":44,"loc":{"start":{"line":44,"column":2},"end":{"line":53,"column":4}},"locations":[{"start":{"line":44,"column":2},"end":{"line":53,"column":4}}]},"1":{"type":"branch","line":45,"loc":{"start":{"line":45,"column":17},"end":{"line":45,"column":34}},"locations":[{"start":{"line":45,"column":17},"end":{"line":45,"column":34}}]}},"b":{"0":[223],"1":[0]},"fnMap":{},"f":{}} +,"/Users/ashwin/code/mcp/inspector/client/src/components/ui/input.tsx": {"path":"/Users/ashwin/code/mcp/inspector/client/src/components/ui/input.tsx","all":false,"statementMap":{"0":{"start":{"line":1,"column":0},"end":{"line":1,"column":31}},"7":{"start":{"line":8,"column":0},"end":{"line":8,"column":61}},"8":{"start":{"line":9,"column":0},"end":{"line":9,"column":43}},"9":{"start":{"line":10,"column":0},"end":{"line":10,"column":12}},"10":{"start":{"line":11,"column":0},"end":{"line":11,"column":12}},"11":{"start":{"line":12,"column":0},"end":{"line":12,"column":19}},"12":{"start":{"line":13,"column":0},"end":{"line":13,"column":22}},"13":{"start":{"line":14,"column":0},"end":{"line":14,"column":359}},"14":{"start":{"line":15,"column":0},"end":{"line":15,"column":20}},"15":{"start":{"line":16,"column":0},"end":{"line":16,"column":10}},"16":{"start":{"line":17,"column":0},"end":{"line":17,"column":17}},"17":{"start":{"line":18,"column":0},"end":{"line":18,"column":18}},"18":{"start":{"line":19,"column":0},"end":{"line":19,"column":8}},"20":{"start":{"line":21,"column":0},"end":{"line":21,"column":4}},"21":{"start":{"line":22,"column":0},"end":{"line":22,"column":2}},"22":{"start":{"line":23,"column":0},"end":{"line":23,"column":28}}},"s":{"0":1,"7":1,"8":1,"9":58,"10":58,"11":58,"12":58,"13":58,"14":58,"15":58,"16":58,"17":58,"18":58,"20":58,"21":1,"22":1},"branchMap":{"0":{"type":"branch","line":9,"loc":{"start":{"line":9,"column":2},"end":{"line":21,"column":4}},"locations":[{"start":{"line":9,"column":2},"end":{"line":21,"column":4}}]}},"b":{"0":[58]},"fnMap":{},"f":{}} +,"/Users/ashwin/code/mcp/inspector/client/src/components/ui/label.tsx": {"path":"/Users/ashwin/code/mcp/inspector/client/src/components/ui/label.tsx","all":false,"statementMap":{"0":{"start":{"line":1,"column":0},"end":{"line":1,"column":31}},"6":{"start":{"line":7,"column":0},"end":{"line":7,"column":26}},"7":{"start":{"line":8,"column":0},"end":{"line":8,"column":95}},"8":{"start":{"line":9,"column":0},"end":{"line":9,"column":2}},"10":{"start":{"line":11,"column":0},"end":{"line":11,"column":31}},"14":{"start":{"line":15,"column":0},"end":{"line":15,"column":37}},"15":{"start":{"line":16,"column":0},"end":{"line":16,"column":22}},"16":{"start":{"line":17,"column":0},"end":{"line":17,"column":13}},"17":{"start":{"line":18,"column":0},"end":{"line":18,"column":46}},"18":{"start":{"line":19,"column":0},"end":{"line":19,"column":14}},"19":{"start":{"line":20,"column":0},"end":{"line":20,"column":4}},"20":{"start":{"line":21,"column":0},"end":{"line":21,"column":3}},"21":{"start":{"line":22,"column":0},"end":{"line":22,"column":52}}},"s":{"0":1,"6":1,"7":1,"8":1,"10":1,"14":1,"15":8,"16":8,"17":8,"18":8,"19":8,"20":8,"21":1},"branchMap":{"0":{"type":"branch","line":15,"loc":{"start":{"line":15,"column":2},"end":{"line":21,"column":3}},"locations":[{"start":{"line":15,"column":2},"end":{"line":21,"column":3}}]}},"b":{"0":[8]},"fnMap":{},"f":{}} +,"/Users/ashwin/code/mcp/inspector/client/src/components/ui/select.tsx": {"path":"/Users/ashwin/code/mcp/inspector/client/src/components/ui/select.tsx","all":false,"statementMap":{"0":{"start":{"line":1,"column":0},"end":{"line":1,"column":31}},"11":{"start":{"line":12,"column":0},"end":{"line":12,"column":36}},"13":{"start":{"line":14,"column":0},"end":{"line":14,"column":42}},"15":{"start":{"line":16,"column":0},"end":{"line":16,"column":42}},"17":{"start":{"line":18,"column":0},"end":{"line":18,"column":39}},"20":{"start":{"line":21,"column":0},"end":{"line":21,"column":47}},"21":{"start":{"line":22,"column":0},"end":{"line":22,"column":26}},"22":{"start":{"line":23,"column":0},"end":{"line":23,"column":13}},"23":{"start":{"line":24,"column":0},"end":{"line":24,"column":18}},"24":{"start":{"line":25,"column":0},"end":{"line":25,"column":320}},"25":{"start":{"line":26,"column":0},"end":{"line":26,"column":16}},"26":{"start":{"line":27,"column":0},"end":{"line":27,"column":6}},"27":{"start":{"line":28,"column":0},"end":{"line":28,"column":14}},"29":{"start":{"line":30,"column":0},"end":{"line":30,"column":14}},"30":{"start":{"line":31,"column":0},"end":{"line":31,"column":34}},"31":{"start":{"line":32,"column":0},"end":{"line":32,"column":54}},"32":{"start":{"line":33,"column":0},"end":{"line":33,"column":27}},"33":{"start":{"line":34,"column":0},"end":{"line":34,"column":28}},"34":{"start":{"line":35,"column":0},"end":{"line":35,"column":3}},"35":{"start":{"line":36,"column":0},"end":{"line":36,"column":64}},"37":{"start":{"line":38,"column":0},"end":{"line":38,"column":46}},"40":{"start":{"line":41,"column":0},"end":{"line":41,"column":37}},"41":{"start":{"line":42,"column":0},"end":{"line":42,"column":33}},"42":{"start":{"line":43,"column":0},"end":{"line":43,"column":13}},"43":{"start":{"line":44,"column":0},"end":{"line":44,"column":18}},"44":{"start":{"line":45,"column":0},"end":{"line":45,"column":61}},"45":{"start":{"line":46,"column":0},"end":{"line":46,"column":16}},"46":{"start":{"line":47,"column":0},"end":{"line":47,"column":6}},"47":{"start":{"line":48,"column":0},"end":{"line":48,"column":14}},"49":{"start":{"line":50,"column":0},"end":{"line":50,"column":21}},"50":{"start":{"line":51,"column":0},"end":{"line":51,"column":35}},"51":{"start":{"line":52,"column":0},"end":{"line":52,"column":3}},"52":{"start":{"line":53,"column":0},"end":{"line":53,"column":78}},"54":{"start":{"line":55,"column":0},"end":{"line":55,"column":48}},"57":{"start":{"line":58,"column":0},"end":{"line":58,"column":37}},"58":{"start":{"line":59,"column":0},"end":{"line":59,"column":35}},"59":{"start":{"line":60,"column":0},"end":{"line":60,"column":13}},"60":{"start":{"line":61,"column":0},"end":{"line":61,"column":18}},"61":{"start":{"line":62,"column":0},"end":{"line":62,"column":61}},"62":{"start":{"line":63,"column":0},"end":{"line":63,"column":16}},"63":{"start":{"line":64,"column":0},"end":{"line":64,"column":6}},"64":{"start":{"line":65,"column":0},"end":{"line":65,"column":14}},"66":{"start":{"line":67,"column":0},"end":{"line":67,"column":23}},"67":{"start":{"line":68,"column":0},"end":{"line":68,"column":37}},"68":{"start":{"line":69,"column":0},"end":{"line":69,"column":3}},"69":{"start":{"line":70,"column":0},"end":{"line":70,"column":36}},"70":{"start":{"line":71,"column":0},"end":{"line":71,"column":47}},"72":{"start":{"line":73,"column":0},"end":{"line":73,"column":39}},"75":{"start":{"line":76,"column":0},"end":{"line":76,"column":68}},"76":{"start":{"line":77,"column":0},"end":{"line":77,"column":26}},"77":{"start":{"line":78,"column":0},"end":{"line":78,"column":28}},"78":{"start":{"line":79,"column":0},"end":{"line":79,"column":15}},"79":{"start":{"line":80,"column":0},"end":{"line":80,"column":20}},"80":{"start":{"line":81,"column":0},"end":{"line":81,"column":462}},"81":{"start":{"line":82,"column":0},"end":{"line":82,"column":32}},"82":{"start":{"line":83,"column":0},"end":{"line":83,"column":140}},"83":{"start":{"line":84,"column":0},"end":{"line":84,"column":18}},"84":{"start":{"line":85,"column":0},"end":{"line":85,"column":8}},"85":{"start":{"line":86,"column":0},"end":{"line":86,"column":25}},"86":{"start":{"line":87,"column":0},"end":{"line":87,"column":16}},"88":{"start":{"line":89,"column":0},"end":{"line":89,"column":30}},"89":{"start":{"line":90,"column":0},"end":{"line":90,"column":31}},"90":{"start":{"line":91,"column":0},"end":{"line":91,"column":22}},"91":{"start":{"line":92,"column":0},"end":{"line":92,"column":16}},"92":{"start":{"line":93,"column":0},"end":{"line":93,"column":34}},"93":{"start":{"line":94,"column":0},"end":{"line":94,"column":102}},"94":{"start":{"line":95,"column":0},"end":{"line":95,"column":10}},"96":{"start":{"line":97,"column":0},"end":{"line":97,"column":18}},"97":{"start":{"line":98,"column":0},"end":{"line":98,"column":33}},"98":{"start":{"line":99,"column":0},"end":{"line":99,"column":32}},"99":{"start":{"line":100,"column":0},"end":{"line":100,"column":30}},"100":{"start":{"line":101,"column":0},"end":{"line":101,"column":27}},"101":{"start":{"line":102,"column":0},"end":{"line":102,"column":3}},"102":{"start":{"line":103,"column":0},"end":{"line":103,"column":64}},"104":{"start":{"line":105,"column":0},"end":{"line":105,"column":37}},"107":{"start":{"line":108,"column":0},"end":{"line":108,"column":37}},"108":{"start":{"line":109,"column":0},"end":{"line":109,"column":24}},"109":{"start":{"line":110,"column":0},"end":{"line":110,"column":13}},"110":{"start":{"line":111,"column":0},"end":{"line":111,"column":66}},"111":{"start":{"line":112,"column":0},"end":{"line":112,"column":14}},"112":{"start":{"line":113,"column":0},"end":{"line":113,"column":4}},"113":{"start":{"line":114,"column":0},"end":{"line":114,"column":3}},"114":{"start":{"line":115,"column":0},"end":{"line":115,"column":60}},"116":{"start":{"line":117,"column":0},"end":{"line":117,"column":36}},"119":{"start":{"line":120,"column":0},"end":{"line":120,"column":47}},"120":{"start":{"line":121,"column":0},"end":{"line":121,"column":23}},"121":{"start":{"line":122,"column":0},"end":{"line":122,"column":13}},"122":{"start":{"line":123,"column":0},"end":{"line":123,"column":18}},"123":{"start":{"line":124,"column":0},"end":{"line":124,"column":226}},"124":{"start":{"line":125,"column":0},"end":{"line":125,"column":16}},"125":{"start":{"line":126,"column":0},"end":{"line":126,"column":6}},"126":{"start":{"line":127,"column":0},"end":{"line":127,"column":14}},"128":{"start":{"line":129,"column":0},"end":{"line":129,"column":84}},"129":{"start":{"line":130,"column":0},"end":{"line":130,"column":37}},"130":{"start":{"line":131,"column":0},"end":{"line":131,"column":41}},"131":{"start":{"line":132,"column":0},"end":{"line":132,"column":38}},"132":{"start":{"line":133,"column":0},"end":{"line":133,"column":11}},"133":{"start":{"line":134,"column":0},"end":{"line":134,"column":67}},"134":{"start":{"line":135,"column":0},"end":{"line":135,"column":25}},"135":{"start":{"line":136,"column":0},"end":{"line":136,"column":3}},"136":{"start":{"line":137,"column":0},"end":{"line":137,"column":58}},"138":{"start":{"line":139,"column":0},"end":{"line":139,"column":41}},"141":{"start":{"line":142,"column":0},"end":{"line":142,"column":37}},"142":{"start":{"line":143,"column":0},"end":{"line":143,"column":28}},"143":{"start":{"line":144,"column":0},"end":{"line":144,"column":13}},"144":{"start":{"line":145,"column":0},"end":{"line":145,"column":57}},"145":{"start":{"line":146,"column":0},"end":{"line":146,"column":14}},"146":{"start":{"line":147,"column":0},"end":{"line":147,"column":4}},"147":{"start":{"line":148,"column":0},"end":{"line":148,"column":3}},"148":{"start":{"line":149,"column":0},"end":{"line":149,"column":68}}},"s":{"0":1,"11":1,"13":1,"15":1,"17":1,"20":1,"21":32,"22":32,"23":32,"24":32,"25":32,"26":32,"27":32,"29":32,"30":32,"31":32,"32":32,"33":32,"34":32,"35":1,"37":1,"40":1,"41":32,"42":32,"43":32,"44":32,"45":32,"46":32,"47":32,"49":32,"50":32,"51":32,"52":1,"54":1,"57":1,"58":32,"59":32,"60":32,"61":32,"62":32,"63":32,"64":32,"66":32,"67":32,"68":32,"69":1,"70":1,"72":1,"75":1,"76":32,"77":32,"78":32,"79":32,"80":32,"81":32,"82":32,"83":32,"84":32,"85":32,"86":32,"88":32,"89":32,"90":32,"91":32,"92":32,"93":32,"94":32,"96":32,"97":32,"98":32,"99":32,"100":32,"101":1,"102":1,"104":1,"107":1,"108":0,"109":0,"110":0,"111":0,"112":0,"113":0,"114":1,"116":1,"119":1,"120":80,"121":80,"122":80,"123":80,"124":80,"125":80,"126":80,"128":80,"129":80,"130":80,"131":80,"132":80,"133":80,"134":80,"135":80,"136":1,"138":1,"141":1,"142":0,"143":0,"144":0,"145":0,"146":0,"147":0,"148":1},"branchMap":{"0":{"type":"branch","line":21,"loc":{"start":{"line":21,"column":2},"end":{"line":35,"column":3}},"locations":[{"start":{"line":21,"column":2},"end":{"line":35,"column":3}}]},"1":{"type":"branch","line":41,"loc":{"start":{"line":41,"column":2},"end":{"line":52,"column":3}},"locations":[{"start":{"line":41,"column":2},"end":{"line":52,"column":3}}]},"2":{"type":"branch","line":58,"loc":{"start":{"line":58,"column":2},"end":{"line":69,"column":3}},"locations":[{"start":{"line":58,"column":2},"end":{"line":69,"column":3}}]},"3":{"type":"branch","line":76,"loc":{"start":{"line":76,"column":2},"end":{"line":101,"column":27}},"locations":[{"start":{"line":76,"column":2},"end":{"line":101,"column":27}}]},"4":{"type":"branch","line":120,"loc":{"start":{"line":120,"column":2},"end":{"line":136,"column":3}},"locations":[{"start":{"line":120,"column":2},"end":{"line":136,"column":3}}]}},"b":{"0":[32],"1":[32],"2":[32],"3":[32],"4":[80]},"fnMap":{},"f":{}} +,"/Users/ashwin/code/mcp/inspector/client/src/components/ui/tabs.tsx": {"path":"/Users/ashwin/code/mcp/inspector/client/src/components/ui/tabs.tsx","all":false,"statementMap":{"0":{"start":{"line":1,"column":0},"end":{"line":1,"column":31}},"5":{"start":{"line":6,"column":0},"end":{"line":6,"column":32}},"7":{"start":{"line":8,"column":0},"end":{"line":8,"column":34}},"10":{"start":{"line":11,"column":0},"end":{"line":11,"column":37}},"11":{"start":{"line":12,"column":0},"end":{"line":12,"column":21}},"12":{"start":{"line":13,"column":0},"end":{"line":13,"column":13}},"13":{"start":{"line":14,"column":0},"end":{"line":14,"column":18}},"14":{"start":{"line":15,"column":0},"end":{"line":15,"column":98}},"15":{"start":{"line":16,"column":0},"end":{"line":16,"column":16}},"16":{"start":{"line":17,"column":0},"end":{"line":17,"column":6}},"17":{"start":{"line":18,"column":0},"end":{"line":18,"column":14}},"18":{"start":{"line":19,"column":0},"end":{"line":19,"column":4}},"19":{"start":{"line":20,"column":0},"end":{"line":20,"column":3}},"20":{"start":{"line":21,"column":0},"end":{"line":21,"column":54}},"22":{"start":{"line":23,"column":0},"end":{"line":23,"column":37}},"25":{"start":{"line":26,"column":0},"end":{"line":26,"column":37}},"26":{"start":{"line":27,"column":0},"end":{"line":27,"column":24}},"27":{"start":{"line":28,"column":0},"end":{"line":28,"column":13}},"28":{"start":{"line":29,"column":0},"end":{"line":29,"column":18}},"29":{"start":{"line":30,"column":0},"end":{"line":30,"column":400}},"30":{"start":{"line":31,"column":0},"end":{"line":31,"column":16}},"31":{"start":{"line":32,"column":0},"end":{"line":32,"column":6}},"32":{"start":{"line":33,"column":0},"end":{"line":33,"column":14}},"33":{"start":{"line":34,"column":0},"end":{"line":34,"column":4}},"34":{"start":{"line":35,"column":0},"end":{"line":35,"column":3}},"35":{"start":{"line":36,"column":0},"end":{"line":36,"column":60}},"37":{"start":{"line":38,"column":0},"end":{"line":38,"column":37}},"40":{"start":{"line":41,"column":0},"end":{"line":41,"column":37}},"41":{"start":{"line":42,"column":0},"end":{"line":42,"column":24}},"42":{"start":{"line":43,"column":0},"end":{"line":43,"column":13}},"43":{"start":{"line":44,"column":0},"end":{"line":44,"column":18}},"44":{"start":{"line":45,"column":0},"end":{"line":45,"column":136}},"45":{"start":{"line":46,"column":0},"end":{"line":46,"column":16}},"46":{"start":{"line":47,"column":0},"end":{"line":47,"column":6}},"47":{"start":{"line":48,"column":0},"end":{"line":48,"column":14}},"48":{"start":{"line":49,"column":0},"end":{"line":49,"column":4}},"49":{"start":{"line":50,"column":0},"end":{"line":50,"column":3}},"50":{"start":{"line":51,"column":0},"end":{"line":51,"column":60}}},"s":{"0":1,"5":1,"7":1,"10":1,"11":9,"12":9,"13":9,"14":9,"15":9,"16":9,"17":9,"18":9,"19":9,"20":1,"22":1,"25":1,"26":54,"27":54,"28":54,"29":54,"30":54,"31":54,"32":54,"33":54,"34":54,"35":1,"37":1,"40":1,"41":64,"42":64,"43":64,"44":64,"45":64,"46":64,"47":64,"48":64,"49":64,"50":1},"branchMap":{"0":{"type":"branch","line":11,"loc":{"start":{"line":11,"column":2},"end":{"line":20,"column":3}},"locations":[{"start":{"line":11,"column":2},"end":{"line":20,"column":3}}]},"1":{"type":"branch","line":26,"loc":{"start":{"line":26,"column":2},"end":{"line":35,"column":3}},"locations":[{"start":{"line":26,"column":2},"end":{"line":35,"column":3}}]},"2":{"type":"branch","line":41,"loc":{"start":{"line":41,"column":2},"end":{"line":50,"column":3}},"locations":[{"start":{"line":41,"column":2},"end":{"line":50,"column":3}}]}},"b":{"0":[9],"1":[54],"2":[64]},"fnMap":{},"f":{}} +,"/Users/ashwin/code/mcp/inspector/client/src/components/ui/textarea.tsx": {"path":"/Users/ashwin/code/mcp/inspector/client/src/components/ui/textarea.tsx","all":false,"statementMap":{"0":{"start":{"line":1,"column":0},"end":{"line":1,"column":31}},"7":{"start":{"line":8,"column":0},"end":{"line":8,"column":70}},"8":{"start":{"line":9,"column":0},"end":{"line":9,"column":37}},"9":{"start":{"line":10,"column":0},"end":{"line":10,"column":12}},"10":{"start":{"line":11,"column":0},"end":{"line":11,"column":15}},"11":{"start":{"line":12,"column":0},"end":{"line":12,"column":22}},"12":{"start":{"line":13,"column":0},"end":{"line":13,"column":265}},"13":{"start":{"line":14,"column":0},"end":{"line":14,"column":20}},"14":{"start":{"line":15,"column":0},"end":{"line":15,"column":10}},"15":{"start":{"line":16,"column":0},"end":{"line":16,"column":17}},"16":{"start":{"line":17,"column":0},"end":{"line":17,"column":18}},"17":{"start":{"line":18,"column":0},"end":{"line":18,"column":8}},"19":{"start":{"line":20,"column":0},"end":{"line":20,"column":4}},"20":{"start":{"line":21,"column":0},"end":{"line":21,"column":2}},"21":{"start":{"line":22,"column":0},"end":{"line":22,"column":34}}},"s":{"0":1,"7":1,"8":1,"9":1,"10":1,"11":1,"12":1,"13":1,"14":1,"15":1,"16":1,"17":1,"19":1,"20":1,"21":1},"branchMap":{"0":{"type":"branch","line":9,"loc":{"start":{"line":9,"column":2},"end":{"line":20,"column":4}},"locations":[{"start":{"line":9,"column":2},"end":{"line":20,"column":4}}]}},"b":{"0":[1]},"fnMap":{},"f":{}} +,"/Users/ashwin/code/mcp/inspector/client/src/lib/notificationTypes.ts": {"path":"/Users/ashwin/code/mcp/inspector/client/src/lib/notificationTypes.ts","all":true,"statementMap":{"0":{"start":{"line":1,"column":0},"end":{"line":1,"column":8}},"6":{"start":{"line":7,"column":0},"end":{"line":7,"column":71}},"7":{"start":{"line":8,"column":0},"end":{"line":8,"column":44}},"8":{"start":{"line":9,"column":0},"end":{"line":9,"column":20}},"9":{"start":{"line":10,"column":0},"end":{"line":10,"column":24}},"10":{"start":{"line":11,"column":0},"end":{"line":11,"column":5}},"11":{"start":{"line":12,"column":0},"end":{"line":12,"column":3}},"13":{"start":{"line":14,"column":0},"end":{"line":14,"column":62}},"14":{"start":{"line":15,"column":0},"end":{"line":15,"column":27}},"15":{"start":{"line":16,"column":0},"end":{"line":16,"column":2}}},"s":{"0":0,"6":0,"7":0,"8":0,"9":0,"10":0,"11":0,"13":0,"14":0,"15":0},"branchMap":{"0":{"type":"branch","line":1,"loc":{"start":{"line":1,"column":562},"end":{"line":19,"column":62}},"locations":[{"start":{"line":1,"column":562},"end":{"line":19,"column":62}}]}},"b":{"0":[0]},"fnMap":{"0":{"name":"(empty-report)","decl":{"start":{"line":1,"column":562},"end":{"line":19,"column":62}},"loc":{"start":{"line":1,"column":562},"end":{"line":19,"column":62}},"line":1}},"f":{"0":0}} +,"/Users/ashwin/code/mcp/inspector/client/src/lib/useTheme.ts": {"path":"/Users/ashwin/code/mcp/inspector/client/src/lib/useTheme.ts","all":false,"statementMap":{"0":{"start":{"line":1,"column":0},"end":{"line":1,"column":57}},"4":{"start":{"line":5,"column":0},"end":{"line":5,"column":56}},"5":{"start":{"line":6,"column":0},"end":{"line":6,"column":51}},"6":{"start":{"line":7,"column":0},"end":{"line":7,"column":62}},"7":{"start":{"line":8,"column":0},"end":{"line":8,"column":34}},"8":{"start":{"line":9,"column":0},"end":{"line":9,"column":5}},"10":{"start":{"line":11,"column":0},"end":{"line":11,"column":19}},"11":{"start":{"line":12,"column":0},"end":{"line":12,"column":49}},"12":{"start":{"line":13,"column":0},"end":{"line":13,"column":37}},"13":{"start":{"line":14,"column":0},"end":{"line":14,"column":6}},"14":{"start":{"line":15,"column":0},"end":{"line":15,"column":62}},"15":{"start":{"line":16,"column":0},"end":{"line":16,"column":31}},"16":{"start":{"line":17,"column":0},"end":{"line":17,"column":58}},"17":{"start":{"line":18,"column":0},"end":{"line":18,"column":7}},"18":{"start":{"line":19,"column":0},"end":{"line":19,"column":6}},"20":{"start":{"line":21,"column":0},"end":{"line":21,"column":65}},"21":{"start":{"line":22,"column":0},"end":{"line":22,"column":77}},"22":{"start":{"line":23,"column":0},"end":{"line":23,"column":6}},"25":{"start":{"line":26,"column":0},"end":{"line":26,"column":29}},"26":{"start":{"line":27,"column":0},"end":{"line":27,"column":73}},"27":{"start":{"line":28,"column":0},"end":{"line":28,"column":12}},"28":{"start":{"line":29,"column":0},"end":{"line":29,"column":33}},"29":{"start":{"line":30,"column":0},"end":{"line":30,"column":5}},"31":{"start":{"line":32,"column":0},"end":{"line":32,"column":72}},"33":{"start":{"line":34,"column":0},"end":{"line":34,"column":18}},"34":{"start":{"line":35,"column":0},"end":{"line":35,"column":77}},"35":{"start":{"line":36,"column":0},"end":{"line":36,"column":6}},"36":{"start":{"line":37,"column":0},"end":{"line":37,"column":14}},"38":{"start":{"line":39,"column":0},"end":{"line":39,"column":10}},"39":{"start":{"line":40,"column":0},"end":{"line":40,"column":10}},"40":{"start":{"line":41,"column":0},"end":{"line":41,"column":38}},"41":{"start":{"line":42,"column":0},"end":{"line":42,"column":25}},"42":{"start":{"line":43,"column":0},"end":{"line":43,"column":46}},"43":{"start":{"line":44,"column":0},"end":{"line":44,"column":34}},"44":{"start":{"line":45,"column":0},"end":{"line":45,"column":79}},"45":{"start":{"line":46,"column":0},"end":{"line":46,"column":7}},"46":{"start":{"line":47,"column":0},"end":{"line":47,"column":11}},"47":{"start":{"line":48,"column":0},"end":{"line":48,"column":4}},"48":{"start":{"line":49,"column":0},"end":{"line":49,"column":2}},"50":{"start":{"line":51,"column":0},"end":{"line":51,"column":24}}},"s":{"0":1,"4":1,"5":16,"6":7,"7":7,"8":16,"10":16,"11":7,"12":7,"13":7,"14":7,"15":0,"16":0,"17":0,"18":0,"20":7,"21":7,"22":7,"25":7,"26":7,"27":7,"28":0,"29":0,"31":7,"33":7,"34":7,"35":7,"36":16,"38":16,"39":16,"40":16,"41":0,"42":0,"43":0,"44":0,"45":0,"46":16,"47":16,"48":16,"50":1},"branchMap":{"0":{"type":"branch","line":5,"loc":{"start":{"line":5,"column":17},"end":{"line":49,"column":2}},"locations":[{"start":{"line":5,"column":17},"end":{"line":49,"column":2}}]},"1":{"type":"branch","line":6,"loc":{"start":{"line":6,"column":44},"end":{"line":9,"column":3}},"locations":[{"start":{"line":6,"column":44},"end":{"line":9,"column":3}}]},"2":{"type":"branch","line":11,"loc":{"start":{"line":11,"column":12},"end":{"line":37,"column":5}},"locations":[{"start":{"line":11,"column":12},"end":{"line":37,"column":5}}]},"3":{"type":"branch","line":27,"loc":{"start":{"line":27,"column":45},"end":{"line":27,"column":64}},"locations":[{"start":{"line":27,"column":45},"end":{"line":27,"column":64}}]},"4":{"type":"branch","line":28,"loc":{"start":{"line":28,"column":4},"end":{"line":30,"column":5}},"locations":[{"start":{"line":28,"column":4},"end":{"line":30,"column":5}}]},"5":{"type":"branch","line":21,"loc":{"start":{"line":21,"column":32},"end":{"line":23,"column":6}},"locations":[{"start":{"line":21,"column":32},"end":{"line":23,"column":6}}]},"6":{"type":"branch","line":34,"loc":{"start":{"line":34,"column":11},"end":{"line":36,"column":6}},"locations":[{"start":{"line":34,"column":11},"end":{"line":36,"column":6}}]}},"b":{"0":[16],"1":[7],"2":[7],"3":[0],"4":[0],"5":[7],"6":[7]},"fnMap":{"0":{"name":"useTheme","decl":{"start":{"line":5,"column":17},"end":{"line":49,"column":2}},"loc":{"start":{"line":5,"column":17},"end":{"line":49,"column":2}},"line":5},"1":{"name":"handleDarkModeChange","decl":{"start":{"line":15,"column":33},"end":{"line":19,"column":6}},"loc":{"start":{"line":15,"column":33},"end":{"line":19,"column":6}},"line":15},"2":{"name":"updateDocumentTheme","decl":{"start":{"line":21,"column":32},"end":{"line":23,"column":6}},"loc":{"start":{"line":21,"column":32},"end":{"line":23,"column":6}},"line":21}},"f":{"0":16,"1":0,"2":7}} +,"/Users/ashwin/code/mcp/inspector/client/src/lib/utils.ts": {"path":"/Users/ashwin/code/mcp/inspector/client/src/lib/utils.ts","all":false,"statementMap":{"0":{"start":{"line":1,"column":0},"end":{"line":1,"column":45}},"3":{"start":{"line":4,"column":0},"end":{"line":4,"column":45}},"4":{"start":{"line":5,"column":0},"end":{"line":5,"column":31}},"5":{"start":{"line":6,"column":0},"end":{"line":6,"column":1}}},"s":{"0":1,"3":1,"4":705,"5":705},"branchMap":{"0":{"type":"branch","line":4,"loc":{"start":{"line":4,"column":7},"end":{"line":6,"column":1}},"locations":[{"start":{"line":4,"column":7},"end":{"line":6,"column":1}}]}},"b":{"0":[705]},"fnMap":{"0":{"name":"cn","decl":{"start":{"line":4,"column":7},"end":{"line":6,"column":1}},"loc":{"start":{"line":4,"column":7},"end":{"line":6,"column":1}},"line":4}},"f":{"0":705}} +,"/Users/ashwin/code/mcp/inspector/client/src/lib/hooks/useConnection.ts": {"path":"/Users/ashwin/code/mcp/inspector/client/src/lib/hooks/useConnection.ts","all":true,"statementMap":{"0":{"start":{"line":1,"column":0},"end":{"line":1,"column":67}},"17":{"start":{"line":18,"column":0},"end":{"line":18,"column":43}},"33":{"start":{"line":34,"column":0},"end":{"line":34,"column":31}},"34":{"start":{"line":35,"column":0},"end":{"line":35,"column":16}},"35":{"start":{"line":36,"column":0},"end":{"line":36,"column":10}},"36":{"start":{"line":37,"column":0},"end":{"line":37,"column":7}},"37":{"start":{"line":38,"column":0},"end":{"line":38,"column":9}},"38":{"start":{"line":39,"column":0},"end":{"line":39,"column":6}},"39":{"start":{"line":40,"column":0},"end":{"line":40,"column":17}},"40":{"start":{"line":41,"column":0},"end":{"line":41,"column":48}},"41":{"start":{"line":42,"column":0},"end":{"line":42,"column":17}},"42":{"start":{"line":43,"column":0},"end":{"line":43,"column":23}},"43":{"start":{"line":44,"column":0},"end":{"line":44,"column":19}},"44":{"start":{"line":45,"column":0},"end":{"line":45,"column":11}},"45":{"start":{"line":46,"column":0},"end":{"line":46,"column":26}},"46":{"start":{"line":47,"column":0},"end":{"line":47,"column":115}},"47":{"start":{"line":48,"column":0},"end":{"line":48,"column":96}},"48":{"start":{"line":49,"column":0},"end":{"line":49,"column":66}},"49":{"start":{"line":50,"column":0},"end":{"line":50,"column":101}},"51":{"start":{"line":52,"column":0},"end":{"line":52,"column":63}},"52":{"start":{"line":53,"column":0},"end":{"line":53,"column":33}},"53":{"start":{"line":54,"column":0},"end":{"line":54,"column":14}},"54":{"start":{"line":55,"column":0},"end":{"line":55,"column":7}},"55":{"start":{"line":56,"column":0},"end":{"line":56,"column":41}},"56":{"start":{"line":57,"column":0},"end":{"line":57,"column":80}},"57":{"start":{"line":58,"column":0},"end":{"line":58,"column":8}},"58":{"start":{"line":59,"column":0},"end":{"line":59,"column":7}},"59":{"start":{"line":60,"column":0},"end":{"line":60,"column":4}},"61":{"start":{"line":62,"column":0},"end":{"line":62,"column":50}},"62":{"start":{"line":63,"column":0},"end":{"line":63,"column":27}},"63":{"start":{"line":64,"column":0},"end":{"line":64,"column":13}},"64":{"start":{"line":65,"column":0},"end":{"line":65,"column":8}},"65":{"start":{"line":66,"column":0},"end":{"line":66,"column":21}},"66":{"start":{"line":67,"column":0},"end":{"line":67,"column":50}},"67":{"start":{"line":68,"column":0},"end":{"line":68,"column":5}},"69":{"start":{"line":70,"column":0},"end":{"line":70,"column":9}},"70":{"start":{"line":71,"column":0},"end":{"line":71,"column":52}},"71":{"start":{"line":72,"column":0},"end":{"line":72,"column":42}},"72":{"start":{"line":73,"column":0},"end":{"line":73,"column":51}},"73":{"start":{"line":74,"column":0},"end":{"line":74,"column":25}},"75":{"start":{"line":76,"column":0},"end":{"line":76,"column":19}},"76":{"start":{"line":77,"column":0},"end":{"line":77,"column":11}},"77":{"start":{"line":78,"column":0},"end":{"line":78,"column":61}},"78":{"start":{"line":79,"column":0},"end":{"line":79,"column":41}},"79":{"start":{"line":80,"column":0},"end":{"line":80,"column":11}},"80":{"start":{"line":81,"column":0},"end":{"line":81,"column":39}},"81":{"start":{"line":82,"column":0},"end":{"line":82,"column":23}},"82":{"start":{"line":83,"column":0},"end":{"line":83,"column":84}},"83":{"start":{"line":84,"column":0},"end":{"line":84,"column":54}},"84":{"start":{"line":85,"column":0},"end":{"line":85,"column":20}},"85":{"start":{"line":86,"column":0},"end":{"line":86,"column":17}},"86":{"start":{"line":87,"column":0},"end":{"line":87,"column":32}},"87":{"start":{"line":88,"column":0},"end":{"line":88,"column":7}},"90":{"start":{"line":91,"column":0},"end":{"line":91,"column":22}},"91":{"start":{"line":92,"column":0},"end":{"line":92,"column":26}},"92":{"start":{"line":93,"column":0},"end":{"line":93,"column":60}},"93":{"start":{"line":94,"column":0},"end":{"line":94,"column":31}},"95":{"start":{"line":96,"column":0},"end":{"line":96,"column":14}},"96":{"start":{"line":97,"column":0},"end":{"line":97,"column":5}},"97":{"start":{"line":98,"column":0},"end":{"line":98,"column":4}},"99":{"start":{"line":100,"column":0},"end":{"line":100,"column":72}},"100":{"start":{"line":101,"column":0},"end":{"line":101,"column":21}},"101":{"start":{"line":102,"column":0},"end":{"line":102,"column":50}},"102":{"start":{"line":103,"column":0},"end":{"line":103,"column":5}},"104":{"start":{"line":105,"column":0},"end":{"line":105,"column":9}},"105":{"start":{"line":106,"column":0},"end":{"line":106,"column":49}},"106":{"start":{"line":107,"column":0},"end":{"line":107,"column":32}},"107":{"start":{"line":108,"column":0},"end":{"line":108,"column":26}},"108":{"start":{"line":109,"column":0},"end":{"line":109,"column":53}},"109":{"start":{"line":110,"column":0},"end":{"line":110,"column":14}},"110":{"start":{"line":111,"column":0},"end":{"line":111,"column":5}},"111":{"start":{"line":112,"column":0},"end":{"line":112,"column":4}},"113":{"start":{"line":114,"column":0},"end":{"line":114,"column":31}},"114":{"start":{"line":115,"column":0},"end":{"line":115,"column":9}},"115":{"start":{"line":116,"column":0},"end":{"line":116,"column":63}},"116":{"start":{"line":117,"column":0},"end":{"line":117,"column":9}},"117":{"start":{"line":118,"column":0},"end":{"line":118,"column":32}},"118":{"start":{"line":119,"column":0},"end":{"line":119,"column":27}},"119":{"start":{"line":120,"column":0},"end":{"line":120,"column":10}},"120":{"start":{"line":121,"column":0},"end":{"line":121,"column":9}},"121":{"start":{"line":122,"column":0},"end":{"line":122,"column":25}},"122":{"start":{"line":123,"column":0},"end":{"line":123,"column":25}},"123":{"start":{"line":124,"column":0},"end":{"line":124,"column":20}},"124":{"start":{"line":125,"column":0},"end":{"line":125,"column":32}},"125":{"start":{"line":126,"column":0},"end":{"line":126,"column":14}},"126":{"start":{"line":127,"column":0},"end":{"line":127,"column":12}},"127":{"start":{"line":128,"column":0},"end":{"line":128,"column":10}},"128":{"start":{"line":129,"column":0},"end":{"line":129,"column":8}},"130":{"start":{"line":131,"column":0},"end":{"line":131,"column":58}},"132":{"start":{"line":133,"column":0},"end":{"line":133,"column":69}},"133":{"start":{"line":134,"column":0},"end":{"line":134,"column":38}},"134":{"start":{"line":135,"column":0},"end":{"line":135,"column":59}},"135":{"start":{"line":136,"column":0},"end":{"line":136,"column":53}},"136":{"start":{"line":137,"column":0},"end":{"line":137,"column":67}},"137":{"start":{"line":138,"column":0},"end":{"line":138,"column":14}},"138":{"start":{"line":139,"column":0},"end":{"line":139,"column":54}},"139":{"start":{"line":140,"column":0},"end":{"line":140,"column":7}},"141":{"start":{"line":142,"column":0},"end":{"line":142,"column":65}},"143":{"start":{"line":144,"column":0},"end":{"line":144,"column":27}},"144":{"start":{"line":145,"column":0},"end":{"line":145,"column":82}},"145":{"start":{"line":146,"column":0},"end":{"line":146,"column":7}},"147":{"start":{"line":148,"column":0},"end":{"line":148,"column":33}},"148":{"start":{"line":149,"column":0},"end":{"line":149,"column":86}},"149":{"start":{"line":150,"column":0},"end":{"line":150,"column":7}},"151":{"start":{"line":152,"column":0},"end":{"line":152,"column":44}},"153":{"start":{"line":154,"column":0},"end":{"line":154,"column":58}},"154":{"start":{"line":155,"column":0},"end":{"line":155,"column":50}},"156":{"start":{"line":157,"column":0},"end":{"line":157,"column":29}},"157":{"start":{"line":158,"column":0},"end":{"line":158,"column":75}},"158":{"start":{"line":159,"column":0},"end":{"line":159,"column":51}},"159":{"start":{"line":160,"column":0},"end":{"line":160,"column":55}},"160":{"start":{"line":161,"column":0},"end":{"line":161,"column":13}},"161":{"start":{"line":162,"column":0},"end":{"line":162,"column":11}},"162":{"start":{"line":163,"column":0},"end":{"line":163,"column":7}},"164":{"start":{"line":165,"column":0},"end":{"line":165,"column":21}},"165":{"start":{"line":166,"column":0},"end":{"line":166,"column":70}},"166":{"start":{"line":167,"column":0},"end":{"line":167,"column":39}},"167":{"start":{"line":168,"column":0},"end":{"line":168,"column":11}},"168":{"start":{"line":169,"column":0},"end":{"line":169,"column":7}},"170":{"start":{"line":171,"column":0},"end":{"line":171,"column":27}},"171":{"start":{"line":172,"column":0},"end":{"line":172,"column":39}},"172":{"start":{"line":173,"column":0},"end":{"line":173,"column":17}},"173":{"start":{"line":174,"column":0},"end":{"line":174,"column":23}},"174":{"start":{"line":175,"column":0},"end":{"line":175,"column":35}},"175":{"start":{"line":176,"column":0},"end":{"line":176,"column":5}},"176":{"start":{"line":177,"column":0},"end":{"line":177,"column":4}},"178":{"start":{"line":179,"column":0},"end":{"line":179,"column":10}},"179":{"start":{"line":180,"column":0},"end":{"line":180,"column":21}},"180":{"start":{"line":181,"column":0},"end":{"line":181,"column":23}},"181":{"start":{"line":182,"column":0},"end":{"line":182,"column":14}},"182":{"start":{"line":183,"column":0},"end":{"line":183,"column":19}},"183":{"start":{"line":184,"column":0},"end":{"line":184,"column":16}},"184":{"start":{"line":185,"column":0},"end":{"line":185,"column":21}},"185":{"start":{"line":186,"column":0},"end":{"line":186,"column":11}},"186":{"start":{"line":187,"column":0},"end":{"line":187,"column":4}},"187":{"start":{"line":188,"column":0},"end":{"line":188,"column":1}}},"s":{"0":0,"17":0,"33":0,"34":0,"35":0,"36":0,"37":0,"38":0,"39":0,"40":0,"41":0,"42":0,"43":0,"44":0,"45":0,"46":0,"47":0,"48":0,"49":0,"51":0,"52":0,"53":0,"54":0,"55":0,"56":0,"57":0,"58":0,"59":0,"61":0,"62":0,"63":0,"64":0,"65":0,"66":0,"67":0,"69":0,"70":0,"71":0,"72":0,"73":0,"75":0,"76":0,"77":0,"78":0,"79":0,"80":0,"81":0,"82":0,"83":0,"84":0,"85":0,"86":0,"87":0,"90":0,"91":0,"92":0,"93":0,"95":0,"96":0,"97":0,"99":0,"100":0,"101":0,"102":0,"104":0,"105":0,"106":0,"107":0,"108":0,"109":0,"110":0,"111":0,"113":0,"114":0,"115":0,"116":0,"117":0,"118":0,"119":0,"120":0,"121":0,"122":0,"123":0,"124":0,"125":0,"126":0,"127":0,"128":0,"130":0,"132":0,"133":0,"134":0,"135":0,"136":0,"137":0,"138":0,"139":0,"141":0,"143":0,"144":0,"145":0,"147":0,"148":0,"149":0,"151":0,"153":0,"154":0,"156":0,"157":0,"158":0,"159":0,"160":0,"161":0,"162":0,"164":0,"165":0,"166":0,"167":0,"168":0,"170":0,"171":0,"172":0,"173":0,"174":0,"175":0,"176":0,"178":0,"179":0,"180":0,"181":0,"182":0,"183":0,"184":0,"185":0,"186":0,"187":0},"branchMap":{"0":{"type":"branch","line":1,"loc":{"start":{"line":1,"column":5219},"end":{"line":188,"column":1}},"locations":[{"start":{"line":1,"column":5219},"end":{"line":188,"column":1}}]}},"b":{"0":[0]},"fnMap":{"0":{"name":"(empty-report)","decl":{"start":{"line":1,"column":5219},"end":{"line":188,"column":1}},"loc":{"start":{"line":1,"column":5219},"end":{"line":188,"column":1}},"line":1}},"f":{"0":0}} +,"/Users/ashwin/code/mcp/inspector/client/src/lib/hooks/useDraggablePane.ts": {"path":"/Users/ashwin/code/mcp/inspector/client/src/lib/hooks/useDraggablePane.ts","all":true,"statementMap":{"0":{"start":{"line":1,"column":0},"end":{"line":1,"column":65}},"2":{"start":{"line":3,"column":0},"end":{"line":3,"column":57}},"3":{"start":{"line":4,"column":0},"end":{"line":4,"column":54}},"4":{"start":{"line":5,"column":0},"end":{"line":5,"column":54}},"5":{"start":{"line":6,"column":0},"end":{"line":6,"column":39}},"6":{"start":{"line":7,"column":0},"end":{"line":7,"column":44}},"8":{"start":{"line":9,"column":0},"end":{"line":9,"column":64}},"9":{"start":{"line":10,"column":0},"end":{"line":10,"column":24}},"10":{"start":{"line":11,"column":0},"end":{"line":11,"column":35}},"11":{"start":{"line":12,"column":0},"end":{"line":12,"column":37}},"12":{"start":{"line":13,"column":0},"end":{"line":13,"column":44}},"13":{"start":{"line":14,"column":0},"end":{"line":14,"column":15}},"15":{"start":{"line":16,"column":0},"end":{"line":16,"column":57}},"16":{"start":{"line":17,"column":0},"end":{"line":17,"column":28}},"17":{"start":{"line":18,"column":0},"end":{"line":18,"column":50}},"18":{"start":{"line":19,"column":0},"end":{"line":19,"column":85}},"19":{"start":{"line":20,"column":0},"end":{"line":20,"column":25}},"20":{"start":{"line":21,"column":0},"end":{"line":21,"column":19}},"22":{"start":{"line":23,"column":0},"end":{"line":23,"column":43}},"23":{"start":{"line":24,"column":0},"end":{"line":24,"column":25}},"24":{"start":{"line":25,"column":0},"end":{"line":25,"column":40}},"25":{"start":{"line":26,"column":0},"end":{"line":26,"column":9}},"27":{"start":{"line":28,"column":0},"end":{"line":28,"column":19}},"28":{"start":{"line":29,"column":0},"end":{"line":29,"column":21}},"29":{"start":{"line":30,"column":0},"end":{"line":30,"column":59}},"30":{"start":{"line":31,"column":0},"end":{"line":31,"column":56}},"31":{"start":{"line":32,"column":0},"end":{"line":32,"column":20}},"32":{"start":{"line":33,"column":0},"end":{"line":33,"column":64}},"33":{"start":{"line":34,"column":0},"end":{"line":34,"column":61}},"34":{"start":{"line":35,"column":0},"end":{"line":35,"column":8}},"35":{"start":{"line":36,"column":0},"end":{"line":36,"column":5}},"36":{"start":{"line":37,"column":0},"end":{"line":37,"column":50}},"38":{"start":{"line":39,"column":0},"end":{"line":39,"column":10}},"39":{"start":{"line":40,"column":0},"end":{"line":40,"column":11}},"40":{"start":{"line":41,"column":0},"end":{"line":41,"column":15}},"41":{"start":{"line":42,"column":0},"end":{"line":42,"column":19}},"42":{"start":{"line":43,"column":0},"end":{"line":43,"column":4}},"43":{"start":{"line":44,"column":0},"end":{"line":44,"column":1}}},"s":{"0":0,"2":0,"3":0,"4":0,"5":0,"6":0,"8":0,"9":0,"10":0,"11":0,"12":0,"13":0,"15":0,"16":0,"17":0,"18":0,"19":0,"20":0,"22":0,"23":0,"24":0,"25":0,"27":0,"28":0,"29":0,"30":0,"31":0,"32":0,"33":0,"34":0,"35":0,"36":0,"38":0,"39":0,"40":0,"41":0,"42":0,"43":0},"branchMap":{"0":{"type":"branch","line":1,"loc":{"start":{"line":1,"column":0},"end":{"line":44,"column":-158}},"locations":[{"start":{"line":1,"column":0},"end":{"line":44,"column":-158}}]}},"b":{"0":[0]},"fnMap":{"0":{"name":"(empty-report)","decl":{"start":{"line":1,"column":0},"end":{"line":44,"column":-158}},"loc":{"start":{"line":1,"column":0},"end":{"line":44,"column":-158}},"line":1}},"f":{"0":0}} +} diff --git a/client/coverage/favicon.png b/client/coverage/favicon.png new file mode 100644 index 0000000000000000000000000000000000000000..c1525b811a167671e9de1fa78aab9f5c0b61cef7 GIT binary patch literal 445 zcmV;u0Yd(XP))rP{nL}Ln%S7`m{0DjX9TLF* zFCb$4Oi7vyLOydb!7n&^ItCzb-%BoB`=x@N2jll2Nj`kauio%aw_@fe&*}LqlFT43 z8doAAe))z_%=P%v^@JHp3Hjhj^6*Kr_h|g_Gr?ZAa&y>wxHE99Gk>A)2MplWz2xdG zy8VD2J|Uf#EAw*bo5O*PO_}X2Tob{%bUoO2G~T`@%S6qPyc}VkhV}UifBuRk>%5v( z)x7B{I~z*k<7dv#5tC+m{km(D087J4O%+<<;K|qwefb6@GSX45wCK}Sn*> + + + + Code coverage report for All files + + + + + + + + + +
+
+

All files

+
+ +
+ 65.59% + Statements + 1331/2029 +
+ + +
+ 83.83% + Branches + 140/167 +
+ + +
+ 42.7% + Functions + 41/96 +
+ + +
+ 65.59% + Lines + 1331/2029 +
+ + +
+

+ Press n or j to go to the next uncovered block, b, p or k for the previous block. +

+ +
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FileStatementsBranchesFunctionsLines
client +
+
0%0/640%0/20%0/20%0/64
client/bin +
+
0%0/160%0/10%0/10%0/16
client/src +
+
59.17%274/46386.2%25/295.88%2/3459.17%274/463
client/src/components +
+
77.34%758/98087.03%94/10869.23%36/5277.34%758/980
client/src/components/ui +
+
95.68%266/27893.75%15/16100%0/095.68%266/278
client/src/lib +
+
61.11%33/5466.66%6/960%3/561.11%33/54
client/src/lib/hooks +
+
0%0/1740%0/20%0/20%0/174
+
+
+
+ + + + + + + + \ No newline at end of file diff --git a/client/coverage/prettify.css b/client/coverage/prettify.css new file mode 100644 index 0000000000..b317a7cda3 --- /dev/null +++ b/client/coverage/prettify.css @@ -0,0 +1 @@ +.pln{color:#000}@media screen{.str{color:#080}.kwd{color:#008}.com{color:#800}.typ{color:#606}.lit{color:#066}.pun,.opn,.clo{color:#660}.tag{color:#008}.atn{color:#606}.atv{color:#080}.dec,.var{color:#606}.fun{color:red}}@media print,projection{.str{color:#060}.kwd{color:#006;font-weight:bold}.com{color:#600;font-style:italic}.typ{color:#404;font-weight:bold}.lit{color:#044}.pun,.opn,.clo{color:#440}.tag{color:#006;font-weight:bold}.atn{color:#404}.atv{color:#060}}pre.prettyprint{padding:2px;border:1px solid #888}ol.linenums{margin-top:0;margin-bottom:0}li.L0,li.L1,li.L2,li.L3,li.L5,li.L6,li.L7,li.L8{list-style-type:none}li.L1,li.L3,li.L5,li.L7,li.L9{background:#eee} diff --git a/client/coverage/prettify.js b/client/coverage/prettify.js new file mode 100644 index 0000000000..b3225238f2 --- /dev/null +++ b/client/coverage/prettify.js @@ -0,0 +1,2 @@ +/* eslint-disable */ +window.PR_SHOULD_USE_CONTINUATION=true;(function(){var h=["break,continue,do,else,for,if,return,while"];var u=[h,"auto,case,char,const,default,double,enum,extern,float,goto,int,long,register,short,signed,sizeof,static,struct,switch,typedef,union,unsigned,void,volatile"];var p=[u,"catch,class,delete,false,import,new,operator,private,protected,public,this,throw,true,try,typeof"];var l=[p,"alignof,align_union,asm,axiom,bool,concept,concept_map,const_cast,constexpr,decltype,dynamic_cast,explicit,export,friend,inline,late_check,mutable,namespace,nullptr,reinterpret_cast,static_assert,static_cast,template,typeid,typename,using,virtual,where"];var x=[p,"abstract,boolean,byte,extends,final,finally,implements,import,instanceof,null,native,package,strictfp,super,synchronized,throws,transient"];var R=[x,"as,base,by,checked,decimal,delegate,descending,dynamic,event,fixed,foreach,from,group,implicit,in,interface,internal,into,is,lock,object,out,override,orderby,params,partial,readonly,ref,sbyte,sealed,stackalloc,string,select,uint,ulong,unchecked,unsafe,ushort,var"];var r="all,and,by,catch,class,else,extends,false,finally,for,if,in,is,isnt,loop,new,no,not,null,of,off,on,or,return,super,then,true,try,unless,until,when,while,yes";var w=[p,"debugger,eval,export,function,get,null,set,undefined,var,with,Infinity,NaN"];var s="caller,delete,die,do,dump,elsif,eval,exit,foreach,for,goto,if,import,last,local,my,next,no,our,print,package,redo,require,sub,undef,unless,until,use,wantarray,while,BEGIN,END";var I=[h,"and,as,assert,class,def,del,elif,except,exec,finally,from,global,import,in,is,lambda,nonlocal,not,or,pass,print,raise,try,with,yield,False,True,None"];var f=[h,"alias,and,begin,case,class,def,defined,elsif,end,ensure,false,in,module,next,nil,not,or,redo,rescue,retry,self,super,then,true,undef,unless,until,when,yield,BEGIN,END"];var H=[h,"case,done,elif,esac,eval,fi,function,in,local,set,then,until"];var A=[l,R,w,s+I,f,H];var e=/^(DIR|FILE|vector|(de|priority_)?queue|list|stack|(const_)?iterator|(multi)?(set|map)|bitset|u?(int|float)\d*)/;var C="str";var z="kwd";var j="com";var O="typ";var G="lit";var L="pun";var F="pln";var m="tag";var E="dec";var J="src";var P="atn";var n="atv";var N="nocode";var M="(?:^^\\.?|[+-]|\\!|\\!=|\\!==|\\#|\\%|\\%=|&|&&|&&=|&=|\\(|\\*|\\*=|\\+=|\\,|\\-=|\\->|\\/|\\/=|:|::|\\;|<|<<|<<=|<=|=|==|===|>|>=|>>|>>=|>>>|>>>=|\\?|\\@|\\[|\\^|\\^=|\\^\\^|\\^\\^=|\\{|\\||\\|=|\\|\\||\\|\\|=|\\~|break|case|continue|delete|do|else|finally|instanceof|return|throw|try|typeof)\\s*";function k(Z){var ad=0;var S=false;var ac=false;for(var V=0,U=Z.length;V122)){if(!(al<65||ag>90)){af.push([Math.max(65,ag)|32,Math.min(al,90)|32])}if(!(al<97||ag>122)){af.push([Math.max(97,ag)&~32,Math.min(al,122)&~32])}}}}af.sort(function(av,au){return(av[0]-au[0])||(au[1]-av[1])});var ai=[];var ap=[NaN,NaN];for(var ar=0;arat[0]){if(at[1]+1>at[0]){an.push("-")}an.push(T(at[1]))}}an.push("]");return an.join("")}function W(al){var aj=al.source.match(new RegExp("(?:\\[(?:[^\\x5C\\x5D]|\\\\[\\s\\S])*\\]|\\\\u[A-Fa-f0-9]{4}|\\\\x[A-Fa-f0-9]{2}|\\\\[0-9]+|\\\\[^ux0-9]|\\(\\?[:!=]|[\\(\\)\\^]|[^\\x5B\\x5C\\(\\)\\^]+)","g"));var ah=aj.length;var an=[];for(var ak=0,am=0;ak=2&&ai==="["){aj[ak]=X(ag)}else{if(ai!=="\\"){aj[ak]=ag.replace(/[a-zA-Z]/g,function(ao){var ap=ao.charCodeAt(0);return"["+String.fromCharCode(ap&~32,ap|32)+"]"})}}}}return aj.join("")}var aa=[];for(var V=0,U=Z.length;V=0;){S[ac.charAt(ae)]=Y}}var af=Y[1];var aa=""+af;if(!ag.hasOwnProperty(aa)){ah.push(af);ag[aa]=null}}ah.push(/[\0-\uffff]/);V=k(ah)})();var X=T.length;var W=function(ah){var Z=ah.sourceCode,Y=ah.basePos;var ad=[Y,F];var af=0;var an=Z.match(V)||[];var aj={};for(var ae=0,aq=an.length;ae=5&&"lang-"===ap.substring(0,5);if(am&&!(ai&&typeof ai[1]==="string")){am=false;ap=J}if(!am){aj[ag]=ap}}var ab=af;af+=ag.length;if(!am){ad.push(Y+ab,ap)}else{var al=ai[1];var ak=ag.indexOf(al);var ac=ak+al.length;if(ai[2]){ac=ag.length-ai[2].length;ak=ac-al.length}var ar=ap.substring(5);B(Y+ab,ag.substring(0,ak),W,ad);B(Y+ab+ak,al,q(ar,al),ad);B(Y+ab+ac,ag.substring(ac),W,ad)}}ah.decorations=ad};return W}function i(T){var W=[],S=[];if(T.tripleQuotedStrings){W.push([C,/^(?:\'\'\'(?:[^\'\\]|\\[\s\S]|\'{1,2}(?=[^\']))*(?:\'\'\'|$)|\"\"\"(?:[^\"\\]|\\[\s\S]|\"{1,2}(?=[^\"]))*(?:\"\"\"|$)|\'(?:[^\\\']|\\[\s\S])*(?:\'|$)|\"(?:[^\\\"]|\\[\s\S])*(?:\"|$))/,null,"'\""])}else{if(T.multiLineStrings){W.push([C,/^(?:\'(?:[^\\\']|\\[\s\S])*(?:\'|$)|\"(?:[^\\\"]|\\[\s\S])*(?:\"|$)|\`(?:[^\\\`]|\\[\s\S])*(?:\`|$))/,null,"'\"`"])}else{W.push([C,/^(?:\'(?:[^\\\'\r\n]|\\.)*(?:\'|$)|\"(?:[^\\\"\r\n]|\\.)*(?:\"|$))/,null,"\"'"])}}if(T.verbatimStrings){S.push([C,/^@\"(?:[^\"]|\"\")*(?:\"|$)/,null])}var Y=T.hashComments;if(Y){if(T.cStyleComments){if(Y>1){W.push([j,/^#(?:##(?:[^#]|#(?!##))*(?:###|$)|.*)/,null,"#"])}else{W.push([j,/^#(?:(?:define|elif|else|endif|error|ifdef|include|ifndef|line|pragma|undef|warning)\b|[^\r\n]*)/,null,"#"])}S.push([C,/^<(?:(?:(?:\.\.\/)*|\/?)(?:[\w-]+(?:\/[\w-]+)+)?[\w-]+\.h|[a-z]\w*)>/,null])}else{W.push([j,/^#[^\r\n]*/,null,"#"])}}if(T.cStyleComments){S.push([j,/^\/\/[^\r\n]*/,null]);S.push([j,/^\/\*[\s\S]*?(?:\*\/|$)/,null])}if(T.regexLiterals){var X=("/(?=[^/*])(?:[^/\\x5B\\x5C]|\\x5C[\\s\\S]|\\x5B(?:[^\\x5C\\x5D]|\\x5C[\\s\\S])*(?:\\x5D|$))+/");S.push(["lang-regex",new RegExp("^"+M+"("+X+")")])}var V=T.types;if(V){S.push([O,V])}var U=(""+T.keywords).replace(/^ | $/g,"");if(U.length){S.push([z,new RegExp("^(?:"+U.replace(/[\s,]+/g,"|")+")\\b"),null])}W.push([F,/^\s+/,null," \r\n\t\xA0"]);S.push([G,/^@[a-z_$][a-z_$@0-9]*/i,null],[O,/^(?:[@_]?[A-Z]+[a-z][A-Za-z_$@0-9]*|\w+_t\b)/,null],[F,/^[a-z_$][a-z_$@0-9]*/i,null],[G,new RegExp("^(?:0x[a-f0-9]+|(?:\\d(?:_\\d+)*\\d*(?:\\.\\d*)?|\\.\\d\\+)(?:e[+\\-]?\\d+)?)[a-z]*","i"),null,"0123456789"],[F,/^\\[\s\S]?/,null],[L,/^.[^\s\w\.$@\'\"\`\/\#\\]*/,null]);return g(W,S)}var K=i({keywords:A,hashComments:true,cStyleComments:true,multiLineStrings:true,regexLiterals:true});function Q(V,ag){var U=/(?:^|\s)nocode(?:\s|$)/;var ab=/\r\n?|\n/;var ac=V.ownerDocument;var S;if(V.currentStyle){S=V.currentStyle.whiteSpace}else{if(window.getComputedStyle){S=ac.defaultView.getComputedStyle(V,null).getPropertyValue("white-space")}}var Z=S&&"pre"===S.substring(0,3);var af=ac.createElement("LI");while(V.firstChild){af.appendChild(V.firstChild)}var W=[af];function ae(al){switch(al.nodeType){case 1:if(U.test(al.className)){break}if("BR"===al.nodeName){ad(al);if(al.parentNode){al.parentNode.removeChild(al)}}else{for(var an=al.firstChild;an;an=an.nextSibling){ae(an)}}break;case 3:case 4:if(Z){var am=al.nodeValue;var aj=am.match(ab);if(aj){var ai=am.substring(0,aj.index);al.nodeValue=ai;var ah=am.substring(aj.index+aj[0].length);if(ah){var ak=al.parentNode;ak.insertBefore(ac.createTextNode(ah),al.nextSibling)}ad(al);if(!ai){al.parentNode.removeChild(al)}}}break}}function ad(ak){while(!ak.nextSibling){ak=ak.parentNode;if(!ak){return}}function ai(al,ar){var aq=ar?al.cloneNode(false):al;var ao=al.parentNode;if(ao){var ap=ai(ao,1);var an=al.nextSibling;ap.appendChild(aq);for(var am=an;am;am=an){an=am.nextSibling;ap.appendChild(am)}}return aq}var ah=ai(ak.nextSibling,0);for(var aj;(aj=ah.parentNode)&&aj.nodeType===1;){ah=aj}W.push(ah)}for(var Y=0;Y=S){ah+=2}if(V>=ap){Z+=2}}}var t={};function c(U,V){for(var S=V.length;--S>=0;){var T=V[S];if(!t.hasOwnProperty(T)){t[T]=U}else{if(window.console){console.warn("cannot override language handler %s",T)}}}}function q(T,S){if(!(T&&t.hasOwnProperty(T))){T=/^\s*]*(?:>|$)/],[j,/^<\!--[\s\S]*?(?:-\->|$)/],["lang-",/^<\?([\s\S]+?)(?:\?>|$)/],["lang-",/^<%([\s\S]+?)(?:%>|$)/],[L,/^(?:<[%?]|[%?]>)/],["lang-",/^]*>([\s\S]+?)<\/xmp\b[^>]*>/i],["lang-js",/^]*>([\s\S]*?)(<\/script\b[^>]*>)/i],["lang-css",/^]*>([\s\S]*?)(<\/style\b[^>]*>)/i],["lang-in.tag",/^(<\/?[a-z][^<>]*>)/i]]),["default-markup","htm","html","mxml","xhtml","xml","xsl"]);c(g([[F,/^[\s]+/,null," \t\r\n"],[n,/^(?:\"[^\"]*\"?|\'[^\']*\'?)/,null,"\"'"]],[[m,/^^<\/?[a-z](?:[\w.:-]*\w)?|\/?>$/i],[P,/^(?!style[\s=]|on)[a-z](?:[\w:-]*\w)?/i],["lang-uq.val",/^=\s*([^>\'\"\s]*(?:[^>\'\"\s\/]|\/(?=\s)))/],[L,/^[=<>\/]+/],["lang-js",/^on\w+\s*=\s*\"([^\"]+)\"/i],["lang-js",/^on\w+\s*=\s*\'([^\']+)\'/i],["lang-js",/^on\w+\s*=\s*([^\"\'>\s]+)/i],["lang-css",/^style\s*=\s*\"([^\"]+)\"/i],["lang-css",/^style\s*=\s*\'([^\']+)\'/i],["lang-css",/^style\s*=\s*([^\"\'>\s]+)/i]]),["in.tag"]);c(g([],[[n,/^[\s\S]+/]]),["uq.val"]);c(i({keywords:l,hashComments:true,cStyleComments:true,types:e}),["c","cc","cpp","cxx","cyc","m"]);c(i({keywords:"null,true,false"}),["json"]);c(i({keywords:R,hashComments:true,cStyleComments:true,verbatimStrings:true,types:e}),["cs"]);c(i({keywords:x,cStyleComments:true}),["java"]);c(i({keywords:H,hashComments:true,multiLineStrings:true}),["bsh","csh","sh"]);c(i({keywords:I,hashComments:true,multiLineStrings:true,tripleQuotedStrings:true}),["cv","py"]);c(i({keywords:s,hashComments:true,multiLineStrings:true,regexLiterals:true}),["perl","pl","pm"]);c(i({keywords:f,hashComments:true,multiLineStrings:true,regexLiterals:true}),["rb"]);c(i({keywords:w,cStyleComments:true,regexLiterals:true}),["js"]);c(i({keywords:r,hashComments:3,cStyleComments:true,multilineStrings:true,tripleQuotedStrings:true,regexLiterals:true}),["coffee"]);c(g([],[[C,/^[\s\S]+/]]),["regex"]);function d(V){var U=V.langExtension;try{var S=a(V.sourceNode);var T=S.sourceCode;V.sourceCode=T;V.spans=S.spans;V.basePos=0;q(U,T)(V);D(V)}catch(W){if("console" in window){console.log(W&&W.stack?W.stack:W)}}}function y(W,V,U){var S=document.createElement("PRE");S.innerHTML=W;if(U){Q(S,U)}var T={langExtension:V,numberLines:U,sourceNode:S};d(T);return S.innerHTML}function b(ad){function Y(af){return document.getElementsByTagName(af)}var ac=[Y("pre"),Y("code"),Y("xmp")];var T=[];for(var aa=0;aa=0){var ah=ai.match(ab);var am;if(!ah&&(am=o(aj))&&"CODE"===am.tagName){ah=am.className.match(ab)}if(ah){ah=ah[1]}var al=false;for(var ak=aj.parentNode;ak;ak=ak.parentNode){if((ak.tagName==="pre"||ak.tagName==="code"||ak.tagName==="xmp")&&ak.className&&ak.className.indexOf("prettyprint")>=0){al=true;break}}if(!al){var af=aj.className.match(/\blinenums\b(?::(\d+))?/);af=af?af[1]&&af[1].length?+af[1]:true:false;if(af){Q(aj,af)}S={langExtension:ah,sourceNode:aj,numberLines:af};d(S)}}}if(X]*(?:>|$)/],[PR.PR_COMMENT,/^<\!--[\s\S]*?(?:-\->|$)/],[PR.PR_PUNCTUATION,/^(?:<[%?]|[%?]>)/],["lang-",/^<\?([\s\S]+?)(?:\?>|$)/],["lang-",/^<%([\s\S]+?)(?:%>|$)/],["lang-",/^]*>([\s\S]+?)<\/xmp\b[^>]*>/i],["lang-handlebars",/^]*type\s*=\s*['"]?text\/x-handlebars-template['"]?\b[^>]*>([\s\S]*?)(<\/script\b[^>]*>)/i],["lang-js",/^]*>([\s\S]*?)(<\/script\b[^>]*>)/i],["lang-css",/^]*>([\s\S]*?)(<\/style\b[^>]*>)/i],["lang-in.tag",/^(<\/?[a-z][^<>]*>)/i],[PR.PR_DECLARATION,/^{{[#^>/]?\s*[\w.][^}]*}}/],[PR.PR_DECLARATION,/^{{&?\s*[\w.][^}]*}}/],[PR.PR_DECLARATION,/^{{{>?\s*[\w.][^}]*}}}/],[PR.PR_COMMENT,/^{{![^}]*}}/]]),["handlebars","hbs"]);PR.registerLangHandler(PR.createSimpleLexer([[PR.PR_PLAIN,/^[ \t\r\n\f]+/,null," \t\r\n\f"]],[[PR.PR_STRING,/^\"(?:[^\n\r\f\\\"]|\\(?:\r\n?|\n|\f)|\\[\s\S])*\"/,null],[PR.PR_STRING,/^\'(?:[^\n\r\f\\\']|\\(?:\r\n?|\n|\f)|\\[\s\S])*\'/,null],["lang-css-str",/^url\(([^\)\"\']*)\)/i],[PR.PR_KEYWORD,/^(?:url|rgb|\!important|@import|@page|@media|@charset|inherit)(?=[^\-\w]|$)/i,null],["lang-css-kw",/^(-?(?:[_a-z]|(?:\\[0-9a-f]+ ?))(?:[_a-z0-9\-]|\\(?:\\[0-9a-f]+ ?))*)\s*:/i],[PR.PR_COMMENT,/^\/\*[^*]*\*+(?:[^\/*][^*]*\*+)*\//],[PR.PR_COMMENT,/^(?:)/],[PR.PR_LITERAL,/^(?:\d+|\d*\.\d+)(?:%|[a-z]+)?/i],[PR.PR_LITERAL,/^#(?:[0-9a-f]{3}){1,2}/i],[PR.PR_PLAIN,/^-?(?:[_a-z]|(?:\\[\da-f]+ ?))(?:[_a-z\d\-]|\\(?:\\[\da-f]+ ?))*/i],[PR.PR_PUNCTUATION,/^[^\s\w\'\"]+/]]),["css"]);PR.registerLangHandler(PR.createSimpleLexer([],[[PR.PR_KEYWORD,/^-?(?:[_a-z]|(?:\\[\da-f]+ ?))(?:[_a-z\d\-]|\\(?:\\[\da-f]+ ?))*/i]]),["css-kw"]);PR.registerLangHandler(PR.createSimpleLexer([],[[PR.PR_STRING,/^[^\)\"\']+/]]),["css-str"]); diff --git a/client/coverage/sort-arrow-sprite.png b/client/coverage/sort-arrow-sprite.png new file mode 100644 index 0000000000000000000000000000000000000000..6ed68316eb3f65dec9063332d2f69bf3093bbfab GIT binary patch literal 138 zcmeAS@N?(olHy`uVBq!ia0vp^>_9Bd!3HEZxJ@+%Qh}Z>jv*C{$p!i!8j}?a+@3A= zIAGwzjijN=FBi!|L1t?LM;Q;gkwn>2cAy-KV{dn nf0J1DIvEHQu*n~6U}x}qyky7vi4|9XhBJ7&`njxgN@xNA8m%nc literal 0 HcmV?d00001 diff --git a/client/coverage/sorter.js b/client/coverage/sorter.js new file mode 100644 index 0000000000..2bb296a8ca --- /dev/null +++ b/client/coverage/sorter.js @@ -0,0 +1,196 @@ +/* eslint-disable */ +var addSorting = (function() { + 'use strict'; + var cols, + currentSort = { + index: 0, + desc: false + }; + + // returns the summary table element + function getTable() { + return document.querySelector('.coverage-summary'); + } + // returns the thead element of the summary table + function getTableHeader() { + return getTable().querySelector('thead tr'); + } + // returns the tbody element of the summary table + function getTableBody() { + return getTable().querySelector('tbody'); + } + // returns the th element for nth column + function getNthColumn(n) { + return getTableHeader().querySelectorAll('th')[n]; + } + + function onFilterInput() { + const searchValue = document.getElementById('fileSearch').value; + const rows = document.getElementsByTagName('tbody')[0].children; + for (let i = 0; i < rows.length; i++) { + const row = rows[i]; + if ( + row.textContent + .toLowerCase() + .includes(searchValue.toLowerCase()) + ) { + row.style.display = ''; + } else { + row.style.display = 'none'; + } + } + } + + // loads the search box + function addSearchBox() { + var template = document.getElementById('filterTemplate'); + var templateClone = template.content.cloneNode(true); + templateClone.getElementById('fileSearch').oninput = onFilterInput; + template.parentElement.appendChild(templateClone); + } + + // loads all columns + function loadColumns() { + var colNodes = getTableHeader().querySelectorAll('th'), + colNode, + cols = [], + col, + i; + + for (i = 0; i < colNodes.length; i += 1) { + colNode = colNodes[i]; + col = { + key: colNode.getAttribute('data-col'), + sortable: !colNode.getAttribute('data-nosort'), + type: colNode.getAttribute('data-type') || 'string' + }; + cols.push(col); + if (col.sortable) { + col.defaultDescSort = col.type === 'number'; + colNode.innerHTML = + colNode.innerHTML + ''; + } + } + return cols; + } + // attaches a data attribute to every tr element with an object + // of data values keyed by column name + function loadRowData(tableRow) { + var tableCols = tableRow.querySelectorAll('td'), + colNode, + col, + data = {}, + i, + val; + for (i = 0; i < tableCols.length; i += 1) { + colNode = tableCols[i]; + col = cols[i]; + val = colNode.getAttribute('data-value'); + if (col.type === 'number') { + val = Number(val); + } + data[col.key] = val; + } + return data; + } + // loads all row data + function loadData() { + var rows = getTableBody().querySelectorAll('tr'), + i; + + for (i = 0; i < rows.length; i += 1) { + rows[i].data = loadRowData(rows[i]); + } + } + // sorts the table using the data for the ith column + function sortByIndex(index, desc) { + var key = cols[index].key, + sorter = function(a, b) { + a = a.data[key]; + b = b.data[key]; + return a < b ? -1 : a > b ? 1 : 0; + }, + finalSorter = sorter, + tableBody = document.querySelector('.coverage-summary tbody'), + rowNodes = tableBody.querySelectorAll('tr'), + rows = [], + i; + + if (desc) { + finalSorter = function(a, b) { + return -1 * sorter(a, b); + }; + } + + for (i = 0; i < rowNodes.length; i += 1) { + rows.push(rowNodes[i]); + tableBody.removeChild(rowNodes[i]); + } + + rows.sort(finalSorter); + + for (i = 0; i < rows.length; i += 1) { + tableBody.appendChild(rows[i]); + } + } + // removes sort indicators for current column being sorted + function removeSortIndicators() { + var col = getNthColumn(currentSort.index), + cls = col.className; + + cls = cls.replace(/ sorted$/, '').replace(/ sorted-desc$/, ''); + col.className = cls; + } + // adds sort indicators for current column being sorted + function addSortIndicators() { + getNthColumn(currentSort.index).className += currentSort.desc + ? ' sorted-desc' + : ' sorted'; + } + // adds event listeners for all sorter widgets + function enableUI() { + var i, + el, + ithSorter = function ithSorter(i) { + var col = cols[i]; + + return function() { + var desc = col.defaultDescSort; + + if (currentSort.index === i) { + desc = !currentSort.desc; + } + sortByIndex(i, desc); + removeSortIndicators(); + currentSort.index = i; + currentSort.desc = desc; + addSortIndicators(); + }; + }; + for (i = 0; i < cols.length; i += 1) { + if (cols[i].sortable) { + // add the click event handler on the th so users + // dont have to click on those tiny arrows + el = getNthColumn(i).querySelector('.sorter').parentElement; + if (el.addEventListener) { + el.addEventListener('click', ithSorter(i)); + } else { + el.attachEvent('onclick', ithSorter(i)); + } + } + } + } + // adds sorting functionality to the UI + return function() { + if (!getTable()) { + return; + } + cols = loadColumns(); + loadData(); + addSearchBox(); + addSortIndicators(); + enableUI(); + }; +})(); + +window.addEventListener('load', addSorting); diff --git a/client/package.json b/client/package.json index 8f5c66b9cb..f9026434df 100644 --- a/client/package.json +++ b/client/package.json @@ -49,6 +49,7 @@ "@types/react-dom": "^18.3.0", "@types/serve-handler": "^6.1.4", "@vitejs/plugin-react": "^4.3.2", + "@vitest/coverage-v8": "^2.1.8", "autoprefixer": "^10.4.20", "eslint": "^9.11.1", "eslint-plugin-react-hooks": "^5.1.0-rc.0", diff --git a/package-lock.json b/package-lock.json index d6fe08ccdb..9c2cba633e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -63,6 +63,7 @@ "@types/react-dom": "^18.3.0", "@types/serve-handler": "^6.1.4", "@vitejs/plugin-react": "^4.3.2", + "@vitest/coverage-v8": "^2.1.8", "autoprefixer": "^10.4.20", "eslint": "^9.11.1", "eslint-plugin-react-hooks": "^5.1.0-rc.0", @@ -405,6 +406,13 @@ "node": ">=6.9.0" } }, + "node_modules/@bcoe/v8-coverage": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", + "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", + "dev": true, + "license": "MIT" + }, "node_modules/@cspotcode/source-map-support": { "version": "0.8.1", "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", @@ -1172,6 +1180,16 @@ "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, + "node_modules/@istanbuljs/schema": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", + "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/@jridgewell/gen-mapping": { "version": "0.3.5", "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", @@ -2805,6 +2823,39 @@ "vite": "^4.2.0 || ^5.0.0 || ^6.0.0" } }, + "node_modules/@vitest/coverage-v8": { + "version": "2.1.8", + "resolved": "https://registry.npmjs.org/@vitest/coverage-v8/-/coverage-v8-2.1.8.tgz", + "integrity": "sha512-2Y7BPlKH18mAZYAW1tYByudlCYrQyl5RGvnnDYJKW5tCiO5qg3KSAy3XAxcxKz900a0ZXxWtKrMuZLe3lKBpJw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@ampproject/remapping": "^2.3.0", + "@bcoe/v8-coverage": "^0.2.3", + "debug": "^4.3.7", + "istanbul-lib-coverage": "^3.2.2", + "istanbul-lib-report": "^3.0.1", + "istanbul-lib-source-maps": "^5.0.6", + "istanbul-reports": "^3.1.7", + "magic-string": "^0.30.12", + "magicast": "^0.3.5", + "std-env": "^3.8.0", + "test-exclude": "^7.0.1", + "tinyrainbow": "^1.2.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "@vitest/browser": "2.1.8", + "vitest": "2.1.8" + }, + "peerDependenciesMeta": { + "@vitest/browser": { + "optional": true + } + } + }, "node_modules/@vitest/expect": { "version": "2.1.8", "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-2.1.8.tgz", @@ -4667,6 +4718,13 @@ "node": ">=18" } }, + "node_modules/html-escaper": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", + "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", + "dev": true, + "license": "MIT" + }, "node_modules/http-errors": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", @@ -4873,6 +4931,73 @@ "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", "license": "ISC" }, + "node_modules/istanbul-lib-coverage": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz", + "integrity": "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-report": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz", + "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "istanbul-lib-coverage": "^3.0.0", + "make-dir": "^4.0.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-lib-report/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-source-maps": { + "version": "5.0.6", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-5.0.6.tgz", + "integrity": "sha512-yg2d+Em4KizZC5niWhQaIomgf5WlL4vOOjZ5xGCmF8SnPE/mDWWXgvRExdcpCgh9lLRRa1/fSYp2ymmbJ1pI+A==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.23", + "debug": "^4.1.1", + "istanbul-lib-coverage": "^3.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-reports": { + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.7.tgz", + "integrity": "sha512-BewmUXImeuRk2YY0PVbxgKAysvhRPUQE0h5QRM++nVWyubKGV0l8qQ5op8+B2DOmwSe63Jivj0BjkPQVf8fP5g==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "html-escaper": "^2.0.0", + "istanbul-lib-report": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/jackspeak": { "version": "3.4.3", "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", @@ -5131,6 +5256,47 @@ "@jridgewell/sourcemap-codec": "^1.5.0" } }, + "node_modules/magicast": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/magicast/-/magicast-0.3.5.tgz", + "integrity": "sha512-L0WhttDl+2BOsybvEOLK7fW3UA0OQ0IQ2d6Zl2x/a6vVRs3bAY0ECOSHHeL5jD+SbOpOCUEi0y1DgHEn9Qn1AQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.25.4", + "@babel/types": "^7.25.4", + "source-map-js": "^1.2.0" + } + }, + "node_modules/make-dir": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", + "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==", + "dev": true, + "license": "MIT", + "dependencies": { + "semver": "^7.5.3" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/make-dir/node_modules/semver": { + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/make-error": { "version": "1.3.6", "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", @@ -6702,6 +6868,47 @@ "tailwindcss": ">=3.0.0 || insiders" } }, + "node_modules/test-exclude": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-7.0.1.tgz", + "integrity": "sha512-pFYqmTw68LXVjeWJMST4+borgQP2AyMNbg1BpZh9LbyhUeNkeaPF9gzfPGUAnSMV3qPYdWUwDIjjCLiSDOl7vg==", + "dev": true, + "license": "ISC", + "dependencies": { + "@istanbuljs/schema": "^0.1.2", + "glob": "^10.4.1", + "minimatch": "^9.0.4" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/test-exclude/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/test-exclude/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/thenify": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz", From 586c497740a096a1929b575c8fd98e08cc2360ce Mon Sep 17 00:00:00 2001 From: Ashwin Bhat Date: Fri, 20 Dec 2024 15:45:55 -0800 Subject: [PATCH 4/5] style: run prettier on src directory --- client/src/App.tsx | 58 +++-- client/src/__tests__/App.test.tsx | 243 +++++++++--------- .../src/__tests__/components/History.test.tsx | 87 ++++--- .../__tests__/components/ListPane.test.tsx | 116 ++++----- .../src/__tests__/components/PingTab.test.tsx | 84 +++--- .../__tests__/components/PromptsTab.test.tsx | 130 +++++----- .../components/ResourcesTab.test.tsx | 195 +++++++------- .../__tests__/components/RootsTab.test.tsx | 144 +++++------ .../__tests__/components/SamplingTab.test.tsx | 136 +++++----- client/src/__tests__/setup/setup.ts | 30 +-- client/src/components/Sidebar.tsx | 32 ++- client/src/components/ToolsTab.tsx | 3 +- client/src/lib/hooks/useConnection.ts | 33 ++- client/src/lib/hooks/useDraggablePane.ts | 37 ++- client/src/main.tsx | 4 +- 15 files changed, 716 insertions(+), 616 deletions(-) diff --git a/client/src/App.tsx b/client/src/App.tsx index c225c305ae..f3791b2d0a 100644 --- a/client/src/App.tsx +++ b/client/src/App.tsx @@ -16,7 +16,7 @@ import { ResourceTemplate, Root, ServerNotification, - Tool + Tool, } from "@modelcontextprotocol/sdk/types.js"; import { useEffect, useRef, useState } from "react"; @@ -124,10 +124,7 @@ const App = () => { const [nextToolCursor, setNextToolCursor] = useState(); const progressTokenRef = useRef(0); - const { - height: historyPaneHeight, - handleDragStart - } = useDraggablePane(300); + const { height: historyPaneHeight, handleDragStart } = useDraggablePane(300); const { connectionStatus, @@ -136,7 +133,7 @@ const App = () => { requestHistory, makeRequest: makeConnectionRequest, sendNotification, - connect: connectMcpServer + connect: connectMcpServer, } = useConnection({ transportType, command, @@ -145,18 +142,21 @@ const App = () => { env, proxyServerUrl: PROXY_SERVER_URL, onNotification: (notification) => { - setNotifications(prev => [...prev, notification as ServerNotification]); + setNotifications((prev) => [...prev, notification as ServerNotification]); }, onStdErrNotification: (notification) => { - setStdErrNotifications(prev => [...prev, notification as StdErrNotification]); + setStdErrNotifications((prev) => [ + ...prev, + notification as StdErrNotification, + ]); }, onPendingRequest: (request, resolve, reject) => { - setPendingSampleRequests(prev => [ + setPendingSampleRequests((prev) => [ ...prev, - { id: nextRequestId.current++, request, resolve, reject } + { id: nextRequestId.current++, request, resolve, reject }, ]); }, - getRoots: () => rootsRef.current + getRoots: () => rootsRef.current, }); const makeRequest = async ( @@ -345,26 +345,40 @@ const App = () => { {mcpClient ? ( (window.location.hash = value)} > - + Resources - + Prompts - + Tools @@ -388,7 +402,9 @@ const App = () => {
- {!serverCapabilities?.resources && !serverCapabilities?.prompts && !serverCapabilities?.tools ? ( + {!serverCapabilities?.resources && + !serverCapabilities?.prompts && + !serverCapabilities?.tools ? (

The connected server does not support any MCP capabilities diff --git a/client/src/__tests__/App.test.tsx b/client/src/__tests__/App.test.tsx index f215280309..1a5d9200d1 100644 --- a/client/src/__tests__/App.test.tsx +++ b/client/src/__tests__/App.test.tsx @@ -1,146 +1,149 @@ -import { describe, it, expect, vi, beforeEach } from 'vitest' -import { render, screen, fireEvent, act } from '@testing-library/react' -import App from '../App' -import { useConnection } from '../lib/hooks/useConnection' -import { useDraggablePane } from '../lib/hooks/useDraggablePane' +import { describe, it, expect, vi, beforeEach } from "vitest"; +import { render, screen, fireEvent, act } from "@testing-library/react"; +import App from "../App"; +import { useConnection } from "../lib/hooks/useConnection"; +import { useDraggablePane } from "../lib/hooks/useDraggablePane"; // Mock URL params -const mockURLSearchParams = vi.fn() -vi.stubGlobal('URLSearchParams', mockURLSearchParams) +const mockURLSearchParams = vi.fn(); +vi.stubGlobal("URLSearchParams", mockURLSearchParams); // Mock the hooks -vi.mock('../lib/hooks/useConnection', () => ({ - useConnection: vi.fn() -})) +vi.mock("../lib/hooks/useConnection", () => ({ + useConnection: vi.fn(), +})); -vi.mock('../lib/hooks/useDraggablePane', () => ({ - useDraggablePane: vi.fn() -})) +vi.mock("../lib/hooks/useDraggablePane", () => ({ + useDraggablePane: vi.fn(), +})); // Mock fetch for config -const mockFetch = vi.fn() -global.fetch = mockFetch +const mockFetch = vi.fn(); +global.fetch = mockFetch; -describe('App', () => { +describe("App", () => { beforeEach(() => { // Reset all mocks - vi.clearAllMocks() + vi.clearAllMocks(); // Mock URL params mockURLSearchParams.mockReturnValue({ - get: () => '3000' - }) + get: () => "3000", + }); // Mock fetch response mockFetch.mockResolvedValue({ - json: () => Promise.resolve({ - defaultEnvironment: {}, - defaultCommand: 'test-command', - defaultArgs: '--test' - }) - }) + json: () => + Promise.resolve({ + defaultEnvironment: {}, + defaultCommand: "test-command", + defaultArgs: "--test", + }), + }); // Mock useConnection hook - const mockUseConnection = useConnection as jest.Mock + const mockUseConnection = useConnection as jest.Mock; mockUseConnection.mockReturnValue({ - connectionStatus: 'disconnected', + connectionStatus: "disconnected", serverCapabilities: null, mcpClient: null, requestHistory: [], makeRequest: vi.fn(), sendNotification: vi.fn(), - connect: vi.fn() - }) + connect: vi.fn(), + }); // Mock useDraggablePane hook - const mockUseDraggablePane = useDraggablePane as jest.Mock + const mockUseDraggablePane = useDraggablePane as jest.Mock; mockUseDraggablePane.mockReturnValue({ height: 300, - handleDragStart: vi.fn() - }) - }) + handleDragStart: vi.fn(), + }); + }); - it('renders initial disconnected state', async () => { + it("renders initial disconnected state", async () => { await act(async () => { - render() - }) - expect(screen.getByText('Connect to an MCP server to start inspecting')).toBeInTheDocument() - }) - - it('loads config on mount', async () => { + render(); + }); + expect( + screen.getByText("Connect to an MCP server to start inspecting"), + ).toBeInTheDocument(); + }); + + it("loads config on mount", async () => { await act(async () => { - render() - }) - expect(mockFetch).toHaveBeenCalledWith('http://localhost:3000/config') - }) + render(); + }); + expect(mockFetch).toHaveBeenCalledWith("http://localhost:3000/config"); + }); - it('shows connected interface when mcpClient is available', async () => { - const mockUseConnection = useConnection as jest.Mock + it("shows connected interface when mcpClient is available", async () => { + const mockUseConnection = useConnection as jest.Mock; mockUseConnection.mockReturnValue({ - connectionStatus: 'connected', + connectionStatus: "connected", serverCapabilities: { resources: true, prompts: true, - tools: true + tools: true, }, mcpClient: {}, requestHistory: [], makeRequest: vi.fn(), sendNotification: vi.fn(), - connect: vi.fn() - }) + connect: vi.fn(), + }); await act(async () => { - render() - }) + render(); + }); // Use more specific selectors - const resourcesTab = screen.getByRole('tab', { name: /resources/i }) - const promptsTab = screen.getByRole('tab', { name: /prompts/i }) - const toolsTab = screen.getByRole('tab', { name: /tools/i }) + const resourcesTab = screen.getByRole("tab", { name: /resources/i }); + const promptsTab = screen.getByRole("tab", { name: /prompts/i }); + const toolsTab = screen.getByRole("tab", { name: /tools/i }); - expect(resourcesTab).toBeInTheDocument() - expect(promptsTab).toBeInTheDocument() - expect(toolsTab).toBeInTheDocument() - }) + expect(resourcesTab).toBeInTheDocument(); + expect(promptsTab).toBeInTheDocument(); + expect(toolsTab).toBeInTheDocument(); + }); - it('disables tabs based on server capabilities', async () => { - const mockUseConnection = useConnection as jest.Mock + it("disables tabs based on server capabilities", async () => { + const mockUseConnection = useConnection as jest.Mock; mockUseConnection.mockReturnValue({ - connectionStatus: 'connected', + connectionStatus: "connected", serverCapabilities: { resources: false, prompts: true, - tools: false + tools: false, }, mcpClient: {}, requestHistory: [], makeRequest: vi.fn(), sendNotification: vi.fn(), - connect: vi.fn() - }) + connect: vi.fn(), + }); await act(async () => { - render() - }) - + render(); + }); + // Resources tab should be disabled - const resourcesTab = screen.getByRole('tab', { name: /resources/i }) - expect(resourcesTab).toHaveAttribute('disabled') + const resourcesTab = screen.getByRole("tab", { name: /resources/i }); + expect(resourcesTab).toHaveAttribute("disabled"); // Prompts tab should be enabled - const promptsTab = screen.getByRole('tab', { name: /prompts/i }) - expect(promptsTab).not.toHaveAttribute('disabled') + const promptsTab = screen.getByRole("tab", { name: /prompts/i }); + expect(promptsTab).not.toHaveAttribute("disabled"); // Tools tab should be disabled - const toolsTab = screen.getByRole('tab', { name: /tools/i }) - expect(toolsTab).toHaveAttribute('disabled') - }) + const toolsTab = screen.getByRole("tab", { name: /tools/i }); + expect(toolsTab).toHaveAttribute("disabled"); + }); - it('shows notification count in sampling tab', async () => { - const mockUseConnection = useConnection as jest.Mock + it("shows notification count in sampling tab", async () => { + const mockUseConnection = useConnection as jest.Mock; mockUseConnection.mockReturnValue({ - connectionStatus: 'connected', + connectionStatus: "connected", serverCapabilities: { sampling: true }, mcpClient: {}, requestHistory: [], @@ -149,65 +152,69 @@ describe('App', () => { connect: vi.fn(), onPendingRequest: (request, resolve, reject) => { // Simulate a pending request - setPendingSampleRequests(prev => [ + setPendingSampleRequests((prev) => [ ...prev, - { id: 1, request, resolve, reject } - ]) - } - }) + { id: 1, request, resolve, reject }, + ]); + }, + }); await act(async () => { - render() - }) - + render(); + }); + // Initially no notification count - const samplingTab = screen.getByRole('tab', { name: /sampling/i }) - expect(samplingTab.querySelector('.bg-red-500')).not.toBeInTheDocument() + const samplingTab = screen.getByRole("tab", { name: /sampling/i }); + expect(samplingTab.querySelector(".bg-red-500")).not.toBeInTheDocument(); // Simulate a pending request await act(async () => { mockUseConnection.mock.calls[0][0].onPendingRequest( - { method: 'test', params: {} }, + { method: "test", params: {} }, () => {}, - () => {} - ) - }) - + () => {}, + ); + }); + // Should show notification count - expect(samplingTab.querySelector('.bg-red-500')).toBeInTheDocument() - }) + expect(samplingTab.querySelector(".bg-red-500")).toBeInTheDocument(); + }); + + it("persists command and args to localStorage", async () => { + const setItemSpy = vi.spyOn(Storage.prototype, "setItem"); - it('persists command and args to localStorage', async () => { - const setItemSpy = vi.spyOn(Storage.prototype, 'setItem') - await act(async () => { - render() - }) - + render(); + }); + // Simulate command change await act(async () => { - const commandInput = screen.getByPlaceholderText(/command/i) - fireEvent.change(commandInput, { target: { value: 'new-command' } }) - }) - - expect(setItemSpy).toHaveBeenCalledWith('lastCommand', 'new-command') - }) - - it('shows error message when server has no capabilities', async () => { - const mockUseConnection = useConnection as jest.Mock + const commandInput = screen.getByPlaceholderText(/command/i); + fireEvent.change(commandInput, { target: { value: "new-command" } }); + }); + + expect(setItemSpy).toHaveBeenCalledWith("lastCommand", "new-command"); + }); + + it("shows error message when server has no capabilities", async () => { + const mockUseConnection = useConnection as jest.Mock; mockUseConnection.mockReturnValue({ - connectionStatus: 'connected', + connectionStatus: "connected", serverCapabilities: {}, mcpClient: {}, requestHistory: [], makeRequest: vi.fn(), sendNotification: vi.fn(), - connect: vi.fn() - }) + connect: vi.fn(), + }); await act(async () => { - render() - }) - expect(screen.getByText('The connected server does not support any MCP capabilities')).toBeInTheDocument() - }) -}) \ No newline at end of file + render(); + }); + expect( + screen.getByText( + "The connected server does not support any MCP capabilities", + ), + ).toBeInTheDocument(); + }); +}); diff --git a/client/src/__tests__/components/History.test.tsx b/client/src/__tests__/components/History.test.tsx index 594b73ebf0..7d190bd786 100644 --- a/client/src/__tests__/components/History.test.tsx +++ b/client/src/__tests__/components/History.test.tsx @@ -1,40 +1,61 @@ -import { describe, it, expect } from 'vitest' -import { render, screen, fireEvent } from '@testing-library/react' -import HistoryAndNotifications from '../../components/History' +import { describe, it, expect } from "vitest"; +import { render, screen, fireEvent } from "@testing-library/react"; +import HistoryAndNotifications from "../../components/History"; -describe('HistoryAndNotifications', () => { +describe("HistoryAndNotifications", () => { const mockHistory = [ - { request: JSON.stringify({ method: 'test1' }), response: JSON.stringify({ result: 'output1' }) }, - { request: JSON.stringify({ method: 'test2' }), response: JSON.stringify({ result: 'output2' }) } - ] + { + request: JSON.stringify({ method: "test1" }), + response: JSON.stringify({ result: "output1" }), + }, + { + request: JSON.stringify({ method: "test2" }), + response: JSON.stringify({ result: "output2" }), + }, + ]; - it('renders history items', () => { - render() - const items = screen.getAllByText(/test[12]/, { exact: false }) - expect(items).toHaveLength(2) - }) + it("renders history items", () => { + render( + , + ); + const items = screen.getAllByText(/test[12]/, { exact: false }); + expect(items).toHaveLength(2); + }); - it('expands history item when clicked', () => { - render() - - const firstItem = screen.getByText(/test1/, { exact: false }) - fireEvent.click(firstItem) - expect(screen.getByText('Request:')).toBeInTheDocument() - expect(screen.getByText(/output1/, { exact: false })).toBeInTheDocument() - }) + it("expands history item when clicked", () => { + render( + , + ); - it('renders and expands server notifications', () => { + const firstItem = screen.getByText(/test1/, { exact: false }); + fireEvent.click(firstItem); + expect(screen.getByText("Request:")).toBeInTheDocument(); + expect(screen.getByText(/output1/, { exact: false })).toBeInTheDocument(); + }); + + it("renders and expands server notifications", () => { const notifications = [ - { method: 'notify1', params: { data: 'test data 1' } }, - { method: 'notify2', params: { data: 'test data 2' } } - ] - render() - - const items = screen.getAllByText(/notify[12]/, { exact: false }) - expect(items).toHaveLength(2) + { method: "notify1", params: { data: "test data 1" } }, + { method: "notify2", params: { data: "test data 2" } }, + ]; + render( + , + ); + + const items = screen.getAllByText(/notify[12]/, { exact: false }); + expect(items).toHaveLength(2); - fireEvent.click(items[0]) - expect(screen.getByText('Details:')).toBeInTheDocument() - expect(screen.getByText(/test data/, { exact: false })).toBeInTheDocument() - }) -}) \ No newline at end of file + fireEvent.click(items[0]); + expect(screen.getByText("Details:")).toBeInTheDocument(); + expect(screen.getByText(/test data/, { exact: false })).toBeInTheDocument(); + }); +}); diff --git a/client/src/__tests__/components/ListPane.test.tsx b/client/src/__tests__/components/ListPane.test.tsx index 081cfb1362..1ea25b708f 100644 --- a/client/src/__tests__/components/ListPane.test.tsx +++ b/client/src/__tests__/components/ListPane.test.tsx @@ -1,17 +1,17 @@ -import { describe, it, expect, vi } from 'vitest' -import { render, screen, fireEvent } from '@testing-library/react' -import ListPane from '../../components/ListPane' +import { describe, it, expect, vi } from "vitest"; +import { render, screen, fireEvent } from "@testing-library/react"; +import ListPane from "../../components/ListPane"; -describe('ListPane', () => { +describe("ListPane", () => { type TestItem = { id: number; name: string; - } + }; const mockItems: TestItem[] = [ - { id: 1, name: 'Item 1' }, - { id: 2, name: 'Item 2' } - ] + { id: 1, name: "Item 1" }, + { id: 2, name: "Item 2" }, + ]; const defaultProps = { items: mockItems, @@ -24,61 +24,61 @@ describe('ListPane', () => { ID: {item.id} ), - title: 'Test Items', - buttonText: 'List Items' - } + title: "Test Items", + buttonText: "List Items", + }; - it('renders title and buttons', () => { - render() - expect(screen.getByText('Test Items')).toBeInTheDocument() - expect(screen.getByText('List Items')).toBeInTheDocument() - expect(screen.getByText('Clear')).toBeInTheDocument() - }) + it("renders title and buttons", () => { + render(); + expect(screen.getByText("Test Items")).toBeInTheDocument(); + expect(screen.getByText("List Items")).toBeInTheDocument(); + expect(screen.getByText("Clear")).toBeInTheDocument(); + }); - it('renders list of items using renderItem prop', () => { - render() - expect(screen.getByText('Item 1')).toBeInTheDocument() - expect(screen.getByText('Item 2')).toBeInTheDocument() - expect(screen.getByText('ID: 1')).toBeInTheDocument() - expect(screen.getByText('ID: 2')).toBeInTheDocument() - }) + it("renders list of items using renderItem prop", () => { + render(); + expect(screen.getByText("Item 1")).toBeInTheDocument(); + expect(screen.getByText("Item 2")).toBeInTheDocument(); + expect(screen.getByText("ID: 1")).toBeInTheDocument(); + expect(screen.getByText("ID: 2")).toBeInTheDocument(); + }); - it('calls listItems when List Items button is clicked', () => { - const listItems = vi.fn() - render() - - fireEvent.click(screen.getByText('List Items')) - expect(listItems).toHaveBeenCalled() - }) + it("calls listItems when List Items button is clicked", () => { + const listItems = vi.fn(); + render(); - it('calls clearItems when Clear button is clicked', () => { - const clearItems = vi.fn() - render() - - fireEvent.click(screen.getByText('Clear')) - expect(clearItems).toHaveBeenCalled() - }) + fireEvent.click(screen.getByText("List Items")); + expect(listItems).toHaveBeenCalled(); + }); - it('calls setSelectedItem when an item is clicked', () => { - const setSelectedItem = vi.fn() - render() - - fireEvent.click(screen.getByText('Item 1')) - expect(setSelectedItem).toHaveBeenCalledWith(mockItems[0]) - }) + it("calls clearItems when Clear button is clicked", () => { + const clearItems = vi.fn(); + render(); - it('disables Clear button when items array is empty', () => { - render() - expect(screen.getByText('Clear')).toBeDisabled() - }) + fireEvent.click(screen.getByText("Clear")); + expect(clearItems).toHaveBeenCalled(); + }); - it('disables List Items button when isButtonDisabled is true', () => { - render() - expect(screen.getByText('List Items')).toBeDisabled() - }) + it("calls setSelectedItem when an item is clicked", () => { + const setSelectedItem = vi.fn(); + render(); - it('enables List Items button when isButtonDisabled is false', () => { - render() - expect(screen.getByText('List Items')).not.toBeDisabled() - }) -}) \ No newline at end of file + fireEvent.click(screen.getByText("Item 1")); + expect(setSelectedItem).toHaveBeenCalledWith(mockItems[0]); + }); + + it("disables Clear button when items array is empty", () => { + render(); + expect(screen.getByText("Clear")).toBeDisabled(); + }); + + it("disables List Items button when isButtonDisabled is true", () => { + render(); + expect(screen.getByText("List Items")).toBeDisabled(); + }); + + it("enables List Items button when isButtonDisabled is false", () => { + render(); + expect(screen.getByText("List Items")).not.toBeDisabled(); + }); +}); diff --git a/client/src/__tests__/components/PingTab.test.tsx b/client/src/__tests__/components/PingTab.test.tsx index 603cb03cb8..75f16dff35 100644 --- a/client/src/__tests__/components/PingTab.test.tsx +++ b/client/src/__tests__/components/PingTab.test.tsx @@ -1,47 +1,51 @@ -import { describe, it, expect, vi } from 'vitest' -import { render, screen, fireEvent } from '@testing-library/react' -import PingTab from '../../components/PingTab' -import { Tabs } from '@/components/ui/tabs' +import { describe, it, expect, vi } from "vitest"; +import { render, screen, fireEvent } from "@testing-library/react"; +import PingTab from "../../components/PingTab"; +import { Tabs } from "@/components/ui/tabs"; -describe('PingTab', () => { +describe("PingTab", () => { const renderWithTabs = (component: React.ReactElement) => { - return render( - - {component} - - ) - } + return render({component}); + }; - it('renders the MEGA PING button', () => { - renderWithTabs( {}} />) - const button = screen.getByRole('button', { name: /mega ping/i }) - expect(button).toBeInTheDocument() - expect(button).toHaveClass('bg-gradient-to-r', 'from-purple-500', 'to-pink-500') - }) + it("renders the MEGA PING button", () => { + renderWithTabs( {}} />); + const button = screen.getByRole("button", { name: /mega ping/i }); + expect(button).toBeInTheDocument(); + expect(button).toHaveClass( + "bg-gradient-to-r", + "from-purple-500", + "to-pink-500", + ); + }); - it('includes rocket and explosion emojis', () => { - renderWithTabs( {}} />) - expect(screen.getByText('🚀')).toBeInTheDocument() - expect(screen.getByText('💥')).toBeInTheDocument() - }) + it("includes rocket and explosion emojis", () => { + renderWithTabs( {}} />); + expect(screen.getByText("🚀")).toBeInTheDocument(); + expect(screen.getByText("💥")).toBeInTheDocument(); + }); - it('calls onPingClick when button is clicked', () => { - const onPingClick = vi.fn() - renderWithTabs() - - fireEvent.click(screen.getByRole('button', { name: /mega ping/i })) - expect(onPingClick).toHaveBeenCalledTimes(1) - }) + it("calls onPingClick when button is clicked", () => { + const onPingClick = vi.fn(); + renderWithTabs(); - it('has animation classes for visual feedback', () => { - renderWithTabs( {}} />) - const button = screen.getByRole('button', { name: /mega ping/i }) - expect(button).toHaveClass('animate-pulse', 'hover:scale-110', 'transition') - }) + fireEvent.click(screen.getByRole("button", { name: /mega ping/i })); + expect(onPingClick).toHaveBeenCalledTimes(1); + }); - it('has focus styles for accessibility', () => { - renderWithTabs( {}} />) - const button = screen.getByRole('button', { name: /mega ping/i }) - expect(button).toHaveClass('focus:outline-none', 'focus:ring-4') - }) -}) \ No newline at end of file + it("has animation classes for visual feedback", () => { + renderWithTabs( {}} />); + const button = screen.getByRole("button", { name: /mega ping/i }); + expect(button).toHaveClass( + "animate-pulse", + "hover:scale-110", + "transition", + ); + }); + + it("has focus styles for accessibility", () => { + renderWithTabs( {}} />); + const button = screen.getByRole("button", { name: /mega ping/i }); + expect(button).toHaveClass("focus:outline-none", "focus:ring-4"); + }); +}); diff --git a/client/src/__tests__/components/PromptsTab.test.tsx b/client/src/__tests__/components/PromptsTab.test.tsx index 62f69efbbb..73aaa87189 100644 --- a/client/src/__tests__/components/PromptsTab.test.tsx +++ b/client/src/__tests__/components/PromptsTab.test.tsx @@ -1,24 +1,24 @@ -import { describe, it, expect, vi } from 'vitest' -import { render, screen, fireEvent } from '@testing-library/react' -import PromptsTab from '../../components/PromptsTab' -import type { Prompt } from '../../components/PromptsTab' -import { Tabs } from '@/components/ui/tabs' +import { describe, it, expect, vi } from "vitest"; +import { render, screen, fireEvent } from "@testing-library/react"; +import PromptsTab from "../../components/PromptsTab"; +import type { Prompt } from "../../components/PromptsTab"; +import { Tabs } from "@/components/ui/tabs"; -describe('PromptsTab', () => { +describe("PromptsTab", () => { const mockPrompts: Prompt[] = [ { - name: 'test-prompt-1', - description: 'Test prompt 1 description', + name: "test-prompt-1", + description: "Test prompt 1 description", arguments: [ - { name: 'arg1', description: 'Argument 1', required: true }, - { name: 'arg2', description: 'Argument 2' } - ] + { name: "arg1", description: "Argument 1", required: true }, + { name: "arg2", description: "Argument 2" }, + ], }, { - name: 'test-prompt-2', - description: 'Test prompt 2 description' - } - ] + name: "test-prompt-2", + description: "Test prompt 2 description", + }, + ]; const defaultProps = { prompts: mockPrompts, @@ -27,70 +27,72 @@ describe('PromptsTab', () => { getPrompt: vi.fn(), selectedPrompt: null, setSelectedPrompt: vi.fn(), - promptContent: '', + promptContent: "", nextCursor: null, - error: null - } + error: null, + }; const renderWithTabs = (component: React.ReactElement) => { - return render( - - {component} - - ) - } + return render({component}); + }; - it('renders list of prompts', () => { - renderWithTabs() - expect(screen.getByText('test-prompt-1')).toBeInTheDocument() - expect(screen.getByText('test-prompt-2')).toBeInTheDocument() - }) + it("renders list of prompts", () => { + renderWithTabs(); + expect(screen.getByText("test-prompt-1")).toBeInTheDocument(); + expect(screen.getByText("test-prompt-2")).toBeInTheDocument(); + }); - it('shows prompt details when selected', () => { + it("shows prompt details when selected", () => { const props = { ...defaultProps, - selectedPrompt: mockPrompts[0] - } - renderWithTabs() - expect(screen.getByText('Test prompt 1 description', { selector: 'p.text-sm.text-gray-600' })).toBeInTheDocument() - expect(screen.getByText('arg1')).toBeInTheDocument() - expect(screen.getByText('arg2')).toBeInTheDocument() - }) + selectedPrompt: mockPrompts[0], + }; + renderWithTabs(); + expect( + screen.getByText("Test prompt 1 description", { + selector: "p.text-sm.text-gray-600", + }), + ).toBeInTheDocument(); + expect(screen.getByText("arg1")).toBeInTheDocument(); + expect(screen.getByText("arg2")).toBeInTheDocument(); + }); - it('handles argument input', () => { - const getPrompt = vi.fn() + it("handles argument input", () => { + const getPrompt = vi.fn(); const props = { ...defaultProps, selectedPrompt: mockPrompts[0], - getPrompt - } - renderWithTabs() - - const arg1Input = screen.getByPlaceholderText('Enter arg1') - fireEvent.change(arg1Input, { target: { value: 'test value' } }) - - const getPromptButton = screen.getByText('Get Prompt') - fireEvent.click(getPromptButton) - - expect(getPrompt).toHaveBeenCalledWith('test-prompt-1', { arg1: 'test value' }) - }) + getPrompt, + }; + renderWithTabs(); + + const arg1Input = screen.getByPlaceholderText("Enter arg1"); + fireEvent.change(arg1Input, { target: { value: "test value" } }); + + const getPromptButton = screen.getByText("Get Prompt"); + fireEvent.click(getPromptButton); + + expect(getPrompt).toHaveBeenCalledWith("test-prompt-1", { + arg1: "test value", + }); + }); - it('shows error message when error prop is provided', () => { + it("shows error message when error prop is provided", () => { const props = { ...defaultProps, - error: 'Test error message' - } - renderWithTabs() - expect(screen.getByText('Test error message')).toBeInTheDocument() - }) + error: "Test error message", + }; + renderWithTabs(); + expect(screen.getByText("Test error message")).toBeInTheDocument(); + }); - it('shows prompt content when provided', () => { + it("shows prompt content when provided", () => { const props = { ...defaultProps, selectedPrompt: mockPrompts[0], - promptContent: 'Test prompt content' - } - renderWithTabs() - expect(screen.getByText('Test prompt content')).toBeInTheDocument() - }) -}) \ No newline at end of file + promptContent: "Test prompt content", + }; + renderWithTabs(); + expect(screen.getByText("Test prompt content")).toBeInTheDocument(); + }); +}); diff --git a/client/src/__tests__/components/ResourcesTab.test.tsx b/client/src/__tests__/components/ResourcesTab.test.tsx index df88bd343b..c0e73a68f6 100644 --- a/client/src/__tests__/components/ResourcesTab.test.tsx +++ b/client/src/__tests__/components/ResourcesTab.test.tsx @@ -1,27 +1,30 @@ -import { describe, it, expect, vi } from 'vitest' -import { render, screen, fireEvent } from '@testing-library/react' -import ResourcesTab from '../../components/ResourcesTab' -import { Tabs } from '@/components/ui/tabs' -import type { Resource, ResourceTemplate } from '@modelcontextprotocol/sdk/types.js' +import { describe, it, expect, vi } from "vitest"; +import { render, screen, fireEvent } from "@testing-library/react"; +import ResourcesTab from "../../components/ResourcesTab"; +import { Tabs } from "@/components/ui/tabs"; +import type { + Resource, + ResourceTemplate, +} from "@modelcontextprotocol/sdk/types.js"; -describe('ResourcesTab', () => { +describe("ResourcesTab", () => { const mockResources: Resource[] = [ - { uri: 'file:///test1.txt', name: 'Test 1' }, - { uri: 'file:///test2.txt', name: 'Test 2' } - ] + { uri: "file:///test1.txt", name: "Test 1" }, + { uri: "file:///test2.txt", name: "Test 2" }, + ]; const mockTemplates: ResourceTemplate[] = [ - { - name: 'Template 1', - description: 'Test template 1', - uriTemplate: 'file:///test/{param1}/{param2}.txt' + { + name: "Template 1", + description: "Test template 1", + uriTemplate: "file:///test/{param1}/{param2}.txt", }, { - name: 'Template 2', - description: 'Test template 2', - uriTemplate: 'file:///other/{name}.txt' - } - ] + name: "Template 2", + description: "Test template 2", + uriTemplate: "file:///other/{name}.txt", + }, + ]; const defaultProps = { resources: mockResources, @@ -33,100 +36,100 @@ describe('ResourcesTab', () => { readResource: vi.fn(), selectedResource: null, setSelectedResource: vi.fn(), - resourceContent: '', + resourceContent: "", nextCursor: null, nextTemplateCursor: null, - error: null - } + error: null, + }; const renderWithTabs = (component: React.ReactElement) => { - return render( - - {component} - - ) - } - - it('renders resources list', () => { - renderWithTabs() - expect(screen.getByText('Test 1')).toBeInTheDocument() - expect(screen.getByText('Test 2')).toBeInTheDocument() - }) - - it('renders templates list', () => { - renderWithTabs() - expect(screen.getByText('Template 1')).toBeInTheDocument() - expect(screen.getByText('Template 2')).toBeInTheDocument() - }) - - it('shows resource content when resource is selected', () => { + return render({component}); + }; + + it("renders resources list", () => { + renderWithTabs(); + expect(screen.getByText("Test 1")).toBeInTheDocument(); + expect(screen.getByText("Test 2")).toBeInTheDocument(); + }); + + it("renders templates list", () => { + renderWithTabs(); + expect(screen.getByText("Template 1")).toBeInTheDocument(); + expect(screen.getByText("Template 2")).toBeInTheDocument(); + }); + + it("shows resource content when resource is selected", () => { const props = { ...defaultProps, selectedResource: mockResources[0], - resourceContent: 'Test content' - } - renderWithTabs() - expect(screen.getByText('Test content')).toBeInTheDocument() - }) - - it('shows template form when template is selected', () => { - renderWithTabs() - - fireEvent.click(screen.getByText('Template 1')) - expect(screen.getByText('Test template 1')).toBeInTheDocument() - expect(screen.getByLabelText('param1')).toBeInTheDocument() - expect(screen.getByLabelText('param2')).toBeInTheDocument() - }) - - it('fills template and reads resource', () => { - const readResource = vi.fn() - const setSelectedResource = vi.fn() + resourceContent: "Test content", + }; + renderWithTabs(); + expect(screen.getByText("Test content")).toBeInTheDocument(); + }); + + it("shows template form when template is selected", () => { + renderWithTabs(); + + fireEvent.click(screen.getByText("Template 1")); + expect(screen.getByText("Test template 1")).toBeInTheDocument(); + expect(screen.getByLabelText("param1")).toBeInTheDocument(); + expect(screen.getByLabelText("param2")).toBeInTheDocument(); + }); + + it("fills template and reads resource", () => { + const readResource = vi.fn(); + const setSelectedResource = vi.fn(); renderWithTabs( - - ) - + />, + ); + // Select template - fireEvent.click(screen.getByText('Template 1')) - + fireEvent.click(screen.getByText("Template 1")); + // Fill in template parameters - fireEvent.change(screen.getByLabelText('param1'), { target: { value: 'value1' } }) - fireEvent.change(screen.getByLabelText('param2'), { target: { value: 'value2' } }) - + fireEvent.change(screen.getByLabelText("param1"), { + target: { value: "value1" }, + }); + fireEvent.change(screen.getByLabelText("param2"), { + target: { value: "value2" }, + }); + // Submit form - fireEvent.click(screen.getByText('Read Resource')) - - expect(readResource).toHaveBeenCalledWith('file:///test/value1/value2.txt') + fireEvent.click(screen.getByText("Read Resource")); + + expect(readResource).toHaveBeenCalledWith("file:///test/value1/value2.txt"); expect(setSelectedResource).toHaveBeenCalledWith( - expect.objectContaining({ - uri: 'file:///test/value1/value2.txt', - name: 'file:///test/value1/value2.txt' - }) - ) - }) - - it('shows error message when error prop is provided', () => { + expect.objectContaining({ + uri: "file:///test/value1/value2.txt", + name: "file:///test/value1/value2.txt", + }), + ); + }); + + it("shows error message when error prop is provided", () => { const props = { ...defaultProps, - error: 'Test error message' - } - renderWithTabs() - expect(screen.getByText('Test error message')).toBeInTheDocument() - }) - - it('refreshes resource content when refresh button is clicked', () => { - const readResource = vi.fn() + error: "Test error message", + }; + renderWithTabs(); + expect(screen.getByText("Test error message")).toBeInTheDocument(); + }); + + it("refreshes resource content when refresh button is clicked", () => { + const readResource = vi.fn(); const props = { ...defaultProps, selectedResource: mockResources[0], - readResource - } - renderWithTabs() - - fireEvent.click(screen.getByText('Refresh')) - expect(readResource).toHaveBeenCalledWith(mockResources[0].uri) - }) -}) \ No newline at end of file + readResource, + }; + renderWithTabs(); + + fireEvent.click(screen.getByText("Refresh")); + expect(readResource).toHaveBeenCalledWith(mockResources[0].uri); + }); +}); diff --git a/client/src/__tests__/components/RootsTab.test.tsx b/client/src/__tests__/components/RootsTab.test.tsx index ab5cd79965..b8186bef1f 100644 --- a/client/src/__tests__/components/RootsTab.test.tsx +++ b/client/src/__tests__/components/RootsTab.test.tsx @@ -1,80 +1,80 @@ -import { describe, it, expect, vi } from 'vitest' -import { render, screen, fireEvent } from '@testing-library/react' -import RootsTab from '../../components/RootsTab' -import { Tabs } from '@/components/ui/tabs' -import type { Root } from '@modelcontextprotocol/sdk/types.js' +import { describe, it, expect, vi } from "vitest"; +import { render, screen, fireEvent } from "@testing-library/react"; +import RootsTab from "../../components/RootsTab"; +import { Tabs } from "@/components/ui/tabs"; +import type { Root } from "@modelcontextprotocol/sdk/types.js"; -describe('RootsTab', () => { +describe("RootsTab", () => { const mockRoots: Root[] = [ - { uri: 'file:///test/path1', name: 'test1' }, - { uri: 'file:///test/path2', name: 'test2' } - ] + { uri: "file:///test/path1", name: "test1" }, + { uri: "file:///test/path2", name: "test2" }, + ]; const defaultProps = { roots: mockRoots, setRoots: vi.fn(), - onRootsChange: vi.fn() - } + onRootsChange: vi.fn(), + }; const renderWithTabs = (component: React.ReactElement) => { - return render( - - {component} - - ) - } - - it('renders list of roots', () => { - renderWithTabs() - expect(screen.getByDisplayValue('file:///test/path1')).toBeInTheDocument() - expect(screen.getByDisplayValue('file:///test/path2')).toBeInTheDocument() - }) - - it('adds a new root when Add Root button is clicked', () => { - const setRoots = vi.fn() - renderWithTabs() - - fireEvent.click(screen.getByText('Add Root')) - - expect(setRoots).toHaveBeenCalled() - const updateFn = setRoots.mock.calls[0][0] - const result = updateFn(mockRoots) - expect(result).toEqual([...mockRoots, { uri: 'file://', name: '' }]) - }) - - it('removes a root when remove button is clicked', () => { - const setRoots = vi.fn() - renderWithTabs() - - const removeButtons = screen.getAllByRole('button', { name: /remove root/i }) - fireEvent.click(removeButtons[0]) - - expect(setRoots).toHaveBeenCalled() - const updateFn = setRoots.mock.calls[0][0] - const result = updateFn(mockRoots) - expect(result).toEqual([mockRoots[1]]) - }) - - it('updates root URI when input changes', () => { - const setRoots = vi.fn() - renderWithTabs() - - const firstInput = screen.getByDisplayValue('file:///test/path1') - fireEvent.change(firstInput, { target: { value: 'file:///new/path' } }) - - expect(setRoots).toHaveBeenCalled() - const updateFn = setRoots.mock.calls[0][0] - const result = updateFn(mockRoots) - expect(result[0].uri).toBe('file:///new/path') - expect(result[1]).toEqual(mockRoots[1]) - }) - - it('calls onRootsChange when Save Changes is clicked', () => { - const onRootsChange = vi.fn() - renderWithTabs() - - fireEvent.click(screen.getByText('Save Changes')) - - expect(onRootsChange).toHaveBeenCalled() - }) -}) \ No newline at end of file + return render({component}); + }; + + it("renders list of roots", () => { + renderWithTabs(); + expect(screen.getByDisplayValue("file:///test/path1")).toBeInTheDocument(); + expect(screen.getByDisplayValue("file:///test/path2")).toBeInTheDocument(); + }); + + it("adds a new root when Add Root button is clicked", () => { + const setRoots = vi.fn(); + renderWithTabs(); + + fireEvent.click(screen.getByText("Add Root")); + + expect(setRoots).toHaveBeenCalled(); + const updateFn = setRoots.mock.calls[0][0]; + const result = updateFn(mockRoots); + expect(result).toEqual([...mockRoots, { uri: "file://", name: "" }]); + }); + + it("removes a root when remove button is clicked", () => { + const setRoots = vi.fn(); + renderWithTabs(); + + const removeButtons = screen.getAllByRole("button", { + name: /remove root/i, + }); + fireEvent.click(removeButtons[0]); + + expect(setRoots).toHaveBeenCalled(); + const updateFn = setRoots.mock.calls[0][0]; + const result = updateFn(mockRoots); + expect(result).toEqual([mockRoots[1]]); + }); + + it("updates root URI when input changes", () => { + const setRoots = vi.fn(); + renderWithTabs(); + + const firstInput = screen.getByDisplayValue("file:///test/path1"); + fireEvent.change(firstInput, { target: { value: "file:///new/path" } }); + + expect(setRoots).toHaveBeenCalled(); + const updateFn = setRoots.mock.calls[0][0]; + const result = updateFn(mockRoots); + expect(result[0].uri).toBe("file:///new/path"); + expect(result[1]).toEqual(mockRoots[1]); + }); + + it("calls onRootsChange when Save Changes is clicked", () => { + const onRootsChange = vi.fn(); + renderWithTabs( + , + ); + + fireEvent.click(screen.getByText("Save Changes")); + + expect(onRootsChange).toHaveBeenCalled(); + }); +}); diff --git a/client/src/__tests__/components/SamplingTab.test.tsx b/client/src/__tests__/components/SamplingTab.test.tsx index 28c0e899d7..d84186e536 100644 --- a/client/src/__tests__/components/SamplingTab.test.tsx +++ b/client/src/__tests__/components/SamplingTab.test.tsx @@ -1,85 +1,91 @@ -import { describe, it, expect, vi } from 'vitest' -import { render, screen, fireEvent } from '@testing-library/react' -import SamplingTab from '../../components/SamplingTab' -import { Tabs } from '@/components/ui/tabs' -import type { CreateMessageRequest } from '@modelcontextprotocol/sdk/types.js' +import { describe, it, expect, vi } from "vitest"; +import { render, screen, fireEvent } from "@testing-library/react"; +import SamplingTab from "../../components/SamplingTab"; +import { Tabs } from "@/components/ui/tabs"; +import type { CreateMessageRequest } from "@modelcontextprotocol/sdk/types.js"; -describe('SamplingTab', () => { +describe("SamplingTab", () => { const mockRequest: CreateMessageRequest = { - model: 'test-model', - role: 'user', + model: "test-model", + role: "user", content: { - type: 'text', - text: 'Test message' - } - } + type: "text", + text: "Test message", + }, + }; const mockPendingRequests = [ { id: 1, request: mockRequest }, - { id: 2, request: { ...mockRequest, content: { type: 'text', text: 'Another test' } } } - ] + { + id: 2, + request: { + ...mockRequest, + content: { type: "text", text: "Another test" }, + }, + }, + ]; const defaultProps = { pendingRequests: mockPendingRequests, onApprove: vi.fn(), - onReject: vi.fn() - } + onReject: vi.fn(), + }; const renderWithTabs = (component: React.ReactElement) => { - return render( - - {component} - - ) - } + return render({component}); + }; - it('renders empty state when no requests', () => { - renderWithTabs() - expect(screen.getByText('No pending requests')).toBeInTheDocument() - }) + it("renders empty state when no requests", () => { + renderWithTabs(); + expect(screen.getByText("No pending requests")).toBeInTheDocument(); + }); - it('renders list of pending requests', () => { - renderWithTabs() - expect(screen.getByText(/Test message/)).toBeInTheDocument() - expect(screen.getByText(/Another test/)).toBeInTheDocument() - }) + it("renders list of pending requests", () => { + renderWithTabs(); + expect(screen.getByText(/Test message/)).toBeInTheDocument(); + expect(screen.getByText(/Another test/)).toBeInTheDocument(); + }); - it('shows request details in JSON format', () => { - renderWithTabs() - const requestJson = screen.getAllByText((content) => content.includes('"model": "test-model"')) - expect(requestJson).toHaveLength(2) - }) + it("shows request details in JSON format", () => { + renderWithTabs(); + const requestJson = screen.getAllByText((content) => + content.includes('"model": "test-model"'), + ); + expect(requestJson).toHaveLength(2); + }); + + it("calls onApprove with stub response when Approve is clicked", () => { + const onApprove = vi.fn(); + renderWithTabs(); + + const approveButtons = screen.getAllByText("Approve"); + fireEvent.click(approveButtons[0]); - it('calls onApprove with stub response when Approve is clicked', () => { - const onApprove = vi.fn() - renderWithTabs() - - const approveButtons = screen.getAllByText('Approve') - fireEvent.click(approveButtons[0]) - expect(onApprove).toHaveBeenCalledWith(1, { - model: 'stub-model', - stopReason: 'endTurn', - role: 'assistant', + model: "stub-model", + stopReason: "endTurn", + role: "assistant", content: { - type: 'text', - text: 'This is a stub response.' - } - }) - }) + type: "text", + text: "This is a stub response.", + }, + }); + }); + + it("calls onReject when Reject is clicked", () => { + const onReject = vi.fn(); + renderWithTabs(); + + const rejectButtons = screen.getAllByText("Reject"); + fireEvent.click(rejectButtons[0]); - it('calls onReject when Reject is clicked', () => { - const onReject = vi.fn() - renderWithTabs() - - const rejectButtons = screen.getAllByText('Reject') - fireEvent.click(rejectButtons[0]) - - expect(onReject).toHaveBeenCalledWith(1) - }) + expect(onReject).toHaveBeenCalledWith(1); + }); - it('shows informational alert about sampling requests', () => { - renderWithTabs() - expect(screen.getByText(/When the server requests LLM sampling/)).toBeInTheDocument() - }) -}) \ No newline at end of file + it("shows informational alert about sampling requests", () => { + renderWithTabs(); + expect( + screen.getByText(/When the server requests LLM sampling/), + ).toBeInTheDocument(); + }); +}); diff --git a/client/src/__tests__/setup/setup.ts b/client/src/__tests__/setup/setup.ts index dcba7c2f0d..e5794233ea 100644 --- a/client/src/__tests__/setup/setup.ts +++ b/client/src/__tests__/setup/setup.ts @@ -1,15 +1,15 @@ -import '@testing-library/jest-dom' -import { expect, afterEach, vi } from 'vitest' -import { cleanup } from '@testing-library/react' -import * as matchers from '@testing-library/jest-dom/matchers' +import "@testing-library/jest-dom"; +import { expect, afterEach, vi } from "vitest"; +import { cleanup } from "@testing-library/react"; +import * as matchers from "@testing-library/jest-dom/matchers"; // @ts-ignore -expect.extend(matchers) +expect.extend(matchers); // Mock window.matchMedia -Object.defineProperty(window, 'matchMedia', { +Object.defineProperty(window, "matchMedia", { writable: true, - value: vi.fn().mockImplementation(query => ({ + value: vi.fn().mockImplementation((query) => ({ matches: false, media: query, onchange: null, @@ -19,16 +19,16 @@ Object.defineProperty(window, 'matchMedia', { removeEventListener: vi.fn(), dispatchEvent: vi.fn(), })), -}) +}); // Mock window.location.hash -Object.defineProperty(window, 'location', { +Object.defineProperty(window, "location", { writable: true, - value: { hash: '' } -}) + value: { hash: "" }, +}); afterEach(() => { - cleanup() - vi.clearAllMocks() - window.location.hash = '' -}) \ No newline at end of file + cleanup(); + vi.clearAllMocks(); + window.location.hash = ""; +}); diff --git a/client/src/components/Sidebar.tsx b/client/src/components/Sidebar.tsx index c716bd2ce1..17cd59d2b1 100644 --- a/client/src/components/Sidebar.tsx +++ b/client/src/components/Sidebar.tsx @@ -1,5 +1,12 @@ import { useState } from "react"; -import { Play, ChevronDown, ChevronRight, CircleHelp, Bug, Github } from "lucide-react"; +import { + Play, + ChevronDown, + ChevronRight, + CircleHelp, + Bug, + Github, +} from "lucide-react"; import { Button } from "@/components/ui/button"; import { Input } from "@/components/ui/input"; import { @@ -243,18 +250,33 @@ const Sidebar = ({

- + - + - - diff --git a/client/src/components/ToolsTab.tsx b/client/src/components/ToolsTab.tsx index 77a97e73dd..6b64c014e9 100644 --- a/client/src/components/ToolsTab.tsx +++ b/client/src/components/ToolsTab.tsx @@ -174,8 +174,7 @@ const ToolsTab = ({ } className="mt-1" /> - ) : - /* @ts-expect-error value type is currently unknown */ + ) : /* @ts-expect-error value type is currently unknown */ value.type === "object" ? (