Implements robust handling for invalid image formats (like 'bmp', 'gif', 'webp') that bypass schema validation:
- Added defensive format validation in image tool handler
- Automatic path correction to ensure file extensions match actual format used
- Warning messages in response when format fallback occurs
- Comprehensive unit and integration test coverage for edge cases
This ensures invalid formats automatically fall back to PNG as requested, preventing
Swift CLI rejection and incorrect file extensions in output paths.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Add preprocessing to handle JSON string arrays from MCP clients
- Support multiple input formats: JSON string, comma-separated, single value
- Handle empty strings and null/undefined values gracefully
- Add comprehensive test coverage for all parsing scenarios
- Fixes "Expected array, received string" error when MCP clients send JSON string arrays
This resolves the issue shown in the test screenshot where include_window_details
was sent as '["ids", "bounds", "off_screen"]' (JSON string) instead of a proper array.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Update README.md to clearly explain that screen captures cannot use format: "data"
- Clarify that screen captures always save to files (temp or specified path)
- Update spec.md to distinguish behavior between app window captures and screen captures
- Make it clear that empty format string defaults to PNG file format for screen captures
- Address confusion where documentation suggested format defaults to "data" when path not given
This resolves the apparent contradiction between documentation and actual behavior
shown in the test screenshot where format: "" resulted in file saving rather than
data format for a screen capture.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Update all test assertions to expect the new three-parameter signature
- Add expect.objectContaining({ timeout: expect.any(Number) }) to all executeSwiftCli assertions
- Fixed 37 test assertions across image.test.ts, image-edge-cases.test.ts, and image-tool.test.ts
- All tests now pass (297 tests passed, 17 skipped)
This completes the integration of PR #2's timeout functionality by ensuring all tests match the new function signature.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Adds configurable timeout support via PEEKABOO_CLI_TIMEOUT env var
- Implements proper SIGTERM/SIGKILL handling for stuck processes
- Updates tests for Linux compatibility
- Fixes hanging issues when permission dialogs appear
Co-authored-by: codegen-sh[bot] <131295404+codegen-sh[bot]@users.noreply.github.com>
The complex JSON parsing logic that handled multiple JSON objects was only
needed because ApplicationFinder was incorrectly outputting errors directly.
Now that the root cause is fixed (ApplicationFinder only throws errors),
we can simplify the TypeScript code to just parse single JSON responses.
This makes the codebase cleaner and error handling more predictable.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Enhanced CaptureError types to include underlying system errors
- Added comprehensive error logging in debug_logs for troubleshooting
- Fixed duplicate error output from ApplicationFinder
- Improved error details for app not found to show available applications
- Updated test expectations to match new error message formats
This ensures that errors from deep within ScreenCaptureKit and file operations
are properly surfaced to users with full context in the debug logs.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Only show window count when it's not 1 in list apps output
- Extract formatApplicationList method for better testability
- Fix Swift test compatibility with new CaptureError signatures
- Add comprehensive test coverage for window count display logic
This improves readability by reducing visual clutter for the common
case of apps with single windows.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Add timeout parameter to all executeSwiftCli calls
- Update image tool tests to include --capture-focus parameter
- All tests now pass (206 passed, 65 skipped as expected)
Fixes failing CI tests in Node.js 20.x environment.
- Removed duplicate catch block that was causing compilation errors
- Fixed missing closing brace in timeout handler
- Verified TypeScript tests now run correctly on Linux with Swift tests skipped
✅ **Merge Conflicts Resolved**
- Merged latest changes from main branch
- Resolved conflicts in docs/spec.md by keeping comprehensive specification
- Added PEEKABOO_CLI_TIMEOUT environment variable documentation
🧪 **Test Suite Updates for Linux Compatibility**
- Added platform-specific test skipping for Swift-dependent tests
- Created tests/setup.ts for global test configuration
- Updated vitest.config.ts with platform detection
- Modified integration tests to skip on non-macOS platforms:
- tests/integration/peekaboo-cli-integration.test.ts
- tests/integration/image-tool.test.ts
- tests/integration/analyze-tool.test.ts
📦 **New Test Scripts**
- `npm run test:unit` - Run only unit tests (any platform)
- `npm run test:typescript` - Run TypeScript tests, skip Swift (Linux-friendly)
- `npm run test:typescript:watch` - Watch mode for TypeScript-only tests
🌍 **Platform Support**
- **macOS**: All tests run (unit + integration + Swift)
- **Linux/CI**: Only TypeScript tests run (Swift tests auto-skipped)
- **Environment Variables**:
- `SKIP_SWIFT_TESTS=true` - Force skip Swift tests
- `CI=true` - Auto-skip Swift tests in CI
📚 **Documentation Updates**
- Added comprehensive testing section to README.md
- Documented platform-specific test behavior
- Added environment variable documentation for test control
This allows the TypeScript parts of Peekaboo to be tested on Linux while maintaining full test coverage on macOS.
- Add PEEKABOO_CLI_TIMEOUT to README.md environment variables table
- Add PEEKABOO_CLI_TIMEOUT to docs/spec.md environment variables section
- Include timeout variable in example configuration
- Document default value of 30000ms (30 seconds)
- Explain purpose: prevents hanging processes during Swift CLI operations
- Replace unreliable process.killed check with signal 0 test
- Use try-catch around all process.kill() calls
- Properly detect if process is still running before SIGKILL
- Fixes bug where SIGKILL was never sent to stuck processes
The process.killed property is set immediately when process.kill()
is called, regardless of actual process termination. Using signal 0
to test process existence is the correct approach.
- Add configurable timeout to executeSwiftCli (default 30s)
- Add timeout support to execPeekaboo (default 15s)
- Support PEEKABOO_CLI_TIMEOUT environment variable
- Graceful process termination with SIGTERM then SIGKILL
- Skip E2E tests in CI environments and non-macOS platforms
- Add test timeouts to vitest config (60s tests, 30s hooks)
- Update tool handlers to use appropriate timeouts
- Prevent multiple promise resolutions with isResolved flag
- Enhanced error messages for timeout scenarios
- Update version from 1.1.2 to 1.0.0-beta.17 to match actual implementation
- Correct package name to @steipete/peekaboo-mcp
- Update log file default to ~/Library/Logs/peekaboo-mcp.log with fallback
- Document enhanced server status functionality with comprehensive diagnostics
- Add timing information for analyze tool
- Update tool schemas to match current Zod implementations
- Document enhanced path handling and error reporting
- Include metadata and performance features in tool descriptions
- Update environment variable defaults and behavior
- Reflect current MCP SDK version (v1.12.0+) and dependencies
- Added debug logging to PermissionsChecker when screen recording check fails
- Updated CHANGELOG with details about the permission error fixes
- This complements the previous commit that fixed overly broad error detection
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Extract permission error detection into a dedicated method
- Add specific error code checks for ScreenCaptureKit and CoreGraphics
- Improve directory existence check in saveImage method
- More reliable detection of screen recording permission denials
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
The image tool now properly handles:
- Case-insensitive format values (e.g., "PNG", "Png", "png" all work)
- "jpeg" as an alias for "jpg" format
- Invalid format values gracefully fall back to "png"
This is implemented through Zod schema preprocessing that normalizes
the format parameter before it reaches the Swift CLI, which only
accepts lowercase "png" and "jpg".
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Add .trim() to app_target when passing to Swift CLI
- Handles cases like " Spotify " correctly matching "Spotify"
- Applies to all app name formats including window specifiers
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Updated package.json version
- Added CHANGELOG entry for beta.19 release
Features in this release:
- Auto-fallback to PNG for invalid format values and screen captures
- Enhanced error messages showing all matching apps for ambiguous identifiers
🤖 Generated with Claude Code
Co-Authored-By: Claude <noreply@anthropic.com>
- Error messages now include the list of matching applications when multiple apps match an identifier
- Shows bundle IDs alongside app names to help users disambiguate (e.g., Calendar (com.apple.iCal))
- Applies to both image and list tools for consistent user experience
- Added comprehensive tests for error detail handling
This makes it much easier for users to understand which specific application to target when there are multiple matches.
🤖 Generated with Claude Code
Co-Authored-By: Claude <noreply@anthropic.com>
- Screen captures with format 'data' now auto-fallback to PNG to prevent stack overflow
- Invalid format values (empty strings, null, unrecognized) gracefully fall back to PNG
- Added comprehensive tests for format validation
- Updated documentation to reflect the new behavior
This provides a better user experience by handling edge cases gracefully instead of returning errors.
🤖 Generated with Claude Code
Co-Authored-By: Claude <noreply@anthropic.com>
- Screen captures now reject format: 'data' with clear error message
- Large screen images cause JavaScript stack overflow when base64 encoded
- Application window captures can still use format: 'data'
- Update tests and documentation to reflect this limitation
- Implement Levenshtein distance algorithm for fuzzy app name matching
- Handle common typos like "Chromee" → "Google Chrome"
- Add window-specific labels in analysis results
- Improve error messages with app name suggestions
- Fix TypeScript JSON parsing for error responses
- Update tests for new error message formats
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Remove trailing comma in test array
- Fix long line in error message
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Added new "auto" capture focus mode that intelligently brings windows to foreground only when needed
- Changed default capture_focus from "background" to "auto" for better screenshot success rates
- Fixed list tool server_status validation to allow empty include_window_details arrays
- Added comprehensive tests for new auto mode functionality
- Enhanced error messages for better user experience
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>