Skip to content

feat: Add Symphony token donation system for open source contributions#122

Merged
pedramamini merged 60 commits intomainfrom
token-donations
Feb 3, 2026
Merged

feat: Add Symphony token donation system for open source contributions#122
pedramamini merged 60 commits intomainfrom
token-donations

Conversation

@pedramamini
Copy link
Collaborator

Summary

Introduces Symphony, a token donation system that enables Maestro users to contribute their AI agent tokens to help maintain and improve open source projects.

  • New Symphony modal (Cmd+Shift+Y) for browsing registered repositories and available issues
  • Contribution workflow to claim issues, work on them with AI assistance, and submit PRs
  • Contributor stats tracking with leaderboard and personal contribution history
  • Registry system for project maintainers to register repositories and categorize issues
  • GitHub integration for PR creation and issue status synchronization

Key Components

Area Files
Types & Constants symphony-types.ts, symphony-constants.ts
IPC Handlers src/main/ipc/handlers/symphony.ts (1,059 lines)
UI Components SymphonyModal.tsx (1,413 lines), AgentCreationDialog.tsx
React Hooks useSymphony.ts, useContribution.ts, useContributorStats.ts
Runner Service symphony-runner.ts
Registry symphony-registry.json
Documentation SYMPHONY_ISSUES.md, SYMPHONY_REGISTRY.md

Test plan

  • Open Symphony modal via Cmd+Shift+Y or Command K menu
  • Browse registered repositories and filter by category
  • View issue details and difficulty ratings
  • Start a contribution and verify agent session creation
  • Complete contribution flow and verify PR creation prompt
  • Check contributor stats and leaderboard display

@claude
Copy link

claude bot commented Dec 30, 2025

Code Review - Symphony Token Donation System

I have conducted a thorough review of PR #122 introducing the Symphony feature. This is a comprehensive 5,300+ line addition across 26 files.


Strengths

Architecture & Security: Clean separation of concerns with proper use of execFileNoThrow utility avoiding shell injection. Follows CLAUDE.md patterns for IPC handlers, modal registration, and layer stack integration.

Caching Strategy: Well-designed with 2-hour TTL for registry and 5-minute TTL for issues. Includes force refresh capability.

Type System: Full TypeScript coverage with detailed interfaces, proper error types with SymphonyError class, and TSDoc documentation.

UX Design: Draft PR immediately claims issues to prevent duplicate work. Real-time updates via IPC events. Keyboard shortcuts and stats tracking.

Security: No credential storage, uses HTTPS for all requests, shallow clones with --depth=1, input sanitization in document path parsing.


Critical Issues

1. MISSING TEST COVERAGE - No test files found for this 5,300+ line feature. This is a major concern.

Required tests: Document path parsing regex, Error handling in IPC handlers, Git operation failures, Cache invalidation logic, State persistence operations

2. PATH VALIDATION MISSING in symphony-runner.ts:108-117 - No validation that docPath does not contain path traversal and no check if file copy succeeded. This is a security concern.

3. SILENT ERROR SWALLOWING in symphony.ts:217-221 - Catch block returns null without logging errors. Should log errors before returning null.

4. GITHUB API RATE LIMITING - Makes unauthenticated API calls with 60 req/hour limit. No rate limit detection or handling. Should use gh CLI auth token if available.

5. PR STATUS NOT IMPLEMENTED - All issues show as available even if claimed by others. TODO comment at symphony.ts:273-274 acknowledges this but it should be fixed before merge or clearly documented in UI.


Recommendations

Before Merge - Blocking:

  1. Add path traversal validation in setupAutoRunDocs
  2. Add error checking for file copy operations
  3. Implement basic tests for critical paths
  4. Add rate limit handling for GitHub API
  5. Document or implement PR status checking

Post-Merge - High Priority:

  1. Comprehensive test suite
  2. Cleanup for failed contributions
  3. Network retry logic
  4. Merge status polling for stats

Final Verdict

This is a well-architected feature with innovative concept and generally high-quality implementation. However, test coverage is critical for a feature of this size.

Recommendation: Address the blocking issues above before merge. The Symphony concept is excellent and with these fixes will be a valuable addition.

Files reviewed: 26 files | Lines: approximately 5,300 additions

@claude
Copy link

claude bot commented Dec 30, 2025

Symphony Feature Review

Summary

This is an ambitious and well-architected feature that introduces a token donation system for open source contributions. The implementation follows established patterns from the codebase and demonstrates strong architectural consistency. However, there are several important concerns around security, error handling, test coverage, and edge cases that should be addressed before merging.


✅ Strengths

1. Excellent Architecture & Code Organization

  • Clean separation of concerns: types, constants, handlers, UI, hooks
  • Follows existing patterns (matches Usage Dashboard, Marketplace)
  • Proper use of execFileNoThrow for security (avoiding shell injection)
  • Well-structured type definitions with comprehensive JSDoc

2. Strong Type Safety

  • Comprehensive TypeScript interfaces covering all data flows
  • Proper error types with SymphonyError class
  • Good use of discriminated unions for status types

3. Good Caching Strategy

  • Appropriate TTLs (2h for registry, 5min for issues)
  • Cache invalidation logic
  • Real-time updates via IPC events

4. Documentation

  • Clear inline comments and JSDoc
  • Comprehensive SYMPHONY_REGISTRY.md and SYMPHONY_ISSUES.md
  • Good examples and guidance for maintainers

🔴 Critical Issues

1. Security: Path Traversal Vulnerability

Location: src/main/ipc/handlers/symphony.ts:621-623

const reposDir = getReposDir(app);
await fs.mkdir(reposDir, { recursive: true });
const localPath = path.join(reposDir, `${repoName}-${contributionId}`);

Issue: repoName comes from user input (repository name) and is not validated before being used in a file path. A malicious registry entry could use path traversal characters.

Fix: Sanitize repoName to prevent path traversal:

const sanitizedRepoName = repoName.replace(/[^a-zA-Z0-9_-]/g, '-');
const localPath = path.join(reposDir, `${sanitizedRepoName}-${contributionId}`);

2. Security: URL Validation Missing

Location: src/main/ipc/handlers/symphony.ts:629

Issue: repoUrl is not validated before being passed to git clone. This could allow non-GitHub URLs, file:// protocol abuse, or other malicious URLs.

Fix: Validate that URLs are GitHub repositories:

function validateGitHubUrl(url: string): boolean {
  try {
    const parsed = new URL(url);
    return parsed.protocol === 'https:' && 
           (parsed.hostname === 'github.com' || parsed.hostname === 'www.github.com');
  } catch {
    return false;
  }
}

3. Race Condition in Contribution State

Location: src/main/ipc/handlers/symphony.ts:608-618

Issue: Multiple concurrent calls to symphony:start could pass the duplicate check but both write, causing corruption. No locking mechanism.

Fix: Implement file locking or atomic updates using a library like proper-lockfile.

4. Missing Authentication Check

Location: src/main/services/symphony-runner.ts:80-84

Issue: No check for gh CLI authentication before attempting PR creation. This will fail silently or with cryptic errors.

Fix: Add authentication verification before starting contribution.


⚠️ Important Issues

5. Error Handling: No Cleanup on Partial Failure

Location: src/main/ipc/handlers/symphony.ts:655-660

Issue: If PR creation fails after pushing the branch, the remote branch remains orphaned. No cleanup of pushed branch.

Fix: Delete the remote branch on failure.

6. Resource Leak: No Cleanup for Cancelled Contributions

Location: src/main/services/symphony-runner.ts:284-286

Issue: Uses execFileNoThrow with rm -rf instead of Node.js fs.rm. Less portable and errors are swallowed.

Fix: Use Node.js file system APIs with proper error logging.

7. Missing Input Validation

Location: src/main/ipc/handlers/symphony.ts:584-605

Issue: No validation of input parameters (documentPaths could be empty, issueNumber could be negative, repoSlug format not validated).

Fix: Add comprehensive input validation.

8. Regular Expression DoS Vulnerability

Location: src/shared/symphony-constants.ts:69-76

Issue: Regex patterns with \s* at the start could be vulnerable to ReDoS with malicious input containing many whitespace characters.

Fix: Limit repetition to prevent ReDoS attacks.


📋 Medium Priority Issues

9. No Test Coverage

Finding: No test files found for Symphony feature.

Impact: Large feature with complex state management and external dependencies has no automated tests.

Recommendation: Add unit tests for core functions and integration tests for contribution lifecycle.

10. Missing Rate Limiting

Location: src/main/ipc/handlers/symphony.ts:237-248

Issue: GitHub API has rate limits. No rate limiting or error handling for 429 responses.

Fix: Add GitHub token authentication, handle 429 responses, implement exponential backoff.

11. Incomplete Issue Status Detection

Location: src/main/ipc/handlers/symphony.ts:278-282

Issue: All issues are marked as available even if they have open PRs. Users could start duplicate work.

Recommendation: Implement the TODO before releasing the feature.

12. Hardcoded Assumptions

Location: src/main/ipc/handlers/symphony.ts:604

Issue: Assumes default branch is main, but many repos use master or other names.

Fix: Query the default branch from GitHub API.


💡 Suggestions & Best Practices

13. Type Safety: Unsafe Type Assertions

Location: src/renderer/hooks/symphony/useSymphony.ts:158-160

Issue: Type assertion bypasses TypeScript safety.

Fix: Remove unnecessary type assertions and trust the IPC layer types.

14. UI: Missing Loading States

Observation: Modal has loading skeletons but no error states for network failures or empty states for no contributions yet.

Recommendation: Add empty state illustrations and error states with retry buttons.

15. Accessibility: Missing ARIA Labels

Issue: Modal lacks proper ARIA attributes for screen readers.

Fix: Add proper ARIA labels and roles for accessibility.


📊 Statistics

  • Files Changed: 26
  • Lines Added: ~5,700
  • New Components: 2 major (SymphonyModal, AgentCreationDialog)
  • New Hooks: 3 (useSymphony, useContribution, useContributorStats)
  • New IPC Handlers: 13
  • Test Coverage: 0%

✅ Recommendations

Before Merge (Critical):

  1. Fix security vulnerabilities (path traversal, URL validation, race conditions, ReDoS)
  2. Add gh auth check
  3. Add input validation
  4. Fix cleanup issues

Before Release (Important):

  1. Implement issue status detection
  2. Add default branch detection
  3. Add basic test coverage
  4. Add rate limiting

Future Enhancements:

  1. Improve accessibility
  2. Add error/empty states
  3. Performance optimizations

🎯 Conclusion

This is a well-designed feature with strong architectural foundations. However, the security issues and lack of error handling make it not ready for merge in its current state.

With the critical issues addressed, this would be an excellent addition to Maestro. The concept is innovative and the implementation is generally high quality.

Estimated effort to address critical issues: 4-6 hours

Recommended action: Request changes, address critical security and error handling issues before merge.

Great work on the architecture and consistency with the codebase! 🎵

@pedramamini pedramamini self-assigned this Dec 30, 2025
@claude
Copy link

claude bot commented Dec 30, 2025

Code Review: Symphony Token Donation System

This is a comprehensive feature implementation introducing a token donation system for open source contributions. Below is my detailed review.


Overall Assessment

Strengths:

  • Well-structured architecture with clear separation of concerns
  • Comprehensive type definitions with detailed documentation
  • Security-conscious design with input validation and sanitization
  • Good use of existing patterns (similar to Playbook Marketplace)
  • Excellent maintainer documentation

Areas for Improvement:

  • Missing test coverage (critical)
  • Security concerns that need attention
  • Performance optimization opportunities

Security Concerns

Critical Issues

1. Command Injection Risk (symphony-runner.ts:108-114)
Using shell commands for file operations:

await execFileNoThrow('mkdir', ['-p', autoRunPath]);
await execFileNoThrow('cp', [sourcePath, destPath]);

Fix: Use Node.js fs.mkdir() and fs.copyFile() instead

2. Path Traversal Risk
Document path validation (symphony.ts:154-157) does not check for encoded traversal (e.g., %2e%2e%2f)
Fix: Add URL decoding check before validation

3. Registry URL Hardcoded
If the GitHub account is compromised, malicious registry could be served
Recommendation: Add checksum validation or signature verification


Potential Bugs

High Priority

1. Race Condition in Contribution State
handleStartContribution updates state optimistically. Multiple simultaneous contributions could corrupt state.
Fix: Add mutex/lock mechanism or queue contributions

2. Missing Cleanup on Failed PR Creation (symphony-runner.ts:172-176)
If PR creation fails, local repo and remote branch remain orphaned.
Fix: Add cleanup in error handler (similar to line 285-287)

3. Empty Commit Could Fail (symphony-runner.ts:161-164)
Some repositories have hooks that reject empty commits with no fallback.
Fix: Add fallback to create a small file change

