Skip to content

Comments

0.15.0 rc#282

Merged
pedramamini merged 327 commits intomainfrom
0.15.0-rc
Feb 3, 2026
Merged

0.15.0 rc#282
pedramamini merged 327 commits intomainfrom
0.15.0-rc

Conversation

@pedramamini
Copy link
Collaborator

No description provided.

chr1syy and others added 30 commits January 27, 2026 11:37
- Ensure prompts for remote SSH agents are sent via stdin as JSON in stream-json mode, fixing agent crashes with large prompts
- Always run background synopsis (history tab) on the correct remote host by propagating SSH config from the main session
- Improve wizard error handling: treat nonzero agent exit codes as success if output parses as a valid response, preventing false error states in confidence-building chat
- General reliability improvements for remote agent session management and output parsing
… remote git IPC handlers

- Ensure remoteCwd is set for all remote git operations (isRepo, status, diff, branch, remote, numstat, tags, branches, info)
- Resolves warning about missing remote working directory
- Enables correct git repo detection and status for remote directories in wizard and agent flows
- Remove unrelated husky and lint-staged dev dependencies
- Fix Windows path encoding in session storage (handle backslashes)
- Add debug logging to empty catch blocks for better diagnostics
- Add type guard validation for JSON parsing in output parser
Implements #165 - adds a third "sticky" mode for the thinking toggle
that keeps thinking content visible after the response completes.

- Add ThinkingMode type ('off' | 'on' | 'sticky') to shared types
- Update settings modal with three-position toggle button group
- Update thinking pill UI to show pin icon for sticky mode
- Update Cmd+Shift+K to cycle through all three states
- Add visual differentiation: off (dim), on (accent), sticky (warning+pin)
- Maintain backward compatibility for legacy boolean settings

Closes #165
The automatic synopsis triggered on process exit was using a short
hardcoded prompt that didn't include anti-caveat instructions. This
caused the agent to add unhelpful preambles like "I don't have any
record of previous work in this session" in toast notifications.

Now uses autorunSynopsisPrompt which includes instructions to jump
straight to the accomplishment without session context caveats.
When creating 3+ phase documents for a single effort, agents should now place them in a dedicated subdirectory for easier organization and batch addition.
- types.ts: ProcessListenerDependencies interface and type re-exports.
- data-listener.ts: Process output streaming with group chat buffering.
- exit-listener.ts: Process exit handling with routing, recovery, synthesis.
- session-id-listener.ts: Agent session ID tracking for group chat.
- usage-listener.ts: Token/cost statistics for participants and moderator.
- error-listener.ts: Agent error logging and forwarding.
- stats-listener.ts: Query-complete events for stats database.
- forwarding-listeners.ts: Simple IPC forwarding (slash-commands, etc.).

This reduces main/index.ts by ~600 lines (1270 → 670) and adds 15 new tests covering forwarding, error, and stats listeners.
PR Review Fixes:
- Fix race condition in exit-listener by moving markAndMaybeSynthesize
  to explicit code paths instead of finally() block
- Add buffer size limits (MAX_BUFFER_SIZE 10MB) with warning logs
- Add REGEX_BATCH_SESSION and REGEX_SYNOPSIS_SESSION for proper filtering
- Fix type safety using canonical ToolExecution and UsageStats imports
- Fix usage-listener indentation bug where safeSend was inside wrong block

Performance Optimizations:
- Add GROUP_CHAT_PREFIX constant for fast string prefix checks
- Skip expensive regex matching for non-group-chat sessions
- Eliminate redundant loadGroupChat calls by using updateParticipant
  return value directly (DB caching)
- Add MSG_ID_RANDOM_LENGTH constant for web broadcast deduplication

Test Coverage:
- Add 4 new test files (exit, data, usage, session-id listeners)
- Total 93 tests covering edge cases, DB caching, and performance
- Verify exact participants data flow from updateParticipant
- Test optional emitter handling and empty participants arrays
- Extract agent:clearError and agent:retryAfterError handlers from
  main/index.ts to dedicated handlers/agent-error.ts module
- Add comprehensive test coverage for agent error handlers (29 tests)
- Centralize GROUP_CHAT_PREFIX constant in process-listeners/types.ts
  to eliminate duplication across 4 listener files
- Remove unused ipcMain import from main/index.ts (all IPC handlers
  now registered through handlers module)
- Add retry logic with exponential backoff for stats DB insertions
  (100ms, 200ms, 400ms delays, max 3 attempts)
- Fix import order in types.ts (move constant after imports)
- Update stats-listener tests for async retry behavior
- Add new test for retry success on transient failure

Addresses review recommendations:
- High: Stats database error handling with retry logic
- Low: Import order consistency
… fixes

