- Add vite.config.web.mts with dedicated web interface configuration
- Configure build output to dist/web/ directory
- Set up code splitting with React in separate chunk
- Enable source maps for development debugging
- Add dev server proxy for API and WebSocket connections
- Create index.html entry point with mobile-optimized meta tags
- Create main.tsx with device detection for mobile/desktop routing
- Add index.css with Tailwind, CSS custom properties, and animations
- Create placeholder mobile/desktop App components for Phase 1/2
- Update tailwind.config.mjs to include src/web files
Implements a useSessions hook that wraps useWebSocket to provide:
- Real-time session list management with add/remove/update handlers
- Active session tracking and selection
- Session interaction methods (sendCommand, interrupt, switchMode)
- Sessions grouped by tool type
- Client-side state tracking (isSending, lastError) preserved across updates
- Auto-connect option and refresh capability
Add a comprehensive useWebSocket hook that handles:
- WebSocket connection lifecycle (connect, disconnect, reconnect)
- Authentication flow (token-based auth via query param or message)
- Real-time message handling for sessions, themes, and state changes
- Automatic reconnection with configurable attempts and delays
- Heartbeat/ping functionality for connection health
- Full TypeScript support with typed message interfaces
Add Card component with support for multiple variants (default, elevated,
outlined, filled, ghost), padding options, and interactive states.
Includes:
- CardHeader subcomponent for consistent headers with title/subtitle/actions
- CardBody subcomponent for main content with padding control
- CardFooter subcomponent for footer actions with optional border
- SessionCard convenience component for session list items
Supports interactive states (clickable, selected, disabled) with keyboard
navigation and accessibility attributes.
Add Badge component with multiple variants for session states:
- success (green): Ready/idle sessions
- warning (yellow): Agent thinking/busy
- error (red): No connection/error
- connecting (orange with pulse): Connecting state
- info (accent color): Informational badges
- default: Neutral styling
Includes three badge styles (solid, outline, subtle, dot) and
convenience components StatusDot and ModeBadge for common use cases.
Add Input, TextArea, and InputGroup components following the same patterns
as the Button component with theme support via useTheme() hook. Features:
- Three variants: default, filled, ghost
- Three sizes: sm, md, lg
- Error state support with visual feedback
- Icon support (left/right) for Input component
- Auto-resize capability for TextArea
- InputGroup wrapper for label, helper text, and error display
Add Button and IconButton components with theme support:
- Multiple variants: primary, secondary, ghost, danger, success
- Three sizes: sm, md, lg
- Loading state with spinner animation
- Support for left/right icons
- Full width option
- IconButton variant for icon-only buttons
- Uses theme colors via useTheme hook
Add utility module that converts theme colors to CSS custom properties:
- generateCSSProperties(): Creates property map from theme
- generateCSSString(): Outputs CSS with :root selector
- injectCSSProperties(): Adds/updates style element in document head
- removeCSSProperties(): Cleans up injected styles
- setElementCSSProperties(): Applies to specific elements
- cssVar(): Helper for inline style usage
CSS variables use --maestro-* prefix with kebab-case naming
(e.g., theme.colors.bgMain -> --maestro-bg-main).
ThemeProvider now automatically injects CSS properties when theme
changes, enabling CSS-based theming alongside React context.
- Add src/web/components/ThemeProvider.tsx with React context for theming
- Provide useTheme and useThemeColors hooks for child components
- Include default theme (Dracula) for initial render before WebSocket connection
- Update tsconfig.json to include src/web and src/shared directories
- Create src/shared/theme-types.ts with Theme, ThemeId, ThemeMode, ThemeColors types
- Add isValidThemeId type guard utility function
- Update renderer types to re-export from shared location
- Update main process themes.ts to use shared types
- Update web-server.ts to import Theme from shared instead of defining WebTheme
- This enables the web interface build to access theme types without duplicating code
Added a new REST API endpoint at /api/theme that returns the currently
configured theme. The endpoint:
- Is protected by token-based authentication (if enabled)
- Is rate limited using GET rate limit config
- Returns the theme object with all color values
- Returns 503 if theme service not configured
- Returns 404 if no theme is currently set
Add REST API endpoint to send SIGINT/Ctrl+C signal to sessions via the web interface.
This allows mobile and desktop web clients to gracefully interrupt running AI agents
or terminal processes.
- Add InterruptSessionCallback type for session interrupt operations
- Add setInterruptSessionCallback method to WebServer class
- Create /api/session/:id/interrupt POST endpoint with authentication and rate limiting
- Wire up callback in main process to use ProcessManager.interrupt()
Add POST endpoint to send commands to active sessions via the web API:
- Add WriteToSessionCallback type for session input
- Implement /api/session/:id/send endpoint with rate limiting (POST limits)
- Validate command presence and type before processing
- Check session exists before attempting to write
- Wire up callback in index.ts using processManager.write()
- Add SessionDetail interface with extended session fields (aiLogs, shellLogs, usageStats, claudeSessionId, isGitRepo)
- Add GetSessionDetailCallback type and setGetSessionDetailCallback method
- Implement /api/session/:id endpoint with authentication and rate limiting
- Returns 404 for non-existent sessions, 503 if callback not configured
- Wire up callback in index.ts to fetch session data from sessions store
- Update header comments to reflect current implementation status
Updated the /api/sessions endpoint to use the getSessionsCallback
to return real session data instead of an empty array placeholder.
Added authentication and rate limiting to the endpoint.
- Install @fastify/rate-limit package
- Configure rate limiting with sensible defaults:
- 100 requests/minute for GET endpoints
- 30 requests/minute for POST endpoints (more restrictive)
- Add RateLimitConfig interface for configuration
- Apply rate limiting to all /web/* routes
- Add /web/api/rate-limit endpoint to check current limits
- Skip rate limiting for /health endpoint
- Custom error response with retry-after information
- Support for X-Forwarded-For header for proxied requests
Added broadcastThemeChange method to WebServer class and integrated
it with the settings:set IPC handler to automatically notify all
connected web clients when the user switches themes in the desktop app.
- Add WebTheme type and GetThemeCallback to web-server.ts
- Add setGetThemeCallback method to WebServer class
- Send theme after sessions list on initial connection
- Send theme after auth success for authenticated clients
- Create src/main/themes.ts with all theme definitions for main process
- Wire up theme callback in index.ts using getThemeById helper
Added real-time session state broadcasting to the web interface:
- Added broadcastSessionStateChange() method to broadcast when session state,
name, or input mode changes
- Added broadcastSessionAdded() and broadcastSessionRemoved() methods for
tracking session lifecycle
- Added broadcastSessionsList() method for bulk session sync
- Modified sessions:setAll IPC handler to detect session changes and broadcast
them to all authenticated web clients
- Added setGetSessionsCallback() to allow web server to fetch current sessions
- Send initial sessions_list to newly connected/authenticated web clients
- Only broadcast to authenticated clients for security
WebSocket message types added:
- session_state_change: { type, sessionId, state, name?, toolType?, inputMode?, cwd?, timestamp }
- session_added: { type, session, timestamp }
- session_removed: { type, sessionId, timestamp }
- sessions_list: { type, sessions, timestamp }
- Added new WebSocket endpoint at /ws/web for web interface clients
- Implemented client connection tracking with unique client IDs
- Added connection/disconnection event handling with logging
- Added message handling for ping/pong, subscribe, and echo
- Added broadcastToWebClients() method for real-time updates
- Added getWebClientCount() method for monitoring connected clients
- Imported WebSocket from 'ws' for readyState checks
- Added WebClient and WebClientMessage type definitions
Created dedicated web interface route namespace in WebServer class:
- /web - Root endpoint returning available interfaces info
- /web/desktop - Desktop web interface entry point (placeholder)
- /web/desktop/* - Wildcard for client-side routing
- /web/mobile - Mobile web interface entry point (placeholder)
- /web/mobile/* - Wildcard for client-side routing
- /web/api - Web API namespace root with endpoint discovery
This establishes the foundation for the new web interface that will
provide both desktop (collaborative) and mobile (remote control)
access to Maestro sessions.
- Add delivery checkmark for user messages when AI responds
- Display AI commands with styled header showing command name and description
- Show full interpolated prompt below the command header
- Fix template variable substitution to happen before prompt display
- Improve hover states for copy/speak buttons
Claude ID: 24a6cdd6-27a7-41e0-af30-679cc2ffe66b
Maestro ID: 5a166b38-b7e9-47f0-a8ff-0113c65f2682
- History activity graph now uses sliding time window that adjusts as
you scroll, showing activity relative to the visible entries rather
than always anchored to "now"
- Session ID pill now opens on hover instead of click for faster access
- Added hover timeout and invisible bridge for smooth tooltip behavior
Claude ID: 24a6cdd6-27a7-41e0-af30-679cc2ffe66b
Maestro ID: 5a166b38-b7e9-47f0-a8ff-0113c65f2682
- Add user-defined session names stored with Claude session origins
- Display session names in AgentSessionsBrowser with tag icon
- Add "Named only" filter to quickly find named sessions
- Include session names in search across title and content modes
- Sync session names when renaming sessions in the sidebar
- Fix macOS code signing with ad-hoc signatures in release workflow
- Fix electron-builder CLI syntax (--config.extraMetadata)
- Improve lightbox navigation with context-aware image arrays
- Fix GitLogViewer search input focus handling
- Improve AI command prompt display with multi-line clamp
Claude ID: 24a6cdd6-27a7-41e0-af30-679cc2ffe66b
Maestro ID: 5a166b38-b7e9-47f0-a8ff-0113c65f2682
- Add template variable system with substitution for session, project,
date/time, and git context (e.g., {{SESSION_NAME}}, {{GIT_BRANCH}})
- Display collapsible template variables documentation in AI Commands panel
- Update default /commit command to include {{CLAUDE_SESSION_ID}} for traceability
- Add tag icon indicator for sessions with custom (user-defined) names
- Improve Git Log Viewer date formatting (time for today, full date for older)
- Improve Git Log search UX with better focus handling
- Change Agent Sessions Browser default search mode to 'all'
- Update README with custom AI commands documentation
- Add template variable file reference to CLAUDE.md
Session: 35b88ae2-fc1a-44de-a1a1-4b0f0f5a14f9
- Add bookmark feature to sessions (star icon on hover, dedicated
Bookmarks section at top of Left Bar when bookmarks exist)
- Improve GitHub release workflow to handle partial build failures
gracefully (continue-on-error for each platform)
- Fix input placeholder spacing ("Ask Claude about" instead of
"askClaudeAbout")
- Update README to document bookmark functionality
The addHistoryEntry helper function was not generating a unique ID for
history entries. This caused all USER-type entries to have undefined IDs,
which meant when the delete handler filtered by entry.id !== entryId, all
entries with undefined IDs would match and be deleted together.
Added generateId() call to ensure each history entry has a unique ID.
Moved the batch run progress indicator from Scratchpad to RightPanel,
so it now persists at the bottom of all three tabs (Files, History,
Scratchpad) when auto mode is active.
- Add elapsedTimeMs field to HistoryEntry interface to track task duration
- Update useBatchProcessor to capture and pass usage stats (tokens, context,
cost) and elapsed time when adding history entries for auto-run tasks
- Enhance HistoryDetailModal with a comprehensive stats panel that shows:
- Context window progress bar with percentage
- Token breakdown (input/output/cache tokens)
- Elapsed time in human-readable format
- Cost per task
- Update main process HistoryEntry interface to match renderer types
This enables users to track resource usage for each auto-run task iteration
in the history details view.
Documents the implementation plan for adding parallel task execution
to the Auto Runner feature. Key concepts:
- Git worktrees for isolated working directories per task
- Configurable concurrency (default: 3 workers)
- UI toggle for serial vs parallel mode
- Merge strategies and conflict handling
- Resource considerations and cleanup
This enables significant speedup when batch tasks are independent,
reducing total execution time from N*T to approximately T (where N
is task count and T is average task duration).
The batch processor was incorrectly overwriting the main session's
claudeSessionId when batch tasks completed. This caused the main panel
to display the batch task's session ID instead of the interactive
session's ID.
Fix: Remove claudeSessionId from the setSessions update when batch tasks
exit. The batch task's claudeSessionId is still returned via the Promise
resolve for tracking/history purposes, but it no longer contaminates
the interactive session state.
- Added new store (maestro-claude-session-origins) to track which Claude
sessions were created via Maestro and whether they were user-initiated
or auto-batch sessions
- Added IPC handlers for registering and retrieving session origins
- Updated App.tsx to register user-initiated sessions when receiving
Claude session IDs (non-batch sessions)
- Updated useBatchProcessor.ts to register auto/batch sessions
- Updated claude:listSessions to include origin type in returned data
- Updated AgentSessionsBrowser.tsx to display colored origin pills:
- MAESTRO (accent color): user-initiated through Maestro
- AUTO (warning color): batch/auto sessions through Maestro
- CLI (dim): sessions created via Claude Code command line
When viewing a Claude session's details, users now see a comprehensive
stats panel showing:
- Cost (with 4 decimal precision)
- Duration (calculated from first to last message timestamps)
- Total tokens with context window percentage (based on 200k)
- Message count
- Token breakdown: input, output, cache read, cache write
- File size and session start time
Extended ClaudeSession interface with token details (inputTokens,
outputTokens, cacheReadTokens, cacheCreationTokens) and durationSeconds.
Backend now calculates duration by parsing first and last timestamps
from the session file.
- Added Star icon import and starredSessions state
- Load starred sessions from settings on component mount
- Added toggleStar function to toggle and persist star status
- Modified filteredSessions to sort starred sessions to the top
- Added star button UI to each session in the list
- Starred sessions are persisted per-project in settings
This matches the functionality already in AgentSessionsModal.tsx
- Add processCarriageReturns() to handle terminal line overwrites (fixes
Claude Code status line "In: X Out: Y" not updating in real-time)
- Apply carriage return processing to both AI and terminal mode output
- Add usage stats extraction for stream-json mode (when images are used)
- The carriage return fix ensures status lines that use \r for in-place
updates display only the final state, not all intermediate updates
- Add starred/favorite sessions in Agent Sessions modal (persisted per-project)
- Add recent Claude sessions hover tooltip on Agent Sessions button for quick access
- Remember window size, position, and maximized/fullscreen state across restarts
- Fix light theme text colors for user message bubbles in chat views
- Fix auto-scroll to pause when user has expanded log entries
- Move history graph tooltip below the graph to avoid overlap
- Adjust warning colors in vibe mode themes for better contrast
- Use Python 3.11 for macOS builds (Python 3.12+ removed distutils module needed by node-gyp)
- Add author email to package.json (required for Linux .deb package maintainer field)
- Shows all agents with active tunnels in a scrollable list
- Each entry displays agent name and group name
- Click agent name to jump to that session
- Click localhost link to open local server
- Click ngrok link (if available) to open public tunnel URL
- Move Pedurple and Maestro's Choice to new Vibe Mode section
- Change Pedurple's third color from orange to pinkish violet (#da70d6)
- Redesign Maestro's Choice: elegant dark theme with gold accents
- Add Dre Synth: 80s synthwave with hot pink, cyan, and deep purple
- Add InQuest: stark black/red/white security aesthetic
- Themes panel now shows Dark Mode, Light Mode, and Vibe Mode sections
- Show actual time range (e.g., '2PM - 3PM') instead of 'X hours ago'
- Display Auto and User counts on separate lines for clarity
- Better visual formatting with labels and values aligned
- Initialize panelWidth to Infinity so widgets show before ResizeObserver fires
- Get initial width immediately on mount
- Widgets were hidden because initial state was 0, failing the > 500/600 checks
- Optimize atBottomStateChange to only update state when value changes
- Disable auto-scroll when user has expanded log entries
- Memoize toggleExpanded, toggleLocalFilter, and setLocalFilterQuery callbacks
- Reduces unnecessary re-renders that caused button blinking