Medium Priority

4. Issue Status Not Updated (symphony.ts:364)
TODO comment shows incomplete implementation - all issues marked as available even if PRs exist.
Impact: Users might try to claim already-claimed issues

5. Cache Invalidation
Cache age calculation does not account for clock skew


Performance Considerations

1. Missing Pagination (symphony.ts:325-380)
GitHub API returns max 30 issues per page. Repositories with more than 30 labeled issues will not show all.
Fix: Add pagination loop

2. Shallow Clone - Good use of --depth=1

3. Cache Strategy - 2-hour TTL for registry is reasonable, but 5-minute TTL for issues might be aggressive

4. Regex Compilation - Patterns compiled on every use, should pre-compile


Architecture and Code Quality

Strengths:

  • IPC handler organization follows existing patterns
  • Comprehensive TypeScript definitions
  • Good use of discriminated unions for status types
  • Custom SymphonyError class

Improvements:

1. SymphonyModal.tsx (1413 lines) - Very large component
Recommendation: Extract into ProjectsTab, ActiveContributionsTab, HistoryTab, StatsTab

2. Error Handling - Add error telemetry/logging

3. Magic Numbers - Some hardcoded values in components should be constants


Test Coverage (Critical)

This feature has ZERO test coverage.

For a security-sensitive feature that:

  • Clones external repositories
  • Creates PRs on behalf of users
  • Handles GitHub credentials
  • Executes code from external sources

Tests are mandatory before merge.

Required Unit Tests:

  • validateGitHubUrl() - test injection attempts
  • validateRepoSlug() - test malformed slugs
  • sanitizeRepoName() - test path traversal sequences
  • parseDocumentPaths() - test ReDoS vectors
  • generateBranchName() - test uniqueness

Required Integration Tests:

  • Symphony runner workflow (mock git/gh commands)
  • PR creation flow
  • State persistence and recovery
  • Cache invalidation

Required E2E Tests:

  • Full contribution flow (use test repository)
  • Error recovery scenarios
  • Concurrent contribution attempts

Target: 70% coverage for security-critical paths


Specific Code Issues

symphony-runner.ts:108 - Use fs module not shell commands
symphony-runner.ts:286 - Validate localPath before rm -rf
symphony.ts:63 - sanitizeRepoName missing dot in character class
symphony.ts:154 - Missing encoded path check
symphony.ts:325 - fetchIssues missing pagination


Documentation

Strengths:

  • Excellent SYMPHONY_ISSUES.md and SYMPHONY_REGISTRY.md
  • Clear examples for maintainers

Missing:

  • User guide for contributors
  • Security policy documentation
  • JSDoc comments on IPC handlers

Recommendations

Before Merge (Must Have)

  1. Add comprehensive test suite
  2. Fix command injection in symphony-runner.ts (use fs module)
  3. Add path traversal validation for encoded paths
  4. Implement error cleanup on PR creation failure
  5. Add pagination for GitHub issues API
  6. Validate local path before deletion

Post-Merge (Nice to Have)

  1. Refactor SymphonyModal into smaller components
  2. Add telemetry for error tracking
  3. Implement checksum validation for registry
  4. Add user documentation
  5. Add rate limiting for GitHub API calls
  6. Implement contribution queue

Metrics

  • Lines Added: 5,579
  • Files Changed: 25
  • Test Coverage: 0%
  • Documentation: Excellent

Conclusion

This is a well-designed and ambitious feature with solid architecture and excellent documentation. However, it should not be merged without:

  1. Comprehensive test coverage (especially security tests)
  2. Fixing command injection vulnerabilities
  3. Implementing proper cleanup on errors
  4. Adding pagination for issues

The concept is sound and follows Maestro patterns well. With security fixes and tests, this will be a valuable addition.

Recommendation: Request changes for security fixes and test coverage before merging.

Great work on this feature!

@claude
Copy link

claude bot commented Jan 8, 2026

Symphony Feature Review

This is an impressive feature implementation that introduces a token donation system for open source contributions. The code is well-structured and follows the project's established patterns.

✅ Strengths

Architecture & Design

  • Excellent separation of concerns: Clear division between IPC handlers, React hooks, UI components, and the runner service
  • Type safety: Comprehensive TypeScript types in symphony-types.ts (402 lines) with proper interfaces for all data structures
  • Follows project patterns: Mirrors established patterns from marketplace and stats features (cache strategy, real-time updates, IPC structure)
  • Security improvements: The latest commit (45e5edc) addresses critical security concerns with path traversal prevention, URL validation, and ReDoS fixes

Code Quality

  • Consistent error handling: Custom SymphonyError class with typed error categories
  • Safe command execution: Uses execFileNoThrow throughout (following project security requirements)
  • Well-documented: Inline comments, comprehensive JSDoc, and two detailed markdown guides
  • Proper caching: 2-hour TTL for registry, 5-minute TTL for issues with force-refresh capability

User Experience

  • Multi-entry points: Keyboard shortcut (Cmd+Shift+Y), Command K, hamburger menu
  • Draft PR claiming: Smart workflow that immediately creates draft PR to prevent duplicate work
  • Progress tracking: Detailed stats with token usage, time tracking, streaks, and achievements
  • Modal priorities: Properly registered with layer stack system

🔍 Areas for Improvement

1. Critical: Missing Git Configuration Before Commits

Location: src/main/services/symphony-runner.ts:47-50, 207-211

The runner creates commits without configuring git user identity. This will fail for users who haven't configured git globally.

Recommendation: Configure git user before committing:
await execFileNoThrow('git', ['config', 'user.name', 'Maestro Symphony'], localPath);
await execFileNoThrow('git', ['config', 'user.email', 'symphony@runmaestro.ai'], localPath);

Same issue exists in finalizeContribution.

2. Security: Path Traversal in Document Paths

Location: src/main/ipc/handlers/symphony.ts:108-117

While validateContributionParams checks for '..' and leading slashes, the check happens AFTER parsing document paths from untrusted issue bodies. Recommend adding validation in parseDocumentPaths to filter immediately.

3. Error Handling: Silent Failures

Location: src/main/services/symphony-runner.ts:246-251

PR body update failure is silently ignored. Should log failures even if not fatal.

4. Race Condition: Cache Write

Location: src/main/ipc/handlers/symphony.ts:223-225

Multiple concurrent getIssues calls could create race conditions when writing cache. Consider atomic writes using temp file + rename.

5. Missing Cleanup on Errors

Location: src/main/services/symphony-runner.ts:130-195

If contribution setup fails after cloning, the cloned repo is left on disk. Add cleanup in catch block.

6. UI: Large Component

SymphonyModal is 1,413 lines. Consider breaking into subcomponents (ProjectsTab, ActiveTab, HistoryTab, StatsTab) following UsageDashboard pattern.

7. Documentation: TODO Comments

Location: src/main/ipc/handlers/symphony.ts:402-403

Critical TODO about fetching linked PRs to determine issue status is unimplemented. This affects the core workflow. Track in a GitHub issue.

🧪 Testing Recommendations

  1. Test git failure scenarios: What happens when git user is unconfigured or gh CLI auth expires mid-contribution?
  2. Test malicious inputs: Issue bodies with path traversal attempts, XSS in issue titles, extremely long document lists
  3. Test network failures: Registry fetch failures, GitHub API rate limits, timeout scenarios
  4. Test concurrent operations: Multiple contributions starting simultaneously

📝 Minor Suggestions

  1. The DOCUMENT_PATH_PATTERNS RegEx array could benefit from test coverage given the ReDoS fix in commit 45e5edc
  2. The symphony.ts:340 cast to SymphonyRegistry could use runtime validation (Zod) for better type safety
  3. Consider adding a clearCache button in the UI for when registry updates need to be seen immediately (2-hour TTL might be too long)
  4. User-facing errors could be more helpful with retry suggestions or troubleshooting links

🎯 Overall Assessment

This is high-quality work that demonstrates:

  • Deep understanding of the Maestro codebase patterns
  • Thoughtful UX design (draft PR claiming is brilliant)
  • Proper security awareness (especially after the 45e5edc fixes)
  • Comprehensive documentation

The identified issues are mostly edge cases and defensive programming improvements. The critical item is the git configuration for commits.

Recommendation: ✅ Approve with minor changes

Focus on fixing:

  1. Git user configuration (critical)
  2. Document path validation (important for security)
  3. Error cleanup on failures (good practice)

The rest can be addressed in follow-up PRs.

Great work on this feature! The Symphony system has the potential to significantly benefit the open source community. 🎵

@claude
Copy link

claude bot commented Jan 8, 2026

Symphony Token Donation Feature - Code Review

I've completed a thorough review of PR #122. This is an ambitious and well-architected feature that enables token donation for open source contributions. Overall, the implementation is solid with excellent security considerations. Here's my detailed feedback:


🎯 Overall Assessment

Strengths:

  • ✅ Excellent security-first approach with comprehensive input validation
  • ✅ Well-structured architecture with clear separation of concerns
  • ✅ Thorough documentation (SYMPHONY_ISSUES.md, SYMPHONY_REGISTRY.md)
  • ✅ Proper use of execFileNoThrow throughout (prevents command injection)
  • ✅ Good error handling and logging patterns
  • ✅ Follows established Maestro patterns (hooks, IPC, modal priorities)
  • ✅ ReDoS prevention in regex patterns (line 73-81 in symphony-constants.ts)

Code Quality: 8.5/10 - Professional implementation with minor areas for improvement


🔒 Security Review

