-
-
Notifications
You must be signed in to change notification settings - Fork 735
feat(webui): adding storybook #5929
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
jameshiester
commented
Oct 15, 2025
- Adds storybook
- Establishes reusable components as separate package
- Enhancements to red team report page to clarify terminology and improve accessibility
⏩ No tests generated (e62d7df) View output ↗ Tip New to Tusk? Learn more here. View check history
|
📝 WalkthroughWalkthrough
Estimated code review effort🎯 4 (Complex) | ⏱️ ~75 minutes Possibly related PRs
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 9
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
src/app/src/pages/redteam/report/components/TestSuites.tsx (1)
72-82
: Type the theme param (avoid any) and keep sx-callback usageUse MUI’s Theme type instead of any. The sx backgroundColor callback is correct. As per coding guidelines.
Apply within this file:
-const getRiskScoreColor = (riskScore: number, theme: any): string => { +const getRiskScoreColor = (riskScore: number, theme: Theme): string => {Add the missing import near the top:
import type { Theme } from '@mui/material/styles';Also applies to: 369-371
🧹 Nitpick comments (13)
packages/storybook/.storybook/theme.css (1)
64-218
: Consider reducing reliance on!important
declarations.The dark theme styling uses
!important
extensively (lines 76-78, 83-84, 91, 95-96, etc.) to override Storybook's default styles. While this ensures the theme takes effect, it can:
- Make future style adjustments more difficult
- Create specificity wars if other styles need to override these
- Indicate that the selectors might not be specific enough
If possible, consider:
- Using more specific selectors to match Storybook's default specificity
- Applying theme classes at a higher level in the DOM
- Working with Storybook's official theming API if it provides better hooks
However, if Storybook's architecture requires this approach, this may be acceptable as a pragmatic solution.
To verify if there's a better approach, check Storybook's theming documentation:
What is the recommended way to theme Storybook 9.1.10 UI elements?
packages/storybook/eslint.config.js (1)
1-26
: Complete the Storybook ESLint integration.The
eslint-plugin-storybook
is imported but never added to the configuration. Either the plugin should be integrated into theextends
array, or the import should be removed.To integrate the Storybook plugin, apply this diff:
export default defineConfig([ globalIgnores(['dist']), { files: ['**/*.{ts,tsx}'], extends: [ js.configs.recommended, tseslint.configs.recommended, reactHooks.configs['recommended-latest'], reactRefresh.configs.vite, + ...storybook.configs['flat/recommended'], ], languageOptions: { ecmaVersion: 2020, globals: globals.browser, }, }, ]);
Alternatively, if the plugin isn't needed, remove the import:
-// For more info, see https://github.com/storybookjs/eslint-plugin-storybook#configuration-flat-config-format -import storybook from 'eslint-plugin-storybook'; - import js from '@eslint/js';Dockerfile (2)
47-47
: Investigate root cause of memory pressure instead of increasing heap size.Increasing
max-old-space-size
to 4GB is a workaround that masks underlying issues. Consider investigating:
- Memory-intensive build steps (large assets, inefficient bundling)
- Memory leaks in build tooling
- Opportunities to optimize the build process
If the memory increase is truly necessary, add a comment explaining why:
+# Increase heap size for memory-intensive Vite build with large asset bundles RUN NODE_OPTIONS="--max-old-space-size=4096" npm run build
38-43
: Remove redundant npm install steps (Dockerfile lines 38–43). The rootnpm ci
already installs all workspace dependencies (src/app
,packages/toolkit
), so these additionalnpm install
commands duplicate installs, increasing image size and build time. Remove them or consolidate with workspace-aware flags.packages/storybook/src/App.tsx (1)
5-20
: Consider removing placeholder demo code.This appears to be the default Vite + React template app. If the Storybook package is intended for component development and testing, this demo component may not be needed long-term.
src/app/src/pages/redteam/report/components/TestSuites.tsx (1)
491-496
: Prefer sx over inline styleReplace the inline style with sx to follow MUI best practices.
- <Button + <Button variant="contained" size="small" color="inherit" - style={{ marginLeft: 8 }} + sx={{ ml: 1 }}package.json (1)
21-24
: Workspaces and scripts LGTM; add audit for new packagesAdd packages/toolkit and packages/storybook to audit:fix to keep security scanning consistent across workspaces.
-"audit:fix": "npm audit fix && npm audit fix --prefix src/app && npm audit fix --prefix site", +"audit:fix": "npm audit fix && npm audit fix --prefix src/app && npm audit fix --prefix site && npm audit fix --prefix packages/toolkit && npm audit fix --prefix packages/storybook",Also applies to: 40-40
packages/storybook/.storybook/main.tsx (1)
1-1
: Optional: use main.ts (not .tsx)Config files aren’t JSX. Rename to main.ts for clarity and tooling defaults.
packages/toolkit/vite.config.ts (3)
12-18
: Don’t externalize devDependenciesOnly externalize runtime deps/peers; including devDeps can create unmet runtime modules for consumers.
-const allDeps = { - ...packageJson.dependencies, - ...packageJson.peerDependencies, - ...packageJson.devDependencies, -}; -const externalDeps = Object.keys(allDeps); +const externalDeps = Object.keys({ + ...(packageJson.dependencies ?? {}), + ...(packageJson.peerDependencies ?? {}), +});
19-36
: Remove unused UMD globalsYou’re emitting only es/cjs. The generated
globals
are unused noise.-// Generate globals mapping for UMD builds -const generateGlobals = (deps: string[]) => { - const globals: Record<string, string> = {}; - deps.forEach((dep) => { - // Convert package names to global variable names - const globalName = dep - .replace(/^@/, '') // Remove @ prefix - .replace(/[\/\-]/g, '') // Remove slashes and hyphens - .replace(/([a-z])([A-Z])/g, '$1$2') // Handle camelCase - .replace(/^[a-z]/, (match) => match.toUpperCase()); // Capitalize first letter - - globals[dep] = globalName; - }); - return globals; -}; - -const globalsMapping = generateGlobals(externalDeps); +// No UMD build; no globals mapping needed @@ - globals: globalsMapping, + // no UMD globals for es build @@ - globals: globalsMapping, + // no UMD globals for cjs buildAlso applies to: 68-80
40-42
: Unnecessary ts-expect-errorvite-plugin-dts v3 provides types. Remove the suppression or cast to Plugin if needed.
- // @ts-expect-error - dts plugin is not typed dts({
packages/toolkit/package.json (2)
11-19
: Remove non-standardstyle
condition inexports
..
The
"style"
condition inside the"."
export isn’t standard. Keep the dedicated"./style.css"
subpath."exports": { ".": { "types": "./dist/index.d.ts", - "style": "./dist/style.css", "import": "./dist/index.mjs", "require": "./dist/index.cjs" }, "./style.css": "./dist/style.css" },
20-22
: Mark CSS as side-effectfulPrevent CSS from being tree-shaken when imported by consumers.
"files": [ "dist" ], + "sideEffects": ["*.css"],
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (3)
package-lock.json
is excluded by!**/package-lock.json
packages/storybook/public/vite.svg
is excluded by!**/*.svg
packages/storybook/src/assets/react.svg
is excluded by!**/*.svg
📒 Files selected for processing (51)
.dockerignore
(1 hunks).github/workflows/main.yml
(3 hunks)CLAUDE.md
(1 hunks)Dockerfile
(1 hunks)examples/websockets-streaming/README.md
(1 hunks)jest.config.ts
(1 hunks)package.json
(3 hunks)packages/storybook/.gitignore
(1 hunks)packages/storybook/.storybook/main.tsx
(1 hunks)packages/storybook/.storybook/preview.tsx
(1 hunks)packages/storybook/.storybook/theme.css
(1 hunks)packages/storybook/.storybook/vitest.setup.ts
(1 hunks)packages/storybook/README.md
(1 hunks)packages/storybook/eslint.config.js
(1 hunks)packages/storybook/index.html
(1 hunks)packages/storybook/package.json
(1 hunks)packages/storybook/src/App.css
(1 hunks)packages/storybook/src/App.tsx
(1 hunks)packages/storybook/src/ThemeProvider.tsx
(1 hunks)packages/storybook/src/index.css
(1 hunks)packages/storybook/src/main.tsx
(1 hunks)packages/storybook/src/stories/form/input/BaseNumberInput.stories.tsx
(1 hunks)packages/storybook/src/stories/redteam/report/risk/RiskChart.stories.tsx
(1 hunks)packages/storybook/tsconfig.app.json
(1 hunks)packages/storybook/tsconfig.json
(1 hunks)packages/storybook/tsconfig.node.json
(1 hunks)packages/storybook/vite.config.ts
(1 hunks)packages/storybook/vitest.shims.d.ts
(1 hunks)packages/toolkit/.gitignore
(1 hunks)packages/toolkit/README.md
(1 hunks)packages/toolkit/package.json
(1 hunks)packages/toolkit/src/components/form/input/BaseNumberInput.test.tsx
(6 hunks)packages/toolkit/src/components/form/input/BaseNumberInput.tsx
(1 hunks)packages/toolkit/src/components/redteam/report/risk/RiskChart.tsx
(1 hunks)packages/toolkit/src/index.ts
(1 hunks)packages/toolkit/src/setupTests.ts
(1 hunks)packages/toolkit/tsconfig.json
(1 hunks)packages/toolkit/vite.config.ts
(1 hunks)site/docs/providers/websocket.md
(2 hunks)src/app/package.json
(1 hunks)src/app/src/components/PageShell.tsx
(3 hunks)src/app/src/main.tsx
(1 hunks)src/app/src/pages/eval/components/ResultsTable.tsx
(1 hunks)src/app/src/pages/model-audit/components/AdvancedOptionsDialog.tsx
(1 hunks)src/app/src/pages/redteam/report/components/SeverityCard.test.tsx
(1 hunks)src/app/src/pages/redteam/report/components/TestSuites.tsx
(1 hunks)src/app/src/pages/redteam/report/utils/color.test.tsx
(2 hunks)src/app/src/pages/redteam/setup/components/RunOptions.tsx
(1 hunks)src/app/src/pages/redteam/setup/components/Targets/CommonConfigurationOptions.tsx
(1 hunks)src/app/src/pages/redteam/setup/components/Targets/WebSocketEndpointConfiguration.tsx
(1 hunks)src/app/src/pages/redteam/setup/components/Targets/tabs/DigitalSignatureAuthTab.tsx
(1 hunks)
🧰 Additional context used
📓 Path-based instructions (18)
**/*.{ts,tsx}
📄 CodeRabbit inference engine (.cursor/rules/gh-cli-workflow.mdc)
Prefer not to introduce new TypeScript types; use existing interfaces whenever possible
**/*.{ts,tsx}
: Use TypeScript with strict type checking
Follow consistent import order (Biome will handle import sorting)
Use consistent curly braces for all control statements
Prefer const over let; avoid var
Use object shorthand syntax whenever possible
Use async/await for asynchronous code
Use consistent error handling with proper type checks
Always sanitize sensitive data before logging
Use structured logger methods (debug/info/warn/error) with a context object instead of interpolating secrets into log strings
Use sanitizeObject for manual sanitization in non-logging contexts before persisting or further processing data
Files:
packages/storybook/src/App.tsx
src/app/src/pages/redteam/setup/components/Targets/CommonConfigurationOptions.tsx
packages/storybook/src/stories/form/input/BaseNumberInput.stories.tsx
src/app/src/pages/redteam/report/utils/color.test.tsx
packages/storybook/src/ThemeProvider.tsx
src/app/src/pages/redteam/setup/components/RunOptions.tsx
src/app/src/pages/eval/components/ResultsTable.tsx
src/app/src/pages/redteam/setup/components/Targets/WebSocketEndpointConfiguration.tsx
src/app/src/components/PageShell.tsx
src/app/src/pages/model-audit/components/AdvancedOptionsDialog.tsx
packages/toolkit/src/components/form/input/BaseNumberInput.test.tsx
packages/storybook/vitest.shims.d.ts
packages/storybook/vite.config.ts
src/app/src/pages/redteam/report/components/SeverityCard.test.tsx
src/app/src/pages/redteam/setup/components/Targets/tabs/DigitalSignatureAuthTab.tsx
packages/toolkit/src/index.ts
packages/storybook/src/stories/redteam/report/risk/RiskChart.stories.tsx
packages/toolkit/src/components/form/input/BaseNumberInput.tsx
src/app/src/main.tsx
packages/toolkit/src/components/redteam/report/risk/RiskChart.tsx
src/app/src/pages/redteam/report/components/TestSuites.tsx
packages/toolkit/src/setupTests.ts
jest.config.ts
packages/storybook/src/main.tsx
packages/toolkit/vite.config.ts
**/*.{tsx,jsx}
📄 CodeRabbit inference engine (.cursor/rules/react-components.mdc)
**/*.{tsx,jsx}
: Use icons from @mui/icons-material
Prefer commonly used icons from @mui/icons-material for intuitive experience
Files:
packages/storybook/src/App.tsx
src/app/src/pages/redteam/setup/components/Targets/CommonConfigurationOptions.tsx
packages/storybook/src/stories/form/input/BaseNumberInput.stories.tsx
src/app/src/pages/redteam/report/utils/color.test.tsx
packages/storybook/src/ThemeProvider.tsx
src/app/src/pages/redteam/setup/components/RunOptions.tsx
src/app/src/pages/eval/components/ResultsTable.tsx
src/app/src/pages/redteam/setup/components/Targets/WebSocketEndpointConfiguration.tsx
src/app/src/components/PageShell.tsx
src/app/src/pages/model-audit/components/AdvancedOptionsDialog.tsx
packages/toolkit/src/components/form/input/BaseNumberInput.test.tsx
src/app/src/pages/redteam/report/components/SeverityCard.test.tsx
src/app/src/pages/redteam/setup/components/Targets/tabs/DigitalSignatureAuthTab.tsx
packages/storybook/src/stories/redteam/report/risk/RiskChart.stories.tsx
packages/toolkit/src/components/form/input/BaseNumberInput.tsx
src/app/src/main.tsx
packages/toolkit/src/components/redteam/report/risk/RiskChart.tsx
src/app/src/pages/redteam/report/components/TestSuites.tsx
packages/storybook/src/main.tsx
src/app/src/**/*.{ts,tsx}
📄 CodeRabbit inference engine (src/app/CLAUDE.md)
src/app/src/**/*.{ts,tsx}
: Never use fetch() directly; always use callApi() from @app/utils/api for all HTTP requests
Access Zustand state outside React components via store.getState(); do not call hooks outside components
Use the @app/* path alias for internal imports as configured in Vite
Files:
src/app/src/pages/redteam/setup/components/Targets/CommonConfigurationOptions.tsx
src/app/src/pages/redteam/report/utils/color.test.tsx
src/app/src/pages/redteam/setup/components/RunOptions.tsx
src/app/src/pages/eval/components/ResultsTable.tsx
src/app/src/pages/redteam/setup/components/Targets/WebSocketEndpointConfiguration.tsx
src/app/src/components/PageShell.tsx
src/app/src/pages/model-audit/components/AdvancedOptionsDialog.tsx
src/app/src/pages/redteam/report/components/SeverityCard.test.tsx
src/app/src/pages/redteam/setup/components/Targets/tabs/DigitalSignatureAuthTab.tsx
src/app/src/main.tsx
src/app/src/pages/redteam/report/components/TestSuites.tsx
src/app/src/{components,pages}/**/*.tsx
📄 CodeRabbit inference engine (src/app/CLAUDE.md)
src/app/src/{components,pages}/**/*.tsx
: Use the class-based ErrorBoundary component (@app/components/ErrorBoundary) to wrap error-prone UI
Access theme via useTheme() from @mui/material/styles instead of hardcoding theme values
Use useMemo/useCallback only when profiling indicates benefit; avoid unnecessary memoization
Implement explicit loading and error states for components performing async operations
Prefer MUI composition and the sx prop for styling over ad-hoc inline styles
Files:
src/app/src/pages/redteam/setup/components/Targets/CommonConfigurationOptions.tsx
src/app/src/pages/redteam/report/utils/color.test.tsx
src/app/src/pages/redteam/setup/components/RunOptions.tsx
src/app/src/pages/eval/components/ResultsTable.tsx
src/app/src/pages/redteam/setup/components/Targets/WebSocketEndpointConfiguration.tsx
src/app/src/components/PageShell.tsx
src/app/src/pages/model-audit/components/AdvancedOptionsDialog.tsx
src/app/src/pages/redteam/report/components/SeverityCard.test.tsx
src/app/src/pages/redteam/setup/components/Targets/tabs/DigitalSignatureAuthTab.tsx
src/app/src/pages/redteam/report/components/TestSuites.tsx
src/app/**/*.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
src/app/**/*.{ts,tsx}
: In the React app (src/app), always use callApi from @app/utils/api for API calls instead of fetch()
React hooks: use useMemo for computed values and useCallback for functions that accept arguments
Files:
src/app/src/pages/redteam/setup/components/Targets/CommonConfigurationOptions.tsx
src/app/src/pages/redteam/report/utils/color.test.tsx
src/app/src/pages/redteam/setup/components/RunOptions.tsx
src/app/src/pages/eval/components/ResultsTable.tsx
src/app/src/pages/redteam/setup/components/Targets/WebSocketEndpointConfiguration.tsx
src/app/src/components/PageShell.tsx
src/app/src/pages/model-audit/components/AdvancedOptionsDialog.tsx
src/app/src/pages/redteam/report/components/SeverityCard.test.tsx
src/app/src/pages/redteam/setup/components/Targets/tabs/DigitalSignatureAuthTab.tsx
src/app/src/main.tsx
src/app/src/pages/redteam/report/components/TestSuites.tsx
{package.json,src/app/package.json,site/package.json,examples/**/package.json}
📄 CodeRabbit inference engine (CLAUDE.md)
PeerDependencies must match devDependencies versions
Files:
src/app/package.json
package.json
{package.json,src/app/package.json,site/package.json}
📄 CodeRabbit inference engine (CLAUDE.md)
Use CommonJS modules (set "type": "commonjs" in package.json)
Files:
src/app/package.json
package.json
**/*.{test,spec}.{js,ts,tsx}
📄 CodeRabbit inference engine (.cursor/rules/gh-cli-workflow.mdc)
Avoid disabling or skipping tests unless absolutely necessary and documented
Files:
src/app/src/pages/redteam/report/utils/color.test.tsx
packages/toolkit/src/components/form/input/BaseNumberInput.test.tsx
src/app/src/pages/redteam/report/components/SeverityCard.test.tsx
src/app/src/**/*.test.{ts,tsx}
📄 CodeRabbit inference engine (src/app/CLAUDE.md)
src/app/src/**/*.test.{ts,tsx}
: In tests, import testing APIs from vitest (e.g., describe, it, expect, vi) and not from @jest/globals
Mock API calls in tests; do not make real network requests (e.g., vi.mock('@app/utils/api'))
Wrap MUI components in a ThemeProvider when testing components that depend on theme
Prefer Testing Library queries that reflect user behavior (getByRole, getByLabelText, etc.)
Clean up after tests as needed (e.g., clear/reset mocks) despite Vitest auto-cleanup
When testing React Router components, render under a MemoryRouter
Use Vitest as the test runner for the frontend app; do not use Jest APIs
Files:
src/app/src/pages/redteam/report/utils/color.test.tsx
src/app/src/pages/redteam/report/components/SeverityCard.test.tsx
src/app/src/components/**/*.tsx
📄 CodeRabbit inference engine (src/app/CLAUDE.md)
src/app/src/components/**/*.tsx
: Create MUI styled components using @mui/material/styles styled API; use shouldForwardProp when adding custom props
Define strict TypeScript interfaces for all component props and provide defaults for optional props where appropriate
Add a displayName to components wrapped with React.memo for better debugging
Files:
src/app/src/components/PageShell.tsx
examples/*/README.md
📄 CodeRabbit inference engine (.cursor/rules/examples.mdc)
examples/*/README.md
: The README.md must begin with the folder name as an H1 heading
Every example README must include instructions on how to run it with 'npx promptfoo@latest init --example example-name'
Include a comprehensive README.md that explains the purpose, prerequisites, instructions, and expected outputs for the example
Document any model-specific capabilities or limitations in examples
Clearly list all required environment variables at the beginning of the README
For each environment variable, explain its purpose, how to obtain it, and any default values or constraints in the README
Include a sample .env file or instructions when multiple environment variables are needed in the README
Document any required API keys or credentials in the README
Provide instructions for cleaning up resources after running the example in the README
When creating examples for specific providers, explain any provider-specific configuration in the README
When creating examples for specific providers, document required environment variables in the README
When creating examples for specific providers, include information about pricing or usage limits in the README
When creating examples for specific providers, highlight unique features or capabilities in the README
When creating examples for specific providers, compare to similar providers where appropriate in the README
Files:
examples/websockets-streaming/README.md
examples/*/{README.md,promptfooconfig.yaml}
📄 CodeRabbit inference engine (.cursor/rules/examples.mdc)
Include placeholder values for secrets/credentials in the README or configuration files
Files:
examples/websockets-streaming/README.md
{site/**,examples/**}
📄 CodeRabbit inference engine (.cursor/rules/gh-cli-workflow.mdc)
Any pull request that only touches files in 'site/' or 'examples/' directories must use the 'docs:' prefix in the PR title, not 'feat:' or 'fix:'
Files:
examples/websockets-streaming/README.md
site/docs/providers/websocket.md
examples/**
📄 CodeRabbit inference engine (.cursor/rules/gh-cli-workflow.mdc)
When modifying examples, update existing files in 'examples/' instead of adding new ones (e.g., replace outdated model IDs rather than introducing new example files)
Files:
examples/websockets-streaming/README.md
examples/**/README.md
📄 CodeRabbit inference engine (examples/CLAUDE.md)
examples/**/README.md
: Each example must include a README.md that begins with a first-level heading: "# folder-name (Human Readable Name)"
README.md must include instructions showing: npx promptfoo@latest init --exampleEach example in examples/ should include a clear README.md
Files:
examples/websockets-streaming/README.md
site/docs/**/*.md
📄 CodeRabbit inference engine (.cursor/rules/docusaurus.mdc)
site/docs/**/*.md
: Prioritize minimal edits when updating existing documentation; avoid creating entirely new sections or rewriting substantial portions; focus edits on improving grammar, spelling, clarity, fixing typos, and structural improvements where needed; do not modify existing headings (h1, h2, h3, etc.) as they are often linked externally.
Structure content to reveal information progressively: begin with essential actions and information, then provide deeper context as necessary; organize information from most important to least important.
Use action-oriented language: clearly outline actionable steps users should take, use concise and direct language, prefer active voice over passive voice, and use imperative mood for instructions.
Use 'eval' instead of 'evaluation' in all documentation; when referring to command line usage, use 'npx promptfoo eval' rather than 'npx promptfoo evaluation'; maintain consistency with this terminology across all examples, code blocks, and explanations.
The project name can be written as either 'Promptfoo' (capitalized) or 'promptfoo' (lowercase) depending on context: use 'Promptfoo' at the beginning of sentences or in headings, and 'promptfoo' in code examples, terminal commands, or when referring to the package name; be consistent with the chosen capitalization within each document or section.
Each markdown documentation file must include required front matter fields: 'title' (the page title shown in search results and browser tabs) and 'description' (a concise summary of the page content, ideally 150-160 characters).
Only add a title attribute to code blocks that represent complete, runnable files; do not add titles to code fragments, partial examples, or snippets that aren't meant to be used as standalone files; this applies to all code blocks regardless of language.
Use special comment directives to highlight specific lines in code blocks: 'highlight-next-line' highlights the line immediately after the comment, 'highligh...
Files:
site/docs/providers/websocket.md
site/**
📄 CodeRabbit inference engine (.cursor/rules/gh-cli-workflow.mdc)
If the change is a feature, update the relevant documentation under 'site/'
Files:
site/docs/providers/websocket.md
site/docs/**/*.{md,mdx}
📄 CodeRabbit inference engine (site/docs/CLAUDE.md)
site/docs/**/*.{md,mdx}
: Use the term "eval" not "evaluation" in documentation and examples
Capitalization: use "Promptfoo" (capitalized) in prose/headings and "promptfoo" (lowercase) in code, commands, and package names
Every doc must include required front matter: title and description
Only add title= to code blocks when showing complete runnable files
Admonitions must have empty lines around their content (Prettier requirement)
Do not modify headings; they may be externally linked
Use progressive disclosure: put essential information first
Use action-oriented, imperative mood in instructions (e.g., "Install the package")
Files:
site/docs/providers/websocket.md
🧠 Learnings (12)
📚 Learning: 2025-10-05T16:56:39.114Z
Learnt from: CR
PR: promptfoo/promptfoo#0
File: src/app/CLAUDE.md:0-0
Timestamp: 2025-10-05T16:56:39.114Z
Learning: Applies to src/app/vite.config.ts : Maintain test configuration (e.g., test section, jsdom, globals) in src/app/vite.config.ts
Applied to files:
packages/storybook/tsconfig.app.json
packages/storybook/tsconfig.node.json
packages/storybook/vite.config.ts
packages/toolkit/src/setupTests.ts
packages/toolkit/vite.config.ts
📚 Learning: 2025-10-05T16:59:20.507Z
Learnt from: CR
PR: promptfoo/promptfoo#0
File: src/redteam/CLAUDE.md:0-0
Timestamp: 2025-10-05T16:59:20.507Z
Learning: Applies to src/redteam/**/*.ts : Use the standardized risk severity levels: critical, high, medium, low when reporting results
Applied to files:
src/app/src/pages/redteam/report/utils/color.test.tsx
📚 Learning: 2025-10-05T16:56:39.114Z
Learnt from: CR
PR: promptfoo/promptfoo#0
File: src/app/CLAUDE.md:0-0
Timestamp: 2025-10-05T16:56:39.114Z
Learning: Applies to src/app/src/{components,pages}/**/*.tsx : Access theme via useTheme() from mui/material/styles instead of hardcoding theme values
Applied to files:
packages/storybook/src/ThemeProvider.tsx
packages/storybook/.storybook/preview.tsx
src/app/src/pages/redteam/report/components/TestSuites.tsx
📚 Learning: 2025-10-05T16:56:39.114Z
Learnt from: CR
PR: promptfoo/promptfoo#0
File: src/app/CLAUDE.md:0-0
Timestamp: 2025-10-05T16:56:39.114Z
Learning: Applies to src/app/src/**/*.test.{ts,tsx} : Wrap MUI components in a ThemeProvider when testing components that depend on theme
Applied to files:
packages/storybook/.storybook/preview.tsx
packages/toolkit/src/components/form/input/BaseNumberInput.test.tsx
📚 Learning: 2025-10-06T03:43:01.653Z
Learnt from: CR
PR: promptfoo/promptfoo#0
File: CLAUDE.md:0-0
Timestamp: 2025-10-06T03:43:01.653Z
Learning: Applies to package.json : Ensure workspaces include src/app and site directories
Applied to files:
package.json
📚 Learning: 2025-10-05T17:00:56.424Z
Learnt from: CR
PR: promptfoo/promptfoo#0
File: test/CLAUDE.md:0-0
Timestamp: 2025-10-05T17:00:56.424Z
Learning: Applies to test/**/jest.config.ts : Use Jest configuration in jest.config.ts (not Vitest config)
Applied to files:
packages/storybook/vite.config.ts
packages/toolkit/vite.config.ts
📚 Learning: 2025-10-05T16:56:39.114Z
Learnt from: CR
PR: promptfoo/promptfoo#0
File: src/app/CLAUDE.md:0-0
Timestamp: 2025-10-05T16:56:39.114Z
Learning: Applies to src/app/src/**/*.test.{ts,tsx} : In tests, import testing APIs from vitest (e.g., describe, it, expect, vi) and not from jest/globals
Applied to files:
packages/storybook/vite.config.ts
📚 Learning: 2025-10-11T15:29:11.784Z
Learnt from: CR
PR: promptfoo/promptfoo#0
File: CLAUDE.md:0-0
Timestamp: 2025-10-11T15:29:11.784Z
Learning: Before committing, run npm run l and npm run f to fix linting and formatting issues
Applied to files:
CLAUDE.md
📚 Learning: 2025-07-18T17:26:07.659Z
Learnt from: CR
PR: promptfoo/promptfoo#0
File: .cursor/rules/gh-cli-workflow.mdc:0-0
Timestamp: 2025-07-18T17:26:07.659Z
Learning: Format and lint the code prior to committing using 'npm run f' and 'npm run l'
Applied to files:
CLAUDE.md
📚 Learning: 2025-07-18T17:25:57.700Z
Learnt from: CR
PR: promptfoo/promptfoo#0
File: .cursor/rules/gh-cli-workflow.mdc:0-0
Timestamp: 2025-07-18T17:25:57.700Z
Learning: Format and lint the code prior to committing using 'npm run f && npm run l'
Applied to files:
CLAUDE.md
📚 Learning: 2025-10-05T16:56:39.114Z
Learnt from: CR
PR: promptfoo/promptfoo#0
File: src/app/CLAUDE.md:0-0
Timestamp: 2025-10-05T16:56:39.114Z
Learning: Applies to src/app/src/setupTests.ts : Global test setup and environment initialization should reside in src/app/src/setupTests.ts
Applied to files:
packages/toolkit/src/setupTests.ts
📚 Learning: 2025-10-05T17:00:56.424Z
Learnt from: CR
PR: promptfoo/promptfoo#0
File: test/CLAUDE.md:0-0
Timestamp: 2025-10-05T17:00:56.424Z
Learning: Applies to test/**/*.test.ts : Import from jest/globals in tests
Applied to files:
packages/toolkit/src/setupTests.ts
🧬 Code graph analysis (7)
packages/storybook/src/stories/form/input/BaseNumberInput.stories.tsx (1)
packages/toolkit/src/components/form/input/BaseNumberInput.tsx (1)
BaseNumberInput
(17-71)
src/app/src/pages/redteam/report/utils/color.test.tsx (1)
packages/storybook/src/ThemeProvider.tsx (1)
darkTheme
(227-227)
packages/storybook/src/ThemeProvider.tsx (1)
src/app/src/components/PageShell.tsx (1)
createAppTheme
(46-323)
packages/storybook/.storybook/preview.tsx (1)
packages/storybook/src/ThemeProvider.tsx (2)
lightTheme
(226-226)darkTheme
(227-227)
packages/toolkit/src/components/form/input/BaseNumberInput.test.tsx (1)
packages/toolkit/src/components/form/input/BaseNumberInput.tsx (1)
BaseNumberInput
(17-71)
src/app/src/pages/redteam/report/components/SeverityCard.test.tsx (1)
src/app/src/components/PageShell.tsx (1)
createAppTheme
(46-323)
packages/storybook/src/stories/redteam/report/risk/RiskChart.stories.tsx (1)
packages/toolkit/src/components/redteam/report/risk/RiskChart.tsx (1)
RiskChart
(8-38)
🪛 LanguageTool
packages/toolkit/README.md
[grammar] ~43-~43: There might be a mistake here.
Context: ...ops:** - children
: The button content - variant
: 'primary' | 'secondary' | 'outline' (d...
(QB_NEW_EN)
[grammar] ~44-~44: There might be a mistake here.
Context: ...ondary' | 'outline' (default: 'primary') - size
: 'small' | 'medium' | 'large' (default:...
(QB_NEW_EN)
[grammar] ~45-~45: There might be a mistake here.
Context: ...| 'medium' | 'large' (default: 'medium') - disabled
: boolean (default: false) - onClick
: ...
(QB_NEW_EN)
[grammar] ~46-~46: There might be a mistake here.
Context: ...) - disabled
: boolean (default: false) - onClick
: () => void - className
: string ### ...
(QB_NEW_EN)
[grammar] ~47-~47: There might be a mistake here.
Context: ...(default: false) - onClick
: () => void - className
: string ### Card A container componen...
(QB_NEW_EN)
[grammar] ~56-~56: There might be a mistake here.
Context: ...Props:** - children
: The card content - title
: string (optional) - subtitle
: string...
(QB_NEW_EN)
[grammar] ~57-~57: There might be a mistake here.
Context: ...ard content - title
: string (optional) - subtitle
: string (optional) - elevated
: boolea...
(QB_NEW_EN)
[grammar] ~58-~58: There might be a mistake here.
Context: ...ptional) - subtitle
: string (optional) - elevated
: boolean (default: false) - className
...
(QB_NEW_EN)
[grammar] ~59-~59: There might be a mistake here.
Context: ...) - elevated
: boolean (default: false) - className
: string ### Input A form input compon...
(QB_NEW_EN)
[grammar] ~68-~68: There might be a mistake here.
Context: ...Props: - label
: string (optional) - placeholder
: string (optional) - value
: string - ...
(QB_NEW_EN)
[grammar] ~69-~69: There might be a mistake here.
Context: ...onal) - placeholder
: string (optional) - value
: string - type
: 'text' | 'email' | 'p...
(QB_NEW_EN)
[grammar] ~70-~70: There might be a mistake here.
Context: ...er: string (optional) -
value: string -
type`: 'text' | 'email' | 'password' | 'numbe...
(QB_NEW_EN)
[grammar] ~71-~71: There might be a mistake here.
Context: ... 'password' | 'number' (default: 'text') - disabled
: boolean (default: false) - required
:...
(QB_NEW_EN)
[grammar] ~72-~72: There might be a mistake here.
Context: ...) - disabled
: boolean (default: false) - required
: boolean (default: false) - error
: st...
(QB_NEW_EN)
[grammar] ~73-~73: There might be a mistake here.
Context: ...) - required
: boolean (default: false) - error
: string (optional) - helpText
: string...
(QB_NEW_EN)
[grammar] ~74-~74: There might be a mistake here.
Context: ...ult: false) - error
: string (optional) - helpText
: string (optional) - onChange
: (value...
(QB_NEW_EN)
[grammar] ~75-~75: There might be a mistake here.
Context: ...ptional) - helpText
: string (optional) - onChange
: (value: string) => void - className
:...
(QB_NEW_EN)
[grammar] ~76-~76: There might be a mistake here.
Context: ...l) - onChange
: (value: string) => void - className
: string ## Development ```bash # Inst...
(QB_NEW_EN)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (27)
- GitHub Check: Tusk Test Runner (1)
- GitHub Check: Tusk Test Runner (3)
- GitHub Check: Tusk Test Runner (4)
- GitHub Check: Tusk Test Runner (2)
- GitHub Check: Share Test
- GitHub Check: Test on Node 24.x and windows-latest
- GitHub Check: Run Integration Tests
- GitHub Check: webui tests
- GitHub Check: Redteam (Staging API)
- GitHub Check: Build Docs
- GitHub Check: Test on Node 22.x and macOS-latest
- GitHub Check: Redteam (Production API)
- GitHub Check: toolkit tests
- GitHub Check: Test on Node 20.x and windows-latest
- GitHub Check: Test on Node 20.x and macOS-latest
- GitHub Check: Test on Node 22.x and windows-latest
- GitHub Check: Test on Node 24.x and ubuntu-latest
- GitHub Check: Test on Node 20.x and ubuntu-latest
- GitHub Check: Generate Assets
- GitHub Check: Test on Node 22.x and ubuntu-latest
- GitHub Check: Build on Node 22.x
- GitHub Check: Build on Node 24.x
- GitHub Check: Build on Node 20.x
- GitHub Check: Style Check
- GitHub Check: test
- GitHub Check: Tusk Tester
- GitHub Check: Analyze (javascript-typescript)
🔇 Additional comments (44)
site/docs/providers/websocket.md (1)
31-31
: Update looks good.Thanks for documenting the new
REQUEST_TIMEOUT_MS
default clearly in both sections.Also applies to: 232-232
examples/websockets-streaming/README.md (1)
13-13
: Command now matches folder name — nice alignment.This update fixes the mismatch between the example identifier and folder path. LGTM.
src/app/src/main.tsx (1)
7-10
: Polyfill implementation verified—no changes required.
supportsScrollTimeline()
, dynamic import with try/catch, and.catch
ininitializeScrollTimelinePolyfill()
cover feature detection, conditional loading, and error handling..dockerignore (1)
15-16
: LGTM! Appropriate Docker build optimizations.The additions correctly exclude development-only artifacts (Storybook) and test files from Docker images, reducing image size without affecting runtime functionality.
packages/storybook/src/index.css (1)
1-17
: LGTM! Standard base styles for Storybook.The global styles follow best practices:
- System font stack for native look and feel
- Box-sizing reset for predictable layout behavior
- Font smoothing for improved rendering
src/app/src/pages/redteam/setup/components/Targets/CommonConfigurationOptions.tsx (1)
13-13
: LGTM! Import source updated to use the toolkit package.The BaseNumberInput component is now imported from the new promptfoo-toolkit package, aligning with the PR's goal of establishing reusable components. The usage remains unchanged, ensuring no functional impact.
src/app/src/pages/redteam/setup/components/Targets/tabs/DigitalSignatureAuthTab.tsx (1)
24-24
: LGTM! Consistent import update.The BaseNumberInput import has been updated to use promptfoo-toolkit, consistent with the broader refactoring effort. No functional changes to the component.
packages/storybook/src/App.css (1)
30-34
: LGTM! Excellent accessibility consideration.The
prefers-reduced-motion
media query respects user preferences for reduced animations, following WCAG accessibility guidelines.packages/storybook/.gitignore (1)
1-27
: LGTM! Comprehensive gitignore patterns.The ignore patterns appropriately cover:
- Build artifacts (dist, node_modules)
- Development files (logs, editor configs)
- Storybook-specific outputs (storybook-static)
CLAUDE.md (1)
334-334
: LGTM! Appropriate exclusion of workspace packages.The
--ignore-dep
flags correctly exclude the new promptfoo-toolkit and storybook packages from cross-workspace version consistency checks, allowing them to maintain independent versioning as separate packages.jest.config.ts (1)
20-20
: LGTM! Correct test isolation for toolkit package.Excluding
packages/toolkit
from Jest's test path prevents duplicate test runs, as the toolkit package maintains its own test configuration and execution strategy.packages/storybook/README.md (1)
1-73
: LGTM! Standard template documentation.The README provides clear guidance on the React + TypeScript + Vite setup with appropriate ESLint configuration examples. The static analysis grammar warnings are false positives from markdown list formatting.
packages/toolkit/src/setupTests.ts (1)
1-11
: LGTM! Standard test setup following learned patterns.The test setup correctly initializes Jest DOM matchers and Prism for syntax highlighting. This follows the learned pattern of placing test setup in dedicated setup files. The Prism language imports ensure syntax highlighting is available during tests.
Based on learnings: Global test setup should reside in setupTests.ts files.
packages/toolkit/.gitignore (1)
1-42
: LGTM! Comprehensive gitignore patterns.The
.gitignore
file includes all necessary patterns for a TypeScript/Node.js library project, covering dependencies, build outputs, environment files, IDE artifacts, and coverage data. The patterns align with best practices for package development.packages/storybook/.storybook/theme.css (1)
1-61
: LGTM! Well-documented CSS variable mapping.The theme CSS provides a clear mapping from MUI CSS variables to Storybook-specific variables with appropriate fallback values. The documentation comments (lines 1-23) explain the variable system well, making maintenance easier.
packages/toolkit/src/components/form/input/BaseNumberInput.tsx (1)
20-20
: Defaultvalue
ofBaseNumberInput
can remain''
.All existing consumers either pass an explicit
value
or correctly handle''
, and tests cover empty-string clearing and numeric inputs without errors.packages/storybook/package.json (1)
45-45
: Vite 7.x compatibility confirmed. Storybook 9.1.10 supports Vite ≥5, so usingvite@^7.1.9
is safe.packages/storybook/src/stories/form/input/BaseNumberInput.stories.tsx (1)
8-24
: LGTM!The wrapper component correctly manages internal state and synchronizes with Storybook's controls. The useEffect pattern ensures prop changes from Storybook controls update the internal state, while the onChange handler maintains both internal state and propagates changes to the parent.
packages/storybook/vitest.shims.d.ts (1)
1-1
: LGTM!Standard TypeScript triple-slash reference directive for Vitest browser provider types.
packages/storybook/src/main.tsx (1)
1-10
: LGTM!Standard React 18 entry point implementation using
createRoot
andStrictMode
.packages/storybook/index.html (1)
1-13
: LGTM!Standard HTML5 entry point with appropriate meta tags and module script for Vite.
src/app/src/pages/redteam/setup/components/RunOptions.tsx (1)
9-9
: LGTM!Import source correctly updated to use the
BaseNumberInput
component from the newpromptfoo-toolkit
package, aligning with the PR's objective to establish reusable components as a separate package.src/app/src/pages/eval/components/ResultsTable.tsx (1)
52-52
: LGTM!Import source correctly updated to use the
BaseNumberInput
component from the newpromptfoo-toolkit
package, consistent with the refactoring across the codebase.src/app/src/pages/model-audit/components/AdvancedOptionsDialog.tsx (1)
16-16
: LGTM! Import migration to toolkit package.The import source change aligns with the PR's objective to establish reusable components in the separate toolkit package. The component usage remains unchanged.
src/app/package.json (1)
66-68
: LGTM! Dependencies added for toolkit integration and form handling.The workspace dependency on
promptfoo-toolkit
correctly uses the file protocol for monorepo integration, and the form-related packages (react-hook-form
,@hookform/resolvers
) are appropriately placed in runtime dependencies.packages/storybook/vite.config.ts (1)
1-16
: LGTM! Standard Vite configuration for Storybook.The configuration appropriately sets up React plugin support and resolves MUI Material from the workspace node_modules. The alias ensures consistent MUI resolution across the Storybook environment.
.github/workflows/main.yml (3)
137-137
: LGTM! Dependency check correctly excludes workspace packages.Ignoring
promptfoo-toolkit
andstorybook
in the dependency version consistency check is appropriate since these are internal workspace packages that follow independent versioning.
246-267
: LGTM! Toolkit CI job properly sequences build and test.The new
toolkit
job correctly builds toolkit dependencies before running tests, ensuring proper validation of the toolkit package in isolation.
286-287
: LGTM! Proper dependency build ordering for app tests.Building the toolkit before running app tests ensures the local workspace dependency is available and up-to-date for the web UI tests.
src/app/src/components/PageShell.tsx (1)
6-6
: LGTM! Theme severity palette refinements.The severity color mappings have been refined to create clearer visual distinction:
high
: Changed fromred[500]
toorange[700]
medium
: New level added usingyellow[700]
These changes improve the accessibility and clarity of severity indicators in the red team report UI.
Also applies to: 62-66, 142-142
packages/storybook/tsconfig.json (1)
1-4
: LGTM! Standard TypeScript project reference setup.This root configuration correctly delegates to separate app and node TypeScript configs, following TypeScript's project references pattern for multi-configuration projects.
src/app/src/pages/redteam/setup/components/Targets/WebSocketEndpointConfiguration.tsx (1)
11-11
: LGTM! Import migration to toolkit package.The import source update aligns with the PR's migration to the shared toolkit package. Component functionality remains unchanged.
packages/storybook/tsconfig.node.json (1)
1-27
: LGTM! Properly configured TypeScript for Node tooling.The configuration appropriately targets ES2023, enables strict type-checking, and includes
vite.config.ts
for Storybook's build tooling. Thecomposite
option supports TypeScript project references.src/app/src/pages/redteam/report/utils/color.test.tsx (1)
14-17
: LGTM! Test expectations correctly updated for new theme structure.The test assertions now properly reference
theme.palette.custom.severity.*
instead of hardcoded palette colors, aligning with the centralized severity color mapping introduced in this PR.Also applies to: 63-67
packages/toolkit/src/index.ts (1)
1-4
: LGTM! Clean public API surface for the toolkit package.The re-exports follow standard library packaging patterns and establish a clear public API surface.
packages/storybook/.storybook/vitest.setup.ts (1)
1-7
: LGTM! Correct setup for Storybook portable stories testing.The configuration properly applies project annotations including a11y addon support, following the official Storybook Vitest integration pattern.
packages/toolkit/src/components/form/input/BaseNumberInput.test.tsx (2)
3-6
: LGTM! Improved import organization and testing setup.The reorganized imports and addition of
renderWithTheme
helper follow testing best practices, especially wrapping MUI components in aThemeProvider
for theme-dependent behavior.Based on learnings.
44-44
: LGTM! Tests now properly exercise controlled component behavior.The switch from
defaultValue
tovalue
prop testing ensures the component works correctly in controlled mode, which is the recommended pattern for form inputs in React.Also applies to: 71-71, 85-85, 100-100, 134-134
src/app/src/pages/redteam/report/components/SeverityCard.test.tsx (2)
7-8
: LGTM! Theme-driven test setup improves maintainability.Creating a theme instance and using it for color expectations ensures tests stay in sync with theme changes, rather than relying on hardcoded color values.
Also applies to: 16-16
22-41
: LGTM! Color assertions now correctly reference custom severity palette.The updated test expectations properly validate against
theme.palette.custom.severity.*
mappings with alpha transparency, aligning with the new centralized severity color system.packages/storybook/tsconfig.app.json (1)
23-23
: No action needed: TypeScript ^5.9.3 supportserasableSyntaxOnly
.packages/storybook/src/stories/redteam/report/risk/RiskChart.stories.tsx (1)
1-212
: Stories look comprehensive and well-structuredGood coverage across values, sizes, and interactive controls.
packages/toolkit/package.json (1)
3-6
: Confirm publish intentPackage is
"private": true
while PR says “publishable UI library”. If you intend to publish, set"private": false
and add publishConfig.packages/storybook/.storybook/main.tsx (1)
38-41
: No action required: ‘@storybook/addon-vitest’ is the official Storybook 9.x addon.
import { dirname, join } from 'path'; | ||
|
||
import { themes } from 'storybook/theming'; | ||
import type { StorybookConfig } from '@storybook/react-vite'; | ||
|
||
/** | ||
* This function is used to resolve the absolute path of a package. | ||
* It is needed in projects that use Yarn PnP or are set up within a monorepo. | ||
*/ | ||
function getAbsolutePath(value: string): string { | ||
return dirname(require.resolve(join(value, 'package.json'))); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fix ESM config: wrong theming import path and undefined require
- Import should be from '@storybook/theming'
- In ESM,
require
is undefined; create it viacreateRequire
Apply:
-import { themes } from 'storybook/theming';
+import { themes } from '@storybook/theming';
+import { createRequire } from 'module';
+const require = createRequire(import.meta.url);
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
import { dirname, join } from 'path'; | |
import { themes } from 'storybook/theming'; | |
import type { StorybookConfig } from '@storybook/react-vite'; | |
/** | |
* This function is used to resolve the absolute path of a package. | |
* It is needed in projects that use Yarn PnP or are set up within a monorepo. | |
*/ | |
function getAbsolutePath(value: string): string { | |
return dirname(require.resolve(join(value, 'package.json'))); | |
} | |
import { dirname, join } from 'path'; | |
import { themes } from '@storybook/theming'; | |
import { createRequire } from 'module'; | |
const require = createRequire(import.meta.url); | |
import type { StorybookConfig } from '@storybook/react-vite'; | |
/** | |
* This function is used to resolve the absolute path of a package. | |
* It is needed in projects that use Yarn PnP or are set up within a monorepo. | |
*/ | |
function getAbsolutePath(value: string): string { | |
return dirname(require.resolve(join(value, 'package.json'))); | |
} |
🤖 Prompt for AI Agents
In packages/storybook/.storybook/main.tsx around lines 1 to 12, fix two ESM
issues: change the theming import to come from '@storybook/theming' (not
'storybook/theming'), and replace the use of require (which is undefined in ESM)
by creating a require function via createRequire from the 'module' package; then
use that created require to resolve the package.json path so getAbsolutePath
works in ESM/monorepo environments.
// biome-ignore lint/correctness/noUnusedImports: React is needed for Storybook | ||
import React, { useEffect } from 'react'; | ||
|
||
import { Theme } from '@mui/material'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Tidy imports, remove debug log, and use CssBaseline as self-closing
- Import Theme from @mui/material/styles
- Remove unused sbThemes import and console.log
- Render CssBaseline as a self-closing component
-import { Theme } from '@mui/material';
+import type { Theme } from '@mui/material/styles';
@@
-import { themes as sbThemes } from 'storybook/theming';
@@
- console.log(sbThemes.dark);
@@
- <ThemeProvider theme={theme}>
- <CssBaseline>{storyFn(context)}</CssBaseline>
- </ThemeProvider>
+ <ThemeProvider theme={theme}>
+ <CssBaseline />
+ {storyFn(context)}
+ </ThemeProvider>
Also applies to: 8-8, 21-21, 38-41
🤖 Prompt for AI Agents
In packages/storybook/.storybook/preview.tsx around lines 4, 8, 21, and 38-41,
tidy imports and remove debug artifacts: change Theme import to come from
'@mui/material/styles', remove the unused sbThemes import and any console.log
calls, and render CssBaseline as a self-closing component (<CssBaseline />)
instead of an opening/closing pair; update any related JSX accordingly and
remove now-unused import references.
"react": "^18.3.1", | ||
"react-dom": "^18.3.1" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion | 🟠 Major
🧩 Analysis chain
Verify React and React-DOM version alignment.
React is pinned to ^18.3.1
while @types/react
uses ^18.3.26
(line 32). Ensure the type definitions match the React runtime version to avoid type mismatches. Consider aligning both to the same patch version.
Run the following script to check for version mismatches across the workspace:
🏁 Script executed:
#!/bin/bash
# Description: Check React version consistency across packages
echo "=== React versions in workspace ==="
rg -g 'package.json' '"react":\s*"[^"]+"' -A 0
echo -e "\n=== @types/react versions in workspace ==="
rg -g 'package.json' '"@types/react":\s*"[^"]+"' -A 0
Length of output: 509
Align React and @types/react patch versions
React (^18.3.1
) and its type definitions (^18.3.26
) are out of sync across packages (packages/storybook, packages/toolkit, src/app). Update both to the same patch release (e.g., ^18.3.26) to ensure consistent type coverage.
🤖 Prompt for AI Agents
In packages/storybook/package.json around lines 15-16, update the "react" and
"react-dom" dependency versions from "^18.3.1" to the same patch release as the
type definitions (e.g., "^18.3.26") so runtime and @types/react are aligned;
after changing those entries, run your package manager install to update the
lockfile (yarn.lock or package-lock.json) and ensure the other packages
mentioned (packages/toolkit, src/app) are similarly reconciled if they still
reference different patch versions.
@@ -0,0 +1,227 @@ | ||
import { createTheme } from '@mui/material'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
Fix import: use createTheme from '@mui/material/styles'
This import will fail or mis-type. MUI’s createTheme comes from @mui/material/styles.
-import { createTheme } from '@mui/material';
+import { createTheme } from '@mui/material/styles';
Additionally, this theme omits app-specific palette.custom fields (e.g., severity). To avoid drift, consider reusing the app’s createAppTheme or sharing a single implementation via toolkit.
To check if any stories/components expect palette.custom.*:
🏁 Script executed:
#!/bin/bash
# Search for custom palette usage that Storybook theme may be missing
rg -nP 'palette\.custom(\.|\[)' -C2 --type=ts --type=tsx
Length of output: 27
🏁 Script executed:
#!/bin/bash
# Search for any usage of palette.custom in .ts/.tsx files
rg -nP 'palette\.custom' -n -C2 --glob '*.ts' --glob '*.tsx'
Length of output: 13104
Fix import path and sync custom palette with app theme
-import { createTheme } from '@mui/material';
+import { createTheme } from '@mui/material/styles';
- Storybook’s theme is missing
palette.custom
(severity levels, overlays) used throughout the app—stories will break or render incorrectly. - Reuse the app’s
createAppTheme
or extract a shared theming utility to ensure Storybook mirrors the same palette.custom configuration.
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
import { createTheme } from '@mui/material'; | |
import { createTheme } from '@mui/material/styles'; |
🤖 Prompt for AI Agents
In packages/storybook/src/ThemeProvider.tsx around line 1, the file imports
createTheme directly from MUI and the Storybook theme lacks the app-specific
palette.custom (severity levels, overlays) causing story breakage; replace the
direct MUI import with the app's shared theme factory (or import
createAppTheme/createSharedTheme from the app/theme module), then instantiate
the Storybook theme using that shared factory so palette.custom is included (or
extract and import a small helper that returns the same palette.custom object)
and ensure the returned theme is passed to ThemeProvider so stories receive the
same severity/overlay config as the app.
"peerDependencies": { | ||
"@emotion/react": "^11.14.0", | ||
"@emotion/styled": "^11.14.1", | ||
"@mui/icons-material": "^7.3.4", | ||
"@mui/material": "^7.3.2", | ||
"@mui/system": "^7.3.2", | ||
"@mui/x-charts": "^7.29.1", | ||
"@testing-library/dom": "^10.4.1", | ||
"@testing-library/jest-dom": "^6.8.0", | ||
"@testing-library/react": "^16.3.0", | ||
"@testing-library/user-event": "^14.6.1", | ||
"react": "^18.3.1", | ||
"react-dom": "^18.3.1", | ||
"react-hook-form": "^7.64.0" | ||
}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Testing libs should not be peerDependencies
Listing @testing-library packages as peers forces consumers to install test-only deps.
Apply:
"peerDependencies": {
"@emotion/react": "^11.14.0",
"@emotion/styled": "^11.14.1",
"@mui/icons-material": "^7.3.4",
- "@mui/material": "^7.3.2",
- "@mui/system": "^7.3.2",
- "@mui/x-charts": "^7.29.1",
- "@testing-library/dom": "^10.4.1",
- "@testing-library/jest-dom": "^6.8.0",
- "@testing-library/react": "^16.3.0",
- "@testing-library/user-event": "^14.6.1",
+ "@mui/material": "^7.3.2",
+ "@mui/system": "^7.3.2",
+ "@mui/x-charts": "^7.29.1",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"react-hook-form": "^7.64.0"
},
"devDependencies": {
+ "@testing-library/dom": "^10.4.1",
+ "@testing-library/jest-dom": "^6.8.0",
+ "@testing-library/react": "^16.3.0",
+ "@testing-library/user-event": "^14.6.1",
"@types/react": "^18.3.26",
"@types/react-dom": "^18.3.7",
"@vitejs/plugin-react": "^5.0.4",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"typescript": "^5.9.3",
"vite": "^7.1.9",
"vite-plugin-dts": "^3.5.0",
"vitest": "^3.2.4"
}
Also applies to: 55-65
🤖 Prompt for AI Agents
packages/toolkit/package.json lines 40-54 (and similarly lines 55-65): the
test-related @testing-library packages are incorrectly listed under
peerDependencies; remove @testing-library/dom, @testing-library/jest-dom,
@testing-library/react, and @testing-library/user-event from peerDependencies
and add them to devDependencies (with appropriate versions already present),
ensuring peerDependencies only contain runtime peers like react/react-dom and
MUI packages.
# promptfoo-toolkit | ||
|
||
A React component library for promptfoo applications. | ||
|
||
## Installation | ||
|
||
```bash | ||
npm install promptfoo-toolkit | ||
``` | ||
|
||
## Usage | ||
|
||
```tsx | ||
import React from 'react'; | ||
import { Button, Card, Input } from 'promptfoo-toolkit'; | ||
|
||
function App() { | ||
return ( | ||
<div> | ||
<Card title="Example Card" subtitle="This is a sample card"> | ||
<Input | ||
label="Name" | ||
placeholder="Enter your name" | ||
onChange={(value) => console.log(value)} | ||
/> | ||
<Button variant="primary" onClick={() => console.log('Clicked!')}> | ||
Click me | ||
</Button> | ||
</Card> | ||
</div> | ||
); | ||
} | ||
``` | ||
|
||
## Components | ||
|
||
### Button | ||
|
||
A customizable button component with multiple variants and sizes. | ||
|
||
**Props:** | ||
|
||
- `children`: The button content | ||
- `variant`: 'primary' | 'secondary' | 'outline' (default: 'primary') | ||
- `size`: 'small' | 'medium' | 'large' (default: 'medium') | ||
- `disabled`: boolean (default: false) | ||
- `onClick`: () => void | ||
- `className`: string | ||
|
||
### Card | ||
|
||
A container component for grouping related content. | ||
|
||
**Props:** | ||
|
||
- `children`: The card content | ||
- `title`: string (optional) | ||
- `subtitle`: string (optional) | ||
- `elevated`: boolean (default: false) | ||
- `className`: string | ||
|
||
### Input | ||
|
||
A form input component with label, validation, and help text support. | ||
|
||
**Props:** | ||
|
||
- `label`: string (optional) | ||
- `placeholder`: string (optional) | ||
- `value`: string | ||
- `type`: 'text' | 'email' | 'password' | 'number' (default: 'text') | ||
- `disabled`: boolean (default: false) | ||
- `required`: boolean (default: false) | ||
- `error`: string (optional) | ||
- `helpText`: string (optional) | ||
- `onChange`: (value: string) => void | ||
- `className`: string | ||
|
||
## Development | ||
|
||
```bash | ||
# Install dependencies | ||
npm install | ||
|
||
# Build the library | ||
npm run build | ||
|
||
# Watch for changes during development | ||
npm run dev | ||
|
||
# Type check | ||
npm run type-check | ||
|
||
# Clean build artifacts | ||
npm run clean | ||
``` | ||
|
||
## License | ||
|
||
MIT |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
Verify that documented components match actual exports.
The README documents Button
, Card
, and Input
components (lines 15, 20, 22), but the AI summary and other context indicate that the toolkit currently exports BaseNumberInput
and RiskChart
. Ensure the documentation accurately reflects the actual public API of the toolkit.
Run the following script to verify the actual exports from the toolkit:
🏁 Script executed:
#!/bin/bash
# Description: Check actual exports from toolkit package
echo "=== Toolkit index.ts exports ==="
cat packages/toolkit/src/index.ts
echo -e "\n=== All component files in toolkit ==="
fd -e tsx -e ts . packages/toolkit/src/components/
Length of output: 429
Update README.md to match toolkit’s actual exports
The README documents Button
, Card
, and Input
, but packages/toolkit/src/index.ts
only exports BaseNumberInput
and RiskChart
. Correct the usage examples and API section in packages/toolkit/README.md
to reflect the actual public components.
🧰 Tools
🪛 LanguageTool
[grammar] ~43-~43: There might be a mistake here.
Context: ...ops:** - children
: The button content - variant
: 'primary' | 'secondary' | 'outline' (d...
(QB_NEW_EN)
[grammar] ~44-~44: There might be a mistake here.
Context: ...ondary' | 'outline' (default: 'primary') - size
: 'small' | 'medium' | 'large' (default:...
(QB_NEW_EN)
[grammar] ~45-~45: There might be a mistake here.
Context: ...| 'medium' | 'large' (default: 'medium') - disabled
: boolean (default: false) - onClick
: ...
(QB_NEW_EN)
[grammar] ~46-~46: There might be a mistake here.
Context: ...) - disabled
: boolean (default: false) - onClick
: () => void - className
: string ### ...
(QB_NEW_EN)
[grammar] ~47-~47: There might be a mistake here.
Context: ...(default: false) - onClick
: () => void - className
: string ### Card A container componen...
(QB_NEW_EN)
[grammar] ~56-~56: There might be a mistake here.
Context: ...Props:** - children
: The card content - title
: string (optional) - subtitle
: string...
(QB_NEW_EN)
[grammar] ~57-~57: There might be a mistake here.
Context: ...ard content - title
: string (optional) - subtitle
: string (optional) - elevated
: boolea...
(QB_NEW_EN)
[grammar] ~58-~58: There might be a mistake here.
Context: ...ptional) - subtitle
: string (optional) - elevated
: boolean (default: false) - className
...
(QB_NEW_EN)
[grammar] ~59-~59: There might be a mistake here.
Context: ...) - elevated
: boolean (default: false) - className
: string ### Input A form input compon...
(QB_NEW_EN)
[grammar] ~68-~68: There might be a mistake here.
Context: ...Props: - label
: string (optional) - placeholder
: string (optional) - value
: string - ...
(QB_NEW_EN)
[grammar] ~69-~69: There might be a mistake here.
Context: ...onal) - placeholder
: string (optional) - value
: string - type
: 'text' | 'email' | 'p...
(QB_NEW_EN)
[grammar] ~70-~70: There might be a mistake here.
Context: ...er: string (optional) -
value: string -
type`: 'text' | 'email' | 'password' | 'numbe...
(QB_NEW_EN)
[grammar] ~71-~71: There might be a mistake here.
Context: ... 'password' | 'number' (default: 'text') - disabled
: boolean (default: false) - required
:...
(QB_NEW_EN)
[grammar] ~72-~72: There might be a mistake here.
Context: ...) - disabled
: boolean (default: false) - required
: boolean (default: false) - error
: st...
(QB_NEW_EN)
[grammar] ~73-~73: There might be a mistake here.
Context: ...) - required
: boolean (default: false) - error
: string (optional) - helpText
: string...
(QB_NEW_EN)
[grammar] ~74-~74: There might be a mistake here.
Context: ...ult: false) - error
: string (optional) - helpText
: string (optional) - onChange
: (value...
(QB_NEW_EN)
[grammar] ~75-~75: There might be a mistake here.
Context: ...ptional) - helpText
: string (optional) - onChange
: (value: string) => void - className
:...
(QB_NEW_EN)
[grammar] ~76-~76: There might be a mistake here.
Context: ...l) - onChange
: (value: string) => void - className
: string ## Development ```bash # Inst...
(QB_NEW_EN)
🤖 Prompt for AI Agents
In packages/toolkit/README.md around lines 1 to 100, the README lists Button,
Card, and Input but the package actually exports BaseNumberInput and RiskChart;
update the Usage example and the Components/API section to document the real
public exports: show an import of { BaseNumberInput, RiskChart } from
'promptfoo-toolkit', provide a minimal JSX usage example for each exported
component, and replace the Props lists with the actual props for BaseNumberInput
(e.g., value, onChange, min, max, step, disabled, className) and RiskChart
(e.g., data, labels, height, width, className); remove or correct any references
to non-exported components and ensure the Development and Installation sections
remain unchanged.
// @ts-ignore | ||
max={100} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
Investigate and remove the @ts-ignore
directive.
The @ts-ignore
comment suppresses TypeScript errors for the max
prop on the Gauge component. This could indicate:
- A version mismatch between the component and its types
- The prop exists at runtime but isn't in the type definitions
- Incorrect usage of the API
Please verify the @mui/x-charts/Gauge
API documentation to confirm whether max
is a valid prop. If it's valid but missing from the types, consider:
- Updating to the latest version of
@mui/x-charts
- Using proper TypeScript assertion instead of
@ts-ignore
- Filing an issue with the library if the types are incomplete
Run the following to check the installed version and compare with the latest:
🏁 Script executed:
#!/bin/bash
# Check current version and compare with latest
npm list @mui/x-charts 2>/dev/null | grep @mui/x-charts || echo "Package not found"
npm view @mui/x-charts version
Length of output: 24
🏁 Script executed:
#!/bin/bash
# Check if @mui/x-charts is declared in toolkit package.json
grep -n '"@mui/x-charts' packages/toolkit/package.json || echo "Not declared"
# Inspect ts-ignore and import usage in RiskChart.tsx
grep -n "@ts-ignore" packages/toolkit/src/components/redteam/report/risk/RiskChart.tsx || echo "No ts-ignore found"
grep -n "from '@mui/x-charts" packages/toolkit/src/components/redteam/report/risk/RiskChart.tsx || echo "Import not found"
Length of output: 118
🌐 Web query:
MUI X Charts Gauge max prop
💡 Result:
Use valueMin and valueMax (not max). The Gauge accepts value, valueMin and valueMax — e.g. . [1][2]
Sources:
[1] MUI X Charts — Gauge docs. [2] MUI X Gauge API.
Replace max
with valueMax
and remove @ts-ignore
The Gauge
API uses valueMin
/valueMax
(not max
). In RiskChart.tsx remove the // @ts-ignore
on line 12 and update to, for example:
<Gauge
valueMin={0}
valueMax={100}
…
/>
🤖 Prompt for AI Agents
In packages/toolkit/src/components/redteam/report/risk/RiskChart.tsx around
lines 12 to 13, remove the "// @ts-ignore" and replace the incorrect Gauge prop
"max" with the correct "valueMax" (and add "valueMin" if missing) so the Gauge
uses valueMin/valueMax (e.g., valueMin=0 and valueMax=100) per the Gauge API;
update props accordingly and remove the ts-ignore comment.
packages/toolkit/tsconfig.json
Outdated
"outDir": "dist", | ||
"rootDir": "src" | ||
}, | ||
"include": ["src/**/*", "../storybook/src/ThemeProvider.tsx"], |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion | 🟠 Major
Reconsider cross-package include for ThemeProvider.
The configuration includes "../storybook/src/ThemeProvider.tsx"
which creates a coupling between the toolkit and storybook packages. This can lead to:
- Build order dependencies (toolkit must build after storybook)
- Tight coupling between packages that should be independent
- Potential circular dependency issues
- Maintenance challenges if storybook is restructured
If ThemeProvider
is needed by toolkit components, consider:
- Moving it to toolkit as the source of truth
- Or using a shared utilities package
- Or making it a peer dependency with type-only imports
Run the following script to understand the dependency:
#!/bin/bash
# Description: Check how ThemeProvider is used in toolkit
echo "=== ThemeProvider imports in toolkit ==="
rg -nP 'import.*ThemeProvider' packages/toolkit/src/ -C 3
echo -e "\n=== ThemeProvider file content ==="
cat packages/storybook/src/ThemeProvider.tsx 2>/dev/null || echo "File not found in context"
🤖 Prompt for AI Agents
In packages/toolkit/tsconfig.json around line 31, the include entry
"../storybook/src/ThemeProvider.tsx" creates an undesirable cross-package
coupling; remove that path from the include and resolve the dependency by either
(A) moving ThemeProvider into packages/toolkit (make toolkit the source of truth
and update imports), or (B) extract ThemeProvider into a new shared package that
both toolkit and storybook depend on, or (C) make storybook a peer/dev
dependency and import ThemeProvider via type-only imports so toolkit's build
doesn't require storybook sources; after choosing one option, update imports
across the repo to reference the new location and run the repository
search/replace and the build to verify no remaining references to the storybook
file.
/// <reference types="vitest" /> | ||
|
||
import { readFileSync } from 'fs'; | ||
import { resolve } from 'path'; | ||
|
||
import react from '@vitejs/plugin-react'; | ||
import { defineConfig } from 'vite'; | ||
import dts from 'vite-plugin-dts'; | ||
|
||
// Read package.json to get all dependencies | ||
const packageJson = JSON.parse(readFileSync(resolve(__dirname, 'package.json'), 'utf-8')); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ESM: __dirname
is undefined
This config runs as ESM (package sets "type":"module"). Define __dirname
via fileURLToPath.
+import { fileURLToPath } from 'url';
/// <reference types="vitest" />
import { readFileSync } from 'fs';
import { resolve } from 'path';
import react from '@vitejs/plugin-react';
import { defineConfig } from 'vite';
import dts from 'vite-plugin-dts';
+const __dirname = fileURLToPath(new URL('.', import.meta.url));
@@
- entry: resolve(__dirname, 'src/index.ts'),
+ entry: resolve(__dirname, 'src/index.ts'),
Also applies to: 61-62
🤖 Prompt for AI Agents
In packages/toolkit/vite.config.ts around lines 1 to 11 (and also apply the same
fix at lines 61-62), the file runs as ESM so __dirname is undefined; define a
proper dirname using fileURLToPath and import.meta.url (import fileURLToPath and
URL from 'url' or just fileURLToPath from 'url') and replace uses of __dirname
with the computed dirname variable derived from fileURLToPath(import.meta.url)
so that readFileSync(resolve(dirname, 'package.json'), ...) and any other path
resolves work in ESM.