Skip to content

Laundry List of Fixes#6

Merged
pedramamini merged 72 commits intomainfrom
pedrams-list-20251127
Nov 29, 2025
Merged

Laundry List of Fixes#6
pedramamini merged 72 commits intomainfrom
pedrams-list-20251127

Conversation

@pedramamini
Copy link
Collaborator

  • MAESTRO: Fix token tracking to use modelUsage for accurate context window
  • MAESTRO: Disable scratchpad Run button when AI agent is thinking
  • MAESTRO: Reduce scratchpad preview font size from default to 13px
  • MAESTRO: Add multi-select filtering to system logs viewer
  • MAESTRO: Preserve keyboard position in Claude session list after viewing details
  • MAESTRO: Add naming and renaming functionality to Claude session list
  • MAESTRO: Display real-time active processes in System Processes view
  • MAESTRO: Hide queued AI messages from CLI terminal view
  • MAESTRO: Remove search capability from Git log viewer
  • MAESTRO: Include vibe themes in Tab key theme cycling
  • MAESTRO: Add expand/collapse toggle for truncated queued messages
  • MAESTRO: Change Pedurple theme accent color from gold to bright pink
  • MAESTRO: Apply scrollbar-thin styling to main panel Virtuoso component
  • MAESTRO: Use spacebar instead of left arrow to collapse folders in sidebar
  • MAESTRO: Ignore leading emojis when alphabetizing sessions in left sidebar
  • MAESTRO: Add hover overlay to collapsed group folder indicators
  • MAESTRO: Add collapsed indicator palette to bookmarks group in sidebar
  • MAESTRO: Add detailed TTS logging for debugging speak functionality
  • MAESTRO: Add image paste and preview support to scratchpad
  • MAESTRO: Move copy/delete buttons side-by-side on CLI terminal commands
  • MAESTRO: Fix bullet rendering in markdown previews
  • MAESTRO: Add tab completion for shell command input
  • MAESTRO: Add splash screen with logo and progress bar during app startup
  • MAESTRO: Preserve AI context when command is interrupted
  • MAESTRO: Unify bookmark/star terminology to use stars consistently
  • MAESTRO: Fix session renaming to persist in Claude session list view
  • MAESTRO: Reset activeClaudeSessionId when opening Claude sessions browser
  • MAESTRO: Display session name in recent sessions overlay
  • MAESTRO: Fix Git overlay borders to match other overlays
  • MAESTRO: Improve overlay UX with timeout delays and invisible bridges
  • MAESTRO: Add delete capability for AI message-response pairs
  • MAESTRO: Show leading bookmark icon only for bookmarked sessions
  • MAESTRO: Enable CMD+SHIFT+[] to cycle within bookmarks folder when open
  • MAESTRO: Fix Git log viewer search functionality
  • MAESTRO: Add search functionality to scratchpad
  • MAESTRO: Add template variables dropdown to Auto Runner prompt
  • MAESTRO: Improve AI commands settings with scrollable preview and larger edit view
  • MAESTRO: Persist recent Claude sessions per Maestro session

…ndow

The Claude Code CLI JSON output has two different token count sections:
- `usage`: Shows billable/new tokens only (excludes cache hits)
- `modelUsage`: Contains per-model breakdown with actual context tokens

Previously, we were reading from `usage.input_tokens` which showed only new
tokens (e.g., 2 tokens) instead of the full context (e.g., 3,241 tokens).

This fix aggregates token counts from modelUsage to properly track:
- Total input tokens in context (including cache reads)
- Total output tokens
- Cache read and creation tokens
- Context window size from each model

The fix applies to both batch mode JSON parsing and stream-json mode.
Falls back to top-level usage if modelUsage isn't available for backwards
compatibility with older CLI versions.
The Run button in the scratchpad panel is now greyed out when the
session state is 'busy' or 'connecting', preventing users from
starting batch runs while the agent may be making changes.
Changed the log level filter from single-select to multi-select toggle behavior:
- Each level button (debug, info, warn, error, toast) now toggles on/off independently
- The "ALL" button toggles all levels on or off
- All levels are selected by default when opening the log viewer
…ing details

When pressing Escape to return from session details to list view:
- Focus is restored to search input for continued keyboard navigation
- Selected item scroll position is maintained
- selectedIndex is preserved so arrow key navigation resumes from the same position

