This commit is contained in:
Pedram Amini
2025-11-26 02:21:20 -06:00
parent c30c053e0f
commit b253c4a7ed
2 changed files with 368 additions and 1292 deletions

1298
CLAUDE.md

File diff suppressed because it is too large Load Diff

View File

@@ -1,19 +1,20 @@
# Contributing to Maestro # Contributing to Maestro
Thank you for your interest in contributing to Maestro! This document provides guidelines, setup instructions, and architectural information for developers. Thank you for your interest in contributing to Maestro! This document provides guidelines, setup instructions, and practical guidance for developers.
For architecture details, see [ARCHITECTURE.md](ARCHITECTURE.md). For quick reference while coding, see [CLAUDE.md](CLAUDE.md).
## Table of Contents ## Table of Contents
- [Development Setup](#development-setup) - [Development Setup](#development-setup)
- [Project Structure](#project-structure) - [Project Structure](#project-structure)
- [Tech Stack](#tech-stack)
- [Development Scripts](#development-scripts) - [Development Scripts](#development-scripts)
- [Architecture](#architecture) - [Common Development Tasks](#common-development-tasks)
- [Code Style](#code-style) - [Code Style](#code-style)
- [Debugging Guide](#debugging-guide)
- [Commit Messages](#commit-messages) - [Commit Messages](#commit-messages)
- [Pull Request Process](#pull-request-process) - [Pull Request Process](#pull-request-process)
- [Building for Release](#building-for-release) - [Building for Release](#building-for-release)
- [GitHub Actions Workflow](#github-actions-workflow)
## Development Setup ## Development Setup
@@ -43,162 +44,254 @@ npm run dev
maestro/ maestro/
├── src/ ├── src/
│ ├── main/ # Electron main process (Node.js backend) │ ├── main/ # Electron main process (Node.js backend)
│ │ ├── utils/ # Shared utilities │ │ ├── index.ts # Entry point, IPC handlers
│ │ ── ... # Process management, IPC, web server │ │ ── process-manager.ts
│ │ ├── preload.ts # Secure IPC bridge
│ │ └── utils/ # Shared utilities
│ └── renderer/ # React frontend (UI) │ └── renderer/ # React frontend (UI)
│ ├── components/ # React components (UI elements, modals, panels) │ ├── App.tsx # Main coordinator
│ ├── hooks/ # Custom React hooks (reusable state logic) │ ├── components/ # React components
│ ├── services/ # Business logic services (git, process management) │ ├── hooks/ # Custom React hooks
│ ├── services/ # IPC wrappers (git, process)
│ ├── contexts/ # React contexts
│ ├── constants/ # Themes, shortcuts, priorities
│ ├── types/ # TypeScript definitions │ ├── types/ # TypeScript definitions
── utils/ # Frontend utilities ── utils/ # Frontend utilities
│ └── constants/ # App constants (themes, shortcuts, emojis)
├── build/ # Application icons ├── build/ # Application icons
├── .github/workflows/ # CI/CD automation ├── .github/workflows/ # CI/CD automation
└── dist/ # Build output (generated) └── dist/ # Build output (generated)
``` ```
## Tech Stack
### Backend (Electron Main Process)
- **Electron 28+** - Desktop application framework
- **TypeScript** - Type-safe JavaScript
- **node-pty** - Terminal emulation for shell sessions
- **Fastify** - High-performance web server for remote access
- **electron-store** - Persistent settings storage
### Frontend (Renderer Process)
- **React 18** - UI framework
- **TypeScript** - Type-safe JavaScript
- **Tailwind CSS** - Utility-first CSS framework
- **Vite** - Fast build tool and dev server
- **Lucide React** - Icon library
- **marked** - Markdown rendering
- **react-syntax-highlighter** - Code syntax highlighting
- **ansi-to-html** - Terminal ANSI escape code rendering
- **dompurify** - HTML sanitization for XSS prevention
- **emoji-mart** - Emoji picker component
## Development Scripts ## Development Scripts
```bash ```bash
# Start dev server with hot reload npm run dev # Start dev server with hot reload
npm run dev npm run build # Full production build
npm run build:main # Build main process only
# Build main process only (Electron backend) npm run build:renderer # Build renderer only
npm run build:main npm start # Start built application
npm run clean # Clean build artifacts
# Build renderer only (React frontend) npm run package # Package for all platforms
npm run build:renderer npm run package:mac # Package for macOS
npm run package:win # Package for Windows
# Full production build npm run package:linux # Package for Linux
npm run build
# Start built application
npm start
# Clean build artifacts and cache
npm run clean
``` ```
## Architecture ## Common Development Tasks
### Process Management ### Adding a New UI Feature
Maestro uses a dual-process architecture where **each session runs two processes simultaneously**: 1. **Plan the state** - Determine if it's per-session or global
2. **Add state management** - In `useSettings.ts` (global) or session state
3. **Create persistence** - Use wrapper function pattern for global settings
4. **Implement UI** - Follow Tailwind + theme color pattern
5. **Add keyboard shortcuts** - In `shortcuts.ts` and `App.tsx`
6. **Test focus flow** - Ensure Escape key navigation works
1. **AI Agent Process** - Runs Claude Code as a child process ### Adding a New Modal
2. **Terminal Process** - Runs a PTY shell session for command execution
This architecture enables seamless switching between AI and terminal modes without process restarts. All processes are managed through IPC (Inter-Process Communication) with secure context isolation. 1. Create component in `src/renderer/components/`
2. Add priority in `src/renderer/constants/modalPriorities.ts`:
```typescript
MY_MODAL: 600,
```
3. Register with layer stack (see [ARCHITECTURE.md](ARCHITECTURE.md#layer-stack-system))
4. Use proper ARIA attributes:
```typescript
<div role="dialog" aria-modal="true" aria-label="My Modal">
```
### Security Model ### Adding Keyboard Shortcuts
Maestro implements strict security measures: 1. Add definition in `src/renderer/constants/shortcuts.ts`:
```typescript
myShortcut: { id: 'myShortcut', label: 'My Action', keys: ['Meta', 'k'] },
```
- **Context isolation enabled** - Renderer has no direct Node.js access 2. Add handler in `App.tsx` keyboard event listener:
- **No node integration in renderer** - No `require()` in renderer process ```typescript
- **Secure IPC via preload script** - Minimal API exposed via `contextBridge` else if (isShortcut(e, 'myShortcut')) {
- **No shell injection** - Uses `execFile` instead of `exec` e.preventDefault();
- **Input sanitization** - All user inputs are validated // Handler code
}
```
### Main Process (Backend) **Supported modifiers:** `Meta` (Cmd/Win), `Ctrl`, `Alt`, `Shift`
**Arrow keys:** `ArrowLeft`, `ArrowRight`, `ArrowUp`, `ArrowDown`
Located in `src/main/`: ### Adding a New Setting
- `index.ts` - Application entry point, IPC handler registration, window management 1. Add state in `useSettings.ts`:
- `process-manager.ts` - Core primitive for spawning and managing CLI processes ```typescript
- `web-server.ts` - Fastify-based HTTP/WebSocket server for remote access const [mySetting, setMySettingState] = useState(defaultValue);
- `agent-detector.ts` - Auto-detects available AI tools via PATH ```
- `preload.ts` - Secure IPC bridge via contextBridge
### Renderer Process (Frontend) 2. Create wrapper function:
```typescript
const setMySetting = (value) => {
setMySettingState(value);
window.maestro.settings.set('mySetting', value);
};
```
Located in `src/renderer/`: 3. Load in useEffect:
```typescript
const saved = await window.maestro.settings.get('mySetting');
if (saved !== undefined) setMySettingState(saved);
```
- `App.tsx` - Main UI coordinator 4. Add to return object and export.
- `main.tsx` - Renderer entry point
- `components/` - React components (modals, panels, UI elements) ### Adding a Slash Command
- `hooks/` - Custom React hooks for reusable state logic
- `services/` - Business logic services (clean wrappers around IPC calls) Add to `src/renderer/slashCommands.ts`:
- `constants/` - Application constants (themes, shortcuts, etc.)
```typescript
{
command: '/mycommand',
description: 'Does something useful',
terminalOnly: false, // Optional: restrict to terminal mode
execute: (context) => {
const { activeSessionId, setSessions } = context;
// Your logic
}
}
```
### Adding a New Theme
Add to `src/renderer/constants/themes.ts`:
```typescript
'my-theme': {
id: 'my-theme',
name: 'My Theme',
mode: 'dark', // or 'light'
colors: {
bgMain: '#...',
bgSidebar: '#...',
bgActivity: '#...',
border: '#...',
textMain: '#...',
textDim: '#...',
accent: '#...',
accentDim: 'rgba(...)',
accentText: '#...',
success: '#...',
warning: '#...',
error: '#...',
}
}
```
Then add the ID to `ThemeId` type in `src/renderer/types/index.ts`.
### Adding an IPC Handler
1. Add handler in `src/main/index.ts`:
```typescript
ipcMain.handle('myNamespace:myAction', async (_, arg1, arg2) => {
// Implementation
return result;
});
```
2. Expose in `src/main/preload.ts`:
```typescript
myNamespace: {
myAction: (arg1, arg2) => ipcRenderer.invoke('myNamespace:myAction', arg1, arg2),
},
```
3. Add types to `MaestroAPI` interface in preload.ts.
## Code Style ## Code Style
### TypeScript ### TypeScript
- All code must be TypeScript with strict mode enabled - Strict mode enabled
- Define interfaces for all data structures - Interface definitions for all data structures
- Export types via `preload.ts` for renderer types - Export types via `preload.ts` for renderer
### React Components ### React Components
- Use functional components with hooks - Functional components with hooks
- Keep components small and focused - Keep components focused and small
- Use Tailwind CSS for styling - Use Tailwind for layout, inline styles for theme colors
- Maintain keyboard accessibility - Maintain keyboard accessibility
- Use inline styles for theme colors, Tailwind for layout - Use `tabIndex={-1}` + `outline-none` for programmatic focus
### Architecture Guidelines ### Security
**Main Process:** - **Always use `execFileNoThrow`** for external commands (never shell-based execution)
- Keep IPC handlers simple and focused - Keep context isolation enabled
- Use TypeScript interfaces for all data structures
- Handle errors gracefully
- No blocking operations
**Renderer Process:**
- Use React hooks
- Keep components small and focused
- Use Tailwind for styling
- Maintain keyboard accessibility
**Security:**
- Never expose Node.js APIs to renderer
- Use preload script for all IPC - Use preload script for all IPC
- Sanitize all user inputs - Sanitize all user inputs
- Use `execFile` instead of `exec` - Use `spawn()` with `shell: false`
## Debugging Guide
### Focus Not Working
1. Add `tabIndex={0}` or `tabIndex={-1}` to element
2. Add `outline-none` class to hide focus ring
3. Use `ref={(el) => el?.focus()}` for auto-focus
4. Check for `e.stopPropagation()` blocking events
### Settings Not Persisting
1. Ensure wrapper function calls `window.maestro.settings.set()`
2. Check loading code in `useSettings.ts` useEffect
3. Verify the key name matches in both save and load
### Modal Escape Not Working
1. Register modal with layer stack (don't handle Escape locally)
2. Check priority in `modalPriorities.ts`
3. Use ref pattern to avoid re-registration:
```typescript
const onCloseRef = useRef(onClose);
onCloseRef.current = onClose;
```
### Theme Colors Not Applying
1. Use `style={{ color: theme.colors.textMain }}` instead of Tailwind color classes
2. Check theme prop is passed to component
3. Never use hardcoded hex colors for themed elements
### Process Output Not Showing
1. Check session ID matches (with `-ai` or `-terminal` suffix)
2. Verify `onData` listener is registered
3. Check process spawned successfully (check pid > 0)
4. Look for errors in DevTools console
### DevTools
Open via Quick Actions (`Cmd+K` → "Toggle DevTools") or set `DEBUG=true` env var.
## Commit Messages ## Commit Messages
Use conventional commits: Use conventional commits:
- `feat:` - New features ```
- `fix:` - Bug fixes feat: new feature
- `docs:` - Documentation changes fix: bug fix
- `refactor:` - Code refactoring docs: documentation changes
- `test:` - Test additions/changes refactor: code refactoring
- `chore:` - Build process or tooling changes test: test additions/changes
chore: build process or tooling changes
```
Example: `feat: add context usage visualization` Example: `feat: add context usage visualization`
## Pull Request Process ## Pull Request Process
1. Create a feature branch from `main` 1. Create a feature branch from `main`
2. Make your changes 2. Make your changes following the code style
3. Add tests if applicable 3. Test thoroughly (keyboard navigation, themes, focus)
4. Update documentation 4. Update documentation if needed
5. Submit PR with clear description 5. Submit PR with clear description
6. Wait for review 6. Wait for review
@@ -206,16 +299,14 @@ Example: `feat: add context usage visualization`
### 1. Prepare Icons ### 1. Prepare Icons
Place your application icons in the `build/` directory: Place icons in `build/` directory:
- `icon.icns` - macOS (512x512 or 1024x1024) - `icon.icns` - macOS (512x512 or 1024x1024)
- `icon.ico` - Windows (256x256) - `icon.ico` - Windows (256x256)
- `icon.png` - Linux (512x512) - `icon.png` - Linux (512x512)
### 2. Update Version ### 2. Update Version
Update version in `package.json`: Update in `package.json`:
```json ```json
{ {
"version": "0.1.0" "version": "0.1.0"
@@ -225,42 +316,25 @@ Update version in `package.json`:
### 3. Build Distributables ### 3. Build Distributables
```bash ```bash
# Build for all platforms npm run package # All platforms
npm run package npm run package:mac # macOS (.dmg, .zip)
npm run package:win # Windows (.exe)
# Platform-specific builds npm run package:linux # Linux (.AppImage, .deb, .rpm)
npm run package:mac # Creates .dmg and .zip
npm run package:win # Creates .exe installer
npm run package:linux # Creates .AppImage, .deb, .rpm
``` ```
Output will be in the `release/` directory. Output in `release/` directory.
## GitHub Actions Workflow ### GitHub Actions
The project includes automated builds via GitHub Actions: Create a release tag to trigger automated builds:
1. **Create a release tag:**
```bash
git tag v0.1.0
git push origin v0.1.0
```
2. **GitHub Actions will automatically:**
- Build for macOS, Windows, and Linux
- Create release artifacts
- Publish a GitHub Release with downloads
## Testing
```bash ```bash
# Run tests (when available) git tag v0.1.0
npm test git push origin v0.1.0
# Type checking
npm run build:main
``` ```
GitHub Actions will build for all platforms and create a release.
## Questions? ## Questions?
Open a GitHub Discussion or reach out in Issues. Open a GitHub Discussion or create an Issue.