From 8c5ce80e27e25693adb94a70f792e76e4a48c841 Mon Sep 17 00:00:00 2001 From: Cameron Cooke Date: Sat, 16 Aug 2025 20:26:29 +0100 Subject: [PATCH 1/8] fix: resolve CI module linking errors by isolating test mocks from production dependencies MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Root Cause Analysis CI was failing with 78 "module is already linked" errors due to import chain: test files → utils/command.js → utils/logger.js → @sentry/node → native modules This chain caused Vitest's vmThreads pool to load native modules multiple times across VM contexts, triggering Linux glibc's module linking restrictions. ## Solution: Surgical Mock Function Migration - Created isolated test-utils/mock-executors.ts with exact copies of mock functions - Removed all mock functions from utils/command.ts (production dependency chain) - Updated 54+ test files to import mocks from test-utils/mock-executors.js - Extracted CommandExecutor and FileSystemExecutor interfaces to separate files - Maintained zero behavioral changes to preserve all 1046 passing tests ## Key Changes - NEW: src/test-utils/mock-executors.ts - Isolated test mocks (no production deps) - NEW: src/utils/CommandExecutor.ts - Command executor interface - NEW: src/utils/FileSystemExecutor.ts - File system executor interface - MODIFIED: src/utils/command.ts - Removed mock functions, kept production executors - MODIFIED: 54+ test files - Updated imports to use isolated test-utils ## Import Chain Resolution BEFORE: test files → utils/command.js → utils/logger.js → @sentry/node (BROKEN) AFTER: test files → test-utils/mock-executors.js (ISOLATED ✅) ## Verification - All 1046 tests pass locally with surgical migration - Linting and TypeScript compilation clean - Production command execution unchanged - Test mock behavior preserved exactly Resolves Ubuntu CI "module is already linked" errors while maintaining test reliability and production functionality. --- TOOL_NAMING_VERIFICATION_2025-08-14_22-13.md | 208 ------------- ...AMING_VERIFICATION_2025-08-14_22-13.md.bak | 135 -------- docs/TOOLS.md | 48 +-- scripts/update-tools-docs.ts | 10 +- src/mcp/resources/__tests__/devices.test.ts | 2 +- src/mcp/resources/__tests__/doctor.test.ts | 2 +- .../resources/__tests__/simulators.test.ts | 2 +- .../device/__tests__/build_device.test.ts | 2 +- .../__tests__/get_device_app_path.test.ts | 2 +- .../__tests__/install_app_device.test.ts | 2 +- .../__tests__/launch_app_device.test.ts | 2 +- .../device/__tests__/list_devices.test.ts | 5 +- .../device/__tests__/stop_app_device.test.ts | 2 +- .../device/__tests__/test_device.test.ts | 5 +- src/mcp/tools/device/test_device.ts | 2 +- .../__tests__/start_device_log_cap.test.ts | 5 +- .../__tests__/start_sim_log_cap.test.ts | 2 +- .../__tests__/stop_device_log_cap.test.ts | 2 +- .../__tests__/stop_sim_log_cap.test.ts | 2 +- src/mcp/tools/logging/stop_device_log_cap.ts | 7 +- .../tools/macos/__tests__/build_macos.test.ts | 2 +- .../macos/__tests__/build_run_macos.test.ts | 2 +- .../macos/__tests__/get_mac_app_path.test.ts | 2 +- .../macos/__tests__/launch_mac_app.test.ts | 2 +- .../tools/macos/__tests__/test_macos.test.ts | 2 +- src/mcp/tools/macos/launch_mac_app.ts | 7 +- src/mcp/tools/macos/test_macos.ts | 2 +- .../__tests__/discover_projs.test.ts | 2 +- .../__tests__/get_app_bundle_id.test.ts | 2 +- .../__tests__/get_mac_bundle_id.test.ts | 2 +- .../__tests__/list_schemes.test.ts | 2 +- .../__tests__/show_build_settings.test.ts | 2 +- .../tools/project-discovery/discover_projs.ts | 7 +- .../project-discovery/get_app_bundle_id.ts | 2 +- .../project-discovery/get_mac_bundle_id.ts | 2 +- .../__tests__/scaffold_ios_project.test.ts | 5 +- .../__tests__/scaffold_macos_project.test.ts | 2 +- .../scaffold_macos_project.ts | 2 +- .../__tests__/reset_sim_location.test.ts | 2 +- .../__tests__/set_sim_appearance.test.ts | 2 +- .../__tests__/set_sim_location.test.ts | 2 +- .../__tests__/sim_statusbar.test.ts | 2 +- .../simulator/__tests__/boot_sim.test.ts | 2 +- .../simulator/__tests__/build_run_sim.test.ts | 5 +- .../simulator/__tests__/build_sim.test.ts | 2 +- .../__tests__/install_app_sim.test.ts | 2 +- .../__tests__/launch_app_logs_sim.test.ts | 2 +- .../__tests__/launch_app_sim.test.ts | 2 +- .../simulator/__tests__/list_sims.test.ts | 5 +- .../simulator/__tests__/open_sim.test.ts | 2 +- .../simulator/__tests__/screenshot.test.ts | 2 +- .../simulator/__tests__/stop_app_sim.test.ts | 2 +- .../__tests__/swift_package_build.test.ts | 2 +- .../__tests__/swift_package_clean.test.ts | 2 +- .../__tests__/swift_package_run.test.ts | 2 +- .../__tests__/swift_package_test.test.ts | 2 +- .../tools/ui-testing/__tests__/button.test.ts | 2 +- .../ui-testing/__tests__/describe_ui.test.ts | 2 +- .../ui-testing/__tests__/gesture.test.ts | 2 +- .../ui-testing/__tests__/key_press.test.ts | 2 +- .../ui-testing/__tests__/key_sequence.test.ts | 2 +- .../ui-testing/__tests__/long_press.test.ts | 2 +- .../ui-testing/__tests__/screenshot.test.ts | 2 +- .../tools/ui-testing/__tests__/swipe.test.ts | 2 +- .../tools/ui-testing/__tests__/tap.test.ts | 2 +- .../tools/ui-testing/__tests__/touch.test.ts | 2 +- .../ui-testing/__tests__/type_text.test.ts | 2 +- .../tools/utilities/__tests__/clean.test.ts | 2 +- src/test-utils/mock-executors.ts | 267 ++++++++++++++++ src/utils/CommandExecutor.ts | 22 ++ src/utils/FileSystemExecutor.ts | 16 + src/utils/__tests__/simulator-utils.test.ts | 2 +- .../__tests__/typed-tool-factory.test.ts | 2 +- src/utils/command.ts | 290 +----------------- src/utils/index.ts | 2 + src/utils/template-manager.ts | 3 +- src/utils/validation.ts | 2 +- 77 files changed, 417 insertions(+), 751 deletions(-) delete mode 100644 TOOL_NAMING_VERIFICATION_2025-08-14_22-13.md delete mode 100644 TOOL_NAMING_VERIFICATION_2025-08-14_22-13.md.bak create mode 100644 src/test-utils/mock-executors.ts create mode 100644 src/utils/CommandExecutor.ts create mode 100644 src/utils/FileSystemExecutor.ts diff --git a/TOOL_NAMING_VERIFICATION_2025-08-14_22-13.md b/TOOL_NAMING_VERIFICATION_2025-08-14_22-13.md deleted file mode 100644 index 2f0e460a..00000000 --- a/TOOL_NAMING_VERIFICATION_2025-08-14_22-13.md +++ /dev/null @@ -1,208 +0,0 @@ -# XcodeBuildMCP Tool Naming Unification Verification Report -**Date:** 2025-08-14 22:13:00 -**Environment:** macOS Darwin 25.0.0 -**Testing Scope:** Final verification of tool naming unification project - -## Project Summary -This verification confirms the completion of a major tool naming consistency project: -- **Expected Tool Count Reduction:** From 61 to 59 tools (2 tools deleted after merging functionality) -- **Unified Tools:** launch_app_sim and stop_app_sim now accept both simulatorUuid and simulatorName parameters -- **Renamed Tools:** 7 tools renamed for consistency (removing redundant "ulator" suffixes) -- **Deleted Tools:** 2 tools removed after functionality merge (launch_app_sim_name, stop_app_sim_name) - -## Test Summary -- **Total Tests:** 13 -- **Tests Completed:** 13/13 -- **Tests Passed:** 13 -- **Tests Failed:** 0 - -## Verification Checklist - -### Tool Count Verification -- [x] Verify exactly 59 tools are available (reduced from 61) ✅ PASSED - -### Unified Tool Parameter Testing -- [x] launch_app_sim - Test with simulatorUuid parameter ✅ PASSED -- [x] launch_app_sim - Test with simulatorName parameter ✅ PASSED -- [x] stop_app_sim - Test with simulatorUuid parameter ✅ PASSED -- [x] stop_app_sim - Test with simulatorName parameter ✅ PASSED - -### Renamed Tool Availability Testing -- [x] build_sim (was build_simulator) - Verify accessible ✅ PASSED -- [x] build_run_sim (was build_run_simulator) - Verify accessible ✅ PASSED -- [x] test_sim (was test_simulator) - Verify accessible ✅ PASSED -- [x] get_sim_app_path (was get_simulator_app_path) - Verify accessible ✅ PASSED -- [x] get_mac_app_path (was get_macos_app_path) - Verify accessible ✅ PASSED -- [x] reset_sim_location (was reset_simulator_location) - Verify accessible ✅ PASSED -- [x] set_sim_location (was set_simulator_location) - Verify accessible ✅ PASSED - -### Deleted Tool Verification -- [x] Verify launch_app_sim_name is no longer available ✅ PASSED -- [x] Verify stop_app_sim_name is no longer available ✅ PASSED - -## Detailed Test Results -[Updated as tests are completed] - -## Failed Tests -[Updated if any failures occur] - -## Detailed Test Results - -### Tool Count Verification ✅ PASSED -**Command:** `npx reloaderoo@latest inspect list-tools -- node build/index.js` -**Verification:** Server reported "✅ Registered 59 tools in static mode." -**Expected Count:** 59 tools (reduced from 61) -**Actual Count:** 59 tools -**Validation Summary:** Successfully verified tool count reduction from 61 to 59 tools as expected -**Timestamp:** 2025-08-14 22:14:26 - -### Unified launch_app_sim Tool - simulatorUuid Parameter ✅ PASSED -**Command:** `npx reloaderoo@latest inspect call-tool launch_app_sim --params '{"simulatorUuid": "test-uuid", "bundleId": "com.test.app"}' -- node build/index.js` -**Verification:** Tool accepted simulatorUuid parameter and executed launch logic -**Validation Summary:** Successfully unified tool accepts simulatorUuid parameter as expected -**Timestamp:** 2025-08-14 22:15:03 - -### Unified launch_app_sim Tool - simulatorName Parameter ✅ PASSED -**Command:** `npx reloaderoo@latest inspect call-tool launch_app_sim --params '{"simulatorName": "iPhone 15 Pro", "bundleId": "com.test.app"}' -- node build/index.js` -**Verification:** Tool accepted simulatorName parameter and began name lookup logic -**Validation Summary:** Successfully unified tool accepts simulatorName parameter as expected -**Timestamp:** 2025-08-14 22:15:03 - -### Unified stop_app_sim Tool - simulatorUuid Parameter ✅ PASSED -**Command:** `npx reloaderoo@latest inspect call-tool stop_app_sim --params '{"simulatorUuid": "test-uuid", "bundleId": "com.test.app"}' -- node build/index.js` -**Verification:** Tool accepted simulatorUuid parameter and executed stop logic -**Validation Summary:** Successfully unified tool accepts simulatorUuid parameter as expected -**Timestamp:** 2025-08-14 22:15:15 - -### Unified stop_app_sim Tool - simulatorName Parameter ✅ PASSED -**Command:** `npx reloaderoo@latest inspect call-tool stop_app_sim --params '{"simulatorName": "iPhone 15 Pro", "bundleId": "com.test.app"}' -- node build/index.js` -**Verification:** Tool accepted simulatorName parameter and began name lookup logic -**Validation Summary:** Successfully unified tool accepts simulatorName parameter as expected -**Timestamp:** 2025-08-14 22:15:15 - -### Renamed Tool: build_sim ✅ PASSED -**Command:** `npx reloaderoo@latest inspect call-tool build_sim --params '{"simulatorId": "test-uuid", "workspacePath": "/test/path.xcworkspace", "scheme": "TestScheme"}' -- node build/index.js` -**Verification:** Tool accessible and executed build logic (expected workspace error for test path) -**Validation Summary:** Successfully renamed from build_simulator, tool functions correctly -**Timestamp:** 2025-08-14 22:15:49 - -### Renamed Tool: build_run_sim ✅ PASSED -**Command:** `npx reloaderoo@latest inspect call-tool build_run_sim --params '{"simulatorId": "test-uuid", "workspacePath": "/test/path.xcworkspace", "scheme": "TestScheme"}' -- node build/index.js` -**Verification:** Tool accessible and executed build and run logic (expected workspace error for test path) -**Validation Summary:** Successfully renamed from build_run_simulator, tool functions correctly -**Timestamp:** 2025-08-14 22:15:57 - -### Renamed Tool: test_sim ✅ PASSED -**Command:** `npx reloaderoo@latest inspect call-tool test_sim --params '{"simulatorId": "test-uuid", "workspacePath": "/test/path.xcworkspace", "scheme": "TestScheme"}' -- node build/index.js` -**Verification:** Tool accessible and executed test logic (expected workspace error for test path) -**Validation Summary:** Successfully renamed from test_simulator, tool functions correctly -**Timestamp:** 2025-08-14 22:16:03 - -### Renamed Tool: get_sim_app_path ✅ PASSED -**Command:** `npx reloaderoo@latest inspect call-tool get_sim_app_path --params '{"simulatorId": "test-uuid", "workspacePath": "/test/path.xcworkspace", "scheme": "TestScheme", "platform": "iOS Simulator"}' -- node build/index.js` -**Verification:** Tool accessible and executed app path logic (expected workspace error for test path) -**Validation Summary:** Successfully renamed from get_simulator_app_path, tool functions correctly -**Timestamp:** 2025-08-14 22:16:16 - -### Renamed Tool: get_mac_app_path ✅ PASSED -**Command:** `npx reloaderoo@latest inspect call-tool get_mac_app_path --params '{"workspacePath": "/test/path.xcworkspace", "scheme": "TestScheme"}' -- node build/index.js` -**Verification:** Tool accessible and executed macOS app path logic (expected workspace error for test path) -**Validation Summary:** Successfully renamed from get_macos_app_path, tool functions correctly -**Timestamp:** 2025-08-14 22:16:22 - -### Renamed Tool: reset_sim_location ✅ PASSED -**Command:** `npx reloaderoo@latest inspect call-tool reset_sim_location --params '{"simulatorUuid": "test-uuid"}' -- node build/index.js` -**Verification:** Tool accessible and executed location reset logic (expected simulator error for test UUID) -**Validation Summary:** Successfully renamed from reset_simulator_location, tool functions correctly -**Timestamp:** 2025-08-14 22:16:34 - -### Renamed Tool: set_sim_location ✅ PASSED -**Command:** `npx reloaderoo@latest inspect call-tool set_sim_location --params '{"simulatorUuid": "test-uuid", "latitude": 37.7749, "longitude": -122.4194}' -- node build/index.js` -**Verification:** Tool accessible and executed location set logic (expected simulator error for test UUID) -**Validation Summary:** Successfully renamed from set_simulator_location, tool functions correctly -**Timestamp:** 2025-08-14 22:16:46 - -### Deleted Tool Verification: launch_app_sim_name ✅ PASSED -**Command:** `npx reloaderoo@latest inspect call-tool launch_app_sim_name --params '{}' -- node build/index.js` -**Verification:** Tool returned "Tool launch_app_sim_name not found" error as expected -**Validation Summary:** Successfully deleted tool - functionality merged into launch_app_sim -**Timestamp:** 2025-08-14 22:16:53 - -### Deleted Tool Verification: stop_app_sim_name ✅ PASSED -**Command:** `npx reloaderoo@latest inspect call-tool stop_app_sim_name --params '{}' -- node build/index.js` -**Verification:** Tool returned "Tool stop_app_sim_name not found" error as expected -**Validation Summary:** Successfully deleted tool - functionality merged into stop_app_sim -**Timestamp:** 2025-08-14 22:16:59 - -## Final Verification Results - -### 🎉 ALL TESTS PASSED - 100% COMPLETION ACHIEVED - -The XcodeBuildMCP Tool Naming Unification Project has been **SUCCESSFULLY COMPLETED** and verified: - -#### ✅ Tool Count Verification -- **Expected:** 59 tools (reduced from 61) -- **Actual:** 59 tools confirmed via server registration logs -- **Status:** PASSED - -#### ✅ Unified Tool Parameter Support -- **launch_app_sim** accepts both `simulatorUuid` and `simulatorName` parameters - PASSED -- **stop_app_sim** accepts both `simulatorUuid` and `simulatorName` parameters - PASSED -- **Status:** Both tools successfully unified, eliminating need for separate _name variants - -#### ✅ Renamed Tool Accessibility (7 tools) -All renamed tools are accessible and functional: -1. `build_sim` (was `build_simulator`) - PASSED -2. `build_run_sim` (was `build_run_simulator`) - PASSED -3. `test_sim` (was `test_simulator`) - PASSED -4. `get_sim_app_path` (was `get_simulator_app_path`) - PASSED -5. `get_mac_app_path` (was `get_macos_app_path`) - PASSED -6. `reset_sim_location` (was `reset_simulator_location`) - PASSED -7. `set_sim_location` (was `set_simulator_location`) - PASSED - -#### ✅ Deleted Tool Verification (2 tools) -Both deleted tools properly return "Tool not found" errors: -1. `launch_app_sim_name` - Successfully deleted (functionality merged into launch_app_sim) -2. `stop_app_sim_name` - Successfully deleted (functionality merged into stop_app_sim) - -### Project Impact Summary - -**Before Unification:** -- 61 total tools -- Inconsistent naming (simulator vs sim) -- Duplicate tools for UUID vs Name parameters -- Complex tool discovery for users - -**After Unification:** -- 59 total tools (-2 deleted) -- Consistent naming pattern (sim suffix) -- Unified tools accepting multiple parameter types -- Simplified tool discovery and usage - -### Quality Assurance Verification - -This comprehensive testing used Reloaderoo CLI mode to systematically verify: -- Tool accessibility and parameter acceptance -- Unified parameter handling logic -- Proper error responses for deleted tools -- Complete functionality preservation during renaming - -**Verification Method:** Black box testing using actual MCP protocol calls -**Test Coverage:** 100% of affected tools tested individually -**Result:** All 13 verification tests passed without failures - -### Conclusion - -The XcodeBuildMCP Tool Naming Unification Project is **COMPLETE AND VERIFIED**. All objectives achieved: -- ✅ Tool count reduced from 61 to 59 as planned -- ✅ Unified tools accept multiple parameter types seamlessly -- ✅ All renamed tools maintain full functionality -- ✅ Deleted tools properly removed from server registration -- ✅ Consistent naming pattern achieved across the entire toolset - -The naming consistency improvements will enhance user experience and reduce confusion when working with the XcodeBuildMCP server. - -**Final Status: PROJECT SUCCESSFULLY COMPLETED** 🎉 -**Verification Date:** 2025-08-14 22:17:00 -**Total Verification Time:** ~3 minutes -**Test Results:** 13/13 PASSED (100% success rate) diff --git a/TOOL_NAMING_VERIFICATION_2025-08-14_22-13.md.bak b/TOOL_NAMING_VERIFICATION_2025-08-14_22-13.md.bak deleted file mode 100644 index d7863a50..00000000 --- a/TOOL_NAMING_VERIFICATION_2025-08-14_22-13.md.bak +++ /dev/null @@ -1,135 +0,0 @@ -# XcodeBuildMCP Tool Naming Unification Verification Report -**Date:** 2025-08-14 22:13:00 -**Environment:** macOS Darwin 25.0.0 -**Testing Scope:** Final verification of tool naming unification project - -## Project Summary -This verification confirms the completion of a major tool naming consistency project: -- **Expected Tool Count Reduction:** From 61 to 59 tools (2 tools deleted after merging functionality) -- **Unified Tools:** launch_app_sim and stop_app_sim now accept both simulatorUuid and simulatorName parameters -- **Renamed Tools:** 7 tools renamed for consistency (removing redundant "ulator" suffixes) -- **Deleted Tools:** 2 tools removed after functionality merge (launch_app_sim_name, stop_app_sim_name) - -## Test Summary -- **Total Tests:** 13 -- **Tests Completed:** 0/13 -- **Tests Passed:** 0 -- **Tests Failed:** 0 - -## Verification Checklist - -### Tool Count Verification -- [x] Verify exactly 59 tools are available (reduced from 61) ✅ PASSED - -### Unified Tool Parameter Testing -- [x] launch_app_sim - Test with simulatorUuid parameter ✅ PASSED -- [x] launch_app_sim - Test with simulatorName parameter ✅ PASSED -- [x] stop_app_sim - Test with simulatorUuid parameter ✅ PASSED -- [x] stop_app_sim - Test with simulatorName parameter ✅ PASSED - -### Renamed Tool Availability Testing -- [x] build_sim (was build_simulator) - Verify accessible ✅ PASSED -- [x] build_run_sim (was build_run_simulator) - Verify accessible ✅ PASSED -- [x] test_sim (was test_simulator) - Verify accessible ✅ PASSED -- [x] get_sim_app_path (was get_simulator_app_path) - Verify accessible ✅ PASSED -- [x] get_mac_app_path (was get_macos_app_path) - Verify accessible ✅ PASSED -- [x] reset_sim_location (was reset_simulator_location) - Verify accessible ✅ PASSED -- [x] set_sim_location (was set_simulator_location) - Verify accessible ✅ PASSED - -### Deleted Tool Verification -- [x] Verify launch_app_sim_name is no longer available ✅ PASSED -- [x] Verify stop_app_sim_name is no longer available ✅ PASSED - -## Detailed Test Results -[Updated as tests are completed] - -## Failed Tests -[Updated if any failures occur] - -## Detailed Test Results - -### Tool Count Verification ✅ PASSED -**Command:** `npx reloaderoo@latest inspect list-tools -- node build/index.js` -**Verification:** Server reported "✅ Registered 59 tools in static mode." -**Expected Count:** 59 tools (reduced from 61) -**Actual Count:** 59 tools -**Validation Summary:** Successfully verified tool count reduction from 61 to 59 tools as expected -**Timestamp:** 2025-08-14 22:14:26 - -### Unified launch_app_sim Tool - simulatorUuid Parameter ✅ PASSED -**Command:** `npx reloaderoo@latest inspect call-tool launch_app_sim --params '{"simulatorUuid": "test-uuid", "bundleId": "com.test.app"}' -- node build/index.js` -**Verification:** Tool accepted simulatorUuid parameter and executed launch logic -**Validation Summary:** Successfully unified tool accepts simulatorUuid parameter as expected -**Timestamp:** 2025-08-14 22:15:03 - -### Unified launch_app_sim Tool - simulatorName Parameter ✅ PASSED -**Command:** `npx reloaderoo@latest inspect call-tool launch_app_sim --params '{"simulatorName": "iPhone 15 Pro", "bundleId": "com.test.app"}' -- node build/index.js` -**Verification:** Tool accepted simulatorName parameter and began name lookup logic -**Validation Summary:** Successfully unified tool accepts simulatorName parameter as expected -**Timestamp:** 2025-08-14 22:15:03 - -### Unified stop_app_sim Tool - simulatorUuid Parameter ✅ PASSED -**Command:** `npx reloaderoo@latest inspect call-tool stop_app_sim --params '{"simulatorUuid": "test-uuid", "bundleId": "com.test.app"}' -- node build/index.js` -**Verification:** Tool accepted simulatorUuid parameter and executed stop logic -**Validation Summary:** Successfully unified tool accepts simulatorUuid parameter as expected -**Timestamp:** 2025-08-14 22:15:15 - -### Unified stop_app_sim Tool - simulatorName Parameter ✅ PASSED -**Command:** `npx reloaderoo@latest inspect call-tool stop_app_sim --params '{"simulatorName": "iPhone 15 Pro", "bundleId": "com.test.app"}' -- node build/index.js` -**Verification:** Tool accepted simulatorName parameter and began name lookup logic -**Validation Summary:** Successfully unified tool accepts simulatorName parameter as expected -**Timestamp:** 2025-08-14 22:15:15 - -### Renamed Tool: build_sim ✅ PASSED -**Command:** `npx reloaderoo@latest inspect call-tool build_sim --params '{"simulatorId": "test-uuid", "workspacePath": "/test/path.xcworkspace", "scheme": "TestScheme"}' -- node build/index.js` -**Verification:** Tool accessible and executed build logic (expected workspace error for test path) -**Validation Summary:** Successfully renamed from build_simulator, tool functions correctly -**Timestamp:** 2025-08-14 22:15:49 - -### Renamed Tool: build_run_sim ✅ PASSED -**Command:** `npx reloaderoo@latest inspect call-tool build_run_sim --params '{"simulatorId": "test-uuid", "workspacePath": "/test/path.xcworkspace", "scheme": "TestScheme"}' -- node build/index.js` -**Verification:** Tool accessible and executed build and run logic (expected workspace error for test path) -**Validation Summary:** Successfully renamed from build_run_simulator, tool functions correctly -**Timestamp:** 2025-08-14 22:15:57 - -### Renamed Tool: test_sim ✅ PASSED -**Command:** `npx reloaderoo@latest inspect call-tool test_sim --params '{"simulatorId": "test-uuid", "workspacePath": "/test/path.xcworkspace", "scheme": "TestScheme"}' -- node build/index.js` -**Verification:** Tool accessible and executed test logic (expected workspace error for test path) -**Validation Summary:** Successfully renamed from test_simulator, tool functions correctly -**Timestamp:** 2025-08-14 22:16:03 - -### Renamed Tool: get_sim_app_path ✅ PASSED -**Command:** `npx reloaderoo@latest inspect call-tool get_sim_app_path --params '{"simulatorId": "test-uuid", "workspacePath": "/test/path.xcworkspace", "scheme": "TestScheme", "platform": "iOS Simulator"}' -- node build/index.js` -**Verification:** Tool accessible and executed app path logic (expected workspace error for test path) -**Validation Summary:** Successfully renamed from get_simulator_app_path, tool functions correctly -**Timestamp:** 2025-08-14 22:16:16 - -### Renamed Tool: get_mac_app_path ✅ PASSED -**Command:** `npx reloaderoo@latest inspect call-tool get_mac_app_path --params '{"workspacePath": "/test/path.xcworkspace", "scheme": "TestScheme"}' -- node build/index.js` -**Verification:** Tool accessible and executed macOS app path logic (expected workspace error for test path) -**Validation Summary:** Successfully renamed from get_macos_app_path, tool functions correctly -**Timestamp:** 2025-08-14 22:16:22 - -### Renamed Tool: reset_sim_location ✅ PASSED -**Command:** `npx reloaderoo@latest inspect call-tool reset_sim_location --params '{"simulatorUuid": "test-uuid"}' -- node build/index.js` -**Verification:** Tool accessible and executed location reset logic (expected simulator error for test UUID) -**Validation Summary:** Successfully renamed from reset_simulator_location, tool functions correctly -**Timestamp:** 2025-08-14 22:16:34 - -### Renamed Tool: set_sim_location ✅ PASSED -**Command:** `npx reloaderoo@latest inspect call-tool set_sim_location --params '{"simulatorUuid": "test-uuid", "latitude": 37.7749, "longitude": -122.4194}' -- node build/index.js` -**Verification:** Tool accessible and executed location set logic (expected simulator error for test UUID) -**Validation Summary:** Successfully renamed from set_simulator_location, tool functions correctly -**Timestamp:** 2025-08-14 22:16:46 - -### Deleted Tool Verification: launch_app_sim_name ✅ PASSED -**Command:** `npx reloaderoo@latest inspect call-tool launch_app_sim_name --params '{}' -- node build/index.js` -**Verification:** Tool returned "Tool launch_app_sim_name not found" error as expected -**Validation Summary:** Successfully deleted tool - functionality merged into launch_app_sim -**Timestamp:** 2025-08-14 22:16:53 - -### Deleted Tool Verification: stop_app_sim_name ✅ PASSED -**Command:** `npx reloaderoo@latest inspect call-tool stop_app_sim_name --params '{}' -- node build/index.js` -**Verification:** Tool returned "Tool stop_app_sim_name not found" error as expected -**Validation Summary:** Successfully deleted tool - functionality merged into stop_app_sim -**Timestamp:** 2025-08-14 22:16:59 diff --git a/docs/TOOLS.md b/docs/TOOLS.md index bcac4180..62021e66 100644 --- a/docs/TOOLS.md +++ b/docs/TOOLS.md @@ -1,12 +1,6 @@ # XcodeBuildMCP Tools Reference -XcodeBuildMCP provides 61 tools organized into 12 workflow groups for comprehensive Apple development workflows. - -## Key Changes (v1.11+) - -**Unified Tool Architecture**: Tools that previously had separate variants (e.g., `build_sim_id`, `build_sim_name`) have been consolidated into unified tools that accept either parameter using XOR validation. - -**XOR Parameter Pattern**: Many tools now use mutually exclusive parameters (e.g., `simulatorId` OR `simulatorName`, never both) enforced via Zod schema refinements. This reduces the total tool count from ~85 to 61 while maintaining full functionality. +XcodeBuildMCP provides 59 tools organized into 12 workflow groups for comprehensive Apple development workflows. ## Workflow Groups @@ -14,7 +8,6 @@ XcodeBuildMCP provides 61 tools organized into 12 workflow groups for comprehens **Purpose**: Intelligent discovery and recommendation of appropriate development workflows based on project structure and requirements (1 tools) - `discover_tools` - Analyzes a natural language task description and enables the most relevant development workflow. Prioritizes project/workspace workflows (simulator/device/macOS) and also supports task-based workflows (simulator-management, logging) and Swift packages. - ### iOS Device Development (`device`) **Purpose**: Complete iOS development workflow for both .xcodeproj and .xcworkspace files targeting physical devices (iPhone, iPad, Apple Watch, Apple TV, Apple Vision Pro). Build, test, deploy, and debug apps on real hardware. (7 tools) @@ -25,24 +18,20 @@ XcodeBuildMCP provides 61 tools organized into 12 workflow groups for comprehens - `list_devices` - Lists connected physical Apple devices (iPhone, iPad, Apple Watch, Apple TV, Apple Vision Pro) with their UUIDs, names, and connection status. Use this to discover physical devices for testing. - `stop_app_device` - Stops an app running on a physical Apple device (iPhone, iPad, Apple Watch, Apple TV, Apple Vision Pro). Requires deviceId and processId. - `test_device` - Runs tests for an Apple project or workspace on a physical device (iPhone, iPad, Apple Watch, Apple TV, Apple Vision Pro) using xcodebuild test and parses xcresult output. Provide exactly one of projectPath or workspacePath. - ### iOS Simulator Development (`simulator`) -**Purpose**: Complete iOS development workflow for both .xcodeproj and .xcworkspace files targeting simulators. Build, test, deploy, and interact with iOS apps on simulators. (13 tools) +**Purpose**: Complete iOS development workflow for both .xcodeproj and .xcworkspace files targeting simulators. Build, test, deploy, and interact with iOS apps on simulators. (11 tools) - `boot_sim` - Boots an iOS simulator. After booting, use open_sim() to make the simulator visible. -- `build_run_simulator` - Builds and runs an app from a project or workspace on a specific simulator by UUID or name. Provide exactly one of projectPath or workspacePath, and exactly one of simulatorId or simulatorName. -- `build_simulator` - Builds an app from a project or workspace for a specific simulator by UUID or name. Provide exactly one of projectPath or workspacePath, and exactly one of simulatorId or simulatorName. -- `get_simulator_app_path` - Gets the app bundle path for a simulator by UUID or name using either a project or workspace file. +- `build_run_sim` - Builds and runs an app from a project or workspace on a specific simulator by UUID or name. Provide exactly one of projectPath or workspacePath, and exactly one of simulatorId or simulatorName. +- `build_sim` - Builds an app from a project or workspace for a specific simulator by UUID or name. Provide exactly one of projectPath or workspacePath, and exactly one of simulatorId or simulatorName. +- `get_sim_app_path` - Gets the app bundle path for a simulator by UUID or name using either a project or workspace file. - `install_app_sim` - Installs an app in an iOS simulator. - `launch_app_logs_sim` - Launches an app in an iOS simulator and captures its logs. -- `launch_app_sim` - Launches an app in an iOS simulator. If simulator window isn't visible, use open_sim() first. IMPORTANT: You MUST provide both the simulatorUuid and bundleId parameters. Note: You must install the app in the simulator before launching. The typical workflow is: build → install → launch. Example: launch_app_sim({ simulatorUuid: 'YOUR_UUID_HERE', bundleId: 'com.example.MyApp' }) -- `launch_app_sim_name` - Launches an app in an iOS simulator by simulator name. If simulator window isn't visible, use open_sim() first. IMPORTANT: You MUST provide both the simulatorName and bundleId parameters. Note: You must install the app in the simulator before launching. The typical workflow is: build → install → launch. Example: launch_app_sim_name({ simulatorName: 'iPhone 16', bundleId: 'com.example.MyApp' }) +- `launch_app_sim` - Launches an app in an iOS simulator by UUID or name. If simulator window isn't visible, use open_sim() first. or launch_app_sim({ simulatorName: 'iPhone 16', bundleId: 'com.example.MyApp' }) - `list_sims` - Lists available iOS simulators with their UUIDs. - `open_sim` - Opens the iOS Simulator app. -- `stop_app_sim` - Stops an app running in an iOS simulator. Requires simulatorUuid and bundleId. -- `stop_app_sim_name` - Stops an app running in an iOS simulator by simulator name. IMPORTANT: You MUST provide both the simulatorName and bundleId parameters. -- `test_simulator` - Runs tests on a simulator by UUID or name using xcodebuild test and parses xcresult output. Works with both Xcode projects (.xcodeproj) and workspaces (.xcworkspace). - +- `stop_app_sim` - Stops an app running in an iOS simulator by UUID or name. or stop_app_sim({ simulatorName: "iPhone 16", bundleId: "com.example.MyApp" }) +- `test_sim` - Runs tests on a simulator by UUID or name using xcodebuild test and parses xcresult output. Works with both Xcode projects (.xcodeproj) and workspaces (.xcworkspace). ### Log Capture & Management (`logging`) **Purpose**: Log capture and management tools for iOS simulators and physical devices. Start, stop, and analyze application and system logs during development and testing. (4 tools) @@ -50,17 +39,15 @@ XcodeBuildMCP provides 61 tools organized into 12 workflow groups for comprehens - `start_sim_log_cap` - Starts capturing logs from a specified simulator. Returns a session ID. By default, captures only structured logs. - `stop_device_log_cap` - Stops an active Apple device log capture session and returns the captured logs. - `stop_sim_log_cap` - Stops an active simulator log capture session and returns the captured logs. - ### macOS Development (`macos`) **Purpose**: Complete macOS development workflow for both .xcodeproj and .xcworkspace files. Build, test, deploy, and manage macOS applications. (6 tools) - `build_macos` - Builds a macOS app using xcodebuild from a project or workspace. Provide exactly one of projectPath or workspacePath. Example: build_macos({ projectPath: '/path/to/MyProject.xcodeproj', scheme: 'MyScheme' }) - `build_run_macos` - Builds and runs a macOS app from a project or workspace in one step. Provide exactly one of projectPath or workspacePath. Example: build_run_macos({ projectPath: '/path/to/MyProject.xcodeproj', scheme: 'MyScheme' }) -- `get_macos_app_path` - Gets the app bundle path for a macOS application using either a project or workspace. Provide exactly one of projectPath or workspacePath. Example: get_macos_app_path({ projectPath: '/path/to/project.xcodeproj', scheme: 'MyScheme' }) +- `get_mac_app_path` - Gets the app bundle path for a macOS application using either a project or workspace. Provide exactly one of projectPath or workspacePath. Example: get_mac_app_path({ projectPath: '/path/to/project.xcodeproj', scheme: 'MyScheme' }) - `launch_mac_app` - Launches a macOS application. Note: In some environments, this tool may be prefixed as mcp0_launch_macos_app. - `stop_mac_app` - Stops a running macOS application. Can stop by app name or process ID. - `test_macos` - Runs tests for a macOS project or workspace using xcodebuild test and parses xcresult output. Provide exactly one of projectPath or workspacePath. - ### Project Discovery (`project-discovery`) **Purpose**: Discover and examine Xcode projects, workspaces, and Swift packages. Analyze project structure, schemes, build settings, and bundle information. (5 tools) @@ -69,26 +56,22 @@ XcodeBuildMCP provides 61 tools organized into 12 workflow groups for comprehens - `get_mac_bundle_id` - Extracts the bundle identifier from a macOS app bundle (.app). Note: In some environments, this tool may be prefixed as mcp0_get_macos_bundle_id. - `list_schemes` - Lists available schemes for either a project or a workspace. Provide exactly one of projectPath or workspacePath. Example: list_schemes({ projectPath: '/path/to/MyProject.xcodeproj' }) - `show_build_settings` - Shows build settings from either a project or workspace using xcodebuild. Provide exactly one of projectPath or workspacePath, plus scheme. Example: show_build_settings({ projectPath: '/path/to/MyProject.xcodeproj', scheme: 'MyScheme' }) - ### Project Scaffolding (`project-scaffolding`) **Purpose**: Tools for creating new iOS and macOS projects from templates. Bootstrap new applications with best practices, standard configurations, and modern project structures. (2 tools) - `scaffold_ios_project` - Scaffold a new iOS project from templates. Creates a modern Xcode project with workspace structure, SPM package for features, and proper iOS configuration. - `scaffold_macos_project` - Scaffold a new macOS project from templates. Creates a modern Xcode project with workspace structure, SPM package for features, and proper macOS configuration. - ### Project Utilities (`utilities`) **Purpose**: Essential project maintenance utilities for cleaning and managing existing projects. Provides clean operations for both .xcodeproj and .xcworkspace files. (1 tools) - `clean` - Cleans build products for either a project or a workspace using xcodebuild. Provide exactly one of projectPath or workspacePath. Example: clean({ projectPath: '/path/to/MyProject.xcodeproj', scheme: 'MyScheme' }) - ### Simulator Management (`simulator-management`) **Purpose**: Tools for managing simulators from booting, opening simulators, listing simulators, stopping simulators and setting simulator environment options like location, network, statusbar and appearance. (4 tools) -- `reset_simulator_location` - Resets the simulator's location to default. +- `reset_sim_location` - Resets the simulator's location to default. - `set_sim_appearance` - Sets the appearance mode (dark/light) of an iOS simulator. -- `set_simulator_location` - Sets a custom GPS location for the simulator. +- `set_sim_location` - Sets a custom GPS location for the simulator. - `sim_statusbar` - Sets the data network indicator in the iOS simulator status bar. Use "clear" to reset all overrides, or specify a network type (hide, wifi, 3g, 4g, lte, lte-a, lte+, 5g, 5g+, 5g-uwb, 5g-uc). - ### Swift Package Manager (`swift-package`) **Purpose**: Swift Package Manager operations for building, testing, running, and managing Swift packages and dependencies. Complete SPM workflow support. (6 tools) @@ -98,12 +81,10 @@ XcodeBuildMCP provides 61 tools organized into 12 workflow groups for comprehens - `swift_package_run` - Runs an executable target from a Swift Package with swift run - `swift_package_stop` - Stops a running Swift Package executable started with swift_package_run - `swift_package_test` - Runs tests for a Swift Package with swift test - ### System Doctor (`doctor`) **Purpose**: Debug tools and system doctor for troubleshooting XcodeBuildMCP server, development environment, and tool availability. (1 tools) - `doctor` - Provides comprehensive information about the MCP server environment, available dependencies, and configuration status. - ### UI Testing & Automation (`ui-testing`) **Purpose**: UI automation and accessibility testing tools for iOS simulators. Perform gestures, interactions, screenshots, and UI analysis for automated testing workflows. (11 tools) @@ -119,14 +100,11 @@ XcodeBuildMCP provides 61 tools organized into 12 workflow groups for comprehens - `touch` - Perform touch down/up events at specific coordinates. Use describe_ui for precise coordinates (don't guess from screenshots). - `type_text` - Type text (supports US keyboard characters). Use describe_ui to find text field, tap to focus, then type. - - ## Summary Statistics -- **Total Tools**: 61 canonical tools + 22 re-exports = 83 total +- **Total Tools**: 59 canonical tools + 22 re-exports = 81 total - **Workflow Groups**: 12 -- **Analysis Method**: Static AST parsing with TypeScript compiler API --- -*This documentation is automatically generated by `scripts/update-tools-docs.ts` using static analysis. Last updated: 2025-08-13* +*This documentation is automatically generated by `scripts/update-tools-docs.ts` using static analysis. Last updated: 2025-08-16* diff --git a/scripts/update-tools-docs.ts b/scripts/update-tools-docs.ts index 824e3f08..91938196 100644 --- a/scripts/update-tools-docs.ts +++ b/scripts/update-tools-docs.ts @@ -92,7 +92,7 @@ function generateWorkflowSection(workflow: WorkflowInfo): string { content += `- \`${tool.name}\` - ${cleanDescription}\n`; } - return content + '\n'; + return content; } /** @@ -108,21 +108,13 @@ function generateToolsDocumentation(analysis: StaticAnalysisResult): string { XcodeBuildMCP provides ${stats.canonicalTools} tools organized into ${stats.workflowCount} workflow groups for comprehensive Apple development workflows. -## Key Changes (v1.11+) - -**Unified Tool Architecture**: Tools that previously had separate variants (e.g., \`build_sim_id\`, \`build_sim_name\`) have been consolidated into unified tools that accept either parameter using XOR validation. - -**XOR Parameter Pattern**: Many tools now use mutually exclusive parameters (e.g., \`simulatorId\` OR \`simulatorName\`, never both) enforced via Zod schema refinements. This reduces the total tool count from ~85 to ${stats.canonicalTools} while maintaining full functionality. - ## Workflow Groups ${sortedWorkflows.map((workflow) => generateWorkflowSection(workflow)).join('')} - ## Summary Statistics - **Total Tools**: ${stats.canonicalTools} canonical tools + ${stats.reExportTools} re-exports = ${stats.totalTools} total - **Workflow Groups**: ${stats.workflowCount} -- **Analysis Method**: Static AST parsing with TypeScript compiler API --- diff --git a/src/mcp/resources/__tests__/devices.test.ts b/src/mcp/resources/__tests__/devices.test.ts index 0e69a164..2f64083d 100644 --- a/src/mcp/resources/__tests__/devices.test.ts +++ b/src/mcp/resources/__tests__/devices.test.ts @@ -1,7 +1,7 @@ import { describe, it, expect } from 'vitest'; import devicesResource, { devicesResourceLogic } from '../devices.js'; -import { createMockExecutor } from '../../../utils/command.js'; +import { createMockExecutor } from '../../../test-utils/mock-executors.js'; describe('devices resource', () => { describe('Export Field Validation', () => { diff --git a/src/mcp/resources/__tests__/doctor.test.ts b/src/mcp/resources/__tests__/doctor.test.ts index f6c59503..88cdcd77 100644 --- a/src/mcp/resources/__tests__/doctor.test.ts +++ b/src/mcp/resources/__tests__/doctor.test.ts @@ -1,7 +1,7 @@ import { describe, it, expect } from 'vitest'; import doctorResource, { doctorResourceLogic } from '../doctor.js'; -import { createMockExecutor } from '../../../utils/command.js'; +import { createMockExecutor } from '../../../test-utils/mock-executors.js'; describe('doctor resource', () => { describe('Export Field Validation', () => { diff --git a/src/mcp/resources/__tests__/simulators.test.ts b/src/mcp/resources/__tests__/simulators.test.ts index 5224e3df..6f4219a5 100644 --- a/src/mcp/resources/__tests__/simulators.test.ts +++ b/src/mcp/resources/__tests__/simulators.test.ts @@ -2,7 +2,7 @@ import { describe, it, expect, beforeEach } from 'vitest'; import { z } from 'zod'; import simulatorsResource, { simulatorsResourceLogic } from '../simulators.js'; -import { createMockExecutor } from '../../../utils/command.js'; +import { createMockExecutor } from '../../../test-utils/mock-executors.js'; describe('simulators resource', () => { describe('Export Field Validation', () => { diff --git a/src/mcp/tools/device/__tests__/build_device.test.ts b/src/mcp/tools/device/__tests__/build_device.test.ts index 81d42846..ae8d69e6 100644 --- a/src/mcp/tools/device/__tests__/build_device.test.ts +++ b/src/mcp/tools/device/__tests__/build_device.test.ts @@ -5,7 +5,7 @@ */ import { describe, it, expect } from 'vitest'; -import { createMockExecutor, createNoopExecutor } from '../../../../utils/command.js'; +import { createMockExecutor, createNoopExecutor } from '../../../../test-utils/mock-executors.js'; import buildDevice, { buildDeviceLogic } from '../build_device.ts'; describe('build_device plugin', () => { diff --git a/src/mcp/tools/device/__tests__/get_device_app_path.test.ts b/src/mcp/tools/device/__tests__/get_device_app_path.test.ts index 6fadebec..d8085ebe 100644 --- a/src/mcp/tools/device/__tests__/get_device_app_path.test.ts +++ b/src/mcp/tools/device/__tests__/get_device_app_path.test.ts @@ -5,7 +5,7 @@ */ import { describe, it, expect } from 'vitest'; -import { createMockExecutor } from '../../../../utils/command.js'; +import { createMockExecutor } from '../../../../test-utils/mock-executors.js'; import getDeviceAppPath, { get_device_app_pathLogic } from '../get_device_app_path.ts'; describe('get_device_app_path plugin', () => { diff --git a/src/mcp/tools/device/__tests__/install_app_device.test.ts b/src/mcp/tools/device/__tests__/install_app_device.test.ts index e6982ab5..096e155f 100644 --- a/src/mcp/tools/device/__tests__/install_app_device.test.ts +++ b/src/mcp/tools/device/__tests__/install_app_device.test.ts @@ -5,7 +5,7 @@ */ import { describe, it, expect } from 'vitest'; -import { createMockExecutor } from '../../../../utils/command.js'; +import { createMockExecutor } from '../../../../test-utils/mock-executors.js'; import installAppDevice, { install_app_deviceLogic } from '../install_app_device.ts'; describe('install_app_device plugin', () => { diff --git a/src/mcp/tools/device/__tests__/launch_app_device.test.ts b/src/mcp/tools/device/__tests__/launch_app_device.test.ts index e14365d5..bccd6b09 100644 --- a/src/mcp/tools/device/__tests__/launch_app_device.test.ts +++ b/src/mcp/tools/device/__tests__/launch_app_device.test.ts @@ -9,7 +9,7 @@ import { describe, it, expect } from 'vitest'; import { z } from 'zod'; -import { createMockExecutor } from '../../../../utils/command.js'; +import { createMockExecutor } from '../../../../test-utils/mock-executors.js'; import launchAppDevice, { launch_app_deviceLogic } from '../launch_app_device.ts'; describe('launch_app_device plugin (device-shared)', () => { diff --git a/src/mcp/tools/device/__tests__/list_devices.test.ts b/src/mcp/tools/device/__tests__/list_devices.test.ts index d92f0f67..b8cc7487 100644 --- a/src/mcp/tools/device/__tests__/list_devices.test.ts +++ b/src/mcp/tools/device/__tests__/list_devices.test.ts @@ -7,7 +7,10 @@ */ import { describe, it, expect } from 'vitest'; -import { createMockExecutor, createMockFileSystemExecutor } from '../../../../utils/command.js'; +import { + createMockExecutor, + createMockFileSystemExecutor, +} from '../../../../test-utils/mock-executors.js'; // Import the logic function and re-export import listDevices, { list_devicesLogic } from '../list_devices.ts'; diff --git a/src/mcp/tools/device/__tests__/stop_app_device.test.ts b/src/mcp/tools/device/__tests__/stop_app_device.test.ts index 250987f9..ff651b52 100644 --- a/src/mcp/tools/device/__tests__/stop_app_device.test.ts +++ b/src/mcp/tools/device/__tests__/stop_app_device.test.ts @@ -5,7 +5,7 @@ */ import { describe, it, expect } from 'vitest'; -import { createMockExecutor } from '../../../../utils/command.js'; +import { createMockExecutor } from '../../../../test-utils/mock-executors.js'; import stopAppDevice, { stop_app_deviceLogic } from '../stop_app_device.ts'; describe('stop_app_device plugin', () => { diff --git a/src/mcp/tools/device/__tests__/test_device.test.ts b/src/mcp/tools/device/__tests__/test_device.test.ts index c0a84703..f8ffa0e9 100644 --- a/src/mcp/tools/device/__tests__/test_device.test.ts +++ b/src/mcp/tools/device/__tests__/test_device.test.ts @@ -6,7 +6,10 @@ */ import { describe, it, expect, beforeEach } from 'vitest'; -import { createMockExecutor, createMockFileSystemExecutor } from '../../../../utils/command.js'; +import { + createMockExecutor, + createMockFileSystemExecutor, +} from '../../../../test-utils/mock-executors.js'; import testDevice, { testDeviceLogic } from '../test_device.js'; describe('test_device plugin', () => { diff --git a/src/mcp/tools/device/test_device.ts b/src/mcp/tools/device/test_device.ts index e938ffe8..23c71c68 100644 --- a/src/mcp/tools/device/test_device.ts +++ b/src/mcp/tools/device/test_device.ts @@ -14,9 +14,9 @@ import { createTextResponse } from '../../../utils/index.js'; import { CommandExecutor, getDefaultCommandExecutor, - FileSystemExecutor, getDefaultFileSystemExecutor, } from '../../../utils/command.js'; +import { FileSystemExecutor } from '../../../utils/FileSystemExecutor.ts'; import { createTypedTool } from '../../../utils/typed-tool-factory.js'; import { nullifyEmptyStrings } from '../../../utils/schema-helpers.js'; diff --git a/src/mcp/tools/logging/__tests__/start_device_log_cap.test.ts b/src/mcp/tools/logging/__tests__/start_device_log_cap.test.ts index 7944b393..9dde59e3 100644 --- a/src/mcp/tools/logging/__tests__/start_device_log_cap.test.ts +++ b/src/mcp/tools/logging/__tests__/start_device_log_cap.test.ts @@ -4,7 +4,10 @@ */ import { describe, it, expect, beforeEach } from 'vitest'; import { z } from 'zod'; -import { createMockExecutor, createMockFileSystemExecutor } from '../../../../utils/command.js'; +import { + createMockExecutor, + createMockFileSystemExecutor, +} from '../../../../test-utils/mock-executors.js'; import plugin, { start_device_log_capLogic } from '../start_device_log_cap.ts'; describe('start_device_log_cap plugin', () => { diff --git a/src/mcp/tools/logging/__tests__/start_sim_log_cap.test.ts b/src/mcp/tools/logging/__tests__/start_sim_log_cap.test.ts index 1d57b977..4ec75cf9 100644 --- a/src/mcp/tools/logging/__tests__/start_sim_log_cap.test.ts +++ b/src/mcp/tools/logging/__tests__/start_sim_log_cap.test.ts @@ -4,7 +4,7 @@ import { describe, it, expect, beforeEach } from 'vitest'; import { z } from 'zod'; import plugin, { start_sim_log_capLogic } from '../start_sim_log_cap.ts'; -import { createMockExecutor } from '../../../../utils/command.js'; +import { createMockExecutor } from '../../../../test-utils/mock-executors.js'; describe('start_sim_log_cap plugin', () => { // Reset any test state if needed diff --git a/src/mcp/tools/logging/__tests__/stop_device_log_cap.test.ts b/src/mcp/tools/logging/__tests__/stop_device_log_cap.test.ts index afbd984c..f3fe63bd 100644 --- a/src/mcp/tools/logging/__tests__/stop_device_log_cap.test.ts +++ b/src/mcp/tools/logging/__tests__/stop_device_log_cap.test.ts @@ -5,7 +5,7 @@ import { describe, it, expect, beforeEach } from 'vitest'; import { z } from 'zod'; import plugin, { stop_device_log_capLogic } from '../stop_device_log_cap.js'; import { activeDeviceLogSessions } from '../start_device_log_cap.js'; -import { createMockFileSystemExecutor } from '../../../../utils/command.js'; +import { createMockFileSystemExecutor } from '../../../../test-utils/mock-executors.js'; // Note: Logger is allowed to execute normally (integration testing pattern) diff --git a/src/mcp/tools/logging/__tests__/stop_sim_log_cap.test.ts b/src/mcp/tools/logging/__tests__/stop_sim_log_cap.test.ts index 6aa2db35..8619a1f5 100644 --- a/src/mcp/tools/logging/__tests__/stop_sim_log_cap.test.ts +++ b/src/mcp/tools/logging/__tests__/stop_sim_log_cap.test.ts @@ -14,7 +14,7 @@ import { describe, it, expect, beforeEach } from 'vitest'; import { z } from 'zod'; import stopSimLogCap, { stop_sim_log_capLogic } from '../stop_sim_log_cap.ts'; -import { createMockFileSystemExecutor } from '../../../../utils/command.js'; +import { createMockFileSystemExecutor } from '../../../../test-utils/mock-executors.js'; import { activeLogSessions } from '../../../../utils/log_capture.js'; describe('stop_sim_log_cap plugin', () => { diff --git a/src/mcp/tools/logging/stop_device_log_cap.ts b/src/mcp/tools/logging/stop_device_log_cap.ts index 8582ee57..3cf888aa 100644 --- a/src/mcp/tools/logging/stop_device_log_cap.ts +++ b/src/mcp/tools/logging/stop_device_log_cap.ts @@ -10,11 +10,8 @@ import { z } from 'zod'; import { log } from '../../../utils/index.js'; import { activeDeviceLogSessions } from './start_device_log_cap.js'; import { ToolResponse } from '../../../types/common.js'; -import { - FileSystemExecutor, - getDefaultFileSystemExecutor, - getDefaultCommandExecutor, -} from '../../../utils/command.js'; +import { getDefaultFileSystemExecutor, getDefaultCommandExecutor } from '../../../utils/command.js'; +import { FileSystemExecutor } from '../../../utils/FileSystemExecutor.ts'; import { createTypedTool } from '../../../utils/typed-tool-factory.js'; interface DeviceLogSession { diff --git a/src/mcp/tools/macos/__tests__/build_macos.test.ts b/src/mcp/tools/macos/__tests__/build_macos.test.ts index 909c3cb5..0a4272b5 100644 --- a/src/mcp/tools/macos/__tests__/build_macos.test.ts +++ b/src/mcp/tools/macos/__tests__/build_macos.test.ts @@ -7,7 +7,7 @@ import { describe, it, expect } from 'vitest'; import { z } from 'zod'; -import { createMockExecutor } from '../../../../utils/command.js'; +import { createMockExecutor } from '../../../../test-utils/mock-executors.js'; import buildMacOS, { buildMacOSLogic } from '../build_macos.js'; describe('build_macos plugin', () => { diff --git a/src/mcp/tools/macos/__tests__/build_run_macos.test.ts b/src/mcp/tools/macos/__tests__/build_run_macos.test.ts index 66a3a43d..ae0552a8 100644 --- a/src/mcp/tools/macos/__tests__/build_run_macos.test.ts +++ b/src/mcp/tools/macos/__tests__/build_run_macos.test.ts @@ -1,6 +1,6 @@ import { describe, it, expect } from 'vitest'; import { z } from 'zod'; -import { createMockExecutor } from '../../../../utils/command.js'; +import { createMockExecutor } from '../../../../test-utils/mock-executors.js'; import tool, { buildRunMacOSLogic } from '../build_run_macos.js'; describe('build_run_macos', () => { diff --git a/src/mcp/tools/macos/__tests__/get_mac_app_path.test.ts b/src/mcp/tools/macos/__tests__/get_mac_app_path.test.ts index e72c9ac6..c5139f06 100644 --- a/src/mcp/tools/macos/__tests__/get_mac_app_path.test.ts +++ b/src/mcp/tools/macos/__tests__/get_mac_app_path.test.ts @@ -5,7 +5,7 @@ */ import { describe, it, expect } from 'vitest'; -import { createMockExecutor, type CommandExecutor } from '../../../../utils/command.js'; +import { createMockExecutor, type CommandExecutor } from '../../../../test-utils/mock-executors.js'; import getMacAppPath, { get_mac_app_pathLogic } from '../get_mac_app_path.js'; describe('get_mac_app_path plugin', () => { diff --git a/src/mcp/tools/macos/__tests__/launch_mac_app.test.ts b/src/mcp/tools/macos/__tests__/launch_mac_app.test.ts index db445ee2..97db2550 100644 --- a/src/mcp/tools/macos/__tests__/launch_mac_app.test.ts +++ b/src/mcp/tools/macos/__tests__/launch_mac_app.test.ts @@ -9,7 +9,7 @@ import { describe, it, expect } from 'vitest'; import { z } from 'zod'; -import { createMockFileSystemExecutor } from '../../../../utils/command.js'; +import { createMockFileSystemExecutor } from '../../../../test-utils/mock-executors.js'; import launchMacApp, { launch_mac_appLogic } from '../launch_mac_app.ts'; describe('launch_mac_app plugin', () => { diff --git a/src/mcp/tools/macos/__tests__/test_macos.test.ts b/src/mcp/tools/macos/__tests__/test_macos.test.ts index 60a1d235..269e5cef 100644 --- a/src/mcp/tools/macos/__tests__/test_macos.test.ts +++ b/src/mcp/tools/macos/__tests__/test_macos.test.ts @@ -5,7 +5,7 @@ */ import { describe, it, expect } from 'vitest'; -import { createMockExecutor } from '../../../../utils/command.js'; +import { createMockExecutor } from '../../../../test-utils/mock-executors.js'; import testMacos, { testMacosLogic } from '../test_macos.ts'; describe('test_macos plugin (unified)', () => { diff --git a/src/mcp/tools/macos/launch_mac_app.ts b/src/mcp/tools/macos/launch_mac_app.ts index 0851a4f6..35ceaa7f 100644 --- a/src/mcp/tools/macos/launch_mac_app.ts +++ b/src/mcp/tools/macos/launch_mac_app.ts @@ -9,11 +9,8 @@ import { z } from 'zod'; import { log } from '../../../utils/index.js'; import { validateFileExists } from '../../../utils/index.js'; import { ToolResponse } from '../../../types/common.js'; -import { - CommandExecutor, - FileSystemExecutor, - getDefaultCommandExecutor, -} from '../../../utils/command.js'; +import { CommandExecutor, getDefaultCommandExecutor } from '../../../utils/command.js'; +import { FileSystemExecutor } from '../../../utils/FileSystemExecutor.ts'; import { createTypedTool } from '../../../utils/typed-tool-factory.js'; // Define schema as ZodObject diff --git a/src/mcp/tools/macos/test_macos.ts b/src/mcp/tools/macos/test_macos.ts index d4cda273..671b9e46 100644 --- a/src/mcp/tools/macos/test_macos.ts +++ b/src/mcp/tools/macos/test_macos.ts @@ -14,9 +14,9 @@ import { createTextResponse } from '../../../utils/index.js'; import { CommandExecutor, getDefaultCommandExecutor, - FileSystemExecutor, getDefaultFileSystemExecutor, } from '../../../utils/command.js'; +import { FileSystemExecutor } from '../../../utils/FileSystemExecutor.ts'; import { createTypedTool } from '../../../utils/typed-tool-factory.js'; import { nullifyEmptyStrings } from '../../../utils/schema-helpers.js'; diff --git a/src/mcp/tools/project-discovery/__tests__/discover_projs.test.ts b/src/mcp/tools/project-discovery/__tests__/discover_projs.test.ts index d4db2c7b..0fccfab8 100644 --- a/src/mcp/tools/project-discovery/__tests__/discover_projs.test.ts +++ b/src/mcp/tools/project-discovery/__tests__/discover_projs.test.ts @@ -10,7 +10,7 @@ import { describe, it, expect, beforeEach } from 'vitest'; import { z } from 'zod'; import plugin, { discover_projsLogic } from '../discover_projs.ts'; -import { createMockFileSystemExecutor } from '../../../../utils/index.js'; +import { createMockFileSystemExecutor } from '../../../../test-utils/mock-executors.js'; describe('discover_projs plugin', () => { let mockFileSystemExecutor: any; diff --git a/src/mcp/tools/project-discovery/__tests__/get_app_bundle_id.test.ts b/src/mcp/tools/project-discovery/__tests__/get_app_bundle_id.test.ts index 781bb250..5e696113 100644 --- a/src/mcp/tools/project-discovery/__tests__/get_app_bundle_id.test.ts +++ b/src/mcp/tools/project-discovery/__tests__/get_app_bundle_id.test.ts @@ -14,7 +14,7 @@ import plugin, { get_app_bundle_idLogic } from '../get_app_bundle_id.ts'; import { createMockFileSystemExecutor, createCommandMatchingMockExecutor, -} from '../../../../utils/command.js'; +} from '../../../../test-utils/mock-executors.js'; describe('get_app_bundle_id plugin', () => { // Helper function to create mock executor for command matching diff --git a/src/mcp/tools/project-discovery/__tests__/get_mac_bundle_id.test.ts b/src/mcp/tools/project-discovery/__tests__/get_mac_bundle_id.test.ts index 876dc7b3..6e919600 100644 --- a/src/mcp/tools/project-discovery/__tests__/get_mac_bundle_id.test.ts +++ b/src/mcp/tools/project-discovery/__tests__/get_mac_bundle_id.test.ts @@ -4,7 +4,7 @@ import plugin, { get_mac_bundle_idLogic } from '../get_mac_bundle_id.ts'; import { createMockFileSystemExecutor, createCommandMatchingMockExecutor, -} from '../../../../utils/command.js'; +} from '../../../../test-utils/mock-executors.js'; describe('get_mac_bundle_id plugin', () => { // Helper function to create mock executor for command matching diff --git a/src/mcp/tools/project-discovery/__tests__/list_schemes.test.ts b/src/mcp/tools/project-discovery/__tests__/list_schemes.test.ts index 815487f2..955e17d7 100644 --- a/src/mcp/tools/project-discovery/__tests__/list_schemes.test.ts +++ b/src/mcp/tools/project-discovery/__tests__/list_schemes.test.ts @@ -6,7 +6,7 @@ import { describe, it, expect } from 'vitest'; import { z } from 'zod'; -import { createMockExecutor } from '../../../../utils/command.js'; +import { createMockExecutor } from '../../../../test-utils/mock-executors.js'; import plugin, { listSchemesLogic } from '../list_schemes.js'; describe('list_schemes plugin', () => { diff --git a/src/mcp/tools/project-discovery/__tests__/show_build_settings.test.ts b/src/mcp/tools/project-discovery/__tests__/show_build_settings.test.ts index 588d23ec..f5882573 100644 --- a/src/mcp/tools/project-discovery/__tests__/show_build_settings.test.ts +++ b/src/mcp/tools/project-discovery/__tests__/show_build_settings.test.ts @@ -1,6 +1,6 @@ import { describe, it, expect } from 'vitest'; import { z } from 'zod'; -import { createMockExecutor } from '../../../../utils/command.js'; +import { createMockExecutor } from '../../../../test-utils/mock-executors.js'; import plugin, { showBuildSettingsLogic } from '../show_build_settings.ts'; describe('show_build_settings plugin', () => { diff --git a/src/mcp/tools/project-discovery/discover_projs.ts b/src/mcp/tools/project-discovery/discover_projs.ts index ba7604bd..1223a3ab 100644 --- a/src/mcp/tools/project-discovery/discover_projs.ts +++ b/src/mcp/tools/project-discovery/discover_projs.ts @@ -9,11 +9,8 @@ import { z } from 'zod'; import * as path from 'node:path'; import { log } from '../../../utils/index.js'; import { ToolResponse, createTextContent } from '../../../types/common.js'; -import { - FileSystemExecutor, - getDefaultFileSystemExecutor, - getDefaultCommandExecutor, -} from '../../../utils/command.js'; +import { getDefaultFileSystemExecutor, getDefaultCommandExecutor } from '../../../utils/command.js'; +import { FileSystemExecutor } from '../../../utils/FileSystemExecutor.ts'; import { createTypedTool } from '../../../utils/typed-tool-factory.js'; // Constants diff --git a/src/mcp/tools/project-discovery/get_app_bundle_id.ts b/src/mcp/tools/project-discovery/get_app_bundle_id.ts index 026dae1b..75c9e95b 100644 --- a/src/mcp/tools/project-discovery/get_app_bundle_id.ts +++ b/src/mcp/tools/project-discovery/get_app_bundle_id.ts @@ -10,10 +10,10 @@ import { log } from '../../../utils/index.js'; import { ToolResponse } from '../../../types/common.js'; import { CommandExecutor, - FileSystemExecutor, getDefaultFileSystemExecutor, getDefaultCommandExecutor, } from '../../../utils/command.js'; +import { FileSystemExecutor } from '../../../utils/FileSystemExecutor.ts'; import { createTypedTool } from '../../../utils/typed-tool-factory.js'; // Define schema as ZodObject diff --git a/src/mcp/tools/project-discovery/get_mac_bundle_id.ts b/src/mcp/tools/project-discovery/get_mac_bundle_id.ts index 19f3d8c6..ee0980be 100644 --- a/src/mcp/tools/project-discovery/get_mac_bundle_id.ts +++ b/src/mcp/tools/project-discovery/get_mac_bundle_id.ts @@ -9,10 +9,10 @@ import { log } from '../../../utils/index.js'; import { ToolResponse } from '../../../types/common.js'; import { CommandExecutor, - FileSystemExecutor, getDefaultFileSystemExecutor, getDefaultCommandExecutor, } from '../../../utils/command.js'; +import { FileSystemExecutor } from '../../../utils/FileSystemExecutor.ts'; import { createTypedTool } from '../../../utils/typed-tool-factory.js'; /** diff --git a/src/mcp/tools/project-scaffolding/__tests__/scaffold_ios_project.test.ts b/src/mcp/tools/project-scaffolding/__tests__/scaffold_ios_project.test.ts index c79af222..4632ebbf 100644 --- a/src/mcp/tools/project-scaffolding/__tests__/scaffold_ios_project.test.ts +++ b/src/mcp/tools/project-scaffolding/__tests__/scaffold_ios_project.test.ts @@ -10,7 +10,10 @@ import { describe, it, expect, beforeEach, afterEach } from 'vitest'; import { z } from 'zod'; import scaffoldIosProject, { scaffold_ios_projectLogic } from '../scaffold_ios_project.ts'; -import { createMockExecutor, createMockFileSystemExecutor } from '../../../../utils/index.js'; +import { + createMockExecutor, + createMockFileSystemExecutor, +} from '../../../../test-utils/mock-executors.js'; describe('scaffold_ios_project plugin', () => { let mockCommandExecutor: any; diff --git a/src/mcp/tools/project-scaffolding/__tests__/scaffold_macos_project.test.ts b/src/mcp/tools/project-scaffolding/__tests__/scaffold_macos_project.test.ts index 741540d3..1675d091 100644 --- a/src/mcp/tools/project-scaffolding/__tests__/scaffold_macos_project.test.ts +++ b/src/mcp/tools/project-scaffolding/__tests__/scaffold_macos_project.test.ts @@ -14,7 +14,7 @@ import { createMockFileSystemExecutor, createNoopExecutor, createMockExecutor, -} from '../../../../utils/command.js'; +} from '../../../../test-utils/mock-executors.js'; import plugin, { scaffold_macos_projectLogic } from '../scaffold_macos_project.js'; import { TemplateManager } from '../../../../utils/index.js'; diff --git a/src/mcp/tools/project-scaffolding/scaffold_macos_project.ts b/src/mcp/tools/project-scaffolding/scaffold_macos_project.ts index 22f1b0c5..0558b244 100644 --- a/src/mcp/tools/project-scaffolding/scaffold_macos_project.ts +++ b/src/mcp/tools/project-scaffolding/scaffold_macos_project.ts @@ -12,10 +12,10 @@ import { TemplateManager } from '../../../utils/index.js'; import { ToolResponse } from '../../../types/common.js'; import { CommandExecutor, - FileSystemExecutor, getDefaultCommandExecutor, getDefaultFileSystemExecutor, } from '../../../utils/command.js'; +import { FileSystemExecutor } from '../../../utils/FileSystemExecutor.ts'; // Common base schema for both iOS and macOS const BaseScaffoldSchema = z.object({ diff --git a/src/mcp/tools/simulator-management/__tests__/reset_sim_location.test.ts b/src/mcp/tools/simulator-management/__tests__/reset_sim_location.test.ts index 71d82206..02bfa3f6 100644 --- a/src/mcp/tools/simulator-management/__tests__/reset_sim_location.test.ts +++ b/src/mcp/tools/simulator-management/__tests__/reset_sim_location.test.ts @@ -1,7 +1,7 @@ import { describe, it, expect } from 'vitest'; import { z } from 'zod'; import resetSimLocationPlugin, { reset_sim_locationLogic } from '../reset_sim_location.ts'; -import { createMockExecutor } from '../../../../utils/command.js'; +import { createMockExecutor } from '../../../../test-utils/mock-executors.js'; describe('reset_sim_location plugin', () => { describe('Export Field Validation (Literal)', () => { diff --git a/src/mcp/tools/simulator-management/__tests__/set_sim_appearance.test.ts b/src/mcp/tools/simulator-management/__tests__/set_sim_appearance.test.ts index 89d61137..aa01487a 100644 --- a/src/mcp/tools/simulator-management/__tests__/set_sim_appearance.test.ts +++ b/src/mcp/tools/simulator-management/__tests__/set_sim_appearance.test.ts @@ -1,7 +1,7 @@ import { describe, it, expect } from 'vitest'; import { z } from 'zod'; import setSimAppearancePlugin, { set_sim_appearanceLogic } from '../set_sim_appearance.ts'; -import { createMockExecutor } from '../../../../utils/command.js'; +import { createMockExecutor } from '../../../../test-utils/mock-executors.js'; describe('set_sim_appearance plugin', () => { describe('Export Field Validation (Literal)', () => { diff --git a/src/mcp/tools/simulator-management/__tests__/set_sim_location.test.ts b/src/mcp/tools/simulator-management/__tests__/set_sim_location.test.ts index 47398e09..f5db3503 100644 --- a/src/mcp/tools/simulator-management/__tests__/set_sim_location.test.ts +++ b/src/mcp/tools/simulator-management/__tests__/set_sim_location.test.ts @@ -6,7 +6,7 @@ import { describe, it, expect, beforeEach } from 'vitest'; import { z } from 'zod'; -import { createMockExecutor, createNoopExecutor } from '../../../../utils/command.js'; +import { createMockExecutor, createNoopExecutor } from '../../../../test-utils/mock-executors.js'; import setSimLocation, { set_sim_locationLogic } from '../set_sim_location.ts'; describe('set_sim_location tool', () => { diff --git a/src/mcp/tools/simulator-management/__tests__/sim_statusbar.test.ts b/src/mcp/tools/simulator-management/__tests__/sim_statusbar.test.ts index 77ef7ced..81414a20 100644 --- a/src/mcp/tools/simulator-management/__tests__/sim_statusbar.test.ts +++ b/src/mcp/tools/simulator-management/__tests__/sim_statusbar.test.ts @@ -6,7 +6,7 @@ import { describe, it, expect } from 'vitest'; import { z } from 'zod'; -import { createMockExecutor, type CommandExecutor } from '../../../../utils/command.js'; +import { createMockExecutor, type CommandExecutor } from '../../../../test-utils/mock-executors.js'; import simStatusbar, { sim_statusbarLogic } from '../sim_statusbar.ts'; describe('sim_statusbar tool', () => { diff --git a/src/mcp/tools/simulator/__tests__/boot_sim.test.ts b/src/mcp/tools/simulator/__tests__/boot_sim.test.ts index 53c55fb6..ac1a2f06 100644 --- a/src/mcp/tools/simulator/__tests__/boot_sim.test.ts +++ b/src/mcp/tools/simulator/__tests__/boot_sim.test.ts @@ -10,7 +10,7 @@ import { createMockExecutor, createMockFileSystemExecutor, createNoopExecutor, -} from '../../../../utils/command.js'; +} from '../../../../test-utils/mock-executors.js'; import bootSim, { boot_simLogic } from '../boot_sim.ts'; describe('boot_sim tool', () => { diff --git a/src/mcp/tools/simulator/__tests__/build_run_sim.test.ts b/src/mcp/tools/simulator/__tests__/build_run_sim.test.ts index 3361ed03..fea58f55 100644 --- a/src/mcp/tools/simulator/__tests__/build_run_sim.test.ts +++ b/src/mcp/tools/simulator/__tests__/build_run_sim.test.ts @@ -5,7 +5,10 @@ import { describe, it, expect, beforeEach } from 'vitest'; import { z } from 'zod'; -import { createMockExecutor, createMockFileSystemExecutor } from '../../../../utils/command.js'; +import { + createMockExecutor, + createMockFileSystemExecutor, +} from '../../../../test-utils/mock-executors.js'; import buildRunSim, { build_run_simLogic } from '../build_run_sim.js'; describe('build_run_sim tool', () => { diff --git a/src/mcp/tools/simulator/__tests__/build_sim.test.ts b/src/mcp/tools/simulator/__tests__/build_sim.test.ts index 0f1b31f7..e1819d77 100644 --- a/src/mcp/tools/simulator/__tests__/build_sim.test.ts +++ b/src/mcp/tools/simulator/__tests__/build_sim.test.ts @@ -1,6 +1,6 @@ import { describe, it, expect, beforeEach } from 'vitest'; import { z } from 'zod'; -import { createMockExecutor } from '../../../../utils/command.js'; +import { createMockExecutor } from '../../../../test-utils/mock-executors.js'; // Import the plugin and logic function import buildSim, { build_simLogic } from '../build_sim.js'; diff --git a/src/mcp/tools/simulator/__tests__/install_app_sim.test.ts b/src/mcp/tools/simulator/__tests__/install_app_sim.test.ts index 77d07342..d6ac648b 100644 --- a/src/mcp/tools/simulator/__tests__/install_app_sim.test.ts +++ b/src/mcp/tools/simulator/__tests__/install_app_sim.test.ts @@ -4,7 +4,7 @@ import { createMockExecutor, createMockFileSystemExecutor, createNoopExecutor, -} from '../../../../utils/command.js'; +} from '../../../../test-utils/mock-executors.js'; import installAppSim, { install_app_simLogic } from '../install_app_sim.ts'; describe('install_app_sim tool', () => { diff --git a/src/mcp/tools/simulator/__tests__/launch_app_logs_sim.test.ts b/src/mcp/tools/simulator/__tests__/launch_app_logs_sim.test.ts index 359ade09..75dc140a 100644 --- a/src/mcp/tools/simulator/__tests__/launch_app_logs_sim.test.ts +++ b/src/mcp/tools/simulator/__tests__/launch_app_logs_sim.test.ts @@ -10,7 +10,7 @@ import launchAppLogsSim, { launch_app_logs_simLogic, LogCaptureFunction, } from '../launch_app_logs_sim.ts'; -import { createMockExecutor } from '../../../../utils/command.js'; +import { createMockExecutor } from '../../../../test-utils/mock-executors.js'; describe('launch_app_logs_sim tool', () => { describe('Export Field Validation (Literal)', () => { diff --git a/src/mcp/tools/simulator/__tests__/launch_app_sim.test.ts b/src/mcp/tools/simulator/__tests__/launch_app_sim.test.ts index 704dbb48..2c9695ec 100644 --- a/src/mcp/tools/simulator/__tests__/launch_app_sim.test.ts +++ b/src/mcp/tools/simulator/__tests__/launch_app_sim.test.ts @@ -1,6 +1,6 @@ import { describe, it, expect, beforeEach } from 'vitest'; import { z } from 'zod'; -import { createMockExecutor } from '../../../../utils/command.js'; +import { createMockExecutor } from '../../../../test-utils/mock-executors.js'; import launchAppSim, { launch_app_simLogic } from '../launch_app_sim.js'; describe('launch_app_sim tool', () => { diff --git a/src/mcp/tools/simulator/__tests__/list_sims.test.ts b/src/mcp/tools/simulator/__tests__/list_sims.test.ts index 08d26c9e..7a78d13f 100644 --- a/src/mcp/tools/simulator/__tests__/list_sims.test.ts +++ b/src/mcp/tools/simulator/__tests__/list_sims.test.ts @@ -1,6 +1,9 @@ import { describe, it, expect, beforeEach } from 'vitest'; import { z } from 'zod'; -import { createMockExecutor, createMockFileSystemExecutor } from '../../../../utils/command.js'; +import { + createMockExecutor, + createMockFileSystemExecutor, +} from '../../../../test-utils/mock-executors.js'; // Import the plugin and logic function import listSims, { list_simsLogic } from '../list_sims.ts'; diff --git a/src/mcp/tools/simulator/__tests__/open_sim.test.ts b/src/mcp/tools/simulator/__tests__/open_sim.test.ts index 2e18669c..feab6964 100644 --- a/src/mcp/tools/simulator/__tests__/open_sim.test.ts +++ b/src/mcp/tools/simulator/__tests__/open_sim.test.ts @@ -6,7 +6,7 @@ import { describe, it, expect } from 'vitest'; import { z } from 'zod'; -import { createMockExecutor, CommandExecutor } from '../../../../utils/command.js'; +import { createMockExecutor, type CommandExecutor } from '../../../../test-utils/mock-executors.js'; import openSim, { open_simLogic } from '../open_sim.ts'; describe('open_sim tool', () => { diff --git a/src/mcp/tools/simulator/__tests__/screenshot.test.ts b/src/mcp/tools/simulator/__tests__/screenshot.test.ts index c23f9a74..f17b8a71 100644 --- a/src/mcp/tools/simulator/__tests__/screenshot.test.ts +++ b/src/mcp/tools/simulator/__tests__/screenshot.test.ts @@ -10,7 +10,7 @@ import { createMockExecutor, createMockFileSystemExecutor, createCommandMatchingMockExecutor, -} from '../../../../utils/command.js'; +} from '../../../../test-utils/mock-executors.js'; import screenshotPlugin, { screenshotLogic } from '../../ui-testing/screenshot.ts'; describe('screenshot plugin', () => { diff --git a/src/mcp/tools/simulator/__tests__/stop_app_sim.test.ts b/src/mcp/tools/simulator/__tests__/stop_app_sim.test.ts index a90867f4..be03777a 100644 --- a/src/mcp/tools/simulator/__tests__/stop_app_sim.test.ts +++ b/src/mcp/tools/simulator/__tests__/stop_app_sim.test.ts @@ -4,7 +4,7 @@ import { createMockExecutor, createMockFileSystemExecutor, createNoopExecutor, -} from '../../../../utils/command.js'; +} from '../../../../test-utils/mock-executors.js'; import plugin, { stop_app_simLogic } from '../stop_app_sim.js'; describe('stop_app_sim plugin', () => { diff --git a/src/mcp/tools/swift-package/__tests__/swift_package_build.test.ts b/src/mcp/tools/swift-package/__tests__/swift_package_build.test.ts index d5d6c85c..1c84cacd 100644 --- a/src/mcp/tools/swift-package/__tests__/swift_package_build.test.ts +++ b/src/mcp/tools/swift-package/__tests__/swift_package_build.test.ts @@ -9,7 +9,7 @@ import { createMockExecutor, createMockFileSystemExecutor, createNoopExecutor, -} from '../../../../utils/command.js'; +} from '../../../../test-utils/mock-executors.js'; import swiftPackageBuild, { swift_package_buildLogic } from '../swift_package_build.ts'; describe('swift_package_build plugin', () => { diff --git a/src/mcp/tools/swift-package/__tests__/swift_package_clean.test.ts b/src/mcp/tools/swift-package/__tests__/swift_package_clean.test.ts index 5f5122e9..137a15f0 100644 --- a/src/mcp/tools/swift-package/__tests__/swift_package_clean.test.ts +++ b/src/mcp/tools/swift-package/__tests__/swift_package_clean.test.ts @@ -9,7 +9,7 @@ import { createMockExecutor, createMockFileSystemExecutor, createNoopExecutor, -} from '../../../../utils/command.js'; +} from '../../../../test-utils/mock-executors.js'; import swiftPackageClean, { swift_package_cleanLogic } from '../swift_package_clean.ts'; describe('swift_package_clean plugin', () => { diff --git a/src/mcp/tools/swift-package/__tests__/swift_package_run.test.ts b/src/mcp/tools/swift-package/__tests__/swift_package_run.test.ts index c2e86b65..420f2ee5 100644 --- a/src/mcp/tools/swift-package/__tests__/swift_package_run.test.ts +++ b/src/mcp/tools/swift-package/__tests__/swift_package_run.test.ts @@ -6,7 +6,7 @@ import { describe, it, expect, beforeEach } from 'vitest'; import { z } from 'zod'; -import { createMockExecutor, createNoopExecutor } from '../../../../utils/command.js'; +import { createMockExecutor, createNoopExecutor } from '../../../../test-utils/mock-executors.js'; import swiftPackageRun, { swift_package_runLogic } from '../swift_package_run.ts'; describe('swift_package_run plugin', () => { diff --git a/src/mcp/tools/swift-package/__tests__/swift_package_test.test.ts b/src/mcp/tools/swift-package/__tests__/swift_package_test.test.ts index 5aac2970..83cb434c 100644 --- a/src/mcp/tools/swift-package/__tests__/swift_package_test.test.ts +++ b/src/mcp/tools/swift-package/__tests__/swift_package_test.test.ts @@ -9,7 +9,7 @@ import { createMockExecutor, createMockFileSystemExecutor, createNoopExecutor, -} from '../../../../utils/command.js'; +} from '../../../../test-utils/mock-executors.js'; import swiftPackageTest, { swift_package_testLogic } from '../swift_package_test.ts'; describe('swift_package_test plugin', () => { diff --git a/src/mcp/tools/ui-testing/__tests__/button.test.ts b/src/mcp/tools/ui-testing/__tests__/button.test.ts index b7ecdd92..1d25fcff 100644 --- a/src/mcp/tools/ui-testing/__tests__/button.test.ts +++ b/src/mcp/tools/ui-testing/__tests__/button.test.ts @@ -4,7 +4,7 @@ import { describe, it, expect, beforeEach } from 'vitest'; import { z } from 'zod'; -import { createMockExecutor, createNoopExecutor } from '../../../../utils/command.js'; +import { createMockExecutor, createNoopExecutor } from '../../../../test-utils/mock-executors.js'; import buttonPlugin, { buttonLogic } from '../button.ts'; describe('Button Plugin', () => { diff --git a/src/mcp/tools/ui-testing/__tests__/describe_ui.test.ts b/src/mcp/tools/ui-testing/__tests__/describe_ui.test.ts index 2e9af9e8..cc3ce199 100644 --- a/src/mcp/tools/ui-testing/__tests__/describe_ui.test.ts +++ b/src/mcp/tools/ui-testing/__tests__/describe_ui.test.ts @@ -4,7 +4,7 @@ import { describe, it, expect, beforeEach } from 'vitest'; import { z } from 'zod'; -import { createMockExecutor, createNoopExecutor } from '../../../../utils/command.js'; +import { createMockExecutor, createNoopExecutor } from '../../../../test-utils/mock-executors.js'; import describeUIPlugin, { describe_uiLogic } from '../describe_ui.ts'; describe('Describe UI Plugin', () => { diff --git a/src/mcp/tools/ui-testing/__tests__/gesture.test.ts b/src/mcp/tools/ui-testing/__tests__/gesture.test.ts index d2a1e4fc..8fec1e0a 100644 --- a/src/mcp/tools/ui-testing/__tests__/gesture.test.ts +++ b/src/mcp/tools/ui-testing/__tests__/gesture.test.ts @@ -8,7 +8,7 @@ import { createMockExecutor, createMockFileSystemExecutor, createNoopExecutor, -} from '../../../../utils/command.js'; +} from '../../../../test-utils/mock-executors.js'; import gesturePlugin, { gestureLogic } from '../gesture.ts'; describe('Gesture Plugin', () => { diff --git a/src/mcp/tools/ui-testing/__tests__/key_press.test.ts b/src/mcp/tools/ui-testing/__tests__/key_press.test.ts index e839fc6b..ce41cb06 100644 --- a/src/mcp/tools/ui-testing/__tests__/key_press.test.ts +++ b/src/mcp/tools/ui-testing/__tests__/key_press.test.ts @@ -8,7 +8,7 @@ import { createMockExecutor, createMockFileSystemExecutor, createNoopExecutor, -} from '../../../../utils/command.js'; +} from '../../../../test-utils/mock-executors.js'; import keyPressPlugin, { key_pressLogic } from '../key_press.js'; describe('Key Press Plugin', () => { diff --git a/src/mcp/tools/ui-testing/__tests__/key_sequence.test.ts b/src/mcp/tools/ui-testing/__tests__/key_sequence.test.ts index 4a42e8bc..9fc23004 100644 --- a/src/mcp/tools/ui-testing/__tests__/key_sequence.test.ts +++ b/src/mcp/tools/ui-testing/__tests__/key_sequence.test.ts @@ -4,7 +4,7 @@ import { describe, it, expect } from 'vitest'; import { z } from 'zod'; -import { createMockExecutor, createNoopExecutor } from '../../../../utils/command.js'; +import { createMockExecutor, createNoopExecutor } from '../../../../test-utils/mock-executors.js'; import keySequencePlugin, { key_sequenceLogic } from '../key_sequence.ts'; describe('Key Sequence Plugin', () => { diff --git a/src/mcp/tools/ui-testing/__tests__/long_press.test.ts b/src/mcp/tools/ui-testing/__tests__/long_press.test.ts index 8ebaaea1..f0c0ee92 100644 --- a/src/mcp/tools/ui-testing/__tests__/long_press.test.ts +++ b/src/mcp/tools/ui-testing/__tests__/long_press.test.ts @@ -4,7 +4,7 @@ import { describe, it, expect } from 'vitest'; import { z } from 'zod'; -import { createMockExecutor } from '../../../../utils/command.js'; +import { createMockExecutor } from '../../../../test-utils/mock-executors.js'; import longPressPlugin, { long_pressLogic } from '../long_press.ts'; describe('Long Press Plugin', () => { diff --git a/src/mcp/tools/ui-testing/__tests__/screenshot.test.ts b/src/mcp/tools/ui-testing/__tests__/screenshot.test.ts index 22a21428..70cac7d3 100644 --- a/src/mcp/tools/ui-testing/__tests__/screenshot.test.ts +++ b/src/mcp/tools/ui-testing/__tests__/screenshot.test.ts @@ -8,7 +8,7 @@ import { createMockExecutor, createMockFileSystemExecutor, createNoopExecutor, -} from '../../../../utils/command.js'; +} from '../../../../test-utils/mock-executors.js'; import screenshotPlugin, { screenshotLogic } from '../screenshot.ts'; describe('Screenshot Plugin', () => { diff --git a/src/mcp/tools/ui-testing/__tests__/swipe.test.ts b/src/mcp/tools/ui-testing/__tests__/swipe.test.ts index 2841faa8..9eca23e9 100644 --- a/src/mcp/tools/ui-testing/__tests__/swipe.test.ts +++ b/src/mcp/tools/ui-testing/__tests__/swipe.test.ts @@ -4,7 +4,7 @@ import { describe, it, expect } from 'vitest'; import { z } from 'zod'; -import { createMockExecutor, createNoopExecutor } from '../../../../utils/command.js'; +import { createMockExecutor, createNoopExecutor } from '../../../../test-utils/mock-executors.js'; import { SystemError, DependencyError } from '../../../../utils/index.js'; // Import the plugin module to test diff --git a/src/mcp/tools/ui-testing/__tests__/tap.test.ts b/src/mcp/tools/ui-testing/__tests__/tap.test.ts index 14ebad48..2279f1aa 100644 --- a/src/mcp/tools/ui-testing/__tests__/tap.test.ts +++ b/src/mcp/tools/ui-testing/__tests__/tap.test.ts @@ -4,7 +4,7 @@ import { describe, it, expect, beforeEach } from 'vitest'; import { z } from 'zod'; -import { createMockExecutor } from '../../../../utils/command.js'; +import { createMockExecutor } from '../../../../test-utils/mock-executors.js'; import tapPlugin, { AxeHelpers, tapLogic } from '../tap.ts'; diff --git a/src/mcp/tools/ui-testing/__tests__/touch.test.ts b/src/mcp/tools/ui-testing/__tests__/touch.test.ts index 71b1b3fd..c1e0eb77 100644 --- a/src/mcp/tools/ui-testing/__tests__/touch.test.ts +++ b/src/mcp/tools/ui-testing/__tests__/touch.test.ts @@ -5,7 +5,7 @@ import { describe, it, expect, beforeEach } from 'vitest'; import { z } from 'zod'; -import { createMockExecutor } from '../../../../utils/command.js'; +import { createMockExecutor } from '../../../../test-utils/mock-executors.js'; import touchPlugin, { touchLogic } from '../touch.ts'; describe('Touch Plugin', () => { diff --git a/src/mcp/tools/ui-testing/__tests__/type_text.test.ts b/src/mcp/tools/ui-testing/__tests__/type_text.test.ts index ce420760..f201d831 100644 --- a/src/mcp/tools/ui-testing/__tests__/type_text.test.ts +++ b/src/mcp/tools/ui-testing/__tests__/type_text.test.ts @@ -8,7 +8,7 @@ import { createMockExecutor, createMockFileSystemExecutor, createNoopExecutor, -} from '../../../../utils/command.js'; +} from '../../../../test-utils/mock-executors.js'; import typeTextPlugin, { type_textLogic } from '../type_text.ts'; // Mock axe helpers for dependency injection diff --git a/src/mcp/tools/utilities/__tests__/clean.test.ts b/src/mcp/tools/utilities/__tests__/clean.test.ts index f65699f5..9d37eaeb 100644 --- a/src/mcp/tools/utilities/__tests__/clean.test.ts +++ b/src/mcp/tools/utilities/__tests__/clean.test.ts @@ -1,6 +1,6 @@ import { describe, it, expect } from 'vitest'; import tool, { cleanLogic } from '../clean.ts'; -import { createMockExecutor } from '../../../../utils/command.js'; +import { createMockExecutor } from '../../../../test-utils/mock-executors.js'; describe('clean (unified) tool', () => { it('exports correct name/description/schema/handler', () => { diff --git a/src/test-utils/mock-executors.ts b/src/test-utils/mock-executors.ts new file mode 100644 index 00000000..f74e7777 --- /dev/null +++ b/src/test-utils/mock-executors.ts @@ -0,0 +1,267 @@ +/** + * Mock Executors for Testing - Dependency Injection Architecture + * + * This module provides mock implementations of CommandExecutor and FileSystemExecutor + * for testing purposes. These mocks are completely isolated from production dependencies + * to avoid import chains that could trigger native module loading issues in test environments. + * + * IMPORTANT: These are EXACT copies of the mock functions originally in utils/command.js + * to ensure zero behavioral changes during the file reorganization. + * + * Responsibilities: + * - Providing mock command execution for tests + * - Providing mock file system operations for tests + * - Maintaining exact behavior compatibility with original implementations + * - Avoiding any dependencies on production logging or instrumentation + */ + +import { ChildProcess } from 'child_process'; +import { CommandExecutor } from '../utils/CommandExecutor.ts'; +import { FileSystemExecutor } from '../utils/FileSystemExecutor.ts'; + +/** + * Create a mock executor for testing + * @param result Mock command result or error to throw + * @returns Mock executor function + */ +export function createMockExecutor( + result: + | { + success?: boolean; + output?: string; + error?: string; + process?: unknown; + } + | Error + | string, +): CommandExecutor { + // If result is Error or string, return executor that rejects + if (result instanceof Error || typeof result === 'string') { + return async () => { + throw result; + }; + } + + const mockProcess = { + pid: 12345, + stdout: null, + stderr: null, + stdin: null, + stdio: [null, null, null], + killed: false, + connected: false, + exitCode: result.success === false ? 1 : 0, + signalCode: null, + spawnargs: [], + spawnfile: 'sh', + } as unknown as ChildProcess; + + return async () => ({ + success: result.success ?? true, + output: result.output ?? '', + error: result.error, + process: (result.process ?? mockProcess) as ChildProcess, + }); +} + +/** + * Create a no-op executor that throws an error if called + * Use this for tests where an executor is required but should never be called + * @returns CommandExecutor that throws on invocation + */ +export function createNoopExecutor(): CommandExecutor { + return async (command) => { + throw new Error( + `🚨 NOOP EXECUTOR CALLED! 🚨\n` + + `Command: ${command.join(' ')}\n` + + `This executor should never be called in this test context.\n` + + `If you see this error, it means the test is exercising a code path that wasn't expected.\n` + + `Either fix the test to avoid this code path, or use createMockExecutor() instead.`, + ); + }; +} + +/** + * Create a command-matching mock executor for testing multi-command scenarios + * Perfect for tools that execute multiple commands (like screenshot: simctl + sips) + * + * @param commandMap - Map of command patterns to their mock responses + * @returns CommandExecutor that matches commands and returns appropriate responses + * + * @example + * ```typescript + * const mockExecutor = createCommandMatchingMockExecutor({ + * 'xcrun simctl': { output: 'Screenshot saved' }, + * 'sips': { output: 'Image optimized' } + * }); + * ``` + */ +export function createCommandMatchingMockExecutor( + commandMap: Record< + string, + { + success?: boolean; + output?: string; + error?: string; + process?: unknown; + } + >, +): CommandExecutor { + return async (command) => { + const commandStr = command.join(' '); + + // Find matching command pattern + const matchedKey = Object.keys(commandMap).find((key) => commandStr.includes(key)); + + if (!matchedKey) { + throw new Error( + `🚨 UNEXPECTED COMMAND! 🚨\n` + + `Command: ${commandStr}\n` + + `Expected one of: ${Object.keys(commandMap).join(', ')}\n` + + `Available patterns: ${JSON.stringify(Object.keys(commandMap), null, 2)}`, + ); + } + + const result = commandMap[matchedKey]; + + const mockProcess = { + pid: 12345, + stdout: null, + stderr: null, + stdin: null, + stdio: [null, null, null], + killed: false, + connected: false, + exitCode: result.success === false ? 1 : 0, + signalCode: null, + spawnargs: [], + spawnfile: 'sh', + } as unknown as ChildProcess; + + return { + success: result.success ?? true, // Success by default (as discussed) + output: result.output ?? '', + error: result.error, + process: (result.process ?? mockProcess) as ChildProcess, + }; + }; +} + +/** + * Create a mock file system executor for testing + */ +export function createMockFileSystemExecutor( + overrides?: Partial, +): FileSystemExecutor { + return { + mkdir: async (): Promise => {}, + readFile: async (): Promise => 'mock file content', + writeFile: async (): Promise => {}, + cp: async (): Promise => {}, + readdir: async (): Promise => [], + rm: async (): Promise => {}, + existsSync: (): boolean => false, + stat: async (): Promise<{ isDirectory(): boolean }> => ({ isDirectory: (): boolean => true }), + mkdtemp: async (): Promise => '/tmp/mock-temp-123456', + tmpdir: (): string => '/tmp', + ...overrides, + }; +} + +/** + * Create a no-op file system executor that throws an error if called + * Use this for tests where an executor is required but should never be called + * @returns CommandExecutor that throws on invocation + */ +export function createNoopFileSystemExecutor(): FileSystemExecutor { + return { + mkdir: async (): Promise => { + throw new Error( + `🚨 NOOP FILESYSTEM EXECUTOR CALLED! 🚨\n` + + `This executor should never be called in this test context.\n` + + `If you see this error, it means the test is exercising a code path that wasn't expected.\n` + + `Either fix the test to avoid this code path, or use createMockFileSystemExecutor() instead.`, + ); + }, + readFile: async (): Promise => { + throw new Error( + `🚨 NOOP FILESYSTEM EXECUTOR CALLED! 🚨\n` + + `This executor should never be called in this test context.\n` + + `If you see this error, it means the test is exercising a code path that wasn't expected.\n` + + `Either fix the test to avoid this code path, or use createMockFileSystemExecutor() instead.`, + ); + }, + writeFile: async (): Promise => { + throw new Error( + `🚨 NOOP FILESYSTEM EXECUTOR CALLED! 🚨\n` + + `This executor should never be called in this test context.\n` + + `If you see this error, it means the test is exercising a code path that wasn't expected.\n` + + `Either fix the test to avoid this code path, or use createMockFileSystemExecutor() instead.`, + ); + }, + cp: async (): Promise => { + throw new Error( + `🚨 NOOP FILESYSTEM EXECUTOR CALLED! 🚨\n` + + `This executor should never be called in this test context.\n` + + `If you see this error, it means the test is exercising a code path that wasn't expected.\n` + + `Either fix the test to avoid this code path, or use createMockFileSystemExecutor() instead.`, + ); + }, + readdir: async (): Promise => { + throw new Error( + `🚨 NOOP FILESYSTEM EXECUTOR CALLED! 🚨\n` + + `This executor should never be called in this test context.\n` + + `If you see this error, it means the test is exercising a code path that wasn't expected.\n` + + `Either fix the test to avoid this code path, or use createMockFileSystemExecutor() instead.`, + ); + }, + rm: async (): Promise => { + throw new Error( + `🚨 NOOP FILESYSTEM EXECUTOR CALLED! 🚨\n` + + `This executor should never be called in this test context.\n` + + `If you see this error, it means the test is exercising a code path that wasn't expected.\n` + + `Either fix the test to avoid this code path, or use createMockFileSystemExecutor() instead.`, + ); + }, + existsSync: (): boolean => { + throw new Error( + `🚨 NOOP FILESYSTEM EXECUTOR CALLED! 🚨\n` + + `This executor should never be called in this test context.\n` + + `If you see this error, it means the test is exercising a code path that wasn't expected.\n` + + `Either fix the test to avoid this code path, or use createMockFileSystemExecutor() instead.`, + ); + }, + stat: async (): Promise<{ isDirectory(): boolean }> => { + throw new Error( + `🚨 NOOP FILESYSTEM EXECUTOR CALLED! 🚨\n` + + `This executor should never be called in this test context.\n` + + `If you see this error, it means the test is exercising a code path that wasn't expected.\n` + + `Either fix the test to avoid this code path, or use createMockFileSystemExecutor() instead.`, + ); + }, + mkdtemp: async (): Promise => { + throw new Error( + `🚨 NOOP FILESYSTEM EXECUTOR CALLED! 🚨\n` + + `This executor should never be called in this test context.\n` + + `If you see this error, it means the test is exercising a code path that wasn't expected.\n` + + `Either fix the test to avoid this code path, or use createMockFileSystemExecutor() instead.`, + ); + }, + tmpdir: (): string => '/tmp', + }; +} + +/** + * Create a mock environment detector for testing + * @param options Mock options for environment detection + * @returns Mock environment detector + */ +export function createMockEnvironmentDetector( + options: { + isRunningUnderClaudeCode?: boolean; + } = {}, +): import('../utils/environment.js').EnvironmentDetector { + return { + isRunningUnderClaudeCode: () => options.isRunningUnderClaudeCode ?? false, + }; +} diff --git a/src/utils/CommandExecutor.ts b/src/utils/CommandExecutor.ts new file mode 100644 index 00000000..ff85881b --- /dev/null +++ b/src/utils/CommandExecutor.ts @@ -0,0 +1,22 @@ +import { ChildProcess } from 'child_process'; + +/** + * Command executor function type for dependency injection + */ +export type CommandExecutor = ( + command: string[], + logPrefix?: string, + useShell?: boolean, + env?: Record, + detached?: boolean, +) => Promise; +/** + * Command execution response interface + */ + +export interface CommandResponse { + success: boolean; + output: string; + error?: string; + process: ChildProcess; +} diff --git a/src/utils/FileSystemExecutor.ts b/src/utils/FileSystemExecutor.ts new file mode 100644 index 00000000..5c91258c --- /dev/null +++ b/src/utils/FileSystemExecutor.ts @@ -0,0 +1,16 @@ +/** + * File system executor interface for dependency injection + */ + +export interface FileSystemExecutor { + mkdir(path: string, options?: { recursive?: boolean }): Promise; + readFile(path: string, encoding?: BufferEncoding): Promise; + writeFile(path: string, content: string, encoding?: BufferEncoding): Promise; + cp(source: string, destination: string, options?: { recursive?: boolean }): Promise; + readdir(path: string, options?: { withFileTypes?: boolean }): Promise; + rm(path: string, options?: { recursive?: boolean; force?: boolean }): Promise; + existsSync(path: string): boolean; + stat(path: string): Promise<{ isDirectory(): boolean }>; + mkdtemp(prefix: string): Promise; + tmpdir(): string; +} diff --git a/src/utils/__tests__/simulator-utils.test.ts b/src/utils/__tests__/simulator-utils.test.ts index d83ee3e7..3d29a1bf 100644 --- a/src/utils/__tests__/simulator-utils.test.ts +++ b/src/utils/__tests__/simulator-utils.test.ts @@ -1,6 +1,6 @@ import { describe, it, expect } from 'vitest'; import { determineSimulatorUuid } from '../simulator-utils.js'; -import { createMockExecutor } from '../command.js'; +import { createMockExecutor } from '../../test-utils/mock-executors.js'; describe('determineSimulatorUuid', () => { const mockSimulatorListOutput = JSON.stringify({ diff --git a/src/utils/__tests__/typed-tool-factory.test.ts b/src/utils/__tests__/typed-tool-factory.test.ts index e81c2148..71e38b19 100644 --- a/src/utils/__tests__/typed-tool-factory.test.ts +++ b/src/utils/__tests__/typed-tool-factory.test.ts @@ -5,7 +5,7 @@ import { describe, it, expect } from 'vitest'; import { z } from 'zod'; import { createTypedTool } from '../typed-tool-factory.js'; -import { createMockExecutor } from '../command.js'; +import { createMockExecutor } from '../../test-utils/mock-executors.js'; import { ToolResponse } from '../../types/common.js'; // Test schema and types diff --git a/src/utils/command.ts b/src/utils/command.ts index c25063a7..d4ca8deb 100644 --- a/src/utils/command.ts +++ b/src/utils/command.ts @@ -9,47 +9,16 @@ * - Managing process spawning, output capture, and error handling */ -import { spawn, ChildProcess } from 'child_process'; +import { spawn } from 'child_process'; import { existsSync } from 'fs'; import { tmpdir as osTmpdir } from 'os'; import { log } from './logger.js'; +import { FileSystemExecutor } from './FileSystemExecutor.ts'; +import { CommandExecutor, CommandResponse } from './CommandExecutor.ts'; -/** - * Command execution response interface - */ -export interface CommandResponse { - success: boolean; - output: string; - error?: string; - process: ChildProcess; -} - -/** - * Command executor function type for dependency injection - */ -export type CommandExecutor = ( - command: string[], - logPrefix?: string, - useShell?: boolean, - env?: Record, - detached?: boolean, -) => Promise; - -/** - * File system executor interface for dependency injection - */ -export interface FileSystemExecutor { - mkdir(path: string, options?: { recursive?: boolean }): Promise; - readFile(path: string, encoding?: BufferEncoding): Promise; - writeFile(path: string, content: string, encoding?: BufferEncoding): Promise; - cp(source: string, destination: string, options?: { recursive?: boolean }): Promise; - readdir(path: string, options?: { withFileTypes?: boolean }): Promise; - rm(path: string, options?: { recursive?: boolean; force?: boolean }): Promise; - existsSync(path: string): boolean; - stat(path: string): Promise<{ isDirectory(): boolean }>; - mkdtemp(prefix: string): Promise; - tmpdir(): string; -} +// Re-export types for backward compatibility +export { CommandExecutor, CommandResponse } from './CommandExecutor.js'; +export { FileSystemExecutor } from './FileSystemExecutor.js'; /** * Default executor implementation using spawn (current production behavior) @@ -258,250 +227,3 @@ export function getDefaultFileSystemExecutor(): FileSystemExecutor { } return defaultFileSystemExecutor; } - -/** - * Create a mock executor for testing - * @param result Mock command result or error to throw - * @returns Mock executor function - */ -export function createMockExecutor( - result: - | { - success?: boolean; - output?: string; - error?: string; - process?: unknown; - } - | Error - | string, -): CommandExecutor { - // If result is Error or string, return executor that rejects - if (result instanceof Error || typeof result === 'string') { - return async () => { - throw result; - }; - } - - const mockProcess = { - pid: 12345, - stdout: null, - stderr: null, - stdin: null, - stdio: [null, null, null], - killed: false, - connected: false, - exitCode: result.success === false ? 1 : 0, - signalCode: null, - spawnargs: [], - spawnfile: 'sh', - } as unknown as ChildProcess; - - return async () => ({ - success: result.success ?? true, - output: result.output ?? '', - error: result.error, - process: (result.process ?? mockProcess) as ChildProcess, - }); -} - -/** - * Create a no-op executor that throws an error if called - * Use this for tests where an executor is required but should never be called - * @returns CommandExecutor that throws on invocation - */ -export function createNoopExecutor(): CommandExecutor { - return async (command) => { - throw new Error( - `🚨 NOOP EXECUTOR CALLED! 🚨\n` + - `Command: ${command.join(' ')}\n` + - `This executor should never be called in this test context.\n` + - `If you see this error, it means the test is exercising a code path that wasn't expected.\n` + - `Either fix the test to avoid this code path, or use createMockExecutor() instead.`, - ); - }; -} - -/** - * Create a command-matching mock executor for testing multi-command scenarios - * Perfect for tools that execute multiple commands (like screenshot: simctl + sips) - * - * @param commandMap - Map of command patterns to their mock responses - * @returns CommandExecutor that matches commands and returns appropriate responses - * - * @example - * ```typescript - * const mockExecutor = createCommandMatchingMockExecutor({ - * 'xcrun simctl': { output: 'Screenshot saved' }, - * 'sips': { output: 'Image optimized' } - * }); - * ``` - */ -export function createCommandMatchingMockExecutor( - commandMap: Record< - string, - { - success?: boolean; - output?: string; - error?: string; - process?: unknown; - } - >, -): CommandExecutor { - return async (command) => { - const commandStr = command.join(' '); - - // Find matching command pattern - const matchedKey = Object.keys(commandMap).find((key) => commandStr.includes(key)); - - if (!matchedKey) { - throw new Error( - `🚨 UNEXPECTED COMMAND! 🚨\n` + - `Command: ${commandStr}\n` + - `Expected one of: ${Object.keys(commandMap).join(', ')}\n` + - `Available patterns: ${JSON.stringify(Object.keys(commandMap), null, 2)}`, - ); - } - - const result = commandMap[matchedKey]; - - const mockProcess = { - pid: 12345, - stdout: null, - stderr: null, - stdin: null, - stdio: [null, null, null], - killed: false, - connected: false, - exitCode: result.success === false ? 1 : 0, - signalCode: null, - spawnargs: [], - spawnfile: 'sh', - } as unknown as ChildProcess; - - return { - success: result.success ?? true, // Success by default (as discussed) - output: result.output ?? '', - error: result.error, - process: (result.process ?? mockProcess) as ChildProcess, - }; - }; -} - -/** - * Create a mock file system executor for testing - */ -export function createMockFileSystemExecutor( - overrides?: Partial, -): FileSystemExecutor { - return { - mkdir: async (): Promise => {}, - readFile: async (): Promise => 'mock file content', - writeFile: async (): Promise => {}, - cp: async (): Promise => {}, - readdir: async (): Promise => [], - rm: async (): Promise => {}, - existsSync: (): boolean => false, - stat: async (): Promise<{ isDirectory(): boolean }> => ({ isDirectory: (): boolean => true }), - mkdtemp: async (): Promise => '/tmp/mock-temp-123456', - tmpdir: (): string => '/tmp', - ...overrides, - }; -} - -/** - * Create a no-op file system executor that throws an error if called - * Use this for tests where an executor is required but should never be called - * @returns CommandExecutor that throws on invocation - */ -export function createNoopFileSystemExecutor(): FileSystemExecutor { - return { - mkdir: async (): Promise => { - throw new Error( - `🚨 NOOP FILESYSTEM EXECUTOR CALLED! 🚨\n` + - `This executor should never be called in this test context.\n` + - `If you see this error, it means the test is exercising a code path that wasn't expected.\n` + - `Either fix the test to avoid this code path, or use createMockFileSystemExecutor() instead.`, - ); - }, - readFile: async (): Promise => { - throw new Error( - `🚨 NOOP FILESYSTEM EXECUTOR CALLED! 🚨\n` + - `This executor should never be called in this test context.\n` + - `If you see this error, it means the test is exercising a code path that wasn't expected.\n` + - `Either fix the test to avoid this code path, or use createMockFileSystemExecutor() instead.`, - ); - }, - writeFile: async (): Promise => { - throw new Error( - `🚨 NOOP FILESYSTEM EXECUTOR CALLED! 🚨\n` + - `This executor should never be called in this test context.\n` + - `If you see this error, it means the test is exercising a code path that wasn't expected.\n` + - `Either fix the test to avoid this code path, or use createMockFileSystemExecutor() instead.`, - ); - }, - cp: async (): Promise => { - throw new Error( - `🚨 NOOP FILESYSTEM EXECUTOR CALLED! 🚨\n` + - `This executor should never be called in this test context.\n` + - `If you see this error, it means the test is exercising a code path that wasn't expected.\n` + - `Either fix the test to avoid this code path, or use createMockFileSystemExecutor() instead.`, - ); - }, - readdir: async (): Promise => { - throw new Error( - `🚨 NOOP FILESYSTEM EXECUTOR CALLED! 🚨\n` + - `This executor should never be called in this test context.\n` + - `If you see this error, it means the test is exercising a code path that wasn't expected.\n` + - `Either fix the test to avoid this code path, or use createMockFileSystemExecutor() instead.`, - ); - }, - rm: async (): Promise => { - throw new Error( - `🚨 NOOP FILESYSTEM EXECUTOR CALLED! 🚨\n` + - `This executor should never be called in this test context.\n` + - `If you see this error, it means the test is exercising a code path that wasn't expected.\n` + - `Either fix the test to avoid this code path, or use createMockFileSystemExecutor() instead.`, - ); - }, - existsSync: (): boolean => { - throw new Error( - `🚨 NOOP FILESYSTEM EXECUTOR CALLED! 🚨\n` + - `This executor should never be called in this test context.\n` + - `If you see this error, it means the test is exercising a code path that wasn't expected.\n` + - `Either fix the test to avoid this code path, or use createMockFileSystemExecutor() instead.`, - ); - }, - stat: async (): Promise<{ isDirectory(): boolean }> => { - throw new Error( - `🚨 NOOP FILESYSTEM EXECUTOR CALLED! 🚨\n` + - `This executor should never be called in this test context.\n` + - `If you see this error, it means the test is exercising a code path that wasn't expected.\n` + - `Either fix the test to avoid this code path, or use createMockFileSystemExecutor() instead.`, - ); - }, - mkdtemp: async (): Promise => { - throw new Error( - `🚨 NOOP FILESYSTEM EXECUTOR CALLED! 🚨\n` + - `This executor should never be called in this test context.\n` + - `If you see this error, it means the test is exercising a code path that wasn't expected.\n` + - `Either fix the test to avoid this code path, or use createMockFileSystemExecutor() instead.`, - ); - }, - tmpdir: (): string => '/tmp', - }; -} - -/** - * Create a mock environment detector for testing - * @param options Mock options for environment detection - * @returns Mock environment detector - */ -export function createMockEnvironmentDetector( - options: { - isRunningUnderClaudeCode?: boolean; - } = {}, -): import('./environment.js').EnvironmentDetector { - return { - isRunningUnderClaudeCode: () => options.isRunningUnderClaudeCode ?? false, - }; -} diff --git a/src/utils/index.ts b/src/utils/index.ts index 8468926d..9354ca87 100644 --- a/src/utils/index.ts +++ b/src/utils/index.ts @@ -1,6 +1,8 @@ // Export all utilities for plugin consumption export * from './logger.js'; export * from './command.js'; +export * from './CommandExecutor.js'; +export * from './FileSystemExecutor.js'; export * from './validation.js'; export * from './errors.js'; export * from './build-utils.js'; diff --git a/src/utils/template-manager.ts b/src/utils/template-manager.ts index 72c6887e..f5d0b371 100644 --- a/src/utils/template-manager.ts +++ b/src/utils/template-manager.ts @@ -3,7 +3,8 @@ import { tmpdir } from 'os'; import { randomUUID } from 'crypto'; import { log } from './logger.js'; import { iOSTemplateVersion, macOSTemplateVersion } from '../version.js'; -import { CommandExecutor, FileSystemExecutor } from './command.js'; +import { CommandExecutor } from './command.js'; +import { FileSystemExecutor } from './FileSystemExecutor.ts'; /** * Template manager for downloading and managing project templates diff --git a/src/utils/validation.ts b/src/utils/validation.ts index 1063341e..2153e833 100644 --- a/src/utils/validation.ts +++ b/src/utils/validation.ts @@ -23,7 +23,7 @@ import * as fs from 'fs'; import { log } from './logger.js'; import { ToolResponse, ValidationResult } from '../types/common.js'; -import { FileSystemExecutor } from './command.js'; +import { FileSystemExecutor } from './FileSystemExecutor.ts'; import { getDefaultEnvironmentDetector } from './environment.js'; /** From 68a290b0302af992ac4f68d51de21dae2e25f096 Mon Sep 17 00:00:00 2001 From: Cameron Cooke Date: Sat, 16 Aug 2025 22:57:55 +0100 Subject: [PATCH 2/8] feat: migrate from barrel imports to focused facades pattern This commit implements a comprehensive architectural improvement that replaces the previous barrel import pattern (importing everything from utils/index.ts) with focused facades that expose specific functionality through dedicated index.ts files in subdirectories. Key Changes: - Created 11 focused facade modules in src/utils/ (execution, logging, responses, validation, axe, plugin-registry, xcodemake, template, version, test, log-capture) - Migrated 65+ tool files from barrel imports to focused facade imports - Added ESLint rule to prevent regression to barrel imports - Updated ARCHITECTURE.md to document the new module organization pattern Performance Impact: - Eliminates loading of unused modules, reducing startup time - Improves module resolution speed for Node.js runtime - Prevents circular dependency issues that were risks with large barrel files - Enables better tree-shaking for bundlers Architecture Benefits: - Clear dependency graph - imports explicitly show what functionality is needed - Reduced coupling between unrelated utility components - Better maintainability and code organization - Type-safe imports with focused interfaces --- docs/ARCHITECTURE.md | 213 +++++++++++++----- eslint.config.js | 8 + src/core/resources.ts | 3 +- src/doctor-cli.ts | 2 +- src/mcp/resources/devices.ts | 4 +- src/mcp/resources/simulators.ts | 4 +- src/mcp/tools/device/build_device.ts | 5 +- src/mcp/tools/device/get_device_app_path.ts | 7 +- src/mcp/tools/device/install_app_device.ts | 4 +- src/mcp/tools/device/launch_app_device.ts | 4 +- src/mcp/tools/device/list_devices.ts | 6 +- src/mcp/tools/device/stop_app_device.ts | 4 +- src/mcp/tools/device/test_device.ts | 11 +- src/mcp/tools/discovery/discover_tools.ts | 6 +- src/mcp/tools/doctor/doctor.ts | 7 +- src/mcp/tools/doctor/lib/doctor.deps.ts | 10 +- src/mcp/tools/logging/start_device_log_cap.ts | 9 +- src/mcp/tools/logging/start_sim_log_cap.ts | 2 +- src/mcp/tools/logging/stop_device_log_cap.ts | 2 +- src/mcp/tools/logging/stop_sim_log_cap.ts | 2 +- src/mcp/tools/macos/build_macos.ts | 7 +- src/mcp/tools/macos/build_run_macos.ts | 9 +- src/mcp/tools/macos/get_mac_app_path.ts | 5 +- src/mcp/tools/macos/launch_mac_app.ts | 8 +- src/mcp/tools/macos/stop_mac_app.ts | 5 +- src/mcp/tools/macos/test_macos.ts | 11 +- .../tools/project-discovery/discover_projs.ts | 2 +- .../project-discovery/get_app_bundle_id.ts | 2 +- .../project-discovery/get_mac_bundle_id.ts | 2 +- .../tools/project-discovery/list_schemes.ts | 7 +- .../project-discovery/show_build_settings.ts | 7 +- .../__tests__/scaffold_macos_project.test.ts | 2 +- .../scaffold_ios_project.ts | 11 +- .../scaffold_macos_project.ts | 6 +- src/mcp/tools/simulator/boot_sim.ts | 4 +- src/mcp/tools/simulator/build_run_sim.ts | 12 +- src/mcp/tools/simulator/build_sim.ts | 7 +- src/mcp/tools/simulator/get_sim_app_path.ts | 7 +- src/mcp/tools/simulator/install_app_sim.ts | 11 +- .../tools/simulator/launch_app_logs_sim.ts | 7 +- src/mcp/tools/simulator/launch_app_sim.ts | 5 +- src/mcp/tools/simulator/list_sims.ts | 6 +- src/mcp/tools/simulator/open_sim.ts | 4 +- src/mcp/tools/simulator/stop_app_sim.ts | 4 +- src/mcp/tools/simulator/test_sim.ts | 8 +- .../swift-package/swift_package_build.ts | 10 +- .../swift-package/swift_package_clean.ts | 7 +- .../tools/swift-package/swift_package_run.ts | 8 +- .../tools/swift-package/swift_package_stop.ts | 3 +- .../tools/swift-package/swift_package_test.ts | 8 +- .../tools/ui-testing/__tests__/swipe.test.ts | 2 +- src/mcp/tools/ui-testing/button.ts | 24 +- src/mcp/tools/ui-testing/describe_ui.ts | 15 +- src/mcp/tools/ui-testing/gesture.ts | 13 +- src/mcp/tools/ui-testing/key_press.ts | 13 +- src/mcp/tools/ui-testing/key_sequence.ts | 13 +- src/mcp/tools/ui-testing/long_press.ts | 13 +- src/mcp/tools/ui-testing/screenshot.ts | 10 +- src/mcp/tools/ui-testing/swipe.ts | 16 +- src/mcp/tools/ui-testing/tap.ts | 18 +- src/mcp/tools/ui-testing/touch.ts | 16 +- src/mcp/tools/ui-testing/type_text.ts | 16 +- src/mcp/tools/utilities/clean.ts | 13 +- src/utils/axe/index.ts | 6 + src/utils/execution/index.ts | 9 + src/utils/index.ts | 4 +- src/utils/log-capture/index.ts | 1 + src/utils/logger.ts | 40 +++- src/utils/logging/index.ts | 5 + src/utils/plugin-registry/index.ts | 2 + src/utils/responses/index.ts | 15 ++ src/utils/simulator-utils.ts | 5 +- src/utils/template/index.ts | 1 + src/utils/test/index.ts | 1 + src/utils/typed-tool-factory.ts | 4 +- src/utils/validation/index.ts | 5 + src/utils/version/index.ts | 1 + src/utils/xcodemake/index.ts | 1 + 78 files changed, 491 insertions(+), 299 deletions(-) create mode 100644 src/utils/axe/index.ts create mode 100644 src/utils/execution/index.ts create mode 100644 src/utils/log-capture/index.ts create mode 100644 src/utils/logging/index.ts create mode 100644 src/utils/plugin-registry/index.ts create mode 100644 src/utils/responses/index.ts create mode 100644 src/utils/template/index.ts create mode 100644 src/utils/test/index.ts create mode 100644 src/utils/validation/index.ts create mode 100644 src/utils/version/index.ts create mode 100644 src/utils/xcodemake/index.ts diff --git a/docs/ARCHITECTURE.md b/docs/ARCHITECTURE.md index b2121ccc..58ccbf1f 100644 --- a/docs/ARCHITECTURE.md +++ b/docs/ARCHITECTURE.md @@ -38,17 +38,22 @@ XcodeBuildMCP is a Model Context Protocol (MCP) server that exposes Xcode operat - MCP server created with stdio transport - Plugin discovery system initialized -3. **Plugin Discovery & Loading** - - `loadPlugins()` scans `src/mcp/tools/` directory automatically - - `loadResources()` scans `src/mcp/resources/` directory automatically - - Each tool exports standardized interface (`name`, `description`, `schema`, `handler`) - - Tools are self-contained with no external dependencies - - Dynamic vs static mode determines loading behavior - -4. **Tool Registration** - - Discovered tools automatically registered with server +3. **Plugin Discovery (Build-Time)** + - A build-time script (`build-plugins/plugin-discovery.ts`) scans the `src/mcp/tools/` and `src/mcp/resources/` directories + - It generates `src/core/generated-plugins.ts` and `src/core/generated-resources.ts` with dynamic import maps + - This approach improves startup performance by avoiding synchronous file system scans and enables code-splitting + - Tool code is only loaded when needed, reducing initial memory footprint + +4. **Plugin & Resource Loading (Runtime)** + - At runtime, `loadPlugins()` and `loadResources()` use the generated loaders from the previous step + - In **Static Mode**, all workflow loaders are executed at startup to register all tools + - In **Dynamic Mode**, only the `discover_tools` tool is registered initially + - The `enableWorkflows` function in `src/core/dynamic-tools.ts` uses generated loaders to dynamically import and register selected workflow tools on demand + +5. **Tool Registration** + - Discovered tools automatically registered with server using pre-generated maps - No manual registration or configuration required - - Environment variables can still control dynamic tool discovery + - Environment variables control dynamic tool discovery behavior 5. **Request Handling** - MCP client calls tool → server routes to tool handler @@ -85,6 +90,66 @@ Tools are self-contained units that export a standardized interface. They don't - Zod schemas for runtime validation - Generic type constraints ensure compile-time safety +## Module Organization and Import Strategy + +### Focused Facades Pattern + +XcodeBuildMCP has migrated from a traditional "barrel file" export pattern (`src/utils/index.ts`) to a more structured **focused facades** pattern. Each distinct area of functionality within `src/utils` is exposed through its own `index.ts` file in a dedicated subdirectory. + +**Example Structure:** + +``` +src/utils/ +├── execution/ +│ └── index.ts # Facade for CommandExecutor, FileSystemExecutor +├── logging/ +│ └── index.ts # Facade for the logger +├── responses/ +│ └── index.ts # Facade for error types and response creators +├── validation/ +│ └── index.ts # Facade for validation utilities +├── axe/ +│ └── index.ts # Facade for axe UI automation helpers +├── plugin-registry/ +│ └── index.ts # Facade for plugin system utilities +├── xcodemake/ +│ └── index.ts # Facade for xcodemake utilities +├── template/ +│ └── index.ts # Facade for template management utilities +├── version/ +│ └── index.ts # Facade for version information +├── test/ +│ └── index.ts # Facade for test utilities +├── log-capture/ +│ └── index.ts # Facade for log capture utilities +└── index.ts # Deprecated barrel file (legacy/external use only) +``` + +This approach offers several architectural benefits: + +- **Clear Dependencies**: It makes the dependency graph explicit. Importing from `utils/execution` clearly indicates a dependency on command execution logic +- **Reduced Coupling**: Modules only import the functionality they need, reducing coupling between unrelated utility components +- **Prevention of Circular Dependencies**: It's much harder to create circular dependencies, which were a risk with the large barrel file +- **Improved Tree-Shaking**: Bundlers can more effectively eliminate unused code +- **Performance**: Eliminates loading of unused modules, reducing startup time and memory usage + +### ESLint Enforcement + +To maintain this architecture, an ESLint rule in `eslint.config.js` explicitly forbids importing from the deprecated barrel file within the `src/` directory. + +**ESLint Rule Snippet** (`eslint.config.js`): + +```javascript +'no-restricted-imports': ['error', { + patterns: [{ + group: ['**/utils/index.js', '../utils/index.js', '../../utils/index.js', '../../../utils/index.js'], + message: 'Barrel imports from utils/index.js are prohibited. Use focused facade imports instead (e.g., utils/logging/index.js, utils/execution/index.js).' + }] +}], +``` + +This rule prevents regression to the previous barrel import pattern and ensures all new code follows the focused facade architecture. + ## Component Details ### Entry Points @@ -116,12 +181,12 @@ MCP server wrapper providing: ### Tool Discovery System #### `src/core/plugin-registry.ts` -Automatic plugin loading system: -- Scans `src/mcp/tools/` directory structure using glob patterns -- Dynamically imports plugin modules -- Validates plugin interface compliance -- Handles both default exports and named exports (for re-exports) -- Supports workflow group metadata via `index.js` files +Runtime plugin loading system that leverages build-time generated code: +- Uses `WORKFLOW_LOADERS` and `WORKFLOW_METADATA` maps from the generated `src/core/generated-plugins.ts` file +- `loadWorkflowGroups()` iterates through the loaders, dynamically importing each workflow module using `await loader()` +- Validates that each imported module contains the required `workflow` metadata export +- Aggregates all tools from the loaded workflows into a single map +- This system eliminates runtime file system scanning, providing significant startup performance boost #### `src/core/plugin-types.ts` Plugin type definitions: @@ -131,49 +196,74 @@ Plugin type definitions: ### Tool Implementation -Each plugin (`src/mcp/tools/*/*.js`) follows this standardized pattern: +Each tool is implemented in TypeScript and follows a standardized pattern that separates the core business logic from the MCP handler boilerplate. This is achieved using the `createTypedTool` factory, which provides compile-time and runtime type safety. -```javascript -// 1. Import dependencies and schemas +**Standard Tool Pattern** (`src/mcp/tools/some-workflow/some_tool.ts`): + +```typescript import { z } from 'zod'; -import { log } from '../../src/utils/logger.js'; -import { executeCommand } from '../../src/utils/command.js'; +import { createTypedTool } from '../../../utils/typed-tool-factory.js'; +import type { CommandExecutor } from '../../../utils/execution/index.js'; +import { getDefaultCommandExecutor } from '../../../utils/execution/index.js'; +import { log } from '../../../utils/logging/index.js'; +import { createTextResponse, createErrorResponse } from '../../../utils/responses/index.js'; + +// 1. Define the Zod schema for parameters +const someToolSchema = z.object({ + requiredParam: z.string().describe('Description for AI'), + optionalParam: z.boolean().optional().describe('Optional parameter'), +}); -// 2. Define and export plugin -export default { - name: 'tool_name', - description: 'Tool description for AI agents', - - // 3. Define parameter schema - schema: { - requiredParam: z.string().describe('Description for AI'), - optionalParam: z.string().optional().describe('Optional parameter') - }, +// 2. Infer the parameter type from the schema +type SomeToolParams = z.infer; + +// 3. Implement the core logic in a separate, testable function +// This function receives strongly-typed parameters and an injected executor. +export async function someToolLogic( + params: SomeToolParams, + executor: CommandExecutor, +): Promise { + log('info', `Executing some_tool with param: ${params.requiredParam}`); - // 4. Implement handler function - async handler(params) { - try { - // 5. Execute tool logic using shared utilities - const result = await executeCommand(['some', 'command']); - - // 6. Return standardized response - return { - content: [{ type: 'text', text: result.output }], - isError: false - }; - } catch (error) { - return { - content: [{ type: 'text', text: `Error: ${error.message}` }], - isError: true - }; + try { + const result = await executor(['some', 'command'], 'Some Tool Operation'); + + if (!result.success) { + return createErrorResponse('Operation failed', result.error); } + + return createTextResponse(`✅ Success: ${result.output}`); + } catch (error) { + const errorMessage = error instanceof Error ? error.message : String(error); + return createErrorResponse('Tool execution failed', errorMessage); } +} + +// 4. Export the tool definition for auto-discovery +export default { + name: 'some_tool', + description: 'Tool description for AI agents. Example: some_tool({ requiredParam: "value" })', + schema: someToolSchema.shape, // Expose shape for MCP SDK + + // 5. Create the handler using the type-safe factory + handler: createTypedTool( + someToolSchema, + someToolLogic, + getDefaultCommandExecutor, + ), }; ``` +This pattern ensures that: +- The `someToolLogic` function is highly testable via dependency injection +- Zod handles all runtime parameter validation automatically +- The handler is type-safe, preventing unsafe access to parameters +- Import paths use focused facades for clear dependency management +``` + ### MCP Resources System -XcodeBuildMCP provides dual interfaces: traditional MCP tools and efficient MCP resources for supported clients. Resources are located in `src/mcp/resources/` and are automatically discovered. For more details on creating resources, see the [Plugin Development Guide](docs/PLUGIN_DEVELOPMENT.md). +XcodeBuildMCP provides dual interfaces: traditional MCP tools and efficient MCP resources for supported clients. Resources are located in `src/mcp/resources/` and are automatically discovered **at build time**. The build process generates `src/core/generated-resources.ts`, which contains dynamic loaders for each resource, improving startup performance. For more details on creating resources, see the [Plugin Development Guide](docs/PLUGIN_DEVELOPMENT.md). #### Resource Architecture @@ -201,7 +291,8 @@ Resources can reuse existing tool logic for consistency: ```typescript // src/mcp/resources/some_resource.ts -import { log, getDefaultCommandExecutor, CommandExecutor } from '../../utils/index.js'; +import { log } from '../../utils/logging/index.js'; +import { getDefaultCommandExecutor, CommandExecutor } from '../../utils/execution/index.js'; import { getSomeResourceLogic } from '../tools/some-workflow/get_some_resource.js'; // Testable resource logic separated from MCP handler @@ -330,12 +421,12 @@ For detailed guidelines, see the [Testing Guide](docs/TESTING.md). ### Test Structure Example -Tests inject mock "executors" for external interactions like command-line execution or file system access. This allows for deterministic testing of tool logic without mocking the implementation itself. +Tests inject mock "executors" for external interactions like command-line execution or file system access. This allows for deterministic testing of tool logic without mocking the implementation itself. The project provides helper functions like `createMockExecutor` and `createMockFileSystemExecutor` in `src/test-utils/mock-executors.ts` to facilitate this pattern. ```typescript import { describe, it, expect } from 'vitest'; -import { toolNameLogic } from '../tool-file.js'; // Import the logic function -import { createMockExecutor } from '../../../utils/test-common.js'; +import { someToolLogic } from '../tool-file.js'; // Import the logic function +import { createMockExecutor } from '../../../test-utils/mock-executors.js'; describe('Tool Name', () => { it('should execute successfully', async () => { @@ -346,7 +437,7 @@ describe('Tool Name', () => { }); // 2. Call the tool's logic function, injecting the mock executor - const result = await toolNameLogic({ param: 'value' }, mockExecutor); + const result = await someToolLogic({ requiredParam: 'value' }, mockExecutor); // 3. Assert the final result expect(result).toEqual({ @@ -367,15 +458,24 @@ describe('Tool Name', () => { ``` - Reads version from `package.json` - Generates `src/version.ts` + +2. **Plugin & Resource Loader Generation** + - The `build-plugins/plugin-discovery.ts` script is executed + - It scans `src/mcp/tools/` and `src/mcp/resources/` to find all workflows and resources + - It generates `src/core/generated-plugins.ts` and `src/core/generated-resources.ts` with dynamic import maps + - This eliminates runtime file system scanning and enables code-splitting + +3. **TypeScript Compilation** + - `tsup` compiles the TypeScript source, including the newly generated files, into JavaScript - Compiles TypeScript with tsup -2. **Build Configuration** (`tsup.config.ts`) +4. **Build Configuration** (`tsup.config.ts`) - Entry points: `index.ts`, `doctor-cli.ts` - Output format: ESM - Target: Node 18+ - Source maps enabled -3. **Distribution Structure** +5. **Distribution Structure** ``` build/ ├── index.js # Main server executable @@ -417,6 +517,9 @@ The guide covers: ### Startup Performance +- **Build-Time Plugin Discovery**: The server avoids expensive and slow file system scans at startup by using pre-generated loader maps. This is the single most significant performance optimization +- **Code-Splitting**: In Dynamic Mode, tool code is only loaded into memory when its workflow is enabled, reducing the initial memory footprint and parse time +- **Focused Facades**: Using targeted imports instead of a large barrel file improves module resolution speed for the Node.js runtime - **Lazy Loading**: Tools only initialized when registered - **Selective Registration**: Fewer tools = faster startup - **Minimal Dependencies**: Fast module resolution diff --git a/eslint.config.js b/eslint.config.js index 9a9e00f4..34574d07 100644 --- a/eslint.config.js +++ b/eslint.config.js @@ -56,6 +56,14 @@ export default [ '@typescript-eslint/prefer-as-const': 'warn', '@typescript-eslint/prefer-nullish-coalescing': 'warn', '@typescript-eslint/prefer-optional-chain': 'warn', + + // Prevent barrel imports to maintain architectural improvements + 'no-restricted-imports': ['error', { + patterns: [{ + group: ['**/utils/index.js', '../utils/index.js', '../../utils/index.js', '../../../utils/index.js'], + message: 'Barrel imports from utils/index.js are prohibited. Use focused facade imports instead (e.g., utils/logging/index.js, utils/execution/index.js).' + }] + }], }, }, { diff --git a/src/core/resources.ts b/src/core/resources.ts index 8ba4ec53..9a709ded 100644 --- a/src/core/resources.ts +++ b/src/core/resources.ts @@ -13,7 +13,8 @@ import { McpServer } from '@camsoft/mcp-sdk/server/mcp.js'; import { ReadResourceResult } from '@camsoft/mcp-sdk/types.js'; -import { log, CommandExecutor } from '../utils/index.js'; +import { log } from '../utils/logging/index.js'; +import type { CommandExecutor } from '../utils/execution/index.js'; import { RESOURCE_LOADERS } from './generated-resources.js'; /** diff --git a/src/doctor-cli.ts b/src/doctor-cli.ts index a9e469ee..88f1d746 100644 --- a/src/doctor-cli.ts +++ b/src/doctor-cli.ts @@ -9,7 +9,7 @@ import { version } from './version.js'; import { doctorLogic } from './mcp/tools/doctor/doctor.js'; -import { getDefaultCommandExecutor } from './utils/index.js'; +import { getDefaultCommandExecutor } from './utils/execution/index.js'; async function runDoctor(): Promise { try { diff --git a/src/mcp/resources/devices.ts b/src/mcp/resources/devices.ts index fd77edce..eeb8dc2f 100644 --- a/src/mcp/resources/devices.ts +++ b/src/mcp/resources/devices.ts @@ -5,7 +5,9 @@ * This resource reuses the existing list_devices tool logic to maintain consistency. */ -import { log, getDefaultCommandExecutor, CommandExecutor } from '../../utils/index.js'; +import { log } from '../../utils/logging/index.js'; +import type { CommandExecutor } from '../../utils/execution/index.js'; +import { getDefaultCommandExecutor } from '../../utils/execution/index.js'; import { list_devicesLogic } from '../tools/device/list_devices.js'; // Testable resource logic separated from MCP handler diff --git a/src/mcp/resources/simulators.ts b/src/mcp/resources/simulators.ts index fe7ca884..b11774e9 100644 --- a/src/mcp/resources/simulators.ts +++ b/src/mcp/resources/simulators.ts @@ -5,7 +5,9 @@ * This resource reuses the existing list_sims tool logic to maintain consistency. */ -import { log, getDefaultCommandExecutor, CommandExecutor } from '../../utils/index.js'; +import { log } from '../../utils/logging/index.js'; +import { getDefaultCommandExecutor } from '../../utils/execution/index.js'; +import type { CommandExecutor } from '../../utils/execution/index.js'; import { list_simsLogic } from '../tools/simulator/list_sims.js'; // Testable resource logic separated from MCP handler diff --git a/src/mcp/tools/device/build_device.ts b/src/mcp/tools/device/build_device.ts index f8b675c6..d641c522 100644 --- a/src/mcp/tools/device/build_device.ts +++ b/src/mcp/tools/device/build_device.ts @@ -7,8 +7,9 @@ import { z } from 'zod'; import { ToolResponse, XcodePlatform } from '../../../types/common.js'; -import { executeXcodeBuildCommand } from '../../../utils/index.js'; -import { CommandExecutor, getDefaultCommandExecutor } from '../../../utils/command.js'; +import { executeXcodeBuildCommand } from '../../../utils/build-utils.js'; +import type { CommandExecutor } from '../../../utils/execution/index.js'; +import { getDefaultCommandExecutor } from '../../../utils/execution/index.js'; import { createTypedTool } from '../../../utils/typed-tool-factory.js'; import { nullifyEmptyStrings } from '../../../utils/schema-helpers.js'; diff --git a/src/mcp/tools/device/get_device_app_path.ts b/src/mcp/tools/device/get_device_app_path.ts index e6263c08..7e640852 100644 --- a/src/mcp/tools/device/get_device_app_path.ts +++ b/src/mcp/tools/device/get_device_app_path.ts @@ -7,9 +7,10 @@ import { z } from 'zod'; import { ToolResponse, XcodePlatform } from '../../../types/common.js'; -import { log } from '../../../utils/index.js'; -import { createTextResponse } from '../../../utils/index.js'; -import { CommandExecutor, getDefaultCommandExecutor } from '../../../utils/index.js'; +import { log } from '../../../utils/logging/index.js'; +import { createTextResponse } from '../../../utils/responses/index.js'; +import type { CommandExecutor } from '../../../utils/execution/index.js'; +import { getDefaultCommandExecutor } from '../../../utils/execution/index.js'; import { createTypedTool } from '../../../utils/typed-tool-factory.js'; import { nullifyEmptyStrings } from '../../../utils/schema-helpers.js'; diff --git a/src/mcp/tools/device/install_app_device.ts b/src/mcp/tools/device/install_app_device.ts index 265796d2..abdf5fb3 100644 --- a/src/mcp/tools/device/install_app_device.ts +++ b/src/mcp/tools/device/install_app_device.ts @@ -7,7 +7,9 @@ import { z } from 'zod'; import { ToolResponse } from '../../../types/common.js'; -import { log, CommandExecutor, getDefaultCommandExecutor } from '../../../utils/index.js'; +import { log } from '../../../utils/logging/index.js'; +import type { CommandExecutor } from '../../../utils/execution/index.js'; +import { getDefaultCommandExecutor } from '../../../utils/execution/index.js'; import { createTypedTool } from '../../../utils/typed-tool-factory.js'; // Define schema as ZodObject diff --git a/src/mcp/tools/device/launch_app_device.ts b/src/mcp/tools/device/launch_app_device.ts index b9bc4fb2..c2c05dcc 100644 --- a/src/mcp/tools/device/launch_app_device.ts +++ b/src/mcp/tools/device/launch_app_device.ts @@ -7,7 +7,9 @@ import { z } from 'zod'; import { ToolResponse } from '../../../types/common.js'; -import { log, CommandExecutor, getDefaultCommandExecutor } from '../../../utils/index.js'; +import { log } from '../../../utils/logging/index.js'; +import type { CommandExecutor } from '../../../utils/execution/index.js'; +import { getDefaultCommandExecutor } from '../../../utils/execution/index.js'; import { createTypedTool } from '../../../utils/typed-tool-factory.js'; import { promises as fs } from 'fs'; import { tmpdir } from 'os'; diff --git a/src/mcp/tools/device/list_devices.ts b/src/mcp/tools/device/list_devices.ts index 82270787..2e31abbc 100644 --- a/src/mcp/tools/device/list_devices.ts +++ b/src/mcp/tools/device/list_devices.ts @@ -6,8 +6,10 @@ */ import { z } from 'zod'; -import { ToolResponse } from '../../../types/common.js'; -import { log, CommandExecutor, getDefaultCommandExecutor } from '../../../utils/index.js'; +import type { ToolResponse } from '../../../types/common.js'; +import { log } from '../../../utils/logging/index.js'; +import type { CommandExecutor } from '../../../utils/execution/index.js'; +import { getDefaultCommandExecutor } from '../../../utils/execution/index.js'; import { createTypedTool } from '../../../utils/typed-tool-factory.js'; import { promises as fs } from 'fs'; import { tmpdir } from 'os'; diff --git a/src/mcp/tools/device/stop_app_device.ts b/src/mcp/tools/device/stop_app_device.ts index 0d981a5f..ec112c33 100644 --- a/src/mcp/tools/device/stop_app_device.ts +++ b/src/mcp/tools/device/stop_app_device.ts @@ -7,7 +7,9 @@ import { z } from 'zod'; import { ToolResponse } from '../../../types/common.js'; -import { log, CommandExecutor, getDefaultCommandExecutor } from '../../../utils/index.js'; +import { log } from '../../../utils/logging/index.js'; +import type { CommandExecutor } from '../../../utils/execution/index.js'; +import { getDefaultCommandExecutor } from '../../../utils/execution/index.js'; import { createTypedTool } from '../../../utils/typed-tool-factory.js'; // Define schema as ZodObject diff --git a/src/mcp/tools/device/test_device.ts b/src/mcp/tools/device/test_device.ts index 23c71c68..b402a5f7 100644 --- a/src/mcp/tools/device/test_device.ts +++ b/src/mcp/tools/device/test_device.ts @@ -8,15 +8,14 @@ import { z } from 'zod'; import { join } from 'path'; import { ToolResponse, XcodePlatform } from '../../../types/common.js'; -import { log } from '../../../utils/index.js'; -import { executeXcodeBuildCommand } from '../../../utils/index.js'; -import { createTextResponse } from '../../../utils/index.js'; +import { log } from '../../../utils/logging/index.js'; +import { executeXcodeBuildCommand } from '../../../utils/build/index.js'; +import { createTextResponse } from '../../../utils/responses/index.js'; +import type { CommandExecutor, FileSystemExecutor } from '../../../utils/execution/index.js'; import { - CommandExecutor, getDefaultCommandExecutor, getDefaultFileSystemExecutor, -} from '../../../utils/command.js'; -import { FileSystemExecutor } from '../../../utils/FileSystemExecutor.ts'; +} from '../../../utils/execution/index.js'; import { createTypedTool } from '../../../utils/typed-tool-factory.js'; import { nullifyEmptyStrings } from '../../../utils/schema-helpers.js'; diff --git a/src/mcp/tools/discovery/discover_tools.ts b/src/mcp/tools/discovery/discover_tools.ts index 6e44219a..08f3e9cd 100644 --- a/src/mcp/tools/discovery/discover_tools.ts +++ b/src/mcp/tools/discovery/discover_tools.ts @@ -1,6 +1,6 @@ import { z } from 'zod'; -import { createTextResponse } from '../../../utils/index.js'; -import { log } from '../../../utils/index.js'; +import { createTextResponse } from '../../../utils/responses/index.js'; +import { log } from '../../../utils/logging/index.js'; // Removed CreateMessageResultSchema import as it's no longer used import { ToolResponse } from '../../../types/common.js'; import { @@ -9,7 +9,7 @@ import { generateWorkflowDescriptions, } from '../../../core/dynamic-tools.js'; import { createTypedTool } from '../../../utils/typed-tool-factory.js'; -import { getDefaultCommandExecutor } from '../../../utils/command.js'; +import { getDefaultCommandExecutor } from '../../../utils/execution/index.js'; import { McpServer } from '@camsoft/mcp-sdk/server/mcp.js'; // Using McpServer type from SDK instead of custom interface diff --git a/src/mcp/tools/doctor/doctor.ts b/src/mcp/tools/doctor/doctor.ts index 0aaef4b5..146f8749 100644 --- a/src/mcp/tools/doctor/doctor.ts +++ b/src/mcp/tools/doctor/doctor.ts @@ -5,9 +5,10 @@ */ import { z } from 'zod'; -import { log } from '../../../utils/index.js'; -import { CommandExecutor, getDefaultCommandExecutor } from '../../../utils/index.js'; -import { version } from '../../../utils/index.js'; +import { log } from '../../../utils/logging/index.js'; +import type { CommandExecutor } from '../../../utils/execution/index.js'; +import { getDefaultCommandExecutor } from '../../../utils/execution/index.js'; +import { version } from '../../../utils/version/index.js'; import { ToolResponse } from '../../../types/common.js'; import { createTypedTool } from '../../../utils/typed-tool-factory.js'; import { type DoctorDependencies, createDoctorDependencies } from './lib/doctor.deps.ts'; diff --git a/src/mcp/tools/doctor/lib/doctor.deps.ts b/src/mcp/tools/doctor/lib/doctor.deps.ts index ff8c3206..d0ce8480 100644 --- a/src/mcp/tools/doctor/lib/doctor.deps.ts +++ b/src/mcp/tools/doctor/lib/doctor.deps.ts @@ -1,14 +1,16 @@ import * as os from 'os'; +import type { CommandExecutor } from '../../../../utils/execution/index.js'; import { - CommandExecutor, loadWorkflowGroups, loadPlugins, - areAxeToolsAvailable, + getEnabledWorkflows, +} from '../../../../utils/plugin-registry/index.js'; +import { areAxeToolsAvailable } from '../../../../utils/axe/index.js'; +import { isXcodemakeEnabled, isXcodemakeAvailable, doesMakefileExist, - getEnabledWorkflows, -} from '../../../../utils/index.js'; +} from '../../../../utils/xcodemake/index.js'; import { getTrackedToolNames } from '../../../../utils/tool-registry.js'; export interface BinaryChecker { diff --git a/src/mcp/tools/logging/start_device_log_cap.ts b/src/mcp/tools/logging/start_device_log_cap.ts index ec2f9ad2..b10bde4b 100644 --- a/src/mcp/tools/logging/start_device_log_cap.ts +++ b/src/mcp/tools/logging/start_device_log_cap.ts @@ -9,12 +9,9 @@ import * as path from 'path'; import * as os from 'os'; import { v4 as uuidv4 } from 'uuid'; import { z } from 'zod'; -import { - log, - CommandExecutor, - FileSystemExecutor, - getDefaultCommandExecutor, -} from '../../../utils/index.js'; +import { log } from '../../../utils/logging/index.js'; +import type { CommandExecutor, FileSystemExecutor } from '../../../utils/execution/index.js'; +import { getDefaultCommandExecutor } from '../../../utils/execution/index.js'; import { ToolResponse } from '../../../types/common.js'; import { createTypedTool } from '../../../utils/typed-tool-factory.js'; diff --git a/src/mcp/tools/logging/start_sim_log_cap.ts b/src/mcp/tools/logging/start_sim_log_cap.ts index 645a6654..139ffe44 100644 --- a/src/mcp/tools/logging/start_sim_log_cap.ts +++ b/src/mcp/tools/logging/start_sim_log_cap.ts @@ -5,7 +5,7 @@ */ import { z } from 'zod'; -import { startLogCapture } from '../../../utils/index.js'; +import { startLogCapture } from '../../../utils/log-capture/index.js'; import { CommandExecutor, getDefaultCommandExecutor } from '../../../utils/command.js'; import { ToolResponse, createTextContent } from '../../../types/common.js'; import { createTypedTool } from '../../../utils/typed-tool-factory.js'; diff --git a/src/mcp/tools/logging/stop_device_log_cap.ts b/src/mcp/tools/logging/stop_device_log_cap.ts index 3cf888aa..b3a68773 100644 --- a/src/mcp/tools/logging/stop_device_log_cap.ts +++ b/src/mcp/tools/logging/stop_device_log_cap.ts @@ -7,7 +7,7 @@ import * as fs from 'fs'; import type { ChildProcess } from 'child_process'; import { z } from 'zod'; -import { log } from '../../../utils/index.js'; +import { log } from '../../../utils/logging/index.js'; import { activeDeviceLogSessions } from './start_device_log_cap.js'; import { ToolResponse } from '../../../types/common.js'; import { getDefaultFileSystemExecutor, getDefaultCommandExecutor } from '../../../utils/command.js'; diff --git a/src/mcp/tools/logging/stop_sim_log_cap.ts b/src/mcp/tools/logging/stop_sim_log_cap.ts index e38533df..90a42789 100644 --- a/src/mcp/tools/logging/stop_sim_log_cap.ts +++ b/src/mcp/tools/logging/stop_sim_log_cap.ts @@ -5,7 +5,7 @@ */ import { z } from 'zod'; -import { stopLogCapture as _stopLogCapture } from '../../../utils/index.js'; +import { stopLogCapture as _stopLogCapture } from '../../../utils/log-capture/index.js'; import { ToolResponse, createTextContent } from '../../../types/common.js'; import { createTypedTool } from '../../../utils/typed-tool-factory.js'; import { getDefaultCommandExecutor } from '../../../utils/command.js'; diff --git a/src/mcp/tools/macos/build_macos.ts b/src/mcp/tools/macos/build_macos.ts index 0abe28c6..8a2aec6a 100644 --- a/src/mcp/tools/macos/build_macos.ts +++ b/src/mcp/tools/macos/build_macos.ts @@ -6,10 +6,11 @@ */ import { z } from 'zod'; -import { log } from '../../../utils/index.js'; -import { executeXcodeBuildCommand } from '../../../utils/index.js'; +import { log } from '../../../utils/logging/index.js'; +import { executeXcodeBuildCommand } from '../../../utils/build/index.js'; import { ToolResponse, XcodePlatform } from '../../../types/common.js'; -import { CommandExecutor, getDefaultCommandExecutor } from '../../../utils/command.js'; +import type { CommandExecutor } from '../../../utils/execution/index.js'; +import { getDefaultCommandExecutor } from '../../../utils/execution/index.js'; import { createTypedTool } from '../../../utils/typed-tool-factory.js'; import { nullifyEmptyStrings } from '../../../utils/schema-helpers.js'; diff --git a/src/mcp/tools/macos/build_run_macos.ts b/src/mcp/tools/macos/build_run_macos.ts index 9d6bdc78..febddba9 100644 --- a/src/mcp/tools/macos/build_run_macos.ts +++ b/src/mcp/tools/macos/build_run_macos.ts @@ -6,11 +6,12 @@ */ import { z } from 'zod'; -import { log } from '../../../utils/index.js'; -import { createTextResponse } from '../../../utils/index.js'; -import { executeXcodeBuildCommand } from '../../../utils/index.js'; +import { log } from '../../../utils/logging/index.js'; +import { createTextResponse } from '../../../utils/responses/index.js'; +import { executeXcodeBuildCommand } from '../../../utils/build/index.js'; import { ToolResponse, XcodePlatform } from '../../../types/common.js'; -import { CommandExecutor, getDefaultCommandExecutor } from '../../../utils/command.js'; +import type { CommandExecutor } from '../../../utils/execution/index.js'; +import { getDefaultCommandExecutor } from '../../../utils/execution/index.js'; import { createTypedTool } from '../../../utils/typed-tool-factory.js'; import { nullifyEmptyStrings } from '../../../utils/schema-helpers.js'; diff --git a/src/mcp/tools/macos/get_mac_app_path.ts b/src/mcp/tools/macos/get_mac_app_path.ts index 581c344e..c10a02cf 100644 --- a/src/mcp/tools/macos/get_mac_app_path.ts +++ b/src/mcp/tools/macos/get_mac_app_path.ts @@ -7,8 +7,9 @@ import { z } from 'zod'; import { ToolResponse } from '../../../types/common.js'; -import { log } from '../../../utils/index.js'; -import { CommandExecutor, getDefaultCommandExecutor } from '../../../utils/index.js'; +import { log } from '../../../utils/logging/index.js'; +import type { CommandExecutor } from '../../../utils/execution/index.js'; +import { getDefaultCommandExecutor } from '../../../utils/execution/index.js'; import { createTypedTool } from '../../../utils/typed-tool-factory.js'; import { nullifyEmptyStrings } from '../../../utils/schema-helpers.js'; diff --git a/src/mcp/tools/macos/launch_mac_app.ts b/src/mcp/tools/macos/launch_mac_app.ts index 35ceaa7f..c2ae435f 100644 --- a/src/mcp/tools/macos/launch_mac_app.ts +++ b/src/mcp/tools/macos/launch_mac_app.ts @@ -6,11 +6,11 @@ */ import { z } from 'zod'; -import { log } from '../../../utils/index.js'; -import { validateFileExists } from '../../../utils/index.js'; +import { log } from '../../../utils/logging/index.js'; +import { validateFileExists } from '../../../utils/validation/index.js'; import { ToolResponse } from '../../../types/common.js'; -import { CommandExecutor, getDefaultCommandExecutor } from '../../../utils/command.js'; -import { FileSystemExecutor } from '../../../utils/FileSystemExecutor.ts'; +import type { CommandExecutor, FileSystemExecutor } from '../../../utils/execution/index.js'; +import { getDefaultCommandExecutor } from '../../../utils/execution/index.js'; import { createTypedTool } from '../../../utils/typed-tool-factory.js'; // Define schema as ZodObject diff --git a/src/mcp/tools/macos/stop_mac_app.ts b/src/mcp/tools/macos/stop_mac_app.ts index 51454c1c..6b5e869b 100644 --- a/src/mcp/tools/macos/stop_mac_app.ts +++ b/src/mcp/tools/macos/stop_mac_app.ts @@ -1,7 +1,8 @@ import { z } from 'zod'; -import { log } from '../../../utils/index.js'; +import { log } from '../../../utils/logging/index.js'; import { ToolResponse } from '../../../types/common.js'; -import { CommandExecutor, getDefaultCommandExecutor } from '../../../utils/command.js'; +import type { CommandExecutor } from '../../../utils/execution/index.js'; +import { getDefaultCommandExecutor } from '../../../utils/execution/index.js'; import { createTypedTool } from '../../../utils/typed-tool-factory.js'; // Define schema as ZodObject diff --git a/src/mcp/tools/macos/test_macos.ts b/src/mcp/tools/macos/test_macos.ts index 671b9e46..f03afd48 100644 --- a/src/mcp/tools/macos/test_macos.ts +++ b/src/mcp/tools/macos/test_macos.ts @@ -8,15 +8,14 @@ import { z } from 'zod'; import { join } from 'path'; import { ToolResponse, XcodePlatform } from '../../../types/common.js'; -import { log } from '../../../utils/index.js'; -import { executeXcodeBuildCommand } from '../../../utils/index.js'; -import { createTextResponse } from '../../../utils/index.js'; +import { log } from '../../../utils/logging/index.js'; +import { executeXcodeBuildCommand } from '../../../utils/build/index.js'; +import { createTextResponse } from '../../../utils/responses/index.js'; +import type { CommandExecutor, FileSystemExecutor } from '../../../utils/execution/index.js'; import { - CommandExecutor, getDefaultCommandExecutor, getDefaultFileSystemExecutor, -} from '../../../utils/command.js'; -import { FileSystemExecutor } from '../../../utils/FileSystemExecutor.ts'; +} from '../../../utils/execution/index.js'; import { createTypedTool } from '../../../utils/typed-tool-factory.js'; import { nullifyEmptyStrings } from '../../../utils/schema-helpers.js'; diff --git a/src/mcp/tools/project-discovery/discover_projs.ts b/src/mcp/tools/project-discovery/discover_projs.ts index 1223a3ab..22efa02a 100644 --- a/src/mcp/tools/project-discovery/discover_projs.ts +++ b/src/mcp/tools/project-discovery/discover_projs.ts @@ -7,7 +7,7 @@ import { z } from 'zod'; import * as path from 'node:path'; -import { log } from '../../../utils/index.js'; +import { log } from '../../../utils/logging/index.js'; import { ToolResponse, createTextContent } from '../../../types/common.js'; import { getDefaultFileSystemExecutor, getDefaultCommandExecutor } from '../../../utils/command.js'; import { FileSystemExecutor } from '../../../utils/FileSystemExecutor.ts'; diff --git a/src/mcp/tools/project-discovery/get_app_bundle_id.ts b/src/mcp/tools/project-discovery/get_app_bundle_id.ts index 75c9e95b..2488ee19 100644 --- a/src/mcp/tools/project-discovery/get_app_bundle_id.ts +++ b/src/mcp/tools/project-discovery/get_app_bundle_id.ts @@ -6,7 +6,7 @@ */ import { z } from 'zod'; -import { log } from '../../../utils/index.js'; +import { log } from '../../../utils/logging/index.js'; import { ToolResponse } from '../../../types/common.js'; import { CommandExecutor, diff --git a/src/mcp/tools/project-discovery/get_mac_bundle_id.ts b/src/mcp/tools/project-discovery/get_mac_bundle_id.ts index ee0980be..cbc4eb7e 100644 --- a/src/mcp/tools/project-discovery/get_mac_bundle_id.ts +++ b/src/mcp/tools/project-discovery/get_mac_bundle_id.ts @@ -5,7 +5,7 @@ */ import { z } from 'zod'; -import { log } from '../../../utils/index.js'; +import { log } from '../../../utils/logging/index.js'; import { ToolResponse } from '../../../types/common.js'; import { CommandExecutor, diff --git a/src/mcp/tools/project-discovery/list_schemes.ts b/src/mcp/tools/project-discovery/list_schemes.ts index 8deda84c..e715ad11 100644 --- a/src/mcp/tools/project-discovery/list_schemes.ts +++ b/src/mcp/tools/project-discovery/list_schemes.ts @@ -6,9 +6,10 @@ */ import { z } from 'zod'; -import { log } from '../../../utils/index.js'; -import { CommandExecutor, getDefaultCommandExecutor } from '../../../utils/index.js'; -import { createTextResponse } from '../../../utils/index.js'; +import { log } from '../../../utils/logging/index.js'; +import type { CommandExecutor } from '../../../utils/execution/index.js'; +import { getDefaultCommandExecutor } from '../../../utils/execution/index.js'; +import { createTextResponse } from '../../../utils/responses/index.js'; import { ToolResponse } from '../../../types/common.js'; import { createTypedTool } from '../../../utils/typed-tool-factory.js'; import { nullifyEmptyStrings } from '../../../utils/schema-helpers.js'; diff --git a/src/mcp/tools/project-discovery/show_build_settings.ts b/src/mcp/tools/project-discovery/show_build_settings.ts index 312ef54c..1e6125bb 100644 --- a/src/mcp/tools/project-discovery/show_build_settings.ts +++ b/src/mcp/tools/project-discovery/show_build_settings.ts @@ -6,9 +6,10 @@ */ import { z } from 'zod'; -import { log } from '../../../utils/index.js'; -import { CommandExecutor, getDefaultCommandExecutor } from '../../../utils/index.js'; -import { createTextResponse } from '../../../utils/index.js'; +import { log } from '../../../utils/logging/index.js'; +import type { CommandExecutor } from '../../../utils/execution/index.js'; +import { getDefaultCommandExecutor } from '../../../utils/execution/index.js'; +import { createTextResponse } from '../../../utils/responses/index.js'; import { ToolResponse } from '../../../types/common.js'; import { createTypedTool } from '../../../utils/typed-tool-factory.js'; import { nullifyEmptyStrings } from '../../../utils/schema-helpers.js'; diff --git a/src/mcp/tools/project-scaffolding/__tests__/scaffold_macos_project.test.ts b/src/mcp/tools/project-scaffolding/__tests__/scaffold_macos_project.test.ts index 1675d091..4e710e8f 100644 --- a/src/mcp/tools/project-scaffolding/__tests__/scaffold_macos_project.test.ts +++ b/src/mcp/tools/project-scaffolding/__tests__/scaffold_macos_project.test.ts @@ -16,7 +16,7 @@ import { createMockExecutor, } from '../../../../test-utils/mock-executors.js'; import plugin, { scaffold_macos_projectLogic } from '../scaffold_macos_project.js'; -import { TemplateManager } from '../../../../utils/index.js'; +import { TemplateManager } from '../../../../utils/template/index.js'; // ONLY ALLOWED MOCKING: createMockFileSystemExecutor diff --git a/src/mcp/tools/project-scaffolding/scaffold_ios_project.ts b/src/mcp/tools/project-scaffolding/scaffold_ios_project.ts index c0c82801..c07ced42 100644 --- a/src/mcp/tools/project-scaffolding/scaffold_ios_project.ts +++ b/src/mcp/tools/project-scaffolding/scaffold_ios_project.ts @@ -6,15 +6,14 @@ import { z } from 'zod'; import { join, dirname, basename } from 'path'; -import { log } from '../../../utils/index.js'; -import { ValidationError } from '../../../utils/index.js'; -import { TemplateManager } from '../../../utils/index.js'; +import { log } from '../../../utils/logging/index.js'; +import { ValidationError } from '../../../utils/responses/index.js'; +import { TemplateManager } from '../../../utils/template/index.js'; +import type { CommandExecutor, FileSystemExecutor } from '../../../utils/execution/index.js'; import { - CommandExecutor, - FileSystemExecutor, getDefaultCommandExecutor, getDefaultFileSystemExecutor, -} from '../../../utils/index.js'; +} from '../../../utils/execution/index.js'; import { ToolResponse } from '../../../types/common.js'; // Common base schema for both iOS and macOS diff --git a/src/mcp/tools/project-scaffolding/scaffold_macos_project.ts b/src/mcp/tools/project-scaffolding/scaffold_macos_project.ts index 0558b244..b57da53e 100644 --- a/src/mcp/tools/project-scaffolding/scaffold_macos_project.ts +++ b/src/mcp/tools/project-scaffolding/scaffold_macos_project.ts @@ -6,9 +6,9 @@ import { z } from 'zod'; import { join, dirname, basename } from 'path'; -import { log } from '../../../utils/index.js'; -import { ValidationError } from '../../../utils/index.js'; -import { TemplateManager } from '../../../utils/index.js'; +import { log } from '../../../utils/logging/index.js'; +import { ValidationError } from '../../../utils/responses/index.js'; +import { TemplateManager } from '../../../utils/template/index.js'; import { ToolResponse } from '../../../types/common.js'; import { CommandExecutor, diff --git a/src/mcp/tools/simulator/boot_sim.ts b/src/mcp/tools/simulator/boot_sim.ts index 1b991455..3ef8b723 100644 --- a/src/mcp/tools/simulator/boot_sim.ts +++ b/src/mcp/tools/simulator/boot_sim.ts @@ -1,6 +1,8 @@ import { z } from 'zod'; import { ToolResponse } from '../../../types/common.js'; -import { log, CommandExecutor, getDefaultCommandExecutor } from '../../../utils/index.js'; +import { log } from '../../../utils/logging/index.js'; +import { getDefaultCommandExecutor } from '../../../utils/execution/index.js'; +import type { CommandExecutor } from '../../../utils/execution/index.js'; import { createTypedTool } from '../../../utils/typed-tool-factory.js'; // Define schema as ZodObject diff --git a/src/mcp/tools/simulator/build_run_sim.ts b/src/mcp/tools/simulator/build_run_sim.ts index 0d3f410a..bc5d9254 100644 --- a/src/mcp/tools/simulator/build_run_sim.ts +++ b/src/mcp/tools/simulator/build_run_sim.ts @@ -8,13 +8,11 @@ import { z } from 'zod'; import { ToolResponse, SharedBuildParams, XcodePlatform } from '../../../types/common.js'; -import { - log, - getDefaultCommandExecutor, - createTextResponse, - executeXcodeBuildCommand, - CommandExecutor, -} from '../../../utils/index.js'; +import { log } from '../../../utils/logging/index.js'; +import { getDefaultCommandExecutor } from '../../../utils/execution/index.js'; +import { createTextResponse } from '../../../utils/responses/index.js'; +import { executeXcodeBuildCommand } from '../../../utils/build/index.js'; +import type { CommandExecutor } from '../../../utils/execution/index.js'; import { determineSimulatorUuid } from '../../../utils/simulator-utils.js'; import { nullifyEmptyStrings } from '../../../utils/schema-helpers.js'; diff --git a/src/mcp/tools/simulator/build_sim.ts b/src/mcp/tools/simulator/build_sim.ts index 5ceb878a..48e15229 100644 --- a/src/mcp/tools/simulator/build_sim.ts +++ b/src/mcp/tools/simulator/build_sim.ts @@ -7,10 +7,11 @@ */ import { z } from 'zod'; -import { log } from '../../../utils/index.js'; -import { executeXcodeBuildCommand } from '../../../utils/index.js'; +import { log } from '../../../utils/logging/index.js'; +import { executeXcodeBuildCommand } from '../../../utils/build/index.js'; import { ToolResponse, XcodePlatform } from '../../../types/common.js'; -import { CommandExecutor, getDefaultCommandExecutor } from '../../../utils/command.js'; +import type { CommandExecutor } from '../../../utils/execution/index.js'; +import { getDefaultCommandExecutor } from '../../../utils/execution/index.js'; import { nullifyEmptyStrings } from '../../../utils/schema-helpers.js'; // Unified schema: XOR between projectPath and workspacePath, and XOR between simulatorId and simulatorName diff --git a/src/mcp/tools/simulator/get_sim_app_path.ts b/src/mcp/tools/simulator/get_sim_app_path.ts index eadbcf23..779d81dc 100644 --- a/src/mcp/tools/simulator/get_sim_app_path.ts +++ b/src/mcp/tools/simulator/get_sim_app_path.ts @@ -7,9 +7,10 @@ */ import { z } from 'zod'; -import { log, getDefaultCommandExecutor } from '../../../utils/index.js'; -import { createTextResponse } from '../../../utils/index.js'; -import { CommandExecutor } from '../../../utils/index.js'; +import { log } from '../../../utils/logging/index.js'; +import { createTextResponse } from '../../../utils/responses/index.js'; +import type { CommandExecutor } from '../../../utils/execution/index.js'; +import { getDefaultCommandExecutor } from '../../../utils/execution/index.js'; import { ToolResponse } from '../../../types/common.js'; import { createTypedTool } from '../../../utils/typed-tool-factory.js'; import { nullifyEmptyStrings } from '../../../utils/schema-helpers.js'; diff --git a/src/mcp/tools/simulator/install_app_sim.ts b/src/mcp/tools/simulator/install_app_sim.ts index e961a0ae..83a42bff 100644 --- a/src/mcp/tools/simulator/install_app_sim.ts +++ b/src/mcp/tools/simulator/install_app_sim.ts @@ -1,12 +1,9 @@ import { z } from 'zod'; import { ToolResponse } from '../../../types/common.js'; -import { - log, - validateFileExists, - CommandExecutor, - FileSystemExecutor, - getDefaultCommandExecutor, -} from '../../../utils/index.js'; +import { log } from '../../../utils/logging/index.js'; +import { validateFileExists } from '../../../utils/validation/index.js'; +import type { CommandExecutor, FileSystemExecutor } from '../../../utils/execution/index.js'; +import { getDefaultCommandExecutor } from '../../../utils/execution/index.js'; import { createTypedTool } from '../../../utils/typed-tool-factory.js'; // Define schema as ZodObject diff --git a/src/mcp/tools/simulator/launch_app_logs_sim.ts b/src/mcp/tools/simulator/launch_app_logs_sim.ts index 05b7adf7..ee0d8d5d 100644 --- a/src/mcp/tools/simulator/launch_app_logs_sim.ts +++ b/src/mcp/tools/simulator/launch_app_logs_sim.ts @@ -1,8 +1,9 @@ import { z } from 'zod'; import { ToolResponse, createTextContent } from '../../../types/common.js'; -import { log } from '../../../utils/index.js'; -import { startLogCapture } from '../../../utils/index.js'; -import { CommandExecutor, getDefaultCommandExecutor } from '../../../utils/command.js'; +import { log } from '../../../utils/logging/index.js'; +import { startLogCapture } from '../../../utils/log-capture/index.js'; +import type { CommandExecutor } from '../../../utils/execution/index.js'; +import { getDefaultCommandExecutor } from '../../../utils/execution/index.js'; import { createTypedTool } from '../../../utils/typed-tool-factory.js'; /** diff --git a/src/mcp/tools/simulator/launch_app_sim.ts b/src/mcp/tools/simulator/launch_app_sim.ts index 474babc0..55eab15a 100644 --- a/src/mcp/tools/simulator/launch_app_sim.ts +++ b/src/mcp/tools/simulator/launch_app_sim.ts @@ -1,7 +1,8 @@ import { z } from 'zod'; import { ToolResponse } from '../../../types/common.js'; -import { log } from '../../../utils/index.js'; -import { CommandExecutor, getDefaultCommandExecutor } from '../../../utils/command.js'; +import { log } from '../../../utils/logging/index.js'; +import type { CommandExecutor } from '../../../utils/execution/index.js'; +import { getDefaultCommandExecutor } from '../../../utils/execution/index.js'; import { nullifyEmptyStrings } from '../../../utils/schema-helpers.js'; // Unified schema: XOR between simulatorUuid and simulatorName diff --git a/src/mcp/tools/simulator/list_sims.ts b/src/mcp/tools/simulator/list_sims.ts index a5483bf9..c1a91183 100644 --- a/src/mcp/tools/simulator/list_sims.ts +++ b/src/mcp/tools/simulator/list_sims.ts @@ -1,6 +1,8 @@ import { z } from 'zod'; -import { ToolResponse } from '../../../types/common.js'; -import { log, CommandExecutor, getDefaultCommandExecutor } from '../../../utils/index.js'; +import type { ToolResponse } from '../../../types/common.js'; +import { log } from '../../../utils/logging/index.js'; +import type { CommandExecutor } from '../../../utils/execution/index.js'; +import { getDefaultCommandExecutor } from '../../../utils/execution/index.js'; import { createTypedTool } from '../../../utils/typed-tool-factory.js'; // Define schema as ZodObject diff --git a/src/mcp/tools/simulator/open_sim.ts b/src/mcp/tools/simulator/open_sim.ts index 9a6a867f..bac0e229 100644 --- a/src/mcp/tools/simulator/open_sim.ts +++ b/src/mcp/tools/simulator/open_sim.ts @@ -1,6 +1,8 @@ import { z } from 'zod'; import { ToolResponse } from '../../../types/common.js'; -import { log, CommandExecutor, getDefaultCommandExecutor } from '../../../utils/index.js'; +import { log } from '../../../utils/logging/index.js'; +import type { CommandExecutor } from '../../../utils/execution/index.js'; +import { getDefaultCommandExecutor } from '../../../utils/execution/index.js'; import { createTypedTool } from '../../../utils/typed-tool-factory.js'; // Define schema as ZodObject diff --git a/src/mcp/tools/simulator/stop_app_sim.ts b/src/mcp/tools/simulator/stop_app_sim.ts index 1800bdb7..2cc900e1 100644 --- a/src/mcp/tools/simulator/stop_app_sim.ts +++ b/src/mcp/tools/simulator/stop_app_sim.ts @@ -1,6 +1,8 @@ import { z } from 'zod'; import { ToolResponse } from '../../../types/common.js'; -import { log, CommandExecutor, getDefaultCommandExecutor } from '../../../utils/index.js'; +import { log } from '../../../utils/logging/index.js'; +import type { CommandExecutor } from '../../../utils/execution/index.js'; +import { getDefaultCommandExecutor } from '../../../utils/execution/index.js'; import { nullifyEmptyStrings } from '../../../utils/schema-helpers.js'; // Unified schema: XOR between simulatorUuid and simulatorName diff --git a/src/mcp/tools/simulator/test_sim.ts b/src/mcp/tools/simulator/test_sim.ts index 54701b06..a5a4daa1 100644 --- a/src/mcp/tools/simulator/test_sim.ts +++ b/src/mcp/tools/simulator/test_sim.ts @@ -7,10 +7,12 @@ */ import { z } from 'zod'; -import { handleTestLogic, log } from '../../../utils/index.js'; -import { XcodePlatform } from '../../../utils/index.js'; +import { handleTestLogic } from '../../../utils/test/index.js'; +import { log } from '../../../utils/logging/index.js'; +import { XcodePlatform } from '../../../types/common.js'; import { ToolResponse } from '../../../types/common.js'; -import { CommandExecutor, getDefaultCommandExecutor } from '../../../utils/command.js'; +import type { CommandExecutor } from '../../../utils/execution/index.js'; +import { getDefaultCommandExecutor } from '../../../utils/execution/index.js'; import { nullifyEmptyStrings } from '../../../utils/schema-helpers.js'; // Define base schema object with all fields diff --git a/src/mcp/tools/swift-package/swift_package_build.ts b/src/mcp/tools/swift-package/swift_package_build.ts index a0163703..0dd4f734 100644 --- a/src/mcp/tools/swift-package/swift_package_build.ts +++ b/src/mcp/tools/swift-package/swift_package_build.ts @@ -1,11 +1,9 @@ import { z } from 'zod'; import path from 'node:path'; -import { - createErrorResponse, - log, - CommandExecutor, - getDefaultCommandExecutor, -} from '../../../utils/index.js'; +import { createErrorResponse } from '../../../utils/responses/index.js'; +import { log } from '../../../utils/logging/index.js'; +import type { CommandExecutor } from '../../../utils/execution/index.js'; +import { getDefaultCommandExecutor } from '../../../utils/execution/index.js'; import { ToolResponse } from '../../../types/common.js'; import { createTypedTool } from '../../../utils/typed-tool-factory.js'; diff --git a/src/mcp/tools/swift-package/swift_package_clean.ts b/src/mcp/tools/swift-package/swift_package_clean.ts index 35236636..dfe380e1 100644 --- a/src/mcp/tools/swift-package/swift_package_clean.ts +++ b/src/mcp/tools/swift-package/swift_package_clean.ts @@ -1,8 +1,9 @@ import { z } from 'zod'; import path from 'node:path'; -import { CommandExecutor, getDefaultCommandExecutor } from '../../../utils/index.js'; -import { createErrorResponse } from '../../../utils/index.js'; -import { log } from '../../../utils/index.js'; +import type { CommandExecutor } from '../../../utils/execution/index.js'; +import { getDefaultCommandExecutor } from '../../../utils/execution/index.js'; +import { createErrorResponse } from '../../../utils/responses/index.js'; +import { log } from '../../../utils/logging/index.js'; import { ToolResponse } from '../../../types/common.js'; import { createTypedTool } from '../../../utils/typed-tool-factory.js'; diff --git a/src/mcp/tools/swift-package/swift_package_run.ts b/src/mcp/tools/swift-package/swift_package_run.ts index 8e6436ed..7720c10b 100644 --- a/src/mcp/tools/swift-package/swift_package_run.ts +++ b/src/mcp/tools/swift-package/swift_package_run.ts @@ -1,9 +1,9 @@ import { z } from 'zod'; import path from 'node:path'; -import { createTextResponse } from '../../../utils/index.js'; -import { createErrorResponse } from '../../../utils/index.js'; -import { log } from '../../../utils/index.js'; -import { CommandExecutor, getDefaultCommandExecutor } from '../../../utils/index.js'; +import { createTextResponse, createErrorResponse } from '../../../utils/responses/index.js'; +import { log } from '../../../utils/logging/index.js'; +import type { CommandExecutor } from '../../../utils/execution/index.js'; +import { getDefaultCommandExecutor } from '../../../utils/execution/index.js'; import { ToolResponse, createTextContent } from '../../../types/common.js'; import { addProcess } from './active-processes.js'; import { createTypedTool } from '../../../utils/typed-tool-factory.js'; diff --git a/src/mcp/tools/swift-package/swift_package_stop.ts b/src/mcp/tools/swift-package/swift_package_stop.ts index 2777f1d4..1197057a 100644 --- a/src/mcp/tools/swift-package/swift_package_stop.ts +++ b/src/mcp/tools/swift-package/swift_package_stop.ts @@ -1,6 +1,5 @@ import { z } from 'zod'; -import { createTextResponse } from '../../../utils/index.js'; -import { createErrorResponse } from '../../../utils/index.js'; +import { createTextResponse, createErrorResponse } from '../../../utils/responses/index.js'; import { getProcess, removeProcess, type ProcessInfo } from './active-processes.js'; import { ToolResponse } from '../../../types/common.js'; diff --git a/src/mcp/tools/swift-package/swift_package_test.ts b/src/mcp/tools/swift-package/swift_package_test.ts index 7f1a66cb..e36e6c98 100644 --- a/src/mcp/tools/swift-package/swift_package_test.ts +++ b/src/mcp/tools/swift-package/swift_package_test.ts @@ -1,9 +1,9 @@ import { z } from 'zod'; import path from 'node:path'; -import { CommandExecutor, getDefaultCommandExecutor } from '../../../utils/index.js'; -import { createTextResponse } from '../../../utils/index.js'; -import { createErrorResponse } from '../../../utils/index.js'; -import { log } from '../../../utils/index.js'; +import type { CommandExecutor } from '../../../utils/execution/index.js'; +import { getDefaultCommandExecutor } from '../../../utils/execution/index.js'; +import { createTextResponse, createErrorResponse } from '../../../utils/responses/index.js'; +import { log } from '../../../utils/logging/index.js'; import { ToolResponse } from '../../../types/common.js'; import { createTypedTool } from '../../../utils/typed-tool-factory.js'; diff --git a/src/mcp/tools/ui-testing/__tests__/swipe.test.ts b/src/mcp/tools/ui-testing/__tests__/swipe.test.ts index 9eca23e9..4e026455 100644 --- a/src/mcp/tools/ui-testing/__tests__/swipe.test.ts +++ b/src/mcp/tools/ui-testing/__tests__/swipe.test.ts @@ -5,7 +5,7 @@ import { describe, it, expect } from 'vitest'; import { z } from 'zod'; import { createMockExecutor, createNoopExecutor } from '../../../../test-utils/mock-executors.js'; -import { SystemError, DependencyError } from '../../../../utils/index.js'; +import { SystemError, DependencyError } from '../../../../utils/responses/index.js'; // Import the plugin module to test import swipePlugin, { AxeHelpers, swipeLogic, SwipeParams } from '../swipe.ts'; diff --git a/src/mcp/tools/ui-testing/button.ts b/src/mcp/tools/ui-testing/button.ts index c0c61947..5ca026ff 100644 --- a/src/mcp/tools/ui-testing/button.ts +++ b/src/mcp/tools/ui-testing/button.ts @@ -1,25 +1,15 @@ -/** - * Hardware Button Plugin - * - * Press hardware buttons on iOS simulator including apple-pay, home, lock, side-button, and siri. - * Supports optional duration parameter for extended button presses. - */ - import { z } from 'zod'; -import { ToolResponse } from '../../../types/common.js'; -import { log, createTextResponse } from '../../../utils/index.js'; -import { - DependencyError, - AxeError, - SystemError, - createErrorResponse, -} from '../../../utils/index.js'; -import { CommandExecutor, getDefaultCommandExecutor } from '../../../utils/index.js'; +import type { ToolResponse } from '../../../types/common.js'; +import { log } from '../../../utils/logging/index.js'; +import { createTextResponse, createErrorResponse } from '../../../utils/responses/index.js'; +import type { CommandExecutor } from '../../../utils/execution/index.js'; +import { getDefaultCommandExecutor } from '../../../utils/execution/index.js'; import { createAxeNotAvailableResponse, getAxePath, getBundledAxeEnvironment, -} from '../../../utils/index.js'; +} from '../../../utils/axe-helpers.js'; +import { DependencyError, AxeError, SystemError } from '../../../utils/errors.js'; import { createTypedTool } from '../../../utils/typed-tool-factory.js'; // Define schema as ZodObject diff --git a/src/mcp/tools/ui-testing/describe_ui.ts b/src/mcp/tools/ui-testing/describe_ui.ts index 1b7bac0d..2d32a229 100644 --- a/src/mcp/tools/ui-testing/describe_ui.ts +++ b/src/mcp/tools/ui-testing/describe_ui.ts @@ -1,18 +1,15 @@ import { z } from 'zod'; import { ToolResponse } from '../../../types/common.js'; -import { log } from '../../../utils/index.js'; -import { - DependencyError, - AxeError, - SystemError, - createErrorResponse, -} from '../../../utils/index.js'; -import { CommandExecutor, getDefaultCommandExecutor } from '../../../utils/index.js'; +import { log } from '../../../utils/logging/index.js'; +import { createErrorResponse } from '../../../utils/responses/index.js'; +import { DependencyError, AxeError, SystemError } from '../../../utils/errors.js'; +import type { CommandExecutor } from '../../../utils/execution/index.js'; +import { getDefaultCommandExecutor } from '../../../utils/execution/index.js'; import { createAxeNotAvailableResponse, getAxePath, getBundledAxeEnvironment, -} from '../../../utils/index.js'; +} from '../../../utils/axe-helpers.js'; import { createTypedTool } from '../../../utils/typed-tool-factory.js'; // Define schema as ZodObject diff --git a/src/mcp/tools/ui-testing/gesture.ts b/src/mcp/tools/ui-testing/gesture.ts index 9de593b2..8414e212 100644 --- a/src/mcp/tools/ui-testing/gesture.ts +++ b/src/mcp/tools/ui-testing/gesture.ts @@ -7,20 +7,21 @@ import { z } from 'zod'; import { ToolResponse } from '../../../types/common.js'; -import { log } from '../../../utils/index.js'; -import { createTextResponse } from '../../../utils/index.js'; +import { log } from '../../../utils/logging/index.js'; import { + createTextResponse, + createErrorResponse, DependencyError, AxeError, SystemError, - createErrorResponse, -} from '../../../utils/index.js'; -import { CommandExecutor, getDefaultCommandExecutor } from '../../../utils/index.js'; +} from '../../../utils/responses/index.js'; +import type { CommandExecutor } from '../../../utils/execution/index.js'; +import { getDefaultCommandExecutor } from '../../../utils/execution/index.js'; import { createAxeNotAvailableResponse, getAxePath, getBundledAxeEnvironment, -} from '../../../utils/index.js'; +} from '../../../utils/axe/index.js'; import { createTypedTool } from '../../../utils/typed-tool-factory.js'; // Define schema as ZodObject diff --git a/src/mcp/tools/ui-testing/key_press.ts b/src/mcp/tools/ui-testing/key_press.ts index bffabd98..2c6f06b5 100644 --- a/src/mcp/tools/ui-testing/key_press.ts +++ b/src/mcp/tools/ui-testing/key_press.ts @@ -1,19 +1,20 @@ import { z } from 'zod'; import { ToolResponse } from '../../../types/common.js'; -import { log } from '../../../utils/index.js'; -import { createTextResponse } from '../../../utils/index.js'; +import { log } from '../../../utils/logging/index.js'; import { + createTextResponse, + createErrorResponse, DependencyError, AxeError, SystemError, - createErrorResponse, -} from '../../../utils/index.js'; -import { CommandExecutor, getDefaultCommandExecutor } from '../../../utils/index.js'; +} from '../../../utils/responses/index.js'; +import type { CommandExecutor } from '../../../utils/execution/index.js'; +import { getDefaultCommandExecutor } from '../../../utils/execution/index.js'; import { createAxeNotAvailableResponse, getAxePath, getBundledAxeEnvironment, -} from '../../../utils/index.js'; +} from '../../../utils/axe/index.js'; import { createTypedTool } from '../../../utils/typed-tool-factory.js'; // Define schema as ZodObject diff --git a/src/mcp/tools/ui-testing/key_sequence.ts b/src/mcp/tools/ui-testing/key_sequence.ts index ed3503eb..856f4b9b 100644 --- a/src/mcp/tools/ui-testing/key_sequence.ts +++ b/src/mcp/tools/ui-testing/key_sequence.ts @@ -6,20 +6,21 @@ import { z } from 'zod'; import { ToolResponse } from '../../../types/common.js'; -import { log } from '../../../utils/index.js'; -import { createTextResponse } from '../../../utils/index.js'; +import { log } from '../../../utils/logging/index.js'; import { + createTextResponse, + createErrorResponse, DependencyError, AxeError, SystemError, - createErrorResponse, -} from '../../../utils/index.js'; -import { CommandExecutor, getDefaultCommandExecutor } from '../../../utils/index.js'; +} from '../../../utils/responses/index.js'; +import type { CommandExecutor } from '../../../utils/execution/index.js'; +import { getDefaultCommandExecutor } from '../../../utils/execution/index.js'; import { createAxeNotAvailableResponse, getAxePath, getBundledAxeEnvironment, -} from '../../../utils/index.js'; +} from '../../../utils/axe/index.js'; import { createTypedTool } from '../../../utils/typed-tool-factory.js'; // Define schema as ZodObject diff --git a/src/mcp/tools/ui-testing/long_press.ts b/src/mcp/tools/ui-testing/long_press.ts index 23e0b23c..f8b8187f 100644 --- a/src/mcp/tools/ui-testing/long_press.ts +++ b/src/mcp/tools/ui-testing/long_press.ts @@ -7,20 +7,21 @@ import { z } from 'zod'; import { ToolResponse } from '../../../types/common.js'; -import { log } from '../../../utils/index.js'; -import { createTextResponse } from '../../../utils/index.js'; +import { log } from '../../../utils/logging/index.js'; import { + createTextResponse, + createErrorResponse, DependencyError, AxeError, SystemError, - createErrorResponse, -} from '../../../utils/index.js'; -import { CommandExecutor, getDefaultCommandExecutor } from '../../../utils/index.js'; +} from '../../../utils/responses/index.js'; +import type { CommandExecutor } from '../../../utils/execution/index.js'; +import { getDefaultCommandExecutor } from '../../../utils/execution/index.js'; import { createAxeNotAvailableResponse, getAxePath, getBundledAxeEnvironment, -} from '../../../utils/index.js'; +} from '../../../utils/axe/index.js'; import { createTypedTool } from '../../../utils/typed-tool-factory.js'; // Define schema as ZodObject diff --git a/src/mcp/tools/ui-testing/screenshot.ts b/src/mcp/tools/ui-testing/screenshot.ts index 8e26800f..bc125a4b 100644 --- a/src/mcp/tools/ui-testing/screenshot.ts +++ b/src/mcp/tools/ui-testing/screenshot.ts @@ -6,15 +6,13 @@ import { tmpdir } from 'os'; import { z } from 'zod'; import { v4 as uuidv4 } from 'uuid'; import { ToolResponse, createImageContent } from '../../../types/common.js'; +import { log } from '../../../utils/logging/index.js'; +import { createErrorResponse, SystemError } from '../../../utils/responses/index.js'; +import type { CommandExecutor, FileSystemExecutor } from '../../../utils/execution/index.js'; import { - log, - SystemError, - createErrorResponse, - CommandExecutor, - FileSystemExecutor, getDefaultFileSystemExecutor, getDefaultCommandExecutor, -} from '../../../utils/index.js'; +} from '../../../utils/execution/index.js'; import { createTypedTool } from '../../../utils/typed-tool-factory.js'; const LOG_PREFIX = '[Screenshot]'; diff --git a/src/mcp/tools/ui-testing/swipe.ts b/src/mcp/tools/ui-testing/swipe.ts index dfb70e17..c16fb980 100644 --- a/src/mcp/tools/ui-testing/swipe.ts +++ b/src/mcp/tools/ui-testing/swipe.ts @@ -6,20 +6,16 @@ import { z } from 'zod'; import { ToolResponse } from '../../../types/common.js'; -import { log } from '../../../utils/index.js'; -import { createTextResponse } from '../../../utils/index.js'; -import { - DependencyError, - AxeError, - SystemError, - createErrorResponse, -} from '../../../utils/index.js'; -import { CommandExecutor, getDefaultCommandExecutor } from '../../../utils/index.js'; +import { log } from '../../../utils/logging/index.js'; +import { createTextResponse, createErrorResponse } from '../../../utils/responses/index.js'; +import { DependencyError, AxeError, SystemError } from '../../../utils/errors.js'; +import type { CommandExecutor } from '../../../utils/execution/index.js'; +import { getDefaultCommandExecutor } from '../../../utils/execution/index.js'; import { createAxeNotAvailableResponse, getAxePath, getBundledAxeEnvironment, -} from '../../../utils/index.js'; +} from '../../../utils/axe-helpers.js'; import { createTypedTool } from '../../../utils/typed-tool-factory.js'; // Define schema as ZodObject diff --git a/src/mcp/tools/ui-testing/tap.ts b/src/mcp/tools/ui-testing/tap.ts index e0ef9c49..9c47beaa 100644 --- a/src/mcp/tools/ui-testing/tap.ts +++ b/src/mcp/tools/ui-testing/tap.ts @@ -1,19 +1,15 @@ import { z } from 'zod'; -import { ToolResponse } from '../../../types/common.js'; -import { log } from '../../../utils/index.js'; -import { createTextResponse } from '../../../utils/index.js'; -import { - DependencyError, - AxeError, - SystemError, - createErrorResponse, -} from '../../../utils/index.js'; -import { CommandExecutor, getDefaultCommandExecutor } from '../../../utils/index.js'; +import type { ToolResponse } from '../../../types/common.js'; +import { log } from '../../../utils/logging/index.js'; +import { createTextResponse, createErrorResponse } from '../../../utils/responses/index.js'; +import type { CommandExecutor } from '../../../utils/execution/index.js'; +import { getDefaultCommandExecutor } from '../../../utils/execution/index.js'; import { createAxeNotAvailableResponse, getAxePath, getBundledAxeEnvironment, -} from '../../../utils/index.js'; +} from '../../../utils/axe-helpers.js'; +import { DependencyError, AxeError, SystemError } from '../../../utils/errors.js'; import { createTypedTool } from '../../../utils/typed-tool-factory.js'; export interface AxeHelpers { diff --git a/src/mcp/tools/ui-testing/touch.ts b/src/mcp/tools/ui-testing/touch.ts index 26c38fef..6eaa97ca 100644 --- a/src/mcp/tools/ui-testing/touch.ts +++ b/src/mcp/tools/ui-testing/touch.ts @@ -6,20 +6,16 @@ */ import { z } from 'zod'; -import { log } from '../../../utils/index.js'; -import { createTextResponse } from '../../../utils/index.js'; -import { - DependencyError, - AxeError, - SystemError, - createErrorResponse, -} from '../../../utils/index.js'; -import { CommandExecutor, getDefaultCommandExecutor } from '../../../utils/index.js'; +import { log } from '../../../utils/logging/index.js'; +import { createTextResponse, createErrorResponse } from '../../../utils/responses/index.js'; +import { DependencyError, AxeError, SystemError } from '../../../utils/errors.js'; +import type { CommandExecutor } from '../../../utils/execution/index.js'; +import { getDefaultCommandExecutor } from '../../../utils/execution/index.js'; import { createAxeNotAvailableResponse, getAxePath, getBundledAxeEnvironment, -} from '../../../utils/index.js'; +} from '../../../utils/axe-helpers.js'; import { ToolResponse } from '../../../types/common.js'; import { createTypedTool } from '../../../utils/typed-tool-factory.js'; diff --git a/src/mcp/tools/ui-testing/type_text.ts b/src/mcp/tools/ui-testing/type_text.ts index 8a10ca53..4f36ab6b 100644 --- a/src/mcp/tools/ui-testing/type_text.ts +++ b/src/mcp/tools/ui-testing/type_text.ts @@ -7,20 +7,16 @@ import { z } from 'zod'; import { ToolResponse } from '../../../types/common.js'; -import { log } from '../../../utils/index.js'; -import { createTextResponse } from '../../../utils/index.js'; -import { - DependencyError, - AxeError, - SystemError, - createErrorResponse, -} from '../../../utils/index.js'; -import { CommandExecutor, getDefaultCommandExecutor } from '../../../utils/index.js'; +import { log } from '../../../utils/logging/index.js'; +import { createTextResponse, createErrorResponse } from '../../../utils/responses/index.js'; +import { DependencyError, AxeError, SystemError } from '../../../utils/errors.js'; +import type { CommandExecutor } from '../../../utils/execution/index.js'; +import { getDefaultCommandExecutor } from '../../../utils/execution/index.js'; import { createAxeNotAvailableResponse, getAxePath, getBundledAxeEnvironment, -} from '../../../utils/index.js'; +} from '../../../utils/axe-helpers.js'; import { createTypedTool } from '../../../utils/typed-tool-factory.js'; const LOG_PREFIX = '[AXe]'; diff --git a/src/mcp/tools/utilities/clean.ts b/src/mcp/tools/utilities/clean.ts index a0e86fc0..cf9a070a 100644 --- a/src/mcp/tools/utilities/clean.ts +++ b/src/mcp/tools/utilities/clean.ts @@ -7,14 +7,11 @@ import { z } from 'zod'; import { createTypedTool } from '../../../utils/typed-tool-factory.js'; -import { - CommandExecutor, - getDefaultCommandExecutor, - executeXcodeBuildCommand, -} from '../../../utils/index.js'; -import { XcodePlatform } from '../../../utils/index.js'; -import { ToolResponse, SharedBuildParams } from '../../../types/common.js'; -import { createErrorResponse } from '../../../utils/index.js'; +import type { CommandExecutor } from '../../../utils/execution/index.js'; +import { getDefaultCommandExecutor } from '../../../utils/execution/index.js'; +import { executeXcodeBuildCommand } from '../../../utils/build/index.js'; +import { ToolResponse, SharedBuildParams, XcodePlatform } from '../../../types/common.js'; +import { createErrorResponse } from '../../../utils/responses/index.js'; import { nullifyEmptyStrings } from '../../../utils/schema-helpers.js'; // Unified schema: XOR between projectPath and workspacePath, sharing common options diff --git a/src/utils/axe/index.ts b/src/utils/axe/index.ts new file mode 100644 index 00000000..03446c8e --- /dev/null +++ b/src/utils/axe/index.ts @@ -0,0 +1,6 @@ +export { + createAxeNotAvailableResponse, + getAxePath, + getBundledAxeEnvironment, + areAxeToolsAvailable, +} from '../axe-helpers.js'; diff --git a/src/utils/execution/index.ts b/src/utils/execution/index.ts new file mode 100644 index 00000000..e44f1fdd --- /dev/null +++ b/src/utils/execution/index.ts @@ -0,0 +1,9 @@ +/** + * Focused execution facade. + * Prefer importing from 'utils/execution/index.js' instead of the legacy utils barrel. + */ +export { getDefaultCommandExecutor, getDefaultFileSystemExecutor } from '../command.js'; + +// Types +export type { CommandExecutor, CommandResponse } from '../CommandExecutor.js'; +export type { FileSystemExecutor } from '../FileSystemExecutor.js'; diff --git a/src/utils/index.ts b/src/utils/index.ts index 9354ca87..2e832340 100644 --- a/src/utils/index.ts +++ b/src/utils/index.ts @@ -1,4 +1,6 @@ -// Export all utilities for plugin consumption +/** + * This barrel will be removed in a future release after a deprecation period. + */ export * from './logger.js'; export * from './command.js'; export * from './CommandExecutor.js'; diff --git a/src/utils/log-capture/index.ts b/src/utils/log-capture/index.ts new file mode 100644 index 00000000..f6d19d43 --- /dev/null +++ b/src/utils/log-capture/index.ts @@ -0,0 +1 @@ +export { startLogCapture, stopLogCapture } from '../log_capture.js'; diff --git a/src/utils/logger.ts b/src/utils/logger.ts index aca0760a..94a72315 100644 --- a/src/utils/logger.ts +++ b/src/utils/logger.ts @@ -17,10 +17,46 @@ * It's used by virtually all other modules for status reporting and error logging. */ -import * as Sentry from '@sentry/node'; +import { createRequire } from 'node:module'; +// Note: Removed "import * as Sentry from '@sentry/node'" to prevent native module loading at import time const SENTRY_ENABLED = process.env.SENTRY_DISABLED !== 'true'; +function isTestEnv(): boolean { + return ( + process.env.VITEST === 'true' || + process.env.NODE_ENV === 'test' || + process.env.XCODEBUILDMCP_SILENCE_LOGS === 'true' + ); +} + +type SentryModule = typeof import('@sentry/node'); + +const require = createRequire(import.meta.url); +let cachedSentry: SentryModule | null = null; + +function loadSentrySync(): SentryModule | null { + if (!SENTRY_ENABLED || isTestEnv()) return null; + if (cachedSentry) return cachedSentry; + try { + cachedSentry = require('@sentry/node') as SentryModule; + return cachedSentry; + } catch { + // If @sentry/node is not installed in some environments, fail silently. + return null; + } +} + +function withSentry(cb: (s: SentryModule) => void): void { + const s = loadSentrySync(); + if (!s) return; + try { + cb(s); + } catch { + // no-op: avoid throwing inside logger + } +} + if (!SENTRY_ENABLED) { log('info', 'Sentry disabled due to SENTRY_DISABLED environment variable'); } @@ -44,7 +80,7 @@ export function log(level: string, message: string): void { const logMessage = `[${timestamp}] [${level.toUpperCase()}] ${message}`; if (level === 'error' && SENTRY_ENABLED) { - Sentry.captureMessage(logMessage); + withSentry((s) => s.captureMessage(logMessage)); } // It's important to use console.error here to ensure logs don't interfere with MCP protocol communication diff --git a/src/utils/logging/index.ts b/src/utils/logging/index.ts new file mode 100644 index 00000000..928b33b2 --- /dev/null +++ b/src/utils/logging/index.ts @@ -0,0 +1,5 @@ +/** + * Focused logging facade. + * Prefer importing from 'utils/logging/index.js' instead of the legacy utils barrel. + */ +export { log } from '../logger.js'; diff --git a/src/utils/plugin-registry/index.ts b/src/utils/plugin-registry/index.ts new file mode 100644 index 00000000..4706700b --- /dev/null +++ b/src/utils/plugin-registry/index.ts @@ -0,0 +1,2 @@ +export { loadWorkflowGroups, loadPlugins } from '../../core/plugin-registry.js'; +export { getEnabledWorkflows } from '../../core/dynamic-tools.js'; diff --git a/src/utils/responses/index.ts b/src/utils/responses/index.ts new file mode 100644 index 00000000..35b89543 --- /dev/null +++ b/src/utils/responses/index.ts @@ -0,0 +1,15 @@ +/** + * Focused responses facade. + * Prefer importing from 'utils/responses/index.js' instead of the legacy utils barrel. + */ +export { createTextResponse } from '../validation.js'; +export { + createErrorResponse, + DependencyError, + AxeError, + SystemError, + ValidationError, +} from '../errors.js'; + +// Types +export type { ToolResponse } from '../../types/common.js'; diff --git a/src/utils/simulator-utils.ts b/src/utils/simulator-utils.ts index c78c78d0..7bd3cb52 100644 --- a/src/utils/simulator-utils.ts +++ b/src/utils/simulator-utils.ts @@ -2,9 +2,10 @@ * Simulator utility functions for name to UUID resolution */ -import { CommandExecutor } from './command.js'; +import type { CommandExecutor } from './execution/index.js'; import { ToolResponse } from '../types/common.js'; -import { createErrorResponse, log } from './index.js'; +import { log } from './logging/index.js'; +import { createErrorResponse } from './responses/index.js'; /** * UUID regex pattern to check if a string looks like a UUID diff --git a/src/utils/template/index.ts b/src/utils/template/index.ts new file mode 100644 index 00000000..f2a04682 --- /dev/null +++ b/src/utils/template/index.ts @@ -0,0 +1 @@ +export { TemplateManager } from '../template-manager.js'; diff --git a/src/utils/test/index.ts b/src/utils/test/index.ts new file mode 100644 index 00000000..04548484 --- /dev/null +++ b/src/utils/test/index.ts @@ -0,0 +1 @@ +export { handleTestLogic } from '../test-common.js'; diff --git a/src/utils/typed-tool-factory.ts b/src/utils/typed-tool-factory.ts index 9c0fc443..b971336a 100644 --- a/src/utils/typed-tool-factory.ts +++ b/src/utils/typed-tool-factory.ts @@ -11,8 +11,8 @@ import { z } from 'zod'; import { ToolResponse } from '../types/common.js'; -import { CommandExecutor } from './command.js'; -import { createErrorResponse } from './index.js'; +import type { CommandExecutor } from './execution/index.js'; +import { createErrorResponse } from './responses/index.js'; /** * Creates a type-safe tool handler that validates parameters at runtime diff --git a/src/utils/validation/index.ts b/src/utils/validation/index.ts new file mode 100644 index 00000000..337b1304 --- /dev/null +++ b/src/utils/validation/index.ts @@ -0,0 +1,5 @@ +/** + * Focused validation facade. + * Prefer importing from 'utils/validation/index.js' instead of the legacy utils barrel. + */ +export * from '../validation.js'; diff --git a/src/utils/version/index.ts b/src/utils/version/index.ts new file mode 100644 index 00000000..282bf15c --- /dev/null +++ b/src/utils/version/index.ts @@ -0,0 +1 @@ +export { version } from '../../version.js'; diff --git a/src/utils/xcodemake/index.ts b/src/utils/xcodemake/index.ts new file mode 100644 index 00000000..a5d061a9 --- /dev/null +++ b/src/utils/xcodemake/index.ts @@ -0,0 +1 @@ +export { isXcodemakeEnabled, isXcodemakeAvailable, doesMakefileExist } from '../xcodemake.js'; From 646d323aad94a47f690fa96e9713c64ccb7f7503 Mon Sep 17 00:00:00 2001 From: Cameron Cooke Date: Sat, 16 Aug 2025 23:11:27 +0100 Subject: [PATCH 3/8] feat: standardize TypeScript imports to use .ts extensions ## Summary - Convert all relative imports from .js to .ts extensions (564 imports across 169 files) - Update ESLint rules to enforce .ts import pattern and prevent regression - Fix remaining barrel imports to use focused facade pattern - Add comprehensive documentation for TypeScript import standards ## Background/Details The project used mixed import extensions (.js and .ts) which created inconsistency and prevented compatibility with native TypeScript runtimes like Bun and Deno. The .js imports were a legacy pattern from older TypeScript compilation setups. ## Solution 1. **Automated Conversion**: Created script to convert all relative .js imports to .ts 2. **ESLint Enforcement**: Updated rules to catch both .js imports and barrel imports 3. **External Package Handling**: Preserved .js extensions for external packages (required) 4. **Focused Facades**: Completed migration from barrel imports to focused facade pattern ## Testing - All 1046 tests pass - Build compiles successfully - ESLint passes with no violations - Verified compatibility with current build system ## Benefits - Future-proof for native TypeScript runtimes (Bun, Deno, Node.js --loader) - Better IDE experience with direct source file navigation - Consistent import pattern matching actual source files - Automated enforcement prevents regression --- AGENTS.md | 28 +++++++++++++++ eslint.config.js | 14 +++++--- src/core/__tests__/resources.test.ts | 2 +- src/core/dynamic-tools.ts | 12 +++---- src/core/plugin-registry.ts | 4 +-- src/core/plugin-types.ts | 2 +- src/core/resources.ts | 6 ++-- src/doctor-cli.ts | 6 ++-- src/index.ts | 14 ++++---- src/mcp/resources/__tests__/devices.test.ts | 4 +-- src/mcp/resources/__tests__/doctor.test.ts | 4 +-- .../resources/__tests__/simulators.test.ts | 4 +-- src/mcp/resources/devices.ts | 8 ++--- src/mcp/resources/doctor.ts | 3 +- src/mcp/resources/simulators.ts | 8 ++--- .../device/__tests__/build_device.test.ts | 2 +- .../__tests__/get_device_app_path.test.ts | 2 +- .../__tests__/install_app_device.test.ts | 2 +- .../__tests__/launch_app_device.test.ts | 2 +- .../device/__tests__/list_devices.test.ts | 2 +- .../device/__tests__/stop_app_device.test.ts | 2 +- .../device/__tests__/test_device.test.ts | 4 +-- src/mcp/tools/device/build_device.ts | 12 +++---- src/mcp/tools/device/clean.ts | 2 +- src/mcp/tools/device/discover_projs.ts | 2 +- src/mcp/tools/device/get_app_bundle_id.ts | 2 +- src/mcp/tools/device/get_device_app_path.ts | 14 ++++---- src/mcp/tools/device/install_app_device.ts | 10 +++--- src/mcp/tools/device/launch_app_device.ts | 10 +++--- src/mcp/tools/device/list_devices.ts | 10 +++--- src/mcp/tools/device/list_schemes.ts | 2 +- src/mcp/tools/device/show_build_settings.ts | 2 +- src/mcp/tools/device/start_device_log_cap.ts | 2 +- src/mcp/tools/device/stop_app_device.ts | 10 +++--- src/mcp/tools/device/stop_device_log_cap.ts | 2 +- src/mcp/tools/device/test_device.ts | 16 ++++----- src/mcp/tools/discovery/discover_tools.ts | 12 +++---- src/mcp/tools/doctor/doctor.ts | 12 +++---- src/mcp/tools/doctor/lib/doctor.deps.ts | 10 +++--- .../__tests__/start_device_log_cap.test.ts | 2 +- .../__tests__/start_sim_log_cap.test.ts | 2 +- .../__tests__/stop_device_log_cap.test.ts | 6 ++-- .../__tests__/stop_sim_log_cap.test.ts | 4 +-- src/mcp/tools/logging/start_device_log_cap.ts | 10 +++--- src/mcp/tools/logging/start_sim_log_cap.ts | 8 ++--- src/mcp/tools/logging/stop_device_log_cap.ts | 10 +++--- src/mcp/tools/logging/stop_sim_log_cap.ts | 8 ++--- .../tools/macos/__tests__/build_macos.test.ts | 4 +-- .../macos/__tests__/build_run_macos.test.ts | 4 +-- .../macos/__tests__/get_mac_app_path.test.ts | 4 +-- .../macos/__tests__/launch_mac_app.test.ts | 2 +- .../tools/macos/__tests__/test_macos.test.ts | 2 +- src/mcp/tools/macos/build_macos.ts | 14 ++++---- src/mcp/tools/macos/build_run_macos.ts | 16 ++++----- src/mcp/tools/macos/clean.ts | 2 +- src/mcp/tools/macos/discover_projs.ts | 2 +- src/mcp/tools/macos/get_mac_app_path.ts | 12 +++---- src/mcp/tools/macos/get_mac_bundle_id.ts | 2 +- src/mcp/tools/macos/launch_mac_app.ts | 12 +++---- src/mcp/tools/macos/list_schemes.ts | 2 +- src/mcp/tools/macos/show_build_settings.ts | 2 +- src/mcp/tools/macos/stop_mac_app.ts | 10 +++--- src/mcp/tools/macos/test_macos.ts | 16 ++++----- .../__tests__/discover_projs.test.ts | 2 +- .../__tests__/get_app_bundle_id.test.ts | 2 +- .../__tests__/get_mac_bundle_id.test.ts | 2 +- .../__tests__/list_schemes.test.ts | 4 +-- .../__tests__/show_build_settings.test.ts | 2 +- .../tools/project-discovery/discover_projs.ts | 8 ++--- .../project-discovery/get_app_bundle_id.ts | 8 ++--- .../project-discovery/get_mac_bundle_id.ts | 8 ++--- .../tools/project-discovery/list_schemes.ts | 14 ++++---- .../project-discovery/show_build_settings.ts | 14 ++++---- .../__tests__/index.test.ts | 2 +- .../__tests__/scaffold_ios_project.test.ts | 2 +- .../__tests__/scaffold_macos_project.test.ts | 6 ++-- .../scaffold_ios_project.ts | 12 +++---- .../scaffold_macos_project.ts | 10 +++--- .../__tests__/index.test.ts | 2 +- .../__tests__/reset_sim_location.test.ts | 2 +- .../__tests__/set_sim_appearance.test.ts | 2 +- .../__tests__/set_sim_location.test.ts | 2 +- .../__tests__/sim_statusbar.test.ts | 2 +- .../tools/simulator-management/boot_sim.ts | 2 +- .../tools/simulator-management/list_sims.ts | 2 +- .../tools/simulator-management/open_sim.ts | 2 +- .../reset_sim_location.ts | 4 +-- .../set_sim_appearance.ts | 3 +- .../simulator-management/set_sim_location.ts | 3 +- .../simulator-management/sim_statusbar.ts | 3 +- .../simulator/__tests__/boot_sim.test.ts | 2 +- .../simulator/__tests__/build_run_sim.test.ts | 4 +-- .../simulator/__tests__/build_sim.test.ts | 4 +-- .../tools/simulator/__tests__/index.test.ts | 2 +- .../__tests__/install_app_sim.test.ts | 2 +- .../__tests__/launch_app_logs_sim.test.ts | 2 +- .../__tests__/launch_app_sim.test.ts | 4 +-- .../simulator/__tests__/list_sims.test.ts | 2 +- .../simulator/__tests__/open_sim.test.ts | 2 +- .../simulator/__tests__/screenshot.test.ts | 2 +- .../simulator/__tests__/stop_app_sim.test.ts | 4 +-- src/mcp/tools/simulator/boot_sim.ts | 10 +++--- src/mcp/tools/simulator/build_run_sim.ts | 16 ++++----- src/mcp/tools/simulator/build_sim.ts | 12 +++---- src/mcp/tools/simulator/clean.ts | 2 +- src/mcp/tools/simulator/describe_ui.ts | 2 +- src/mcp/tools/simulator/discover_projs.ts | 2 +- src/mcp/tools/simulator/get_app_bundle_id.ts | 2 +- src/mcp/tools/simulator/get_sim_app_path.ts | 14 ++++---- src/mcp/tools/simulator/install_app_sim.ts | 12 +++---- .../tools/simulator/launch_app_logs_sim.ts | 12 +++---- src/mcp/tools/simulator/launch_app_sim.ts | 10 +++--- src/mcp/tools/simulator/list_schemes.ts | 2 +- src/mcp/tools/simulator/list_sims.ts | 10 +++--- src/mcp/tools/simulator/open_sim.ts | 10 +++--- src/mcp/tools/simulator/screenshot.ts | 2 +- .../tools/simulator/show_build_settings.ts | 2 +- src/mcp/tools/simulator/stop_app_sim.ts | 10 +++--- src/mcp/tools/simulator/test_sim.ts | 14 ++++---- .../__tests__/active-processes.test.ts | 2 +- .../__tests__/swift_package_build.test.ts | 2 +- .../__tests__/swift_package_clean.test.ts | 2 +- .../__tests__/swift_package_list.test.ts | 2 +- .../__tests__/swift_package_run.test.ts | 2 +- .../__tests__/swift_package_stop.test.ts | 2 +- .../__tests__/swift_package_test.test.ts | 2 +- .../swift-package/swift_package_build.ts | 12 +++---- .../swift-package/swift_package_clean.ts | 12 +++---- .../tools/swift-package/swift_package_list.ts | 6 ++-- .../tools/swift-package/swift_package_run.ts | 14 ++++---- .../tools/swift-package/swift_package_stop.ts | 6 ++-- .../tools/swift-package/swift_package_test.ts | 12 +++---- .../tools/ui-testing/__tests__/button.test.ts | 2 +- .../ui-testing/__tests__/describe_ui.test.ts | 2 +- .../ui-testing/__tests__/gesture.test.ts | 2 +- .../ui-testing/__tests__/key_press.test.ts | 4 +-- .../ui-testing/__tests__/key_sequence.test.ts | 2 +- .../ui-testing/__tests__/long_press.test.ts | 2 +- .../ui-testing/__tests__/screenshot.test.ts | 2 +- .../tools/ui-testing/__tests__/swipe.test.ts | 4 +-- .../tools/ui-testing/__tests__/tap.test.ts | 2 +- .../tools/ui-testing/__tests__/touch.test.ts | 2 +- .../ui-testing/__tests__/type_text.test.ts | 2 +- src/mcp/tools/ui-testing/button.ts | 16 ++++----- src/mcp/tools/ui-testing/describe_ui.ts | 16 ++++----- src/mcp/tools/ui-testing/gesture.ts | 14 ++++---- src/mcp/tools/ui-testing/key_press.ts | 14 ++++---- src/mcp/tools/ui-testing/key_sequence.ts | 14 ++++---- src/mcp/tools/ui-testing/long_press.ts | 14 ++++---- src/mcp/tools/ui-testing/screenshot.ts | 12 +++---- src/mcp/tools/ui-testing/swipe.ts | 16 ++++----- src/mcp/tools/ui-testing/tap.ts | 16 ++++----- src/mcp/tools/ui-testing/touch.ts | 16 ++++----- src/mcp/tools/ui-testing/type_text.ts | 16 ++++----- .../tools/utilities/__tests__/clean.test.ts | 2 +- src/mcp/tools/utilities/clean.ts | 14 ++++---- src/server/server.ts | 4 +-- src/utils/__tests__/simulator-utils.test.ts | 4 +-- .../__tests__/typed-tool-factory.test.ts | 6 ++-- src/utils/axe-helpers.ts | 4 +-- src/utils/axe/index.ts | 2 +- src/utils/build-utils.ts | 12 +++---- src/utils/command.ts | 6 ++-- src/utils/environment.ts | 2 +- src/utils/errors.ts | 2 +- src/utils/execution/index.ts | 6 ++-- src/utils/index.ts | 36 +++++++++---------- src/utils/log-capture/index.ts | 2 +- src/utils/log_capture.ts | 4 +-- src/utils/logging/index.ts | 2 +- src/utils/plugin-registry/index.ts | 4 +-- src/utils/responses/index.ts | 6 ++-- src/utils/sentry.ts | 2 +- src/utils/simulator-utils.ts | 8 ++--- src/utils/template-manager.ts | 6 ++-- src/utils/template/index.ts | 2 +- src/utils/test-common.ts | 12 +++---- src/utils/test/index.ts | 2 +- src/utils/tool-registry.ts | 6 ++-- src/utils/typed-tool-factory.ts | 6 ++-- src/utils/validation.ts | 6 ++-- src/utils/validation/index.ts | 2 +- src/utils/version/index.ts | 2 +- src/utils/xcode.ts | 4 +-- src/utils/xcodemake.ts | 4 +-- src/utils/xcodemake/index.ts | 2 +- 186 files changed, 603 insertions(+), 565 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index db467ecc..c06f243b 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -165,6 +165,34 @@ This approach ensures that tests are robust, easy to maintain, and verify the ac For complete guidelines, refer to @docs/TESTING.md. +## TypeScript Import Standards + +This project uses **TypeScript file extensions** (`.ts`) for all relative imports to ensure compatibility with native TypeScript runtimes. + +### Import Rules + +- ✅ **Use `.ts` extensions**: `import { tool } from './tool.ts'` +- ✅ **Use `.ts` for re-exports**: `export { default } from '../shared/tool.ts'` +- ✅ **External packages use `.js`**: `import { McpServer } from '@camsoft/mcp-sdk/server/mcp.js'` +- ❌ **Never use `.js` for internal files**: `import { tool } from './tool.js'` ← ESLint error + +### Benefits + +1. **Future-proof**: Compatible with native TypeScript runtimes (Bun, Deno, Node.js --loader) +2. **IDE Experience**: Direct navigation to source TypeScript files +3. **Consistency**: Import path matches the actual file you're editing +4. **Modern Standard**: Aligns with TypeScript 4.7+ `allowImportingTsExtensions` + +### ESLint Enforcement + +The project automatically enforces this standard: + +```bash +npm run lint # Will catch .js imports for internal files +``` + +This ensures all new code follows the `.ts` import pattern and maintains compatibility with both current and future TypeScript execution environments. + ## Release Process Follow standardized development workflow with feature branches, structured pull requests, and linear commit history. **Never push to main directly or force push without permission.** diff --git a/eslint.config.js b/eslint.config.js index 34574d07..26677ec3 100644 --- a/eslint.config.js +++ b/eslint.config.js @@ -59,10 +59,16 @@ export default [ // Prevent barrel imports to maintain architectural improvements 'no-restricted-imports': ['error', { - patterns: [{ - group: ['**/utils/index.js', '../utils/index.js', '../../utils/index.js', '../../../utils/index.js'], - message: 'Barrel imports from utils/index.js are prohibited. Use focused facade imports instead (e.g., utils/logging/index.js, utils/execution/index.js).' - }] + patterns: [ + { + group: ['**/utils/index.js', '../utils/index.js', '../../utils/index.js', '../../../utils/index.js', '**/utils/index.ts', '../utils/index.ts', '../../utils/index.ts', '../../../utils/index.ts'], + message: 'Barrel imports from utils/index are prohibited. Use focused facade imports instead (e.g., utils/logging/index.ts, utils/execution/index.ts).' + }, + { + group: ['./**/*.js', '../**/*.js'], + message: 'Import TypeScript files with .ts extension, not .js. This ensures compatibility with native TypeScript runtimes like Bun and Deno. Change .js to .ts in your import path.' + } + ] }], }, }, diff --git a/src/core/__tests__/resources.test.ts b/src/core/__tests__/resources.test.ts index fa351c2c..b822cb5a 100644 --- a/src/core/__tests__/resources.test.ts +++ b/src/core/__tests__/resources.test.ts @@ -1,7 +1,7 @@ import { describe, it, expect, beforeEach } from 'vitest'; import { McpServer } from '@camsoft/mcp-sdk/server/mcp.js'; -import { registerResources, getAvailableResources, loadResources } from '../resources.js'; +import { registerResources, getAvailableResources, loadResources } from '../resources.ts'; describe('resources', () => { let mockServer: McpServer; diff --git a/src/core/dynamic-tools.ts b/src/core/dynamic-tools.ts index 99606212..2f0586ea 100644 --- a/src/core/dynamic-tools.ts +++ b/src/core/dynamic-tools.ts @@ -1,14 +1,14 @@ -import { log } from '../utils/logger.js'; -import { getDefaultCommandExecutor, CommandExecutor } from '../utils/command.js'; -import { WORKFLOW_LOADERS, WorkflowName, WORKFLOW_METADATA } from './generated-plugins.js'; -import { ToolResponse } from '../types/common.js'; -import { PluginMeta } from './plugin-types.js'; +import { log } from '../utils/logger.ts'; +import { getDefaultCommandExecutor, CommandExecutor } from '../utils/command.ts'; +import { WORKFLOW_LOADERS, WorkflowName, WORKFLOW_METADATA } from './generated-plugins.ts'; +import { ToolResponse } from '../types/common.ts'; +import { PluginMeta } from './plugin-types.ts'; import { McpServer } from '@camsoft/mcp-sdk/server/mcp.js'; import { registerAndTrackTools, removeTrackedTools, isToolRegistered, -} from '../utils/tool-registry.js'; +} from '../utils/tool-registry.ts'; import { ZodRawShape } from 'zod'; // Track enabled workflows and their tools for replacement functionality diff --git a/src/core/plugin-registry.ts b/src/core/plugin-registry.ts index 1e222d4a..cf4b2aaa 100644 --- a/src/core/plugin-registry.ts +++ b/src/core/plugin-registry.ts @@ -1,5 +1,5 @@ -import type { PluginMeta, WorkflowGroup, WorkflowMeta } from './plugin-types.js'; -import { WORKFLOW_LOADERS, WorkflowName, WORKFLOW_METADATA } from './generated-plugins.js'; +import type { PluginMeta, WorkflowGroup, WorkflowMeta } from './plugin-types.ts'; +import { WORKFLOW_LOADERS, WorkflowName, WORKFLOW_METADATA } from './generated-plugins.ts'; export async function loadPlugins(): Promise> { const plugins = new Map(); diff --git a/src/core/plugin-types.ts b/src/core/plugin-types.ts index 36f2360a..590691e2 100644 --- a/src/core/plugin-types.ts +++ b/src/core/plugin-types.ts @@ -1,5 +1,5 @@ import { z } from 'zod'; -import { ToolResponse } from '../types/common.js'; +import { ToolResponse } from '../types/common.ts'; export interface PluginMeta { readonly name: string; // Verb used by MCP diff --git a/src/core/resources.ts b/src/core/resources.ts index 9a709ded..1f136fea 100644 --- a/src/core/resources.ts +++ b/src/core/resources.ts @@ -13,9 +13,9 @@ import { McpServer } from '@camsoft/mcp-sdk/server/mcp.js'; import { ReadResourceResult } from '@camsoft/mcp-sdk/types.js'; -import { log } from '../utils/logging/index.js'; -import type { CommandExecutor } from '../utils/execution/index.js'; -import { RESOURCE_LOADERS } from './generated-resources.js'; +import { log } from '../utils/logging/index.ts'; +import type { CommandExecutor } from '../utils/execution/index.ts'; +import { RESOURCE_LOADERS } from './generated-resources.ts'; /** * Resource metadata interface diff --git a/src/doctor-cli.ts b/src/doctor-cli.ts index 88f1d746..e3adafc3 100644 --- a/src/doctor-cli.ts +++ b/src/doctor-cli.ts @@ -7,9 +7,9 @@ * to the console. It's designed to be run directly via npx or mise. */ -import { version } from './version.js'; -import { doctorLogic } from './mcp/tools/doctor/doctor.js'; -import { getDefaultCommandExecutor } from './utils/execution/index.js'; +import { version } from './version.ts'; +import { doctorLogic } from './mcp/tools/doctor/doctor.ts'; +import { getDefaultCommandExecutor } from './utils/execution/index.ts'; async function runDoctor(): Promise { try { diff --git a/src/index.ts b/src/index.ts index 264bfe0f..e5735227 100644 --- a/src/index.ts +++ b/src/index.ts @@ -14,31 +14,31 @@ */ // Import Sentry instrumentation -import './utils/sentry.js'; +import './utils/sentry.ts'; // Import server components -import { createServer, startServer } from './server/server.js'; +import { createServer, startServer } from './server/server.ts'; import { McpServer } from '@camsoft/mcp-sdk/server/mcp.js'; // Import utilities -import { log } from './utils/logger.js'; +import { log } from './utils/logger.ts'; // Import version -import { version } from './version.js'; +import { version } from './version.ts'; // Import xcodemake utilities -import { isXcodemakeEnabled, isXcodemakeAvailable } from './utils/xcodemake.js'; +import { isXcodemakeEnabled, isXcodemakeAvailable } from './utils/xcodemake.ts'; // Import process for stdout configuration import process from 'node:process'; // Import resource management -import { registerResources } from './core/resources.js'; +import { registerResources } from './core/resources.ts'; import { registerDiscoveryTools, registerAllToolsStatic, registerSelectedWorkflows, -} from './utils/tool-registry.js'; +} from './utils/tool-registry.ts'; /** * Main function to start the server diff --git a/src/mcp/resources/__tests__/devices.test.ts b/src/mcp/resources/__tests__/devices.test.ts index 2f64083d..aabed34f 100644 --- a/src/mcp/resources/__tests__/devices.test.ts +++ b/src/mcp/resources/__tests__/devices.test.ts @@ -1,7 +1,7 @@ import { describe, it, expect } from 'vitest'; -import devicesResource, { devicesResourceLogic } from '../devices.js'; -import { createMockExecutor } from '../../../test-utils/mock-executors.js'; +import devicesResource, { devicesResourceLogic } from '../devices.ts'; +import { createMockExecutor } from '../../../test-utils/mock-executors.ts'; describe('devices resource', () => { describe('Export Field Validation', () => { diff --git a/src/mcp/resources/__tests__/doctor.test.ts b/src/mcp/resources/__tests__/doctor.test.ts index 88cdcd77..9cf33b52 100644 --- a/src/mcp/resources/__tests__/doctor.test.ts +++ b/src/mcp/resources/__tests__/doctor.test.ts @@ -1,7 +1,7 @@ import { describe, it, expect } from 'vitest'; -import doctorResource, { doctorResourceLogic } from '../doctor.js'; -import { createMockExecutor } from '../../../test-utils/mock-executors.js'; +import doctorResource, { doctorResourceLogic } from '../doctor.ts'; +import { createMockExecutor } from '../../../test-utils/mock-executors.ts'; describe('doctor resource', () => { describe('Export Field Validation', () => { diff --git a/src/mcp/resources/__tests__/simulators.test.ts b/src/mcp/resources/__tests__/simulators.test.ts index 6f4219a5..22aaf34f 100644 --- a/src/mcp/resources/__tests__/simulators.test.ts +++ b/src/mcp/resources/__tests__/simulators.test.ts @@ -1,8 +1,8 @@ import { describe, it, expect, beforeEach } from 'vitest'; import { z } from 'zod'; -import simulatorsResource, { simulatorsResourceLogic } from '../simulators.js'; -import { createMockExecutor } from '../../../test-utils/mock-executors.js'; +import simulatorsResource, { simulatorsResourceLogic } from '../simulators.ts'; +import { createMockExecutor } from '../../../test-utils/mock-executors.ts'; describe('simulators resource', () => { describe('Export Field Validation', () => { diff --git a/src/mcp/resources/devices.ts b/src/mcp/resources/devices.ts index eeb8dc2f..cb8d5e39 100644 --- a/src/mcp/resources/devices.ts +++ b/src/mcp/resources/devices.ts @@ -5,10 +5,10 @@ * This resource reuses the existing list_devices tool logic to maintain consistency. */ -import { log } from '../../utils/logging/index.js'; -import type { CommandExecutor } from '../../utils/execution/index.js'; -import { getDefaultCommandExecutor } from '../../utils/execution/index.js'; -import { list_devicesLogic } from '../tools/device/list_devices.js'; +import { log } from '../../utils/logging/index.ts'; +import type { CommandExecutor } from '../../utils/execution/index.ts'; +import { getDefaultCommandExecutor } from '../../utils/execution/index.ts'; +import { list_devicesLogic } from '../tools/device/list_devices.ts'; // Testable resource logic separated from MCP handler export async function devicesResourceLogic( diff --git a/src/mcp/resources/doctor.ts b/src/mcp/resources/doctor.ts index 0fb18c14..851b9a1d 100644 --- a/src/mcp/resources/doctor.ts +++ b/src/mcp/resources/doctor.ts @@ -5,7 +5,8 @@ * This resource reuses the existing doctor tool logic to maintain consistency. */ -import { log, getDefaultCommandExecutor, CommandExecutor } from '../../utils/index.ts'; +import { log } from '../../utils/logging/index.ts'; +import { getDefaultCommandExecutor, CommandExecutor } from '../../utils/execution/index.ts'; import { doctorLogic } from '../tools/doctor/doctor.ts'; // Testable resource logic separated from MCP handler diff --git a/src/mcp/resources/simulators.ts b/src/mcp/resources/simulators.ts index b11774e9..2da3afeb 100644 --- a/src/mcp/resources/simulators.ts +++ b/src/mcp/resources/simulators.ts @@ -5,10 +5,10 @@ * This resource reuses the existing list_sims tool logic to maintain consistency. */ -import { log } from '../../utils/logging/index.js'; -import { getDefaultCommandExecutor } from '../../utils/execution/index.js'; -import type { CommandExecutor } from '../../utils/execution/index.js'; -import { list_simsLogic } from '../tools/simulator/list_sims.js'; +import { log } from '../../utils/logging/index.ts'; +import { getDefaultCommandExecutor } from '../../utils/execution/index.ts'; +import type { CommandExecutor } from '../../utils/execution/index.ts'; +import { list_simsLogic } from '../tools/simulator/list_sims.ts'; // Testable resource logic separated from MCP handler export async function simulatorsResourceLogic( diff --git a/src/mcp/tools/device/__tests__/build_device.test.ts b/src/mcp/tools/device/__tests__/build_device.test.ts index ae8d69e6..ad2d3512 100644 --- a/src/mcp/tools/device/__tests__/build_device.test.ts +++ b/src/mcp/tools/device/__tests__/build_device.test.ts @@ -5,7 +5,7 @@ */ import { describe, it, expect } from 'vitest'; -import { createMockExecutor, createNoopExecutor } from '../../../../test-utils/mock-executors.js'; +import { createMockExecutor, createNoopExecutor } from '../../../../test-utils/mock-executors.ts'; import buildDevice, { buildDeviceLogic } from '../build_device.ts'; describe('build_device plugin', () => { diff --git a/src/mcp/tools/device/__tests__/get_device_app_path.test.ts b/src/mcp/tools/device/__tests__/get_device_app_path.test.ts index d8085ebe..3ad9437f 100644 --- a/src/mcp/tools/device/__tests__/get_device_app_path.test.ts +++ b/src/mcp/tools/device/__tests__/get_device_app_path.test.ts @@ -5,7 +5,7 @@ */ import { describe, it, expect } from 'vitest'; -import { createMockExecutor } from '../../../../test-utils/mock-executors.js'; +import { createMockExecutor } from '../../../../test-utils/mock-executors.ts'; import getDeviceAppPath, { get_device_app_pathLogic } from '../get_device_app_path.ts'; describe('get_device_app_path plugin', () => { diff --git a/src/mcp/tools/device/__tests__/install_app_device.test.ts b/src/mcp/tools/device/__tests__/install_app_device.test.ts index 096e155f..59f8f204 100644 --- a/src/mcp/tools/device/__tests__/install_app_device.test.ts +++ b/src/mcp/tools/device/__tests__/install_app_device.test.ts @@ -5,7 +5,7 @@ */ import { describe, it, expect } from 'vitest'; -import { createMockExecutor } from '../../../../test-utils/mock-executors.js'; +import { createMockExecutor } from '../../../../test-utils/mock-executors.ts'; import installAppDevice, { install_app_deviceLogic } from '../install_app_device.ts'; describe('install_app_device plugin', () => { diff --git a/src/mcp/tools/device/__tests__/launch_app_device.test.ts b/src/mcp/tools/device/__tests__/launch_app_device.test.ts index bccd6b09..21e2e202 100644 --- a/src/mcp/tools/device/__tests__/launch_app_device.test.ts +++ b/src/mcp/tools/device/__tests__/launch_app_device.test.ts @@ -9,7 +9,7 @@ import { describe, it, expect } from 'vitest'; import { z } from 'zod'; -import { createMockExecutor } from '../../../../test-utils/mock-executors.js'; +import { createMockExecutor } from '../../../../test-utils/mock-executors.ts'; import launchAppDevice, { launch_app_deviceLogic } from '../launch_app_device.ts'; describe('launch_app_device plugin (device-shared)', () => { diff --git a/src/mcp/tools/device/__tests__/list_devices.test.ts b/src/mcp/tools/device/__tests__/list_devices.test.ts index b8cc7487..588cb4f7 100644 --- a/src/mcp/tools/device/__tests__/list_devices.test.ts +++ b/src/mcp/tools/device/__tests__/list_devices.test.ts @@ -10,7 +10,7 @@ import { describe, it, expect } from 'vitest'; import { createMockExecutor, createMockFileSystemExecutor, -} from '../../../../test-utils/mock-executors.js'; +} from '../../../../test-utils/mock-executors.ts'; // Import the logic function and re-export import listDevices, { list_devicesLogic } from '../list_devices.ts'; diff --git a/src/mcp/tools/device/__tests__/stop_app_device.test.ts b/src/mcp/tools/device/__tests__/stop_app_device.test.ts index ff651b52..b8a05974 100644 --- a/src/mcp/tools/device/__tests__/stop_app_device.test.ts +++ b/src/mcp/tools/device/__tests__/stop_app_device.test.ts @@ -5,7 +5,7 @@ */ import { describe, it, expect } from 'vitest'; -import { createMockExecutor } from '../../../../test-utils/mock-executors.js'; +import { createMockExecutor } from '../../../../test-utils/mock-executors.ts'; import stopAppDevice, { stop_app_deviceLogic } from '../stop_app_device.ts'; describe('stop_app_device plugin', () => { diff --git a/src/mcp/tools/device/__tests__/test_device.test.ts b/src/mcp/tools/device/__tests__/test_device.test.ts index f8ffa0e9..a5f86350 100644 --- a/src/mcp/tools/device/__tests__/test_device.test.ts +++ b/src/mcp/tools/device/__tests__/test_device.test.ts @@ -9,8 +9,8 @@ import { describe, it, expect, beforeEach } from 'vitest'; import { createMockExecutor, createMockFileSystemExecutor, -} from '../../../../test-utils/mock-executors.js'; -import testDevice, { testDeviceLogic } from '../test_device.js'; +} from '../../../../test-utils/mock-executors.ts'; +import testDevice, { testDeviceLogic } from '../test_device.ts'; describe('test_device plugin', () => { describe('Export Field Validation (Literal)', () => { diff --git a/src/mcp/tools/device/build_device.ts b/src/mcp/tools/device/build_device.ts index d641c522..11af16a5 100644 --- a/src/mcp/tools/device/build_device.ts +++ b/src/mcp/tools/device/build_device.ts @@ -6,12 +6,12 @@ */ import { z } from 'zod'; -import { ToolResponse, XcodePlatform } from '../../../types/common.js'; -import { executeXcodeBuildCommand } from '../../../utils/build-utils.js'; -import type { CommandExecutor } from '../../../utils/execution/index.js'; -import { getDefaultCommandExecutor } from '../../../utils/execution/index.js'; -import { createTypedTool } from '../../../utils/typed-tool-factory.js'; -import { nullifyEmptyStrings } from '../../../utils/schema-helpers.js'; +import { ToolResponse, XcodePlatform } from '../../../types/common.ts'; +import { executeXcodeBuildCommand } from '../../../utils/build-utils.ts'; +import type { CommandExecutor } from '../../../utils/execution/index.ts'; +import { getDefaultCommandExecutor } from '../../../utils/execution/index.ts'; +import { createTypedTool } from '../../../utils/typed-tool-factory.ts'; +import { nullifyEmptyStrings } from '../../../utils/schema-helpers.ts'; // Unified schema: XOR between projectPath and workspacePath const baseSchemaObject = z.object({ diff --git a/src/mcp/tools/device/clean.ts b/src/mcp/tools/device/clean.ts index 85727d4d..552c9c17 100644 --- a/src/mcp/tools/device/clean.ts +++ b/src/mcp/tools/device/clean.ts @@ -1,2 +1,2 @@ // Re-export unified clean tool for device-project workflow -export { default } from '../utilities/clean.js'; +export { default } from '../utilities/clean.ts'; diff --git a/src/mcp/tools/device/discover_projs.ts b/src/mcp/tools/device/discover_projs.ts index 44b43df5..58fbf05d 100644 --- a/src/mcp/tools/device/discover_projs.ts +++ b/src/mcp/tools/device/discover_projs.ts @@ -1,2 +1,2 @@ // Re-export from project-discovery to complete workflow -export { default } from '../project-discovery/discover_projs.js'; +export { default } from '../project-discovery/discover_projs.ts'; diff --git a/src/mcp/tools/device/get_app_bundle_id.ts b/src/mcp/tools/device/get_app_bundle_id.ts index 11b4c5f8..6c0bfc0d 100644 --- a/src/mcp/tools/device/get_app_bundle_id.ts +++ b/src/mcp/tools/device/get_app_bundle_id.ts @@ -1,2 +1,2 @@ // Re-export from project-discovery to complete workflow -export { default } from '../project-discovery/get_app_bundle_id.js'; +export { default } from '../project-discovery/get_app_bundle_id.ts'; diff --git a/src/mcp/tools/device/get_device_app_path.ts b/src/mcp/tools/device/get_device_app_path.ts index 7e640852..15455e27 100644 --- a/src/mcp/tools/device/get_device_app_path.ts +++ b/src/mcp/tools/device/get_device_app_path.ts @@ -6,13 +6,13 @@ */ import { z } from 'zod'; -import { ToolResponse, XcodePlatform } from '../../../types/common.js'; -import { log } from '../../../utils/logging/index.js'; -import { createTextResponse } from '../../../utils/responses/index.js'; -import type { CommandExecutor } from '../../../utils/execution/index.js'; -import { getDefaultCommandExecutor } from '../../../utils/execution/index.js'; -import { createTypedTool } from '../../../utils/typed-tool-factory.js'; -import { nullifyEmptyStrings } from '../../../utils/schema-helpers.js'; +import { ToolResponse, XcodePlatform } from '../../../types/common.ts'; +import { log } from '../../../utils/logging/index.ts'; +import { createTextResponse } from '../../../utils/responses/index.ts'; +import type { CommandExecutor } from '../../../utils/execution/index.ts'; +import { getDefaultCommandExecutor } from '../../../utils/execution/index.ts'; +import { createTypedTool } from '../../../utils/typed-tool-factory.ts'; +import { nullifyEmptyStrings } from '../../../utils/schema-helpers.ts'; // Unified schema: XOR between projectPath and workspacePath, sharing common options const baseOptions = { diff --git a/src/mcp/tools/device/install_app_device.ts b/src/mcp/tools/device/install_app_device.ts index abdf5fb3..c7e65b7a 100644 --- a/src/mcp/tools/device/install_app_device.ts +++ b/src/mcp/tools/device/install_app_device.ts @@ -6,11 +6,11 @@ */ import { z } from 'zod'; -import { ToolResponse } from '../../../types/common.js'; -import { log } from '../../../utils/logging/index.js'; -import type { CommandExecutor } from '../../../utils/execution/index.js'; -import { getDefaultCommandExecutor } from '../../../utils/execution/index.js'; -import { createTypedTool } from '../../../utils/typed-tool-factory.js'; +import { ToolResponse } from '../../../types/common.ts'; +import { log } from '../../../utils/logging/index.ts'; +import type { CommandExecutor } from '../../../utils/execution/index.ts'; +import { getDefaultCommandExecutor } from '../../../utils/execution/index.ts'; +import { createTypedTool } from '../../../utils/typed-tool-factory.ts'; // Define schema as ZodObject const installAppDeviceSchema = z.object({ diff --git a/src/mcp/tools/device/launch_app_device.ts b/src/mcp/tools/device/launch_app_device.ts index c2c05dcc..e0a0843b 100644 --- a/src/mcp/tools/device/launch_app_device.ts +++ b/src/mcp/tools/device/launch_app_device.ts @@ -6,11 +6,11 @@ */ import { z } from 'zod'; -import { ToolResponse } from '../../../types/common.js'; -import { log } from '../../../utils/logging/index.js'; -import type { CommandExecutor } from '../../../utils/execution/index.js'; -import { getDefaultCommandExecutor } from '../../../utils/execution/index.js'; -import { createTypedTool } from '../../../utils/typed-tool-factory.js'; +import { ToolResponse } from '../../../types/common.ts'; +import { log } from '../../../utils/logging/index.ts'; +import type { CommandExecutor } from '../../../utils/execution/index.ts'; +import { getDefaultCommandExecutor } from '../../../utils/execution/index.ts'; +import { createTypedTool } from '../../../utils/typed-tool-factory.ts'; import { promises as fs } from 'fs'; import { tmpdir } from 'os'; import { join } from 'path'; diff --git a/src/mcp/tools/device/list_devices.ts b/src/mcp/tools/device/list_devices.ts index 2e31abbc..47227266 100644 --- a/src/mcp/tools/device/list_devices.ts +++ b/src/mcp/tools/device/list_devices.ts @@ -6,11 +6,11 @@ */ import { z } from 'zod'; -import type { ToolResponse } from '../../../types/common.js'; -import { log } from '../../../utils/logging/index.js'; -import type { CommandExecutor } from '../../../utils/execution/index.js'; -import { getDefaultCommandExecutor } from '../../../utils/execution/index.js'; -import { createTypedTool } from '../../../utils/typed-tool-factory.js'; +import type { ToolResponse } from '../../../types/common.ts'; +import { log } from '../../../utils/logging/index.ts'; +import type { CommandExecutor } from '../../../utils/execution/index.ts'; +import { getDefaultCommandExecutor } from '../../../utils/execution/index.ts'; +import { createTypedTool } from '../../../utils/typed-tool-factory.ts'; import { promises as fs } from 'fs'; import { tmpdir } from 'os'; import { join } from 'path'; diff --git a/src/mcp/tools/device/list_schemes.ts b/src/mcp/tools/device/list_schemes.ts index f2869155..b046dde4 100644 --- a/src/mcp/tools/device/list_schemes.ts +++ b/src/mcp/tools/device/list_schemes.ts @@ -1,2 +1,2 @@ // Re-export unified list_schemes tool for device-project workflow -export { default } from '../project-discovery/list_schemes.js'; +export { default } from '../project-discovery/list_schemes.ts'; diff --git a/src/mcp/tools/device/show_build_settings.ts b/src/mcp/tools/device/show_build_settings.ts index e6345523..0e15b943 100644 --- a/src/mcp/tools/device/show_build_settings.ts +++ b/src/mcp/tools/device/show_build_settings.ts @@ -1,2 +1,2 @@ // Re-export unified tool for device-project workflow -export { default } from '../project-discovery/show_build_settings.js'; +export { default } from '../project-discovery/show_build_settings.ts'; diff --git a/src/mcp/tools/device/start_device_log_cap.ts b/src/mcp/tools/device/start_device_log_cap.ts index 9b790b4b..19dd6c04 100644 --- a/src/mcp/tools/device/start_device_log_cap.ts +++ b/src/mcp/tools/device/start_device_log_cap.ts @@ -1,2 +1,2 @@ // Re-export from logging to complete workflow -export { default } from '../logging/start_device_log_cap.js'; +export { default } from '../logging/start_device_log_cap.ts'; diff --git a/src/mcp/tools/device/stop_app_device.ts b/src/mcp/tools/device/stop_app_device.ts index ec112c33..9785db55 100644 --- a/src/mcp/tools/device/stop_app_device.ts +++ b/src/mcp/tools/device/stop_app_device.ts @@ -6,11 +6,11 @@ */ import { z } from 'zod'; -import { ToolResponse } from '../../../types/common.js'; -import { log } from '../../../utils/logging/index.js'; -import type { CommandExecutor } from '../../../utils/execution/index.js'; -import { getDefaultCommandExecutor } from '../../../utils/execution/index.js'; -import { createTypedTool } from '../../../utils/typed-tool-factory.js'; +import { ToolResponse } from '../../../types/common.ts'; +import { log } from '../../../utils/logging/index.ts'; +import type { CommandExecutor } from '../../../utils/execution/index.ts'; +import { getDefaultCommandExecutor } from '../../../utils/execution/index.ts'; +import { createTypedTool } from '../../../utils/typed-tool-factory.ts'; // Define schema as ZodObject const stopAppDeviceSchema = z.object({ diff --git a/src/mcp/tools/device/stop_device_log_cap.ts b/src/mcp/tools/device/stop_device_log_cap.ts index f94d7f99..48a20e09 100644 --- a/src/mcp/tools/device/stop_device_log_cap.ts +++ b/src/mcp/tools/device/stop_device_log_cap.ts @@ -1,2 +1,2 @@ // Re-export from logging to complete workflow -export { default } from '../logging/stop_device_log_cap.js'; +export { default } from '../logging/stop_device_log_cap.ts'; diff --git a/src/mcp/tools/device/test_device.ts b/src/mcp/tools/device/test_device.ts index b402a5f7..2fee4e6a 100644 --- a/src/mcp/tools/device/test_device.ts +++ b/src/mcp/tools/device/test_device.ts @@ -7,17 +7,17 @@ import { z } from 'zod'; import { join } from 'path'; -import { ToolResponse, XcodePlatform } from '../../../types/common.js'; -import { log } from '../../../utils/logging/index.js'; -import { executeXcodeBuildCommand } from '../../../utils/build/index.js'; -import { createTextResponse } from '../../../utils/responses/index.js'; -import type { CommandExecutor, FileSystemExecutor } from '../../../utils/execution/index.js'; +import { ToolResponse, XcodePlatform } from '../../../types/common.ts'; +import { log } from '../../../utils/logging/index.ts'; +import { executeXcodeBuildCommand } from '../../../utils/build/index.ts'; +import { createTextResponse } from '../../../utils/responses/index.ts'; +import type { CommandExecutor, FileSystemExecutor } from '../../../utils/execution/index.ts'; import { getDefaultCommandExecutor, getDefaultFileSystemExecutor, -} from '../../../utils/execution/index.js'; -import { createTypedTool } from '../../../utils/typed-tool-factory.js'; -import { nullifyEmptyStrings } from '../../../utils/schema-helpers.js'; +} from '../../../utils/execution/index.ts'; +import { createTypedTool } from '../../../utils/typed-tool-factory.ts'; +import { nullifyEmptyStrings } from '../../../utils/schema-helpers.ts'; // Unified schema: XOR between projectPath and workspacePath const baseSchemaObject = z.object({ diff --git a/src/mcp/tools/discovery/discover_tools.ts b/src/mcp/tools/discovery/discover_tools.ts index 08f3e9cd..aac02774 100644 --- a/src/mcp/tools/discovery/discover_tools.ts +++ b/src/mcp/tools/discovery/discover_tools.ts @@ -1,15 +1,15 @@ import { z } from 'zod'; -import { createTextResponse } from '../../../utils/responses/index.js'; -import { log } from '../../../utils/logging/index.js'; +import { createTextResponse } from '../../../utils/responses/index.ts'; +import { log } from '../../../utils/logging/index.ts'; // Removed CreateMessageResultSchema import as it's no longer used -import { ToolResponse } from '../../../types/common.js'; +import { ToolResponse } from '../../../types/common.ts'; import { enableWorkflows, getAvailableWorkflows, generateWorkflowDescriptions, -} from '../../../core/dynamic-tools.js'; -import { createTypedTool } from '../../../utils/typed-tool-factory.js'; -import { getDefaultCommandExecutor } from '../../../utils/execution/index.js'; +} from '../../../core/dynamic-tools.ts'; +import { createTypedTool } from '../../../utils/typed-tool-factory.ts'; +import { getDefaultCommandExecutor } from '../../../utils/execution/index.ts'; import { McpServer } from '@camsoft/mcp-sdk/server/mcp.js'; // Using McpServer type from SDK instead of custom interface diff --git a/src/mcp/tools/doctor/doctor.ts b/src/mcp/tools/doctor/doctor.ts index 146f8749..c0e7799a 100644 --- a/src/mcp/tools/doctor/doctor.ts +++ b/src/mcp/tools/doctor/doctor.ts @@ -5,12 +5,12 @@ */ import { z } from 'zod'; -import { log } from '../../../utils/logging/index.js'; -import type { CommandExecutor } from '../../../utils/execution/index.js'; -import { getDefaultCommandExecutor } from '../../../utils/execution/index.js'; -import { version } from '../../../utils/version/index.js'; -import { ToolResponse } from '../../../types/common.js'; -import { createTypedTool } from '../../../utils/typed-tool-factory.js'; +import { log } from '../../../utils/logging/index.ts'; +import type { CommandExecutor } from '../../../utils/execution/index.ts'; +import { getDefaultCommandExecutor } from '../../../utils/execution/index.ts'; +import { version } from '../../../utils/version/index.ts'; +import { ToolResponse } from '../../../types/common.ts'; +import { createTypedTool } from '../../../utils/typed-tool-factory.ts'; import { type DoctorDependencies, createDoctorDependencies } from './lib/doctor.deps.ts'; // Constants diff --git a/src/mcp/tools/doctor/lib/doctor.deps.ts b/src/mcp/tools/doctor/lib/doctor.deps.ts index d0ce8480..7e967517 100644 --- a/src/mcp/tools/doctor/lib/doctor.deps.ts +++ b/src/mcp/tools/doctor/lib/doctor.deps.ts @@ -1,17 +1,17 @@ import * as os from 'os'; -import type { CommandExecutor } from '../../../../utils/execution/index.js'; +import type { CommandExecutor } from '../../../../utils/execution/index.ts'; import { loadWorkflowGroups, loadPlugins, getEnabledWorkflows, -} from '../../../../utils/plugin-registry/index.js'; -import { areAxeToolsAvailable } from '../../../../utils/axe/index.js'; +} from '../../../../utils/plugin-registry/index.ts'; +import { areAxeToolsAvailable } from '../../../../utils/axe/index.ts'; import { isXcodemakeEnabled, isXcodemakeAvailable, doesMakefileExist, -} from '../../../../utils/xcodemake/index.js'; -import { getTrackedToolNames } from '../../../../utils/tool-registry.js'; +} from '../../../../utils/xcodemake/index.ts'; +import { getTrackedToolNames } from '../../../../utils/tool-registry.ts'; export interface BinaryChecker { checkBinaryAvailability(binary: string): Promise<{ available: boolean; version?: string }>; diff --git a/src/mcp/tools/logging/__tests__/start_device_log_cap.test.ts b/src/mcp/tools/logging/__tests__/start_device_log_cap.test.ts index 9dde59e3..ce7b2c4f 100644 --- a/src/mcp/tools/logging/__tests__/start_device_log_cap.test.ts +++ b/src/mcp/tools/logging/__tests__/start_device_log_cap.test.ts @@ -7,7 +7,7 @@ import { z } from 'zod'; import { createMockExecutor, createMockFileSystemExecutor, -} from '../../../../test-utils/mock-executors.js'; +} from '../../../../test-utils/mock-executors.ts'; import plugin, { start_device_log_capLogic } from '../start_device_log_cap.ts'; describe('start_device_log_cap plugin', () => { diff --git a/src/mcp/tools/logging/__tests__/start_sim_log_cap.test.ts b/src/mcp/tools/logging/__tests__/start_sim_log_cap.test.ts index 4ec75cf9..8880c7db 100644 --- a/src/mcp/tools/logging/__tests__/start_sim_log_cap.test.ts +++ b/src/mcp/tools/logging/__tests__/start_sim_log_cap.test.ts @@ -4,7 +4,7 @@ import { describe, it, expect, beforeEach } from 'vitest'; import { z } from 'zod'; import plugin, { start_sim_log_capLogic } from '../start_sim_log_cap.ts'; -import { createMockExecutor } from '../../../../test-utils/mock-executors.js'; +import { createMockExecutor } from '../../../../test-utils/mock-executors.ts'; describe('start_sim_log_cap plugin', () => { // Reset any test state if needed diff --git a/src/mcp/tools/logging/__tests__/stop_device_log_cap.test.ts b/src/mcp/tools/logging/__tests__/stop_device_log_cap.test.ts index f3fe63bd..a7bb3423 100644 --- a/src/mcp/tools/logging/__tests__/stop_device_log_cap.test.ts +++ b/src/mcp/tools/logging/__tests__/stop_device_log_cap.test.ts @@ -3,9 +3,9 @@ */ import { describe, it, expect, beforeEach } from 'vitest'; import { z } from 'zod'; -import plugin, { stop_device_log_capLogic } from '../stop_device_log_cap.js'; -import { activeDeviceLogSessions } from '../start_device_log_cap.js'; -import { createMockFileSystemExecutor } from '../../../../test-utils/mock-executors.js'; +import plugin, { stop_device_log_capLogic } from '../stop_device_log_cap.ts'; +import { activeDeviceLogSessions } from '../start_device_log_cap.ts'; +import { createMockFileSystemExecutor } from '../../../../test-utils/mock-executors.ts'; // Note: Logger is allowed to execute normally (integration testing pattern) diff --git a/src/mcp/tools/logging/__tests__/stop_sim_log_cap.test.ts b/src/mcp/tools/logging/__tests__/stop_sim_log_cap.test.ts index 8619a1f5..0b9bf78e 100644 --- a/src/mcp/tools/logging/__tests__/stop_sim_log_cap.test.ts +++ b/src/mcp/tools/logging/__tests__/stop_sim_log_cap.test.ts @@ -14,8 +14,8 @@ import { describe, it, expect, beforeEach } from 'vitest'; import { z } from 'zod'; import stopSimLogCap, { stop_sim_log_capLogic } from '../stop_sim_log_cap.ts'; -import { createMockFileSystemExecutor } from '../../../../test-utils/mock-executors.js'; -import { activeLogSessions } from '../../../../utils/log_capture.js'; +import { createMockFileSystemExecutor } from '../../../../test-utils/mock-executors.ts'; +import { activeLogSessions } from '../../../../utils/log_capture.ts'; describe('stop_sim_log_cap plugin', () => { let mockFileSystem: any; diff --git a/src/mcp/tools/logging/start_device_log_cap.ts b/src/mcp/tools/logging/start_device_log_cap.ts index b10bde4b..af55133e 100644 --- a/src/mcp/tools/logging/start_device_log_cap.ts +++ b/src/mcp/tools/logging/start_device_log_cap.ts @@ -9,11 +9,11 @@ import * as path from 'path'; import * as os from 'os'; import { v4 as uuidv4 } from 'uuid'; import { z } from 'zod'; -import { log } from '../../../utils/logging/index.js'; -import type { CommandExecutor, FileSystemExecutor } from '../../../utils/execution/index.js'; -import { getDefaultCommandExecutor } from '../../../utils/execution/index.js'; -import { ToolResponse } from '../../../types/common.js'; -import { createTypedTool } from '../../../utils/typed-tool-factory.js'; +import { log } from '../../../utils/logging/index.ts'; +import type { CommandExecutor, FileSystemExecutor } from '../../../utils/execution/index.ts'; +import { getDefaultCommandExecutor } from '../../../utils/execution/index.ts'; +import { ToolResponse } from '../../../types/common.ts'; +import { createTypedTool } from '../../../utils/typed-tool-factory.ts'; /** * Log file retention policy for device logs: diff --git a/src/mcp/tools/logging/start_sim_log_cap.ts b/src/mcp/tools/logging/start_sim_log_cap.ts index 139ffe44..2a0ea651 100644 --- a/src/mcp/tools/logging/start_sim_log_cap.ts +++ b/src/mcp/tools/logging/start_sim_log_cap.ts @@ -5,10 +5,10 @@ */ import { z } from 'zod'; -import { startLogCapture } from '../../../utils/log-capture/index.js'; -import { CommandExecutor, getDefaultCommandExecutor } from '../../../utils/command.js'; -import { ToolResponse, createTextContent } from '../../../types/common.js'; -import { createTypedTool } from '../../../utils/typed-tool-factory.js'; +import { startLogCapture } from '../../../utils/log-capture/index.ts'; +import { CommandExecutor, getDefaultCommandExecutor } from '../../../utils/command.ts'; +import { ToolResponse, createTextContent } from '../../../types/common.ts'; +import { createTypedTool } from '../../../utils/typed-tool-factory.ts'; // Define schema as ZodObject const startSimLogCapSchema = z.object({ diff --git a/src/mcp/tools/logging/stop_device_log_cap.ts b/src/mcp/tools/logging/stop_device_log_cap.ts index b3a68773..9c6f13e0 100644 --- a/src/mcp/tools/logging/stop_device_log_cap.ts +++ b/src/mcp/tools/logging/stop_device_log_cap.ts @@ -7,12 +7,12 @@ import * as fs from 'fs'; import type { ChildProcess } from 'child_process'; import { z } from 'zod'; -import { log } from '../../../utils/logging/index.js'; -import { activeDeviceLogSessions } from './start_device_log_cap.js'; -import { ToolResponse } from '../../../types/common.js'; -import { getDefaultFileSystemExecutor, getDefaultCommandExecutor } from '../../../utils/command.js'; +import { log } from '../../../utils/logging/index.ts'; +import { activeDeviceLogSessions } from './start_device_log_cap.ts'; +import { ToolResponse } from '../../../types/common.ts'; +import { getDefaultFileSystemExecutor, getDefaultCommandExecutor } from '../../../utils/command.ts'; import { FileSystemExecutor } from '../../../utils/FileSystemExecutor.ts'; -import { createTypedTool } from '../../../utils/typed-tool-factory.js'; +import { createTypedTool } from '../../../utils/typed-tool-factory.ts'; interface DeviceLogSession { process: diff --git a/src/mcp/tools/logging/stop_sim_log_cap.ts b/src/mcp/tools/logging/stop_sim_log_cap.ts index 90a42789..b90e3e63 100644 --- a/src/mcp/tools/logging/stop_sim_log_cap.ts +++ b/src/mcp/tools/logging/stop_sim_log_cap.ts @@ -5,10 +5,10 @@ */ import { z } from 'zod'; -import { stopLogCapture as _stopLogCapture } from '../../../utils/log-capture/index.js'; -import { ToolResponse, createTextContent } from '../../../types/common.js'; -import { createTypedTool } from '../../../utils/typed-tool-factory.js'; -import { getDefaultCommandExecutor } from '../../../utils/command.js'; +import { stopLogCapture as _stopLogCapture } from '../../../utils/log-capture/index.ts'; +import { ToolResponse, createTextContent } from '../../../types/common.ts'; +import { createTypedTool } from '../../../utils/typed-tool-factory.ts'; +import { getDefaultCommandExecutor } from '../../../utils/command.ts'; // Define schema as ZodObject const stopSimLogCapSchema = z.object({ diff --git a/src/mcp/tools/macos/__tests__/build_macos.test.ts b/src/mcp/tools/macos/__tests__/build_macos.test.ts index 0a4272b5..55a89810 100644 --- a/src/mcp/tools/macos/__tests__/build_macos.test.ts +++ b/src/mcp/tools/macos/__tests__/build_macos.test.ts @@ -7,8 +7,8 @@ import { describe, it, expect } from 'vitest'; import { z } from 'zod'; -import { createMockExecutor } from '../../../../test-utils/mock-executors.js'; -import buildMacOS, { buildMacOSLogic } from '../build_macos.js'; +import { createMockExecutor } from '../../../../test-utils/mock-executors.ts'; +import buildMacOS, { buildMacOSLogic } from '../build_macos.ts'; describe('build_macos plugin', () => { describe('Export Field Validation (Literal)', () => { diff --git a/src/mcp/tools/macos/__tests__/build_run_macos.test.ts b/src/mcp/tools/macos/__tests__/build_run_macos.test.ts index ae0552a8..c250ec58 100644 --- a/src/mcp/tools/macos/__tests__/build_run_macos.test.ts +++ b/src/mcp/tools/macos/__tests__/build_run_macos.test.ts @@ -1,7 +1,7 @@ import { describe, it, expect } from 'vitest'; import { z } from 'zod'; -import { createMockExecutor } from '../../../../test-utils/mock-executors.js'; -import tool, { buildRunMacOSLogic } from '../build_run_macos.js'; +import { createMockExecutor } from '../../../../test-utils/mock-executors.ts'; +import tool, { buildRunMacOSLogic } from '../build_run_macos.ts'; describe('build_run_macos', () => { describe('Export Field Validation (Literal)', () => { diff --git a/src/mcp/tools/macos/__tests__/get_mac_app_path.test.ts b/src/mcp/tools/macos/__tests__/get_mac_app_path.test.ts index c5139f06..42cb8bc6 100644 --- a/src/mcp/tools/macos/__tests__/get_mac_app_path.test.ts +++ b/src/mcp/tools/macos/__tests__/get_mac_app_path.test.ts @@ -5,8 +5,8 @@ */ import { describe, it, expect } from 'vitest'; -import { createMockExecutor, type CommandExecutor } from '../../../../test-utils/mock-executors.js'; -import getMacAppPath, { get_mac_app_pathLogic } from '../get_mac_app_path.js'; +import { createMockExecutor, type CommandExecutor } from '../../../../test-utils/mock-executors.ts'; +import getMacAppPath, { get_mac_app_pathLogic } from '../get_mac_app_path.ts'; describe('get_mac_app_path plugin', () => { describe('Export Field Validation (Literal)', () => { diff --git a/src/mcp/tools/macos/__tests__/launch_mac_app.test.ts b/src/mcp/tools/macos/__tests__/launch_mac_app.test.ts index 97db2550..23fb6889 100644 --- a/src/mcp/tools/macos/__tests__/launch_mac_app.test.ts +++ b/src/mcp/tools/macos/__tests__/launch_mac_app.test.ts @@ -9,7 +9,7 @@ import { describe, it, expect } from 'vitest'; import { z } from 'zod'; -import { createMockFileSystemExecutor } from '../../../../test-utils/mock-executors.js'; +import { createMockFileSystemExecutor } from '../../../../test-utils/mock-executors.ts'; import launchMacApp, { launch_mac_appLogic } from '../launch_mac_app.ts'; describe('launch_mac_app plugin', () => { diff --git a/src/mcp/tools/macos/__tests__/test_macos.test.ts b/src/mcp/tools/macos/__tests__/test_macos.test.ts index 269e5cef..8bfa3965 100644 --- a/src/mcp/tools/macos/__tests__/test_macos.test.ts +++ b/src/mcp/tools/macos/__tests__/test_macos.test.ts @@ -5,7 +5,7 @@ */ import { describe, it, expect } from 'vitest'; -import { createMockExecutor } from '../../../../test-utils/mock-executors.js'; +import { createMockExecutor } from '../../../../test-utils/mock-executors.ts'; import testMacos, { testMacosLogic } from '../test_macos.ts'; describe('test_macos plugin (unified)', () => { diff --git a/src/mcp/tools/macos/build_macos.ts b/src/mcp/tools/macos/build_macos.ts index 8a2aec6a..9cbc081e 100644 --- a/src/mcp/tools/macos/build_macos.ts +++ b/src/mcp/tools/macos/build_macos.ts @@ -6,13 +6,13 @@ */ import { z } from 'zod'; -import { log } from '../../../utils/logging/index.js'; -import { executeXcodeBuildCommand } from '../../../utils/build/index.js'; -import { ToolResponse, XcodePlatform } from '../../../types/common.js'; -import type { CommandExecutor } from '../../../utils/execution/index.js'; -import { getDefaultCommandExecutor } from '../../../utils/execution/index.js'; -import { createTypedTool } from '../../../utils/typed-tool-factory.js'; -import { nullifyEmptyStrings } from '../../../utils/schema-helpers.js'; +import { log } from '../../../utils/logging/index.ts'; +import { executeXcodeBuildCommand } from '../../../utils/build/index.ts'; +import { ToolResponse, XcodePlatform } from '../../../types/common.ts'; +import type { CommandExecutor } from '../../../utils/execution/index.ts'; +import { getDefaultCommandExecutor } from '../../../utils/execution/index.ts'; +import { createTypedTool } from '../../../utils/typed-tool-factory.ts'; +import { nullifyEmptyStrings } from '../../../utils/schema-helpers.ts'; // Types for dependency injection export interface BuildUtilsDependencies { diff --git a/src/mcp/tools/macos/build_run_macos.ts b/src/mcp/tools/macos/build_run_macos.ts index febddba9..19d5f2f0 100644 --- a/src/mcp/tools/macos/build_run_macos.ts +++ b/src/mcp/tools/macos/build_run_macos.ts @@ -6,14 +6,14 @@ */ import { z } from 'zod'; -import { log } from '../../../utils/logging/index.js'; -import { createTextResponse } from '../../../utils/responses/index.js'; -import { executeXcodeBuildCommand } from '../../../utils/build/index.js'; -import { ToolResponse, XcodePlatform } from '../../../types/common.js'; -import type { CommandExecutor } from '../../../utils/execution/index.js'; -import { getDefaultCommandExecutor } from '../../../utils/execution/index.js'; -import { createTypedTool } from '../../../utils/typed-tool-factory.js'; -import { nullifyEmptyStrings } from '../../../utils/schema-helpers.js'; +import { log } from '../../../utils/logging/index.ts'; +import { createTextResponse } from '../../../utils/responses/index.ts'; +import { executeXcodeBuildCommand } from '../../../utils/build/index.ts'; +import { ToolResponse, XcodePlatform } from '../../../types/common.ts'; +import type { CommandExecutor } from '../../../utils/execution/index.ts'; +import { getDefaultCommandExecutor } from '../../../utils/execution/index.ts'; +import { createTypedTool } from '../../../utils/typed-tool-factory.ts'; +import { nullifyEmptyStrings } from '../../../utils/schema-helpers.ts'; // Unified schema: XOR between projectPath and workspacePath const baseSchemaObject = z.object({ diff --git a/src/mcp/tools/macos/clean.ts b/src/mcp/tools/macos/clean.ts index 59dc6f0c..5af33211 100644 --- a/src/mcp/tools/macos/clean.ts +++ b/src/mcp/tools/macos/clean.ts @@ -1,2 +1,2 @@ // Re-export unified clean tool for macos-project workflow -export { default } from '../utilities/clean.js'; +export { default } from '../utilities/clean.ts'; diff --git a/src/mcp/tools/macos/discover_projs.ts b/src/mcp/tools/macos/discover_projs.ts index 44b43df5..58fbf05d 100644 --- a/src/mcp/tools/macos/discover_projs.ts +++ b/src/mcp/tools/macos/discover_projs.ts @@ -1,2 +1,2 @@ // Re-export from project-discovery to complete workflow -export { default } from '../project-discovery/discover_projs.js'; +export { default } from '../project-discovery/discover_projs.ts'; diff --git a/src/mcp/tools/macos/get_mac_app_path.ts b/src/mcp/tools/macos/get_mac_app_path.ts index c10a02cf..9e32d3ea 100644 --- a/src/mcp/tools/macos/get_mac_app_path.ts +++ b/src/mcp/tools/macos/get_mac_app_path.ts @@ -6,12 +6,12 @@ */ import { z } from 'zod'; -import { ToolResponse } from '../../../types/common.js'; -import { log } from '../../../utils/logging/index.js'; -import type { CommandExecutor } from '../../../utils/execution/index.js'; -import { getDefaultCommandExecutor } from '../../../utils/execution/index.js'; -import { createTypedTool } from '../../../utils/typed-tool-factory.js'; -import { nullifyEmptyStrings } from '../../../utils/schema-helpers.js'; +import { ToolResponse } from '../../../types/common.ts'; +import { log } from '../../../utils/logging/index.ts'; +import type { CommandExecutor } from '../../../utils/execution/index.ts'; +import { getDefaultCommandExecutor } from '../../../utils/execution/index.ts'; +import { createTypedTool } from '../../../utils/typed-tool-factory.ts'; +import { nullifyEmptyStrings } from '../../../utils/schema-helpers.ts'; // Unified schema: XOR between projectPath and workspacePath, sharing common options const baseOptions = { diff --git a/src/mcp/tools/macos/get_mac_bundle_id.ts b/src/mcp/tools/macos/get_mac_bundle_id.ts index 68f3c6aa..9935d53e 100644 --- a/src/mcp/tools/macos/get_mac_bundle_id.ts +++ b/src/mcp/tools/macos/get_mac_bundle_id.ts @@ -1,2 +1,2 @@ // Re-export from project-discovery to complete workflow -export { default } from '../project-discovery/get_mac_bundle_id.js'; +export { default } from '../project-discovery/get_mac_bundle_id.ts'; diff --git a/src/mcp/tools/macos/launch_mac_app.ts b/src/mcp/tools/macos/launch_mac_app.ts index c2ae435f..f3174943 100644 --- a/src/mcp/tools/macos/launch_mac_app.ts +++ b/src/mcp/tools/macos/launch_mac_app.ts @@ -6,12 +6,12 @@ */ import { z } from 'zod'; -import { log } from '../../../utils/logging/index.js'; -import { validateFileExists } from '../../../utils/validation/index.js'; -import { ToolResponse } from '../../../types/common.js'; -import type { CommandExecutor, FileSystemExecutor } from '../../../utils/execution/index.js'; -import { getDefaultCommandExecutor } from '../../../utils/execution/index.js'; -import { createTypedTool } from '../../../utils/typed-tool-factory.js'; +import { log } from '../../../utils/logging/index.ts'; +import { validateFileExists } from '../../../utils/validation/index.ts'; +import { ToolResponse } from '../../../types/common.ts'; +import type { CommandExecutor, FileSystemExecutor } from '../../../utils/execution/index.ts'; +import { getDefaultCommandExecutor } from '../../../utils/execution/index.ts'; +import { createTypedTool } from '../../../utils/typed-tool-factory.ts'; // Define schema as ZodObject const launchMacAppSchema = z.object({ diff --git a/src/mcp/tools/macos/list_schemes.ts b/src/mcp/tools/macos/list_schemes.ts index c5f6f78b..67519898 100644 --- a/src/mcp/tools/macos/list_schemes.ts +++ b/src/mcp/tools/macos/list_schemes.ts @@ -1,2 +1,2 @@ // Re-export unified list_schemes tool for macos-project workflow -export { default } from '../project-discovery/list_schemes.js'; +export { default } from '../project-discovery/list_schemes.ts'; diff --git a/src/mcp/tools/macos/show_build_settings.ts b/src/mcp/tools/macos/show_build_settings.ts index c8b76aa5..77db451b 100644 --- a/src/mcp/tools/macos/show_build_settings.ts +++ b/src/mcp/tools/macos/show_build_settings.ts @@ -1,2 +1,2 @@ // Re-export unified tool for macos-project workflow -export { default } from '../project-discovery/show_build_settings.js'; +export { default } from '../project-discovery/show_build_settings.ts'; diff --git a/src/mcp/tools/macos/stop_mac_app.ts b/src/mcp/tools/macos/stop_mac_app.ts index 6b5e869b..2fdfc75f 100644 --- a/src/mcp/tools/macos/stop_mac_app.ts +++ b/src/mcp/tools/macos/stop_mac_app.ts @@ -1,9 +1,9 @@ import { z } from 'zod'; -import { log } from '../../../utils/logging/index.js'; -import { ToolResponse } from '../../../types/common.js'; -import type { CommandExecutor } from '../../../utils/execution/index.js'; -import { getDefaultCommandExecutor } from '../../../utils/execution/index.js'; -import { createTypedTool } from '../../../utils/typed-tool-factory.js'; +import { log } from '../../../utils/logging/index.ts'; +import { ToolResponse } from '../../../types/common.ts'; +import type { CommandExecutor } from '../../../utils/execution/index.ts'; +import { getDefaultCommandExecutor } from '../../../utils/execution/index.ts'; +import { createTypedTool } from '../../../utils/typed-tool-factory.ts'; // Define schema as ZodObject const stopMacAppSchema = z.object({ diff --git a/src/mcp/tools/macos/test_macos.ts b/src/mcp/tools/macos/test_macos.ts index f03afd48..40728853 100644 --- a/src/mcp/tools/macos/test_macos.ts +++ b/src/mcp/tools/macos/test_macos.ts @@ -7,17 +7,17 @@ import { z } from 'zod'; import { join } from 'path'; -import { ToolResponse, XcodePlatform } from '../../../types/common.js'; -import { log } from '../../../utils/logging/index.js'; -import { executeXcodeBuildCommand } from '../../../utils/build/index.js'; -import { createTextResponse } from '../../../utils/responses/index.js'; -import type { CommandExecutor, FileSystemExecutor } from '../../../utils/execution/index.js'; +import { ToolResponse, XcodePlatform } from '../../../types/common.ts'; +import { log } from '../../../utils/logging/index.ts'; +import { executeXcodeBuildCommand } from '../../../utils/build/index.ts'; +import { createTextResponse } from '../../../utils/responses/index.ts'; +import type { CommandExecutor, FileSystemExecutor } from '../../../utils/execution/index.ts'; import { getDefaultCommandExecutor, getDefaultFileSystemExecutor, -} from '../../../utils/execution/index.js'; -import { createTypedTool } from '../../../utils/typed-tool-factory.js'; -import { nullifyEmptyStrings } from '../../../utils/schema-helpers.js'; +} from '../../../utils/execution/index.ts'; +import { createTypedTool } from '../../../utils/typed-tool-factory.ts'; +import { nullifyEmptyStrings } from '../../../utils/schema-helpers.ts'; // Unified schema: XOR between projectPath and workspacePath const baseSchemaObject = z.object({ diff --git a/src/mcp/tools/project-discovery/__tests__/discover_projs.test.ts b/src/mcp/tools/project-discovery/__tests__/discover_projs.test.ts index 0fccfab8..07dcfef6 100644 --- a/src/mcp/tools/project-discovery/__tests__/discover_projs.test.ts +++ b/src/mcp/tools/project-discovery/__tests__/discover_projs.test.ts @@ -10,7 +10,7 @@ import { describe, it, expect, beforeEach } from 'vitest'; import { z } from 'zod'; import plugin, { discover_projsLogic } from '../discover_projs.ts'; -import { createMockFileSystemExecutor } from '../../../../test-utils/mock-executors.js'; +import { createMockFileSystemExecutor } from '../../../../test-utils/mock-executors.ts'; describe('discover_projs plugin', () => { let mockFileSystemExecutor: any; diff --git a/src/mcp/tools/project-discovery/__tests__/get_app_bundle_id.test.ts b/src/mcp/tools/project-discovery/__tests__/get_app_bundle_id.test.ts index 5e696113..43d81ae3 100644 --- a/src/mcp/tools/project-discovery/__tests__/get_app_bundle_id.test.ts +++ b/src/mcp/tools/project-discovery/__tests__/get_app_bundle_id.test.ts @@ -14,7 +14,7 @@ import plugin, { get_app_bundle_idLogic } from '../get_app_bundle_id.ts'; import { createMockFileSystemExecutor, createCommandMatchingMockExecutor, -} from '../../../../test-utils/mock-executors.js'; +} from '../../../../test-utils/mock-executors.ts'; describe('get_app_bundle_id plugin', () => { // Helper function to create mock executor for command matching diff --git a/src/mcp/tools/project-discovery/__tests__/get_mac_bundle_id.test.ts b/src/mcp/tools/project-discovery/__tests__/get_mac_bundle_id.test.ts index 6e919600..4d7a747b 100644 --- a/src/mcp/tools/project-discovery/__tests__/get_mac_bundle_id.test.ts +++ b/src/mcp/tools/project-discovery/__tests__/get_mac_bundle_id.test.ts @@ -4,7 +4,7 @@ import plugin, { get_mac_bundle_idLogic } from '../get_mac_bundle_id.ts'; import { createMockFileSystemExecutor, createCommandMatchingMockExecutor, -} from '../../../../test-utils/mock-executors.js'; +} from '../../../../test-utils/mock-executors.ts'; describe('get_mac_bundle_id plugin', () => { // Helper function to create mock executor for command matching diff --git a/src/mcp/tools/project-discovery/__tests__/list_schemes.test.ts b/src/mcp/tools/project-discovery/__tests__/list_schemes.test.ts index 955e17d7..de2f2425 100644 --- a/src/mcp/tools/project-discovery/__tests__/list_schemes.test.ts +++ b/src/mcp/tools/project-discovery/__tests__/list_schemes.test.ts @@ -6,8 +6,8 @@ import { describe, it, expect } from 'vitest'; import { z } from 'zod'; -import { createMockExecutor } from '../../../../test-utils/mock-executors.js'; -import plugin, { listSchemesLogic } from '../list_schemes.js'; +import { createMockExecutor } from '../../../../test-utils/mock-executors.ts'; +import plugin, { listSchemesLogic } from '../list_schemes.ts'; describe('list_schemes plugin', () => { describe('Export Field Validation (Literal)', () => { diff --git a/src/mcp/tools/project-discovery/__tests__/show_build_settings.test.ts b/src/mcp/tools/project-discovery/__tests__/show_build_settings.test.ts index f5882573..5fd7f186 100644 --- a/src/mcp/tools/project-discovery/__tests__/show_build_settings.test.ts +++ b/src/mcp/tools/project-discovery/__tests__/show_build_settings.test.ts @@ -1,6 +1,6 @@ import { describe, it, expect } from 'vitest'; import { z } from 'zod'; -import { createMockExecutor } from '../../../../test-utils/mock-executors.js'; +import { createMockExecutor } from '../../../../test-utils/mock-executors.ts'; import plugin, { showBuildSettingsLogic } from '../show_build_settings.ts'; describe('show_build_settings plugin', () => { diff --git a/src/mcp/tools/project-discovery/discover_projs.ts b/src/mcp/tools/project-discovery/discover_projs.ts index 22efa02a..1d5b2115 100644 --- a/src/mcp/tools/project-discovery/discover_projs.ts +++ b/src/mcp/tools/project-discovery/discover_projs.ts @@ -7,11 +7,11 @@ import { z } from 'zod'; import * as path from 'node:path'; -import { log } from '../../../utils/logging/index.js'; -import { ToolResponse, createTextContent } from '../../../types/common.js'; -import { getDefaultFileSystemExecutor, getDefaultCommandExecutor } from '../../../utils/command.js'; +import { log } from '../../../utils/logging/index.ts'; +import { ToolResponse, createTextContent } from '../../../types/common.ts'; +import { getDefaultFileSystemExecutor, getDefaultCommandExecutor } from '../../../utils/command.ts'; import { FileSystemExecutor } from '../../../utils/FileSystemExecutor.ts'; -import { createTypedTool } from '../../../utils/typed-tool-factory.js'; +import { createTypedTool } from '../../../utils/typed-tool-factory.ts'; // Constants const DEFAULT_MAX_DEPTH = 5; diff --git a/src/mcp/tools/project-discovery/get_app_bundle_id.ts b/src/mcp/tools/project-discovery/get_app_bundle_id.ts index 2488ee19..35d22519 100644 --- a/src/mcp/tools/project-discovery/get_app_bundle_id.ts +++ b/src/mcp/tools/project-discovery/get_app_bundle_id.ts @@ -6,15 +6,15 @@ */ import { z } from 'zod'; -import { log } from '../../../utils/logging/index.js'; -import { ToolResponse } from '../../../types/common.js'; +import { log } from '../../../utils/logging/index.ts'; +import { ToolResponse } from '../../../types/common.ts'; import { CommandExecutor, getDefaultFileSystemExecutor, getDefaultCommandExecutor, -} from '../../../utils/command.js'; +} from '../../../utils/command.ts'; import { FileSystemExecutor } from '../../../utils/FileSystemExecutor.ts'; -import { createTypedTool } from '../../../utils/typed-tool-factory.js'; +import { createTypedTool } from '../../../utils/typed-tool-factory.ts'; // Define schema as ZodObject const getAppBundleIdSchema = z.object({ diff --git a/src/mcp/tools/project-discovery/get_mac_bundle_id.ts b/src/mcp/tools/project-discovery/get_mac_bundle_id.ts index cbc4eb7e..92c67742 100644 --- a/src/mcp/tools/project-discovery/get_mac_bundle_id.ts +++ b/src/mcp/tools/project-discovery/get_mac_bundle_id.ts @@ -5,15 +5,15 @@ */ import { z } from 'zod'; -import { log } from '../../../utils/logging/index.js'; -import { ToolResponse } from '../../../types/common.js'; +import { log } from '../../../utils/logging/index.ts'; +import { ToolResponse } from '../../../types/common.ts'; import { CommandExecutor, getDefaultFileSystemExecutor, getDefaultCommandExecutor, -} from '../../../utils/command.js'; +} from '../../../utils/command.ts'; import { FileSystemExecutor } from '../../../utils/FileSystemExecutor.ts'; -import { createTypedTool } from '../../../utils/typed-tool-factory.js'; +import { createTypedTool } from '../../../utils/typed-tool-factory.ts'; /** * Sync wrapper for CommandExecutor to handle synchronous commands diff --git a/src/mcp/tools/project-discovery/list_schemes.ts b/src/mcp/tools/project-discovery/list_schemes.ts index e715ad11..56102e66 100644 --- a/src/mcp/tools/project-discovery/list_schemes.ts +++ b/src/mcp/tools/project-discovery/list_schemes.ts @@ -6,13 +6,13 @@ */ import { z } from 'zod'; -import { log } from '../../../utils/logging/index.js'; -import type { CommandExecutor } from '../../../utils/execution/index.js'; -import { getDefaultCommandExecutor } from '../../../utils/execution/index.js'; -import { createTextResponse } from '../../../utils/responses/index.js'; -import { ToolResponse } from '../../../types/common.js'; -import { createTypedTool } from '../../../utils/typed-tool-factory.js'; -import { nullifyEmptyStrings } from '../../../utils/schema-helpers.js'; +import { log } from '../../../utils/logging/index.ts'; +import type { CommandExecutor } from '../../../utils/execution/index.ts'; +import { getDefaultCommandExecutor } from '../../../utils/execution/index.ts'; +import { createTextResponse } from '../../../utils/responses/index.ts'; +import { ToolResponse } from '../../../types/common.ts'; +import { createTypedTool } from '../../../utils/typed-tool-factory.ts'; +import { nullifyEmptyStrings } from '../../../utils/schema-helpers.ts'; // Unified schema: XOR between projectPath and workspacePath const baseSchemaObject = z.object({ diff --git a/src/mcp/tools/project-discovery/show_build_settings.ts b/src/mcp/tools/project-discovery/show_build_settings.ts index 1e6125bb..4a8f0fb4 100644 --- a/src/mcp/tools/project-discovery/show_build_settings.ts +++ b/src/mcp/tools/project-discovery/show_build_settings.ts @@ -6,13 +6,13 @@ */ import { z } from 'zod'; -import { log } from '../../../utils/logging/index.js'; -import type { CommandExecutor } from '../../../utils/execution/index.js'; -import { getDefaultCommandExecutor } from '../../../utils/execution/index.js'; -import { createTextResponse } from '../../../utils/responses/index.js'; -import { ToolResponse } from '../../../types/common.js'; -import { createTypedTool } from '../../../utils/typed-tool-factory.js'; -import { nullifyEmptyStrings } from '../../../utils/schema-helpers.js'; +import { log } from '../../../utils/logging/index.ts'; +import type { CommandExecutor } from '../../../utils/execution/index.ts'; +import { getDefaultCommandExecutor } from '../../../utils/execution/index.ts'; +import { createTextResponse } from '../../../utils/responses/index.ts'; +import { ToolResponse } from '../../../types/common.ts'; +import { createTypedTool } from '../../../utils/typed-tool-factory.ts'; +import { nullifyEmptyStrings } from '../../../utils/schema-helpers.ts'; // Unified schema: XOR between projectPath and workspacePath const baseSchemaObject = z.object({ diff --git a/src/mcp/tools/project-scaffolding/__tests__/index.test.ts b/src/mcp/tools/project-scaffolding/__tests__/index.test.ts index e606a8be..66651d2b 100644 --- a/src/mcp/tools/project-scaffolding/__tests__/index.test.ts +++ b/src/mcp/tools/project-scaffolding/__tests__/index.test.ts @@ -2,7 +2,7 @@ * Tests for project-scaffolding workflow metadata */ import { describe, it, expect } from 'vitest'; -import { workflow } from '../index.js'; +import { workflow } from '../index.ts'; describe('project-scaffolding workflow metadata', () => { describe('Workflow Structure', () => { diff --git a/src/mcp/tools/project-scaffolding/__tests__/scaffold_ios_project.test.ts b/src/mcp/tools/project-scaffolding/__tests__/scaffold_ios_project.test.ts index 4632ebbf..647c5842 100644 --- a/src/mcp/tools/project-scaffolding/__tests__/scaffold_ios_project.test.ts +++ b/src/mcp/tools/project-scaffolding/__tests__/scaffold_ios_project.test.ts @@ -13,7 +13,7 @@ import scaffoldIosProject, { scaffold_ios_projectLogic } from '../scaffold_ios_p import { createMockExecutor, createMockFileSystemExecutor, -} from '../../../../test-utils/mock-executors.js'; +} from '../../../../test-utils/mock-executors.ts'; describe('scaffold_ios_project plugin', () => { let mockCommandExecutor: any; diff --git a/src/mcp/tools/project-scaffolding/__tests__/scaffold_macos_project.test.ts b/src/mcp/tools/project-scaffolding/__tests__/scaffold_macos_project.test.ts index 4e710e8f..d489f395 100644 --- a/src/mcp/tools/project-scaffolding/__tests__/scaffold_macos_project.test.ts +++ b/src/mcp/tools/project-scaffolding/__tests__/scaffold_macos_project.test.ts @@ -14,9 +14,9 @@ import { createMockFileSystemExecutor, createNoopExecutor, createMockExecutor, -} from '../../../../test-utils/mock-executors.js'; -import plugin, { scaffold_macos_projectLogic } from '../scaffold_macos_project.js'; -import { TemplateManager } from '../../../../utils/template/index.js'; +} from '../../../../test-utils/mock-executors.ts'; +import plugin, { scaffold_macos_projectLogic } from '../scaffold_macos_project.ts'; +import { TemplateManager } from '../../../../utils/template/index.ts'; // ONLY ALLOWED MOCKING: createMockFileSystemExecutor diff --git a/src/mcp/tools/project-scaffolding/scaffold_ios_project.ts b/src/mcp/tools/project-scaffolding/scaffold_ios_project.ts index c07ced42..29726790 100644 --- a/src/mcp/tools/project-scaffolding/scaffold_ios_project.ts +++ b/src/mcp/tools/project-scaffolding/scaffold_ios_project.ts @@ -6,15 +6,15 @@ import { z } from 'zod'; import { join, dirname, basename } from 'path'; -import { log } from '../../../utils/logging/index.js'; -import { ValidationError } from '../../../utils/responses/index.js'; -import { TemplateManager } from '../../../utils/template/index.js'; -import type { CommandExecutor, FileSystemExecutor } from '../../../utils/execution/index.js'; +import { log } from '../../../utils/logging/index.ts'; +import { ValidationError } from '../../../utils/responses/index.ts'; +import { TemplateManager } from '../../../utils/template/index.ts'; +import type { CommandExecutor, FileSystemExecutor } from '../../../utils/execution/index.ts'; import { getDefaultCommandExecutor, getDefaultFileSystemExecutor, -} from '../../../utils/execution/index.js'; -import { ToolResponse } from '../../../types/common.js'; +} from '../../../utils/execution/index.ts'; +import { ToolResponse } from '../../../types/common.ts'; // Common base schema for both iOS and macOS const BaseScaffoldSchema = z.object({ diff --git a/src/mcp/tools/project-scaffolding/scaffold_macos_project.ts b/src/mcp/tools/project-scaffolding/scaffold_macos_project.ts index b57da53e..062364ca 100644 --- a/src/mcp/tools/project-scaffolding/scaffold_macos_project.ts +++ b/src/mcp/tools/project-scaffolding/scaffold_macos_project.ts @@ -6,15 +6,15 @@ import { z } from 'zod'; import { join, dirname, basename } from 'path'; -import { log } from '../../../utils/logging/index.js'; -import { ValidationError } from '../../../utils/responses/index.js'; -import { TemplateManager } from '../../../utils/template/index.js'; -import { ToolResponse } from '../../../types/common.js'; +import { log } from '../../../utils/logging/index.ts'; +import { ValidationError } from '../../../utils/responses/index.ts'; +import { TemplateManager } from '../../../utils/template/index.ts'; +import { ToolResponse } from '../../../types/common.ts'; import { CommandExecutor, getDefaultCommandExecutor, getDefaultFileSystemExecutor, -} from '../../../utils/command.js'; +} from '../../../utils/command.ts'; import { FileSystemExecutor } from '../../../utils/FileSystemExecutor.ts'; // Common base schema for both iOS and macOS diff --git a/src/mcp/tools/simulator-management/__tests__/index.test.ts b/src/mcp/tools/simulator-management/__tests__/index.test.ts index 1d7ec9e7..3cdf064c 100644 --- a/src/mcp/tools/simulator-management/__tests__/index.test.ts +++ b/src/mcp/tools/simulator-management/__tests__/index.test.ts @@ -2,7 +2,7 @@ * Tests for simulator-management workflow metadata */ import { describe, it, expect } from 'vitest'; -import { workflow } from '../index.js'; +import { workflow } from '../index.ts'; describe('simulator-management workflow metadata', () => { describe('Workflow Structure', () => { diff --git a/src/mcp/tools/simulator-management/__tests__/reset_sim_location.test.ts b/src/mcp/tools/simulator-management/__tests__/reset_sim_location.test.ts index 02bfa3f6..38d51f07 100644 --- a/src/mcp/tools/simulator-management/__tests__/reset_sim_location.test.ts +++ b/src/mcp/tools/simulator-management/__tests__/reset_sim_location.test.ts @@ -1,7 +1,7 @@ import { describe, it, expect } from 'vitest'; import { z } from 'zod'; import resetSimLocationPlugin, { reset_sim_locationLogic } from '../reset_sim_location.ts'; -import { createMockExecutor } from '../../../../test-utils/mock-executors.js'; +import { createMockExecutor } from '../../../../test-utils/mock-executors.ts'; describe('reset_sim_location plugin', () => { describe('Export Field Validation (Literal)', () => { diff --git a/src/mcp/tools/simulator-management/__tests__/set_sim_appearance.test.ts b/src/mcp/tools/simulator-management/__tests__/set_sim_appearance.test.ts index aa01487a..1866a9f2 100644 --- a/src/mcp/tools/simulator-management/__tests__/set_sim_appearance.test.ts +++ b/src/mcp/tools/simulator-management/__tests__/set_sim_appearance.test.ts @@ -1,7 +1,7 @@ import { describe, it, expect } from 'vitest'; import { z } from 'zod'; import setSimAppearancePlugin, { set_sim_appearanceLogic } from '../set_sim_appearance.ts'; -import { createMockExecutor } from '../../../../test-utils/mock-executors.js'; +import { createMockExecutor } from '../../../../test-utils/mock-executors.ts'; describe('set_sim_appearance plugin', () => { describe('Export Field Validation (Literal)', () => { diff --git a/src/mcp/tools/simulator-management/__tests__/set_sim_location.test.ts b/src/mcp/tools/simulator-management/__tests__/set_sim_location.test.ts index f5db3503..606fae5d 100644 --- a/src/mcp/tools/simulator-management/__tests__/set_sim_location.test.ts +++ b/src/mcp/tools/simulator-management/__tests__/set_sim_location.test.ts @@ -6,7 +6,7 @@ import { describe, it, expect, beforeEach } from 'vitest'; import { z } from 'zod'; -import { createMockExecutor, createNoopExecutor } from '../../../../test-utils/mock-executors.js'; +import { createMockExecutor, createNoopExecutor } from '../../../../test-utils/mock-executors.ts'; import setSimLocation, { set_sim_locationLogic } from '../set_sim_location.ts'; describe('set_sim_location tool', () => { diff --git a/src/mcp/tools/simulator-management/__tests__/sim_statusbar.test.ts b/src/mcp/tools/simulator-management/__tests__/sim_statusbar.test.ts index 81414a20..ba364d85 100644 --- a/src/mcp/tools/simulator-management/__tests__/sim_statusbar.test.ts +++ b/src/mcp/tools/simulator-management/__tests__/sim_statusbar.test.ts @@ -6,7 +6,7 @@ import { describe, it, expect } from 'vitest'; import { z } from 'zod'; -import { createMockExecutor, type CommandExecutor } from '../../../../test-utils/mock-executors.js'; +import { createMockExecutor, type CommandExecutor } from '../../../../test-utils/mock-executors.ts'; import simStatusbar, { sim_statusbarLogic } from '../sim_statusbar.ts'; describe('sim_statusbar tool', () => { diff --git a/src/mcp/tools/simulator-management/boot_sim.ts b/src/mcp/tools/simulator-management/boot_sim.ts index 079d8aa6..174a6c68 100644 --- a/src/mcp/tools/simulator-management/boot_sim.ts +++ b/src/mcp/tools/simulator-management/boot_sim.ts @@ -1,2 +1,2 @@ // Re-export from simulator to avoid duplication -export { default } from '../simulator/boot_sim.js'; +export { default } from '../simulator/boot_sim.ts'; diff --git a/src/mcp/tools/simulator-management/list_sims.ts b/src/mcp/tools/simulator-management/list_sims.ts index b14bd8a1..3c5a2ff0 100644 --- a/src/mcp/tools/simulator-management/list_sims.ts +++ b/src/mcp/tools/simulator-management/list_sims.ts @@ -1,2 +1,2 @@ // Re-export from simulator to avoid duplication -export { default } from '../simulator/list_sims.js'; +export { default } from '../simulator/list_sims.ts'; diff --git a/src/mcp/tools/simulator-management/open_sim.ts b/src/mcp/tools/simulator-management/open_sim.ts index e71b63c0..43a8857f 100644 --- a/src/mcp/tools/simulator-management/open_sim.ts +++ b/src/mcp/tools/simulator-management/open_sim.ts @@ -1,2 +1,2 @@ // Re-export from simulator to avoid duplication -export { default } from '../simulator/open_sim.js'; +export { default } from '../simulator/open_sim.ts'; diff --git a/src/mcp/tools/simulator-management/reset_sim_location.ts b/src/mcp/tools/simulator-management/reset_sim_location.ts index 9b17171c..f6c55fc7 100644 --- a/src/mcp/tools/simulator-management/reset_sim_location.ts +++ b/src/mcp/tools/simulator-management/reset_sim_location.ts @@ -1,7 +1,7 @@ import { z } from 'zod'; import { ToolResponse } from '../../../types/common.ts'; -import { log } from '../../../utils/index.ts'; -import { CommandExecutor, getDefaultCommandExecutor } from '../../../utils/index.ts'; +import { log } from '../../../utils/logging/index.ts'; +import { CommandExecutor, getDefaultCommandExecutor } from '../../../utils/execution/index.ts'; import { createTypedTool } from '../../../utils/typed-tool-factory.ts'; // Define schema as ZodObject diff --git a/src/mcp/tools/simulator-management/set_sim_appearance.ts b/src/mcp/tools/simulator-management/set_sim_appearance.ts index 4fae1ba5..b8d65eeb 100644 --- a/src/mcp/tools/simulator-management/set_sim_appearance.ts +++ b/src/mcp/tools/simulator-management/set_sim_appearance.ts @@ -1,6 +1,7 @@ import { z } from 'zod'; import { ToolResponse } from '../../../types/common.ts'; -import { log, CommandExecutor, getDefaultCommandExecutor } from '../../../utils/index.ts'; +import { log } from '../../../utils/logging/index.ts'; +import { CommandExecutor, getDefaultCommandExecutor } from '../../../utils/execution/index.ts'; import { createTypedTool } from '../../../utils/typed-tool-factory.ts'; // Define schema as ZodObject diff --git a/src/mcp/tools/simulator-management/set_sim_location.ts b/src/mcp/tools/simulator-management/set_sim_location.ts index 306935e0..df2047b2 100644 --- a/src/mcp/tools/simulator-management/set_sim_location.ts +++ b/src/mcp/tools/simulator-management/set_sim_location.ts @@ -1,6 +1,7 @@ import { z } from 'zod'; import { ToolResponse } from '../../../types/common.ts'; -import { log, CommandExecutor, getDefaultCommandExecutor } from '../../../utils/index.ts'; +import { log } from '../../../utils/logging/index.ts'; +import { CommandExecutor, getDefaultCommandExecutor } from '../../../utils/execution/index.ts'; import { createTypedTool } from '../../../utils/typed-tool-factory.ts'; // Define schema as ZodObject diff --git a/src/mcp/tools/simulator-management/sim_statusbar.ts b/src/mcp/tools/simulator-management/sim_statusbar.ts index aa7148c3..261ea800 100644 --- a/src/mcp/tools/simulator-management/sim_statusbar.ts +++ b/src/mcp/tools/simulator-management/sim_statusbar.ts @@ -1,6 +1,7 @@ import { z } from 'zod'; import { ToolResponse } from '../../../types/common.ts'; -import { log, CommandExecutor, getDefaultCommandExecutor } from '../../../utils/index.ts'; +import { log } from '../../../utils/logging/index.ts'; +import { CommandExecutor, getDefaultCommandExecutor } from '../../../utils/execution/index.ts'; import { createTypedTool } from '../../../utils/typed-tool-factory.ts'; // Define schema as ZodObject diff --git a/src/mcp/tools/simulator/__tests__/boot_sim.test.ts b/src/mcp/tools/simulator/__tests__/boot_sim.test.ts index ac1a2f06..4f258031 100644 --- a/src/mcp/tools/simulator/__tests__/boot_sim.test.ts +++ b/src/mcp/tools/simulator/__tests__/boot_sim.test.ts @@ -10,7 +10,7 @@ import { createMockExecutor, createMockFileSystemExecutor, createNoopExecutor, -} from '../../../../test-utils/mock-executors.js'; +} from '../../../../test-utils/mock-executors.ts'; import bootSim, { boot_simLogic } from '../boot_sim.ts'; describe('boot_sim tool', () => { diff --git a/src/mcp/tools/simulator/__tests__/build_run_sim.test.ts b/src/mcp/tools/simulator/__tests__/build_run_sim.test.ts index fea58f55..ac2fec8f 100644 --- a/src/mcp/tools/simulator/__tests__/build_run_sim.test.ts +++ b/src/mcp/tools/simulator/__tests__/build_run_sim.test.ts @@ -8,8 +8,8 @@ import { z } from 'zod'; import { createMockExecutor, createMockFileSystemExecutor, -} from '../../../../test-utils/mock-executors.js'; -import buildRunSim, { build_run_simLogic } from '../build_run_sim.js'; +} from '../../../../test-utils/mock-executors.ts'; +import buildRunSim, { build_run_simLogic } from '../build_run_sim.ts'; describe('build_run_sim tool', () => { describe('Export Field Validation (Literal)', () => { diff --git a/src/mcp/tools/simulator/__tests__/build_sim.test.ts b/src/mcp/tools/simulator/__tests__/build_sim.test.ts index e1819d77..af69244c 100644 --- a/src/mcp/tools/simulator/__tests__/build_sim.test.ts +++ b/src/mcp/tools/simulator/__tests__/build_sim.test.ts @@ -1,9 +1,9 @@ import { describe, it, expect, beforeEach } from 'vitest'; import { z } from 'zod'; -import { createMockExecutor } from '../../../../test-utils/mock-executors.js'; +import { createMockExecutor } from '../../../../test-utils/mock-executors.ts'; // Import the plugin and logic function -import buildSim, { build_simLogic } from '../build_sim.js'; +import buildSim, { build_simLogic } from '../build_sim.ts'; describe('build_sim tool', () => { // Only clear any remaining mocks if needed diff --git a/src/mcp/tools/simulator/__tests__/index.test.ts b/src/mcp/tools/simulator/__tests__/index.test.ts index 2a7f5685..a23f9593 100644 --- a/src/mcp/tools/simulator/__tests__/index.test.ts +++ b/src/mcp/tools/simulator/__tests__/index.test.ts @@ -2,7 +2,7 @@ * Tests for simulator-project workflow metadata */ import { describe, it, expect } from 'vitest'; -import { workflow } from '../index.js'; +import { workflow } from '../index.ts'; describe('simulator-project workflow metadata', () => { describe('Workflow Structure', () => { diff --git a/src/mcp/tools/simulator/__tests__/install_app_sim.test.ts b/src/mcp/tools/simulator/__tests__/install_app_sim.test.ts index d6ac648b..173ec986 100644 --- a/src/mcp/tools/simulator/__tests__/install_app_sim.test.ts +++ b/src/mcp/tools/simulator/__tests__/install_app_sim.test.ts @@ -4,7 +4,7 @@ import { createMockExecutor, createMockFileSystemExecutor, createNoopExecutor, -} from '../../../../test-utils/mock-executors.js'; +} from '../../../../test-utils/mock-executors.ts'; import installAppSim, { install_app_simLogic } from '../install_app_sim.ts'; describe('install_app_sim tool', () => { diff --git a/src/mcp/tools/simulator/__tests__/launch_app_logs_sim.test.ts b/src/mcp/tools/simulator/__tests__/launch_app_logs_sim.test.ts index 75dc140a..27cfcff3 100644 --- a/src/mcp/tools/simulator/__tests__/launch_app_logs_sim.test.ts +++ b/src/mcp/tools/simulator/__tests__/launch_app_logs_sim.test.ts @@ -10,7 +10,7 @@ import launchAppLogsSim, { launch_app_logs_simLogic, LogCaptureFunction, } from '../launch_app_logs_sim.ts'; -import { createMockExecutor } from '../../../../test-utils/mock-executors.js'; +import { createMockExecutor } from '../../../../test-utils/mock-executors.ts'; describe('launch_app_logs_sim tool', () => { describe('Export Field Validation (Literal)', () => { diff --git a/src/mcp/tools/simulator/__tests__/launch_app_sim.test.ts b/src/mcp/tools/simulator/__tests__/launch_app_sim.test.ts index 2c9695ec..4ad74fd6 100644 --- a/src/mcp/tools/simulator/__tests__/launch_app_sim.test.ts +++ b/src/mcp/tools/simulator/__tests__/launch_app_sim.test.ts @@ -1,7 +1,7 @@ import { describe, it, expect, beforeEach } from 'vitest'; import { z } from 'zod'; -import { createMockExecutor } from '../../../../test-utils/mock-executors.js'; -import launchAppSim, { launch_app_simLogic } from '../launch_app_sim.js'; +import { createMockExecutor } from '../../../../test-utils/mock-executors.ts'; +import launchAppSim, { launch_app_simLogic } from '../launch_app_sim.ts'; describe('launch_app_sim tool', () => { describe('Export Field Validation (Literal)', () => { diff --git a/src/mcp/tools/simulator/__tests__/list_sims.test.ts b/src/mcp/tools/simulator/__tests__/list_sims.test.ts index 7a78d13f..00dfb84d 100644 --- a/src/mcp/tools/simulator/__tests__/list_sims.test.ts +++ b/src/mcp/tools/simulator/__tests__/list_sims.test.ts @@ -3,7 +3,7 @@ import { z } from 'zod'; import { createMockExecutor, createMockFileSystemExecutor, -} from '../../../../test-utils/mock-executors.js'; +} from '../../../../test-utils/mock-executors.ts'; // Import the plugin and logic function import listSims, { list_simsLogic } from '../list_sims.ts'; diff --git a/src/mcp/tools/simulator/__tests__/open_sim.test.ts b/src/mcp/tools/simulator/__tests__/open_sim.test.ts index feab6964..fc82b1de 100644 --- a/src/mcp/tools/simulator/__tests__/open_sim.test.ts +++ b/src/mcp/tools/simulator/__tests__/open_sim.test.ts @@ -6,7 +6,7 @@ import { describe, it, expect } from 'vitest'; import { z } from 'zod'; -import { createMockExecutor, type CommandExecutor } from '../../../../test-utils/mock-executors.js'; +import { createMockExecutor, type CommandExecutor } from '../../../../test-utils/mock-executors.ts'; import openSim, { open_simLogic } from '../open_sim.ts'; describe('open_sim tool', () => { diff --git a/src/mcp/tools/simulator/__tests__/screenshot.test.ts b/src/mcp/tools/simulator/__tests__/screenshot.test.ts index f17b8a71..6a108264 100644 --- a/src/mcp/tools/simulator/__tests__/screenshot.test.ts +++ b/src/mcp/tools/simulator/__tests__/screenshot.test.ts @@ -10,7 +10,7 @@ import { createMockExecutor, createMockFileSystemExecutor, createCommandMatchingMockExecutor, -} from '../../../../test-utils/mock-executors.js'; +} from '../../../../test-utils/mock-executors.ts'; import screenshotPlugin, { screenshotLogic } from '../../ui-testing/screenshot.ts'; describe('screenshot plugin', () => { diff --git a/src/mcp/tools/simulator/__tests__/stop_app_sim.test.ts b/src/mcp/tools/simulator/__tests__/stop_app_sim.test.ts index be03777a..4147ca6d 100644 --- a/src/mcp/tools/simulator/__tests__/stop_app_sim.test.ts +++ b/src/mcp/tools/simulator/__tests__/stop_app_sim.test.ts @@ -4,8 +4,8 @@ import { createMockExecutor, createMockFileSystemExecutor, createNoopExecutor, -} from '../../../../test-utils/mock-executors.js'; -import plugin, { stop_app_simLogic } from '../stop_app_sim.js'; +} from '../../../../test-utils/mock-executors.ts'; +import plugin, { stop_app_simLogic } from '../stop_app_sim.ts'; describe('stop_app_sim plugin', () => { describe('Export Field Validation (Literal)', () => { diff --git a/src/mcp/tools/simulator/boot_sim.ts b/src/mcp/tools/simulator/boot_sim.ts index 3ef8b723..5c036211 100644 --- a/src/mcp/tools/simulator/boot_sim.ts +++ b/src/mcp/tools/simulator/boot_sim.ts @@ -1,9 +1,9 @@ import { z } from 'zod'; -import { ToolResponse } from '../../../types/common.js'; -import { log } from '../../../utils/logging/index.js'; -import { getDefaultCommandExecutor } from '../../../utils/execution/index.js'; -import type { CommandExecutor } from '../../../utils/execution/index.js'; -import { createTypedTool } from '../../../utils/typed-tool-factory.js'; +import { ToolResponse } from '../../../types/common.ts'; +import { log } from '../../../utils/logging/index.ts'; +import { getDefaultCommandExecutor } from '../../../utils/execution/index.ts'; +import type { CommandExecutor } from '../../../utils/execution/index.ts'; +import { createTypedTool } from '../../../utils/typed-tool-factory.ts'; // Define schema as ZodObject const bootSimSchema = z.object({ diff --git a/src/mcp/tools/simulator/build_run_sim.ts b/src/mcp/tools/simulator/build_run_sim.ts index bc5d9254..3241d592 100644 --- a/src/mcp/tools/simulator/build_run_sim.ts +++ b/src/mcp/tools/simulator/build_run_sim.ts @@ -7,14 +7,14 @@ */ import { z } from 'zod'; -import { ToolResponse, SharedBuildParams, XcodePlatform } from '../../../types/common.js'; -import { log } from '../../../utils/logging/index.js'; -import { getDefaultCommandExecutor } from '../../../utils/execution/index.js'; -import { createTextResponse } from '../../../utils/responses/index.js'; -import { executeXcodeBuildCommand } from '../../../utils/build/index.js'; -import type { CommandExecutor } from '../../../utils/execution/index.js'; -import { determineSimulatorUuid } from '../../../utils/simulator-utils.js'; -import { nullifyEmptyStrings } from '../../../utils/schema-helpers.js'; +import { ToolResponse, SharedBuildParams, XcodePlatform } from '../../../types/common.ts'; +import { log } from '../../../utils/logging/index.ts'; +import { getDefaultCommandExecutor } from '../../../utils/execution/index.ts'; +import { createTextResponse } from '../../../utils/responses/index.ts'; +import { executeXcodeBuildCommand } from '../../../utils/build/index.ts'; +import type { CommandExecutor } from '../../../utils/execution/index.ts'; +import { determineSimulatorUuid } from '../../../utils/simulator-utils.ts'; +import { nullifyEmptyStrings } from '../../../utils/schema-helpers.ts'; // Unified schema: XOR between projectPath and workspacePath, and XOR between simulatorId and simulatorName const baseOptions = { diff --git a/src/mcp/tools/simulator/build_sim.ts b/src/mcp/tools/simulator/build_sim.ts index 48e15229..41145c78 100644 --- a/src/mcp/tools/simulator/build_sim.ts +++ b/src/mcp/tools/simulator/build_sim.ts @@ -7,12 +7,12 @@ */ import { z } from 'zod'; -import { log } from '../../../utils/logging/index.js'; -import { executeXcodeBuildCommand } from '../../../utils/build/index.js'; -import { ToolResponse, XcodePlatform } from '../../../types/common.js'; -import type { CommandExecutor } from '../../../utils/execution/index.js'; -import { getDefaultCommandExecutor } from '../../../utils/execution/index.js'; -import { nullifyEmptyStrings } from '../../../utils/schema-helpers.js'; +import { log } from '../../../utils/logging/index.ts'; +import { executeXcodeBuildCommand } from '../../../utils/build/index.ts'; +import { ToolResponse, XcodePlatform } from '../../../types/common.ts'; +import type { CommandExecutor } from '../../../utils/execution/index.ts'; +import { getDefaultCommandExecutor } from '../../../utils/execution/index.ts'; +import { nullifyEmptyStrings } from '../../../utils/schema-helpers.ts'; // Unified schema: XOR between projectPath and workspacePath, and XOR between simulatorId and simulatorName const baseOptions = { diff --git a/src/mcp/tools/simulator/clean.ts b/src/mcp/tools/simulator/clean.ts index 917e6338..76494c98 100644 --- a/src/mcp/tools/simulator/clean.ts +++ b/src/mcp/tools/simulator/clean.ts @@ -1,2 +1,2 @@ // Re-export unified clean tool for simulator-project workflow -export { default } from '../utilities/clean.js'; +export { default } from '../utilities/clean.ts'; diff --git a/src/mcp/tools/simulator/describe_ui.ts b/src/mcp/tools/simulator/describe_ui.ts index 24b24163..3208a22d 100644 --- a/src/mcp/tools/simulator/describe_ui.ts +++ b/src/mcp/tools/simulator/describe_ui.ts @@ -1,2 +1,2 @@ // Re-export from ui-testing to avoid duplication -export { default } from '../ui-testing/describe_ui.js'; +export { default } from '../ui-testing/describe_ui.ts'; diff --git a/src/mcp/tools/simulator/discover_projs.ts b/src/mcp/tools/simulator/discover_projs.ts index 44b43df5..58fbf05d 100644 --- a/src/mcp/tools/simulator/discover_projs.ts +++ b/src/mcp/tools/simulator/discover_projs.ts @@ -1,2 +1,2 @@ // Re-export from project-discovery to complete workflow -export { default } from '../project-discovery/discover_projs.js'; +export { default } from '../project-discovery/discover_projs.ts'; diff --git a/src/mcp/tools/simulator/get_app_bundle_id.ts b/src/mcp/tools/simulator/get_app_bundle_id.ts index 11b4c5f8..6c0bfc0d 100644 --- a/src/mcp/tools/simulator/get_app_bundle_id.ts +++ b/src/mcp/tools/simulator/get_app_bundle_id.ts @@ -1,2 +1,2 @@ // Re-export from project-discovery to complete workflow -export { default } from '../project-discovery/get_app_bundle_id.js'; +export { default } from '../project-discovery/get_app_bundle_id.ts'; diff --git a/src/mcp/tools/simulator/get_sim_app_path.ts b/src/mcp/tools/simulator/get_sim_app_path.ts index 779d81dc..44a1df75 100644 --- a/src/mcp/tools/simulator/get_sim_app_path.ts +++ b/src/mcp/tools/simulator/get_sim_app_path.ts @@ -7,13 +7,13 @@ */ import { z } from 'zod'; -import { log } from '../../../utils/logging/index.js'; -import { createTextResponse } from '../../../utils/responses/index.js'; -import type { CommandExecutor } from '../../../utils/execution/index.js'; -import { getDefaultCommandExecutor } from '../../../utils/execution/index.js'; -import { ToolResponse } from '../../../types/common.js'; -import { createTypedTool } from '../../../utils/typed-tool-factory.js'; -import { nullifyEmptyStrings } from '../../../utils/schema-helpers.js'; +import { log } from '../../../utils/logging/index.ts'; +import { createTextResponse } from '../../../utils/responses/index.ts'; +import type { CommandExecutor } from '../../../utils/execution/index.ts'; +import { getDefaultCommandExecutor } from '../../../utils/execution/index.ts'; +import { ToolResponse } from '../../../types/common.ts'; +import { createTypedTool } from '../../../utils/typed-tool-factory.ts'; +import { nullifyEmptyStrings } from '../../../utils/schema-helpers.ts'; const XcodePlatform = { macOS: 'macOS', diff --git a/src/mcp/tools/simulator/install_app_sim.ts b/src/mcp/tools/simulator/install_app_sim.ts index 83a42bff..b1a58750 100644 --- a/src/mcp/tools/simulator/install_app_sim.ts +++ b/src/mcp/tools/simulator/install_app_sim.ts @@ -1,10 +1,10 @@ import { z } from 'zod'; -import { ToolResponse } from '../../../types/common.js'; -import { log } from '../../../utils/logging/index.js'; -import { validateFileExists } from '../../../utils/validation/index.js'; -import type { CommandExecutor, FileSystemExecutor } from '../../../utils/execution/index.js'; -import { getDefaultCommandExecutor } from '../../../utils/execution/index.js'; -import { createTypedTool } from '../../../utils/typed-tool-factory.js'; +import { ToolResponse } from '../../../types/common.ts'; +import { log } from '../../../utils/logging/index.ts'; +import { validateFileExists } from '../../../utils/validation/index.ts'; +import type { CommandExecutor, FileSystemExecutor } from '../../../utils/execution/index.ts'; +import { getDefaultCommandExecutor } from '../../../utils/execution/index.ts'; +import { createTypedTool } from '../../../utils/typed-tool-factory.ts'; // Define schema as ZodObject const installAppSimSchema = z.object({ diff --git a/src/mcp/tools/simulator/launch_app_logs_sim.ts b/src/mcp/tools/simulator/launch_app_logs_sim.ts index ee0d8d5d..4cdb81a7 100644 --- a/src/mcp/tools/simulator/launch_app_logs_sim.ts +++ b/src/mcp/tools/simulator/launch_app_logs_sim.ts @@ -1,10 +1,10 @@ import { z } from 'zod'; -import { ToolResponse, createTextContent } from '../../../types/common.js'; -import { log } from '../../../utils/logging/index.js'; -import { startLogCapture } from '../../../utils/log-capture/index.js'; -import type { CommandExecutor } from '../../../utils/execution/index.js'; -import { getDefaultCommandExecutor } from '../../../utils/execution/index.js'; -import { createTypedTool } from '../../../utils/typed-tool-factory.js'; +import { ToolResponse, createTextContent } from '../../../types/common.ts'; +import { log } from '../../../utils/logging/index.ts'; +import { startLogCapture } from '../../../utils/log-capture/index.ts'; +import type { CommandExecutor } from '../../../utils/execution/index.ts'; +import { getDefaultCommandExecutor } from '../../../utils/execution/index.ts'; +import { createTypedTool } from '../../../utils/typed-tool-factory.ts'; /** * Log capture function type for dependency injection diff --git a/src/mcp/tools/simulator/launch_app_sim.ts b/src/mcp/tools/simulator/launch_app_sim.ts index 55eab15a..c4548441 100644 --- a/src/mcp/tools/simulator/launch_app_sim.ts +++ b/src/mcp/tools/simulator/launch_app_sim.ts @@ -1,9 +1,9 @@ import { z } from 'zod'; -import { ToolResponse } from '../../../types/common.js'; -import { log } from '../../../utils/logging/index.js'; -import type { CommandExecutor } from '../../../utils/execution/index.js'; -import { getDefaultCommandExecutor } from '../../../utils/execution/index.js'; -import { nullifyEmptyStrings } from '../../../utils/schema-helpers.js'; +import { ToolResponse } from '../../../types/common.ts'; +import { log } from '../../../utils/logging/index.ts'; +import type { CommandExecutor } from '../../../utils/execution/index.ts'; +import { getDefaultCommandExecutor } from '../../../utils/execution/index.ts'; +import { nullifyEmptyStrings } from '../../../utils/schema-helpers.ts'; // Unified schema: XOR between simulatorUuid and simulatorName const baseOptions = { diff --git a/src/mcp/tools/simulator/list_schemes.ts b/src/mcp/tools/simulator/list_schemes.ts index fee2bd9f..1ecdf67f 100644 --- a/src/mcp/tools/simulator/list_schemes.ts +++ b/src/mcp/tools/simulator/list_schemes.ts @@ -1,2 +1,2 @@ // Re-export unified list_schemes tool for simulator-project workflow -export { default } from '../project-discovery/list_schemes.js'; +export { default } from '../project-discovery/list_schemes.ts'; diff --git a/src/mcp/tools/simulator/list_sims.ts b/src/mcp/tools/simulator/list_sims.ts index c1a91183..6dfcd6e4 100644 --- a/src/mcp/tools/simulator/list_sims.ts +++ b/src/mcp/tools/simulator/list_sims.ts @@ -1,9 +1,9 @@ import { z } from 'zod'; -import type { ToolResponse } from '../../../types/common.js'; -import { log } from '../../../utils/logging/index.js'; -import type { CommandExecutor } from '../../../utils/execution/index.js'; -import { getDefaultCommandExecutor } from '../../../utils/execution/index.js'; -import { createTypedTool } from '../../../utils/typed-tool-factory.js'; +import type { ToolResponse } from '../../../types/common.ts'; +import { log } from '../../../utils/logging/index.ts'; +import type { CommandExecutor } from '../../../utils/execution/index.ts'; +import { getDefaultCommandExecutor } from '../../../utils/execution/index.ts'; +import { createTypedTool } from '../../../utils/typed-tool-factory.ts'; // Define schema as ZodObject const listSimsSchema = z.object({ diff --git a/src/mcp/tools/simulator/open_sim.ts b/src/mcp/tools/simulator/open_sim.ts index bac0e229..1970895c 100644 --- a/src/mcp/tools/simulator/open_sim.ts +++ b/src/mcp/tools/simulator/open_sim.ts @@ -1,9 +1,9 @@ import { z } from 'zod'; -import { ToolResponse } from '../../../types/common.js'; -import { log } from '../../../utils/logging/index.js'; -import type { CommandExecutor } from '../../../utils/execution/index.js'; -import { getDefaultCommandExecutor } from '../../../utils/execution/index.js'; -import { createTypedTool } from '../../../utils/typed-tool-factory.js'; +import { ToolResponse } from '../../../types/common.ts'; +import { log } from '../../../utils/logging/index.ts'; +import type { CommandExecutor } from '../../../utils/execution/index.ts'; +import { getDefaultCommandExecutor } from '../../../utils/execution/index.ts'; +import { createTypedTool } from '../../../utils/typed-tool-factory.ts'; // Define schema as ZodObject const openSimSchema = z.object({}); diff --git a/src/mcp/tools/simulator/screenshot.ts b/src/mcp/tools/simulator/screenshot.ts index 69ebf506..a4cde5a0 100644 --- a/src/mcp/tools/simulator/screenshot.ts +++ b/src/mcp/tools/simulator/screenshot.ts @@ -1,2 +1,2 @@ // Re-export from ui-testing to avoid duplication -export { default } from '../ui-testing/screenshot.js'; +export { default } from '../ui-testing/screenshot.ts'; diff --git a/src/mcp/tools/simulator/show_build_settings.ts b/src/mcp/tools/simulator/show_build_settings.ts index 1490a8fd..14d779c0 100644 --- a/src/mcp/tools/simulator/show_build_settings.ts +++ b/src/mcp/tools/simulator/show_build_settings.ts @@ -1,2 +1,2 @@ // Re-export unified tool for simulator-project workflow -export { default } from '../project-discovery/show_build_settings.js'; +export { default } from '../project-discovery/show_build_settings.ts'; diff --git a/src/mcp/tools/simulator/stop_app_sim.ts b/src/mcp/tools/simulator/stop_app_sim.ts index 2cc900e1..45bb88bd 100644 --- a/src/mcp/tools/simulator/stop_app_sim.ts +++ b/src/mcp/tools/simulator/stop_app_sim.ts @@ -1,9 +1,9 @@ import { z } from 'zod'; -import { ToolResponse } from '../../../types/common.js'; -import { log } from '../../../utils/logging/index.js'; -import type { CommandExecutor } from '../../../utils/execution/index.js'; -import { getDefaultCommandExecutor } from '../../../utils/execution/index.js'; -import { nullifyEmptyStrings } from '../../../utils/schema-helpers.js'; +import { ToolResponse } from '../../../types/common.ts'; +import { log } from '../../../utils/logging/index.ts'; +import type { CommandExecutor } from '../../../utils/execution/index.ts'; +import { getDefaultCommandExecutor } from '../../../utils/execution/index.ts'; +import { nullifyEmptyStrings } from '../../../utils/schema-helpers.ts'; // Unified schema: XOR between simulatorUuid and simulatorName const baseOptions = { diff --git a/src/mcp/tools/simulator/test_sim.ts b/src/mcp/tools/simulator/test_sim.ts index a5a4daa1..728aac57 100644 --- a/src/mcp/tools/simulator/test_sim.ts +++ b/src/mcp/tools/simulator/test_sim.ts @@ -7,13 +7,13 @@ */ import { z } from 'zod'; -import { handleTestLogic } from '../../../utils/test/index.js'; -import { log } from '../../../utils/logging/index.js'; -import { XcodePlatform } from '../../../types/common.js'; -import { ToolResponse } from '../../../types/common.js'; -import type { CommandExecutor } from '../../../utils/execution/index.js'; -import { getDefaultCommandExecutor } from '../../../utils/execution/index.js'; -import { nullifyEmptyStrings } from '../../../utils/schema-helpers.js'; +import { handleTestLogic } from '../../../utils/test/index.ts'; +import { log } from '../../../utils/logging/index.ts'; +import { XcodePlatform } from '../../../types/common.ts'; +import { ToolResponse } from '../../../types/common.ts'; +import type { CommandExecutor } from '../../../utils/execution/index.ts'; +import { getDefaultCommandExecutor } from '../../../utils/execution/index.ts'; +import { nullifyEmptyStrings } from '../../../utils/schema-helpers.ts'; // Define base schema object with all fields const baseSchemaObject = z.object({ diff --git a/src/mcp/tools/swift-package/__tests__/active-processes.test.ts b/src/mcp/tools/swift-package/__tests__/active-processes.test.ts index f649e208..e10114a5 100644 --- a/src/mcp/tools/swift-package/__tests__/active-processes.test.ts +++ b/src/mcp/tools/swift-package/__tests__/active-processes.test.ts @@ -11,7 +11,7 @@ import { removeProcess, clearAllProcesses, type ProcessInfo, -} from '../active-processes.js'; +} from '../active-processes.ts'; describe('active-processes module', () => { // Clear the map before each test diff --git a/src/mcp/tools/swift-package/__tests__/swift_package_build.test.ts b/src/mcp/tools/swift-package/__tests__/swift_package_build.test.ts index 1c84cacd..180d4baa 100644 --- a/src/mcp/tools/swift-package/__tests__/swift_package_build.test.ts +++ b/src/mcp/tools/swift-package/__tests__/swift_package_build.test.ts @@ -9,7 +9,7 @@ import { createMockExecutor, createMockFileSystemExecutor, createNoopExecutor, -} from '../../../../test-utils/mock-executors.js'; +} from '../../../../test-utils/mock-executors.ts'; import swiftPackageBuild, { swift_package_buildLogic } from '../swift_package_build.ts'; describe('swift_package_build plugin', () => { diff --git a/src/mcp/tools/swift-package/__tests__/swift_package_clean.test.ts b/src/mcp/tools/swift-package/__tests__/swift_package_clean.test.ts index 137a15f0..d443a1b1 100644 --- a/src/mcp/tools/swift-package/__tests__/swift_package_clean.test.ts +++ b/src/mcp/tools/swift-package/__tests__/swift_package_clean.test.ts @@ -9,7 +9,7 @@ import { createMockExecutor, createMockFileSystemExecutor, createNoopExecutor, -} from '../../../../test-utils/mock-executors.js'; +} from '../../../../test-utils/mock-executors.ts'; import swiftPackageClean, { swift_package_cleanLogic } from '../swift_package_clean.ts'; describe('swift_package_clean plugin', () => { diff --git a/src/mcp/tools/swift-package/__tests__/swift_package_list.test.ts b/src/mcp/tools/swift-package/__tests__/swift_package_list.test.ts index a7140efd..b4f1d4be 100644 --- a/src/mcp/tools/swift-package/__tests__/swift_package_list.test.ts +++ b/src/mcp/tools/swift-package/__tests__/swift_package_list.test.ts @@ -5,7 +5,7 @@ */ import { describe, it, expect, beforeEach } from 'vitest'; -import swiftPackageList, { swift_package_listLogic } from '../swift_package_list.js'; +import swiftPackageList, { swift_package_listLogic } from '../swift_package_list.ts'; describe('swift_package_list plugin', () => { // No mocks to clear with pure dependency injection diff --git a/src/mcp/tools/swift-package/__tests__/swift_package_run.test.ts b/src/mcp/tools/swift-package/__tests__/swift_package_run.test.ts index 420f2ee5..e59357a8 100644 --- a/src/mcp/tools/swift-package/__tests__/swift_package_run.test.ts +++ b/src/mcp/tools/swift-package/__tests__/swift_package_run.test.ts @@ -6,7 +6,7 @@ import { describe, it, expect, beforeEach } from 'vitest'; import { z } from 'zod'; -import { createMockExecutor, createNoopExecutor } from '../../../../test-utils/mock-executors.js'; +import { createMockExecutor, createNoopExecutor } from '../../../../test-utils/mock-executors.ts'; import swiftPackageRun, { swift_package_runLogic } from '../swift_package_run.ts'; describe('swift_package_run plugin', () => { diff --git a/src/mcp/tools/swift-package/__tests__/swift_package_stop.test.ts b/src/mcp/tools/swift-package/__tests__/swift_package_stop.test.ts index 29cbc0bc..7d8586d1 100644 --- a/src/mcp/tools/swift-package/__tests__/swift_package_stop.test.ts +++ b/src/mcp/tools/swift-package/__tests__/swift_package_stop.test.ts @@ -10,7 +10,7 @@ import swiftPackageStop, { createMockProcessManager, swift_package_stopLogic, type ProcessManager, -} from '../swift_package_stop.js'; +} from '../swift_package_stop.ts'; /** * Mock process implementation for testing diff --git a/src/mcp/tools/swift-package/__tests__/swift_package_test.test.ts b/src/mcp/tools/swift-package/__tests__/swift_package_test.test.ts index 83cb434c..4ad8c6c3 100644 --- a/src/mcp/tools/swift-package/__tests__/swift_package_test.test.ts +++ b/src/mcp/tools/swift-package/__tests__/swift_package_test.test.ts @@ -9,7 +9,7 @@ import { createMockExecutor, createMockFileSystemExecutor, createNoopExecutor, -} from '../../../../test-utils/mock-executors.js'; +} from '../../../../test-utils/mock-executors.ts'; import swiftPackageTest, { swift_package_testLogic } from '../swift_package_test.ts'; describe('swift_package_test plugin', () => { diff --git a/src/mcp/tools/swift-package/swift_package_build.ts b/src/mcp/tools/swift-package/swift_package_build.ts index 0dd4f734..51d14427 100644 --- a/src/mcp/tools/swift-package/swift_package_build.ts +++ b/src/mcp/tools/swift-package/swift_package_build.ts @@ -1,11 +1,11 @@ import { z } from 'zod'; import path from 'node:path'; -import { createErrorResponse } from '../../../utils/responses/index.js'; -import { log } from '../../../utils/logging/index.js'; -import type { CommandExecutor } from '../../../utils/execution/index.js'; -import { getDefaultCommandExecutor } from '../../../utils/execution/index.js'; -import { ToolResponse } from '../../../types/common.js'; -import { createTypedTool } from '../../../utils/typed-tool-factory.js'; +import { createErrorResponse } from '../../../utils/responses/index.ts'; +import { log } from '../../../utils/logging/index.ts'; +import type { CommandExecutor } from '../../../utils/execution/index.ts'; +import { getDefaultCommandExecutor } from '../../../utils/execution/index.ts'; +import { ToolResponse } from '../../../types/common.ts'; +import { createTypedTool } from '../../../utils/typed-tool-factory.ts'; // Define schema as ZodObject const swiftPackageBuildSchema = z.object({ diff --git a/src/mcp/tools/swift-package/swift_package_clean.ts b/src/mcp/tools/swift-package/swift_package_clean.ts index dfe380e1..f268dee2 100644 --- a/src/mcp/tools/swift-package/swift_package_clean.ts +++ b/src/mcp/tools/swift-package/swift_package_clean.ts @@ -1,11 +1,11 @@ import { z } from 'zod'; import path from 'node:path'; -import type { CommandExecutor } from '../../../utils/execution/index.js'; -import { getDefaultCommandExecutor } from '../../../utils/execution/index.js'; -import { createErrorResponse } from '../../../utils/responses/index.js'; -import { log } from '../../../utils/logging/index.js'; -import { ToolResponse } from '../../../types/common.js'; -import { createTypedTool } from '../../../utils/typed-tool-factory.js'; +import type { CommandExecutor } from '../../../utils/execution/index.ts'; +import { getDefaultCommandExecutor } from '../../../utils/execution/index.ts'; +import { createErrorResponse } from '../../../utils/responses/index.ts'; +import { log } from '../../../utils/logging/index.ts'; +import { ToolResponse } from '../../../types/common.ts'; +import { createTypedTool } from '../../../utils/typed-tool-factory.ts'; // Define schema as ZodObject const swiftPackageCleanSchema = z.object({ diff --git a/src/mcp/tools/swift-package/swift_package_list.ts b/src/mcp/tools/swift-package/swift_package_list.ts index adcb2737..f72fcf89 100644 --- a/src/mcp/tools/swift-package/swift_package_list.ts +++ b/src/mcp/tools/swift-package/swift_package_list.ts @@ -4,9 +4,9 @@ // Import the shared activeProcesses map from swift_package_run // This maintains the same behavior as the original implementation import { z } from 'zod'; -import { ToolResponse, createTextContent } from '../../../types/common.js'; -import { createTypedTool } from '../../../utils/typed-tool-factory.js'; -import { getDefaultCommandExecutor } from '../../../utils/command.js'; +import { ToolResponse, createTextContent } from '../../../types/common.ts'; +import { createTypedTool } from '../../../utils/typed-tool-factory.ts'; +import { getDefaultCommandExecutor } from '../../../utils/command.ts'; interface ProcessInfo { executableName?: string; diff --git a/src/mcp/tools/swift-package/swift_package_run.ts b/src/mcp/tools/swift-package/swift_package_run.ts index 7720c10b..e5ba55a9 100644 --- a/src/mcp/tools/swift-package/swift_package_run.ts +++ b/src/mcp/tools/swift-package/swift_package_run.ts @@ -1,12 +1,12 @@ import { z } from 'zod'; import path from 'node:path'; -import { createTextResponse, createErrorResponse } from '../../../utils/responses/index.js'; -import { log } from '../../../utils/logging/index.js'; -import type { CommandExecutor } from '../../../utils/execution/index.js'; -import { getDefaultCommandExecutor } from '../../../utils/execution/index.js'; -import { ToolResponse, createTextContent } from '../../../types/common.js'; -import { addProcess } from './active-processes.js'; -import { createTypedTool } from '../../../utils/typed-tool-factory.js'; +import { createTextResponse, createErrorResponse } from '../../../utils/responses/index.ts'; +import { log } from '../../../utils/logging/index.ts'; +import type { CommandExecutor } from '../../../utils/execution/index.ts'; +import { getDefaultCommandExecutor } from '../../../utils/execution/index.ts'; +import { ToolResponse, createTextContent } from '../../../types/common.ts'; +import { addProcess } from './active-processes.ts'; +import { createTypedTool } from '../../../utils/typed-tool-factory.ts'; // Define schema as ZodObject const swiftPackageRunSchema = z.object({ diff --git a/src/mcp/tools/swift-package/swift_package_stop.ts b/src/mcp/tools/swift-package/swift_package_stop.ts index 1197057a..be0f5602 100644 --- a/src/mcp/tools/swift-package/swift_package_stop.ts +++ b/src/mcp/tools/swift-package/swift_package_stop.ts @@ -1,7 +1,7 @@ import { z } from 'zod'; -import { createTextResponse, createErrorResponse } from '../../../utils/responses/index.js'; -import { getProcess, removeProcess, type ProcessInfo } from './active-processes.js'; -import { ToolResponse } from '../../../types/common.js'; +import { createTextResponse, createErrorResponse } from '../../../utils/responses/index.ts'; +import { getProcess, removeProcess, type ProcessInfo } from './active-processes.ts'; +import { ToolResponse } from '../../../types/common.ts'; // Define schema as ZodObject const swiftPackageStopSchema = z.object({ diff --git a/src/mcp/tools/swift-package/swift_package_test.ts b/src/mcp/tools/swift-package/swift_package_test.ts index e36e6c98..a5386fa1 100644 --- a/src/mcp/tools/swift-package/swift_package_test.ts +++ b/src/mcp/tools/swift-package/swift_package_test.ts @@ -1,11 +1,11 @@ import { z } from 'zod'; import path from 'node:path'; -import type { CommandExecutor } from '../../../utils/execution/index.js'; -import { getDefaultCommandExecutor } from '../../../utils/execution/index.js'; -import { createTextResponse, createErrorResponse } from '../../../utils/responses/index.js'; -import { log } from '../../../utils/logging/index.js'; -import { ToolResponse } from '../../../types/common.js'; -import { createTypedTool } from '../../../utils/typed-tool-factory.js'; +import type { CommandExecutor } from '../../../utils/execution/index.ts'; +import { getDefaultCommandExecutor } from '../../../utils/execution/index.ts'; +import { createTextResponse, createErrorResponse } from '../../../utils/responses/index.ts'; +import { log } from '../../../utils/logging/index.ts'; +import { ToolResponse } from '../../../types/common.ts'; +import { createTypedTool } from '../../../utils/typed-tool-factory.ts'; // Define schema as ZodObject const swiftPackageTestSchema = z.object({ diff --git a/src/mcp/tools/ui-testing/__tests__/button.test.ts b/src/mcp/tools/ui-testing/__tests__/button.test.ts index 1d25fcff..4d350b9a 100644 --- a/src/mcp/tools/ui-testing/__tests__/button.test.ts +++ b/src/mcp/tools/ui-testing/__tests__/button.test.ts @@ -4,7 +4,7 @@ import { describe, it, expect, beforeEach } from 'vitest'; import { z } from 'zod'; -import { createMockExecutor, createNoopExecutor } from '../../../../test-utils/mock-executors.js'; +import { createMockExecutor, createNoopExecutor } from '../../../../test-utils/mock-executors.ts'; import buttonPlugin, { buttonLogic } from '../button.ts'; describe('Button Plugin', () => { diff --git a/src/mcp/tools/ui-testing/__tests__/describe_ui.test.ts b/src/mcp/tools/ui-testing/__tests__/describe_ui.test.ts index cc3ce199..8004555e 100644 --- a/src/mcp/tools/ui-testing/__tests__/describe_ui.test.ts +++ b/src/mcp/tools/ui-testing/__tests__/describe_ui.test.ts @@ -4,7 +4,7 @@ import { describe, it, expect, beforeEach } from 'vitest'; import { z } from 'zod'; -import { createMockExecutor, createNoopExecutor } from '../../../../test-utils/mock-executors.js'; +import { createMockExecutor, createNoopExecutor } from '../../../../test-utils/mock-executors.ts'; import describeUIPlugin, { describe_uiLogic } from '../describe_ui.ts'; describe('Describe UI Plugin', () => { diff --git a/src/mcp/tools/ui-testing/__tests__/gesture.test.ts b/src/mcp/tools/ui-testing/__tests__/gesture.test.ts index 8fec1e0a..7a683f1a 100644 --- a/src/mcp/tools/ui-testing/__tests__/gesture.test.ts +++ b/src/mcp/tools/ui-testing/__tests__/gesture.test.ts @@ -8,7 +8,7 @@ import { createMockExecutor, createMockFileSystemExecutor, createNoopExecutor, -} from '../../../../test-utils/mock-executors.js'; +} from '../../../../test-utils/mock-executors.ts'; import gesturePlugin, { gestureLogic } from '../gesture.ts'; describe('Gesture Plugin', () => { diff --git a/src/mcp/tools/ui-testing/__tests__/key_press.test.ts b/src/mcp/tools/ui-testing/__tests__/key_press.test.ts index ce41cb06..26c28a21 100644 --- a/src/mcp/tools/ui-testing/__tests__/key_press.test.ts +++ b/src/mcp/tools/ui-testing/__tests__/key_press.test.ts @@ -8,8 +8,8 @@ import { createMockExecutor, createMockFileSystemExecutor, createNoopExecutor, -} from '../../../../test-utils/mock-executors.js'; -import keyPressPlugin, { key_pressLogic } from '../key_press.js'; +} from '../../../../test-utils/mock-executors.ts'; +import keyPressPlugin, { key_pressLogic } from '../key_press.ts'; describe('Key Press Plugin', () => { describe('Export Field Validation (Literal)', () => { diff --git a/src/mcp/tools/ui-testing/__tests__/key_sequence.test.ts b/src/mcp/tools/ui-testing/__tests__/key_sequence.test.ts index 9fc23004..1921c0e4 100644 --- a/src/mcp/tools/ui-testing/__tests__/key_sequence.test.ts +++ b/src/mcp/tools/ui-testing/__tests__/key_sequence.test.ts @@ -4,7 +4,7 @@ import { describe, it, expect } from 'vitest'; import { z } from 'zod'; -import { createMockExecutor, createNoopExecutor } from '../../../../test-utils/mock-executors.js'; +import { createMockExecutor, createNoopExecutor } from '../../../../test-utils/mock-executors.ts'; import keySequencePlugin, { key_sequenceLogic } from '../key_sequence.ts'; describe('Key Sequence Plugin', () => { diff --git a/src/mcp/tools/ui-testing/__tests__/long_press.test.ts b/src/mcp/tools/ui-testing/__tests__/long_press.test.ts index f0c0ee92..d14e730e 100644 --- a/src/mcp/tools/ui-testing/__tests__/long_press.test.ts +++ b/src/mcp/tools/ui-testing/__tests__/long_press.test.ts @@ -4,7 +4,7 @@ import { describe, it, expect } from 'vitest'; import { z } from 'zod'; -import { createMockExecutor } from '../../../../test-utils/mock-executors.js'; +import { createMockExecutor } from '../../../../test-utils/mock-executors.ts'; import longPressPlugin, { long_pressLogic } from '../long_press.ts'; describe('Long Press Plugin', () => { diff --git a/src/mcp/tools/ui-testing/__tests__/screenshot.test.ts b/src/mcp/tools/ui-testing/__tests__/screenshot.test.ts index 70cac7d3..4c94b77e 100644 --- a/src/mcp/tools/ui-testing/__tests__/screenshot.test.ts +++ b/src/mcp/tools/ui-testing/__tests__/screenshot.test.ts @@ -8,7 +8,7 @@ import { createMockExecutor, createMockFileSystemExecutor, createNoopExecutor, -} from '../../../../test-utils/mock-executors.js'; +} from '../../../../test-utils/mock-executors.ts'; import screenshotPlugin, { screenshotLogic } from '../screenshot.ts'; describe('Screenshot Plugin', () => { diff --git a/src/mcp/tools/ui-testing/__tests__/swipe.test.ts b/src/mcp/tools/ui-testing/__tests__/swipe.test.ts index 4e026455..e4fbf3f6 100644 --- a/src/mcp/tools/ui-testing/__tests__/swipe.test.ts +++ b/src/mcp/tools/ui-testing/__tests__/swipe.test.ts @@ -4,8 +4,8 @@ import { describe, it, expect } from 'vitest'; import { z } from 'zod'; -import { createMockExecutor, createNoopExecutor } from '../../../../test-utils/mock-executors.js'; -import { SystemError, DependencyError } from '../../../../utils/responses/index.js'; +import { createMockExecutor, createNoopExecutor } from '../../../../test-utils/mock-executors.ts'; +import { SystemError, DependencyError } from '../../../../utils/responses/index.ts'; // Import the plugin module to test import swipePlugin, { AxeHelpers, swipeLogic, SwipeParams } from '../swipe.ts'; diff --git a/src/mcp/tools/ui-testing/__tests__/tap.test.ts b/src/mcp/tools/ui-testing/__tests__/tap.test.ts index 2279f1aa..e52fe6f7 100644 --- a/src/mcp/tools/ui-testing/__tests__/tap.test.ts +++ b/src/mcp/tools/ui-testing/__tests__/tap.test.ts @@ -4,7 +4,7 @@ import { describe, it, expect, beforeEach } from 'vitest'; import { z } from 'zod'; -import { createMockExecutor } from '../../../../test-utils/mock-executors.js'; +import { createMockExecutor } from '../../../../test-utils/mock-executors.ts'; import tapPlugin, { AxeHelpers, tapLogic } from '../tap.ts'; diff --git a/src/mcp/tools/ui-testing/__tests__/touch.test.ts b/src/mcp/tools/ui-testing/__tests__/touch.test.ts index c1e0eb77..8efda141 100644 --- a/src/mcp/tools/ui-testing/__tests__/touch.test.ts +++ b/src/mcp/tools/ui-testing/__tests__/touch.test.ts @@ -5,7 +5,7 @@ import { describe, it, expect, beforeEach } from 'vitest'; import { z } from 'zod'; -import { createMockExecutor } from '../../../../test-utils/mock-executors.js'; +import { createMockExecutor } from '../../../../test-utils/mock-executors.ts'; import touchPlugin, { touchLogic } from '../touch.ts'; describe('Touch Plugin', () => { diff --git a/src/mcp/tools/ui-testing/__tests__/type_text.test.ts b/src/mcp/tools/ui-testing/__tests__/type_text.test.ts index f201d831..859f9466 100644 --- a/src/mcp/tools/ui-testing/__tests__/type_text.test.ts +++ b/src/mcp/tools/ui-testing/__tests__/type_text.test.ts @@ -8,7 +8,7 @@ import { createMockExecutor, createMockFileSystemExecutor, createNoopExecutor, -} from '../../../../test-utils/mock-executors.js'; +} from '../../../../test-utils/mock-executors.ts'; import typeTextPlugin, { type_textLogic } from '../type_text.ts'; // Mock axe helpers for dependency injection diff --git a/src/mcp/tools/ui-testing/button.ts b/src/mcp/tools/ui-testing/button.ts index 5ca026ff..acc1ccb9 100644 --- a/src/mcp/tools/ui-testing/button.ts +++ b/src/mcp/tools/ui-testing/button.ts @@ -1,16 +1,16 @@ import { z } from 'zod'; -import type { ToolResponse } from '../../../types/common.js'; -import { log } from '../../../utils/logging/index.js'; -import { createTextResponse, createErrorResponse } from '../../../utils/responses/index.js'; -import type { CommandExecutor } from '../../../utils/execution/index.js'; -import { getDefaultCommandExecutor } from '../../../utils/execution/index.js'; +import type { ToolResponse } from '../../../types/common.ts'; +import { log } from '../../../utils/logging/index.ts'; +import { createTextResponse, createErrorResponse } from '../../../utils/responses/index.ts'; +import type { CommandExecutor } from '../../../utils/execution/index.ts'; +import { getDefaultCommandExecutor } from '../../../utils/execution/index.ts'; import { createAxeNotAvailableResponse, getAxePath, getBundledAxeEnvironment, -} from '../../../utils/axe-helpers.js'; -import { DependencyError, AxeError, SystemError } from '../../../utils/errors.js'; -import { createTypedTool } from '../../../utils/typed-tool-factory.js'; +} from '../../../utils/axe-helpers.ts'; +import { DependencyError, AxeError, SystemError } from '../../../utils/errors.ts'; +import { createTypedTool } from '../../../utils/typed-tool-factory.ts'; // Define schema as ZodObject const buttonSchema = z.object({ diff --git a/src/mcp/tools/ui-testing/describe_ui.ts b/src/mcp/tools/ui-testing/describe_ui.ts index 2d32a229..c384e887 100644 --- a/src/mcp/tools/ui-testing/describe_ui.ts +++ b/src/mcp/tools/ui-testing/describe_ui.ts @@ -1,16 +1,16 @@ import { z } from 'zod'; -import { ToolResponse } from '../../../types/common.js'; -import { log } from '../../../utils/logging/index.js'; -import { createErrorResponse } from '../../../utils/responses/index.js'; -import { DependencyError, AxeError, SystemError } from '../../../utils/errors.js'; -import type { CommandExecutor } from '../../../utils/execution/index.js'; -import { getDefaultCommandExecutor } from '../../../utils/execution/index.js'; +import { ToolResponse } from '../../../types/common.ts'; +import { log } from '../../../utils/logging/index.ts'; +import { createErrorResponse } from '../../../utils/responses/index.ts'; +import { DependencyError, AxeError, SystemError } from '../../../utils/errors.ts'; +import type { CommandExecutor } from '../../../utils/execution/index.ts'; +import { getDefaultCommandExecutor } from '../../../utils/execution/index.ts'; import { createAxeNotAvailableResponse, getAxePath, getBundledAxeEnvironment, -} from '../../../utils/axe-helpers.js'; -import { createTypedTool } from '../../../utils/typed-tool-factory.js'; +} from '../../../utils/axe-helpers.ts'; +import { createTypedTool } from '../../../utils/typed-tool-factory.ts'; // Define schema as ZodObject const describeUiSchema = z.object({ diff --git a/src/mcp/tools/ui-testing/gesture.ts b/src/mcp/tools/ui-testing/gesture.ts index 8414e212..fface159 100644 --- a/src/mcp/tools/ui-testing/gesture.ts +++ b/src/mcp/tools/ui-testing/gesture.ts @@ -6,23 +6,23 @@ */ import { z } from 'zod'; -import { ToolResponse } from '../../../types/common.js'; -import { log } from '../../../utils/logging/index.js'; +import { ToolResponse } from '../../../types/common.ts'; +import { log } from '../../../utils/logging/index.ts'; import { createTextResponse, createErrorResponse, DependencyError, AxeError, SystemError, -} from '../../../utils/responses/index.js'; -import type { CommandExecutor } from '../../../utils/execution/index.js'; -import { getDefaultCommandExecutor } from '../../../utils/execution/index.js'; +} from '../../../utils/responses/index.ts'; +import type { CommandExecutor } from '../../../utils/execution/index.ts'; +import { getDefaultCommandExecutor } from '../../../utils/execution/index.ts'; import { createAxeNotAvailableResponse, getAxePath, getBundledAxeEnvironment, -} from '../../../utils/axe/index.js'; -import { createTypedTool } from '../../../utils/typed-tool-factory.js'; +} from '../../../utils/axe/index.ts'; +import { createTypedTool } from '../../../utils/typed-tool-factory.ts'; // Define schema as ZodObject const gestureSchema = z.object({ diff --git a/src/mcp/tools/ui-testing/key_press.ts b/src/mcp/tools/ui-testing/key_press.ts index 2c6f06b5..c386283d 100644 --- a/src/mcp/tools/ui-testing/key_press.ts +++ b/src/mcp/tools/ui-testing/key_press.ts @@ -1,21 +1,21 @@ import { z } from 'zod'; -import { ToolResponse } from '../../../types/common.js'; -import { log } from '../../../utils/logging/index.js'; +import { ToolResponse } from '../../../types/common.ts'; +import { log } from '../../../utils/logging/index.ts'; import { createTextResponse, createErrorResponse, DependencyError, AxeError, SystemError, -} from '../../../utils/responses/index.js'; -import type { CommandExecutor } from '../../../utils/execution/index.js'; -import { getDefaultCommandExecutor } from '../../../utils/execution/index.js'; +} from '../../../utils/responses/index.ts'; +import type { CommandExecutor } from '../../../utils/execution/index.ts'; +import { getDefaultCommandExecutor } from '../../../utils/execution/index.ts'; import { createAxeNotAvailableResponse, getAxePath, getBundledAxeEnvironment, -} from '../../../utils/axe/index.js'; -import { createTypedTool } from '../../../utils/typed-tool-factory.js'; +} from '../../../utils/axe/index.ts'; +import { createTypedTool } from '../../../utils/typed-tool-factory.ts'; // Define schema as ZodObject const keyPressSchema = z.object({ diff --git a/src/mcp/tools/ui-testing/key_sequence.ts b/src/mcp/tools/ui-testing/key_sequence.ts index 856f4b9b..f2904373 100644 --- a/src/mcp/tools/ui-testing/key_sequence.ts +++ b/src/mcp/tools/ui-testing/key_sequence.ts @@ -5,23 +5,23 @@ */ import { z } from 'zod'; -import { ToolResponse } from '../../../types/common.js'; -import { log } from '../../../utils/logging/index.js'; +import { ToolResponse } from '../../../types/common.ts'; +import { log } from '../../../utils/logging/index.ts'; import { createTextResponse, createErrorResponse, DependencyError, AxeError, SystemError, -} from '../../../utils/responses/index.js'; -import type { CommandExecutor } from '../../../utils/execution/index.js'; -import { getDefaultCommandExecutor } from '../../../utils/execution/index.js'; +} from '../../../utils/responses/index.ts'; +import type { CommandExecutor } from '../../../utils/execution/index.ts'; +import { getDefaultCommandExecutor } from '../../../utils/execution/index.ts'; import { createAxeNotAvailableResponse, getAxePath, getBundledAxeEnvironment, -} from '../../../utils/axe/index.js'; -import { createTypedTool } from '../../../utils/typed-tool-factory.js'; +} from '../../../utils/axe/index.ts'; +import { createTypedTool } from '../../../utils/typed-tool-factory.ts'; // Define schema as ZodObject const keySequenceSchema = z.object({ diff --git a/src/mcp/tools/ui-testing/long_press.ts b/src/mcp/tools/ui-testing/long_press.ts index f8b8187f..fbd7ce0c 100644 --- a/src/mcp/tools/ui-testing/long_press.ts +++ b/src/mcp/tools/ui-testing/long_press.ts @@ -6,23 +6,23 @@ */ import { z } from 'zod'; -import { ToolResponse } from '../../../types/common.js'; -import { log } from '../../../utils/logging/index.js'; +import { ToolResponse } from '../../../types/common.ts'; +import { log } from '../../../utils/logging/index.ts'; import { createTextResponse, createErrorResponse, DependencyError, AxeError, SystemError, -} from '../../../utils/responses/index.js'; -import type { CommandExecutor } from '../../../utils/execution/index.js'; -import { getDefaultCommandExecutor } from '../../../utils/execution/index.js'; +} from '../../../utils/responses/index.ts'; +import type { CommandExecutor } from '../../../utils/execution/index.ts'; +import { getDefaultCommandExecutor } from '../../../utils/execution/index.ts'; import { createAxeNotAvailableResponse, getAxePath, getBundledAxeEnvironment, -} from '../../../utils/axe/index.js'; -import { createTypedTool } from '../../../utils/typed-tool-factory.js'; +} from '../../../utils/axe/index.ts'; +import { createTypedTool } from '../../../utils/typed-tool-factory.ts'; // Define schema as ZodObject const longPressSchema = z.object({ diff --git a/src/mcp/tools/ui-testing/screenshot.ts b/src/mcp/tools/ui-testing/screenshot.ts index bc125a4b..adcb52eb 100644 --- a/src/mcp/tools/ui-testing/screenshot.ts +++ b/src/mcp/tools/ui-testing/screenshot.ts @@ -5,15 +5,15 @@ import * as path from 'path'; import { tmpdir } from 'os'; import { z } from 'zod'; import { v4 as uuidv4 } from 'uuid'; -import { ToolResponse, createImageContent } from '../../../types/common.js'; -import { log } from '../../../utils/logging/index.js'; -import { createErrorResponse, SystemError } from '../../../utils/responses/index.js'; -import type { CommandExecutor, FileSystemExecutor } from '../../../utils/execution/index.js'; +import { ToolResponse, createImageContent } from '../../../types/common.ts'; +import { log } from '../../../utils/logging/index.ts'; +import { createErrorResponse, SystemError } from '../../../utils/responses/index.ts'; +import type { CommandExecutor, FileSystemExecutor } from '../../../utils/execution/index.ts'; import { getDefaultFileSystemExecutor, getDefaultCommandExecutor, -} from '../../../utils/execution/index.js'; -import { createTypedTool } from '../../../utils/typed-tool-factory.js'; +} from '../../../utils/execution/index.ts'; +import { createTypedTool } from '../../../utils/typed-tool-factory.ts'; const LOG_PREFIX = '[Screenshot]'; diff --git a/src/mcp/tools/ui-testing/swipe.ts b/src/mcp/tools/ui-testing/swipe.ts index c16fb980..2b99635b 100644 --- a/src/mcp/tools/ui-testing/swipe.ts +++ b/src/mcp/tools/ui-testing/swipe.ts @@ -5,18 +5,18 @@ */ import { z } from 'zod'; -import { ToolResponse } from '../../../types/common.js'; -import { log } from '../../../utils/logging/index.js'; -import { createTextResponse, createErrorResponse } from '../../../utils/responses/index.js'; -import { DependencyError, AxeError, SystemError } from '../../../utils/errors.js'; -import type { CommandExecutor } from '../../../utils/execution/index.js'; -import { getDefaultCommandExecutor } from '../../../utils/execution/index.js'; +import { ToolResponse } from '../../../types/common.ts'; +import { log } from '../../../utils/logging/index.ts'; +import { createTextResponse, createErrorResponse } from '../../../utils/responses/index.ts'; +import { DependencyError, AxeError, SystemError } from '../../../utils/errors.ts'; +import type { CommandExecutor } from '../../../utils/execution/index.ts'; +import { getDefaultCommandExecutor } from '../../../utils/execution/index.ts'; import { createAxeNotAvailableResponse, getAxePath, getBundledAxeEnvironment, -} from '../../../utils/axe-helpers.js'; -import { createTypedTool } from '../../../utils/typed-tool-factory.js'; +} from '../../../utils/axe-helpers.ts'; +import { createTypedTool } from '../../../utils/typed-tool-factory.ts'; // Define schema as ZodObject const swipeSchema = z.object({ diff --git a/src/mcp/tools/ui-testing/tap.ts b/src/mcp/tools/ui-testing/tap.ts index 9c47beaa..15f7aaf6 100644 --- a/src/mcp/tools/ui-testing/tap.ts +++ b/src/mcp/tools/ui-testing/tap.ts @@ -1,16 +1,16 @@ import { z } from 'zod'; -import type { ToolResponse } from '../../../types/common.js'; -import { log } from '../../../utils/logging/index.js'; -import { createTextResponse, createErrorResponse } from '../../../utils/responses/index.js'; -import type { CommandExecutor } from '../../../utils/execution/index.js'; -import { getDefaultCommandExecutor } from '../../../utils/execution/index.js'; +import type { ToolResponse } from '../../../types/common.ts'; +import { log } from '../../../utils/logging/index.ts'; +import { createTextResponse, createErrorResponse } from '../../../utils/responses/index.ts'; +import type { CommandExecutor } from '../../../utils/execution/index.ts'; +import { getDefaultCommandExecutor } from '../../../utils/execution/index.ts'; import { createAxeNotAvailableResponse, getAxePath, getBundledAxeEnvironment, -} from '../../../utils/axe-helpers.js'; -import { DependencyError, AxeError, SystemError } from '../../../utils/errors.js'; -import { createTypedTool } from '../../../utils/typed-tool-factory.js'; +} from '../../../utils/axe-helpers.ts'; +import { DependencyError, AxeError, SystemError } from '../../../utils/errors.ts'; +import { createTypedTool } from '../../../utils/typed-tool-factory.ts'; export interface AxeHelpers { getAxePath: () => string | null; diff --git a/src/mcp/tools/ui-testing/touch.ts b/src/mcp/tools/ui-testing/touch.ts index 6eaa97ca..410812f4 100644 --- a/src/mcp/tools/ui-testing/touch.ts +++ b/src/mcp/tools/ui-testing/touch.ts @@ -6,18 +6,18 @@ */ import { z } from 'zod'; -import { log } from '../../../utils/logging/index.js'; -import { createTextResponse, createErrorResponse } from '../../../utils/responses/index.js'; -import { DependencyError, AxeError, SystemError } from '../../../utils/errors.js'; -import type { CommandExecutor } from '../../../utils/execution/index.js'; -import { getDefaultCommandExecutor } from '../../../utils/execution/index.js'; +import { log } from '../../../utils/logging/index.ts'; +import { createTextResponse, createErrorResponse } from '../../../utils/responses/index.ts'; +import { DependencyError, AxeError, SystemError } from '../../../utils/errors.ts'; +import type { CommandExecutor } from '../../../utils/execution/index.ts'; +import { getDefaultCommandExecutor } from '../../../utils/execution/index.ts'; import { createAxeNotAvailableResponse, getAxePath, getBundledAxeEnvironment, -} from '../../../utils/axe-helpers.js'; -import { ToolResponse } from '../../../types/common.js'; -import { createTypedTool } from '../../../utils/typed-tool-factory.js'; +} from '../../../utils/axe-helpers.ts'; +import { ToolResponse } from '../../../types/common.ts'; +import { createTypedTool } from '../../../utils/typed-tool-factory.ts'; // Define schema as ZodObject const touchSchema = z.object({ diff --git a/src/mcp/tools/ui-testing/type_text.ts b/src/mcp/tools/ui-testing/type_text.ts index 4f36ab6b..45562d9a 100644 --- a/src/mcp/tools/ui-testing/type_text.ts +++ b/src/mcp/tools/ui-testing/type_text.ts @@ -6,18 +6,18 @@ */ import { z } from 'zod'; -import { ToolResponse } from '../../../types/common.js'; -import { log } from '../../../utils/logging/index.js'; -import { createTextResponse, createErrorResponse } from '../../../utils/responses/index.js'; -import { DependencyError, AxeError, SystemError } from '../../../utils/errors.js'; -import type { CommandExecutor } from '../../../utils/execution/index.js'; -import { getDefaultCommandExecutor } from '../../../utils/execution/index.js'; +import { ToolResponse } from '../../../types/common.ts'; +import { log } from '../../../utils/logging/index.ts'; +import { createTextResponse, createErrorResponse } from '../../../utils/responses/index.ts'; +import { DependencyError, AxeError, SystemError } from '../../../utils/errors.ts'; +import type { CommandExecutor } from '../../../utils/execution/index.ts'; +import { getDefaultCommandExecutor } from '../../../utils/execution/index.ts'; import { createAxeNotAvailableResponse, getAxePath, getBundledAxeEnvironment, -} from '../../../utils/axe-helpers.js'; -import { createTypedTool } from '../../../utils/typed-tool-factory.js'; +} from '../../../utils/axe-helpers.ts'; +import { createTypedTool } from '../../../utils/typed-tool-factory.ts'; const LOG_PREFIX = '[AXe]'; diff --git a/src/mcp/tools/utilities/__tests__/clean.test.ts b/src/mcp/tools/utilities/__tests__/clean.test.ts index 9d37eaeb..3812b855 100644 --- a/src/mcp/tools/utilities/__tests__/clean.test.ts +++ b/src/mcp/tools/utilities/__tests__/clean.test.ts @@ -1,6 +1,6 @@ import { describe, it, expect } from 'vitest'; import tool, { cleanLogic } from '../clean.ts'; -import { createMockExecutor } from '../../../../test-utils/mock-executors.js'; +import { createMockExecutor } from '../../../../test-utils/mock-executors.ts'; describe('clean (unified) tool', () => { it('exports correct name/description/schema/handler', () => { diff --git a/src/mcp/tools/utilities/clean.ts b/src/mcp/tools/utilities/clean.ts index cf9a070a..5e0fa9a5 100644 --- a/src/mcp/tools/utilities/clean.ts +++ b/src/mcp/tools/utilities/clean.ts @@ -6,13 +6,13 @@ */ import { z } from 'zod'; -import { createTypedTool } from '../../../utils/typed-tool-factory.js'; -import type { CommandExecutor } from '../../../utils/execution/index.js'; -import { getDefaultCommandExecutor } from '../../../utils/execution/index.js'; -import { executeXcodeBuildCommand } from '../../../utils/build/index.js'; -import { ToolResponse, SharedBuildParams, XcodePlatform } from '../../../types/common.js'; -import { createErrorResponse } from '../../../utils/responses/index.js'; -import { nullifyEmptyStrings } from '../../../utils/schema-helpers.js'; +import { createTypedTool } from '../../../utils/typed-tool-factory.ts'; +import type { CommandExecutor } from '../../../utils/execution/index.ts'; +import { getDefaultCommandExecutor } from '../../../utils/execution/index.ts'; +import { executeXcodeBuildCommand } from '../../../utils/build/index.ts'; +import { ToolResponse, SharedBuildParams, XcodePlatform } from '../../../types/common.ts'; +import { createErrorResponse } from '../../../utils/responses/index.ts'; +import { nullifyEmptyStrings } from '../../../utils/schema-helpers.ts'; // Unified schema: XOR between projectPath and workspacePath, sharing common options const baseOptions = { diff --git a/src/server/server.ts b/src/server/server.ts index cd4bc8ce..e0e929e3 100644 --- a/src/server/server.ts +++ b/src/server/server.ts @@ -14,8 +14,8 @@ import { McpServer } from '@camsoft/mcp-sdk/server/mcp.js'; import { StdioServerTransport } from '@camsoft/mcp-sdk/server/stdio.js'; -import { log } from '../utils/logger.js'; -import { version } from '../version.js'; +import { log } from '../utils/logger.ts'; +import { version } from '../version.ts'; import * as Sentry from '@sentry/node'; /** diff --git a/src/utils/__tests__/simulator-utils.test.ts b/src/utils/__tests__/simulator-utils.test.ts index 3d29a1bf..bdd3b140 100644 --- a/src/utils/__tests__/simulator-utils.test.ts +++ b/src/utils/__tests__/simulator-utils.test.ts @@ -1,6 +1,6 @@ import { describe, it, expect } from 'vitest'; -import { determineSimulatorUuid } from '../simulator-utils.js'; -import { createMockExecutor } from '../../test-utils/mock-executors.js'; +import { determineSimulatorUuid } from '../simulator-utils.ts'; +import { createMockExecutor } from '../../test-utils/mock-executors.ts'; describe('determineSimulatorUuid', () => { const mockSimulatorListOutput = JSON.stringify({ diff --git a/src/utils/__tests__/typed-tool-factory.test.ts b/src/utils/__tests__/typed-tool-factory.test.ts index 71e38b19..5667443f 100644 --- a/src/utils/__tests__/typed-tool-factory.test.ts +++ b/src/utils/__tests__/typed-tool-factory.test.ts @@ -4,9 +4,9 @@ import { describe, it, expect } from 'vitest'; import { z } from 'zod'; -import { createTypedTool } from '../typed-tool-factory.js'; -import { createMockExecutor } from '../../test-utils/mock-executors.js'; -import { ToolResponse } from '../../types/common.js'; +import { createTypedTool } from '../typed-tool-factory.ts'; +import { createMockExecutor } from '../../test-utils/mock-executors.ts'; +import { ToolResponse } from '../../types/common.ts'; // Test schema and types const testSchema = z.object({ diff --git a/src/utils/axe-helpers.ts b/src/utils/axe-helpers.ts index e1a3c03e..5326e2b5 100644 --- a/src/utils/axe-helpers.ts +++ b/src/utils/axe-helpers.ts @@ -8,8 +8,8 @@ import { existsSync } from 'fs'; import { dirname, join } from 'path'; import { fileURLToPath } from 'url'; -import { createTextResponse } from './validation.js'; -import { ToolResponse } from '../types/common.js'; +import { createTextResponse } from './validation.ts'; +import { ToolResponse } from '../types/common.ts'; // Get bundled AXe path - always use the bundled version for consistency const __filename = fileURLToPath(import.meta.url); diff --git a/src/utils/axe/index.ts b/src/utils/axe/index.ts index 03446c8e..b3e39cc0 100644 --- a/src/utils/axe/index.ts +++ b/src/utils/axe/index.ts @@ -3,4 +3,4 @@ export { getAxePath, getBundledAxeEnvironment, areAxeToolsAvailable, -} from '../axe-helpers.js'; +} from '../axe-helpers.ts'; diff --git a/src/utils/build-utils.ts b/src/utils/build-utils.ts index dc22a2ab..545923cf 100644 --- a/src/utils/build-utils.ts +++ b/src/utils/build-utils.ts @@ -17,11 +17,11 @@ * while adding build-specific behavior, formatting, and error handling. */ -import { log } from './logger.js'; -import { XcodePlatform, constructDestinationString } from './xcode.js'; -import { CommandExecutor } from './command.js'; -import { ToolResponse, SharedBuildParams, PlatformBuildOptions } from '../types/common.js'; -import { createTextResponse, consolidateContentForClaudeCode } from './validation.js'; +import { log } from './logger.ts'; +import { XcodePlatform, constructDestinationString } from './xcode.ts'; +import { CommandExecutor } from './command.ts'; +import { ToolResponse, SharedBuildParams, PlatformBuildOptions } from '../types/common.ts'; +import { createTextResponse, consolidateContentForClaudeCode } from './validation.ts'; import { isXcodemakeEnabled, isXcodemakeAvailable, @@ -29,7 +29,7 @@ import { executeMakeCommand, doesMakefileExist, doesMakeLogFileExist, -} from './xcodemake.js'; +} from './xcodemake.ts'; import path from 'path'; /** diff --git a/src/utils/command.ts b/src/utils/command.ts index d4ca8deb..9e746ca1 100644 --- a/src/utils/command.ts +++ b/src/utils/command.ts @@ -12,13 +12,13 @@ import { spawn } from 'child_process'; import { existsSync } from 'fs'; import { tmpdir as osTmpdir } from 'os'; -import { log } from './logger.js'; +import { log } from './logger.ts'; import { FileSystemExecutor } from './FileSystemExecutor.ts'; import { CommandExecutor, CommandResponse } from './CommandExecutor.ts'; // Re-export types for backward compatibility -export { CommandExecutor, CommandResponse } from './CommandExecutor.js'; -export { FileSystemExecutor } from './FileSystemExecutor.js'; +export { CommandExecutor, CommandResponse } from './CommandExecutor.ts'; +export { FileSystemExecutor } from './FileSystemExecutor.ts'; /** * Default executor implementation using spawn (current production behavior) diff --git a/src/utils/environment.ts b/src/utils/environment.ts index ade5cb27..c610dd4b 100644 --- a/src/utils/environment.ts +++ b/src/utils/environment.ts @@ -6,7 +6,7 @@ */ import { execSync } from 'child_process'; -import { log } from './logger.js'; +import { log } from './logger.ts'; /** * Interface for environment detection abstraction diff --git a/src/utils/errors.ts b/src/utils/errors.ts index ec182fd0..359399cb 100644 --- a/src/utils/errors.ts +++ b/src/utils/errors.ts @@ -1,4 +1,4 @@ -import { ToolResponse } from '../types/common.js'; +import { ToolResponse } from '../types/common.ts'; /** * Error Utilities - Type-safe error hierarchy for the application diff --git a/src/utils/execution/index.ts b/src/utils/execution/index.ts index e44f1fdd..8a8f8c42 100644 --- a/src/utils/execution/index.ts +++ b/src/utils/execution/index.ts @@ -2,8 +2,8 @@ * Focused execution facade. * Prefer importing from 'utils/execution/index.js' instead of the legacy utils barrel. */ -export { getDefaultCommandExecutor, getDefaultFileSystemExecutor } from '../command.js'; +export { getDefaultCommandExecutor, getDefaultFileSystemExecutor } from '../command.ts'; // Types -export type { CommandExecutor, CommandResponse } from '../CommandExecutor.js'; -export type { FileSystemExecutor } from '../FileSystemExecutor.js'; +export type { CommandExecutor, CommandResponse } from '../CommandExecutor.ts'; +export type { FileSystemExecutor } from '../FileSystemExecutor.ts'; diff --git a/src/utils/index.ts b/src/utils/index.ts index 2e832340..3bedfc5d 100644 --- a/src/utils/index.ts +++ b/src/utils/index.ts @@ -1,21 +1,21 @@ /** * This barrel will be removed in a future release after a deprecation period. */ -export * from './logger.js'; -export * from './command.js'; -export * from './CommandExecutor.js'; -export * from './FileSystemExecutor.js'; -export * from './validation.js'; -export * from './errors.js'; -export * from './build-utils.js'; -export * from './xcode.js'; -export * from './axe-helpers.js'; -export * from './log_capture.js'; -export * from './template-manager.js'; -export * from './test-common.js'; -export * from './xcodemake.js'; -export * from './environment.js'; -export * from './tool-registry.js'; -export * from '../version.js'; -export * from '../core/dynamic-tools.js'; -export * from '../core/plugin-registry.js'; +export * from './logger.ts'; +export * from './command.ts'; +export * from './CommandExecutor.ts'; +export * from './FileSystemExecutor.ts'; +export * from './validation.ts'; +export * from './errors.ts'; +export * from './build-utils.ts'; +export * from './xcode.ts'; +export * from './axe-helpers.ts'; +export * from './log_capture.ts'; +export * from './template-manager.ts'; +export * from './test-common.ts'; +export * from './xcodemake.ts'; +export * from './environment.ts'; +export * from './tool-registry.ts'; +export * from '../version.ts'; +export * from '../core/dynamic-tools.ts'; +export * from '../core/plugin-registry.ts'; diff --git a/src/utils/log-capture/index.ts b/src/utils/log-capture/index.ts index f6d19d43..986c525a 100644 --- a/src/utils/log-capture/index.ts +++ b/src/utils/log-capture/index.ts @@ -1 +1 @@ -export { startLogCapture, stopLogCapture } from '../log_capture.js'; +export { startLogCapture, stopLogCapture } from '../log_capture.ts'; diff --git a/src/utils/log_capture.ts b/src/utils/log_capture.ts index 6becf9f7..dadfb4bf 100644 --- a/src/utils/log_capture.ts +++ b/src/utils/log_capture.ts @@ -3,8 +3,8 @@ import * as path from 'path'; import * as os from 'os'; import type { ChildProcess } from 'child_process'; import { v4 as uuidv4 } from 'uuid'; -import { log } from '../utils/logger.js'; -import { CommandExecutor, getDefaultCommandExecutor } from './command.js'; +import { log } from '../utils/logger.ts'; +import { CommandExecutor, getDefaultCommandExecutor } from './command.ts'; /** * Log file retention policy: diff --git a/src/utils/logging/index.ts b/src/utils/logging/index.ts index 928b33b2..eaa25e7e 100644 --- a/src/utils/logging/index.ts +++ b/src/utils/logging/index.ts @@ -2,4 +2,4 @@ * Focused logging facade. * Prefer importing from 'utils/logging/index.js' instead of the legacy utils barrel. */ -export { log } from '../logger.js'; +export { log } from '../logger.ts'; diff --git a/src/utils/plugin-registry/index.ts b/src/utils/plugin-registry/index.ts index 4706700b..f3010767 100644 --- a/src/utils/plugin-registry/index.ts +++ b/src/utils/plugin-registry/index.ts @@ -1,2 +1,2 @@ -export { loadWorkflowGroups, loadPlugins } from '../../core/plugin-registry.js'; -export { getEnabledWorkflows } from '../../core/dynamic-tools.js'; +export { loadWorkflowGroups, loadPlugins } from '../../core/plugin-registry.ts'; +export { getEnabledWorkflows } from '../../core/dynamic-tools.ts'; diff --git a/src/utils/responses/index.ts b/src/utils/responses/index.ts index 35b89543..ef740dcc 100644 --- a/src/utils/responses/index.ts +++ b/src/utils/responses/index.ts @@ -2,14 +2,14 @@ * Focused responses facade. * Prefer importing from 'utils/responses/index.js' instead of the legacy utils barrel. */ -export { createTextResponse } from '../validation.js'; +export { createTextResponse } from '../validation.ts'; export { createErrorResponse, DependencyError, AxeError, SystemError, ValidationError, -} from '../errors.js'; +} from '../errors.ts'; // Types -export type { ToolResponse } from '../../types/common.js'; +export type { ToolResponse } from '../../types/common.ts'; diff --git a/src/utils/sentry.ts b/src/utils/sentry.ts index daf436b5..77cd33c5 100644 --- a/src/utils/sentry.ts +++ b/src/utils/sentry.ts @@ -6,7 +6,7 @@ */ import * as Sentry from '@sentry/node'; -import { version } from '../version.js'; +import { version } from '../version.ts'; import { execSync } from 'child_process'; // Inlined system info functions to avoid circular dependencies diff --git a/src/utils/simulator-utils.ts b/src/utils/simulator-utils.ts index 7bd3cb52..f595c49f 100644 --- a/src/utils/simulator-utils.ts +++ b/src/utils/simulator-utils.ts @@ -2,10 +2,10 @@ * Simulator utility functions for name to UUID resolution */ -import type { CommandExecutor } from './execution/index.js'; -import { ToolResponse } from '../types/common.js'; -import { log } from './logging/index.js'; -import { createErrorResponse } from './responses/index.js'; +import type { CommandExecutor } from './execution/index.ts'; +import { ToolResponse } from '../types/common.ts'; +import { log } from './logging/index.ts'; +import { createErrorResponse } from './responses/index.ts'; /** * UUID regex pattern to check if a string looks like a UUID diff --git a/src/utils/template-manager.ts b/src/utils/template-manager.ts index f5d0b371..f5e3e128 100644 --- a/src/utils/template-manager.ts +++ b/src/utils/template-manager.ts @@ -1,9 +1,9 @@ import { join } from 'path'; import { tmpdir } from 'os'; import { randomUUID } from 'crypto'; -import { log } from './logger.js'; -import { iOSTemplateVersion, macOSTemplateVersion } from '../version.js'; -import { CommandExecutor } from './command.js'; +import { log } from './logger.ts'; +import { iOSTemplateVersion, macOSTemplateVersion } from '../version.ts'; +import { CommandExecutor } from './command.ts'; import { FileSystemExecutor } from './FileSystemExecutor.ts'; /** diff --git a/src/utils/template/index.ts b/src/utils/template/index.ts index f2a04682..926b729e 100644 --- a/src/utils/template/index.ts +++ b/src/utils/template/index.ts @@ -1 +1 @@ -export { TemplateManager } from '../template-manager.js'; +export { TemplateManager } from '../template-manager.ts'; diff --git a/src/utils/test-common.ts b/src/utils/test-common.ts index 7f8b8a8d..1eeb6135 100644 --- a/src/utils/test-common.ts +++ b/src/utils/test-common.ts @@ -17,12 +17,12 @@ import { exec } from 'child_process'; import { mkdtemp, rm } from 'fs/promises'; import { tmpdir } from 'os'; import { join } from 'path'; -import { log } from './logger.js'; -import { XcodePlatform } from './xcode.js'; -import { executeXcodeBuildCommand } from './build-utils.js'; -import { createTextResponse, consolidateContentForClaudeCode } from './validation.js'; -import { ToolResponse } from '../types/common.js'; -import { CommandExecutor, getDefaultCommandExecutor } from './command.js'; +import { log } from './logger.ts'; +import { XcodePlatform } from './xcode.ts'; +import { executeXcodeBuildCommand } from './build-utils.ts'; +import { createTextResponse, consolidateContentForClaudeCode } from './validation.ts'; +import { ToolResponse } from '../types/common.ts'; +import { CommandExecutor, getDefaultCommandExecutor } from './command.ts'; /** * Type definition for test summary structure from xcresulttool diff --git a/src/utils/test/index.ts b/src/utils/test/index.ts index 04548484..30ff6fcb 100644 --- a/src/utils/test/index.ts +++ b/src/utils/test/index.ts @@ -1 +1 @@ -export { handleTestLogic } from '../test-common.js'; +export { handleTestLogic } from '../test-common.ts'; diff --git a/src/utils/tool-registry.ts b/src/utils/tool-registry.ts index ea2b33d8..69bf974f 100644 --- a/src/utils/tool-registry.ts +++ b/src/utils/tool-registry.ts @@ -1,7 +1,7 @@ import { McpServer, RegisteredTool } from '@camsoft/mcp-sdk/server/mcp.js'; -import { loadPlugins } from '../core/plugin-registry.js'; -import { ToolResponse } from '../types/common.js'; -import { log } from './logger.js'; +import { loadPlugins } from '../core/plugin-registry.ts'; +import { ToolResponse } from '../types/common.ts'; +import { log } from './logger.ts'; // Global registry to track registered tools for cleanup const toolRegistry = new Map(); diff --git a/src/utils/typed-tool-factory.ts b/src/utils/typed-tool-factory.ts index b971336a..1eddf16a 100644 --- a/src/utils/typed-tool-factory.ts +++ b/src/utils/typed-tool-factory.ts @@ -10,9 +10,9 @@ */ import { z } from 'zod'; -import { ToolResponse } from '../types/common.js'; -import type { CommandExecutor } from './execution/index.js'; -import { createErrorResponse } from './responses/index.js'; +import { ToolResponse } from '../types/common.ts'; +import type { CommandExecutor } from './execution/index.ts'; +import { createErrorResponse } from './responses/index.ts'; /** * Creates a type-safe tool handler that validates parameters at runtime diff --git a/src/utils/validation.ts b/src/utils/validation.ts index 2153e833..4c2a7f84 100644 --- a/src/utils/validation.ts +++ b/src/utils/validation.ts @@ -21,10 +21,10 @@ */ import * as fs from 'fs'; -import { log } from './logger.js'; -import { ToolResponse, ValidationResult } from '../types/common.js'; +import { log } from './logger.ts'; +import { ToolResponse, ValidationResult } from '../types/common.ts'; import { FileSystemExecutor } from './FileSystemExecutor.ts'; -import { getDefaultEnvironmentDetector } from './environment.js'; +import { getDefaultEnvironmentDetector } from './environment.ts'; /** * Creates a text response with the given message diff --git a/src/utils/validation/index.ts b/src/utils/validation/index.ts index 337b1304..8b1303dd 100644 --- a/src/utils/validation/index.ts +++ b/src/utils/validation/index.ts @@ -2,4 +2,4 @@ * Focused validation facade. * Prefer importing from 'utils/validation/index.js' instead of the legacy utils barrel. */ -export * from '../validation.js'; +export * from '../validation.ts'; diff --git a/src/utils/version/index.ts b/src/utils/version/index.ts index 282bf15c..e5e1336f 100644 --- a/src/utils/version/index.ts +++ b/src/utils/version/index.ts @@ -1 +1 @@ -export { version } from '../../version.js'; +export { version } from '../../version.ts'; diff --git a/src/utils/xcode.ts b/src/utils/xcode.ts index 9dc663fd..b400ac27 100644 --- a/src/utils/xcode.ts +++ b/src/utils/xcode.ts @@ -12,8 +12,8 @@ * which build upon these core functions to provide higher-level abstractions. */ -import { log } from './logger.js'; -import { XcodePlatform } from '../types/common.js'; +import { log } from './logger.ts'; +import { XcodePlatform } from '../types/common.ts'; // Re-export XcodePlatform for use in other modules export { XcodePlatform }; diff --git a/src/utils/xcodemake.ts b/src/utils/xcodemake.ts index 1e369243..00a46f39 100644 --- a/src/utils/xcodemake.ts +++ b/src/utils/xcodemake.ts @@ -13,8 +13,8 @@ * - Auto-downloading xcodemake if enabled but not found */ -import { log } from './logger.js'; -import { CommandResponse, getDefaultCommandExecutor } from './command.js'; +import { log } from './logger.ts'; +import { CommandResponse, getDefaultCommandExecutor } from './command.ts'; import { existsSync, readdirSync } from 'fs'; import * as path from 'path'; import * as os from 'os'; diff --git a/src/utils/xcodemake/index.ts b/src/utils/xcodemake/index.ts index a5d061a9..cb24f210 100644 --- a/src/utils/xcodemake/index.ts +++ b/src/utils/xcodemake/index.ts @@ -1 +1 @@ -export { isXcodemakeEnabled, isXcodemakeAvailable, doesMakefileExist } from '../xcodemake.js'; +export { isXcodemakeEnabled, isXcodemakeAvailable, doesMakefileExist } from '../xcodemake.ts'; From 21c65b96821124f2122a67eb48c21d0ba0462cb0 Mon Sep 17 00:00:00 2001 From: Cameron Cooke Date: Sat, 16 Aug 2025 23:22:33 +0100 Subject: [PATCH 4/8] fix: add missing build facade and update gitignore to be more specific - Change gitignore pattern from 'build/' to '/build/' to only ignore root build artifacts - Add src/utils/build/index.ts focused facade that was accidentally gitignored - This fixes CI build failures where files import from utils/build/index.ts --- .gitignore | 2 +- src/utils/build/index.ts | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) create mode 100644 src/utils/build/index.ts diff --git a/.gitignore b/.gitignore index d691ee70..5a7c598b 100644 --- a/.gitignore +++ b/.gitignore @@ -6,7 +6,7 @@ yarn-error.log* # TypeScript build output dist/ -build/ +/build/ *.tsbuildinfo # Auto-generated files diff --git a/src/utils/build/index.ts b/src/utils/build/index.ts new file mode 100644 index 00000000..61a6c70b --- /dev/null +++ b/src/utils/build/index.ts @@ -0,0 +1 @@ +export { executeXcodeBuildCommand } from '../build-utils.ts'; \ No newline at end of file From b7e9fab24510922ffe6fe88b108aed39f1815b3f Mon Sep 17 00:00:00 2001 From: Cameron Cooke Date: Sat, 16 Aug 2025 23:30:23 +0100 Subject: [PATCH 5/8] refactor: complete focused facade architecture implementation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Summary - Finalize the focused facade architecture by fixing remaining inconsistent imports - Remove the deprecated utils/index.ts barrel file completely - Ensure all imports use proper focused facades throughout the codebase ## Changes Made ### Import Consistency Fixes - Fix build_device.ts to use utils/build/index.ts instead of direct build-utils.ts import - Fix test-common.ts to use utils/build/index.ts for executeXcodeBuildCommand import - Update test files to use utils/responses/index.ts for SystemError imports instead of barrel - Update scaffold project files to use proper focused facades for dynamic imports ### Architecture Completion - **REMOVED**: src/utils/index.ts - deprecated barrel file completely deleted - All imports now consistently use focused facades (build/, responses/, execution/, etc.) - No more barrel imports anywhere in the codebase ## Technical Benefits - **Improved tree-shaking**: Bundlers can better eliminate unused code - **Clearer dependencies**: Import paths explicitly show what functionality is needed - **Prevention of circular dependencies**: Focused facades reduce coupling risks - **Better performance**: Eliminates loading of unused modules during startup - **Architectural consistency**: Single pattern enforced across entire codebase ## Validation - ✅ TypeScript compilation: No errors - ✅ ESLint: Only 1 minor unrelated warning - ✅ Prettier: All files properly formatted - ✅ Tests: 1046 tests passing - ✅ Build: Successful compilation with all tools working The focused facade architecture is now fully implemented and enforced. --- src/mcp/tools/device/build_device.ts | 2 +- .../__tests__/scaffold_macos_project.test.ts | 2 +- .../scaffold_ios_project.ts | 3 +-- .../simulator/__tests__/screenshot.test.ts | 2 +- .../ui-testing/__tests__/screenshot.test.ts | 2 +- src/utils/index.ts | 21 ------------------- src/utils/test-common.ts | 2 +- 7 files changed, 6 insertions(+), 28 deletions(-) delete mode 100644 src/utils/index.ts diff --git a/src/mcp/tools/device/build_device.ts b/src/mcp/tools/device/build_device.ts index 11af16a5..d838ef1b 100644 --- a/src/mcp/tools/device/build_device.ts +++ b/src/mcp/tools/device/build_device.ts @@ -7,7 +7,7 @@ import { z } from 'zod'; import { ToolResponse, XcodePlatform } from '../../../types/common.ts'; -import { executeXcodeBuildCommand } from '../../../utils/build-utils.ts'; +import { executeXcodeBuildCommand } from '../../../utils/build/index.ts'; import type { CommandExecutor } from '../../../utils/execution/index.ts'; import { getDefaultCommandExecutor } from '../../../utils/execution/index.ts'; import { createTypedTool } from '../../../utils/typed-tool-factory.ts'; diff --git a/src/mcp/tools/project-scaffolding/__tests__/scaffold_macos_project.test.ts b/src/mcp/tools/project-scaffolding/__tests__/scaffold_macos_project.test.ts index d489f395..06624662 100644 --- a/src/mcp/tools/project-scaffolding/__tests__/scaffold_macos_project.test.ts +++ b/src/mcp/tools/project-scaffolding/__tests__/scaffold_macos_project.test.ts @@ -192,7 +192,7 @@ describe('scaffold_macos_project plugin', () => { // Restore original TemplateManager for command generation tests const { TemplateManager: OriginalTemplateManager } = await import( - '../../../../utils/index.js' + '../../../../utils/template/index.ts' ); (TemplateManager as any).getTemplatePath = OriginalTemplateManager.getTemplatePath; (TemplateManager as any).cleanup = OriginalTemplateManager.cleanup; diff --git a/src/mcp/tools/project-scaffolding/scaffold_ios_project.ts b/src/mcp/tools/project-scaffolding/scaffold_ios_project.ts index 29726790..72940499 100644 --- a/src/mcp/tools/project-scaffolding/scaffold_ios_project.ts +++ b/src/mcp/tools/project-scaffolding/scaffold_ios_project.ts @@ -456,9 +456,8 @@ async function scaffoldProject( // Get template path from TemplateManager let templatePath; try { - // Import the default command executor if not provided + // Use the default command executor if not provided if (!commandExecutor) { - const { getDefaultCommandExecutor } = await import('../../../utils/index.js'); commandExecutor = getDefaultCommandExecutor(); } diff --git a/src/mcp/tools/simulator/__tests__/screenshot.test.ts b/src/mcp/tools/simulator/__tests__/screenshot.test.ts index 6a108264..244c445f 100644 --- a/src/mcp/tools/simulator/__tests__/screenshot.test.ts +++ b/src/mcp/tools/simulator/__tests__/screenshot.test.ts @@ -11,6 +11,7 @@ import { createMockFileSystemExecutor, createCommandMatchingMockExecutor, } from '../../../../test-utils/mock-executors.ts'; +import { SystemError } from '../../../../utils/responses/index.ts'; import screenshotPlugin, { screenshotLogic } from '../../ui-testing/screenshot.ts'; describe('screenshot plugin', () => { @@ -444,7 +445,6 @@ describe('screenshot plugin', () => { }); it('should handle SystemError exceptions', async () => { - const { SystemError } = await import('../../../../utils/index.js'); const mockExecutor = createMockExecutor(new SystemError('System error occurred')); const mockPathDeps = { diff --git a/src/mcp/tools/ui-testing/__tests__/screenshot.test.ts b/src/mcp/tools/ui-testing/__tests__/screenshot.test.ts index 4c94b77e..78a10e21 100644 --- a/src/mcp/tools/ui-testing/__tests__/screenshot.test.ts +++ b/src/mcp/tools/ui-testing/__tests__/screenshot.test.ts @@ -9,6 +9,7 @@ import { createMockFileSystemExecutor, createNoopExecutor, } from '../../../../test-utils/mock-executors.ts'; +import { SystemError } from '../../../../utils/responses/index.ts'; import screenshotPlugin, { screenshotLogic } from '../screenshot.ts'; describe('Screenshot Plugin', () => { @@ -388,7 +389,6 @@ describe('Screenshot Plugin', () => { it('should handle SystemError from command execution', async () => { const mockExecutor = async () => { - const SystemError = (await import('../../../../utils/index.js')).SystemError; throw new SystemError('System error occurred'); }; diff --git a/src/utils/index.ts b/src/utils/index.ts deleted file mode 100644 index 3bedfc5d..00000000 --- a/src/utils/index.ts +++ /dev/null @@ -1,21 +0,0 @@ -/** - * This barrel will be removed in a future release after a deprecation period. - */ -export * from './logger.ts'; -export * from './command.ts'; -export * from './CommandExecutor.ts'; -export * from './FileSystemExecutor.ts'; -export * from './validation.ts'; -export * from './errors.ts'; -export * from './build-utils.ts'; -export * from './xcode.ts'; -export * from './axe-helpers.ts'; -export * from './log_capture.ts'; -export * from './template-manager.ts'; -export * from './test-common.ts'; -export * from './xcodemake.ts'; -export * from './environment.ts'; -export * from './tool-registry.ts'; -export * from '../version.ts'; -export * from '../core/dynamic-tools.ts'; -export * from '../core/plugin-registry.ts'; diff --git a/src/utils/test-common.ts b/src/utils/test-common.ts index 1eeb6135..68051635 100644 --- a/src/utils/test-common.ts +++ b/src/utils/test-common.ts @@ -19,7 +19,7 @@ import { tmpdir } from 'os'; import { join } from 'path'; import { log } from './logger.ts'; import { XcodePlatform } from './xcode.ts'; -import { executeXcodeBuildCommand } from './build-utils.ts'; +import { executeXcodeBuildCommand } from './build/index.ts'; import { createTextResponse, consolidateContentForClaudeCode } from './validation.ts'; import { ToolResponse } from '../types/common.ts'; import { CommandExecutor, getDefaultCommandExecutor } from './command.ts'; From 8a6be6850cf850fca0bc531620224b8e776ef8ac Mon Sep 17 00:00:00 2001 From: Cameron Cooke Date: Sun, 17 Aug 2025 09:26:00 +0100 Subject: [PATCH 6/8] fix: switch from vmThreads to threads pool to resolve CI "module is already linked" errors MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Root Cause Analysis CI was failing with 78 "module is already linked" errors due to: - Node.js 24.x + Vitest vmThreads pool triggering ESM linker bug - Tests still import Sentry via production dependency chain: test → tool → utils/build → utils/command → utils/logger → @sentry/node - vmThreads pool has known issues with native modules like Sentry ## Solution: Switch to threads pool - Changed pool from 'vmThreads' to 'threads' - Increased maxThreads from 1 to 4 for better performance - threads pool handles native modules better than vmThreads - Fixes the Node.js ESM linker issue while improving performance ## Evidence from dependency graph analysis Using madge revealed the exact import chain still bringing Sentry into tests: build_device.test.ts → build_device.ts → utils/build/index.ts → utils/build-utils.ts → utils/command.ts → utils/logger.ts → @sentry/node ## Benefits - Resolves CI "module is already linked" errors - Better performance (threads faster than vmThreads) - More robust handling of native modules - Maintains all existing test functionality (1046 tests pass) ## Testing - All tests pass locally with threads pool - TypeScript compilation and linting clean - No behavioral changes to test execution --- vitest.config.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/vitest.config.ts b/vitest.config.ts index 6f09012d..7736bd83 100644 --- a/vitest.config.ts +++ b/vitest.config.ts @@ -21,10 +21,10 @@ export default defineConfig({ '**/__pycache__/**', '**/dist/**' ], - pool: 'vmThreads', + pool: 'threads', poolOptions: { - vmThreads: { - maxThreads: 1 + threads: { + maxThreads: 4 } }, env: { From 94ae3ee28d8887e4f551547f9df7f797d8679f26 Mon Sep 17 00:00:00 2001 From: Cameron Cooke Date: Sun, 17 Aug 2025 10:15:59 +0100 Subject: [PATCH 7/8] Use consistent env name --- src/utils/logger.ts | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/utils/logger.ts b/src/utils/logger.ts index 94a72315..6bb86141 100644 --- a/src/utils/logger.ts +++ b/src/utils/logger.ts @@ -20,7 +20,8 @@ import { createRequire } from 'node:module'; // Note: Removed "import * as Sentry from '@sentry/node'" to prevent native module loading at import time -const SENTRY_ENABLED = process.env.SENTRY_DISABLED !== 'true'; +const SENTRY_ENABLED = + process.env.SENTRY_DISABLED !== 'true' && process.env.XCODEBUILDMCP_SENTRY_DISABLED !== 'true'; function isTestEnv(): boolean { return ( @@ -58,7 +59,11 @@ function withSentry(cb: (s: SentryModule) => void): void { } if (!SENTRY_ENABLED) { - log('info', 'Sentry disabled due to SENTRY_DISABLED environment variable'); + if (process.env.SENTRY_DISABLED === 'true') { + log('info', 'Sentry disabled due to SENTRY_DISABLED environment variable'); + } else if (process.env.XCODEBUILDMCP_SENTRY_DISABLED === 'true') { + log('info', 'Sentry disabled due to XCODEBUILDMCP_SENTRY_DISABLED environment variable'); + } } /** From 16c5db691c393adf5792c48924709d0c65426a86 Mon Sep 17 00:00:00 2001 From: Cameron Cooke Date: Sun, 17 Aug 2025 10:18:31 +0100 Subject: [PATCH 8/8] Fix security concerns --- src/mcp/tools/discovery/discover_tools.ts | 30 ++++++++++++++----- .../scaffold_ios_project.ts | 4 +-- src/utils/command.ts | 9 +++--- 3 files changed, 27 insertions(+), 16 deletions(-) diff --git a/src/mcp/tools/discovery/discover_tools.ts b/src/mcp/tools/discovery/discover_tools.ts index aac02774..985ece46 100644 --- a/src/mcp/tools/discovery/discover_tools.ts +++ b/src/mcp/tools/discovery/discover_tools.ts @@ -21,14 +21,28 @@ interface LLMConfig { } // Default LLM configuration with environment variable overrides -const getLLMConfig = (): LLMConfig => ({ - maxTokens: process.env.XCODEBUILDMCP_LLM_MAX_TOKENS - ? parseInt(process.env.XCODEBUILDMCP_LLM_MAX_TOKENS, 10) - : 200, - temperature: process.env.XCODEBUILDMCP_LLM_TEMPERATURE - ? parseFloat(process.env.XCODEBUILDMCP_LLM_TEMPERATURE) - : undefined, -}); +const getLLMConfig = (): LLMConfig => { + let maxTokens = 200; // default + if (process.env.XCODEBUILDMCP_LLM_MAX_TOKENS) { + const parsed = parseInt(process.env.XCODEBUILDMCP_LLM_MAX_TOKENS, 10); + if (!isNaN(parsed) && parsed > 0) { + maxTokens = parsed; + } + } + + let temperature: number | undefined; + if (process.env.XCODEBUILDMCP_LLM_TEMPERATURE) { + const parsed = parseFloat(process.env.XCODEBUILDMCP_LLM_TEMPERATURE); + if (!isNaN(parsed) && parsed >= 0 && parsed <= 2) { + temperature = parsed; + } + } + + return { + maxTokens, + temperature, + }; +}; /** * Sanitizes user input to prevent injection attacks and ensure safe LLM usage diff --git a/src/mcp/tools/project-scaffolding/scaffold_ios_project.ts b/src/mcp/tools/project-scaffolding/scaffold_ios_project.ts index 72940499..4e7bfb18 100644 --- a/src/mcp/tools/project-scaffolding/scaffold_ios_project.ts +++ b/src/mcp/tools/project-scaffolding/scaffold_ios_project.ts @@ -457,9 +457,7 @@ async function scaffoldProject( let templatePath; try { // Use the default command executor if not provided - if (!commandExecutor) { - commandExecutor = getDefaultCommandExecutor(); - } + commandExecutor ??= getDefaultCommandExecutor(); templatePath = await TemplateManager.getTemplatePath( platform, diff --git a/src/utils/command.ts b/src/utils/command.ts index 9e746ca1..05ecf63e 100644 --- a/src/utils/command.ts +++ b/src/utils/command.ts @@ -43,11 +43,10 @@ async function defaultExecutor( // For shell execution, we need to format as ['sh', '-c', 'full command string'] const commandString = command .map((arg) => { - // If the argument contains spaces or special characters, wrap it in quotes - // Ensure existing quotes are escaped - if (/[\s,"'=]/.test(arg) && !/^".*"$/.test(arg)) { - // Check if needs quoting and isn't already quoted - return `"${arg.replace(/(["\\])/g, '\\$1')}"`; // Escape existing quotes and backslashes + // Shell metacharacters that require quoting: space, quotes, equals, dollar, backticks, semicolons, pipes, etc. + if (/[\s,"'=$`;&|<>(){}[\]\\*?~]/.test(arg) && !/^".*"$/.test(arg)) { + // Escape all quotes and backslashes, then wrap in double quotes + return `"${arg.replace(/(["\\])/g, '\\$1')}"`; } return arg; })