Excellent Security Practices

  1. Path Traversal Prevention (symphony.ts:59-70)

    • Proper sanitization of repo names
    • Document path validation blocks ..\ → modify → writeState()`
    • No locking mechanism for concurrent modifications
    • Risk: If two contributions complete simultaneously, one update could be lost
    • Recommendation: Implement file-based locking or use a queue for state writes
  2. Missing Error Handling in parseDocumentPaths (symphony.ts:261-275)

    • ReDoS is prevented, but malformed UTF-8 or very large bodies (>1MB) could cause issues
    • Recommendation: Add body size limit and early return:
    function parseDocumentPaths(body: string): string[] {
      if (body.length > 1024 * 1024) { // 1MB limit
        logger.warn('Issue body too large', LOG_CONTEXT);
        return [];
      }
      // ... rest of function
    }

Medium Priority

  1. Hardcoded --depth=1 May Break Some Repos (symphony-runner.ts:33)

    • Shallow clones can cause issues with certain git operations
    • Auto Run tasks might need full history
    • Recommendation: Make clone depth configurable or document this limitation
  2. No Timeout on Git Operations (symphony-runner.ts)

    • Clone/push operations could hang indefinitely on slow networks
    • Recommendation: Add timeouts to execFileNoThrow calls (30-60s)

Performance Considerations

  1. Cache Strategy is Sound

    • 2-hour TTL for registry, 5-minute for issues (symphony-constants.ts:18-19)
    • ✅ Good balance between freshness and API usage
  2. Registry Fetch Performance

    • Current implementation fetches entire registry each time
    • For 100+ repos, consider pagination or incremental updates
  3. File I/O Blocking Main Process

    • readState/writeState use sync-style operations in async functions
    • Recommendation: Consider moving state management to a separate store file (like stats-db.ts pattern)

🎨 Code Quality Improvements

Type Safety

  1. Missing Return Type (symphony.ts:261)

    • parseDocumentPaths has implicit return type
    • Recommendation: Add explicit : string[] (already correct, but could be explicit in JSDoc)
  2. Magic Numbers (symphony.ts:69, symphony-runner.ts:107-108)

    • Hardcoded 100 (max repo name length), file paths
    • Recommendation: Extract to named constants

Error Messages

  1. User-Facing Error Messages Could Be Better (symphony.ts:374-376)
    • Technical errors like "GitHub CLI error: ..." shown to users
    • Recommendation: Add user-friendly wrapper messages:
    return { 
      authenticated: false, 
      error: 'Unable to authenticate with GitHub. Please run "gh auth login" and try again.' 
    };

🧪 Test Coverage

Missing Test Scenarios:

  1. Edge cases for document path parsing (empty body, 1000s of paths)
  2. State file corruption handling
  3. Concurrent contribution state updates
  4. Network failures during clone/push operations
  5. Repository validation edge cases (special characters, very long names)

Recommendation: Add unit tests for:

  • All validation functions (validateRepoSlug, validateGitHubUrl, etc.)
  • Document path parsing with malicious/edge-case inputs
  • State management race conditions

📋 Minor Issues & Nitpicks

  1. Inconsistent Logging Context (symphony-runner.ts:13)

    • Uses [SymphonyRunner] while handlers use [Symphony]
    • Recommend consistent naming
  2. Unused Imports (symphony-runner.ts:10-11)

    • Commented-out type imports should be removed or uncommented
  3. TODO Comment (symphony.ts:352)

    • "TODO: In a future enhancement, fetch linked PRs..."
    • Create GitHub issue to track this or implement now
  4. mkdir -p Could Fail on Some Systems (symphony-runner.ts:108)

    • Using shell commands (mkdir, cp) instead of Node.js fs
    • Recommendation: Use fs.mkdir and fs.copyFile for portability

🎯 Architecture Feedback

Strengths:

  • Clean separation between IPC handlers, runner service, and UI
  • Follows Maestro's established patterns (usage dashboard, marketplace)
  • Good use of TypeScript for type safety

Suggestions:

  1. Consider extracting cache logic into a dedicated symphony-cache.ts service
  2. State management could benefit from event sourcing pattern (append-only log)
  3. Consider WebSocket for real-time contribution updates instead of polling

Recommendations Summary

Must Fix Before Merge

  • Add cleanup on startContribution failure
  • Implement state write locking/queueing to prevent race conditions
  • Add body size limit to parseDocumentPaths

Should Fix Soon

  • Add GitHub API rate limit handling
  • Add repository size validation before cloning
  • Add timeouts to long-running git operations
  • Replace shell commands (mkdir, cp) with Node.js fs APIs

Nice to Have

  • Add unit tests for validation functions
  • Extract cache logic to separate service
  • Improve user-facing error messages
  • Create GitHub issue for "fetch linked PRs" TODO

🎉 Conclusion

This is a high-quality implementation with excellent security awareness. The security fixes in commit 691bd69 addressed the major concerns. The remaining issues are primarily around edge cases and robustness.

Recommendation: Approve with requested changes. The must-fix items are straightforward and low-risk to implement.

Great work on this feature! The documentation is particularly impressive, and the architecture follows Maestro's patterns well. 🎵


Reviewed by Claude Code - Following CLAUDE.md conventions

@claude
Copy link

claude bot commented Jan 8, 2026

Symphony Token Donation Feature - Code Review

I've completed a thorough review of PR #122. This is an ambitious and well-architected feature that enables token donation for open source contributions. Overall, the implementation is solid with excellent security considerations. Here's my detailed feedback:


🎯 Overall Assessment

Strengths:

  • ✅ Excellent security-first approach with comprehensive input validation
  • ✅ Well-structured architecture with clear separation of concerns
  • ✅ Thorough documentation (SYMPHONY_ISSUES.md, SYMPHONY_REGISTRY.md)
  • ✅ Proper use of execFileNoThrow throughout (prevents command injection)
  • ✅ Good error handling and logging patterns
  • ✅ Follows established Maestro patterns (hooks, IPC, modal priorities)
  • ✅ ReDoS prevention in regex patterns (line 73-81 in symphony-constants.ts)

Code Quality: 8.5/10 - Professional implementation with minor areas for improvement


🔒 Security Review

Excellent Security Practices

  1. Path Traversal Prevention (symphony.ts:59-70)

    • Proper sanitization of repo names
    • Document path validation blocks .. and absolute paths (line 154-156)
  2. URL Validation (symphony.ts:76-94)

    • Enforces HTTPS only
    • Restricts to github.com domain
    • Validates URL structure
  3. Safe Command Execution

    • Consistent use of execFileNoThrow instead of shell execution
    • No string interpolation in command arguments
  4. GitHub CLI Authentication Check (symphony.ts:364-380)

    • Validates gh CLI is authenticated before PR operations
    • Good error messages for unauthenticated state

Security Concerns

⚠️ Medium Priority Issues:

  1. Missing Rate Limiting (symphony.ts:301-359)

    • The fetchIssues function has no rate limit protection for GitHub API calls
    • Could hit GitHub rate limits quickly if multiple repos are queried
    • Recommendation: Add exponential backoff and respect X-RateLimit-* headers
  2. No Repository Size Validation (symphony-runner.ts:31-35)

    • cloneRepo does not check repository size before cloning
    • A malicious large repository could fill disk space
    • Recommendation: Check repo size via API before cloning or add timeout/size limits
  3. Cleanup on Failure (symphony-runner.ts:136-195)

    • If startContribution fails after cloning, the local directory is not cleaned up
    • Recommendation: Add try/catch with cleanup in error path

🐛 Potential Bugs

High Priority

  1. Race Condition in State Updates (symphony.ts:870-913)

    • Multiple handlers call readState() → modify → writeState()
    • No locking mechanism for concurrent modifications
    • Risk: If two contributions complete simultaneously, one update could be lost
    • Recommendation: Implement file-based locking or use a queue for state writes
  2. Missing Error Handling in parseDocumentPaths (symphony.ts:261-275)

    • ReDoS is prevented, but malformed UTF-8 or very large bodies (>1MB) could cause issues
    • Recommendation: Add body size limit and early return

Medium Priority

  1. Hardcoded --depth=1 May Break Some Repos (symphony-runner.ts:33)

    • Shallow clones can cause issues with certain git operations
    • Auto Run tasks might need full history
    • Recommendation: Make clone depth configurable or document this limitation
  2. No Timeout on Git Operations (symphony-runner.ts)

    • Clone/push operations could hang indefinitely on slow networks
    • Recommendation: Add timeouts to execFileNoThrow calls (30-60s)

Performance Considerations

  1. Cache Strategy is Sound

    • 2-hour TTL for registry, 5-minute for issues (symphony-constants.ts:18-19)
    • ✅ Good balance between freshness and API usage
  2. Registry Fetch Performance

    • Current implementation fetches entire registry each time
    • For 100+ repos, consider pagination or incremental updates
  3. File I/O Blocking Main Process

    • readState/writeState use sync-style operations in async functions
    • Recommendation: Consider moving state management to a separate store file (like stats-db.ts pattern)

🎨 Code Quality Improvements

Type Safety

  1. Missing Return Type (symphony.ts:261)

    • parseDocumentPaths has implicit return type
    • Recommendation: Add explicit return type annotation
  2. Magic Numbers (symphony.ts:69, symphony-runner.ts:107-108)

    • Hardcoded 100 (max repo name length), file paths
    • Recommendation: Extract to named constants

Error Messages

  1. User-Facing Error Messages Could Be Better (symphony.ts:374-376)
    • Technical errors like "GitHub CLI error: ..." shown to users
    • Recommendation: Add user-friendly wrapper messages

🧪 Test Coverage

Missing Test Scenarios:

  1. Edge cases for document path parsing (empty body, 1000s of paths)
  2. State file corruption handling
  3. Concurrent contribution state updates
  4. Network failures during clone/push operations
  5. Repository validation edge cases (special characters, very long names)

Recommendation: Add unit tests for:

  • All validation functions (validateRepoSlug, validateGitHubUrl, etc.)
  • Document path parsing with malicious/edge-case inputs
  • State management race conditions

📋 Minor Issues & Nitpicks

  1. Inconsistent Logging Context (symphony-runner.ts:13)

    • Uses [SymphonyRunner] while handlers use [Symphony]
    • Recommend consistent naming
  2. Unused Imports (symphony-runner.ts:10-11)

    • Commented-out type imports should be removed or uncommented
  3. TODO Comment (symphony.ts:352)

    • "TODO: In a future enhancement, fetch linked PRs..."
    • Create GitHub issue to track this or implement now
  4. mkdir -p Could Fail on Some Systems (symphony-runner.ts:108)

    • Using shell commands (mkdir, cp) instead of Node.js fs
    • Recommendation: Use fs.mkdir and fs.copyFile for portability

🎯 Architecture Feedback

Strengths:

  • Clean separation between IPC handlers, runner service, and UI
  • Follows Maestro established patterns (usage dashboard, marketplace)
  • Good use of TypeScript for type safety

Suggestions:

  1. Consider extracting cache logic into a dedicated symphony-cache.ts service
  2. State management could benefit from event sourcing pattern (append-only log)
  3. Consider WebSocket for real-time contribution updates instead of polling

Recommendations Summary

Must Fix Before Merge

  • Add cleanup on startContribution failure
  • Implement state write locking/queueing to prevent race conditions
  • Add body size limit to parseDocumentPaths

Should Fix Soon

  • Add GitHub API rate limit handling
  • Add repository size validation before cloning
  • Add timeouts to long-running git operations
  • Replace shell commands (mkdir, cp) with Node.js fs APIs

Nice to Have

  • Add unit tests for validation functions
  • Extract cache logic to separate service
  • Improve user-facing error messages
  • Create GitHub issue for "fetch linked PRs" TODO

🎉 Conclusion

This is a high-quality implementation with excellent security awareness. The security fixes in commit 691bd69 addressed the major concerns. The remaining issues are primarily around edge cases and robustness.

Recommendation: Approve with requested changes. The must-fix items are straightforward and low-risk to implement.

Great work on this feature! The documentation is particularly impressive, and the architecture follows Maestro patterns well. 🎵


Reviewed by Claude Code - Following CLAUDE.md conventions

@claude
Copy link

claude bot commented Jan 8, 2026

Code Review - PR #122: Symphony Token Donation System

I've completed a thorough review of this pull request. Overall, this is a well-structured and thoughtfully implemented feature with strong security practices.

✅ Strengths

Security & Best Practices

  • Excellent security hygiene: Proper use of execFileNoThrow throughout instead of shell execution
  • Path traversal protection: sanitizeRepoName() and document path validation prevent directory traversal attacks
  • URL validation: Strict HTTPS-only GitHub URL validation with hostname checking
  • Input validation: Comprehensive parameter validation in validateContributionParams()
  • ReDoS mitigation: Document path regex patterns use bounded repetition to prevent ReDoS attacks
  • Authentication checks: Proper gh CLI authentication verification before PR operations

Code Quality

  • Consistent patterns: Follows established Maestro patterns (IPC handlers, caching, real-time updates)
  • Good separation of concerns: Clean separation between handlers, services, and UI components
  • Comprehensive types: Strong TypeScript typing with detailed interfaces
  • Error handling: Proper error propagation with custom SymphonyError class
  • Caching strategy: Smart caching with appropriate TTLs (2h for registry, 5m for issues)

Architecture

  • Layer stack integration: Proper modal priority registration following existing patterns
  • Real-time updates: symphony:updated event broadcasting for UI synchronization
  • Colorblind accessibility: Uses COLORBLIND_AGENT_PALETTE for status colors
  • Cleanup on failure: Proper resource cleanup when operations fail

⚠️ Issues & Concerns

1. Missing Test Coverage (Critical)

No test files found. Need unit tests for validation functions, document path parsing, security functions, and state transitions.

2. Potential Race Conditions (src/main/ipc/handlers/symphony.ts:789-799)

Checking for existing contributions is not atomic with the state write. If two contributions start simultaneously for the same issue, both could pass the check. Consider using a mutex/lock pattern.

3. Resource Cleanup Concerns (src/main/services/symphony-runner.ts:284-286)

Using rm -rf via execFileNoThrow is not portable to Windows and inconsistent with line 825 in symphony.ts which uses fs.rm(). Use fs.rm() consistently.

4. Error Handling Gaps (src/main/services/symphony-runner.ts:107-114)

setupAutoRunDocs function uses mkdir and cp commands without error handling. Use fs.mkdir(), fs.access(), and fs.copyFile() with proper error handling.

5. GitHub API Rate Limiting (src/main/ipc/handlers/symphony.ts:345-362)

Fetching issues without authentication means hitting unauthenticated rate limits (60 requests/hour). Consider using gh API token for authenticated requests (5000 requests/hour).

6. Incomplete Implementation (src/main/ipc/handlers/symphony.ts:386-390)

Issue status is hardcoded to available with a TODO comment about fetching linked PRs. Users might claim issues already being worked on by others. Either implement PR checking or add a prominent UI warning.

7. Empty Commit Approach (src/main/services/symphony-runner.ts:48-50)

Creating an empty commit to enable pushing without changes creates noise in git history. Consider if there's a cleaner approach.

8. Missing Validation in UI (src/renderer/components/SymphonyModal.tsx)

The UI doesn't validate that the user has gh CLI installed before showing the Start Contribution button. Check gh availability on modal open.

🔧 Minor Issues

  1. Hardcoded Base Branch Fallback: Falls back to main if default branch can't be detected. Consider logging a warning.
  2. Incomplete Streak Calculation: Uses simplified calculation that only checks yesterday or today.

📊 Performance Considerations

  1. Large file handling: setupAutoRunDocs() copies files synchronously in a loop
  2. State file writes: Every status update writes the entire state JSON
  3. Registry fetching: Consider background refresh to keep data fresh

🎯 Summary

This PR implements a sophisticated feature with excellent security practices and follows Maestro's architectural patterns well. Main concerns:

  1. Lack of test coverage (most critical)
  2. Potential race condition in contribution creation
  3. Incomplete implementation of issue status detection
  4. Resource cleanup inconsistencies

Recommendation: Approve with minor changes

The security issues from the earlier review have been addressed. The remaining issues are mostly edge cases and polish. Recommended actions:

  1. Add test coverage before merging (at minimum, unit tests for validation functions)
  2. Address the race condition in symphony:start
  3. Standardize on fs.rm() instead of shell rm
  4. Add UI check for gh CLI availability

Great work on this feature! The token donation concept is innovative and the implementation is solid. 🎵

Reviewed Files: src/main/ipc/handlers/symphony.ts (1,293 lines), src/main/services/symphony-runner.ts (290 lines), src/renderer/components/SymphonyModal.tsx (1,413 lines), src/shared/symphony-types.ts (402 lines), src/shared/symphony-constants.ts (97 lines), and various integration points

@claude
Copy link

claude bot commented Jan 8, 2026

Code Review: Symphony Token Donation System

Thank you for this substantial contribution! The Symphony feature is well-architected and follows most of the project's security and code quality standards. I've completed a comprehensive security and code quality review.


Executive Summary

Overall Assessment:Approve with requested changes

The implementation demonstrates excellent security practices, particularly around command injection prevention. However, there are 2 security issues that should be addressed before merging: SSRF protection for external URL downloads and a missing modal priority constant.


🔴 Critical Issues (Must Fix)

1. SSRF Vulnerability in External Document Downloads

Location: src/main/ipc/handlers/symphony.ts:1289-1302

Issue: The code downloads external URLs from issue bodies without validating against SSRF attacks:

if (doc.isExternal) {
  const response = await fetch(doc.path);
  // No validation against internal IPs, localhost, or file:// protocol
}

Risk: Malicious actors could craft issues with URLs pointing to:

  • Internal network resources (AWS metadata: http://169.254.169.254/latest/meta-data/)
  • Localhost services
  • Private IP ranges

Fix Required:

function isExternalUrlSafe(url: string): boolean {
  try {
    const parsed = new URL(url);
    // Only allow HTTPS
    if (parsed.protocol !== 'https:') return false;
    
    // Block localhost
    if (parsed.hostname === 'localhost' || 
        parsed.hostname === '127.0.0.1' || 
        parsed.hostname === '::1') return false;
    
    // Block private IP ranges
    if (parsed.hostname.startsWith('192.168.') || 
        parsed.hostname.startsWith('10.')) return false;
    
    // Block 172.16.0.0/12
    if (parsed.hostname.startsWith('172.')) {
      const octet = parseInt(parsed.hostname.split('.')[1], 10);
      if (octet >= 16 && octet <= 31) return false;
    }
    
    // Block link-local addresses (169.254.0.0/16)
    if (parsed.hostname.startsWith('169.254.')) return false;
    
    return true;
  } catch {
    return false;
  }
}

// Then use it before downloading:
if (doc.isExternal) {
  if (!isExternalUrlSafe(doc.path)) {
    logger.warn('Blocked unsafe external URL', LOG_CONTEXT, { url: doc.path });
    continue;
  }
  // ... proceed with fetch
}

🟡 Medium Issues (Should Fix)

2. Missing Modal Priority Constant

Location: src/renderer/components/SymphonyModal.tsx:927

priority: MODAL_PRIORITIES.SYMPHONY ?? 710,

The fallback value suggests MODAL_PRIORITIES.SYMPHONY might not be defined. Please verify it exists in src/renderer/constants/modalPriorities.ts. According to CLAUDE.md, all modals should have explicit priorities defined.


3. Credential Exposure in Logs

Location: Multiple locations where repoUrl is logged

Issue: Repository URLs may contain authentication tokens (e.g., https://token@github.com/owner/repo).

Recommendation: Sanitize URLs before logging:

function sanitizeUrlForLogging(url: string): string {
  try {
    const parsed = new URL(url);
    parsed.username = '';
    parsed.password = '';
    return parsed.toString();
  } catch {
    return '[invalid-url]';
  }
}

// Usage:
logger.info('Cloning repository', LOG_CONTEXT, { 
  repoUrl: sanitizeUrlForLogging(repoUrl), 
  targetPath 
});

✅ Excellent Security Practices

Command Injection Prevention ⭐

Perfect adherence to CLAUDE.md requirements:

const result = await execFileNoThrow('git', ['clone', '--depth=1', repoUrl, targetPath]);

Consistently uses execFileNoThrow throughout - no shell injection vulnerabilities found.


Input Validation ⭐

Comprehensive validation for all user inputs:

function validateRepoSlug(slug: string): { valid: boolean; error?: string }
function validateGitHubUrl(url: string): { valid: boolean; error?: string }
function validateContributionParams(params): { valid: boolean; error?: string }

Path traversal protection is properly implemented:

const resolvedSource = path.resolve(localPath, doc.path);
if (!resolvedSource.startsWith(localPath)) {
  logger.error('Attempted path traversal in document copy', LOG_CONTEXT);
  continue;
}

ReDoS Protection ⭐

The regex patterns in symphony-constants.ts include ReDoS mitigations:

  • Bounded quantifiers ({0,20}, {1,200})
  • 1MB body size limit with truncation
  • Reasonable complexity patterns

📋 Code Quality Observations

✅ Good Patterns

  1. IPC Handlers: Properly use createIpcHandler utility
  2. Modal Registration: Correct layer stack integration with priority and focus trap
  3. Error Handling: Comprehensive try-catch blocks with detailed logging
  4. Type Safety: Strong TypeScript typing throughout
  5. Accessibility: Proper ARIA attributes and keyboard navigation
  6. Colorblind Support: Uses COLORBLIND_AGENT_PALETTE

Minor Improvements

  1. Network Retry Logic: Consider adding exponential backoff for transient failures in useSymphony.ts:158-170
  2. Resource Cleanup: The force: true flag in directory cleanup is appropriate, but consider logging if cleanup fails
  3. State Concurrency: While Electron main process is single-threaded, consider a mutex for state modifications if concurrent operations become a concern

📊 Test Coverage

I see a test file was added:

  • src/__tests__/renderer/components/HistoryPanel.test.tsx (42 additions)

Recommendation: Consider adding specific tests for:

  • parseDocumentPaths() function with various input formats
  • URL validation functions
  • Contribution state transitions
  • Error handling paths in the runner service

📖 Documentation

Excellent documentation added:

  • docs/SYMPHONY_ISSUES.md - Clear guidance for maintainers
  • docs/SYMPHONY_REGISTRY.md - Registry documentation
  • Both documents are well-structured and comprehensive

🎯 Action Items

Before Merge:

  1. 🔴 Fix SSRF vulnerability - Add isExternalUrlSafe() validation
  2. 🟡 Verify MODAL_PRIORITIES.SYMPHONY exists in constants
  3. 🟡 Add URL sanitization for logging

Follow-up (Post-Merge):

  1. Add unit tests for document parsing and URL validation
  2. Consider network retry logic for registry fetching
  3. Monitor logs for any cleanup failures

Summary

This is a well-designed and secure implementation of a complex feature. The code follows project conventions exceptionally well, particularly around security (command injection prevention, input validation, path traversal protection). The main concern is SSRF protection for external downloads, which is straightforward to fix.

Great work on this feature! The Symphony token donation system will be a valuable addition to Maestro. 🎵

Verdict: Approve pending fixes for the SSRF vulnerability and modal priority constant verification.

@claude
Copy link

claude bot commented Jan 9, 2026

Comprehensive Code Review: Symphony Token Donation System

Overall Assessment

This is a well-architected feature with excellent security consciousness and strong adherence to the codebase patterns documented in CLAUDE.md. The Symphony implementation shows mature engineering practices with comprehensive error handling, input validation, and thoughtful UX design.

Key Strengths:

  • ✅ Excellent security validation (path traversal prevention, URL validation, repo slug checks)
  • ✅ Safe command execution using execFileNoThrow throughout
  • ✅ Comprehensive error handling with typed error classes
  • ✅ Consistent with existing patterns (MarketplaceModal styling, layer stack integration)
  • ✅ Good documentation (JSDoc comments, CLAUDE.md updates, user guides)
  • ✅ Accessibility features (ARIA labels, keyboard navigation)

Primary Concerns:

  1. Critical: Markdown XSS vulnerability in document preview
  2. High: Race conditions in PR creation and metadata management
  3. High: Missing test coverage for security-critical paths
  4. Medium: Performance issues with large datasets

Critical Issues 🚨

1. Markdown XSS Vulnerability (SymphonyModal.tsx)

Location: src/renderer/components/SymphonyModal.tsx:1109-1133

Issue: External document content is rendered directly in ReactMarkdown without sanitization. This could potentially execute malicious JavaScript via markdown features.

Recommendation: Add DOMPurify or configure ReactMarkdown's allowedElements list to prevent XSS attacks.


2. Race Condition in PR Creation (symphony.ts)

Location: src/main/ipc/handlers/symphony.ts:1494-1529

Issue: The deferred PR creation flow lacks locking mechanism. If multiple commits trigger createDraftPR simultaneously, duplicate PRs could be created.

Recommendation: Implement file-based locking or atomic flag in metadata.json (e.g., prCreationInProgress: boolean) to prevent concurrent PR creation attempts.


3. Metadata File Race Condition (symphony.ts)

Location: src/main/ipc/handlers/symphony.ts:1398-1410

Issue: Metadata writes lack atomic file operations. Concurrent modifications could corrupt the file.

Recommendation: Use atomic write pattern (write to temp file, then rename).


High Priority Issues ⚠️

4. Missing Rate Limiting for GitHub API

Location: src/main/ipc/handlers/symphony.ts:392-449

Issue: GitHub API calls have no rate limit handling or exponential backoff. Could hit API limits with many concurrent requests.

Recommendation: Implement rate limiting with bottleneck library, add exponential backoff for retries, handle 429 responses.


5. gh CLI Authentication Fragility

Location: src/main/ipc/handlers/symphony.ts:492-507

Issue: Authentication checks parse error messages via string matching, which is fragile.

Recommendation: Use gh auth status --json token for structured output instead of parsing stderr strings.


6. Large File Download Without Size Limit

Location: src/main/services/symphony-runner.ts:132-146

Issue: No size limit on external document downloads. Could download gigabytes of data.

Recommendation: Add MAX_DOCUMENT_SIZE check (e.g., 10MB) with streaming download and size validation.


Test Coverage Recommendations 🧪

The PR lacks test coverage. Priority tests needed:

  1. Security Validation - Test path traversal rejection, URL validation, document path sanitization
  2. Git Operations - Test cleanup on failure, prevent duplicate PR creation, handle no-commit scenarios
  3. UI Component - Test markdown sanitization, keyboard shortcuts, error states
  4. Race Conditions - Test concurrent metadata writes, concurrent PR creation

Summary and Priority Actions

This is a production-ready feature with excellent engineering practices. Issues are manageable.

Before Merge:

  1. ✅ Fix markdown XSS (add DOMPurify)
  2. ✅ Add PR creation locking mechanism
  3. ✅ Implement atomic metadata writes

Post-Merge:

  1. Add comprehensive test suite
  2. Implement rate limiting for GitHub API
  3. Add file size limits for downloads
  4. Extract business logic to service classes
  5. Add telemetry for monitoring

Commendations 🌟

Excellent work on:

  • Security-first approach with comprehensive validation
  • Consistent adherence to codebase patterns
  • Thorough documentation
  • Accessibility features
  • Thoughtful UX (deferred PR creation, document preview)

This feature represents a significant addition to Maestro and will provide real value to the open source community. Great job! 🎵

@claude
Copy link

claude bot commented Jan 9, 2026

Symphony Feature Review

I've completed a comprehensive review of PR #122 introducing the Symphony token donation system. Overall, this is a well-architected and thoughtfully implemented feature with strong security practices and good adherence to project conventions. Below are my findings:


Strengths

1. Security & Input Validation

The implementation demonstrates excellent security awareness:

  • URL validation (symphony.ts:77-94): Only allows HTTPS GitHub URLs, preventing SSRF attacks
  • Path traversal prevention (symphony.ts:64-71, 158-160, 1693-1695): Sanitizes repo names and validates document paths
  • ReDoS prevention (symphony-constants.ts:69-81): Document path regex patterns use bounded repetition
  • Size limits (symphony.ts:286-301): 1MB body size limit prevents performance issues during parsing
  • Safe command execution: Consistent use of execFileNoThrow utility throughout (no shell injection vulnerabilities)

2. Code Quality & Architecture

  • Clean separation of concerns: Types (symphony-types.ts), constants (symphony-constants.ts), handlers (symphony.ts), UI (SymphonyModal.tsx)
  • Comprehensive type definitions: 422 lines of well-documented TypeScript interfaces covering all data flows
  • Deferred PR creation pattern (symphony.ts:1657-1943): Avoids "no commits" errors by creating PRs only after first commit
  • Real-time updates: Uses event broadcasting pattern consistent with Usage Dashboard
  • Cache strategy: 2-hour TTL for registry, 5-minute TTL for issues with force refresh support

3. Adherence to Project Conventions

  • Follows CLAUDE.md patterns for settings persistence, IPC handlers, modal registration
  • Uses createIpcHandler utility consistently
  • Implements layer stack pattern for modal management
  • Uses colorblind-accessible palettes (Wong palette) for status colors
  • Follows existing patterns from MarketplaceModal (consistent 1200px width, w-80 left column)

4. Test Coverage

The HistoryPanel test file shows excellent testing practices:

  • 1932 lines of comprehensive tests
  • Tests pure functions, components, virtualization, keyboard navigation, edge cases
  • Proper mocking of IPC calls and DOM APIs
  • Tests for XSS prevention and Unicode handling

⚠️ Issues & Recommendations

Critical

None identified. The security implementations are solid and there are no obvious critical bugs.

High Priority

  1. Missing PR Status Check Parsing (symphony.ts:1480-1481, 1532-1533)

    • The PR status response is typed with merged and merged_at fields
    • However, GitHub's API uses merged_at for merged PRs but the merged boolean should be checked first
    • Recommendation: Verify the GitHub API response shape matches expectations or add defensive checks
  2. Error Handling in Document Download (symphony.ts:1723-1739)

    • External document download failures log warnings but silently continue
    • If ALL documents fail to download, the contribution starts with no documents
    • Recommendation: Add validation that at least one document was successfully resolved before proceeding
  3. Streak Calculation Simplification (symphony.ts:1361-1377)

    • The streak logic compares date strings which may have timezone issues
    • Uses Date.now() for "yesterday" calculation which could be off by hours
    • Recommendation: Use UTC dates for consistency: new Date().toISOString().split('T')[0]

Medium Priority

  1. Memory Management (symphony.ts:456-516)

    • enrichIssuesWithPRStatus fetches up to 100 PRs per repo
    • No pagination handling if a repo has >100 open PRs
    • Recommendation: Add warning log if response contains 100 PRs (likely truncated)
  2. Cache File Permissions

    • Symphony state and cache files written to userData directory without explicit permissions
    • Recommendation: Consider restricting file permissions (0600) for state files containing contribution metadata
  3. Default Branch Detection (symphony.ts:579-601)

    • Falls back to 'main' if detection fails, which may not always be correct
    • Recommendation: Return an error if detection fails rather than assuming
  4. Contribution Metadata Validation (symphony.ts:1846-1852)

    • Metadata file read without schema validation
    • Recommendation: Add basic validation to ensure required fields exist

Low Priority / Nice-to-Have

  1. Type Safety: The as type assertions in IPC responses (symphony.ts:371, 411, etc.) bypass type checking

    • Recommendation: Add runtime validation with a library like Zod
  2. Constants Organization: SYMPHONY_CATEGORIES uses emoji strings which may not render on all systems

    • Recommendation: Consider emoji fallbacks or use icon components instead
  3. Documentation: The deferred PR creation flow is complex and well-implemented, but could benefit from a sequence diagram in docs

    • Recommendation: Add to SYMPHONY_REGISTRY.md
  4. Test Gap: No tests visible for the main symphony IPC handlers

    • Recommendation: Add integration tests for the contribution lifecycle

📊 Performance Considerations

  • Document parsing: 1MB body size limit is reasonable for preventing DOS
  • Virtualization: UI uses React components but Symphony modal doesn't appear to use virtualization for large issue lists (unlike HistoryPanel)
    • Recommendation: Consider virtualizing if repos have >100 issues
  • Fetch operations: No retry logic for network requests
    • Recommendation: Add exponential backoff for registry/issue fetching

🔒 Security Assessment

Overall: STRONG

The codebase demonstrates security awareness:

  • ✅ Input validation on all external data
  • ✅ No shell command injection vectors (uses execFileNoThrow)
  • ✅ Path traversal prevention
  • ✅ SSRF prevention (GitHub URLs only)
  • ✅ ReDoS prevention in regex patterns
  • ✅ XSS prevention (React handles escaping)

One minor concern:

  • External document URLs are fetched without size limits (symphony.ts:1733)
    • Recommendation: Add response size limit (e.g., 10MB) before buffering

📝 Code Style & Conventions

✅ Follows project conventions
✅ Consistent with CLAUDE.md patterns
✅ Good TypeScript usage
✅ Clear separation of concerns
✅ Helpful code comments

Minor style notes:

  • Some long functions (e.g., symphony:startContribution at 150+ lines) could be split into helpers
  • Consider extracting GitHub API calls into a separate github-api.ts utility

🎯 Conclusion

This is a high-quality PR that introduces a substantial new feature with:

  • ✅ Strong security practices
  • ✅ Good architecture and code organization
  • ✅ Adherence to project conventions
  • ✅ Thoughtful error handling
  • ⚠️ A few minor issues that should be addressed before merge

Recommendation: APPROVE with minor changes requested

The issues identified are mostly edge cases and potential future improvements. None are blocking, but addressing the High Priority items (especially error handling for document downloads and streak calculation) would strengthen the implementation.


Great work on this feature! The deferred PR creation pattern and external document caching are particularly clever solutions. 🎉

@claude
Copy link

claude bot commented Jan 9, 2026

PR Review: Symphony Token Donation System

Overall Assessment

This is an impressive and well-architected feature that adds significant value to Maestro. The implementation demonstrates strong engineering practices with comprehensive security measures, thorough testing, and excellent documentation. The 9,042 line addition introduces a complete token donation ecosystem that feels production-ready.

Recommendation: Approve with minor suggestions


✅ Strengths

1. Security-First Design

The security posture is excellent:

  • Path traversal protection via sanitizeRepoName() removes .. sequences and leading dots (symphony.ts:64-71)
  • URL validation enforces HTTPS-only GitHub URLs (symphony.ts:77-95)
  • Repository slug validation with GitHub naming rules (symphony.ts:100-120)
  • Consistent use of execFileNoThrow (15 usages) - no shell injection vulnerabilities
  • ReDoS prevention in regex patterns with bounded repetition (symphony-constants.ts:69-81)
  • Body size limits (1MB max) to prevent DoS via large issue bodies (symphony.ts:287)

2. Robust Architecture

  • Type-safe throughout with comprehensive TypeScript definitions (422 lines in symphony-types.ts)
  • Separation of concerns: IPC handlers (1,988 lines), UI components (1,807 lines), hooks, services all cleanly separated
  • Caching strategy: Registry cached 2hrs, issues 5min - appropriate TTLs for each data type
  • Error handling: Custom SymphonyError class with typed error categories
  • State persistence: Proper disk-based state management with JSON storage

3. Testing & Documentation

  • Comprehensive test coverage: 1,180 lines of tests covering validation, parsing, and handlers
  • Excellent documentation:
    • CLAUDE.md updated with 75 new lines explaining Symphony integration
    • SYMPHONY_ISSUES.md (176 lines) and SYMPHONY_REGISTRY.md (158 lines) provide maintainer guides
    • Inline code comments are clear and purposeful

4. UI/UX Excellence

  • Colorblind-accessible using Wong palette (COLORBLIND_AGENT_PALETTE)
  • Consistent with existing patterns: Matches MarketplaceModal styling (same 1200px width, w-80 left column)
  • Layer stack integration for proper modal management (MODAL_PRIORITIES.SYMPHONY)
  • Real-time updates via IPC broadcasts for stats/progress

5. Performance Considerations

  • Shallow git clones (--depth=1) for speed (symphony-runner.ts:45)
  • Deduplication in document path parsing via Map (symphony.ts:303)
  • Efficient state updates with memoization patterns in hooks
  • Pagination support for large issue lists

🔍 Areas for Improvement

1. Critical: Missing Rate Limiting

Issue: GitHub API calls have no rate limiting, risking API quota exhaustion.

Location: fetchIssues() in symphony.ts:392-449

Recommendation: Add rate limit detection and backoff:

if (!response.ok) {
  if (response.status === 429 || response.status === 403) {
    const resetHeader = response.headers.get('X-RateLimit-Reset');
    const resetTime = resetHeader ? new Date(parseInt(resetHeader) * 1000) : null;
    throw new SymphonyError(
      `GitHub API rate limit exceeded. ${resetTime ? `Resets at ${resetTime.toLocaleString()}` : ''}`,
      'github_api'
    );
  }
  // existing error handling...
}

2. Security: Authentication Token Storage

Issue: No mention of GitHub token management for private repo contributions.

Recommendation: Document whether/how GitHub authentication works. If Symphony supports private repos, ensure tokens are stored securely (OS keychain, not plaintext).

3. Error Recovery: Draft PR Creation Race Condition

Issue: Deferred PR creation could fail if branch is deleted externally before first commit.

Location: App.tsx:4681+ (onProcessExit handler), symphony.ts:1150+

Recommendation: Add idempotency check:

// Before creating PR, verify branch still exists
const branchExists = await execFileNoThrow('git', ['rev-parse', '--verify', branchName], localPath);
if (branchExists.exitCode !== 0) {
  throw new SymphonyError('Branch no longer exists', 'git');
}

4. Performance: Large Issue Body Handling

Issue: 1MB truncation is good, but no warning to user about truncated documents.

Location: symphony.ts:295-301

Recommendation: Return truncation metadata so UI can warn users:

function parseDocumentPaths(body: string): { 
  docs: DocumentReference[]; 
  truncated: boolean 
} {
  const truncated = body.length > MAX_BODY_SIZE;
  // ... parsing logic
  return { docs: Array.from(docs.values()), truncated };
}

5. Code Quality: Magic Numbers

Issue: Some hardcoded values could be constants.

Examples:

  • SymphonyModal.tsx:1200 (modal width) - define as SYMPHONY_MODAL_WIDTH
  • symphony.ts:100 (repo name length limit) - define as MAX_REPO_NAME_LENGTH

6. Testing: Missing Integration Tests

Observation: Tests are comprehensive for unit-level validation but lack end-to-end flow tests.

Recommendation: Add integration test covering:

// Test: Complete contribution lifecycle
test('full contribution workflow', async () => {
  // 1. Fetch registry
  // 2. Select repo and issue
  // 3. Clone repo
  // 4. Create branch
  // 5. Setup auto-run docs
  // 6. Create draft PR
  // 7. Complete contribution
  // 8. Verify stats updated
});

📊 Code Metrics

Metric Value Assessment
Lines Added 9,042 Large but justified for complete feature
Main Handler 1,988 lines Could be split but well-organized
UI Component 1,807 lines Consider extracting sub-components
Test Coverage 1,180 lines Good coverage, add integration tests
Type Definitions 422 lines Excellent type safety

🎯 Specific Code Comments

Excellent Patterns

  1. Validation waterfall (symphony.ts:125-164): Clean, readable validation chain
  2. Document path deduplication (symphony.ts:303-348): Smart use of Map for deduplication
  3. Contribution ID generation (symphony.ts:270-274): Uses timestamp + random for uniqueness
  4. Status color accessibility (SymphonyModal.tsx:91-100): Wong palette for colorblind users

Consider Refactoring

  1. SymphonyModal.tsx (1,807 lines): Extract tabs into separate components:

    • <ProjectsTab />
    • <ActiveContributionsTab />
    • <HistoryTab />
    • <StatsTab />

    This would improve maintainability and test isolation.

  2. symphony.ts handler registration (lines 700-1900): Consider splitting into:

    • symphony-registry-handlers.ts (registry/issues fetching)
    • symphony-contribution-handlers.ts (contribution lifecycle)
    • symphony-state-handlers.ts (state management)

🔐 Security Checklist Review

✅ No SQL injection (no SQL usage)
✅ No command injection (proper use of execFileNoThrow)
✅ No path traversal (sanitization in place)
✅ Input validation (comprehensive)
✅ No XSS (React auto-escapes, ReactMarkdown with sanitization)
⚠️ Rate limiting (missing - see recommendation #1)
⚠️ Auth token security (needs documentation)


🚀 Performance Checklist

✅ Efficient git operations (shallow clones)
✅ Caching strategy (appropriate TTLs)
✅ Deduplication (document paths)
✅ Memoization (React hooks)
✅ Pagination (issue lists)
⚠️ Large modal components (consider code-splitting)


📝 Documentation Quality

Exceptional:

  • CLAUDE.md integration guide is thorough and follows existing patterns
  • SYMPHONY_ISSUES.md explains the contribution flow clearly
  • SYMPHONY_REGISTRY.md provides clear maintainer instructions
  • Inline comments are purposeful, not excessive

Suggestion: Add a Symphony troubleshooting section to CLAUDE.md covering:

  • What to do if GitHub API rate limit is hit
  • How to recover from failed PR creation
  • How to cleanup stuck contributions

🎨 UI/UX Notes

Wins

  • Consistent modal styling with Marketplace
  • Accessibility-first color choices
  • Clear status indicators with icons
  • Keyboard shortcuts (Cmd+Shift+Y)

Minor Polish

  • Consider adding loading skeletons for issue lists (similar to UsageDashboard pattern)
  • Add empty state illustrations when no repos/issues found
  • Consider toast notifications for background PR creation events

🧪 Test Coverage Analysis

Well Covered:

  • Validation helpers (sanitization, URL validation, slug validation)
  • Document path parsing (including edge cases)
  • Helper functions (branch name generation, cache validity)
  • IPC handler registration

Needs Coverage:

  • Error recovery flows (branch deleted, PR creation failure)
  • Cache expiration edge cases
  • Concurrent contribution handling
  • Stats aggregation with multiple active contributions

🏁 Conclusion

This PR represents high-quality engineering work that adds a valuable community-building feature to Maestro. The implementation is secure, well-tested, and thoughtfully architected. The few suggestions above are mostly minor enhancements rather than critical issues.

Before Merge

  1. ✅ Add rate limiting for GitHub API calls
  2. ✅ Document authentication token handling
  3. ⚠️ Consider splitting large files (optional, doesn't block merge)
  4. ⚠️ Add integration tests (can be follow-up PR)

Great work! 🎉


Review conducted by Claude Code PR Review Agent
Focus areas: Security, code quality, performance, testing, best practices

@claude
Copy link

claude bot commented Jan 9, 2026

PR Review: Symphony Token Donation System

Overview

This is an impressive feature implementation that introduces Symphony, a token donation system enabling Maestro users to contribute AI agent tokens toward open source project maintenance. The architecture is well-thought-out with proper separation of concerns, comprehensive type safety, and excellent test coverage.

✅ Strengths

Architecture & Design

  • Clean separation: IPC handlers, React hooks, UI components, and types are properly organized
  • Type safety: Comprehensive TypeScript definitions in symphony-types.ts with clear interfaces
  • Deferred PR creation: Smart strategy to avoid "no commits between branches" errors - PR is only created after first real commit
  • External document support: Handles both repo-relative paths and GitHub attachment URLs elegantly
  • Real-time updates: Proper event broadcasting with symphony:updated and symphony:prCreated events

Security

  • Path traversal prevention: Good validation in validateContributionParams() checks for .. and absolute paths
  • GitHub URL validation: Only allows HTTPS URLs from github.com domains
  • Repository slug validation: Enforces GitHub username/repo naming rules
  • Sanitization: sanitizeRepoName() removes dangerous characters
  • Git user config: Sets local git config to avoid relying on global settings

Code Quality

  • Excellent test coverage: 63 tests covering validation, parsing, caching, state operations
  • Error handling: Proper error types with SymphonyError class and descriptive error messages
  • Documentation: SYMPHONY_ISSUES.md and SYMPHONY_REGISTRY.md provide clear guidance for maintainers
  • Consistent patterns: Follows existing Maestro patterns (useMarketplace, Usage Dashboard)
  • Cache strategy: Smart caching with 2-hour TTL for registry, 5-min for issues

Performance

  • Shallow clones: Uses --depth=1 for faster repository cloning
  • Cached API responses: Reduces GitHub API calls with proper TTL management
  • 1MB issue body limit: Prevents performance issues from large issue descriptions
  • Debounced updates: Real-time updates use debouncing to avoid excessive re-renders

🔍 Issues & Concerns

1. ReDoS Vulnerability (Fixed)

✅ Good catch in commit caeb218 fixing the ReDoS vulnerability in document path regex patterns. The original patterns could have caused exponential backtracking with malicious input.

2. Missing Input Validation

Location: symphony.ts:131-164 (validateContributionParams)

The validation doesn't check:

  • contributionId format/length
  • sessionId format/length
  • issueTitle length (could be arbitrarily long)
  • Empty repoName string (only checks truthy)

Recommendation: Add explicit validation:

if (!params.contributionId || params.contributionId.length > 100) {
  return { valid: false, error: 'Invalid contribution ID' };
}
if (!params.issueTitle || params.issueTitle.length > 500) {
  return { valid: false, error: 'Issue title too long' };
}

3. GitHub CLI Authentication Not Enforced

Location: symphony-runner.ts:93-127 (createDraftPR)

The code calls gh pr create but doesn't verify gh is authenticated beforehand. This could fail silently after cloning and branching.

Recommendation: Add authentication check before starting contribution:

// Check gh CLI auth status
const authResult = await execFileNoThrow('gh', ['auth', 'status']);
if (authResult.exitCode !== 0) {
  return { success: false, error: 'GitHub CLI not authenticated. Run: gh auth login' };
}

4. Race Condition in PR Creation

Location: App.tsx - symphony:prCreated event listener

If multiple Symphony sessions complete simultaneously, there could be race conditions updating session metadata. The event handler updates sessions by ID but doesn't use locks or atomic operations.

Recommendation: Add session update mutex or use a queue for session updates.

5. Incomplete Cleanup on Failure

Location: symphony-runner.ts:18-25 (cleanupLocalRepo)

The cleanup function logs warnings but doesn't propagate failures. If cleanup fails due to permissions, locked files, etc., orphaned directories accumulate.

Recommendation:

  • Track failed cleanups and alert user
  • Implement retry logic with exponential backoff
  • Consider background cleanup task for orphaned directories

6. fetch() Without Timeout

Location: Multiple places (registry fetch, document downloads, issue fetching)

All fetch() calls lack timeout configuration, potentially hanging indefinitely on slow networks.

Recommendation: Add timeout wrapper:

const fetchWithTimeout = (url: string, timeout = 10000) => {
  return Promise.race([
    fetch(url),
    new Promise((_, reject) => 
      setTimeout(() => reject(new Error('Request timeout')), timeout)
    )
  ]);
};

7. Missing Rate Limit Handling

Location: GitHub API calls in symphony.ts

GitHub API has rate limits (60/hour unauthenticated, 5000/hour authenticated). The code doesn't check rate limit headers or handle 403 rate limit responses.

Recommendation:

  • Parse X-RateLimit-Remaining header
  • Show user-friendly message when rate limited
  • Implement exponential backoff for retries

8. Large Document Memory Risk

Location: symphony-runner.ts:132-146 (downloadFile)

Downloads entire file to memory with response.arrayBuffer(). Large documents (100MB+ attachments) could cause OOM errors.

Recommendation: Stream large files to disk:

const stream = fs.createWriteStream(destPath);
response.body?.pipe(stream);

9. Hard-Coded Git Config

Location: symphony-runner.ts:60-72 (configureGitUser)

Sets user.name to "Maestro Symphony" and email to symphony@runmaestro.ai. This overwrites user's repo-specific config and attributes all commits to Maestro.

Recommendation: Use user's global git config if available, only fallback to default:

const globalName = await execFileNoThrow('git', ['config', '--global', 'user.name']);
const name = globalName.exitCode === 0 ? globalName.stdout.trim() : 'Maestro Symphony';

10. Type Inconsistencies

Location: symphony-types.ts:258-266 (CompletedContribution)

Has both merged?: boolean and wasMerged?: boolean fields - appears to be a legacy migration issue.

Recommendation: Standardize on wasMerged and add migration code to convert old data.

🔒 Security Considerations

Already Addressed ✅

  • Path traversal validation
  • GitHub URL validation
  • Repository slug validation
  • Character sanitization

Additional Recommendations

  1. CSP for External Documents: External markdown documents could contain malicious scripts. Ensure markdown renderer sanitizes HTML.

  2. SSRF Protection: When fetching external URLs, validate they're from trusted domains (github.com, githubusercontent.com).

  3. Command Injection: The execFileNoThrow usage is safe (no shell), but verify all git operations use array args, never string concatenation.

  4. Token Exposure: Ensure GitHub tokens aren't accidentally logged in error messages or analytics.

🎯 Performance Considerations

Good Practices ✅

  • Shallow git clones
  • Cached API responses
  • Debounced UI updates
  • 1MB issue parsing limit

Optimization Opportunities

  1. Parallel Document Processing: Could process multiple Auto Run documents in parallel where dependencies allow.

  2. Incremental Fetch: Instead of fetching all issues at once, implement pagination/cursor-based fetching for repos with 100+ issues.

  3. Virtual Scrolling: Repository/issue lists could use virtual scrolling for large registries.

📝 Code Quality & Best Practices

Excellent ✅

  • Comprehensive test coverage (63 tests)
  • TypeScript strict mode compliance
  • Clear separation of concerns
  • Consistent error handling
  • Detailed inline documentation
  • Follows project conventions from CLAUDE.md

Suggestions

  1. Extract Magic Numbers: Constants like 100 (max repo name length), 500 (max issue title) should be named constants.

  2. Reduce Modal Size: SymphonyModal.tsx is 1,807 lines. Consider splitting into sub-components:

    • ProjectsTab.tsx
    • ActiveTab.tsx
    • HistoryTab.tsx
    • StatsTab.tsx
  3. Add JSDoc: Public functions in hooks lack JSDoc comments explaining parameters and return values.

🧪 Test Coverage

Excellent test coverage with 63 passing tests covering:

  • ✅ Validation helpers
  • ✅ Document path parsing
  • ✅ Cache operations
  • ✅ State operations
  • ✅ IPC handler registration

Missing Coverage:

  • End-to-end contribution flow (clone → PR → complete)
  • Error scenarios (network failures, git errors)
  • React component testing (SymphonyModal, hooks)
  • Race condition scenarios

📊 Impact Assessment

User Experience

  • Positive: Opens new contribution opportunities, gamification via stats
  • Risk: Complex feature may confuse new users - needs good onboarding

Maintainability

  • Positive: Well-structured, follows existing patterns
  • Risk: Large feature surface area requires ongoing maintenance

Performance

  • Positive: Good caching strategy, shallow clones
  • Risk: Multiple concurrent Symphony sessions could strain resources

🎓 Recommendations

Must Fix Before Merge

  1. ✅ ReDoS vulnerability (already fixed in caeb218)
  2. Add GitHub CLI authentication check before contribution start
  3. Add timeout to all fetch() calls
  4. Fix type inconsistency (merged vs wasMerged)

Should Fix Soon

  1. Improve cleanup error handling with retry logic
  2. Add rate limit detection and user-friendly messaging
  3. Stream large document downloads instead of in-memory
  4. Add input length validation for IDs and titles

Nice to Have

  1. Split SymphonyModal into sub-components
  2. Add end-to-end integration tests
  3. Use user's git config when available
  4. Implement parallel document processing

✨ Final Verdict

This is a high-quality feature implementation with excellent architecture, proper security considerations, and comprehensive test coverage. The code follows project conventions and demonstrates thoughtful design decisions like deferred PR creation and external document support.

The issues identified are mostly minor security/reliability improvements rather than blocking problems. With the fixes to must-fix items (particularly authentication check and fetch timeouts), this PR is ready for merge.

Recommendation: ✅ Approve with minor revisions


Great work on this feature! The Symphony system has the potential to create a vibrant open source contribution ecosystem. 🎵

Reviewed with attention to security, performance, code quality, and architectural best practices.

@claude
Copy link

claude bot commented Jan 9, 2026

Code Review - Symphony Token Donation Feature

This is a substantial and well-architected addition to Maestro. The implementation demonstrates strong security awareness, excellent test coverage, and adherence to project conventions.


✅ Strengths

1. Security-First Design

  • Path traversal prevention with proper sanitization
  • URL validation restricting to HTTPS GitHub URLs only
  • Repository slug validation with GitHub username/repo format enforcement
  • Consistent use of execFileNoThrow (never shell-based commands)
  • ReDoS attack prevention with bounded repetition in regex patterns
  • 1MB cap on issue body parsing to prevent DoS
  • Comprehensive parameter validation before operations

2. Test Coverage

  • 81 test cases covering validation, parsing, cache, state, and lifecycle
  • Tests verify security validations work correctly
  • Proper mocking strategy
  • All tests passing per PR description

3. Code Quality

  • Clean separation of concerns (handlers, runner service, types, constants)
  • Comprehensive TypeScript types
  • Custom SymphonyError class with typed error categories
  • Consistent structured logging
  • Smart caching with TTLs (2hr registry, 5min issues)
  • Broadcast pattern for real-time UI updates

4. Architecture Patterns

  • Deferred PR creation avoiding no commits between branches error
  • Auto-completion flow marking PRs ready when Auto Run completes
  • External document downloads to cache (keeps repos clean)
  • Reliable contribution tracking via metadata.json
  • Worktree support integration

5. Documentation

  • Excellent inline comments explaining complex logic
  • Comprehensive CLAUDE.md updates with architecture details
  • SYMPHONY_ISSUES.md and SYMPHONY_REGISTRY.md for maintainers
  • JSDoc comments on interfaces

@claude
Copy link

claude bot commented Jan 9, 2026

Areas for Consideration

1. Performance and Scalability

Issue Pagination Missing
fetchIssues() fetches all issues in one request. GitHub defaults to 30 items per page, so repos with 30+ Symphony issues need pagination support.

Rate Limiting
No GitHub API rate limit handling. While 5-minute cache helps, rapid refreshes could hit limits (60/hr unauthenticated, 5000/hr authenticated).

Recommendation: Add rate limit detection via X-RateLimit-Remaining header, optionally support GitHub PAT.

2. Error Recovery

Incomplete Cleanup on Failure
In symphony-runner.ts:245-249, if operations fail after creating a draft PR, the PR remains open while local repo is cleaned up.

Recommendation: Track PR creation separately and close orphaned PRs on failure.

3. Code Duplication

Duplicate PR Creation Logic
PR creation exists in both symphony.ts:343-372 and symphony-runner.ts:92-127 with slight differences.

Recommendation: Consolidate into shared utility function.

4. Type Safety Edge Cases

Merged vs WasMerged
CompletedContribution has both merged and wasMerged for backward compatibility, but no migration logic ensures consistency.

DocumentReference Validation
External documents skip path traversal validation (correct), but no validation that isExternal documents have valid URLs.

Recommendation: Validate external document URLs are valid GitHub URLs before download.

5. User Experience

No Progress During Clone
Large repos can take time even with shallow clone. UI shows Cloning but no progress percentage.

Worktree Clarification
CLAUDE.md mentions Symphony works with worktrees, but no explicit worktree handling visible in runner.

Clarification needed: Document whether Symphony uses worktrees by default.

@claude
Copy link

claude bot commented Jan 9, 2026

Potential Bugs

1. symphony-runner.ts:293

Checks for nothing to commit in stderr, but git typically outputs this to stdout.

Fix: Check both stdout and stderr for the message.

2. Race Condition in Stats

symphony:getStats aggregates active contributions real-time. If contribution completes during calculation, tokens could be counted twice.

Mitigation: Likely minor in practice due to atomic reads, but timestamps could prevent this.


Future Enhancements

  1. Contribution templates per repo category
  2. Dry run mode to preview documents
  3. PR commenting with progress updates
  4. Public leaderboard (opt-in)
  5. Multi-issue PR support

Final Verdict

This PR is high-quality and production-ready. Security measures, test coverage, and architecture are exemplary. Issues identified are minor nice-to-haves rather than blockers.

Recommendations Before Merge:

  1. Fix nothing to commit check (Bug 1) - low effort
  2. Add PR cleanup on runner failures
  3. Validate external document URLs
  4. Add pagination for issue fetching

Can Merge With:

  • Documentation clarification on worktree behavior
  • Future issues filed for rate limiting and progress indication

Overall Rating: 9/10 - Excellent work! 🎉


Review conducted using CLAUDE.md conventions, focused on security, performance, and maintainability.

@claude
Copy link

claude bot commented Jan 9, 2026

Code Review: Symphony Token Donation System

I've completed a thorough review of PR #122. This is a substantial feature addition (32 files changed, ~10k lines added). Overall, the implementation is solid with good security practices, but I have several recommendations.

Strengths

Security

  • Excellent input validation with dedicated functions (sanitizeRepoName, validateGitHubUrl, validateRepoSlug)
  • Proper use of execFileNoThrow throughout - avoiding shell injection
  • Path traversal protection for document paths
  • ReDoS protection in regex patterns
  • HTTPS-only enforcement and hostname validation

Architecture

  • Well-structured type system with comprehensive interfaces
  • Proper separation of concerns
  • Caching strategy with reasonable TTLs (2hr registry, 5min issues)
  • Comprehensive test coverage (2,035 lines)
  • Consistent with codebase patterns per CLAUDE.md

Code Quality

  • Extensive documentation
  • Error handling with custom SymphonyError class
  • Real-time updates via IPC
  • Colorblind-accessible status colors

Issues & Recommendations

1. GitHub API Rate Limiting (HIGH PRIORITY)

No rate limit handling for GitHub API calls. Unauthenticated requests have a 60/hour limit. Recommend adding:

  • Rate limit detection from response headers
  • User-facing error messages
  • Optional GitHub token support (5,000/hour)
  • Exponential backoff

2. External Document Download Validation (MEDIUM PRIORITY)

External document URLs are not validated before download (line 1724). Could enable SSRF attacks. Recommend:

  • Whitelist only GitHub domains
  • Add size limits (10MB max)
  • Validate URLs before fetch

3. Error Recovery in Cleanup (LOW PRIORITY)

Silent error suppression in cleanup (line 1037). Recommend logging failures for debugging.

Security Summary

Area Status Notes
Input Validation ✅ Excellent Comprehensive
Command Injection ✅ Secure Proper execFileNoThrow usage
Path Traversal ✅ Protected Validates paths
SSRF ⚠️ Needs Work External downloads not validated
Rate Limiting ⚠️ Missing No GitHub API rate limit handling
ReDoS ✅ Protected Bounded patterns

Testing Recommendations

  1. Rate limit handling - rapidly refresh issues
  2. Malicious document paths
  3. Network failures
  4. Large repos (50+ issues)
  5. External docs with various URLs
  6. Concurrent contributions

Final Verdict

Approve with minor changes

High-quality work! The two medium-priority issues should be addressed before merging. Architecture is solid, security mostly excellent, code follows best practices.

Merge checklist:

  • Add GitHub API rate limit handling
  • Validate external document URLs
  • Add logging for cleanup failures
  • Test rate limit scenarios

Great work! Symphony is well-architected and will be a valuable addition to Maestro. 🎵

- Added short flags -g (list agents) and -a (list playbooks) that were
  missing from documentation but exist in implementation
- Documented the clean playbooks command with --dry-run option (was
  completely undocumented)
- Clarified that list agents --json outputs a JSON array, not JSONL
  (different from other list commands)
- Updated JSON event examples to include missing fields: collapsed in
  group events, document in document_complete events
- Added loop_complete event type in JSON output examples
- Added success, usageStats, and totalCost fields to JSON examples
- Changed "Appearance: Font size, UI density" to "Themes" (there is no
  Appearance tab - themes have their own tab, fonts are in General)
- Changed "SSH Remotes" to "SSH Hosts" to match actual tab name
- Updated General tab description to include all settings (font family,
  terminal width, log buffer, shell config, stats, document graph, etc.)

Verified accurate: storage paths, cross-device sync, sleep prevention,
notifications, and pre-release channel sections.
- Add "Requires Session" column to Tab Menu table with availability conditions
- Add missing tab menu actions: Export as HTML, Publish as GitHub Gist, Move to First/Last Position
- Fix Tab Export section to reference "Export as HTML" instead of "Context: Copy to Clipboard"
- Change "Right-click" to "Hover over" in three sections (hover overlay, not right-click menu)
- Correct Command Palette labels to match actual QuickActionsModal implementation
- Document alternative sharing options (Copy to Clipboard, Publish as GitHub Gist)
## CHANGES
- Re-organized "Opening the Document Graph" section to put "From File Preview"
  first as the primary entry point (Cmd+Shift+G)
- Fixed misleading description of graph icon in Files tab - it only appears
  after a graph has been opened at least once, and is a branch icon not
  "circular arrows"
- Added "From File Context Menu" option for right-clicking markdown files
- Removed "Tab - Cycle through connected nodes" from keyboard shortcuts -
  this feature was documented but NOT implemented in the code
- Fixed Enter key behavior documentation: "Recenter view" for document nodes,
  "Open URL" for external link nodes
- Updated Depth Control section to document full range (0-5) including
  Depth 0 = "All" option which was undocumented
- Added missing Cmd/Ctrl+F keyboard shortcut for focusing search field
- Fixed minor typo: "positions are saved" removed (not fully accurate)
- Fixed theme count from 12 to 17 (6 dark, 6 light, 4 vibe, 1 custom)
- Listed all theme names for each category
- Clarified provider support: Claude Code, Codex (OpenAI), OpenCode are
  fully-integrated; Aider, Gemini CLI, Qwen3 Coder are planned
- Verified all other features and shortcuts match source code
- Fixed Agent Status Indicators: Yellow is used for both "thinking" AND
  "waiting for user input" states, not just thinking
- Fixed File Editing section: incorrectly claimed auto-save. Files do NOT
  auto-save; users must press Cmd+S/Ctrl+S. Confirmation dialog appears
  when closing with unsaved changes
- Fixed Collapsed Mode shortcut: was Cmd+B/Ctrl+B, actual shortcut is
  Opt+Cmd+Left/Alt+Ctrl+Left per shortcuts.ts
- Added missing Prompt Composer keyboard shortcut Cmd+Shift+P/Ctrl+Shift+P
Changed "OpenAI Codex" to "Codex (OpenAI)" to match the actual agent name defined in agent-detector.ts source code.
- Correct "Managing Worktrees" section UI descriptions:
  - Branch icon is GitBranch, not a green checkmark
  - Collapse/expand is via worktree count band, not a chevron on parent
  - Describe drawer styling with accent background

- Improve "Creating a Worktree Sub-Agent" section:
  - Document both access methods (header hover and context menu)
  - Rename "Watch for Changes" to "Watch for new worktrees"
  - Add note about quick creation via context menu

- Add missing "Duplicate..." action to Worktree Actions table
- Added Beta notice callout (feature shows "Beta" badge in UI)
- Fixed "How It Works" section: added keyboard shortcut (Opt+Cmd+C),
  Quick Actions option, and moderator selection step
- Added Tip callout explaining auto-add participants via @mentions
- Added note about hyphenated names for @mentions with spaces
- Added "Managing Group Chats" section with context menu options
- Added "Input Features" section (read-only, images, prompt composer, etc.)
- Changed inconsistent dashes to em-dashes for consistency
Changed "OpenAI Codex" to "Codex (OpenAI)" in the main documentation
index page to match the actual agent name in agent-detector.ts line 76.
This is consistent with corrections already made to getting-started.md
and features.md.

Verified that the agent support list is accurate:
- Claude Code, Codex, OpenCode: fully integrated (verified capabilities)
- Aider, Gemini CLI, Qwen3 Coder: defined as placeholders for future
- Added portable .exe option for Windows and architecture details for macOS/Linux
- Changed "OpenAI Codex" to "Codex" to match agent-detector.ts naming convention
- Added planned agents (Aider, Gemini CLI, Qwen3 Coder) with repository links
- Added "Building from Source" section with Node.js 22+ requirement
- Used em-dashes for consistency with other documentation files
- Fixed v0.14.5 release date from "January 1, 1" to "January 11, 2026"
- Added v0.14.5 changelog content (was empty)
- Updated previous releases list with v0.14.5 as draft
- Fixed v0.6.x auto-save claim (documents require manual save)
- Fixed v0.12.x "tab right-click menu" to "tab hover overlay menu"
- Fixed typo "received" to "receive"
- Draft PR creation is now deferred until the first commit lands ⏳
- PR info now syncs from contribution metadata into state automatically 🔄
- Creating a draft PR now updates both metadata.json and state.json reliably 🗃️
- Symphony adds new `completed` contribution status across types and UI ✅
- Active contribution duration now displays real timeSpent-based timing accurately ⌛
- Symphony issue cards now link directly to claimed PRs externally 🔗
- Playbook Exchange adds richer keyboard navigation and cross-platform shortcuts ⌨️
- Playbook imports now include optional assets/ folder and remote-session guidance 📦
- Troubleshooting upgrades: richer logs, process tree monitor, and error recovery 🛠️
- Prevented double-counting contributions within the same week 🧯
- Added robust weekly streak tests, covering gaps and record updates 🧪
- External `target="_blank"` links now open in your system browser 🌐
- ProcessManager now validates working directory existence with clear errors 🧰
- Standardized cwd handling via tilde expansion before spawning processes 🧭
- Agent creation now resolves real home directory to avoid `~` pitfalls 🏠
- Achievement share image now showcases Symphony stats and earned badges 🖼️
- Symphony contribution cards gained merged/closed compatibility plus token display 🧾
- Symphony dashboard now includes Tasks metric and shows streaks in weeks 📊
…ra height 📏

- Added extra padding above Symphony section for cleaner visual separation 🧼
- Renamed Symphony header to highlight token donation participation messaging 🎶
- Removed Symphony achievements icon row for a more focused stats layout 🧩
- Dropped earned-achievements counting logic from Symphony rendering path 🧠
- Updated memo dependencies to stop tracking removed Symphony achievements state 🔗
- Tests now mock `useContributorStats` to stabilize Symphony-related rendering 🎭
- Cycle Symphony modal tabs with ⌘⇧[ / ⌘⇧] keyboard shortcut! 🔁
- Added wraparound tab navigation for seamless forward/back switching! 🧭
- Updated modal help text to advertise the new tab-cycling shortcut! 📝
After rebase onto main, the preload.ts file was refactored into modular
files in src/main/preload/. This commit adds:

- src/main/preload/symphony.ts: Symphony API factory function
- Updates to preload/index.ts to export and wire up Symphony API
- Updates to global.d.ts with full Symphony type definitions
- Fix null coalescing for optional checkPRStatuses response fields
@claude
Copy link

claude bot commented Jan 22, 2026

Code Review: Symphony Token Donation System

Thank you for this comprehensive feature implementation! I've completed a thorough review of the Symphony system. Overall, the feature is well-architected with excellent documentation and extensive test coverage (10,061 test lines!), but there are several critical issues that need attention before production deployment.

📊 Review Summary

  • Lines Changed: +18,994 / -306
  • Test Coverage: 324 test cases across 7 test files
  • Critical Issues Found: 5 security vulnerabilities
  • Performance Issues: 6 optimization opportunities
  • Overall Assessment: ⚠️ Needs revisions before merge

🔴 Critical Security Issues

1. Path Traversal Vulnerability

Location: src/main/ipc/handlers/symphony.ts:1820-1825

Issue: Uses path.resolve() for path traversal protection, which can be bypassed:

const resolvedSource = path.resolve(localPath, doc.path);
if (!resolvedSource.startsWith(localPath)) {
  logger.error('Attempted path traversal in document path', LOG_CONTEXT, { docPath: doc.path });
  continue;
}

Problem: path.resolve() can be bypassed with carefully crafted paths containing symbolic links or Windows path formats.

Recommendation:

// Normalize and validate before resolving
const normalizedPath = path.normalize(doc.path);
if (normalizedPath.includes('..') || path.isAbsolute(normalizedPath)) {
  throw new Error('Invalid document path');
}
const resolvedSource = path.join(localPath, normalizedPath);
if (!resolvedSource.startsWith(path.resolve(localPath) + path.sep)) {
  throw new Error('Path traversal detected');
}

2. Missing GitHub Token Authentication

Location: src/main/ipc/handlers/symphony.ts:413-417

Issue: GitHub API calls lack authentication, causing aggressive rate limiting (60 req/hour):

const response = await fetch(url, {
  headers: {
    'Accept': 'application/vnd.github.v3+json',
    'User-Agent': 'Maestro-Symphony',
  },
});

Impact: Users will hit rate limits quickly when browsing Symphony projects.

Recommendation:

  • Add optional GitHub PAT support via settings
  • Store token securely (system keychain)
  • Use authenticated requests when token available (5000 req/hour)
  • Add rate limit tracking and user-friendly warnings

3. Incomplete Git User Configuration Validation

Location: src/main/services/symphony-runner.ts:60-72, 230

Issue: Git config returns false on failure but calling code ignores the return value:

// Sets config but doesn't verify success
const configured = await this.configureGitUser(localPath);
// Line 230: Ignores return value!

Impact: Commits will fail with cryptic errors if git user.name/user.email aren't set.

Recommendation:

const configured = await this.configureGitUser(localPath);
if (!configured) {
  throw new Error('Failed to configure git user. Please set git user.name and user.email globally.');
}

4. Potential Command Injection in PR Creation

Location: src/main/ipc/handlers/symphony.ts:649-651

Issue: Issue title/body passed to gh CLI without sanitization:

['pr', 'create', '--draft', '--base', baseBranch, '--head', branchName, '--title', title, '--body', body]

Risk: While execFileNoThrow prevents shell injection, malicious issue titles with special characters could cause gh CLI parsing errors.

Recommendation: Sanitize or validate title/body strings, or use gh pr create --body-file to avoid parsing issues.

5. Incomplete Remote Branch Cleanup

Location: src/main/ipc/handlers/symphony.ts:1042-1055, 658

Issue: Creates and pushes branch before PR creation, but cleanup only removes local directory:

// Branch is pushed at line 638
await execFileNoThrow('git', ['push', 'origin', branchName], { cwd: localPath });

// PR creation fails at line 650+
// Cleanup at line 658 only removes directory
await fs.rm(localPath, { recursive: true, force: true });
// Remote branch remains orphaned!

Recommendation: Add explicit remote branch deletion on all failure paths after push.


🟡 Error Handling Issues

1. Silent Document Download Failures

Location: src/main/ipc/handlers/symphony.ts:1804-1818

Documents silently fail to download and contribution continues with incomplete data. Users won't discover missing documents until processing starts.

Recommendation: Collect all failures and either fail the operation entirely or return warnings in the response.

2. Race Condition in PR Status Updates

Location: src/main/ipc/handlers/symphony.ts:1542-1566

Syncs PR info from metadata.json without file locking. Concurrent modifications could cause data loss.

Recommendation: Implement atomic file writes with temp file + rename pattern, or add file locking.

3. Week Streak Calculation Logic Error

Location: src/main/ipc/handlers/symphony.ts:1388-1404

Week transition logic may not increment streak correctly when contributing on Sunday of week N and Monday of week N+1.

Recommendation: Add comprehensive tests for week boundary edge cases, or use day-based tracking.


⚡ Performance Issues

1. O(n²) Issue-PR Matching with Unnecessary Regex Creation

Location: src/main/ipc/handlers/symphony.ts:501-525

Creates new RegExp objects inside nested loop:

for (const pr of prs) {
  const prText = `${pr.title} ${pr.body || ''}`;
  for (const issue of issues) {
    const patterns = [
      new RegExp(`#${issue.number}\\b`),  // Created N*M times!
      new RegExp(`\\(#${issue.number}\\)`),
    ];

