102 lines
7.2 KiB
Markdown
102 lines
7.2 KiB
Markdown
# Inspector V2
|
|
|
|
This is an application for inspecting MCP servers. Has three incarnations, Web, TUI, and CLI.
|
|
|
|
## Project Structure
|
|
|
|
```
|
|
inspector/
|
|
├── clients/
|
|
│ ├── web/ # Web client code
|
|
│ ├── cli/ # CLI client code
|
|
│ ├── tui/ # TUI client code
|
|
│ ├── launcher/ # Shared launcher
|
|
├── core/ # Shared core code
|
|
├── soecification/ # Build specification
|
|
...
|
|
```
|
|
|
|
## Maintenance Rules
|
|
|
|
### Keep documentation files up to date
|
|
- When adding, removing, renaming, or changing the purpose of any file or folder, update the corresponding entry in the main README.md and/or the related clients/*/README.md
|
|
- When the structure of the project, the tech stack, or the developer setup changes, update appropriate README.md files with the details.
|
|
- When adding new commands, dependencies, or architectural patterns, update the relevant sections of appropriate README.md files as well.
|
|
- When rules for implementation and testing change, update this file AGENTS.md
|
|
|
|
### Always test new or modified coderea
|
|
- Ensure all code has corresponding tests
|
|
- Ensure test coverage for each file is at least 90%
|
|
- In unit tests that expect error output, suppress it from the console
|
|
|
|
### Responding to Code Reviews
|
|
- When asked to respond to a code review of a PR,
|
|
- it is not necessary to implement all suggestions
|
|
- you are free to implement suggestions in a different way or to ignore if there is a good reason
|
|
- after making the changes, respond to each review comment with what was done (or why it was ignored)
|
|
|
|
### Lint-fixed, Formatted code
|
|
- Ensure linting and formatting are applied after every change
|
|
- ALWAYS do `npm run format`, `npm run lint`, `npm run typecheck`, `npm run test` and `npm run build` before pushing any changes
|
|
|
|
### Typescript instructions
|
|
- Use TypeScript for all new code
|
|
- Follow TypeScript best practices and coding standards
|
|
- NEVER use 'any' as a type
|
|
- NEVER suppress error types (e.g., no-unused-vars, no-explicit-any) in the typescript or eslint configuration as a way of satisfying the linter or compiler.
|
|
- Utilize type annotations and interfaces to improve code clarity and maintainability
|
|
- Leverage TypeScript's type inference and static analysis features for better code quality and refactoring
|
|
- Use type guards and type assertions to handle potential type mismatches and ensure type safety
|
|
- Take advantage of TypeScript's advanced features like generics, type aliases, and conditional types to write more expressive and reusable code
|
|
- Regularly review and refactor TypeScript code to ensure it remains well-structured and adheres to evolving best practices
|
|
|
|
## React instructions
|
|
- UI Components
|
|
- We are using the Mantine component library for UI.
|
|
- Instructions are at https://mantine.dev/llms.txt
|
|
- Avoid using div and other basic HTML elements for layout purposes.
|
|
- Prefer Mantine's Box, Group, and Stack components for layout.
|
|
- Use Mantine's theme and styling utilities to ensure a consistent and responsive design.
|
|
- NEVER use inline styles on a component.
|
|
- NEVER use raw hex values (`#ddd`, `#94a3b8`, etc.) or `rgba()` literals for colors in component props or theme files. Use `--inspector-*` CSS custom properties defined in `App.css :root` (e.g., `c: 'var(--inspector-text-primary)'`). If no existing token fits, add one to `:root` first.
|
|
- NEVER add a CSS class to a Mantine component when the styles can instead be expressed as component props or a theme variant. CSS classes are a last resort.
|
|
- PREFER component props (via `.withProps()`) to CSS for behavioral and visual styles.
|
|
- PREFER defining styles as theme variants (via `Component.extend()` in `src/theme/<Component>.ts`) over CSS classes. Each Mantine component with custom variants has its own file in `src/theme/`, exporting a `Theme<Name>` constant. The barrel `src/theme/index.ts` re-exports them all and `theme.ts` imports from the barrel. Flat CSS properties (margin, padding, background, border, color, font-size, etc.) belong in the theme. Only pseudo-selectors, nested child selectors, keyframes, and native HTML element styles belong in App.css.
|
|
- App.css must contain ONLY styles that cannot be expressed in the Mantine theme: `@keyframes`, pseudo-selectors (`:hover`, `:focus`), cross-component hover relationships, nested child-element selectors for third-party HTML output (e.g. ReactMarkdown), and styles for native HTML elements (`img`, `iframe`). When refactoring a component, actively move any flat CSS properties out of App.css and into theme variants or `.withProps()` constants.
|
|
- NEVER use inline code; instead extract to functions in the same file, exported or located in a shared location if immediately reusable.
|
|
- In a component's file, for sub-components:
|
|
- ALWAYS use Mantine components for layout and content, configured with props for styling and behavior.
|
|
- ALWAYS declare a subcomponent as a named constant using `.withProps()` if it has two or more props.
|
|
- NEVER use `Box` for subcomponent constants — `Box` does not support `.withProps()`. Use `Group`, `Stack`, `Flex`, `Text`, `Paper`, `UnstyledButton`, or `Image` instead. Pick the component that best matches the purpose: `Paper` for bordered/surfaced containers, `Text` for any text or content wrapper, `Stack`/`Group`/`Flex` for layout.
|
|
- NEVER use a CSS class on a subcomponent constant when the styles can be expressed as a Mantine theme variant instead. Define variants in `src/theme/<Component>.ts` using `Component.extend({ styles: (_theme, props) => { ... } })` and reference them with `variant="variantName"` on the component or in `.withProps()`.
|
|
- CSS classes are ONLY acceptable on subcomponents for styles that cannot be expressed as flat CSS-in-JS properties in the theme — specifically: pseudo-selectors (`:hover`, `:focus`), cross-component hover relationships (`.parent:hover .child`), nested child-element selectors (`.wrapper p`, `.wrapper code`), `@keyframes` definitions, and native HTML elements (`img`, `iframe`) that are not Mantine components.
|
|
- When a theme variant needs a CSS class for nested/pseudo selectors, use `classNames` in the theme extension to auto-assign it — never add `className` manually in JSX for theme-styled components.
|
|
- Example — subcomponent constant with `withProps`:
|
|
```tsx
|
|
const CardContent = Group.withProps({
|
|
flex: 1,
|
|
align: 'flex-start',
|
|
justify: 'space-between',
|
|
wrap: 'nowrap',
|
|
});
|
|
return <CardContent> ... </CardContent>
|
|
```
|
|
- Example — theme variant with auto-assigned className for nested selectors:
|
|
```tsx
|
|
// src/theme/Paper.ts
|
|
export const ThemePaper = Paper.extend({
|
|
classNames: (_theme, props) => {
|
|
if (props.variant === 'message') return { root: 'message' };
|
|
return {};
|
|
},
|
|
styles: (_theme, props) => {
|
|
if (props.variant === 'message') {
|
|
return { root: { padding: '1.5rem', borderRadius: 12 } };
|
|
}
|
|
return { root: {} };
|
|
},
|
|
}),
|
|
|
|
// Component.tsx
|
|
const MessageContainer = Paper.withProps({ variant: 'message' });
|
|
```
|