This allows users to browse sessions with Enter, examine details, press Escape,
and continue navigating down the list without losing their place.
Added inline editing for session names in the Claude session browser:
- Sessions can be named/renamed from the list view via pencil icon on hover
- Sessions can be named/renamed from the details view header
- Existing session names display with tag icon and edit button
- Sessions without names show an add name button on hover
- Names are persisted via the updateSessionName IPC API
- Enter saves, Escape cancels, blur also saves
- Add process:getActiveProcesses IPC handler to expose ProcessManager's running processes
- Update preload.ts to expose getActiveProcesses API method
- Rewrite ProcessMonitor to fetch and display actual running processes from ProcessManager
- Parse process session IDs to match them to their Maestro sessions (handles -ai, -terminal, -batch suffixes)
- Show batch mode processes when auto-runner is active
- Add refresh button and 2-second polling for real-time updates
- Show active process count badge on sessions and in header
Added condition to only show queued messages section when inputMode is 'ai',
preventing AI queued messages from appearing on the CLI terminal side.
Removed the non-functional search feature from GitLogViewer:
- Removed search input field and related state (searchQuery, isSearchFocused)
- Removed filter logic for entries based on search query
- Removed '/' keyboard shortcut for focusing search
- Updated UI to display entries directly without filtering
- Cleaned up unused imports (Search, X from lucide-react)
The theme picker's Tab key cycling was only including dark and light themes.
Updated to cycle through dark → light → vibe → dark as expected.
Queued AI messages are truncated to 200 characters for display. This adds
a Show all/Show less toggle button that allows users to view the full
content of long queued messages and collapse them back down.
Updated the Pedurple vibe theme's accent color from gold (#d4af37) to
hot pink (#ff69b4) so the third color in the theme palette preview
displays as bright pink. Also swapped the warning color to use the
previous gold accent for visual balance.
Added scrollbar-thin class to the Virtuoso component in TerminalOutput.tsx
to match the beautiful scrollbar styling used in the left and right sidebars.
…debar

Changed the keyboard shortcut for collapsing group folders in the left
sidebar from the left arrow key to the spacebar for better ergonomics.
…debar

Added helper functions to strip leading emojis from session and group names
before comparing for alphabetical sorting. This ensures names like "🎉 My Project"
are sorted by the text portion ("My Project") rather than by the emoji's Unicode
codepoint.

Changes made to:
- SessionList.tsx: Added stripLeadingEmojis and compareSessionNames helpers
- App.tsx: Added compareNamesIgnoringEmojis for sortedSessions calculation
- useSessionManager.ts: Added same helpers for session sorting hook
When a group folder in the left sidebar is collapsed, hovering over
individual session indicator dots now shows a detailed overlay with
session name, state, tool type, context usage, git changes, cost,
active time, and working directory - matching the behavior of the
skinny sidebar mode. Clicking an indicator selects that session.
When the bookmarks section in the left sidebar is collapsed, it now shows
the same indicator widget palette as other group folders. Each bookmarked
session appears as a colored dot based on its state, with hover tooltips
showing session details including name, state, context usage, git status,
session cost, and active time.
Include text content preview, full command arguments, and execution details
in system logs to help debug TTS issues. Logs now show:
- Incoming request with command, text length, and text preview (up to 200 chars)
- Executing command with executable, args count, and full args (text truncated to 100 chars)
- Success/error states with relevant context
- Changed context from 'Notification' to 'TTS' for easier filtering
- Add IPC handlers for per-session attachment storage (save, load, delete, list)
- Images stored in userData/attachments/{sessionId}/ directory
- Add paste handler that saves images and inserts markdown reference
- Add image upload button in edit mode
- Custom AttachmentImage component loads images from session storage
- Image cache to avoid repeated IPC calls
- Thumbnail preview of attached images in edit mode
- Lightbox for full-size image viewing
- Uses maestro-attachment:// protocol for referencing stored images
- Images are session-specific so no overlap between Maestro sessions
- Also fixed bullet rendering in markdown preview (added list-style-type)
Previously, the delete button was positioned at top-right and the copy
button at bottom-right. For short terminal commands (single line), these
positions would overlap causing the buttons to appear on top of each other.

Now both buttons are placed together in the action buttons container at
bottom-right, arranged side-by-side with proper spacing.
Tailwind's preflight reset removes list-style from ul/ol elements.
Added explicit list styling with !important to the global CSS to
restore bullet points (disc, circle, square) and numbered lists
(decimal, lower-alpha, lower-roman) in prose containers.
Implements primitive tab completion for the terminal mode shell command
input box with two sources of suggestions:

1. Shell command history - matches previous commands that start with
   the current input
2. File tree - matches files and folders in the current directory,
   supporting path-based completion (e.g., "cd src/comp" matches files
   in src/ starting with "comp")

Features:
- Tab key opens the completion dropdown when in terminal mode
- Single match auto-completes immediately
- Multiple matches show a dropdown with icons (history, folder, file)
- Arrow keys navigate suggestions, Tab/Enter confirms, Escape cancels
- Dropdown closes automatically when switching input modes
- Add native HTML/CSS splash screen that appears immediately on app load
- Display centered Maestro logo (wand icon in purple rounded rectangle)
- Show "MAESTRO" title text in JetBrains Mono font matching sidebar styling
- Add animated progress bar that fills while app initializes
- Preload Google Fonts to prevent Flash of Unstyled Text (FOUT)
- Implement fade-out animation when React app finishes loading
- Add TypeScript type declarations for splash screen global functions
- Trigger splash screen hide when initial data load completes in App.tsx
Switch Claude Code from --output-format json to stream-json mode so that
the session_id is captured early in the response stream rather than only
at process exit. This ensures that when a user interrupts an AI command,
the next command can still --resume the same Claude session, preserving
all context including the interrupted partial response.

Changes:
- Updated agent-detector.ts to use stream-json output format with --verbose
- Updated process-manager.ts to detect stream-json mode from args
- Simplified image handling since base args now include stream-json output
Changed the session pill in the main panel header bar to use "Star Session"
and "Unstar Session" instead of "Bookmark Session" and "Remove Bookmark".
Now uses the same per-project storage key (starredClaudeSessions:${cwd})
as the AgentSessionsBrowser for consistency across components.
When renaming a session from the main panel's session pill, the name
was only being saved to local settings (namedClaudeSessions) but not
to the backend storage (claudeSessionOriginsStore). This caused renamed
sessions to not show their names in the Claude session list view.

Now calls window.maestro.claude.updateSessionName() to persist the name
to the backend, matching the behavior of renaming from AgentSessionsBrowser.
…wser

When opening the Claude sessions browser from the button, keyboard shortcut,
or quick actions modal, the activeClaudeSessionId is now reset to null. This
ensures the browser always opens to the list view rather than auto-jumping to
a previously viewed session's details pane.

The auto-jump behavior is preserved only when explicitly navigating to a
specific session (e.g., from the recent sessions overlay), where
activeClaudeSessionId is intentionally set before opening the browser.
- Added sessionName field to RecentClaudeSession interface
- Updated onResumeClaudeSession signature to accept optional sessionName parameter
- Modified AgentSessionsBrowser to pass sessionName when resuming a session
- Enhanced recent sessions overlay display to show session name prominently
  when available, with first message as secondary info below the name
Changed border styling from separate borderColor/border properties to
the shorthand border format with inline color. The previous approach
of setting borderColor and then border: '1px solid' was causing white
borders because the shorthand property resets the color component.

Fixed in:
- MainPanel.tsx (Git pill tooltip overlay)
- GitDiffViewer.tsx (modal dialog)
- GitStatusWidget.tsx (hover tooltip)
- Add 150ms close timeout to all hover overlays (git, context, sessions, session pill)
- Add invisible bridge divs with pointer-events-auto to span the gap between triggers and overlays
- Convert GitStatusWidget from CSS group-hover to JavaScript state management for better control
- Add proper mouse enter/leave handlers on overlay content to maintain open state when mouse reaches it
- Fix pointer-events handling so overlays stay open when mousing from trigger to dropdown

This fixes the issue where overlays would vanish when trying to move the mouse to interact with them.
@claude
Copy link

claude bot commented Nov 29, 2025

Pull Request Review

Overview

This PR introduces 37 significant features and fixes across 59 files with ~5,770 additions. The scope is very large, which increases review complexity and merge risk.

Strengths

  • Security-conscious: Proper use of execFileNoThrow for external commands
  • Well-structured IPC: New handlers follow existing patterns with proper error handling
  • Good UX improvements: Tab completion, splash screen, image paste support
  • Proper TypeScript typing: New APIs are well-typed in preload.ts

Notable implementations:

  • Tab completion hook: Clean implementation with history + file tree integration
  • Attachment API: Per-session image storage with proper caching
  • Global stats streaming: Progressive updates during calculation
  • Message deletion with fallback: Smart UUID + content matching

CRITICAL Issues

1. Path Traversal Vulnerability in Attachments API

Location: src/main/index.ts:2339-2369

The attachments API doesn't sanitize sessionId or filename parameters. Malicious values like ../../../etc/passwd could write files outside the intended directory.

Fix: Use path.basename() and reject filenames containing .. or path separators.

Same issue in: attachments:load, attachments:delete, attachments:list

2. TTS Command Injection Potential

Location: src/main/index.ts:2262-2335

User-provided command string is split and spawned without validation.

Fix: Whitelist allowed commands: say, espeak, festival

Performance Issues

3. Global Stats Reads All Files Synchronously

Location: src/main/index.ts:1562-1588

Reading thousands of large JSONL files could block the main process.

Recommendations:

  • Add timeout/cancellation
  • Process in batches with setImmediate
  • Add max file size checks

4. Regex Performance in Global Stats

Location: src/main/index.ts:1585-1595

Running 6+ regex passes over multi-MB files is inefficient.

Better: Single pass with JSON.parse per line

Other Issues

  1. Message deletion lacks ownership validation (src/main/index.ts:1747-1850)
  2. Hardcoded pricing will become outdated (src/main/index.ts:1500-1505)
  3. History callback lacks pagination (src/main/index.ts:263-281)
  4. Inline splash screen script could violate CSP (src/renderer/index.html:137-178)

Testing Recommendations

  1. Security: Try path traversal attacks on attachment API
  2. Performance: Test global stats with 100+ Claude sessions
  3. Edge cases: Malformed JSONL, symlinks, locked files
  4. Integration: Verify web server changes with mobile clients
  5. Regression: Test existing features (large surface area)

Verdict

Conditionally Approve - Features are valuable and mostly well-implemented, but the path traversal vulnerability MUST be fixed before merging.

Before Merge

  1. FIX CRITICAL: Path traversal in all 4 attachment handlers
  2. ADD: TTS command whitelist validation
  3. ADD: Timeout for global stats operation
  4. CONSIDER: Split into smaller PRs for easier review

Great work on the comprehensive feature additions!

…etion

- Added BatchCompleteInfo interface to useBatchProcessor hook
- Added onComplete callback prop to useBatchProcessor
- Track batch start time to calculate elapsed duration
- Call onComplete with session info, task counts, and timing when batch finishes
- In App.tsx, pass onComplete callback that shows toast notification:
  - Success toast when all tasks completed
  - Warning toast when batch was stopped early
  - Info toast for partial completions
  - Includes group name, project name, and elapsed time
… with issue tag and image analysis instructions
@claude
Copy link

claude bot commented Nov 29, 2025

Pull Request Review: Laundry List of Fixes

Thank you for this comprehensive PR! Overall, the code quality is excellent with strong attention to security and UX.

Strengths

Security Best Practices

  • Excellent use of execFileNoThrow for all git operations preventing command injection
  • Safe attachment handling with proper path validation
  • Proper input sanitization with DOMPurify

Code Quality

  • Strong TypeScript usage with proper interfaces
  • Comprehensive error handling with logging context
  • Follows CLAUDE.md patterns consistently

Areas for Improvement

1. TTS Command Parsing - Security Risk (Medium)

src/main/index.ts:2278-2288 - The TTS command parsing uses regex on user-provided strings which could execute arbitrary code.

Recommendations:

  • Validate executable is in an allowlist (say, espeak, festival)
  • Use safer config format (JSON with executable and args fields)
  • Add warning in settings UI about command injection risks

2. Global Stats Performance (Low)

src/main/index.ts:1500-1665 - Reads ALL .jsonl files with regex matching on entire contents. Could block for minutes on large workspaces.

Recommendations:

  • Add timeout/cancellation mechanism
  • Stream file reads instead of loading entire files
  • Add progress indicator in UI
  • Cache results with TTL

3. Delete Message Pair Edge Cases (Low)

src/main/index.ts:1752-1849 - Fallback content matching could delete wrong pair if duplicate messages exist.

Recommendations:

  • Add timestamp to match criteria
  • Log warning for duplicate content

4. Attachment File Size Limits (Low)

src/main/index.ts:2342-2376 - No validation on base64 image size before writing.

Recommendation: Add max file size check (10MB) to prevent disk exhaustion.

5. Tab Completion Performance (Low)

src/renderer/hooks/useTabCompletion.ts:20-43 - Recursive tree traversal on every render could lag with 10k+ files.

Recommendation: Limit depth or cache more aggressively.

Minor Issues

  • Splash screen progress caps at 70% then jumps to 100%
  • Line 2351 regex doesn't handle image/svg+xml
  • TTS has 5+ logger calls per operation

Testing Recommendations

  1. TTS Security: Test with malicious input
  2. Global Stats: Test with 100+ sessions
  3. Attachments: Test with 50MB+ images
  4. Delete Message: Test duplicate messages
  5. Tab Completion: Test with 10k+ files

Test Coverage Note

No test files added for new features. Consider adding:

  • Unit tests for parseDataUrl
  • Unit tests for TTS command parsing
  • Integration tests for attachment CRUD
  • Tests for message deletion edge cases

Summary

Overall: LGTM with minor recommendations

High-quality PR with excellent security practices. Main concerns:

  1. TTS command injection risk (recommend fixing before merge)
  2. Global stats performance (can be addressed in follow-up)
  3. Missing tests (can be addressed in follow-up)

Great work on UX improvements!

@claude
Copy link

claude bot commented Nov 29, 2025

Pull Request Review: Laundry List of Fixes

This is a substantial PR with 5,852 additions and 1,143 deletions across 60 files. The changes include numerous feature additions, bug fixes, and UX improvements. Here's my comprehensive review:

🎯 Overall Assessment

Verdict: Approve with Minor Recommendations

This PR demonstrates solid engineering practices with proper security considerations, thoughtful architecture, and adherence to the project's coding conventions. The changes are well-structured and add significant value.


✅ Strengths

1. Security Practices

  • ✅ Consistent use of execFileNoThrow utility instead of shell-based command execution (prevents command injection)
  • ✅ Web server uses token-based authentication with UUID regeneration on restart
  • ✅ Rate limiting implemented for web endpoints (100 req/min for GET, 50 for POST)
  • ✅ Proper CORS configuration in web server
  • ✅ Attachments stored with session-based isolation

2. Code Quality

  • ✅ Follows established patterns from CLAUDE.md (layer stack registration, settings persistence, theme colors)
  • ✅ Proper TypeScript typing throughout
  • ✅ Good separation of concerns (main/renderer processes)
  • ✅ Consistent error handling with try-catch and proper logging

3. Architecture

  • ✅ Token tracking fix properly uses modelUsage aggregation (lines 317-358 in process-manager.ts)
  • ✅ Image cache implementation in Scratchpad prevents redundant IPC calls
  • ✅ Tab completion hook well-designed with proper memoization
  • ✅ Web server architecture supports mobile clients with WebSocket streaming

4. UX Improvements

  • ✅ Numerous quality-of-life features (tab completion, image paste, search, etc.)
  • ✅ Consistent use of overlay timeouts and invisible bridges for smooth UX
  • ✅ Proper keyboard navigation and focus management

⚠️ Issues & Recommendations

🔴 High Priority

1. Missing Test Coverage

Location: Entire codebase
Issue: No test files found (.test.ts, .spec.ts)

Recommendation:

// Add tests for critical paths, e.g.:
// src/renderer/hooks/useTabCompletion.test.ts
describe('useTabCompletion', () => {
  it('should suggest files from file tree', () => {
    // test implementation
  });
  
  it('should suggest from shell history', () => {
    // test implementation
  });
});

Rationale: With 60 files changed, automated tests would catch regressions. Priority areas:

  • deleteMessagePair logic (file parsing/deletion)
  • Tab completion path resolution
  • Token usage aggregation
  • Image cache management

2. Potential Memory Leak in Image Cache

Location: src/renderer/components/Scratchpad.tsx:35

// Cache for loaded images to avoid repeated IPC calls
const imageCache = new Map<string, string>();

Issue: Global cache never cleared, will grow indefinitely as users work with images

Recommendation:

// Add LRU cache with size limit
import LRU from 'lru-cache';

const imageCache = new LRU<string, string>({
  max: 100, // Max 100 images
  maxSize: 50 * 1024 * 1024, // Max 50MB
  sizeCalculation: (value) => value.length,
});

Or implement manual cleanup when sessions close.

🟡 Medium Priority

3. Error Handling in deleteMessagePair

Location: src/main/index.ts:1747-1852

Issue: Content-based fallback matching could delete wrong message if duplicates exist

// Lines 1801-1820: Searches from end for matching content
if (messageText.trim() === normalizedFallback) {
  userMessageIndex = i;
  logger.info('Found message by content match', 'ClaudeSessions', { sessionId, index: i });
  break;
}

Recommendation:

  • Add warning to user when using content-based fallback
  • Consider adding timestamp proximity check to improve match accuracy
  • Log both UUID and content hash for debugging

4. Incomplete Error Comments

Location: src/renderer/App.tsx:4103

log.text / Fallback: match by content if UUID doesn't match

Issue: This appears to be a malformed comment (should be //)

Fix:

log.text // Fallback: match by content if UUID doesn't match

5. Magic Numbers in Global Stats Calculation

Location: src/main/index.ts:1504-1510

const inputCost = (input / 1_000_000) * 3;
const outputCost = (output / 1_000_000) * 15;
const cacheReadCost = (cacheRead / 1_000_000) * 0.30;
const cacheCreationCost = (cacheCreation / 1_000_000) * 3.75;

Recommendation: Extract to constants

const PRICING = {
  INPUT_TOKEN_COST: 3.00,    // per 1M tokens
  OUTPUT_TOKEN_COST: 15.00,  // per 1M tokens
  CACHE_READ_COST: 0.30,     // per 1M tokens
  CACHE_CREATION_COST: 3.75, // per 1M tokens
} as const;

This makes pricing updates easier and documents the API costs.

🟢 Low Priority

6. Performance: Global Stats Streaming

Location: src/main/index.ts:1497-1667

Observation: Stats calculation sends update after EVERY project directory

Recommendation: Throttle updates to reduce IPC overhead:

let updateCounter = 0;
const UPDATE_FREQUENCY = 10; // Send update every 10 projects

if (++updateCounter % UPDATE_FREQUENCY === 0) {
  sendUpdate({...});
}

7. Console.log Statements

Location: Multiple files (e.g., process-manager.ts:357)

console.log('[ProcessManager] Emitting usage stats from stream-json:', usageStats);

Recommendation: Replace with logger calls for consistency:

logger.debug('Emitting usage stats from stream-json', 'ProcessManager', usageStats);

8. Theme Color Count Update

Location: ARCHITECTURE.md:422, CLAUDE.md:139

Good catch! Theme colors updated from 12 to 13 (added accentForeground). Documentation updated correctly. ✅


🎨 Code Style Observations

Positive:

  • Consistent use of inline styles for theme colors (not Tailwind classes)
  • Proper layer stack registration in modals
  • Settings properly persisted via window.maestro.settings.set()
  • Good use of TypeScript as const for immutable objects

Minor Nitpicks:

  • Some files have 700+ lines (e.g., Scratchpad.tsx - consider splitting)
  • Mix of function components and hooks could benefit from more composition

🔒 Security Deep Dive

Excellent security posture overall:

  1. Command Injection Prevention: All git/shell commands use execFileNoThrow
  2. XSS Prevention: React escapes content by default; markdown renderer uses react-markdown (safe)
  3. Path Traversal: File operations use path.join() with proper validation
  4. Authentication: Web server requires UUID token in all routes
  5. Rate Limiting: Prevents DoS on web endpoints

One concern:

  • File Deletion in deleteMessagePair: Directly overwrites .jsonl files. Consider atomic write pattern:
    const tempFile = sessionFile + '.tmp';
    await fs.writeFile(tempFile, newContent);
    await fs.rename(tempFile, sessionFile);

📊 Performance Considerations

Good:

  • ✅ Image caching reduces IPC calls
  • ✅ Tab completion properly memoized
  • ✅ Process polling at 2s intervals (reasonable)
  • ✅ Virtuoso for log rendering (handles long outputs)

Watch:

  • ⚠️ Global stats iterates ALL Claude projects - could be slow with many sessions
  • ⚠️ Image cache unbounded growth (mentioned above)

🧪 Test Coverage Recommendations

Given no existing tests, prioritize:

  1. Critical Business Logic:

    • Token usage calculation and aggregation
    • Message deletion with UUID/content fallback
    • Tab completion path resolution
  2. Security-Sensitive Functions:

    • execFileNoThrow wrapper
    • Web server token validation
    • Attachment file path handling
  3. Complex UI Interactions:

    • Layer stack priority ordering
    • Modal escape key handling
    • Batch runner state management

📝 Documentation

Strengths:

  • ✅ ARCHITECTURE.md updated with new APIs
  • ✅ CLAUDE.md updated with theme color count
  • ✅ Inline comments explain complex logic (e.g., modelUsage aggregation)

Suggestions:

  • Document the image cache strategy (when/how it's cleared)
  • Add JSDoc to deleteMessagePair explaining UUID vs content matching
  • Document global stats streaming behavior for API consumers

🎯 Conclusion

This is a well-executed PR that adds significant functionality while maintaining code quality and security standards. The issues identified are minor and can be addressed in follow-up work.

Merge Recommendation: APPROVE

Post-Merge TODO:

  1. Add test coverage for critical paths
  2. Implement LRU cache for images
  3. Extract pricing constants
  4. Fix malformed comment on line 4103
  5. Consider atomic writes for file deletions

Great work on this release! The attention to security (execFileNoThrow everywhere), UX polish (overlays, delays, smooth interactions), and architectural consistency is impressive. 🎉

@claude
Copy link

claude bot commented Nov 29, 2025

Pull Request Review

This is a comprehensive PR with 60 files changed covering many improvements. Here's my detailed feedback:

Overall Assessment

This is a well-structured PR with solid improvements. The code quality is generally good, but there are some security, performance, and architectural concerns to address.


🔴 Critical Issues

1. Command Injection Risk in TTS (src/main/index.ts:2295-2320)

The TTS implementation spawns shell commands based on user-provided input without proper validation:

const fullCommand = command || 'say';
const parts = fullCommand.split(' ');
const ttsCommand = parts[0];
const ttsArgs = [...parts.slice(1), text];

Risk: If command contains malicious input like "; rm -rf /", this could execute arbitrary commands.

Recommendation:

  • Whitelist allowed TTS commands
  • Use execFileNoThrow instead of spawn for better security
  • Validate/sanitize all command inputs

2. Unvalidated User Input in Attachment Filenames (src/main/index.ts:2365-2402)

const filePath = path.join(attachmentsDir, finalFilename);

Risk: Path traversal vulnerability if filename contains ../ sequences.

Recommendation: Add filename sanitization:

const sanitizeFilename = (name: string) => {
  return name.replace(/[^a-zA-Z0-9._-]/g, '_').replace(/\.\./g, '_');
};

3. Missing Error Handling in Claude Session Deletion (src/main/index.ts:1750-1852)

The deleteMessagePair function modifies JSONL files with fallback content matching but lacks transaction safety. If the write fails midway, data could be corrupted.

Recommendation:

  • Use atomic writes (write to temp file, then rename)
  • Add backup mechanism before modifying session files

⚠️ High Priority Issues

4. Performance: Blocking I/O in Global Stats (src/main/index.ts:1497-1664)

Reading entire session files into memory and using regex on large strings is inefficient and could freeze the main process.

Recommendation:

  • Stream file processing line-by-line
  • Add debouncing/throttling to progress updates
  • Consider moving to a worker thread for CPU-intensive work

5. Memory Leak Risk in Web Server (src/main/web-server.ts:1161-1168)

Dead WebSocket connections aren't cleaned up. If readyState is not OPEN, the client stays in the map indefinitely.

Recommendation: Add cleanup logic to remove closed connections during broadcast.

6. Race Condition in Session Busy Check (src/main/web-server.ts:1025-1034)

Session state could change between the busy check and command execution (TOCTOU - Time of Check, Time of Use).

Recommendation: Move busy check into the command execution callback for atomic state management.


🟡 Medium Priority Issues

7. Inconsistent Error Handling in Tab Completion

src/renderer/hooks/useTabCompletion.ts doesn't handle cases where session.fileTree exists but contains invalid data.

Recommendation: Add defensive checks and error boundaries.

8. Toast Log Level Overload (src/main/utils/logger.ts:6, 26)

Adding 'toast' as a log level mixes UI concerns with logging levels. Toast notifications are presentational, not a severity level.

Recommendation: Keep toast notifications separate from log levels. Use info level with a type: 'toast' metadata field instead.

9. Console.log Debugging in Production (src/main/web-server.ts:1184, 1195)

Debug console.log statements should be replaced with proper logger calls or removed.

10. Missing Input Validation on Web Commands (src/main/web-server.ts:1041)

While there's a busy check, there's no validation of command content (length, characters, etc.).

Recommendation: Add command length and content validation.


📝 Code Quality Improvements

11. Magic Numbers

  • Line 1497: Token cost calculations - Extract constants
  • Line 18 in logger.ts: maxLogs = 1000 - Make configurable

12. Type Safety

  • src/main/web-server.ts:947: JSON.parse needs schema validation with Zod or similar
  • Several 'as' type assertions could be replaced with proper type guards

13. Documentation

  • The new web-server.ts file is well-documented ✅
  • useTabCompletion.ts could use JSDoc comments for exported functions
  • Claude session manipulation functions need more detailed comments about file format assumptions

Positive Highlights

  1. Security Token Architecture (web-server.ts): Good security model with UUID tokens
  2. Rate Limiting: Proper implementation with configurable limits
  3. Streaming Updates: Global stats streaming is a nice UX touch
  4. Code Organization: Clear separation of concerns in web server
  5. Consistent Patterns: Follows existing codebase conventions (per CLAUDE.md)
  6. Comprehensive Logging: Good use of structured logging throughout

🧪 Testing Recommendations

  1. Security Tests:

    • Test attachment upload with '../../../etc/passwd' filename
    • Test TTS with malicious command strings
    • Test WebSocket message injection
  2. Performance Tests:

    • Test global stats with 1000+ Claude sessions
    • Test WebSocket broadcast with 100+ clients
    • Test tab completion with 10,000+ files
  3. Integration Tests:

    • Test concurrent web + desktop commands
    • Test session deletion during active conversation
    • Test WebSocket reconnection handling

📋 Action Items

Must Fix Before Merge:

  1. ❗ Fix command injection in TTS (Issue Internal Logging #1)
  2. ❗ Fix path traversal in attachments (Issue Add Claude Code GitHub Workflow #2)
  3. ❗ Add atomic writes for Claude session modification (Issue Raychaser/claude path 01 #3)

Should Fix:
4. Add dead connection cleanup (Issue #5)
5. Fix race condition in busy check (Issue #6)
6. Stream large file processing (Issue #4)

Nice to Have:
7. Remove console.log statements (Issue #9)
8. Extract magic numbers to constants (Issue #11)
9. Add input validation on web commands (Issue #10)


📊 Test Coverage

Please ensure tests cover:

  • Attachment upload/download/delete with edge cases
  • Claude session message deletion (by UUID and content)
  • Global stats calculation with various project sizes
  • Tab completion with special characters in paths
  • WebSocket message handling for all new message types
  • Web server security token validation

🎯 Conclusion

This PR adds significant value with mobile support, tab completion, session management, and many UX improvements. The code structure is solid, but critical security issues must be addressed before merging. Once the command injection and path traversal vulnerabilities are fixed, this will be a great addition.

Recommendation: Request changes for security fixes, then approve.

Estimated Effort to Fix Critical Issues: 2-4 hours

@claude
Copy link

claude bot commented Nov 29, 2025

Pull Request Review - PR 6

This is a substantial PR with 38 commits adding many improvements and features to Maestro. Overall code quality is good, but there are several areas that need attention.

Strengths

  1. Excellent Commit Granularity - Each commit addresses a single concern with descriptive messages
  2. Security-Conscious - Uses execFileNoThrow, proper path.join(), isolated session storage
  3. Stream-JSON Mode - Well-implemented transition that preserves context on interrupt
  4. Web Server Integration - Good WebSocket broadcasting for mobile interface

Critical Issues

1. Missing Input Validation (HIGH)

File: src/main/index.ts

Attachments API - No validation:

  • No file size limit (could cause OOM)
  • No filename sanitization (path traversal risk)
  • No MIME type validation

TTS Command - Missing allowlist validation

Fix: Add filename sanitization, 10MB size limit, command allowlist

2. Race Condition (MEDIUM)

File: src/main/index.ts (claude:getGlobalStats)

Window could be destroyed between check and send. Multiple concurrent calls will interleave updates.

Fix: Add try-catch, use debouncing/locking

3. Silent Error Handling (MEDIUM)

File: src/main/index.ts (deleteMessagePair)

Catches JSON parse errors silently without logging.

Fix: Add proper error logging

Code Quality

Positive:

  • Strong TypeScript usage
  • Good separation of concerns
  • Follows CLAUDE.md conventions

Improvements Needed:

  • Extract duplicate emoji-stripping logic to utils
  • Break up long functions (claude:getGlobalStats is 175 lines)
  • Use named constants instead of magic numbers
  • Standardize error return patterns

Performance

Global Stats Calculation:

  • Reads ALL Claude sessions across ALL projects
  • Could block main process for 10+ seconds with many sessions
  • Recommendation: Move to worker thread, add caching

Testing

Missing tests for:

  • Attachments API edge cases
  • Message deletion fallback matching
  • Stream-JSON parsing with malformed input
  • Corrupted JSONL handling

Security Summary

Issue Severity
File size validation HIGH
Filename sanitization HIGH
TTS command validation MEDIUM

Verdict

APPROVE WITH CHANGES

Great work on this PR! The features are well-designed and the code quality is solid. However, input validation issues must be fixed before merge.

Must fix before merge:

  1. Filename sanitization in attachments
  2. File size limits (10MB)
  3. TTS command allowlist
  4. Error logging in deleteMessagePair

Estimated effort: 2-4 hours

…simplification

Scratchpad lightbox enhancements:
- Add navigation between images with ←/→ arrows
- Add copy to clipboard and delete buttons
- Support keyboard navigation (arrow keys, Delete/Backspace, ESC)
- Show image counter and navigation hints

Collapsed sidebar improvements:
- Add menu overlay when sidebar is collapsed
- Access shortcuts help, settings, logs, process monitor, and about

Terminal output:
- Move delivery checkmark to end of action buttons

Mobile web interface simplification:
- Remove command history drawer and recent command chips
- Simplify layout with fixed 100dvh height
- Remove input expansion behavior on small screens
- Make AutoRun indicator more prominent with bold colors and larger text
@claude
Copy link

claude bot commented Nov 29, 2025

PR Review: Laundry List of Fixes

This is a comprehensive PR with 60 files changed (+6108/-1267 lines) containing 37 distinct features and fixes. Overall, the changes are well-implemented with good attention to detail. Below is a structured review covering code quality, potential issues, performance, security, and testing.


Strengths

Code Quality

  • Consistent adherence to CLAUDE.md conventions - proper use of IPC patterns, theme colors via inline styles, and standardized terminology
  • Good TypeScript typing - proper interfaces for new features (TabCompletionSuggestion, AttachmentImage props, etc.)
  • Proper security practices - uses execFileNoThrow for command execution (follows security guidelines)
  • Well-organized code structure - new hooks (useTabCompletion, useMobileLandscape) follow established patterns
  • Thoughtful UX improvements - splash screen, tab completion, image paste support, overlay timeouts

Architecture

  • Clean separation of concerns - new web server callbacks properly abstracted
  • Good state management - proper use of React hooks and context
  • Event-driven design - streaming updates for global stats calculation

⚠️ Issues & Concerns

1. Performance - File Operations (High Priority)

src/main/index.ts:1500-1665 - claude:getGlobalStats

Issues:

  • Reads entire JSONL files into memory for regex matching
  • Could cause memory issues with large session files (100MB+)
  • Blocks event loop during processing despite streaming updates
  • Regex on full file content is inefficient

Recommendation:
Use streaming line-by-line processing instead of loading entire files into memory.

2. Security - Path Traversal (Medium Priority)

src/main/index.ts:1764 - claude:deleteMessagePair

Issues:

  • projectPath from renderer is not validated
  • sessionId could contain path traversal sequences
  • Missing path sanitization before filesystem operations

Recommendation:
Add input validation and ensure resolved paths stay within expected directories.

3. Bug - Content Matching Collision (Medium Priority)

src/main/index.ts:1790-1815 - Fallback content matching

Issue:

  • If a user sends identical messages multiple times, this will match the LAST occurrence
  • Could delete wrong message pair in sessions with duplicate content

Recommendation:

  • Add timestamp proximity check or require UUID for deletion
  • Warn users if multiple matches found

4. Resource Leak - Image Cache (Low Priority)

src/renderer/components/Scratchpad.tsx:34

Issue:

  • Global cache with no size limit or eviction policy
  • Base64 image data URLs can be very large (several MB each)
  • Could cause memory bloat in long-running sessions
  • Never cleared even when sessions are deleted

Recommendation:
Add cache size limit and LRU eviction policy (e.g., 50 images or 100MB max).

5. Code Organization - PR Size (Process Issue)

60 files changed, 37 features

Concerns:

  • Extremely difficult to review thoroughly
  • High risk of bugs slipping through
  • Harder to track down issues later

Recommendation:
Break into smaller PRs grouped by feature area for future work


🔍 Potential Bugs

6. Race Condition - Tab Completion

src/renderer/hooks/useTabCompletion.ts:22-43

  • useMemo depends on session?.fileTree which updates frequently
  • Could cause stale suggestions if file tree updates mid-typing

7. Error Handling - Attachment Operations

src/main/index.ts:2344-2400

  • Attachment operations don't handle disk full scenarios
  • No quota limits per session
  • Missing cleanup when sessions are deleted

8. Type Safety - Theme Colors

ARCHITECTURE.md:420 & src/main/themes.ts

  • Added 13th theme color (accentForeground) but existing themes may not have it
  • Runtime errors possible if older theme definitions loaded

🎯 Performance Considerations

Positive

  • ✅ Streaming updates for global stats (prevents UI freeze)
  • ✅ Image caching reduces IPC round-trips
  • ✅ Tab completion properly memoized
  • ✅ WebSocket broadcast for mobile instead of polling

Needs Improvement

  • ⚠️ matchAll regex on large file content (use streaming)
  • ⚠️ Unbounded image cache (add LRU eviction)

🧪 Test Coverage

Missing Tests:

  1. ❌ Tab completion edge cases
  2. ❌ Claude message deletion (content matching collisions, UUID fallback)
  3. ❌ Global stats calculation (large files, malformed JSON)
  4. ❌ Attachment operations (quota limits, invalid formats)
  5. ❌ Web server rate limiting and WebSocket handling
  6. ❌ Theme migration for new accentForeground color

🔒 Security Assessment

Critical

  • ⚠️ Path traversal in claude:deleteMessagePair (needs validation)

Good Practices

  • ✅ Uses execFileNoThrow for TTS commands
  • ✅ Proper CORS and rate limiting in web server
  • ✅ No shell injection vulnerabilities

📝 Recommendations Summary

Must Fix Before Merge

  1. Add path validation to claude:deleteMessagePair and other file operations
  2. Fix content matching in message deletion (handle duplicates or require UUID)
  3. Add image cache eviction policy to prevent memory bloat

Should Fix Soon

  1. Optimize global stats to use streaming instead of loading entire files
  2. Add attachment cleanup when sessions are deleted
  3. Break large PRs into smaller chunks for future work

Nice to Have

  1. Add tests for new features
  2. Add theme migration for new accentForeground color
  3. Document new IPC APIs in ARCHITECTURE.md

Conclusion

This PR delivers significant value with 37 user-facing improvements. The code quality is generally high and follows project conventions well. However, the PR size makes thorough review challenging and there are 3 critical issues that should be addressed before merge:

  1. Path traversal vulnerability in file operations
  2. Performance issues with large file processing
  3. Resource leak in image cache

Recommendation: Fix the critical issues, then consider merging with a plan to address performance optimizations and add test coverage in follow-up PRs. For future work, please break large feature sets into smaller, focused PRs (5-10 files max).

Great work overall! The features are well-thought-out and the implementation quality is solid. 🚀

- Change TTS to pipe text via stdin for better compatibility
- Add ability to stop TTS playback mid-speech (stop button in Settings and TerminalOutput)
- Add session selection sync from mobile web interface to desktop
- Fix group lookup to use session.groupId instead of searching sessionIds
- Add loading spinner for global stats in AboutModal
- Format cost numbers with locale-aware formatting

Claude ID: 6d45561a-5ae7-4043-8af1-1f6eb349af4e
Maestro ID: 5a166b38-b7e9-47f0-a8ff-0113c65f2682
@claude
Copy link

claude bot commented Nov 29, 2025

Code Review: Laundry List of Fixes

This is an extensive PR with 60 files changed (+6,407/-1,316 lines) covering a wide range of features and improvements. Overall, the code quality is good with well-structured additions. Here's my detailed review:


Strengths

1. Excellent Security Practices

  • ✅ TTS implementation properly uses stdin pipe instead of command arguments, preventing injection vulnerabilities
  • ✅ Image handling with stream-json uses structured JSON format (not shell commands)
  • ✅ Attachment API validates file paths and uses proper path joining
  • ✅ Web server maintains security token protection throughout
  • ✅ Follows the codebase pattern of using execFileNoThrow where applicable

2. Good Architecture Decisions

  • Token tracking fix (src/main/process-manager.ts:318-460): Using modelUsage instead of top-level usage is the correct approach for accurate context window tracking
  • ✅ Centralized command execution through renderer maintains single source of truth
  • ✅ Web server callbacks properly forward to desktop logic for state management
  • ✅ Process manager cleanly separates PTY vs child_process handling

3. Code Quality

  • ✅ Comprehensive logging throughout for debugging
  • ✅ TypeScript interfaces properly defined
  • ✅ Error handling with try-catch blocks
  • ✅ Follows existing code conventions

⚠️ Issues & Recommendations

CRITICAL: Security Concerns

1. TTS Process Management - Potential Resource Leak (src/main/index.ts:2280-2410)

Issue: TTS processes are tracked in activeTtsProcesses Map but may not be cleaned up if the app crashes or processes fail silently.

Location: src/main/index.ts:2280

Recommendation:

// Add cleanup on app shutdown
app.on('before-quit', () => {
  for (const [id, { process }] of activeTtsProcesses) {
    try {
      process.kill('SIGTERM');
    } catch (err) {
      logger.error('Failed to kill TTS process on shutdown', 'TTS', err);
    }
  }
  activeTtsProcesses.clear();
});

2. Missing Input Validation on Attachments (src/main/index.ts:1844-1969)

Issue: File size limits not enforced. A malicious/buggy client could fill disk with large base64 images.

Location: src/main/index.ts:1844

Recommendation:

// Add size limit check (e.g., 10MB)
const MAX_ATTACHMENT_SIZE = 10 * 1024 * 1024;
const buffer = Buffer.from(base64Match[2], 'base64');
if (buffer.length > MAX_ATTACHMENT_SIZE) {
  return { success: false, error: 'Attachment too large (max 10MB)' };
}

HIGH: Potential Bugs

3. Message Deletion Content Matching May Fail (src/main/index.ts:1821-1825)

Issue: Content-based fallback matching uses exact string comparison but doesn't account for whitespace normalization differences.

Location: src/main/index.ts:1821

Problem:

if (messageText.trim() === normalizedFallback) {  // May miss messages with different whitespace

Recommendation: Consider normalizing both sides more aggressively (collapse multiple spaces, normalize newlines).

4. Race Condition in Global Stats Calculation (src/main/index.ts:1511-1679)

Issue: If claude:getGlobalStats is called multiple times concurrently, multiple iterations happen without coordination.

Location: src/main/index.ts:1511

Recommendation: Add a mutex/flag to prevent concurrent execution:

let globalStatsRunning = false;
ipcMain.handle('claude:getGlobalStats', async () => {
  if (globalStatsRunning) {
    throw new Error('Global stats calculation already in progress');
  }
  globalStatsRunning = true;
  try {
    // ... existing code
  } finally {
    globalStatsRunning = false;
  }
});

5. Incomplete Error Handling in Process Manager (src/main/process-manager.ts:492-507)

Issue: Stream-json message writing to stdin doesn't handle write errors.

Location: src/main/process-manager.ts:500

Current:

childProcess.stdin?.write(streamJsonMessage + '\n');
childProcess.stdin?.end();

Should be:

if (childProcess.stdin) {
  childProcess.stdin.on('error', (err) => {
    console.error('[ProcessManager] stdin write error:', err);
    this.emit('data', sessionId, `[error] Failed to send message: ${err.message}`);
  });
  childProcess.stdin.write(streamJsonMessage + '\n');
  childProcess.stdin.end();
}

MEDIUM: Performance & Best Practices

6. Inefficient File Reading in Global Stats (src/main/index.ts:1588)

Issue: Reads entire file content into memory with regex matching. For large .jsonl files (hundreds of MB), this could cause memory issues.

Location: src/main/index.ts:1588

Recommendation: Use streaming line reader or process file in chunks:

// Consider using readline or stream processing for large files
import * as readline from 'readline';
const fileStream = fs.createReadStream(filePath);
const rl = readline.createInterface({ input: fileStream });
for await (const line of rl) {
  // Process line by line
}

7. Excessive Console Logging in Production (src/main/process-manager.ts)

Issue: Many console.log calls throughout process manager will spam production logs.

Recommendation: Use the logger utility consistently:

// Instead of: console.log('[ProcessManager] ...')
logger.debug('Message', 'ProcessManager', { data });

8. No Rate Limiting on Delete Operations (src/main/index.ts:1764)

Issue: claude:deleteMessagePair has no throttling. Client could spam deletes.

Recommendation: Add debouncing or rate limiting to destructive operations.

LOW: Code Quality

9. Magic Numbers (src/main/process-manager.ts:326, 429)

Location: contextWindow = 200000; // Default for Claude

Recommendation: Extract to named constants:

const DEFAULT_CLAUDE_CONTEXT_WINDOW = 200000;

10. Inconsistent Error Messages (src/main/index.ts:1771)

Issue: Returns both { success: false, error: string } and throws exceptions across different handlers.

Recommendation: Standardize error handling pattern across all IPC handlers.


📊 Testing Recommendations

Missing Test Coverage:

  1. Token aggregation logic - Test that modelUsage is correctly summed across multiple models
  2. Message deletion - Test UUID matching, content fallback, and edge cases
  3. TTS interruption - Test that processes are properly killed
  4. Attachment size limits - Test file size validation
  5. Global stats - Test with large .jsonl files (>100MB)
  6. Stream-json with images - Test base64 parsing edge cases

Integration Tests Needed:

  • Web server command flow (web client → web server → renderer → process manager)
  • Multi-session state synchronization across desktop and web clients
  • Error propagation through the callback chain

🎯 Summary

Overall Assessment: ✅ Approve with recommendations

This PR delivers substantial functionality improvements and follows good security practices. The critical issues are primarily about resource management and defensive programming rather than fundamental design flaws.

Priority Actions (Before Merge):

  1. 🔴 Add attachment size validation (prevents disk filling)
  2. 🔴 Add TTS process cleanup on app shutdown
  3. 🟡 Add mutex to global stats (prevent concurrent runs)
  4. 🟡 Handle stdin write errors in stream-json mode

Post-Merge Improvements:

  • Replace console.log with logger utility
  • Add unit tests for token aggregation and message deletion
  • Consider streaming for large file processing
  • Standardize error handling patterns

Good work on this extensive update! The codebase follows security best practices and the architectural decisions are sound. The recommended fixes are mostly defensive programming improvements.

Session cycling (Cmd+Shift+{/}) now correctly follows the visual order
of sessions as they appear in the sidebar: bookmarks section first,
then groups (alphabetically), then ungrouped sessions. Bookmarked
sessions can now be cycled through in both their bookmark position
and their regular group/ungrouped position, matching the visual layout.

Claude ID: 34a8dd77-d500-4237-b4c0-3a1606c9338a
Maestro ID: 5a166b38-b7e9-47f0-a8ff-0113c65f2682
Simplify cost display formatting in history views for better readability.
Currency values are more conventionally shown with 2 decimal places.

Claude ID: 34a8dd77-d500-4237-b4c0-3a1606c9338a
Maestro ID: 5a166b38-b7e9-47f0-a8ff-0113c65f2682
@claude
Copy link

claude bot commented Nov 29, 2025

Pull Request Review - PR #6

This is a comprehensive PR with 37 commits and 6,463 additions covering numerous features and improvements. Overall, the code quality is good, but I've identified several areas requiring attention.


Critical Issues

1. Security: File System Path Traversal Vulnerability

Location: src/main/index.ts:1416-1440

The attachments:save handler is vulnerable to path traversal attacks. A malicious filename like ../../.ssh/id_rsa could write files outside the intended directory.

Fix Required:

  • Sanitize filename using path.basename() and character whitelisting
  • Verify resolved path is within attachmentsDir before writing
  • Apply same fix to attachments:load and attachments:delete

2. Security: Unbounded Memory Growth in TTS Process Tracking

Location: src/main/index.ts:2281-2286

The activeTtsProcesses Map never cleans up on error events, causing memory leaks in long-running apps.

Fix Required:

  • Add activeTtsProcesses.delete(ttsId) in the error handler (currently missing)
  • Consider periodic cleanup of stale entries

3. Performance: Global Stats Computation Blocks Main Thread

Location: src/main/index.ts:1514-1679

The claude:getGlobalStats handler performs intensive synchronous regex operations on large JSONL files, blocking the event loop.

Recommendations:

  • Move computation to a worker thread or use streaming line-by-line parsing
  • Add timeout/cancellation support
  • Consider caching results with invalidation on file changes

High Priority Issues

4. Error Handling: Silent Failures in Message Deletion

Location: src/main/index.ts:1764-1866

Malformed JSONL entries are silently preserved in claude:deleteMessagePair, which may cause data corruption. Add warning logs for malformed entries.

5. Race Condition: Attachment Cache Not Thread-Safe

Location: src/renderer/components/Scratchpad.tsx:34

The global imageCache Map stores strings, not promises, allowing concurrent requests to trigger duplicate IPC calls. Cache promises instead.

6. Incomplete Cleanup: Web Server Callbacks Not Unregistered

Location: src/main/index.ts:221-282

Multiple server.setXCallback() calls create closures but are never cleaned up on app shutdown.


Medium Priority Issues

  1. Code Quality: Inconsistent stream-JSON mode detection
  2. UX: Missing loading/cancel UI for global stats calculation
  3. Type Safety: AutoRun state uses inline types instead of shared interface
  4. Testing: Zero test coverage for new features (attachments, message deletion, global stats, TTS)

Positive Observations

  • Excellent TTS debugging logs
  • Good error messages with actionable context
  • Follows conventions: uses execFileNoThrow, proper IPC patterns
  • Documentation properly updated
  • Well-formatted commit messages
  • Great UX improvements

Testing Checklist

Before merging, verify:

  • Test attachments with malicious filenames
  • Run global stats on 1000+ sessions
  • Test TTS interruption/restart scenarios
  • Verify JSONL message deletion integrity
  • Test attachment cache with concurrent requests
  • Confirm no memory leaks after extended use

Recommendation

Conditional approval pending security fixes.

Issues #1 and #2 must be addressed before merge. Issue #3 should be tracked for future optimization.

Overall, this is a solid feature-rich PR that significantly improves Maestro. Great work!


Review by Claude Code Agent

- Remove bullet points from markdown checkbox list items in FilePreview
  and Scratchpad for cleaner task list appearance
- Move opacity hover transition from container to individual session
  indicators in collapsed bookmarks/groups palettes for better feedback

Claude ID: aa1bea17-be18-4561-a1bb-56e7bf71cda2
Maestro ID: 5a166b38-b7e9-47f0-a8ff-0113c65f2682
@claude
Copy link

claude bot commented Nov 29, 2025

Code Review - PR #6: Laundry List of Fixes

Summary

This is a substantial PR with 6,467 additions and 1,335 deletions across 59 files. The changes introduce many valuable features including image paste support, tab completion, global Claude stats, message deletion, TTS improvements, and web server enhancements. Overall, the code quality is good with proper security practices in place.

✅ Strengths

Security

  • Excellent use of execFileNoThrow: All Git and shell commands properly use the secure execFile wrapper to prevent command injection vulnerabilities
  • Web server security: Token-based authentication with UUID regeneration on restart provides good security for the web interface
  • Rate limiting: Web server includes rate limiting configuration to prevent abuse

Code Quality

  • Well-structured IPC handlers: Clear separation of concerns with appropriate error handling
  • Comprehensive logging: Good use of the logger throughout with appropriate context
  • Theme system: Proper extension to support 13 colors including new accentForeground for better contrast
  • Type safety: Good TypeScript usage with proper interfaces

🔍 Issues & Concerns

1. Performance - Global Stats Calculation ⚠️ HIGH PRIORITY

Location: src/main/index.ts:1514-1680

The claude:getGlobalStats handler reads and parses ALL Claude session files across ALL projects using regex pattern matching:

const inputMatches = content.matchAll(/"input_tokens"\s*:\s*(\d+)/g);

Issues:

  • Reading entire large files into memory (await fs.readFile(filePath, 'utf-8'))
  • Regex matching on potentially multi-MB JSONL files
  • Blocking operation that could freeze the main process for users with many sessions
  • No timeout or cancellation mechanism

Recommendation:

  • Add a timeout mechanism
  • Consider limiting max files to process
  • Add progress feedback in the UI
  • Consider caching results with TTL

2. TTS Process Management ⚠️ MEDIUM PRIORITY

Location: src/main/index.ts:2279-2372

const activeTtsProcesses = new Map<number, { process: ..., command: string }>();
let ttsProcessIdCounter = 0;

Issues:

  • Process counter could overflow (though unlikely in practice)
  • No cleanup of old map entries if processes fail silently
  • SIGTERM might not work on all platforms

Recommendation:

  • Add periodic cleanup of completed processes from the map
  • Consider platform-specific kill strategies
  • Add max concurrent TTS limit to prevent resource exhaustion

3. Message Deletion Logic ⚠️ MEDIUM PRIORITY

Location: src/main/index.ts:1764-1867

The claude:deleteMessagePair function:

  1. Reads entire session file
  2. Parses all lines
  3. Searches linearly (O(n)) for matches
  4. Rewrites entire file

Issues:

  • No atomic write (potential data loss if app crashes during write)
  • No backup before destructive operation
  • Linear search with content fallback could be slow for large sessions
  • No validation that the deleted content is actually a complete pair

Recommendation:

  • Use atomic file write pattern (write to temp, then rename)
  • Add file backup before deletion
  • Consider adding undo capability
  • Validate response completeness before deletion

4. Attachment Storage ⚠️ LOW PRIORITY

Location: src/main/index.ts:2409-2508

Issues:

  • No size limits on uploaded images
  • No cleanup of attachments when sessions are deleted
  • No file type validation beyond extension check
  • Could accumulate orphaned files over time

Recommendation:

  • Add max file size limit (e.g., 10MB)
  • Implement cleanup on session deletion
  • Validate file magic bytes, not just extensions
  • Add storage quota per session

5. Missing Test Coverage ⚠️ HIGH PRIORITY

Finding: No test files found in the codebase

Recommendation:

  • Add unit tests for critical functions:
    • execFileNoThrow
    • Message deletion logic
    • Stats calculation
    • Tab completion
  • Add integration tests for IPC handlers
  • Consider E2E tests for critical user flows

6. Scratchpad Image Cache ⚠️ LOW PRIORITY

Location: src/renderer/components/Scratchpad.tsx:34

const imageCache = new Map<string, string>();

Issues:

  • Global cache never cleared - could grow unbounded
  • Stores full base64 data URLs in memory
  • No size limit

Recommendation:

  • Add LRU cache with size limit
  • Clear cache when session is closed
  • Consider lazy loading for large images

🎯 Specific Code Issues

Path Encoding Issue

Location: src/main/index.ts:1778

const encodedPath = projectPath.replace(/\//g, '-');

Issue: Simple character replacement is not a robust encoding strategy. Paths like /foo/bar and -foo-bar would collide.

Recommendation: Use proper encoding like base64 or URL encoding.

Regex Token Extraction

Location: src/main/index.ts:1595-1606

const inputMatches = content.matchAll(/"input_tokens"\s*:\s*(\d+)/g);

Issue: Regex parsing of JSON is fragile and could miss valid tokens or match inside strings.

Recommendation: Parse JSONL line-by-line properly with JSON.parse, then extract fields.

Missing Error Boundaries

Location: Multiple React components

Issue: No error boundaries to catch rendering errors in new features like image preview, tab completion UI.

Recommendation: Add error boundaries around new complex UI components.

📊 Best Practices Applied ✅

  1. Follows CLAUDE.md conventions: Uses correct terminology (Left Bar, Right Bar, AI Terminal)
  2. Settings persistence: Properly implemented in useSettings.ts
  3. Modal layer stack: Correctly registers modals with priorities
  4. Theme colors: Properly uses inline styles for theme colors
  5. IPC security: All IPC handlers properly validated

🔧 Minor Suggestions

  1. Add JSDoc comments to complex functions like deleteMessagePair, getGlobalStats
  2. Extract magic numbers: Token pricing constants should be in a config file
  3. Add TypeScript strict null checks where missing
  4. Consider debouncing tab completion to avoid excessive computations
  5. Add telemetry for new features to understand usage patterns

Overall Assessment

Rating: ⭐⭐⭐⭐ (4/5)

This PR adds significant value with many user-requested features. The code quality is generally good with proper security practices. The main concerns are:

  1. Performance of global stats calculation
  2. Data safety in message deletion
  3. Missing tests for critical functionality

Recommendation: Approve with requested changes

The high-priority items (performance, tests, atomic writes) should be addressed before or shortly after merge. The medium/low priority items can be tracked as follow-up issues.


Great work on this comprehensive update! The features look solid, just need some hardening around edge cases and performance. 🚀

@pedramamini pedramamini merged commit e0712ed into main Nov 29, 2025
1 check passed
@pedramamini pedramamini deleted the pedrams-list-20251127 branch November 29, 2025 03:00
This was referenced Dec 14, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

Comments