feat: add MCP servers for UI component libraries#141
feat: add MCP servers for UI component libraries#141cabana8471-arch wants to merge 2 commits intoAutoForgeAI:masterfrom
Conversation
Add support for UI component library selection during project creation: - Add Phase 3b (UI library) and Phase 3c (visual style) to create-spec - Add app_spec_parser.py for shared UI config parsing - Add design_tokens.py with style presets (neobrutalism, glassmorphism, retro) - Update client.py with UI_MCP_TOOLS and dynamic MCP server configuration - Add UILibrarySelector and VisualStyleSelector React components - Generate design tokens on spec creation completion - Add 36 unit tests for UI configuration parsing Supported libraries: shadcn-ui (React), ark-ui (multi-framework) Libraries with MCP get rapid component generation via npx servers. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
|
Warning Rate limit exceeded
⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. 📝 WalkthroughWalkthroughThis pull request introduces UI component library and visual style selection phases to the project specification flow. It adds parsing utilities to extract configuration from spec files, design token generation based on style preferences, MCP server integration for UI tools, and React components for selecting libraries and styles during project initialization. Changes
Sequence Diagram(s)sequenceDiagram
participant User as User
participant UI as React Form
participant Spec as Spec Generator
participant Parser as Config Parser
participant Tokens as Token Generator
participant MCP as MCP Client
User->>UI: Select UI Library & Visual Style
UI->>Spec: Send selections
Spec->>Spec: Write app_spec.txt with config
Spec->>Parser: Parse UI config from spec
Parser-->>Spec: Return UIConfig
Spec->>Tokens: generate_design_tokens_from_spec()
alt Style is non-default
Tokens->>Tokens: Load preset (neobrutalism/glassmorphism/retro)
Tokens->>Tokens: Generate design-tokens.json
Tokens-->>Spec: Return tokens file path
Spec->>Spec: Emit file_written event
else Default style
Tokens-->>Spec: Return None (skip token generation)
end
Spec->>MCP: Initialize UI MCP servers
alt has_mcp is true
MCP->>MCP: Register shadcn-ui/ark-ui tools
MCP->>MCP: Resolve npx command (platform-aware)
MCP-->>Spec: UI tools ready
else has_mcp is false
MCP-->>Spec: No UI tools
end
Spec-->>User: Project initialized with config
Estimated Code Review Effort🎯 4 (Complex) | ⏱️ ~50 minutes Possibly Related PRs
Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
.claude/commands/create-spec.md (1)
294-296:⚠️ Potential issue | 🟡 MinorIncorrect phase reference.
Line 296 references "Phase 3b" for the database storage question, but this was renumbered to "Phase 3d" earlier in this PR (line 155).
📝 Suggested fix
**MANDATORY: Infrastructure Features** -If the app requires a database (Phase 3b answer was "Yes" or "Not sure"), you MUST include 5 Infrastructure features (indices 0-4): +If the app requires a database (Phase 3d answer was "Yes" or "Not sure"), you MUST include 5 Infrastructure features (indices 0-4):
🤖 Fix all issues with AI agents
In `@client.py`:
- Around line 363-368: In create_client, avoid repeatedly calling
get_ui_config_from_spec(project_dir); call it once at the start of the function
(e.g., ui_config = get_ui_config_from_spec(project_dir)) and reuse that
ui_config when building allowed_tools, computing permissions, and reading MCP
server config (references: allowed_tools logic, permissions block, MCP server
config block); remove the extra get_ui_config_from_spec calls and use the cached
ui_config variable throughout create_client to prevent multiple disk
reads/parses.
In `@test_ui_config.py`:
- Around line 23-28: The test module is missing coverage for
generate_design_tokens_from_spec; import generate_design_tokens_from_spec into
test_ui_config.py and add an integration-style test that calls
generate_design_tokens_from_spec with a representative spec (or fixture used by
server/services/spec_chat_session.py) and asserts the returned tokens match
expected values or that keys/structure produced by generate_design_tokens,
get_style_preset, and validate_visual_style are present; reference the function
name generate_design_tokens_from_spec and the call site in spec_chat_session.py
to mirror the real input/usage so the end-to-end flow is validated.
🧹 Nitpick comments (9)
server/services/spec_chat_session.py (1)
24-27: DuplicateROOT_DIRdefinition.
ROOT_DIRis defined twice - once at line 25 and again at line 63. Both compute the same value. Remove the duplicate to avoid confusion.♻️ Suggested fix
# Add root directory to path for imports ROOT_DIR = Path(__file__).parent.parent.parent if str(ROOT_DIR) not in sys.path: sys.path.insert(0, str(ROOT_DIR)) # Load environment variables from .env file if present load_dotenv() logger = logging.getLogger(__name__) # ... (API_ENV_VARS definition) async def _make_multimodal_message(content_blocks: list[dict]) -> AsyncGenerator[dict, None]: # ... -# Root directory of the project -ROOT_DIR = Path(__file__).parent.parent.parentAlso applies to: 62-63
ui/src/components/VisualStyleSelector.tsx (1)
165-171: Consider removing unused hover state or wrapping inrole="listbox".Two observations on this segment:
The
hoveredIdstate (Lines 72, 169-171) is tracked but immediately suppressed withvoid _hovered. If hover preview effects are planned, add a TODO comment with the intent; otherwise, remove the unused state to reduce complexity.Each Card uses
role="option"(Line 184), but there's no parent element withrole="listbox". For complete ARIA semantics, wrap the grid in a container withrole="listbox":♻️ Suggested fix for ARIA listbox
return ( - <div className={cn('grid grid-cols-1 gap-3 sm:grid-cols-2 lg:grid-cols-3', className)}> + <div + role="listbox" + aria-label="Visual style selection" + className={cn('grid grid-cols-1 gap-3 sm:grid-cols-2 lg:grid-cols-3', className)} + > {VISUAL_STYLES.map((style) => {ui/src/components/UILibrarySelector.tsx (2)
86-88: Redundant check inisCompatible.The
lib.id === 'none'check is redundant because the 'none' library (Lines 48-53) already includes all frameworks (['react', 'vue', 'solid', 'svelte', 'vanilla']) in itsframeworksarray. The first conditionlib.frameworks.includes(framework)will always return true for 'none'.♻️ Suggested simplification
const isCompatible = (lib: UILibrary) => { - return lib.frameworks.includes(framework) || lib.id === 'none' + return lib.frameworks.includes(framework) }
90-91: Addrole="listbox"to parent container for ARIA compliance.Similar to
VisualStyleSelector, each Card usesrole="option"but there's no parentrole="listbox"container.♻️ Suggested fix
return ( - <div className={cn('grid grid-cols-1 gap-3 sm:grid-cols-2', className)}> + <div + role="listbox" + aria-label="UI library selection" + className={cn('grid grid-cols-1 gap-3 sm:grid-cols-2', className)} + > {UI_LIBRARIES.map((lib) => {design_tokens.py (2)
174-178: Consider handling file write errors.The
tokens_path.write_text()call can raiseOSErrororPermissionErrorif the file cannot be written (disk full, permission denied, etc.). The caller (generate_design_tokens_from_spec) doesn't handle this, and an unhandled exception could interrupt the spec generation flow.🛡️ Suggested defensive handling
# Write design tokens tokens_path = autocoder_dir / "design-tokens.json" - tokens_path.write_text(json.dumps(preset, indent=2), encoding="utf-8") - - return tokens_path + try: + tokens_path.write_text(json.dumps(preset, indent=2), encoding="utf-8") + return tokens_path + except OSError: + return None
163-164: Document why "custom" returns None.The function returns
Nonefor both "default" and "custom" styles, but the reasoning differs:
- "default" needs no tokens (uses library defaults)
- "custom" expects user-provided tokens (shouldn't generate preset tokens)
Adding a brief comment would clarify this intent for future maintainers.
📝 Suggested documentation
+ # "default" uses library defaults; "custom" expects user-provided tokens if style == "default" or style == "custom": return Noneclient.py (1)
511-515: Avoid passingNoneforenvin MCP server config.Line 514 sets
"env": Nonewhenui_mcp_envis empty. Some SDK implementations may not handleNonegracefully. Prefer omitting the key entirely or passing an empty dict.🛡️ Suggested fix
- mcp_servers["ui_components"] = { - "command": npx_cmd, - "args": ui_mcp_args, - "env": ui_mcp_env if ui_mcp_env else None, - } + ui_mcp_config = { + "command": npx_cmd, + "args": ui_mcp_args, + } + if ui_mcp_env: + ui_mcp_config["env"] = ui_mcp_env + mcp_servers["ui_components"] = ui_mcp_configapp_spec_parser.py (2)
66-69: Comment filtering is incomplete.The check
value.startswith("<!--")only catches XML comments at the very beginning of the value. Comments preceded by whitespace (after strip) or inline comments won't be filtered.For example, this would still return
"value ":<tag>value <!-- comment --></tag>Consider using regex to strip comments if this is a concern:
♻️ Suggested improvement
if match: value = match.group(1).strip() # Filter out XML comments - if value and not value.startswith("<!--"): + # Remove XML comments and re-strip + value = re.sub(r"<!--.*?-->", "", value, flags=re.DOTALL).strip() + if value: return value return None
174-184: Consider moving constants to the top of the module.Python convention typically places module-level constants near the top (after imports) for visibility. These constants (
VALID_UI_LIBRARIES,MCP_SUPPORTED_LIBRARIES,VALID_VISUAL_STYLES,VALID_FRAMEWORKS) are referenced externally and would be easier to find at the top.
- Cache ui_config in client.py to avoid 3 redundant file reads - Fix env:None in MCP config by omitting key when empty - Add integration tests for generate_design_tokens_from_spec - Fix Phase 3b → 3d reference in create-spec.md - Remove duplicate ROOT_DIR in spec_chat_session.py - Add ARIA listbox role to UILibrarySelector and VisualStyleSelector - Remove redundant isCompatible check in UILibrarySelector - Add OSError handling in design_tokens.py - Move constants to top of app_spec_parser.py - Improve XML comment filtering with regex pattern Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
…atterns (Feature AutoForgeAI#141) Replace all remaining 'forbidden_output' references with 'forbidden_patterns' to match the validator registry in validators.py and the VALIDATOR_TYPES constant. - api/dspy_signatures.py: Updated DSPy signature field descriptions - api/static_spec_adapter.py: Updated create_validator() call - tests/verify_feature_8.py: Updated test validator type list Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Summary
Add support for selecting UI component libraries during project creation, with MCP server integration for rapid component generation.
.autocoder/design-tokens.jsonChanges
New Files
app_spec_parser.py- Shared parser for UI config from app_spec.txtdesign_tokens.py- Design token generation with style presetstest_ui_config.py- 36 unit tests for UI configurationui/src/components/UILibrarySelector.tsx- React component for library selectionui/src/components/VisualStyleSelector.tsx- React component for style selectionui/public/previews/README.md- Guidelines for preview imagesModified Files
.claude/commands/create-spec.md- Added Phase 3b and 3c questions.claude/templates/app_spec.template.txt- Added<ui_components>and<visual_style>sections.claude/templates/coding_prompt.template.md- Added UI verification checklist.claude/templates/initializer_prompt.template.md- Added UI library documentationclient.py- Added UI_MCP_TOOLS and dynamic MCP server configurationserver/services/spec_chat_session.py- Generate design tokens on spec completionCLAUDE.md- Documented UI MCP servers and visual stylesTest Plan
Dependencies
This PR depends on #128 (Token Optimization) being merged first.
Generated with Claude Code
Summary by CodeRabbit
Release Notes
New Features
Documentation
Tests
✏️ Tip: You can customize this high-level summary in your review settings.