Impact: With 100 PRs × 50 issues = 10,000 regex creations per call.

Recommendation:

// Build map once outside loop
const prTexts = new Map(prs.map(pr => [pr.number, `${pr.title} ${pr.body || ''}`]));
const issuePatterns = new Map(issues.map(issue => [
  issue.number,
  [new RegExp(`#${issue.number}\\b`), new RegExp(`\\(#${issue.number}\\)`)]
]));

2. Sequential Document Downloads

Location: src/main/ipc/handlers/symphony.ts:1801-1834

Downloads documents one at a time instead of in parallel.

Impact: 10 documents at 2s each = 20s total instead of ~2s with parallelization.

Recommendation: Use Promise.all() with concurrency limit (e.g., 5 concurrent downloads).

3. Excessive State File Writes

Location: src/main/ipc/handlers/symphony.ts:1240-1252

Updates state file on every progress update.

Impact: Excessive disk I/O during active contributions.

Recommendation: Debounce writes (e.g., max once per 5 seconds) or batch updates.

4. Uncached GitHub API Calls

Location: src/main/ipc/handlers/symphony.ts:1470-1657

checkPRStatuses fetches PR status for every history entry on every call with no caching.

Recommendation: Cache results for 5 minutes, add rate limit tracking.


📋 Code Quality Issues

