diff --git a/CHANGELOG.md b/CHANGELOG.md index 241527d..b73fa3b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,7 +5,7 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## [1.0.0-beta.3] - YYYY-MM-DD +## [1.0.0-beta.3] - 2025-01-21 ### Added - Enhanced `image` tool to support optional immediate analysis of the captured screenshot by providing a `question` and `provider_config`. @@ -24,12 +24,26 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added - Initial E2E tests for CLI image capture. -## [1.0.0-beta.4] - YYYY-MM-DD +## [1.0.0-beta.4] - 2025-01-25 ### โœจ Added +- Comprehensive Swift unit tests for all CLI components +- Release preparation script with extensive validation checks +- Swift code linting and formatting with SwiftLint and SwiftFormat +- Enhanced image tool with blur detection, custom formats (PNG/JPG), and naming patterns +- Robust error handling for Swift CLI integration -- **Swift CLI `image` command:** Added `--screen-index ` option to capture a specific display when `--mode screen` is used. (Part of `image` tool simplification) -- **MCP `image` tool:** Now fully supports `app_target: "screen:INDEX"` by utilizing the Swift CLI's new `--screen-index` capability. +### ๐Ÿ› Fixed +- Swift CLI integration tests now properly handle error output +- Fixed Swift code to comply with SwiftLint rules +- Corrected JSON structure expectations in tests + +### ๐Ÿ“š Changed +- Updated all dependencies to latest versions +- Improved test coverage for both TypeScript and Swift code +- Enhanced release process with automated checks +- Swift CLI `image` command: Added `--screen-index ` option to capture a specific display when `--mode screen` is used +- MCP `image` tool: Now fully supports `app_target: "screen:INDEX"` by utilizing the Swift CLI's new `--screen-index` capability ### โ™ป๏ธ Changed diff --git a/examples/test-peekaboo.js b/examples/test-peekaboo.js new file mode 100755 index 0000000..8f8f37f --- /dev/null +++ b/examples/test-peekaboo.js @@ -0,0 +1,118 @@ +#!/usr/bin/env node + +/** + * Simple test script to verify Peekaboo MCP is working correctly + * Run this after installing the package to test basic functionality + */ + +import { spawn } from 'child_process'; + +console.log('๐Ÿงช Testing Peekaboo MCP Server...\n'); + +// Test 1: List available tools +console.log('๐Ÿ“‹ Test 1: Listing available tools...'); +const listToolsRequest = { + jsonrpc: "2.0", + id: 1, + method: "tools/list" +}; + +// Test 2: List running applications +console.log('๐Ÿ“ฑ Test 2: Listing running applications...'); +const listAppsRequest = { + jsonrpc: "2.0", + id: 2, + method: "tools/call", + params: { + name: "list", + arguments: { + target: "apps" + } + } +}; + +// Test 3: Capture screen +console.log('๐Ÿ“ธ Test 3: Capturing screen...'); +const captureScreenRequest = { + jsonrpc: "2.0", + id: 3, + method: "tools/call", + params: { + name: "image", + arguments: { + app_target: "screen", + format: "data" + } + } +}; + +// Start the server +const server = spawn('node', ['dist/index.js'], { + stdio: ['pipe', 'pipe', 'pipe'] +}); + +let responses = []; +let currentTest = 1; + +server.stdout.on('data', (data) => { + const lines = data.toString().split('\n').filter(line => line.trim()); + + for (const line of lines) { + try { + const response = JSON.parse(line); + responses.push(response); + + if (response.id === 1) { + console.log('โœ… Tools available:', response.result.tools.map(t => t.name).join(', ')); + + // Send next test + server.stdin.write(JSON.stringify(listAppsRequest) + '\n'); + } else if (response.id === 2) { + const apps = response.result[0]?.content[0]?.text; + if (apps) { + const appData = JSON.parse(apps); + console.log(`โœ… Found ${appData.applications.length} running applications`); + } + + // Send next test + server.stdin.write(JSON.stringify(captureScreenRequest) + '\n'); + } else if (response.id === 3) { + if (response.result && response.result[0]) { + console.log('โœ… Screen captured successfully'); + console.log('\n๐ŸŽ‰ All tests passed!'); + } else if (response.error) { + console.log('โŒ Screen capture failed:', response.error.message); + } + + // Exit + server.kill(); + process.exit(0); + } + } catch (e) { + // Ignore non-JSON lines + } + } +}); + +server.stderr.on('data', (data) => { + console.error('Server error:', data.toString()); +}); + +server.on('close', (code) => { + if (code !== 0) { + console.error(`\nโŒ Server exited with code ${code}`); + process.exit(1); + } +}); + +// Send first test +setTimeout(() => { + server.stdin.write(JSON.stringify(listToolsRequest) + '\n'); +}, 100); + +// Timeout after 10 seconds +setTimeout(() => { + console.error('\nโŒ Test timed out'); + server.kill(); + process.exit(1); +}, 10000); \ No newline at end of file