- Move WebServer class to dedicated file and add module index
- Extract shared types to centralized types.ts
- Fix XSS vulnerability by sanitizing sessionId/tabId in URL parameters
- Fix IPC listener memory leak with proper cleanup on timeout
- Add autoRunStates cleanup when sessions go offline
- Refactor message handlers with send() and sendError() helpers
- Add XSS sanitization tests and e2e test configuration
- Extract LiveSessionManager (178 lines) for live session and AutoRun state tracking
- Extract CallbackRegistry (208 lines) for centralized callback management
- Reduce WebServer.ts from 778 to 582 lines (25% reduction)
- Add managers/ directory with proper exports
- Maintain consistent public API (no breaking changes)
Show complete command with all arguments instead of limiting to first 5
args. Full command visibility is essential for debugging SSH and other
spawn issues.
…ities

- Remove incorrect normalization for Claude Code (reports per-turn values directly)
- Keep normalization only for Codex (reports cumulative session totals)
- Create src/shared/contextUsage.ts as single source of truth
- Consolidate duplicate code from renderer, main, and web/mobile
- Add w-full to ContextWarningSash for full-width display
- Update tests to reflect correct formula and behavior
When the wizard generates Auto Run documents, it now defaults to using
<agentPath>/Auto Run Docs for the {{AUTORUN_FOLDER}} template variable
instead of leaving it empty when not explicitly provided.
Adds a /skills slash command (Claude Code only) that reads skill files
from .claude/skills/*/skill.md directories and displays them in chat
with name, description, and approximate token count.
Rename "Audio Feedback" → "Custom Notification" and "TTS Command" →
"Command Chain" to better reflect the flexible nature of this feature.
Users can chain commands together with pipes to mix and match
notification tools (TTS, logging, desktop notifications, etc.).

Closes #168
Replace 'multi-document batch runs' and 'batch processing' terminology
with 'Auto Run' (individual documents) and 'Playbook' (collections of
Auto Run documents) across user-facing documentation.

Preserves 'batch mode' references where they describe Claude Code's
actual non-interactive operation mode.
- Add aider to AGENT_ARTIFACTS, AGENT_TARGET_NOTES, and display name mappings
- Add aider to agentIcons.ts
- Add aider to sessionValidation display names
- Remove duplicate droid entries in agent-detector.ts (Windows and Unix probes)
- Remove duplicate factory-droid entry in agentIcons.ts
- Add isWebContentsAvailable() helper function to safe-send.ts for
  checking if a BrowserWindow's webContents is available for IPC
- Use new utility across all IPC handlers for consistent safety checks
- Remove duplicate factory-droid entry from AGENT_DEFINITIONS
- Fix StdoutHandler to use proper webContents availability checks
- Add WelcomeContent and TourWelcome components for improved onboarding
- Simplify HistoryHelpModal by removing file path display
- Update EmptyStateView with enhanced welcome experience
- Fix tests by adding webContents.isDestroyed() mocks to all mock windows
- Add comprehensive tests for isWebContentsAvailable utility

Claude ID: 7effd201-908e-4f8d-a5d1-fe5e9737e751
Maestro ID: b9bc0d08-5be2-4fdf-93cd-5618a8d53b35
- Fix dual border issue where both AI tab and file tab showed active
  styling when file tab was selected. AI tabs now only show border when
  activeFileTabId is null.
- Update extension badge styling: remove leading dot, uppercase letters,
  smaller font (9px), reduced padding for minimal height impact.
- Update tests to expect new uppercase extension badge format (e.g.,
  'TS' instead of '.ts').
- Fix new tab creation (Cmd+T) not appearing in unified tab bar by
  adding new AI tabs to unifiedTabOrder in createTab()
- Fix new AI tab not being displayed when file tab was active by
  clearing activeFileTabId in createTab()
- Fix AI tab isActive check to handle undefined activeFileTabId
  (use !activeFileTabId instead of === null)
- Remove redundant filename/path header from file tab context menu
  (info already shown in tab and file preview subheading)
- Use JavaScript toUpperCase() for extension badges instead of CSS
  text-transform to ensure DOM content matches displayed text
- Update tests to use 'Copy File Path' selector instead of removed
  file-text-icon for identifying file tab overlays
Relocate the log level setting to be more appropriately placed in General
settings, positioned above the GitHub CLI Path setting.
The issue was caused by legacy overlay behavior in FilePreview component:
- useClickOutside hook was calling onClose when clicking outside the preview
- Layer registration was blocking lower layers and capturing focus

Added isTabMode prop to FilePreview to distinguish tab-based rendering:
- When isTabMode=true: disable click-outside-to-close behavior
- When isTabMode=true: don't block lower layers or aggressively capture focus
- When isTabMode=true: set focusTrap to 'none' and allowClickOutside to true

File preview tabs now persist until explicitly closed by:
- Clicking the X button on the tab
- Using Cmd+W keyboard shortcut
- Middle-clicking the tab
- Using context menu "Close Tab"

Updated tests to verify click-outside is disabled in tab mode.
Use theme colors to create vibrant, readable diagrams instead of washed-out
defaults. Nodes now have tinted backgrounds with prominent accent-colored
borders, and different node types use distinct colors (accent, success,
warning) for visual variety.

- Add blendColors() and transparentize() helpers for color mixing
- Use accent color for primary nodes, success for secondary, warning for tertiary
- Connection lines use accent color instead of dim text
- Enhanced styling for flowcharts, sequence diagrams, Gantt charts, pie charts,
  ER diagrams, git graphs, quadrant charts, and Sankey diagrams
- Better edge label backgrounds for readability
- Extended pie chart palette to 12 distinct colors
Tab management shortcuts (Cmd+T new tab, Cmd+W close tab) now work
when viewing a file preview tab. Previously these shortcuts were
blocked because file preview registers as an overlay in the layer
stack. Added these to the allowlist of shortcuts that work when
overlays (but not modals) are open.
…tration

Tab behavior changes:
- Escape key no longer closes file tabs (only closes internal UI like
  search and TOC overlay). Use Cmd+W or close button to close tabs.
- File preview in tab mode skips layer stack registration entirely
  since tabs are main content, not overlays. This prevents tabs from
  intercepting keyboard shortcuts or participating in overlay logic.

Updated tests to verify tab-mode Escape behavior.
Added isTabSwitcherShortcut to the overlay allowlist so users can
open the tab switcher modal while viewing a file preview tab.
Add onWheel stopPropagation to TOC overlay container so mouse wheel
events over the ToC scroll only the ToC, not the underlying file
content. Also update tests to reflect the previous change where ToC
stays open when clicking items (dismiss via click outside or Escape).
Extended isTabManagementShortcut to include Cmd+Shift+T for reopening
closed tabs when overlays are open. The closeFileTab helper already
adds file tabs to unifiedClosedTabHistory, and reopenUnifiedClosedTab
handles restoring both AI and file tabs. This ensures Cmd+Shift+T works
from file preview and other overlay contexts.
Added global image cache to MarkdownImage component to prevent
re-fetching images on re-renders, which was causing scrollbar
flickering. Key changes:

- Global imageCache Map stores loaded images with TTL (10 min)
- Images are cached by resolved path, including dimensions
- Loading placeholder has min-height/min-width to reduce layout shift
- Loaded images use aspectRatio from cached dimensions
- onLoad handler captures and caches natural dimensions

This eliminates the flickering/scrollbar jumping when viewing
markdown files with embedded images.
Added overscrollBehavior: 'contain' to both the main content
container and the TOC overlay's scrollable entries section. Also
added onWheel stopPropagation to the TOC entries div to fully
prevent scroll events from leaking between the ToC overlay and
the main file preview content. This prevents scroll chaining that
could cause scrollbar flickering.
Regular click on file links replaces current tab content, while
Cmd/Ctrl+Click opens a new tab adjacent to the current tab.
Replace backdrop-based click-outside detection with useClickOutside hook.
The previous fixed backdrop div intercepted all pointer events including
wheel events, preventing file content from scrolling while ToC was open.
Now wheel events over file content scroll the content, while wheel events
over the ToC scroll the ToC list.
- Added FilePreviewHistoryEntry type to track navigation history per tab
- Extended FilePreviewTab with navigationHistory and navigationIndex fields
- Updated handleOpenFileTab to build navigation history when replacing content
- Added handleFileTabNavigateBack/Forward/ToIndex handlers for per-tab nav
- Wired navigation props through MainPanel to FilePreview component
- Each file tab maintains its own independent navigation history
After saving a file in the file preview tab, the UI was reverting to the
original content despite showing "Saved". This occurred because:
- editContent was cleared to undefined after save
- The base content field was never updated to the saved value
- UI fell back to stale original content

Added savedContent parameter to handleFileTabEditContentChange to update
the tab's base content alongside clearing editContent after save.
All image references now consistently use relative ./screenshots/ paths
instead of mixed formats (some were /screenshots/ or screenshots/).
…lickOutside hooks

The tests were failing because FilePreview uses useClickOutside twice (once for
container dismiss, once for TOC dismiss) and the mock was only capturing the
last call. Updated the mock to track both calls separately and added proper
act() wrapping for React state updates.
Key changes:
- Accept main's fix for context usage calculation (returns null for
  accumulated multi-tool turn values instead of capping at 100%)
- Adopt main's refactored structure:
  - agent-detector.ts → agents/detector.ts + definitions.ts + capabilities.ts
  - stats-db.ts → stats/*.ts modules
  - agent-session-storage types → agents/index.ts
- Port factory-droid agent to new agents/definitions.ts structure
- Remove obsolete shared/contextUsage.ts (logic now in renderer/utils)
- Update all import paths to reference new module locations
- Preserve all RC features: Symphony, File Preview Tabs, TabNaming, etc.

The context window fix is critical: main's approach correctly handles
when Claude Code reports accumulated token values from multi-tool turns
by returning null, causing the UI to preserve the last valid percentage.
RC's approach masked this by capping at 100%, hiding the issue.
…tab system

- detector.test.ts: Update agent count from 7 to 8 (aider was added)
- session-storage.test.ts: Fix import paths for factory-droid storage
- agents.test.ts: Add AGENT_DEFINITIONS to mock for handler tests
- stats.test.ts: Remove tests for non-existent initialization handlers
- usage-aggregator.test.ts: Update DEFAULT_CONTEXT_WINDOWS test for actual ToolType values
- MainPanel.test.tsx: Migrate from previewFile prop to activeFileTabId/activeFileTab system
- contextUsage.test.ts: Update tests for current ToolType values (removed 'claude', 'aider')
- SessionStatusBanner.test.tsx: Update test for null return when tokens exceed context
- usage-listener.test.ts: Fix expected contextUsage (falls back to 200k default)
- App.tsx: Remove unused import (reopenClosedTab), legacy navigation
  variables (backHistory, forwardHistory, filePreviewHistory,
  filePreviewHistoryIndex), legacy callbacks (setFilePreviewHistory,
  setFilePreviewHistoryIndex), unused async handler (handleOpenFileTabAsync),
  and legacy navigation handlers (handleNavigateBack, handleNavigateForward,
  handleNavigateToIndex) - all superseded by per-tab navigation system
- MainPanel.tsx: Prefix unused destructured props with underscore
- contextUsage.ts: Remove unused UsageStats import

This removes ~250 lines of dead code from the legacy session-level
file preview navigation system, which has been replaced by the per-tab
breadcrumb navigation in the unified tab system.
@claude
Copy link

claude bot commented Feb 3, 2026

PR Review: 0.15.0 RC

Summary

This is a major release with 402 files changed (+65,528/-5,730 lines). The PR introduces Symphony (AI-powered open source contributions), SSH remote execution improvements, unified session storage abstraction, and history manager refactoring. Overall code quality is high with extensive test coverage, but there are security concerns that should be addressed before merging.


✅ Strengths

1. Excellent Test Coverage

  • 16 new test files with ~15,000 lines of test code
  • Key test files:
    • symphony.integration.test.ts (2,974 lines) - end-to-end flows
    • symphony.test.ts (5,247 lines) - IPC handlers
    • symphony-runner.test.ts (1,346 lines) - service logic
    • remote-git.test.ts (1,039 lines) - remote operations
    • history-manager.test.ts (1,390 lines) - migration logic
    • session-storage.test.ts (1,591 lines) - storage abstraction

2. Strong Security Patterns

The implementation includes proper input validation:

  • URL validation (symphony.ts:78-96) - HTTPS-only, GitHub domain whitelist
  • Path sanitization (symphony.ts:64-72) - removes .., limits length
  • Repository slug validation (symphony.ts:101-121) - enforces GitHub naming rules
  • Document path validation (symphony.ts:156-184) - prevents traversal, whitelists external URLs
  • Branch template is hardcoded and safe (BRANCH_TEMPLATE = 'symphony/issue-{issue}-{timestamp}')

3. Well-Documented Architecture

  • New files: SYMPHONY_REGISTRY.md, SYMPHONY_ISSUES.md
  • Clear documentation for maintainers and contributors
  • Updated CLAUDE.md, ARCHITECTURE.md, CONTRIBUTING.md with new patterns

4. SSH Remote Execution Improvements

  • Reusable ssh-spawn-wrapper.ts utility
  • Proper integration with session storage
  • Tests cover SSH scenarios

⚠️ Security Concerns (High Priority)

1. File Download Validation (symphony-runner.ts:144-158, symphony.ts:2256-2278)

Issue: No validation of downloaded file content type or size before writing to disk.

async function downloadFile(url: string, destPath: string): Promise<boolean> {
  const response = await fetch(url);
  const buffer = await response.arrayBuffer();
  await fs.writeFile(destPath, Buffer.from(buffer));
}

Risks:

  • Could download files >100MB (DoS)
  • Could download malicious content disguised as markdown
  • No virus scanning or content validation

Recommendation:

async function downloadFile(url: string, destPath: string): Promise<boolean> {
  const response = await fetch(url);
  
  // Validate content type
  const contentType = response.headers.get('content-type');
  if (!contentType?.includes('text/markdown') && !contentType?.includes('text/plain')) {
    throw new Error(\`Invalid content type: \${contentType}\`);
  }
  
  // Limit file size (5MB)
  const contentLength = response.headers.get('content-length');
  if (contentLength && parseInt(contentLength) > 5 * 1024 * 1024) {
    throw new Error('File too large');
  }
  
  const buffer = await response.arrayBuffer();
  if (buffer.byteLength > 5 * 1024 * 1024) {
    throw new Error('File too large');
  }
  
  await fs.writeFile(destPath, Buffer.from(buffer));
}

2. SSH Command Construction Security Audit Needed

Files: ssh-spawn-wrapper.ts, ssh-command-builder.ts

Issue: Complex argument escaping logic handles prompts >4000 chars differently. This needs thorough security review.

// ssh-spawn-wrapper.ts:83-194
function buildSshCommand() {
  // Complex logic for shell escaping across platforms
}

Recommendation:

  • Security audit of buildSshCommand() for shell injection vulnerabilities
  • Add unit tests with malicious inputs (special chars, quotes, newlines)
  • Consider using SSH's built-in quoting mechanisms instead of shell escaping

3. Issue Body Size DoS Protection (symphony.ts:307-322)

Issue: 1MB limit is logged but not consistently enforced before parsing.

if (issue.body.length > 1024 * 1024) {
  console.warn('[symphony] Issue body exceeds 1MB, truncating...');
}
const paths = parseDocumentPaths(issue.body); // But body not truncated here

Recommendation:

let body = issue.body;
if (body.length > 1024 * 1024) {
  console.warn('[symphony] Issue body exceeds 1MB, truncating...');
  body = body.substring(0, 1024 * 1024);
}
const paths = parseDocumentPaths(body);

4. GitHub CLI Authentication Parsing (symphony.ts:577-598)

Issue: Relies on parsing stderr/stdout for authentication state. Error messages could be spoofed.

Recommendation:

  • Use gh auth status --hostname github.com with explicit hostname
  • Check exit code in addition to output parsing
  • Consider using GitHub API token validation endpoint as fallback

🔍 Missing Test Coverage

High Priority - Add Unit Tests:

  1. Input Validation Functions (currently untested):

    • validateGitHubUrl() with malicious URLs
    • validateRepoSlug() with edge cases
    • sanitizeRepoName() with path traversal attempts
    • parseDocumentPaths() with large bodies, XSS attempts
  2. File Download Security:

    • Downloading files >10MB
    • Downloading non-markdown content types
    • Following redirects to non-GitHub domains
    • Handling malformed response headers
  3. SSH Command Injection:

    • Large prompts (>4000 chars) with special characters
    • Prompts with quotes, backticks, semicolons
    • Malformed paths in SSH remote operations

📝 Code Quality Observations

Good Practices:

  • ✅ Consistent error handling patterns
  • ✅ TypeScript types are well-defined
  • ✅ Proper use of async/await
  • ✅ IPC handlers follow established patterns
  • ✅ Constants extracted to separate files

Minor Issues:

  1. Large Handler File (symphony.ts - 2,583 lines):

    • Consider splitting into smaller modules (registry, issues, contributions, lifecycle)
    • Extract validation functions to symphony-validation.ts
  2. Console Logging in Production Code:

    • Multiple console.warn() and console.error() calls
    • Consider using structured logging with levels
  3. Magic Numbers:

    • 1024 * 1024 (1MB) appears in multiple places
    • Extract to constants: MAX_ISSUE_BODY_SIZE, MAX_DOWNLOAD_SIZE

🎯 Recommendations

Before Merging:

  1. Security (CRITICAL):

    • Add file size/content-type validation to downloadFile()
    • Security audit buildSshCommand() for injection vulnerabilities
    • Consistently enforce issue body size limit
    • Strengthen GitHub CLI auth validation
  2. Testing (HIGH):

    • Add unit tests for all input validation functions
    • Add security-specific test cases (malicious inputs)
    • Test file download edge cases
  3. Code Quality (MEDIUM):

    • Extract magic numbers to constants
    • Consider splitting symphony.ts into smaller modules
    • Replace console logging with structured logger

Post-Merge:

  1. Documentation:

    • Document threat model for Symphony (trusted registry vs. untrusted repos)
    • Document security assumptions about GitHub-only URLs
    • Add security section to SYMPHONY_REGISTRY.md
  2. Monitoring:

    • Add metrics for failed downloads, auth issues
    • Track Symphony contribution success rates
    • Monitor file sizes and processing times

🏆 Conclusion

This is a well-architected feature with strong test coverage and good security foundations. However, the file download validation gap and SSH command construction complexity need to be addressed before merging to production. Once the security concerns are resolved, this will be an excellent addition to Maestro.

Recommendation: Request changes for security issues, then approve after fixes.


Review conducted by: Claude Sonnet 4.5 via gh pr comment
Files analyzed: 402 changed files
Focus areas: Security, test coverage, code quality, documentation

@claude
Copy link

claude bot commented Feb 3, 2026

PR #282 Review - 0.15.0 RC

Overall Assessment

This is a massive release candidate PR with 402 files changed, 65K+ additions, and ~6K deletions. The code quality is excellent with professional engineering practices throughout.

Rating: ✅ APPROVE with minor revisions

  • Risk Level: Medium-High (massive scope, but well-mitigated by extensive testing)
  • Code Quality: Excellent
  • Test Coverage: Outstanding (431 test files, 93+ new tests)

Key Improvements 🎉

1. SSH Remote Execution (Major Enhancement)

  • ✅ Comprehensive SSH support via ssh-spawn-wrapper.ts
  • ✅ Proper shell escaping with shellEscape()
  • ✅ Large prompt handling (auto-switch to stream-json mode for >4KB prompts)
  • ✅ Full SSH support for Group Chat, synopsis, context grooming, and all session storage implementations
  • ✅ Excellent adherence to CLAUDE.md SSH awareness guidelines

2. Process Listener Refactoring (Architectural Win)

  • ✅ Reduced main/index.ts from 1270 to 670 lines (47% reduction!)
  • ✅ Extracted 8 modular listener modules with clear responsibilities
  • ✅ Clean dependency injection for testability
  • ✅ Smart performance optimizations (prefix checks before regex, DB caching)

3. Context Usage Calculation Fixes (Critical Bug Fix)

  • ✅ Single source of truth in contextUsage.ts
  • ✅ Agent-specific semantics (Claude input-only vs OpenAI input+output)
  • ✅ Proper accumulation detection

4. Security Improvements

  • ✅ XSS prevention with sanitizeId() in web routes
  • ✅ Memory leak fixes with IPC listener cleanup
  • ✅ New isWebContentsAvailable() utility for safety across 10+ handlers

5. Factory Droid Integration

  • ✅ Complete agent support with SSH remote capability
  • ✅ Proper JSONL parsing and Windows path handling
  • ✅ 18 new tests for session storage

6. Windows Compatibility


Issues Found

Major (Should Fix Before Release)

  1. SSH PATH Evolution May Miss Edge Cases (src/main/utils/ssh-command-builder.ts:273-299)

    • Issue: Hardcoded PATH setup (~/.local/bin, ~/bin, etc.) may miss agent installations in non-standard locations
    • History: Code shows 3-4 iterations (started with $SHELL -ilc, then bash -lc, now explicit PATH)
    • Risk: "command not found" errors in exotic SSH environments
    • Recommendation: Add user-configurable "Remote PATH Override" setting for edge cases
  2. Buffer Size Limit Not Enforced (src/main/process-listeners/data-listener.ts:61-66)

    • Issue: MAX_BUFFER_SIZE (10MB) triggers warning log but doesn't prevent unbounded growth
    • Risk: Memory exhaustion from misbehaving agents
    • Recommendation: Implement actual buffer truncation or process termination
    if (totalSize > MAX_BUFFER_SIZE) {
      console.warn('[ProcessManager] Buffer exceeded, truncating...');
      this.dataBuffer = this.dataBuffer.slice(-MAX_BUFFER_SIZE); // Add this
    }
  3. Context Window Detection Edge Case (src/renderer/utils/contextUsage.ts:116)

    • Issue: Returns null when totalContextTokens > effectiveContextWindow, relies on caller to preserve previous value
    • Risk: If caller doesn't handle null properly, context percentage could disappear
    • Recommendation: Audit all callers or add defensive fallback

Minor (Nice to Have)

  • Some empty catch blocks with "debug logging" comments could be improved
  • Test mocking complexity could benefit from common fixtures/factories
  • SSH config validation removed from UI - consider adding informational tooltips

Test Coverage Assessment ✅

Excellent - Outstanding coverage of new features:

  • ✅ Process Listeners: 7 new test files
  • ✅ SSH Remote: 15+ test files covering all aspects
  • ✅ Session Storage: 44+ tests for OpenCode, Codex, Factory Droid
  • ✅ Context Usage: Edge case coverage
  • ✅ Windows Compatibility: Platform-specific tests
  • ✅ Integration Tests: GroupChat SSH flow verification

Minor gaps (acceptable for RC):

  • Buffer overflow behavior tests missing
  • XSS sanitization tests could be expanded

Compliance with CLAUDE.md Patterns ✅

  • ✅ SSH Awareness: All spawning uses wrapSpawnWithSsh() pattern
  • ✅ IPC Safety: isWebContentsAvailable() used consistently
  • ✅ Layer Stack: Proper modal registration
  • ✅ Settings Persistence: Proper store wrappers
  • ✅ Performance: Debouncing, regex optimization, DB caching

Recommendations

Before Merge (Critical)

  1. Add buffer truncation enforcement in data-listener.ts
  2. Add SSH "Remote PATH Override" setting for edge cases
  3. Audit all contextUsage.ts null return handlers

Post-Merge (Follow-up PRs)

  1. Extract common test fixtures for SSH/webContents mocking
  2. Add integration test for buffer overflow scenario
  3. Add user documentation for SSH PATH requirements

Conclusion

This PR demonstrates professional engineering practices with:

  • Strong security awareness (XSS, shell injection, memory safety)
  • Excellent cross-platform support
  • Comprehensive test coverage (93+ new tests)
  • Clear architectural improvements (47% reduction in main/index.ts)

The massive scope is well-managed through extensive testing, clear commits, and quality-first approach.

Final Verdict: ✅ APPROVE after addressing the 3 major issues above.

Great work on this release! 🚀

handleCloseCurrentTab was duplicating file tab close logic inline
but not adding closed tabs to unifiedClosedTabHistory, causing
Cmd+Shift+T to restore a different tab instead of the most recently
closed one. Now uses closeFileTabHelper which properly tracks history.
The TabBar scroll-into-view effect only triggered for AI tabs. Added
activeFileTabId to the useEffect dependencies so file preview tabs
are also scrolled into view when opened.
@pedramamini pedramamini merged commit 2e11445 into main Feb 3, 2026
2 checks passed
@pedramamini pedramamini deleted the 0.15.0-rc branch February 3, 2026 01:41
@claude
Copy link

claude bot commented Feb 3, 2026

Pull Request Review: 0.15.0 RC

Overview

This is a massive release candidate (65K additions, 5.7K deletions, 104 files) introducing the Symphony feature - a crowdsourced AI-powered contribution system for open source projects. The PR demonstrates excellent engineering practices with comprehensive test coverage and documentation.


Key Features Added

1. Symphony Contribution System

  • Registry system for open source project discovery
  • GitHub issue integration with runmaestro.ai label
  • Auto Run orchestration for AI-assisted contributions
  • Draft PR claiming to prevent duplicate work
  • Achievement system with 8 achievements
  • Statistics tracking (tokens, time, cost estimation)

2. Major Infrastructure

  • Remote control integration (1015+ lines of tests)
  • Session storage refactoring (1591+ lines of tests)
  • History manager (1390+ lines of tests)
  • Tab naming system (663+ lines of tests)
  • Enhanced stdout handling (1189+ lines of tests)

Strengths

Code Quality

Excellent type safety - Comprehensive TypeScript types in symphony-types.ts
Security-conscious - ReDoS prevention in regex patterns (line-limited quantifiers)
Proper error handling - Uses execFileNoThrow for safe command execution
Separation of concerns - Clean IPC → Service → Runner architecture
Immutable patterns - Proper state management

Testing

Outstanding coverage - 22K+ lines of new tests
Integration tests - symphony.integration.test.ts (2974 lines)
Unit tests - All core modules tested
Test organization - Clear test structure and naming

Documentation

User-facing docs - SYMPHONY_ISSUES.md, SYMPHONY_REGISTRY.md
Developer docs - Updated CLAUDE.md, ARCHITECTURE.md
Screenshots - Visual documentation
Inline comments - Well-commented code

Performance

Caching strategy - 2hr registry cache, 5min issue cache
Shallow clones - --depth=1 for faster cloning
Real-time updates - IPC broadcasting for UI updates
Polling optimization - 2s during active, 5s for stats


Issues & Recommendations

Security Concerns

1. Path Traversal Protection ⚠️

File: src/shared/symphony-constants.ts:76-81

The document path regex patterns are well-designed for ReDoS prevention, but I'd recommend adding explicit path traversal validation:

// Add to validation logic
function isValidDocumentPath(path: string): boolean {
  const normalized = path.normalize(path);
  return !normalized.includes('..') && !normalized.startsWith('/');
}

2. GitHub URL Validation ⚠️

File: src/main/ipc/handlers/symphony.ts

Ensure GitHub URL validation prevents SSRF attacks. Verify that only github.com and githubusercontent.com domains are allowed for external document downloads.

3. Command Injection ✅ (Already handled well)

Good use of execFileNoThrow which properly escapes arguments. No issues found.

Code Quality Issues

1. Magic Numbers 🔧

File: src/shared/symphony-constants.ts:18-19

Consider extracting cache TTL values to environment variables for easier tuning:

export const REGISTRY_CACHE_TTL_MS = process.env.SYMPHONY_REGISTRY_CACHE_MS 
  ? parseInt(process.env.SYMPHONY_REGISTRY_CACHE_MS) 
  : 2 * 60 * 60 * 1000;

2. Error Type Granularity 🔧

File: src/shared/symphony-types.ts

The SymphonyErrorType enum could benefit from more specific error types:

  • GH_RATE_LIMIT_EXCEEDED
  • GH_AUTH_REQUIRED
  • GH_REPO_ARCHIVED
  • LOCAL_DISK_FULL

This would enable better error handling and user messaging.

3. Hardcoded Strings 🔧

File: src/main/services/symphony-runner.ts:63-64

// Consider moving to constants
const SYMPHONY_GIT_USER_NAME = 'Maestro Symphony';
const SYMPHONY_GIT_USER_EMAIL = 'symphony@runmaestro.ai';

Performance Considerations

1. Polling Frequency 💭

Files: useContribution.ts (2s), useContributorStats.ts (5s)

Consider WebSocket-based real-time updates instead of polling for better performance and lower resource usage. The infrastructure is already there (web-server.ts has WebSocket support).

2. Large PR Detection 💭

With 104 files changed, the GitHub diff API returns 406. Consider:

  • Paginating file lists
  • Implementing incremental review tooling
  • Breaking up mega-releases into smaller feature PRs

3. Memory Management ⚠️

File: src/main/services/symphony-runner.ts

Consider implementing cleanup for:

  • Cached registry data after TTL expiry
  • Downloaded external documents
  • Abandoned contribution repos

Test Coverage Gaps

1. Missing Error Path Tests 🔧

While test coverage is excellent, verify these scenarios are tested:

  • Network failures during PR creation
  • Git authentication failures
  • Disk space exhaustion during clone
  • Concurrent contribution attempts on same issue

2. Race Condition Testing ⚠️

Scenario: Two users start the same issue simultaneously

Ensure tests cover:

  • Draft PR creation race conditions
  • Branch name collision handling
  • State file write conflicts

Breaking Changes

⚠️ Version bump to 0.15.0 indicates minor version change. Verify:

  1. Backward compatibility with existing session files
  2. Migration path for users upgrading from 0.14.x
  3. API contract changes (if any)

Documentation Review

SYMPHONY_ISSUES.md

✅ Clear, comprehensive guide for maintainers
✅ Good examples and best practices
✅ Proper warning about AI limitations

SYMPHONY_REGISTRY.md

✅ Complete schema documentation
✅ Registration instructions
✅ Category definitions

Missing Documentation

  • Migration guide for 0.14.x → 0.15.0 users
  • Troubleshooting guide for common Symphony errors
  • API rate limiting documentation for GitHub API usage

Dependency Review

File: package.json

✅ No suspicious dependencies added
✅ Version bumps appear reasonable
⚠️ Node engine requirement: >=22.0.0 - Ensure this is documented in README/installation docs

Removed dependencies:

  • 516 lines removed from package-lock.json suggests cleanup ✅

Additional Recommendations

1. Feature Flags 💭

Consider adding a feature flag for Symphony to allow:

  • Gradual rollout
  • A/B testing
  • Quick disable if issues arise

2. Analytics 💭

Track Symphony feature adoption:

  • Number of contributions started
  • Success/failure rates
  • Average completion time
  • Most popular repositories

3. Rate Limiting ⚠️

Implement client-side rate limiting for GitHub API calls to prevent:

  • API quota exhaustion
  • Service degradation for all users
  • Need to share API quota across instances

4. Contribution Resumption 💭

Consider adding ability to resume interrupted contributions:

  • Save Auto Run progress
  • Resume from last completed document
  • Handle network disconnections gracefully

Final Assessment

Overall Score: 9/10

This is an exceptionally well-engineered feature release with:

  • Excellent code organization and architecture
  • Outstanding test coverage (22K+ lines of tests)
  • Comprehensive documentation
  • Security-conscious implementation
  • Performance optimization

Recommendation: Approve with Minor Revisions

Required Before Merge:

  1. ✅ Add explicit path traversal validation for document paths
  2. ✅ Verify GitHub URL whitelist prevents SSRF
  3. ✅ Add rate limiting for GitHub API calls
  4. ✅ Add memory cleanup for cached data

Recommended (Can be follow-up PRs):

  1. Replace polling with WebSockets for real-time updates
  2. Add feature flag for Symphony
  3. Add migration documentation
  4. Expand error type granularity
  5. Add analytics tracking

Testing Checklist

Before merging, please verify:

  • All tests pass (npm test)
  • Integration tests pass (npm run test:integration)
  • E2E tests pass (npm run test:e2e)
  • Builds successfully on all platforms (Mac, Windows, Linux)
  • Symphony feature works end-to-end:
    • Registry fetching and caching
    • Issue discovery and filtering
    • Repository cloning
    • Draft PR creation
    • Auto Run execution
    • PR finalization
    • Achievement unlocking
    • Statistics tracking

Acknowledgments

Excellent work on this release! The Symphony feature is a creative solution for AI-assisted open source contributions. The code quality, test coverage, and documentation are all exemplary. This will be a valuable addition to the Maestro ecosystem.

Reviewed by: Claude Sonnet 4.5
Review Date: 2026-02-03

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.

5 participants