mirror of
https://github.com/samsonjs/Peekaboo.git
synced 2026-04-27 15:07:41 +00:00
Add build dir, prepare package
This commit is contained in:
parent
a7970d8de7
commit
eab4e5a394
10 changed files with 5808 additions and 31 deletions
107
.gitignore
vendored
107
.gitignore
vendored
|
|
@ -1,2 +1,109 @@
|
||||||
# macOS
|
# macOS
|
||||||
.DS_Store
|
.DS_Store
|
||||||
|
.AppleDouble
|
||||||
|
.LSOverride
|
||||||
|
Icon
|
||||||
|
._*
|
||||||
|
.DocumentRevisions-V100
|
||||||
|
.fseventsd
|
||||||
|
.Spotlight-V100
|
||||||
|
.TemporaryItems
|
||||||
|
.Trashes
|
||||||
|
.VolumeIcon.icns
|
||||||
|
.com.apple.timemachine.donotpresent
|
||||||
|
.AppleDB
|
||||||
|
.AppleDesktop
|
||||||
|
Network Trash Folder
|
||||||
|
Temporary Items
|
||||||
|
.apdisk
|
||||||
|
|
||||||
|
# Node.js / TypeScript
|
||||||
|
node_modules/
|
||||||
|
npm-debug.log*
|
||||||
|
yarn-debug.log*
|
||||||
|
yarn-error.log*
|
||||||
|
lerna-debug.log*
|
||||||
|
.npm
|
||||||
|
.yarn-integrity
|
||||||
|
*.tsbuildinfo
|
||||||
|
.eslintcache
|
||||||
|
.node_repl_history
|
||||||
|
*.tgz
|
||||||
|
.env
|
||||||
|
.env.local
|
||||||
|
.env.development.local
|
||||||
|
.env.test.local
|
||||||
|
.env.production.local
|
||||||
|
|
||||||
|
# TypeScript
|
||||||
|
dist/
|
||||||
|
build/
|
||||||
|
*.js.map
|
||||||
|
|
||||||
|
# Logs
|
||||||
|
logs/
|
||||||
|
*.log
|
||||||
|
pids/
|
||||||
|
*.pid
|
||||||
|
*.seed
|
||||||
|
*.pid.lock
|
||||||
|
|
||||||
|
# Testing
|
||||||
|
coverage/
|
||||||
|
.nyc_output/
|
||||||
|
lib-cov/
|
||||||
|
*.lcov
|
||||||
|
.grunt
|
||||||
|
.lock-wscript
|
||||||
|
|
||||||
|
# IDEs and editors
|
||||||
|
.idea/
|
||||||
|
.vscode/
|
||||||
|
*.swp
|
||||||
|
*.swo
|
||||||
|
*~
|
||||||
|
.project
|
||||||
|
.classpath
|
||||||
|
.c9/
|
||||||
|
*.launch
|
||||||
|
.settings/
|
||||||
|
*.sublime-workspace
|
||||||
|
*.sublime-project
|
||||||
|
|
||||||
|
# Swift / Xcode
|
||||||
|
swift-cli/
|
||||||
|
peekaboo
|
||||||
|
.build/
|
||||||
|
DerivedData/
|
||||||
|
*.pbxuser
|
||||||
|
!default.pbxuser
|
||||||
|
*.mode1v3
|
||||||
|
!default.mode1v3
|
||||||
|
*.mode2v3
|
||||||
|
!default.mode2v3
|
||||||
|
*.perspectivev3
|
||||||
|
!default.perspectivev3
|
||||||
|
xcuserdata/
|
||||||
|
*.xccheckout
|
||||||
|
*.moved-aside
|
||||||
|
*.xcuserstate
|
||||||
|
*.xcscmblueprint
|
||||||
|
*.hmap
|
||||||
|
*.ipa
|
||||||
|
*.dSYM.zip
|
||||||
|
*.dSYM
|
||||||
|
Packages/
|
||||||
|
Package.pins
|
||||||
|
Package.resolved
|
||||||
|
.swiftpm/
|
||||||
|
*.playground
|
||||||
|
timeline.xctimeline
|
||||||
|
playground.xcworkspace
|
||||||
|
|
||||||
|
# Temporary files
|
||||||
|
*.tmp
|
||||||
|
*.temp
|
||||||
|
.cache/
|
||||||
|
|
||||||
|
# OS generated files
|
||||||
|
Thumbs.db
|
||||||
|
|
|
||||||
62
.npmignore
Normal file
62
.npmignore
Normal file
|
|
@ -0,0 +1,62 @@
|
||||||
|
# Source files
|
||||||
|
src/
|
||||||
|
swift-cli/Sources/
|
||||||
|
swift-cli/Tests/
|
||||||
|
|
||||||
|
# Test files
|
||||||
|
tests/
|
||||||
|
test_peekaboo.sh
|
||||||
|
jest.config.cjs
|
||||||
|
coverage/
|
||||||
|
*.test.ts
|
||||||
|
*.test.js
|
||||||
|
|
||||||
|
# Development files
|
||||||
|
.gitignore
|
||||||
|
.eslintrc*
|
||||||
|
.prettierrc*
|
||||||
|
tsconfig.json
|
||||||
|
.editorconfig
|
||||||
|
.nvmrc
|
||||||
|
|
||||||
|
# IDE and system files
|
||||||
|
.vscode/
|
||||||
|
.idea/
|
||||||
|
.DS_Store
|
||||||
|
*.swp
|
||||||
|
*.swo
|
||||||
|
*~
|
||||||
|
|
||||||
|
# Build artifacts
|
||||||
|
*.tsbuildinfo
|
||||||
|
.build/
|
||||||
|
DerivedData/
|
||||||
|
|
||||||
|
# Documentation source
|
||||||
|
docs/
|
||||||
|
*.md
|
||||||
|
!README.md
|
||||||
|
!LICENSE
|
||||||
|
|
||||||
|
# CI/CD
|
||||||
|
.github/
|
||||||
|
.gitlab-ci.yml
|
||||||
|
.travis.yml
|
||||||
|
|
||||||
|
# Temporary files
|
||||||
|
*.tmp
|
||||||
|
*.temp
|
||||||
|
.cache/
|
||||||
|
*.log
|
||||||
|
|
||||||
|
# Development dependencies
|
||||||
|
pino-pretty
|
||||||
|
|
||||||
|
# Swift build files (except the binary)
|
||||||
|
swift-cli/Package.swift
|
||||||
|
swift-cli/Package.resolved
|
||||||
|
swift-cli/.build/
|
||||||
|
swift-cli/.swiftpm/
|
||||||
|
|
||||||
|
# Keep only the compiled binary
|
||||||
|
!peekaboo
|
||||||
13
README.md
13
README.md
|
|
@ -1,5 +1,12 @@
|
||||||
# Peekaboo MCP Server
|
# Peekaboo MCP Server
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
[](https://www.npmjs.com/package/@steipete/peekaboo-mcp)
|
||||||
|
[](https://opensource.org/licenses/MIT)
|
||||||
|
[](https://www.apple.com/macos/)
|
||||||
|
[](https://nodejs.org/)
|
||||||
|
|
||||||
A macOS utility exposed via Node.js MCP server for advanced screen captures, image analysis, and window management.
|
A macOS utility exposed via Node.js MCP server for advanced screen captures, image analysis, and window management.
|
||||||
|
|
||||||
## 🚀 Installation & Setup
|
## 🚀 Installation & Setup
|
||||||
|
|
@ -29,17 +36,17 @@ xcode-select --install
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Install globally for system-wide access
|
# Install globally for system-wide access
|
||||||
npm install -g peekaboo-mcp
|
npm install -g @steipete/peekaboo-mcp
|
||||||
|
|
||||||
# Or install locally in your project
|
# Or install locally in your project
|
||||||
npm install peekaboo-mcp
|
npm install @steipete/peekaboo-mcp
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Method 2: From Source
|
#### Method 2: From Source
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Clone the repository
|
# Clone the repository
|
||||||
git clone https://github.com/yourusername/peekaboo.git
|
git clone https://github.com/steipete/peekaboo.git
|
||||||
cd peekaboo
|
cd peekaboo
|
||||||
|
|
||||||
# Install Node.js dependencies
|
# Install Node.js dependencies
|
||||||
|
|
|
||||||
33
jest.config.cjs
Normal file
33
jest.config.cjs
Normal file
|
|
@ -0,0 +1,33 @@
|
||||||
|
/** @type {import('jest').Config} */
|
||||||
|
module.exports = {
|
||||||
|
preset: 'ts-jest/presets/default-esm',
|
||||||
|
testEnvironment: 'node',
|
||||||
|
extensionsToTreatAsEsm: ['.ts'],
|
||||||
|
transform: {
|
||||||
|
'^.+\.ts$': ['ts-jest', {
|
||||||
|
useESM: true,
|
||||||
|
tsconfig: {
|
||||||
|
module: 'ESNext',
|
||||||
|
target: 'es2022',
|
||||||
|
moduleResolution: 'NodeNext',
|
||||||
|
allowSyntheticDefaultImports: true,
|
||||||
|
esModuleInterop: true
|
||||||
|
}
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
moduleNameMapper: {
|
||||||
|
'^(\.{1,2}/.*)\.js$': '$1',
|
||||||
|
},
|
||||||
|
moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node'],
|
||||||
|
testMatch: [
|
||||||
|
'**/tests/unit/**/*.test.ts',
|
||||||
|
'**/tests/integration/**/*.test.ts',
|
||||||
|
],
|
||||||
|
collectCoverageFrom: [
|
||||||
|
'src/**/*.ts',
|
||||||
|
'!src/**/*.d.ts',
|
||||||
|
'!src/index.ts'
|
||||||
|
],
|
||||||
|
coverageDirectory: 'coverage',
|
||||||
|
coverageReporters: ['text', 'lcov', 'html']
|
||||||
|
};
|
||||||
5408
package-lock.json
generated
Normal file
5408
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load diff
68
package.json
Normal file
68
package.json
Normal file
|
|
@ -0,0 +1,68 @@
|
||||||
|
{
|
||||||
|
"name": "@steipete/peekaboo-mcp",
|
||||||
|
"version": "1.0.0-alpha1",
|
||||||
|
"description": "A macOS utility exposed via Node.js MCP server for advanced screen captures, image analysis, and window management",
|
||||||
|
"type": "module",
|
||||||
|
"main": "dist/index.js",
|
||||||
|
"bin": {
|
||||||
|
"peekaboo-mcp": "dist/index.js"
|
||||||
|
},
|
||||||
|
"files": [
|
||||||
|
"dist/",
|
||||||
|
"peekaboo"
|
||||||
|
],
|
||||||
|
"scripts": {
|
||||||
|
"build": "tsc",
|
||||||
|
"build:swift": "./scripts/build-swift-cli.sh",
|
||||||
|
"build:all": "npm run build:swift && npm run build",
|
||||||
|
"start": "node dist/index.js",
|
||||||
|
"prepublishOnly": "npm run build:all",
|
||||||
|
"dev": "tsc --watch",
|
||||||
|
"clean": "rm -rf dist",
|
||||||
|
"test": "jest",
|
||||||
|
"test:watch": "jest --watch",
|
||||||
|
"test:coverage": "jest --coverage",
|
||||||
|
"test:swift": "cd swift-cli && swift test",
|
||||||
|
"test:integration": "npm run build && npm run test:swift && npm test",
|
||||||
|
"test:all": "npm run test:integration",
|
||||||
|
"postinstall": "chmod +x dist/index.js 2>/dev/null || true"
|
||||||
|
},
|
||||||
|
"keywords": [
|
||||||
|
"mcp",
|
||||||
|
"screen-capture",
|
||||||
|
"macos",
|
||||||
|
"ai-analysis",
|
||||||
|
"image-analysis",
|
||||||
|
"window-management"
|
||||||
|
],
|
||||||
|
"author": "Peter Steinberger <steipete@gmail.com>",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@modelcontextprotocol/sdk": "^1.12.0",
|
||||||
|
"openai": "^4.0.0",
|
||||||
|
"pino": "^8.0.0",
|
||||||
|
"zod": "^3.22.0"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@types/jest": "^29.5.8",
|
||||||
|
"@types/node": "^20.10.0",
|
||||||
|
"jest": "^29.7.0",
|
||||||
|
"pino-pretty": "^10.0.0",
|
||||||
|
"ts-jest": "^29.1.1",
|
||||||
|
"typescript": "^5.3.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18.0.0"
|
||||||
|
},
|
||||||
|
"os": [
|
||||||
|
"darwin"
|
||||||
|
],
|
||||||
|
"repository": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/steipete/peekaboo.git"
|
||||||
|
},
|
||||||
|
"bugs": {
|
||||||
|
"url": "https://github.com/steipete/peekaboo/issues"
|
||||||
|
},
|
||||||
|
"homepage": "https://github.com/steipete/peekaboo#readme"
|
||||||
|
}
|
||||||
18
scripts/build-swift-cli.sh
Executable file
18
scripts/build-swift-cli.sh
Executable file
|
|
@ -0,0 +1,18 @@
|
||||||
|
#!/bin/bash
|
||||||
|
set -e
|
||||||
|
|
||||||
|
echo "Building Swift CLI..."
|
||||||
|
|
||||||
|
# Change to swift-cli directory
|
||||||
|
cd "$(dirname "$0")/../swift-cli"
|
||||||
|
|
||||||
|
# Build the Swift CLI in release mode
|
||||||
|
swift build --configuration release
|
||||||
|
|
||||||
|
# Copy the binary to the root directory
|
||||||
|
cp .build/release/peekaboo ../peekaboo
|
||||||
|
|
||||||
|
# Make it executable
|
||||||
|
chmod +x ../peekaboo
|
||||||
|
|
||||||
|
echo "Swift CLI built successfully and copied to ./peekaboo"
|
||||||
52
scripts/build-swift-universal.sh
Executable file
52
scripts/build-swift-universal.sh
Executable file
|
|
@ -0,0 +1,52 @@
|
||||||
|
#!/bin/bash
|
||||||
|
set -e # Exit immediately if a command exits with a non-zero status.
|
||||||
|
|
||||||
|
PROJECT_ROOT_REL=".." # Relative path to project root from swift-cli
|
||||||
|
PROJECT_ROOT=$(cd "$(dirname "$0")/$PROJECT_ROOT_REL" && pwd)
|
||||||
|
SWIFT_PROJECT_PATH="$PROJECT_ROOT/swift-cli"
|
||||||
|
FINAL_BINARY_NAME="peekaboo"
|
||||||
|
FINAL_BINARY_PATH="$PROJECT_ROOT/$FINAL_BINARY_NAME"
|
||||||
|
|
||||||
|
ARM64_BINARY_TEMP="$PROJECT_ROOT/${FINAL_BINARY_NAME}-arm64"
|
||||||
|
X86_64_BINARY_TEMP="$PROJECT_ROOT/${FINAL_BINARY_NAME}-x86_64"
|
||||||
|
|
||||||
|
# Swift compiler flags for size optimization
|
||||||
|
# -Osize: Optimize for binary size.
|
||||||
|
# -wmo: Whole Module Optimization, allows more aggressive optimizations.
|
||||||
|
# -Xlinker -dead_strip: Remove dead code at the linking stage.
|
||||||
|
SWIFT_OPTIMIZATION_FLAGS="-Xswiftc -Osize -Xswiftc -wmo -Xlinker -dead_strip -Xlinker -no_uuid"
|
||||||
|
|
||||||
|
echo "🧹 Cleaning previous build artifacts..."
|
||||||
|
(cd "$SWIFT_PROJECT_PATH" && swift package reset) || echo "'swift package reset' encountered an issue, attempting rm -rf..."
|
||||||
|
rm -rf "$SWIFT_PROJECT_PATH/.build"
|
||||||
|
rm -f "$ARM64_BINARY_TEMP" "$X86_64_BINARY_TEMP" "$FINAL_BINARY_PATH.tmp"
|
||||||
|
|
||||||
|
echo "🏗️ Building for arm64 (Apple Silicon)..."
|
||||||
|
(cd "$SWIFT_PROJECT_PATH" && swift build --arch arm64 -c release $SWIFT_OPTIMIZATION_FLAGS)
|
||||||
|
cp "$SWIFT_PROJECT_PATH/.build/arm64-apple-macosx/release/$FINAL_BINARY_NAME" "$ARM64_BINARY_TEMP"
|
||||||
|
echo "✅ arm64 build complete: $ARM64_BINARY_TEMP"
|
||||||
|
|
||||||
|
echo "🏗️ Building for x86_64 (Intel)..."
|
||||||
|
(cd "$SWIFT_PROJECT_PATH" && swift build --arch x86_64 -c release $SWIFT_OPTIMIZATION_FLAGS)
|
||||||
|
cp "$SWIFT_PROJECT_PATH/.build/x86_64-apple-macosx/release/$FINAL_BINARY_NAME" "$X86_64_BINARY_TEMP"
|
||||||
|
echo "✅ x86_64 build complete: $X86_64_BINARY_TEMP"
|
||||||
|
|
||||||
|
echo "🔗 Creating universal binary..."
|
||||||
|
lipo -create -output "$FINAL_BINARY_PATH.tmp" "$ARM64_BINARY_TEMP" "$X86_64_BINARY_TEMP"
|
||||||
|
|
||||||
|
echo "🤏 Stripping symbols for further size reduction..."
|
||||||
|
# -S: Remove debugging symbols
|
||||||
|
# -x: Remove non-global symbols
|
||||||
|
strip -Sx "$FINAL_BINARY_PATH.tmp"
|
||||||
|
|
||||||
|
# Replace the old binary with the new one
|
||||||
|
mv "$FINAL_BINARY_PATH.tmp" "$FINAL_BINARY_PATH"
|
||||||
|
|
||||||
|
echo "🗑️ Cleaning up temporary architecture-specific binaries..."
|
||||||
|
rm -f "$ARM64_BINARY_TEMP" "$X86_64_BINARY_TEMP"
|
||||||
|
|
||||||
|
echo "🔍 Verifying final universal binary..."
|
||||||
|
lipo -info "$FINAL_BINARY_PATH"
|
||||||
|
ls -lh "$FINAL_BINARY_PATH"
|
||||||
|
|
||||||
|
echo "🎉 Universal binary '$FINAL_BINARY_PATH' created and optimized successfully!"
|
||||||
40
src/index.ts
40
src/index.ts
|
|
@ -38,34 +38,30 @@ initializeSwiftCliPath(packageRootDir);
|
||||||
let hasSentInitialStatus = false;
|
let hasSentInitialStatus = false;
|
||||||
|
|
||||||
// Initialize logger
|
// Initialize logger
|
||||||
const pinoTransports = [];
|
const logLevel = process.env.LOG_LEVEL || 'info';
|
||||||
|
const logFile = path.join(os.tmpdir(), 'peekaboo-mcp.log');
|
||||||
|
|
||||||
// Default file transport
|
// Create logger with file destination by default
|
||||||
pinoTransports.push({
|
const logger = process.env.PEEKABOO_MCP_CONSOLE_LOGGING === 'true'
|
||||||
level: process.env.LOG_LEVEL || 'info',
|
? pino({
|
||||||
target: 'pino/file',
|
name: 'peekaboo-mcp',
|
||||||
options: {
|
level: logLevel,
|
||||||
destination: path.join(os.tmpdir(), 'peekaboo-mcp.log'),
|
transport: {
|
||||||
mkdir: true // Ensure the directory exists
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Conditional console logging for development
|
|
||||||
if (process.env.PEEKABOO_MCP_CONSOLE_LOGGING === 'true') {
|
|
||||||
pinoTransports.push({
|
|
||||||
level: process.env.LOG_LEVEL || 'info', // Or a more verbose level for console e.g. 'debug'
|
|
||||||
target: 'pino-pretty',
|
target: 'pino-pretty',
|
||||||
options: {
|
options: {
|
||||||
destination: 2, // stderr
|
colorize: true,
|
||||||
colorize: true, // pino-pretty typically defaults to true if TTY
|
translateTime: true,
|
||||||
|
ignore: 'pid,hostname'
|
||||||
}
|
}
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
})
|
||||||
const logger = pino({
|
: pino({
|
||||||
name: 'peekaboo-mcp',
|
name: 'peekaboo-mcp',
|
||||||
level: process.env.LOG_LEVEL || 'info', // Overall minimum level, transport levels can be more specific
|
level: logLevel
|
||||||
}, pino.multistream(pinoTransports as any)); // Use pino.multistream
|
}, pino.destination({
|
||||||
|
dest: logFile,
|
||||||
|
sync: false
|
||||||
|
}));
|
||||||
|
|
||||||
// Tool context for handlers
|
// Tool context for handlers
|
||||||
const toolContext = { logger };
|
const toolContext = { logger };
|
||||||
|
|
|
||||||
26
tsconfig.json
Normal file
26
tsconfig.json
Normal file
|
|
@ -0,0 +1,26 @@
|
||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"target": "ES2022",
|
||||||
|
"module": "ESNext",
|
||||||
|
"moduleResolution": "Node",
|
||||||
|
"outDir": "./dist",
|
||||||
|
"rootDir": "./src",
|
||||||
|
"strict": true,
|
||||||
|
"esModuleInterop": true,
|
||||||
|
"skipLibCheck": true,
|
||||||
|
"forceConsistentCasingInFileNames": true,
|
||||||
|
"declaration": true,
|
||||||
|
"declarationMap": true,
|
||||||
|
"sourceMap": true,
|
||||||
|
"allowSyntheticDefaultImports": true,
|
||||||
|
"resolveJsonModule": true
|
||||||
|
},
|
||||||
|
"include": [
|
||||||
|
"src/**/*"
|
||||||
|
],
|
||||||
|
"exclude": [
|
||||||
|
"node_modules",
|
||||||
|
"dist",
|
||||||
|
"**/*.test.ts"
|
||||||
|
]
|
||||||
|
}
|
||||||
Loading…
Reference in a new issue