|
1 | | -# Button Builder - AI Agent Instructions |
2 | | - |
3 | | -## Project Overview |
4 | | -Button Builder is a **Home Assistant custom integration** that provides a visual UI for designing `custom:button-card` YAML configurations. It's a React/TypeScript frontend embedded in HA via iframe panel. |
5 | | - |
6 | | -## Architecture |
7 | | - |
8 | | -### Dual-Layer Structure |
9 | | -1. **Frontend (React/Vite)**: `src/App.tsx`, `src/components/`, `src/services/`, `src/utils/` |
10 | | -2. **HA Integration (Python)**: `custom_components/button_builder/` - registers sidebar panel |
11 | | - |
12 | | -### Key Data Flow |
13 | | -``` |
14 | | -User Input → ConfigPanel → ButtonConfig state → yamlGenerator.ts → YAML Output |
15 | | - ↓ |
16 | | - PreviewCard (live preview) |
17 | | -``` |
18 | | - |
19 | | -### Critical Files |
20 | | -- **`src/types.ts`**: `ButtonConfig` interface (~100+ properties) - the single source of truth |
21 | | -- **`src/ButtonCardApp.tsx`**: Main state management, preset handling, import/export |
22 | | -- **`src/utils/yamlGenerator.ts`**: Converts `ButtonConfig` → button-card YAML (1300+ lines) |
23 | | -- **`src/presets.ts`**: 80+ style presets with `Partial<ButtonConfig>` configs |
24 | | -- **`src/services/geminiService.ts`**: AI generation with structured schema output |
25 | | - |
26 | | -## Project Structure |
27 | | -``` |
28 | | -button-builder/ |
29 | | -├── src/ # Source code |
30 | | -│ ├── components/ # React components |
31 | | -│ ├── services/ # API services |
32 | | -│ ├── utils/ # Utility functions |
33 | | -│ ├── bubble-card/ # Bubble Card builder (beta) |
34 | | -│ └── assets/ # Images & assets |
35 | | -├── docs/ # Documentation |
36 | | -├── scripts/ # Build & deploy scripts |
37 | | -├── wiki/ # GitHub wiki pages |
38 | | -├── custom_components/ # Home Assistant integration |
39 | | -│ └── button_builder/ |
40 | | -│ └── www/ # Built frontend files |
41 | | -└── brands_submission/ # HACS brand assets |
42 | | -``` |
43 | | - |
44 | | -## Development Workflow |
45 | | - |
46 | | -### Commands |
47 | | -```bash |
48 | | -npm run dev # Local dev server at localhost:3000 |
49 | | -npm run build # Build to custom_components/button_builder/www/ |
50 | | -``` |
51 | | - |
52 | | -### Version Bump Checklist (CRITICAL) |
53 | | -When releasing, update version in **BOTH**: |
54 | | -1. `package.json` → `"version"` |
55 | | -2. `custom_components/button_builder/manifest.json` → `"version"` |
56 | | - |
57 | | -Cache busting uses `manifest.json` version + timestamp, so mismatched versions cause stale cache issues. |
58 | | - |
59 | | -### Release Process |
60 | | -```bash |
61 | | -npm run build |
62 | | -git add -A && git commit -m "message" |
63 | | -git tag vX.Y.Z && git push origin main --tags |
64 | | -gh release create vX.Y.Z --title "vX.Y.Z" --notes "..." --latest |
65 | | -``` |
66 | | - |
67 | | -## Code Patterns |
68 | | - |
69 | | -### State Management |
70 | | -- `isApplyingPresetRef` uses `useRef` (not `useState`) to avoid React batching race conditions |
71 | | -- `setConfig` wrapper auto-clears `activePreset` when user modifies config manually |
72 | | -- Config persists to `localStorage` with key `button-builder-config` |
73 | | - |
74 | | -### Adding New ButtonConfig Properties |
75 | | -1. Add to `ButtonConfig` interface in `src/types.ts` |
76 | | -2. Add default value to `DEFAULT_CONFIG` in `src/types.ts` |
77 | | -3. Add UI control in `src/components/ConfigPanel.tsx` |
78 | | -4. Handle in `src/utils/yamlGenerator.ts` to output correct YAML |
79 | | -5. Add to AI schema in `src/services/geminiService.ts` if AI should generate it |
80 | | - |
81 | | -### Preset Structure |
82 | | -```typescript |
83 | | -// src/presets.ts |
84 | | -{ |
85 | | - name: 'Preset Name', |
86 | | - description: 'Short description', |
87 | | - category: 'minimal' | 'glass' | 'neon' | 'gradient' | 'animated' | '3d' | 'cyberpunk' | 'retro' | 'nature' | 'icon-styles' | 'custom', |
88 | | - config: Partial<ButtonConfig> // Only override properties, rest use defaults |
89 | | -} |
90 | | -``` |
91 | | - |
92 | | -### YAML Generation Pattern |
93 | | -```typescript |
94 | | -// yamlGenerator.ts - only output non-default values |
95 | | -if (config.propertyName !== DEFAULT_CONFIG.propertyName) { |
96 | | - yaml += `property_name: ${config.propertyName}\n`; |
97 | | -} |
98 | | -``` |
99 | | - |
100 | | -## Common Pitfalls |
101 | | - |
102 | | -1. **Removing props/state**: Search ALL `.tsx` files for references before removing - leftover references cause runtime crashes (not caught by build) |
103 | | -2. **HA caching**: After HACS update, users need: Restart HA + hard refresh browser (Ctrl+Shift+R) |
104 | | -3. **Panel registration**: Uses 2-second delay in `__init__.py` to ensure HA frontend is ready |
105 | | -4. **Tailwind in production**: Uses CDN (`cdn.tailwindcss.com`) - expected console warning |
106 | | - |
107 | | -## Testing in Home Assistant |
108 | | - |
109 | | -The panel runs inside HA's iframe sandbox. To test locally with HA APIs: |
110 | | -- Panel URL: `/button_builder/panel.html?v={version}` |
111 | | -- Static assets served from `/button_builder/` |
112 | | -- Auth token read from `localStorage.hassTokens` |
113 | | - |
114 | | -## File Relationships |
115 | | -``` |
116 | | -ButtonConfig (src/types.ts) |
117 | | - ├── src/components/ConfigPanel.tsx (UI inputs) |
118 | | - ├── src/components/PreviewCard.tsx (live preview) |
119 | | - ├── src/utils/yamlGenerator.ts (YAML output) |
120 | | - ├── src/services/geminiService.ts (AI schema) |
121 | | - └── src/presets.ts (preset configs) |
122 | | -``` |
| 1 | +# Button Builder – AI Agent Guide |
| 2 | +- What this is: Home Assistant custom integration plus a React/Vite UI to design `custom:button-card` YAML (and a beta bubble-card builder). The panel is served from `custom_components/button_builder/www/` into an HA iframe registered in `custom_components/button_builder/__init__.py` (2s delayed setup). |
| 3 | +- Frontend map: Main entry `src/ButtonCardApp.tsx`, shell `src/App.tsx`, UI pieces under `src/components/`, YAML logic in `src/utils/yamlGenerator.ts`, presets in `src/presets.ts`, services in `src/services/`. Bubble-card has a parallel stack in `src/bubble-card/` (`BubbleCardApp`, `components/Preview.tsx`, `utils/yamlGenerator.ts`). |
| 4 | +- State/data flow: User input in `components/ConfigPanel.tsx` updates `ButtonConfig` state (held in `ButtonCardApp.tsx`) → `utils/yamlGenerator.ts` emits YAML (only non-defaults) → live preview `components/PreviewCard.tsx` and YAML viewer. Bubble-card mirrors this with its own types and generator. |
| 5 | +- Canonical schema: `src/types.ts` defines `ButtonConfig` + `DEFAULT_CONFIG`. When adding a field, update `DEFAULT_CONFIG`, expose controls in `components/ConfigPanel.tsx`, render/preview as needed, emit via `utils/yamlGenerator.ts`, include in presets (`src/presets.ts`) and AI schema (`services/geminiService.ts`). Bubble-card equivalents live in `src/bubble-card/types.ts` and friends. |
| 6 | +- Presets: ~80 presets in `src/presets.ts` (bubble-card has its own). Application uses `isApplyingPresetRef` to avoid React batching glitches; manual edits clear `activePreset` through the `setConfig` wrapper. |
| 7 | +- Persistence/import: Button config persists to `localStorage` key `button-builder-config`; Gemini key lives only in-browser. YAML import path: `utils/yamlImporter.ts` maps button-card options back into `ButtonConfig`. |
| 8 | +- Services: `services/geminiService.ts` uses `@google/genai` with a structured schema returning `ButtonConfig`. `homeAssistantService.ts` and `dashboardService.ts` wrap HA APIs; auth tokens expected in `localStorage.hassTokens`. |
| 9 | +- Styling/assets: Lucide + MDI icons; Tailwind injected via CDN in production (console warning is normal). Core styles `src/index.css`; HTML entry `src/index.html`. Keep ASCII; existing assets in `src/assets/`. |
| 10 | +- Build/dev: `npm run dev` (Vite on :3000), `npm run build` outputs to `custom_components/button_builder/www/`, `npm run preview` to inspect the build. Windows scripts in `scripts/*.ps1` wrap build/deploy steps. |
| 11 | +- Deploy/HA: Served in HA at `/button_builder/panel.html?v={version}`. Keep versions in `package.json` and `custom_components/button_builder/manifest.json` in lockstep for cache busting; HA caches aggressively—rebuild, copy to HA, restart HA, hard-refresh browser. |
| 12 | +- Patterns to preserve: Do not remove props/state without updating all `.tsx` call sites. Keep schema aligned between `DEFAULT_CONFIG` and both YAML generators (button + bubble) to avoid missing YAML. Presets/AI schema must track new fields. |
| 13 | +- Files to know: `src/components/` (UI controls + preview + MagicBuilder), `src/utils/yamlGenerator.ts` and `src/utils/yamlImporter.ts`, `src/services/` (Gemini/HA APIs), `src/presets.ts`, `custom_components/button_builder/__init__.py` (panel registration) and `manifest.json` (versioning), `custom_components/button_builder/www/` (built assets, do not hand-edit). |
0 commit comments