A comprehensive example UI plugin that demonstrates how to create custom dashboard widgets with React components and IPC communication in Auto Code.
This plugin adds a Project Statistics widget to the Auto Code dashboard that displays real-time metrics about your specs, including completion rates, in-progress builds, and success rates. It's a complete implementation demonstrating all key aspects of UI plugin development.
- Dashboard Widget: Adds a beautiful, informative widget to the main dashboard
- Real-time Stats: Shows spec counts (total, completed, pending, in-progress, failed)
- Success Rate: Calculates and displays project success percentage with visual progress bar
- Auto-refresh: Automatically updates statistics every 30 seconds
- Manual Refresh: Click-to-refresh button for instant updates
- Backend Communication: Demonstrates IPC handlers for frontend-backend data flow
- State Caching: Implements performance optimizations with data caching
- Error Handling: Graceful error states with retry functionality
This plugin demonstrates the complete UIPlugin API:
get_ui_components()- Registers dashboard widget componentregister_ipc_handlers()- Provides IPC handlers for data fetchingon_frontend_ready()- Pre-calculates stats for fast initial loadon_window_focus()- Refreshes data when window regains focus
The ui-component.tsx file shows best practices for React components:
- Modern React Hooks -
useState,useEffectfor state and lifecycle - TypeScript - Fully typed props and state interfaces
- IPC Communication - Calling backend handlers via
window.electronAPI - Auto-refresh - Interval-based data updates
- Loading States - Skeleton loaders and spinners
- Error Handling - Error boundaries and retry logic
- Tailwind CSS - Modern, responsive styling
- Icons - Lucide React icons for visual polish
The plugin demonstrates bidirectional communication:
Backend (plugin.py):
def register_ipc_handlers(self, context: UIContext) -> dict[str, Callable]:
def get_project_stats(event, project_dir: str):
# Calculate and return stats
stats = self._calculate_stats(Path(project_dir))
return {"success": True, "data": stats}
return {
"ui-extension:get-stats": get_project_stats,
"ui-extension:refresh-stats": refresh_stats,
}Frontend (ui-component.tsx):
const result = await window.electronAPI.invoke('ui-extension:get-stats', projectDir);
if (result.success) {
setStats(result.data);
}-
Using the Electron UI (Recommended):
- Open Auto Code desktop app
- Navigate to Plugins (keyboard shortcut:
U) - Click Install Plugin
- Select Directory as installation source
- Browse to
examples/plugins/ui-extension - Click Install
-
Manual Installation:
cp -r examples/plugins/ui-extension ~/.auto-claude/plugins/user/ -
Verify Installation:
python -c "from apps.backend.plugins.loader import PluginLoader; loader = PluginLoader(); plugin = loader.load_plugin('examples/plugins/ui-extension'); print('OK')"
Once installed and enabled:
- Navigate to Dashboard: The widget appears automatically on the main dashboard
- View Statistics: See your project metrics at a glance
- Auto-updates: Stats refresh every 30 seconds automatically
- Manual Refresh: Click the refresh icon in the top-right corner to update immediately
- Total Specs: Count of all specs in
.auto-claude/specs/ - Completed: Specs with
status: "completed" - In Progress: Specs currently being built
- Failed: Specs that failed during build
- Success Rate: Percentage of completed specs
The widget accepts these configuration props (defined in get_ui_components()):
props={
"refreshInterval": 30000, # Auto-refresh interval (ms)
"showCharts": True, # Show visual charts (future)
}This plugin requires:
read_files- To read spec directories and implementation plans
No write or network permissions needed.
ui-extension/
├── plugin.json # Plugin metadata and manifest
├── plugin.py # Backend implementation (Python)
├── ui-component.tsx # Frontend component (React/TypeScript)
└── README.md # This documentation
To add new metrics to the stats calculation:
def _calculate_stats(self, project_dir: Path) -> dict[str, Any]:
stats = {
# ... existing stats ...
"customMetric": 0, # Add your metric
}
# Calculate your metric
for spec_path in specs_dir.iterdir():
# ... your calculation logic ...
stats["customMetric"] += 1
return statsThen update the frontend interface and display:
interface ProjectStats {
// ... existing fields ...
customMetric: number;
}
// In component JSX:
<StatCard
icon={<YourIcon />}
label="Custom Metric"
value={stats.customMetric}
color="text-purple-500"
/>To add more backend functionality:
def register_ipc_handlers(self, context: UIContext) -> dict[str, Callable]:
def custom_handler(event, param: str):
# Your logic here
return {"success": True, "data": result}
return {
# ... existing handlers ...
f"{self.name}:custom-action": custom_handler,
}Call from frontend:
const result = await window.electronAPI.invoke('ui-extension:custom-action', param);The React component uses Tailwind CSS classes. Customize the appearance:
// Change color scheme
<div className="bg-purple-500"> // Instead of bg-primary
// Adjust layout
<div className="grid grid-cols-3 gap-6"> // Instead of grid-cols-4
// Add animations
<div className="transition-all duration-300 hover:scale-105">For real-world plugins, you may want to:
- Bundle TypeScript/React: Use Vite or Webpack to compile TypeScript
- Add Tests: Write unit tests for both Python and TypeScript code
- Optimize Performance: Add debouncing, memoization, virtual scrolling
- Add Configuration UI: Let users customize refresh interval, colors, etc.
This plugin uses the DASHBOARD extension point. UI plugins can also extend:
SIDEBAR- Add items to sidebar navigationSETTINGS- Add panels to settings pageTOOLBAR- Add buttons to main toolbarCONTEXT_MENU- Add items to right-click menusSTATUS_BAR- Add items to status bar
Example for sidebar:
UIComponentDefinition(
id="my-sidebar-item",
extension_point=UIExtensionPoint.SIDEBAR,
title="My Tool",
icon="puzzle",
route="/my-tool",
order=50,
)- Check plugin is enabled: Go to Plugins page and verify status
- Refresh the page: Try reloading the Electron app
- Check extension point: Verify you're on the Dashboard view
- Check logs: Look for errors in backend logs
- Verify channel names: Must match exactly between backend and frontend
- Check permissions: Ensure
read_filespermission is granted - Test backend separately: Try calling handler from Python REPL
- Check project directory: Verify path to
.auto-claude/specs/is correct - Verify spec format: Ensure specs have
implementation_plan.jsonfiles - Clear cache: Call
ui-extension:refresh-statsto force recalculation
- Install dependencies: Run
npm installinapps/frontend/ - Check types: Ensure
window.electronAPItypes are defined - Rebuild frontend: Run
npm run buildinapps/frontend/
This plugin implements several optimizations:
- Data Caching: Stats are cached in memory to avoid re-reading files
- Debounced Refresh: Auto-refresh doesn't show loading spinner
- Lazy Calculation: Stats only calculated when widget is visible
- Window Focus: Cache is cleared when window regains focus for fresh data
For very large projects (100+ specs), consider:
- Adding pagination or filtering
- Using background workers for calculation
- Implementing incremental updates instead of full recalculation
- UI Plugin Development Guide
- Plugin SDK Documentation
- Plugin Getting Started
- React Component Patterns
This pattern can be adapted for many use cases:
- Build Queue Widget: Show current and upcoming builds
- Test Results Dashboard: Display test coverage and pass rates
- Git Activity Timeline: Visualize commits and branches
- Resource Monitor: Show CPU, memory, disk usage
- Integration Status: Display connected services (Linear, GitHub, etc.)
MIT - See LICENSE file for details