Skip to main content
Glama

macOS Automator MCP Server

by steipete
test-validator.ts3.75 kB
import fs from 'node:fs/promises'; import path from 'node:path'; import { exec } from 'node:child_process'; import { promisify } from 'node:util'; import matter from 'gray-matter'; const execPromise = promisify(exec); /** * Simple test script to validate AppleScript and JXA syntax */ async function validateScript( scriptContent: string, language: 'applescript' | 'javascript' ): Promise<{ isValid: boolean; error?: string }> { if (!scriptContent || scriptContent.trim() === '') { return { isValid: false, error: 'Empty script content' }; } try { // Escape single quotes in the script content for safe shell execution const escapedScript = scriptContent.replace(/'/g, "'\\''") if (language === 'applescript') { // Directly validate AppleScript syntax with osascript -e await execPromise(`osascript -l AppleScript -e '${escapedScript}' > /dev/null 2>&1`); } else { // For JXA, use osascript with JavaScript language flag await execPromise(`osascript -l JavaScript -e '${escapedScript}' > /dev/null 2>&1`); } return { isValid: true }; } catch (error) { const errorObj = error as { stderr?: string; stdout?: string; message?: string }; return { isValid: false, error: errorObj.stderr || errorObj.stdout || errorObj.message || 'Unknown error during syntax validation' }; } } /** * Extracts script content from a markdown file */ function extractScriptFromMarkdown(markdownContent: string): string | null { const scriptBlockRegex = /```(?:applescript|javascript)\s*\n([\s\S]*?)\n```/i; const scriptMatch = markdownContent.match(scriptBlockRegex); return scriptMatch && scriptMatch[1] ? scriptMatch[1].trim() : null; } /** * Validates AppleScript or JXA syntax in a knowledge base tip file */ async function validateTipFile(filePath: string): Promise<boolean> { try { const fileContent = await fs.readFile(filePath, 'utf-8'); const { data: frontmatter, content: markdownBody } = matter(fileContent); // Check if this is an AppleScript or JXA file const language = frontmatter.language as 'applescript' | 'javascript'; if (!language || !['applescript', 'javascript'].includes(language)) { // Not a script file or missing language specification return true; } // Extract the script content from markdown const scriptContent = extractScriptFromMarkdown(markdownBody); if (!scriptContent) { // No script content found return true; } // Validate the script syntax const result = await validateScript(scriptContent, language); console.log(` Syntax: ${result.isValid ? 'Valid' : 'Invalid'}`); if (!result.isValid && result.error) { console.log(` Error: ${result.error}`); return false; } return true; } catch (error) { const errorMessage = error instanceof Error ? error.message : String(error); console.error(` Error: ${errorMessage}`); return false; } } async function runTests() { const testFiles = [ 'test_valid_applescript.md', 'test_invalid_applescript.md', 'test_valid_jxa.md', 'test_invalid_jxa.md' ]; const testDir = path.join(process.cwd(), 'knowledge_base/test_syntax_validation'); console.log('Testing Script Validator on Test Files:'); console.log('======================================='); for (const file of testFiles) { const filePath = path.join(testDir, file); try { console.log(`\nTesting ${file}:`); const result = await validateTipFile(filePath); console.log(`Result: ${result ? 'Valid' : 'Invalid'}`); } catch (error) { console.error(`Error testing ${file}:`, error); } } } runTests().catch(console.error);

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/steipete/macos-automator-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server