1. God Component

Location: src/renderer/components/SymphonyModal.tsx (2,146 lines)

Component handles too many responsibilities: repository browsing, issue listing, contribution management, stats display, PR status checking.

Recommendation: Split into focused components:

  • ProjectsTab.tsx, ActiveTab.tsx, HistoryTab.tsx, StatsTab.tsx
  • RepositoryGrid.tsx, IssueList.tsx, DocumentPreview.tsx

2. Long IPC Handler Function

Location: src/main/ipc/handlers/symphony.ts:972-1126 (154 lines)

The symphony:start handler is too long and mixes concerns.

Recommendation: Extract subfunctions:

  • cloneRepository()
  • createContributionBranch()
  • createDraftPR()

3. Mixed Business Logic and UI

Location: src/renderer/components/SymphonyModal.tsx:1156-1404

Business logic (PR status checking, contribution finalization) is embedded in UI component.

Recommendation: Move to custom hooks or service layer for better testability.


✅ Test Coverage Analysis

Strengths:

  • Excellent path traversal testing (multiple attack vectors)
  • Comprehensive URL validation (javascript:, file:, data: URIs)
  • Good input sanitization (XSS, SQL injection, command injection)
  • Extensive error handling tests (network, git, filesystem)

Critical Gaps:

❌ Token/Credential Security Tests Missing

Location: src/__tests__/main/ipc/handlers/symphony.test.ts:1563-1629

Tests verify gh auth status but don't test:

  • Token leakage in error messages/logs
  • Expired token scenarios
  • Token scope validation
  • Mid-session token revocation

❌ Race Condition Test Accepts Data Loss

Location: src/__tests__/main/ipc/handlers/symphony.test.ts:1770-1848

it('should handle concurrent state updates without file corruption', async () => {
  // Note: Due to read-modify-write race conditions, some entries may be lost,
  // but the file structure should remain valid JSON

This is concerning! The test explicitly accepts data loss in concurrent scenarios. This needs proper locking or atomic operations.

❌ Atomic File Operations Not Properly Tested

Location: src/__tests__/integration/symphony.integration.test.ts:2874-2915

Test claims to verify atomic writes but only checks that final JSON is valid, not that writes are actually atomic (no simulation of interrupted writes).


💡 Positive Highlights

  1. 📚 Excellent documentation - SYMPHONY_ISSUES.md and SYMPHONY_REGISTRY.md are comprehensive
  2. 🧪 Extensive test coverage - 10,061 lines of tests covering most scenarios
  3. 🎨 Well-structured types - symphony-types.ts is clean and well-organized
  4. 🔌 Clean IPC architecture - Proper separation of concerns between main/renderer
  5. ♿ Accessibility - Good keyboard navigation and ARIA labels
  6. 📊 Stats tracking - Comprehensive contributor statistics and leaderboard

🎯 Recommendations Before Merge

Must Fix (Blocking):

  1. ✋ Fix path traversal vulnerability
  2. ✋ Add git config validation error handling
  3. ✋ Implement proper remote branch cleanup on failures
  4. ✋ Add token security tests (leakage prevention, expiration)
  5. ✋ Fix race condition handling (don't accept data loss)

Should Fix (High Priority):

  1. Add GitHub token authentication support
  2. Optimize O(n²) issue-PR matching
  3. Parallelize document downloads
  4. Add atomic file operations with proper testing
  5. Split SymphonyModal into smaller components

Nice to Have:

  1. Add rate limit tracking and warnings
  2. Debounce state file writes
  3. Extract long functions into smaller pieces
  4. Add JSDoc to complex algorithms

📝 Final Verdict

This is a well-designed feature with excellent potential, but it has several security and reliability issues that need addressing before production use. The test coverage is impressive in breadth, but has critical gaps in concurrent operation safety and credential handling.

Priority: Fix the 5 blocking security issues and add proper concurrent operation handling, then this will be ready to merge.

Great work on the documentation and overall architecture! 🎉

- Added Music icon import to SessionList.tsx
- Added setSymphonyModalOpen to HamburgerMenuContentProps
- Added Symphony button between Usage Dashboard and divider
- Updated SessionListProps with setSymphonyModalOpen
- Updated useSessionListProps hook to pass Symphony setter
- Extracted symphonyModalOpen from ModalContext in App.tsx
- Import SymphonyModal and SymphonyContributionData
- Add SymphonyModal component with full onStartContribution handler
- Add symphonyMetadata to Session interface in types/index.ts
- Import and re-export SymphonySessionMetadata from shared types
- Fix registerActive call to use totalDocuments instead of documentPaths
- Fix setRightPanelTab to setActiveRightTab
The Symphony handlers were defined but never called in src/main/index.ts.
Added import and invocation of registerSymphonyHandlers with app and
getMainWindow dependencies.
The handler expects { url: string } but preload was passing just the
url string directly. This caused "Invalid URL" errors when trying to
preview document content.
- Add symphony API mock to test setup (getRegistry, getIssues, getState, etc.)
- Add Music and Server icons to SessionList test mocks
- Add setSymphonyModalOpen prop to SessionList test defaults

All 16,138 tests now pass.
Add the Symphony hotkey (⌘⇧Y) and command palette entry that were lost
during the rebase. Changes include:
- Add onOpenSymphony to QuickActionsModalProps and command palette actions
- Add onOpenSymphony prop chain through AppModals to App.tsx
- Add setSymphonyModalOpen to keyboard handler context
- Add openSymphony shortcut handler in useMainKeyboardHandler
The handler expected documentPaths[] but preload/App.tsx send totalDocuments.
Changed handler to accept totalDocuments directly since only the count is needed.
@pedramamini pedramamini marked this pull request as ready for review January 30, 2026 23:29
@pedramamini pedramamini added the RC Getting soak time in RC branch now label Jan 30, 2026
@pedramamini pedramamini merged commit edd41fd into main Feb 3, 2026
1 check passed
@pedramamini pedramamini deleted the token-donations branch February 7, 2026 01:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

RC Getting soak time in RC branch now

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

Comments