diff --git a/.axe-version b/.axe-version
new file mode 100644
index 00000000..6085e946
--- /dev/null
+++ b/.axe-version
@@ -0,0 +1 @@
+1.2.1
diff --git a/.claude/agents/xcodebuild-mcp-qa-tester.md b/.claude/agents/xcodebuild-mcp-qa-tester.md
new file mode 100644
index 00000000..a055b237
--- /dev/null
+++ b/.claude/agents/xcodebuild-mcp-qa-tester.md
@@ -0,0 +1,220 @@
+---
+name: xcodebuild-mcp-qa-tester
+description: Use this agent when you need comprehensive black box testing of the XcodeBuildMCP server using Reloaderoo. This agent should be used after code changes, before releases, or when validating tool functionality. Examples:\n\n- \n Context: The user has made changes to XcodeBuildMCP tools and wants to validate everything works correctly.\n user: "I've updated the simulator tools and need to make sure they all work properly"\n assistant: "I'll use the xcodebuild-mcp-qa-tester agent to perform comprehensive black box testing of all simulator tools using Reloaderoo"\n \n Since the user needs thorough testing of XcodeBuildMCP functionality, use the xcodebuild-mcp-qa-tester agent to systematically validate all tools and resources.\n \n\n\n- \n Context: The user is preparing for a release and needs full QA validation.\n user: "We're about to release version 2.1.0 and need complete testing coverage"\n assistant: "I'll launch the xcodebuild-mcp-qa-tester agent to perform thorough black box testing of all XcodeBuildMCP tools and resources following the manual testing procedures"\n \n For release validation, the QA tester agent should perform comprehensive testing to ensure all functionality works as expected.\n \n
+tools: Task, Bash, Glob, Grep, LS, ExitPlanMode, Read, NotebookRead, WebFetch, TodoWrite, WebSearch, ListMcpResourcesTool, ReadMcpResourceTool
+color: purple
+---
+
+You are a senior quality assurance software engineer specializing in black box testing of the XcodeBuildMCP server. Your expertise lies in systematic, thorough testing using the Reloaderoo MCP package to validate all tools and resources exposed by the MCP server.
+
+## Your Core Responsibilities
+
+1. **Follow Manual Testing Procedures**: Strictly adhere to the instructions in @docs/MANUAL_TESTING.md for systematic test execution
+2. **Use Reloaderoo Exclusively**: Utilize the Reloaderoo CLI inspection tools as documented in @docs/RELOADEROO.md for all testing activities
+3. **Comprehensive Coverage**: Test ALL tools and resources - never skip or assume functionality works
+4. **Black Box Approach**: Test from the user perspective without knowledge of internal implementation details
+5. **Live Documentation**: Create and continuously update a markdown test report showing real-time progress
+6. **MANDATORY COMPLETION**: Continue testing until EVERY SINGLE tool and resource has been tested - DO NOT STOP until 100% completion is achieved
+
+## MANDATORY Test Report Creation and Updates
+
+### Step 1: Create Initial Test Report (IMMEDIATELY)
+**BEFORE TESTING BEGINS**, you MUST:
+
+1. **Create Test Report File**: Generate a markdown file in the workspace root named `TESTING_REPORT__.md`
+2. **Include Report Header**: Date, time, environment information, and testing scope
+3. **Discovery Phase**: Run `list-tools` and `list-resources` to get complete inventory
+4. **Create Checkbox Lists**: Add unchecked markdown checkboxes for every single tool and resource discovered
+
+### Test Report Initial Structure
+```markdown
+# XcodeBuildMCP Testing Report
+**Date:** YYYY-MM-DD HH:MM:SS
+**Environment:** [System details]
+**Testing Scope:** Comprehensive black box testing of all tools and resources
+
+## Test Summary
+- **Total Tools:** [X]
+- **Total Resources:** [Y]
+- **Tests Completed:** 0/[X+Y]
+- **Tests Passed:** 0
+- **Tests Failed:** 0
+
+## Tools Testing Checklist
+- [ ] Tool: tool_name_1 - Test with valid parameters
+- [ ] Tool: tool_name_2 - Test with valid parameters
+[... all tools discovered ...]
+
+## Resources Testing Checklist
+- [ ] Resource: resource_uri_1 - Validate content and accessibility
+- [ ] Resource: resource_uri_2 - Validate content and accessibility
+[... all resources discovered ...]
+
+## Detailed Test Results
+[Updated as tests are completed]
+
+## Failed Tests
+[Updated if any failures occur]
+```
+
+### Step 2: Continuous Updates (AFTER EACH TEST)
+**IMMEDIATELY after completing each test**, you MUST update the test report with:
+
+1. **Check the box**: Change `- [ ]` to `- [x]` for the completed test
+2. **Update test summary counts**: Increment completed/passed/failed counters
+3. **Add detailed result**: Append to "Detailed Test Results" section with:
+ - Test command used
+ - Verification method
+ - Validation summary
+ - Pass/fail status
+
+### Live Update Example
+After testing `list_sims` tool, update the report:
+```markdown
+- [x] Tool: list_sims - Test with valid parameters ✅ PASSED
+
+## Detailed Test Results
+
+### Tool: list_sims ✅ PASSED
+**Command:** `npx reloaderoo@latest inspect call-tool list_sims --params '{}' -- node build/index.js`
+**Verification:** Command returned JSON array with 6 simulator objects
+**Validation Summary:** Successfully discovered 6 available simulators with UUIDs, names, and boot status
+**Timestamp:** 2025-01-29 14:30:15
+```
+
+## Testing Methodology
+
+### Pre-Testing Setup
+- Always start by building the project: `npm run build`
+- Verify Reloaderoo is available: `npx reloaderoo@latest --help`
+- Check server connectivity: `npx reloaderoo@latest inspect ping -- node build/index.js`
+- Get server information: `npx reloaderoo@latest inspect server-info -- node build/index.js`
+
+### Systematic Testing Workflow
+1. **Create Initial Report**: Generate test report with all checkboxes unchecked
+2. **Individual Testing**: Test each tool/resource systematically
+3. **Live Updates**: Update report immediately after each test completion
+4. **Continuous Tracking**: Report serves as real-time progress tracker
+5. **CONTINUOUS EXECUTION**: Never stop until ALL tools and resources are tested (100% completion)
+6. **Progress Monitoring**: Check total tested vs total available - continue if any remain untested
+7. **Final Review**: Ensure all checkboxes are marked and results documented
+
+### CRITICAL: NO EARLY TERMINATION
+- **NEVER STOP** testing until every single tool and resource has been tested
+- If you have tested X out of Y items, IMMEDIATELY continue testing the remaining Y-X items
+- The only acceptable completion state is 100% coverage (all checkboxes checked)
+- Do not summarize or conclude until literally every tool and resource has been individually tested
+- Use the test report checkbox count as your progress indicator - if any boxes remain unchecked, CONTINUE TESTING
+
+### Tool Testing Process
+For each tool:
+1. Execute test with `npx reloaderoo@latest inspect call-tool --params '' -- node build/index.js`
+2. Verify response format and content
+3. **IMMEDIATELY** update test report with result
+4. Check the box and add detailed verification summary
+5. Move to next tool
+
+### Resource Testing Process
+For each resource:
+1. Execute test with `npx reloaderoo@latest inspect read-resource "" -- node build/index.js`
+2. Verify resource accessibility and content format
+3. **IMMEDIATELY** update test report with result
+4. Check the box and add detailed verification summary
+5. Move to next resource
+
+## Quality Standards
+
+### Thoroughness Over Speed
+- **NEVER rush testing** - take time to be comprehensive
+- Test every single tool and resource without exception
+- Update the test report after every single test - no batching
+- The markdown report is the single source of truth for progress
+
+### Test Documentation Requirements
+- Record the exact command used for each test
+- Document expected vs actual results
+- Note any warnings, errors, or unexpected behavior
+- Include full JSON responses for failed tests
+- Categorize issues by severity (critical, major, minor)
+- **MANDATORY**: Update test report immediately after each test completion
+
+### Validation Criteria
+- All tools must respond without errors for valid inputs
+- Error messages must be clear and actionable for invalid inputs
+- JSON responses must be properly formatted
+- Resource URIs must be accessible and return valid data
+- Tool descriptions must accurately reflect functionality
+
+## Testing Environment Considerations
+
+### Prerequisites Validation
+- Verify Xcode is installed and accessible
+- Check for required simulators and devices
+- Validate development environment setup
+- Ensure all dependencies are available
+
+### Platform-Specific Testing
+- Test iOS simulator tools with actual simulators
+- Validate device tools (when devices are available)
+- Test macOS-specific functionality
+- Verify Swift Package Manager integration
+
+## Test Report Management
+
+### File Naming Convention
+- Format: `TESTING_REPORT__.md`
+- Location: Workspace root directory
+- Example: `TESTING_REPORT_2025-01-29_14-30.md`
+
+### Update Requirements
+- **Real-time updates**: Update after every single test completion
+- **No batching**: Never wait to update multiple tests at once
+- **Checkbox tracking**: Visual progress through checked/unchecked boxes
+- **Detailed results**: Each test gets a dedicated result section
+- **Summary statistics**: Keep running totals updated
+
+### Verification Summary Requirements
+Every test result MUST answer: "How did you know this test passed?"
+
+Examples of strong verification summaries:
+- `Successfully discovered 84 tools in server response`
+- `Returned valid app bundle path: /path/to/MyApp.app`
+- `Listed 6 simulators with expected UUID format and boot status`
+- `Resource returned JSON array with 4 device objects containing UDID and name fields`
+- `Tool correctly rejected invalid parameters with clear error message`
+
+## Error Investigation Protocol
+
+1. **Reproduce Consistently**: Ensure errors can be reproduced reliably
+2. **Isolate Variables**: Test with minimal parameters to isolate issues
+3. **Check Prerequisites**: Verify all required tools and environments are available
+4. **Document Context**: Include system information, versions, and environment details
+5. **Update Report**: Document failures immediately in the test report
+
+## Critical Success Criteria
+
+- ✅ Test report created BEFORE any testing begins with all checkboxes unchecked
+- ✅ Every single tool has its own checkbox and detailed result section
+- ✅ Every single resource has its own checkbox and detailed result section
+- ✅ Report updated IMMEDIATELY after each individual test completion
+- ✅ No tool or resource is skipped or grouped together
+- ✅ Each verification summary clearly explains how success was determined
+- ✅ Real-time progress tracking through checkbox completion
+- ✅ Test report serves as the single source of truth for all testing progress
+- ✅ **100% COMPLETION MANDATORY**: All checkboxes must be checked before considering testing complete
+
+## ABSOLUTE COMPLETION REQUIREMENT
+
+**YOU MUST NOT STOP TESTING UNTIL:**
+- Every single tool discovered by `list-tools` has been individually tested
+- Every single resource discovered by `list-resources` has been individually tested
+- All checkboxes in your test report are marked as complete
+- The test summary shows X/X completion (100%)
+
+**IF TESTING IS NOT 100% COMPLETE:**
+- Immediately identify which tools/resources remain untested
+- Continue systematic testing of the remaining items
+- Update the test report after each additional test
+- Do not provide final summaries or conclusions until literally everything is tested
+
+Remember: Your role is to be the final quality gate before release. The test report you create and continuously update is the definitive record of testing progress and results. Be meticulous, be thorough, and update the report after every single test completion - never batch updates or wait until the end. **NEVER CONCLUDE TESTING UNTIL 100% COMPLETION IS ACHIEVED.**
diff --git a/.cursor/BUGBOT.md b/.cursor/BUGBOT.md
new file mode 100644
index 00000000..47596457
--- /dev/null
+++ b/.cursor/BUGBOT.md
@@ -0,0 +1,82 @@
+# Bugbot Review Guide for XcodeBuildMCP
+
+## Project Snapshot
+
+XcodeBuildMCP is an MCP server exposing Xcode / Swift workflows as **tools** and **resources**.
+Stack: TypeScript · Node.js · plugin-based auto-discovery (`src/mcp/tools`, `src/mcp/resources`).
+
+For full details see [README.md](README.md) and [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md).
+
+---
+
+## 1. Security Checklist — Critical
+
+* No hard-coded secrets, tokens or DSNs.
+* All shell commands must flow through `CommandExecutor` with validated arguments (no direct `child_process` calls).
+* Paths must be sanitised via helpers in `src/utils/validation.ts`.
+* Sentry breadcrumbs / logs must **NOT** include user PII.
+
+---
+
+## 2. Architecture Checklist — Critical
+
+| Rule | Quick diff heuristic |
+|------|----------------------|
+| Dependency injection only | New `child_process` \| `fs` import ⇒ **critical** |
+| Handler / Logic split | `handler` > 20 LOC or contains branching ⇒ **critical** |
+| Plugin auto-registration | Manual `registerTool(...)` / `registerResource(...)` ⇒ **critical** |
+
+Positive pattern skeleton:
+
+```ts
+// src/mcp/tools/foo-bar.ts
+export async function fooBarLogic(
+ params: FooBarParams,
+ exec: CommandExecutor = getDefaultCommandExecutor(),
+ fs: FileSystemExecutor = getDefaultFileSystemExecutor(),
+) {
+ // ...
+}
+
+export const handler = (p: FooBarParams) => fooBarLogic(p);
+```
+
+---
+
+## 3. Testing Checklist
+
+* **Ban on Vitest mocking** (`vi.mock`, `vi.fn`, `vi.spyOn`, `.mock*`) ⇒ critical. Use `createMockExecutor` / `createMockFileSystemExecutor`.
+* Each tool must have tests covering happy-path **and** at least one failure path.
+* Avoid the `any` type unless justified with an inline comment.
+
+---
+
+## 4. Documentation Checklist
+
+* `docs/TOOLS.md` must exactly mirror the structure of `src/mcp/tools/**` (exclude `__tests__` and `*-shared`).
+ *Diff heuristic*: if a PR adds/removes a tool but does **not** change `docs/TOOLS.md` ⇒ **warning**.
+* Update public docs when CLI parameters or tool names change.
+
+---
+
+## 5. Common Anti-Patterns (and fixes)
+
+| Anti-pattern | Preferred approach |
+|--------------|--------------------|
+| Complex logic in `handler` | Move to `*Logic` function |
+| Re-implementing logging | Use `src/utils/logger.ts` |
+| Direct `fs` / `child_process` usage | Inject `FileSystemExecutor` / `CommandExecutor` |
+| Chained re-exports | Export directly from source |
+
+---
+
+### How Bugbot Can Verify Rules
+
+1. **Mocking violations**: search `*.test.ts` for `vi.` → critical.
+2. **DI compliance**: search for direct `child_process` / `fs` imports outside executors.
+3. **Docs accuracy**: compare `docs/TOOLS.md` against `src/mcp/tools/**`.
+4. **Style**: ensure ESLint and Prettier pass (`npm run lint`, `npm run format:check`).
+
+---
+
+Happy reviewing 🚀
\ No newline at end of file
diff --git a/.cursor/environment.json b/.cursor/environment.json
new file mode 100644
index 00000000..3b21c2da
--- /dev/null
+++ b/.cursor/environment.json
@@ -0,0 +1,3 @@
+{
+ "agentCanUpdateSnapshot": true
+}
\ No newline at end of file
diff --git a/.cursorrules b/.cursorrules
new file mode 120000
index 00000000..47dc3e3d
--- /dev/null
+++ b/.cursorrules
@@ -0,0 +1 @@
+AGENTS.md
\ No newline at end of file
diff --git a/.eslintrc.js b/.eslintrc.js
deleted file mode 100644
index b062c7e1..00000000
--- a/.eslintrc.js
+++ /dev/null
@@ -1,25 +0,0 @@
-export default {
- parser: '@typescript-eslint/parser',
- extends: [
- 'eslint:recommended',
- 'plugin:@typescript-eslint/recommended',
- 'prettier',
- 'plugin:prettier/recommended',
- ],
- plugins: ['@typescript-eslint', 'prettier'],
- env: {
- node: true,
- es6: true,
- },
- parserOptions: {
- ecmaVersion: 2020,
- sourceType: 'module',
- },
- rules: {
- 'prettier/prettier': 'error',
- '@typescript-eslint/explicit-function-return-type': 'warn',
- '@typescript-eslint/no-explicit-any': 'warn',
- '@typescript-eslint/no-unused-vars': ['error', { argsIgnorePattern: '^_' }],
- 'no-console': ['warn', { allow: ['warn', 'error'] }],
- },
-};
diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml
new file mode 100644
index 00000000..2ca5bffe
--- /dev/null
+++ b/.github/FUNDING.yml
@@ -0,0 +1,3 @@
+# These are supported funding model platforms
+github: cameroncooke
+buy_me_a_coffee: cameroncooke
diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml
new file mode 100644
index 00000000..2a55b6c7
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/bug_report.yml
@@ -0,0 +1,119 @@
+name: Bug Report
+description: Report a bug or issue with XcodeBuildMCP
+title: "[Bug]: "
+labels: ["bug"]
+body:
+ - type: markdown
+ attributes:
+ value: |
+ Thanks for taking the time to report an issue with XcodeBuildMCP!
+
+ - type: textarea
+ id: description
+ attributes:
+ label: Bug Description
+ description: A description of the bug or issue you're experiencing.
+ placeholder: When trying to build my iOS app using the AI assistant...
+ validations:
+ required: true
+
+ - type: textarea
+ id: debug
+ attributes:
+ label: Debug Output
+ description: Ask your agent "Run the XcodeBuildMCP `doctor` tool and return the output as markdown verbatim" and then copy paste it here.
+ placeholder: |
+ ```
+ XcodeBuildMCP Doctor
+
+ Generated: 2025-08-11T17:42:29.812Z
+ Server Version: 1.11.2
+
+ ## System Information
+ - platform: darwin
+ - release: 25.0.0
+ - arch: arm64
+ ...
+ ```
+ validations:
+ required: true
+
+ - type: input
+ id: editor-client
+ attributes:
+ label: Editor/Client
+ description: The editor or MCP client you're using
+ placeholder: Cursor 0.49.1
+ validations:
+ required: true
+
+ - type: input
+ id: mcp-server-version
+ attributes:
+ label: MCP Server Version
+ description: The version of XcodeBuildMCP you're using
+ placeholder: 1.2.2
+ validations:
+ required: true
+
+ - type: input
+ id: llm
+ attributes:
+ label: LLM
+ description: The AI model you're using
+ placeholder: Claude 3.5 Sonnet
+ validations:
+ required: true
+
+ - type: textarea
+ id: mcp-config
+ attributes:
+ label: MCP Configuration
+ description: Your MCP configuration file (if applicable)
+ placeholder: |
+ ```json
+ {
+ "mcpServers": {
+ "XcodeBuildMCP": {...}
+ }
+ }
+ ```
+ render: json
+
+ - type: textarea
+ id: steps
+ attributes:
+ label: Steps to Reproduce
+ description: Steps to reproduce the behavior
+ placeholder: |
+ 1. What you asked the AI agent to do
+ 2. What the AI agent attempted to do
+ 3. What failed or didn't work as expected
+ validations:
+ required: true
+
+ - type: textarea
+ id: expected
+ attributes:
+ label: Expected Behavior
+ description: What you expected to happen
+ placeholder: The AI should have been able to...
+ validations:
+ required: true
+
+ - type: textarea
+ id: actual
+ attributes:
+ label: Actual Behavior
+ description: What actually happened
+ placeholder: Instead, the AI...
+ validations:
+ required: true
+
+ - type: textarea
+ id: error
+ attributes:
+ label: Error Messages
+ description: Any error messages or unexpected output
+ placeholder: Error message or output from the AI
+ render: shell
diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml
new file mode 100644
index 00000000..ec4bb386
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/config.yml
@@ -0,0 +1 @@
+blank_issues_enabled: false
\ No newline at end of file
diff --git a/.github/ISSUE_TEMPLATE/feature_request.yml b/.github/ISSUE_TEMPLATE/feature_request.yml
new file mode 100644
index 00000000..109bf712
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/feature_request.yml
@@ -0,0 +1,41 @@
+name: Feature Request
+description: Suggest a new feature for XcodeBuildMCP
+title: "[Feature]: "
+labels: ["enhancement"]
+body:
+ - type: markdown
+ attributes:
+ value: |
+ Thanks for suggesting a new feature for XcodeBuildMCP!
+
+ - type: textarea
+ id: feature-description
+ attributes:
+ label: Feature Description
+ description: Describe the new capability you'd like to add to XcodeBuildMCP
+ placeholder: I would like the AI assistant to be able to...
+ validations:
+ required: true
+
+ - type: textarea
+ id: use-cases
+ attributes:
+ label: Use Cases
+ description: Describe specific scenarios where this feature would be useful
+ placeholder: |
+ - Building and testing iOS apps with custom schemes
+ - Managing multiple simulator configurations
+ - Automating complex Xcode workflows
+ validations:
+ required: false
+
+ - type: textarea
+ id: example-interactions
+ attributes:
+ label: Example Interactions
+ description: Provide examples of how you envision using this feature
+ placeholder: |
+ You: [Example request to the AI]
+ AI: [Desired response/action]
+ validations:
+ required: false
diff --git a/.github/workflows/README.md b/.github/workflows/README.md
new file mode 100644
index 00000000..946318c8
--- /dev/null
+++ b/.github/workflows/README.md
@@ -0,0 +1 @@
+# Test workflow trigger
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
new file mode 100644
index 00000000..17a06a74
--- /dev/null
+++ b/.github/workflows/ci.yml
@@ -0,0 +1,44 @@
+name: CI
+
+on:
+ push:
+ branches: [ main ]
+ pull_request:
+ branches: [ main ]
+
+jobs:
+ build-and-test:
+ runs-on: ubuntu-latest
+
+ strategy:
+ matrix:
+ node-version: [24.x]
+
+ steps:
+ - uses: actions/checkout@v3
+
+ - name: Use Node.js ${{ matrix.node-version }}
+ uses: actions/setup-node@v3
+ with:
+ node-version: ${{ matrix.node-version }}
+ cache: 'npm'
+
+ - name: Install dependencies
+ run: npm ci
+
+ - name: Build
+ run: npm run build
+
+ - name: Lint
+ run: npm run lint
+
+ - name: Check formatting
+ run: npm run format:check
+
+ - name: Type check
+ run: npm run typecheck
+
+ - name: Run tests
+ run: npm test
+
+ - run: npx pkg-pr-new publish
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
new file mode 100644
index 00000000..eb0254a9
--- /dev/null
+++ b/.github/workflows/release.yml
@@ -0,0 +1,210 @@
+name: Release
+
+on:
+ push:
+ tags:
+ - 'v*'
+ workflow_dispatch:
+ inputs:
+ version:
+ description: 'Test version (e.g., 1.9.1-test)'
+ required: true
+ type: string
+
+permissions:
+ contents: write
+ id-token: write
+
+jobs:
+ release:
+ runs-on: macos-latest
+ environment: production
+
+ steps:
+ - name: Checkout code
+ uses: actions/checkout@v4
+ with:
+ fetch-depth: 0
+
+ - name: Setup Node.js
+ uses: actions/setup-node@v4
+ with:
+ node-version: '24'
+ registry-url: 'https://registry.npmjs.org'
+
+ # Ensure npm 11.5.1 or later is installed
+ - name: Update npm
+ run: npm install -g npm@latest
+
+ - name: Clear npm cache and install dependencies
+ run: |
+ npm cache clean --force
+ rm -rf node_modules package-lock.json
+ npm install --ignore-scripts
+
+ - name: Check formatting
+ run: npm run format:check
+
+ - name: Bundle AXe artifacts
+ run: npm run bundle:axe
+
+ - name: Build TypeScript
+ run: npm run build
+
+ - name: Run tests
+ run: npm test
+
+ - name: Get version from tag or input
+ id: get_version
+ run: |
+ if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
+ VERSION="${{ github.event.inputs.version }}"
+ echo "VERSION=$VERSION" >> $GITHUB_OUTPUT
+ echo "IS_TEST=true" >> $GITHUB_OUTPUT
+ echo "📝 Test version: $VERSION"
+ # Update package.json version for test releases only
+ npm version $VERSION --no-git-tag-version
+ else
+ VERSION=${GITHUB_REF#refs/tags/v}
+ echo "VERSION=$VERSION" >> $GITHUB_OUTPUT
+ echo "IS_TEST=false" >> $GITHUB_OUTPUT
+ echo "🚀 Release version: $VERSION"
+ # For tag-based releases, package.json was already updated by release script
+ fi
+
+ - name: Create package
+ run: npm pack
+
+ - name: Test publish (dry run for manual triggers)
+ if: github.event_name == 'workflow_dispatch'
+ run: |
+ echo "🧪 Testing package creation (dry run)"
+ npm publish --dry-run --access public
+
+ - name: Publish to NPM (production releases only)
+ if: github.event_name == 'push'
+ run: |
+ VERSION="${{ steps.get_version.outputs.VERSION }}"
+ # Skip if this exact version is already published (idempotent reruns)
+ if npm view xcodebuildmcp@"$VERSION" version >/dev/null 2>&1; then
+ echo "✅ xcodebuildmcp@$VERSION already on NPM. Skipping publish."
+ exit 0
+ fi
+ # Determine the appropriate npm tag based on version
+ if [[ "$VERSION" == *"-beta"* ]]; then
+ NPM_TAG="beta"
+ elif [[ "$VERSION" == *"-alpha"* ]]; then
+ NPM_TAG="alpha"
+ elif [[ "$VERSION" == *"-rc"* ]]; then
+ NPM_TAG="rc"
+ else
+ # For stable releases, explicitly use latest tag
+ NPM_TAG="latest"
+ fi
+ echo "📦 Publishing to NPM with tag: $NPM_TAG"
+ npm publish --access public --tag "$NPM_TAG"
+
+ - name: Create GitHub Release (production releases only)
+ if: github.event_name == 'push'
+ uses: softprops/action-gh-release@v1
+ with:
+ tag_name: v${{ steps.get_version.outputs.VERSION }}
+ name: Release v${{ steps.get_version.outputs.VERSION }}
+ body: |
+ ## Release v${{ steps.get_version.outputs.VERSION }}
+
+ ### Installation
+ ```bash
+ npm install -g xcodebuildmcp@${{ steps.get_version.outputs.VERSION }}
+ ```
+
+ Or use with npx:
+ ```bash
+ npx xcodebuildmcp@${{ steps.get_version.outputs.VERSION }}
+ ```
+
+ 📦 **NPM Package**: https://www.npmjs.com/package/xcodebuildmcp/v/${{ steps.get_version.outputs.VERSION }}
+ files: |
+ xcodebuildmcp-${{ steps.get_version.outputs.VERSION }}.tgz
+ draft: false
+ prerelease: false
+
+ - name: Summary
+ run: |
+ if [ "${{ steps.get_version.outputs.IS_TEST }}" = "true" ]; then
+ echo "🧪 Test completed for version: ${{ steps.get_version.outputs.VERSION }}"
+ echo "Ready for production release!"
+ else
+ echo "🎉 Production release completed!"
+ echo "Version: ${{ steps.get_version.outputs.VERSION }}"
+ echo "📦 NPM: https://www.npmjs.com/package/xcodebuildmcp/v/${{ steps.get_version.outputs.VERSION }}"
+ echo "📚 MCP Registry: publish attempted in separate job (mcp_registry)"
+ fi
+
+ mcp_registry:
+ if: github.event_name == 'push'
+ needs: release
+ runs-on: ubuntu-latest
+ env:
+ MCP_DNS_PRIVATE_KEY: ${{ secrets.MCP_DNS_PRIVATE_KEY }}
+ steps:
+ - name: Checkout code
+ uses: actions/checkout@v4
+ with:
+ fetch-depth: 0
+
+ - name: Get version from tag
+ id: get_version_mcp
+ run: |
+ VERSION=${GITHUB_REF#refs/tags/v}
+ echo "VERSION=$VERSION" >> $GITHUB_OUTPUT
+ echo "🚢 MCP publish for version: $VERSION"
+
+ - name: Missing secret — skip MCP publish
+ if: env.MCP_DNS_PRIVATE_KEY == ''
+ run: |
+ echo "⚠️ Skipping MCP Registry publish: secrets.MCP_DNS_PRIVATE_KEY is not set."
+ echo "This is optional and does not affect the release."
+
+ - name: Setup Go (for MCP Publisher)
+ if: env.MCP_DNS_PRIVATE_KEY != ''
+ uses: actions/setup-go@v5
+ with:
+ go-version: '1.22'
+
+ - name: Install MCP Publisher
+ if: env.MCP_DNS_PRIVATE_KEY != ''
+ run: |
+ echo "📥 Fetching MCP Publisher"
+ git clone https://github.com/modelcontextprotocol/registry publisher-repo
+ cd publisher-repo
+ make publisher
+ cp bin/mcp-publisher ../mcp-publisher
+ cd ..
+ chmod +x mcp-publisher
+
+ - name: Login to MCP Registry (DNS)
+ if: env.MCP_DNS_PRIVATE_KEY != ''
+ run: |
+ echo "🔐 Using DNS authentication for com.xcodebuildmcp/* namespace"
+ ./mcp-publisher login dns --domain xcodebuildmcp.com --private-key "${MCP_DNS_PRIVATE_KEY}"
+
+ - name: Publish to MCP Registry (best-effort)
+ if: env.MCP_DNS_PRIVATE_KEY != ''
+ run: |
+ echo "🚢 Publishing to MCP Registry with retries..."
+ attempts=0
+ max_attempts=5
+ delay=5
+ until ./mcp-publisher publish; do
+ rc=$?
+ attempts=$((attempts+1))
+ if [ $attempts -ge $max_attempts ]; then
+ echo "⚠️ MCP Registry publish failed after $attempts attempts (exit $rc). Skipping without failing workflow."
+ exit 0
+ fi
+ echo "⚠️ Publish failed (exit $rc). Retrying in ${delay}s... (attempt ${attempts}/${max_attempts})"
+ sleep $delay
+ delay=$((delay*2))
+ done
+ echo "✅ MCP Registry publish succeeded."
diff --git a/.github/workflows/sentry.yml b/.github/workflows/sentry.yml
new file mode 100644
index 00000000..d88f57ed
--- /dev/null
+++ b/.github/workflows/sentry.yml
@@ -0,0 +1,36 @@
+name: Sentry Release
+on:
+ push:
+ tags:
+ - 'v*'
+
+jobs:
+ release:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v4
+ with:
+ fetch-depth: 0
+ - name: Install dependencies
+ run: npm ci
+
+ - name: Build project
+ run: npm run build
+
+ - name: Run tests
+ run: npm test
+
+ - name: Extract version from build/version.js
+ id: get_version
+ run: echo "MCP_VERSION=$(grep -oE "'[0-9]+\.[0-9]+\.[0-9]+'" build/version.js | tr -d "'")" >> $GITHUB_OUTPUT
+
+ - name: Create Sentry release
+ uses: getsentry/action-release@v3
+ env:
+ SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }}
+ SENTRY_ORG: ${{ secrets.SENTRY_ORG }}
+ SENTRY_PROJECT: ${{ secrets.SENTRY_PROJECT }}
+ with:
+ environment: production
+ sourcemaps: "./build"
+ version: ${{ steps.get_version.outputs.MCP_VERSION }}
\ No newline at end of file
diff --git a/.gitignore b/.gitignore
index 4be2ca3b..f49d4c5e 100644
--- a/.gitignore
+++ b/.gitignore
@@ -6,15 +6,22 @@ yarn-error.log*
# TypeScript build output
dist/
-build/
+/build/
*.tsbuildinfo
# Auto-generated files
src/version.ts
+src/core/generated-plugins.ts
+src/core/generated-resources.ts
# IDE and editor files
.idea/
-.vscode/
+.vscode/*
+!.vscode/mcp.json
+!.vscode/launch.json
+!.vscode/settings.json
+!.vscode/tasks.json
+!.vscode/extensions.json
*.swp
*.swo
.DS_Store
@@ -81,6 +88,25 @@ xcuserdata/
.cache
.parcel-cache
-# Windsurf rules
+# Windsurf
.windsurfrules
+# Sentry Config File
+.sentryclirc
+
+# Claude Config File
+**/.claude/settings.local.json
+
+# incremental builds
+Makefile
+buildServer.json
+
+# Bundled AXe artifacts (generated during build)
+bundled/
+
+/.mcpregistry_github_token
+/.mcpregistry_registry_token
+/key.pem
+.mcpli
+.factory
+DerivedData
diff --git a/.vscode/extensions.json b/.vscode/extensions.json
new file mode 100644
index 00000000..59daa7a0
--- /dev/null
+++ b/.vscode/extensions.json
@@ -0,0 +1,11 @@
+{
+ "recommendations": [
+ "dbaeumer.vscode-eslint"
+ ],
+ "unwantedRecommendations": [
+ "esbenp.prettier-vscode"
+ ]
+}
+
+
+
diff --git a/.vscode/launch.json b/.vscode/launch.json
new file mode 100644
index 00000000..fb633852
--- /dev/null
+++ b/.vscode/launch.json
@@ -0,0 +1,53 @@
+{
+ "version": "0.2.0",
+ "configurations": [
+ {
+ "type": "node",
+ "request": "attach",
+ "name": "Wait for MCP Server to Start",
+ "port": 9999,
+ "address": "localhost",
+ "restart": true,
+ "skipFiles": [
+ "/**"
+ ],
+ "sourceMaps": true,
+ "outFiles": [
+ "${workspaceFolder}/build/**/*.js"
+ ],
+ "cwd": "${workspaceFolder}",
+ "sourceMapPathOverrides": {
+ "/*": "${workspaceFolder}/src/*"
+ },
+ "timeout": 60000,
+ "localRoot": "${workspaceFolder}",
+ "remoteRoot": "${workspaceFolder}"
+ },
+ {
+ "type": "node",
+ "request": "launch",
+ "name": "Launch MCP Server Dev",
+ "program": "${workspaceFolder}/build/index.js",
+ "cwd": "${workspaceFolder}",
+ "runtimeArgs": [
+ "--inspect=9999"
+ ],
+ "env": {
+ "XCODEBUILDMCP_DEBUG": "true",
+ "INCREMENTAL_BUILDS_ENABLED": "false",
+ "XCODEBUILDMCP_IOS_TEMPLATE_PATH": "${workspaceFolder}/../XcodeBuildMCP-iOS-Template",
+ "XCODEBUILDMCP_MACOS_TEMPLATE_PATH": "${workspaceFolder}/../XcodeBuildMCP-macOS-Template"
+ },
+ "sourceMaps": true,
+ "outFiles": [
+ "${workspaceFolder}/build/**/*.js"
+ ],
+ "skipFiles": [
+ "/**"
+ ],
+ "sourceMapPathOverrides": {
+ "/*": "${workspaceFolder}/src/*"
+ }
+ }
+ ]
+}
\ No newline at end of file
diff --git a/.vscode/mcp.json b/.vscode/mcp.json
new file mode 100644
index 00000000..de9ab67b
--- /dev/null
+++ b/.vscode/mcp.json
@@ -0,0 +1,33 @@
+{
+ "servers": {
+ "XcodeBuildMCP": {
+ "type": "stdio",
+ "command": "npx",
+ "args": [
+ "-y",
+ "xcodebuildmcp@latest"
+ ],
+ "env": {
+ "XCODEBUILDMCP_DEBUG": "true",
+ "INCREMENTAL_BUILDS_ENABLED": "false",
+ "XCODEBUILDMCP_IOS_TEMPLATE_PATH": "${workspaceFolder}/../XcodeBuildMCP-iOS-Template",
+ "XCODEBUILDMCP_MACOS_TEMPLATE_PATH": "${workspaceFolder}/../XcodeBuildMCP-macOS-Template"
+ }
+ },
+ "XcodeBuildMCP-Dev": {
+ "type": "stdio",
+ "command": "node",
+ "args": [
+ "--inspect=9999",
+ "--trace-warnings",
+ "${workspaceFolder}/build/index.js"
+ ],
+ "env": {
+ "XCODEBUILDMCP_DEBUG": "true",
+ "INCREMENTAL_BUILDS_ENABLED": "false",
+ "XCODEBUILDMCP_IOS_TEMPLATE_PATH": "${workspaceFolder}/../XcodeBuildMCP-iOS-Template",
+ "XCODEBUILDMCP_MACOS_TEMPLATE_PATH": "${workspaceFolder}/../XcodeBuildMCP-macOS-Template"
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/.vscode/settings.json b/.vscode/settings.json
new file mode 100644
index 00000000..93934668
--- /dev/null
+++ b/.vscode/settings.json
@@ -0,0 +1,47 @@
+{
+ "eslint.useFlatConfig": true,
+ "eslint.validate": [
+ "javascript",
+ "typescript"
+ ],
+ "eslint.runtime": "/opt/homebrew/bin/node",
+ "eslint.format.enable": true,
+ "eslint.nodePath": "${workspaceFolder}/node_modules",
+ "eslint.workingDirectories": [
+ {
+ "directory": "${workspaceFolder}",
+ "changeProcessCWD": true
+ }
+ ],
+ "typescript.tsdk": "node_modules/typescript/lib",
+ "typescript.enablePromptUseWorkspaceTsdk": true,
+ "typescript.tsserver.maxTsServerMemory": 4096,
+ "javascript.validate.enable": false,
+ "typescript.validate.enable": false,
+ "editor.codeActionsOnSave": {
+ "source.fixAll.eslint": "explicit"
+ },
+ "editor.defaultFormatter": "vscode.typescript-language-features",
+ "[typescript]": {
+ "editor.defaultFormatter": "vscode.typescript-language-features"
+ },
+ "[javascript]": {
+ "editor.defaultFormatter": "vscode.typescript-language-features"
+ },
+ "terminal.integrated.shellIntegration.decorationsEnabled": "never",
+ "vitest.nodeExecutable": "/opt/homebrew/bin/node",
+ "[json]": {
+ "editor.defaultFormatter": "vscode.json-language-features"
+ },
+ "[jsonc]": {
+ "editor.defaultFormatter": "vscode.json-language-features"
+ },
+ "chat.mcp.serverSampling": {
+ "XcodeBuildMCP/.vscode/mcp.json: XcodeBuildMCP-Dev": {
+ "allowedDuringChat": true,
+ "allowedModels": [
+ "copilot/gpt-5.2"
+ ]
+ }
+ },
+}
\ No newline at end of file
diff --git a/.vscode/tasks.json b/.vscode/tasks.json
new file mode 100644
index 00000000..c89555ba
--- /dev/null
+++ b/.vscode/tasks.json
@@ -0,0 +1,112 @@
+{
+ "$schema": "https://raw.githubusercontent.com/microsoft/vscode/master/extensions/npm/schemas/v1.1.1/tasks.schema.json",
+ "version": "2.0.0",
+ "tasks": [
+ {
+ "label": "build",
+ "type": "npm",
+ "script": "build",
+ "group": {
+ "kind": "build",
+ "isDefault": true
+ },
+ "presentation": {
+ "echo": true,
+ "reveal": "always",
+ "focus": false,
+ "panel": "shared",
+ "showReuseMessage": true,
+ "clear": false
+ },
+ "problemMatcher": [
+ "$tsc"
+ ]
+ },
+ {
+ "label": "run",
+ "type": "npm",
+ "script": "inspect",
+ "group": "build",
+ "presentation": {
+ "echo": true,
+ "reveal": "always",
+ "focus": true,
+ "panel": "new"
+ }
+ },
+ {
+ "label": "test",
+ "type": "npm",
+ "script": "test",
+ "group": {
+ "kind": "test",
+ "isDefault": true
+ },
+ "presentation": {
+ "echo": true,
+ "reveal": "always",
+ "focus": false,
+ "panel": "shared"
+ }
+ },
+ {
+ "label": "lint",
+ "type": "npm",
+ "script": "lint",
+ "group": "build",
+ "presentation": {
+ "echo": true,
+ "reveal": "silent",
+ "focus": false,
+ "panel": "shared"
+ },
+ "problemMatcher": [
+ "$eslint-stylish"
+ ]
+ },
+ {
+ "label": "lint:fix",
+ "type": "npm",
+ "script": "lint:fix",
+ "group": "build"
+ },
+ {
+ "label": "format",
+ "type": "npm",
+ "script": "format",
+ "group": "build"
+ },
+ {
+ "label": "typecheck (watch)",
+ "type": "shell",
+ "command": "npx tsc --noEmit --watch",
+ "isBackground": true,
+ "problemMatcher": [
+ "$tsc-watch"
+ ],
+ "group": "build"
+ },
+ {
+ "label": "dev (watch)",
+ "type": "npm",
+ "script": "dev",
+ "isBackground": true,
+ "group": "build",
+ "presentation": {
+ "panel": "dedicated",
+ "reveal": "always"
+ }
+ },
+ {
+ "label": "build: dev doctor",
+ "dependsOn": [
+ "lint",
+ "typecheck (watch)"
+ ],
+ "group": {
+ "kind": "build",
+ "isDefault": false
+ }
+ }
+ ]
+}
\ No newline at end of file
diff --git a/AGENTS.md b/AGENTS.md
new file mode 100644
index 00000000..e7881092
--- /dev/null
+++ b/AGENTS.md
@@ -0,0 +1,210 @@
+This file provides guidance to AI assisants (Claude Code, Cursor etc) when working with code in this repository.
+
+## Project Overview
+
+XcodeBuildMCP is a Model Context Protocol (MCP) server providing standardized tools for AI assistants to interact with Xcode projects, iOS simulators, devices, and Apple development workflows. It's a TypeScript/Node.js project that runs as a stdio-based MCP server.
+
+## Common Commands
+
+### Build & Development
+```bash
+npm run build # Compile TypeScript with tsup, generates version info
+npm run dev # Watch mode development
+npm run bundle:axe # Bundle axe CLI tool for simulator automation (needed when using local MCP server)
+npm run test # Run complete Vitest test suite
+npm run test:watch # Watch mode testing
+npm run lint # ESLint code checking
+npm run lint:fix # ESLint code checking and fixing
+npm run format:check # Prettier code checking
+npm run format # Prettier code formatting
+npm run typecheck # TypeScript type checking
+npm run inspect # Run interactive MCP protocol inspector
+npm run doctor # Doctor CLI
+```
+
+### Development with Reloaderoo
+
+**Reloaderoo** (v1.1.2+) provides CLI-based testing and hot-reload capabilities for XcodeBuildMCP without requiring MCP client configuration.
+
+#### Quick Start
+
+**CLI Mode (Testing & Development):**
+```bash
+# List all tools
+npx reloaderoo inspect list-tools -- node build/index.js
+
+# Call any tool
+npx reloaderoo inspect call-tool list_devices --params '{}' -- node build/index.js
+
+# Get server information
+npx reloaderoo inspect server-info -- node build/index.js
+
+# List and read resources
+npx reloaderoo inspect list-resources -- node build/index.js
+npx reloaderoo inspect read-resource "xcodebuildmcp://devices" -- node build/index.js
+```
+
+**Proxy Mode (MCP Client Integration):**
+```bash
+# Start persistent server for MCP clients
+npx reloaderoo proxy -- node build/index.js
+
+# With debug logging
+npx reloaderoo proxy --log-level debug -- node build/index.js
+
+# Then ask AI: "Please restart the MCP server to load my changes"
+```
+
+#### All CLI Inspect Commands
+
+Reloaderoo provides 8 inspect subcommands for comprehensive MCP server testing:
+
+```bash
+# Server capabilities and information
+npx reloaderoo inspect server-info -- node build/index.js
+
+# Tool management
+npx reloaderoo inspect list-tools -- node build/index.js
+npx reloaderoo inspect call-tool --params '' -- node build/index.js
+
+# Resource access
+npx reloaderoo inspect list-resources -- node build/index.js
+npx reloaderoo inspect read-resource "" -- node build/index.js
+
+# Prompt management
+npx reloaderoo inspect list-prompts -- node build/index.js
+npx reloaderoo inspect get-prompt --args '' -- node build/index.js
+
+# Connectivity testing
+npx reloaderoo inspect ping -- node build/index.js
+```
+
+#### Advanced Options
+
+```bash
+# Custom working directory
+npx reloaderoo inspect list-tools --working-dir /custom/path -- node build/index.js
+
+# Timeout configuration
+npx reloaderoo inspect call-tool slow_tool --timeout 60000 --params '{}' -- node build/index.js
+
+# Use timeout configuration if needed
+npx reloaderoo inspect server-info --timeout 60000 -- node build/index.js
+
+# Debug logging (use proxy mode for detailed logging)
+npx reloaderoo proxy --log-level debug -- node build/index.js
+```
+
+#### Key Benefits
+
+- ✅ **No MCP Client Setup**: Direct CLI access to all tools
+- ✅ **Raw JSON Output**: Perfect for AI agents and programmatic use
+- ✅ **Hot-Reload Support**: `restart_server` tool for MCP client development
+- ✅ **Claude Code Compatible**: Automatic content block consolidation
+- ✅ **8 Inspect Commands**: Complete MCP protocol testing capabilities
+- ✅ **Universal Compatibility**: Works on any system via npx
+
+For complete documentation, examples, and troubleshooting, see @docs/RELOADEROO.md
+
+## Architecture Overview
+
+### Plugin-Based MCP architecture
+
+XcodeBuildMCP uses the concept of configuration by convention for MCP exposing and running MCP capabilities like tools and resources. This means to add a new tool or resource, you simply create a new file in the appropriate directory and it will be automatically loaded and exposed to MCP clients.
+
+#### Tools
+
+Tools are the core of the MCP server and are the primary way to interact with the server. They are organized into directories by their functionality and are automatically loaded and exposed to MCP clients.
+
+For more information see @docs/PLUGIN_DEVELOPMENT.md
+
+#### Resources
+
+Resources are the secondary way to interact with the server. They are used to provide data to tools and are organized into directories by their functionality and are automatically loaded and exposed to MCP clients.
+
+For more information see @docs/PLUGIN_DEVELOPMENT.md
+
+### Tool Registration
+
+XcodeBuildMCP loads tools at startup. To limit the toolset, set `XCODEBUILDMCP_ENABLED_WORKFLOWS` to a comma-separated list of workflow directory names (for example: `simulator,project-discovery`). The `session-management` workflow is always auto-included since other tools depend on it.
+
+#### Claude Code Compatibility Workaround
+- **Detection**: Automatic detection when running under Claude Code.
+- **Purpose**: Workaround for Claude Code's MCP specification violation where it only displays the first content block in tool responses.
+- **Behavior**: When Claude Code is detected, multiple content blocks are automatically consolidated into a single text response, separated by `---` dividers. This ensures all information (including test results and stderr warnings) is visible to Claude Code users.
+
+### Core Architecture Layers
+1. **MCP Transport**: stdio protocol communication
+2. **Plugin Discovery**: Automatic tool AND resource registration system
+3. **MCP Resources**: URI-based data access (e.g., `xcodebuildmcp://simulators`)
+4. **Tool Implementation**: Self-contained workflow modules
+5. **Shared Utilities**: Command execution, build management, validation
+6. **Types**: Shared interfaces and Zod schemas
+
+For more information see @docs/ARCHITECTURE.md
+
+## Testing
+
+The project enforces a strict **Dependency Injection (DI)** testing philosophy.
+
+- **NO Vitest Mocking**: The use of `vi.mock()`, `vi.fn()`, `vi.spyOn()`, etc., is **completely banned**.
+- **Executors**: All external interactions (like running commands or accessing the file system) are handled through injectable "executors".
+ - `CommandExecutor`: For running shell commands.
+ - `FileSystemExecutor`: For file system operations.
+- **Testing Logic**: Tests import the core `...Logic` function from a tool file and pass in a mock executor (`createMockExecutor` or `createMockFileSystemExecutor`) to simulate different outcomes.
+
+This approach ensures that tests are robust, easy to maintain, and verify the actual integration between components without being tightly coupled to implementation details.
+
+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 '@modelcontextprotocol/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.**
+
+For complete guidelines, refer to @docs/RELEASE_PROCESS.md
+
+## Useful external resources
+
+### Model Context Protocol
+
+https://modelcontextprotocol.io/llms-full.txt
+
+### MCP Specification
+
+https://modelcontextprotocol.io/specification
+
+### MCP Inspector
+
+https://github.com/modelcontextprotocol/inspector
+
+### MCP Client SDKs
+
+https://github.com/modelcontextprotocol/typescript-sdk
diff --git a/CHANGELOG.md b/CHANGELOG.md
new file mode 100644
index 00000000..8b0a3f59
--- /dev/null
+++ b/CHANGELOG.md
@@ -0,0 +1,187 @@
+# Changelog
+
+## [1.16.0] - 2025-12-30
+- Remove dynamic tool discovery (`discover_tools`) and `XCODEBUILDMCP_DYNAMIC_TOOLS`. Use `XCODEBUILDMCP_ENABLED_WORKFLOWS` to limit startup tool registration.
+- Add MCP tool annotations to all tools.
+
+## [1.14.0] - 2025-09-22
+- Add video capture tool for simulators
+
+## [1.13.1] - 2025-09-21
+- Add simulator erase content and settings tool
+
+## [1.12.3] - 2025-08-22
+- Pass environment variables to test runs on device, simulator, and macOS via an optional testRunnerEnv input (auto-prefixed as TEST_RUNNER_).
+
+## [1.12.2] - 2025-08-21
+### Fixed
+- **Clean tool**: Fixed issue where clean would fail for simulators
+
+## [1.12.1] - 2025-08-18
+### Improved
+- **Sentry Logging**: No longer logs domain errors to Sentry, now only logs MCP server errors.
+
+## [1.12.0] - 2025-08-17
+### Added
+- Unify project/workspace and sim id/name tools into a single tools reducing the number of tools from 81 to 59, this helps reduce the client agent's context window size by 27%!
+- **Selective Workflow Loading**: New `XCODEBUILDMCP_ENABLED_WORKFLOWS` environment variable allows loading only specific workflow groups in static mode, reducing context window usage for clients that don't support MCP sampling (Thanks to @codeman9 for their first contribution!)
+- Rename `diagnosics` tool and cli to `doctor`
+- Add Sentry instrumentation to track MCP usage statistics (can be disabled by setting `XCODEBUILDMCP_SENTRY_DISABLED=true`)
+- Add support for MCP setLevel handler to allow clients to control the log level of the MCP server
+
+## [v1.11.2] - 2025-08-08
+- Fixed "registerTools is not a function" errors during package upgrades
+
+## [v1.11.1] - 2025-08-07
+- Improved tool discovery to be more accurate and context-aware
+
+## [v1.11.0] - 2025-08-07
+- Major refactor/rewrite to improve code quality and maintainability in preparation for future development
+- Added support for dynamic tools (VSCode only for now)
+- Added support for MCP Resources (devices, simulators, environment info)
+- Workaround for https://github.com/cameroncooke/XcodeBuildMCP/issues/66 and https://github.com/anthropics/claude-code/issues/1804 issues where Claude Code would only see the first text content from tool responses
+
+## [v1.10.0] - 2025-06-10
+### Added
+- **App Lifecycle Management**: New tools for stopping running applications
+ - `stop_app_device`: Stop apps running on physical Apple devices (iPhone, iPad, Apple Watch, Apple TV, Apple Vision Pro)
+ - `stop_app_sim`: Stop apps running on iOS/watchOS/tvOS/visionOS simulators
+ - `stop_mac_app`: Stop macOS applications by name or process ID
+- **Enhanced Launch Tools**: Device launch tools now return process IDs for better app management
+- **Bundled AXe Distribution**: AXe binary and frameworks now included in npm package for zero-setup UI automation
+
+### Fixed
+- **WiFi Device Detection**: Improved detection of Apple devices connected over WiFi networks
+- **Device Connectivity**: Better handling of paired devices with different connection states
+
+### Improved
+- **Simplified Installation**: No separate AXe installation required - everything works out of the box
+
+## [v1.9.0] - 2025-06-09
+- Added support for hardware devices over USB and Wi-Fi
+- New tools for Apple device deployment:
+ - `install_app_device`
+ - `launch_app_device`
+- Updated all simulator and device tools to be platform-agnostic, supporting all Apple platforms (iOS, iPadOS, watchOS, tvOS, visionOS)
+- Changed `get_ios_bundle_id` to `get_app_bundle_id` with support for all Apple platforms
+
+## [v1.8.0] - 2025-06-07
+- Added support for running tests on macOS, iOS simulators, and iOS devices
+- New tools for testing:
+ - `test_macos_workspace`
+ - `test_macos_project`
+ - `test_ios_simulator_name_workspace`
+ - `test_ios_simulator_name_project`
+ - `test_ios_simulator_id_workspace`
+ - `test_ios_simulator_id_project`
+ - `test_ios_device_workspace`
+ - `test_ios_device_project`
+
+## [v1.7.0] - 2025-06-04
+- Added support for Swift Package Manager (SPM)
+- New tools for Swift Package Manager:
+ - `swift_package_build`
+ - `swift_package_clean`
+ - `swift_package_test`
+ - `swift_package_run`
+ - `swift_package_list`
+ - `swift_package_stop`
+
+## [v1.6.1] - 2025-06-03
+- Improve UI tool hints
+
+## [v1.6.0] - 2025-06-03
+- Moved project templates to external GitHub repositories for independent versioning
+- Added support for downloading templates from GitHub releases
+- Added local template override support via environment variables
+- Added `scaffold_ios_project` and `scaffold_macos_project` tools for creating new projects
+- Centralized template version management in package.json for easier updates
+
+## [v1.5.0] - 2025-06-01
+- UI automation is no longer in beta!
+- Added support for AXe UI automation
+- Revised default installation instructions to prefer npx instead of mise
+
+## [v1.4.0] - 2025-05-11
+- Merge the incremental build beta branch into main
+- Add preferXcodebuild argument to build tools with improved error handling allowing the agent to force the use of xcodebuild over xcodemake for complex projects. It also adds a hint when incremental builds fail due to non-compiler errors, enabling the agent to automatically switch to xcodebuild for a recovery build attempt, improving reliability.
+
+## [v1.3.7] - 2025-05-08
+- Fix Claude Code issue due to long tool names
+
+## [v1.4.0-beta.3] - 2025-05-07
+- Fixed issue where incremental builds would only work for "Debug" build configurations
+-
+## [v1.4.0-beta.2] - 2025-05-07
+- Same as beta 1 but has the latest features from the main release channel
+
+## [v1.4.0-beta.1] - 2025-05-05
+- Added experimental support for incremental builds (requires opt-in)
+
+## [v1.3.6] - 2025-05-07
+- Added support for enabling/disabling tools via environment variables
+
+## [v1.3.5] - 2025-05-05
+- Fixed the text input UI automation tool
+- Improve the UI automation tool hints to reduce agent tool call errors
+- Improved the project discovery tool to reduce agent tool call errors
+- Added instructions for installing idb client manually
+
+## [v1.3.4] - 2025-05-04
+- Improved Sentry integration
+
+## [v1.3.3] - 2025-05-04
+- Added Sentry opt-out functionality
+
+## [v1.3.1] - 2025-05-03
+- Added Sentry integration for error reporting
+
+## [v1.3.0] - 2025-04-28
+
+- Added support for interacting with the simulator (tap, swipe etc.)
+- Added support for capturing simulator screenshots
+
+Please note that the UI automation features are an early preview and currently in beta your mileage may vary.
+
+## [v1.2.4] - 2025-04-24
+- Improved xcodebuild reporting of warnings and errors in tool response
+- Refactor build utils and remove redundant code
+
+## [v1.2.3] - 2025-04-23
+- Added support for skipping macro validation
+
+## [v1.2.2] - 2025-04-23
+- Improved log readability with version information for easier debugging
+- Enhanced overall stability and performance
+
+## [v1.2.1] - 2025-04-23
+- General stability improvements and bug fixes
+
+## [v1.2.0] - 2025-04-14
+### Added
+- New simulator log capture feature: Easily view and debug your app's logs while running in the simulator
+- Automatic project discovery: XcodeBuildMCP now finds your Xcode projects and workspaces automatically
+- Support for both Intel and Apple Silicon Macs in macOS builds
+
+### Improved
+- Cleaner, more readable build output with better error messages
+- Faster build times and more reliable build process
+- Enhanced documentation with clearer usage examples
+
+## [v1.1.0] - 2025-04-05
+### Added
+- Real-time build progress reporting
+- Separate tools for iOS and macOS builds
+- Better workspace and project support
+
+### Improved
+- Simplified build commands with better parameter handling
+- More reliable clean operations for both projects and workspaces
+
+## [v1.0.2] - 2025-04-02
+- Improved documentation with better examples and clearer instructions
+- Easier version tracking for compatibility checks
+
+## [v1.0.1] - 2025-04-02
+- Initial release of XcodeBuildMCP
+- Basic support for building iOS and macOS applications
diff --git a/CLAUDE.md b/CLAUDE.md
new file mode 120000
index 00000000..47dc3e3d
--- /dev/null
+++ b/CLAUDE.md
@@ -0,0 +1 @@
+AGENTS.md
\ No newline at end of file
diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md
new file mode 100644
index 00000000..57c6600b
--- /dev/null
+++ b/CODE_OF_CONDUCT.md
@@ -0,0 +1,128 @@
+# Contributor Covenant Code of Conduct
+
+## Our Pledge
+
+We as members, contributors, and leaders pledge to make participation in our
+community a harassment-free experience for everyone, regardless of age, body
+size, visible or invisible disability, ethnicity, sex characteristics, gender
+identity and expression, level of experience, education, socio-economic status,
+nationality, personal appearance, race, religion, or sexual identity
+and orientation.
+
+We pledge to act and interact in ways that contribute to an open, welcoming,
+diverse, inclusive, and healthy community.
+
+## Our Standards
+
+Examples of behavior that contributes to a positive environment for our
+community include:
+
+* Demonstrating empathy and kindness toward other people
+* Being respectful of differing opinions, viewpoints, and experiences
+* Giving and gracefully accepting constructive feedback
+* Accepting responsibility and apologizing to those affected by our mistakes,
+ and learning from the experience
+* Focusing on what is best not just for us as individuals, but for the
+ overall community
+
+Examples of unacceptable behavior include:
+
+* The use of sexualized language or imagery, and sexual attention or
+ advances of any kind
+* Trolling, insulting or derogatory comments, and personal or political attacks
+* Public or private harassment
+* Publishing others' private information, such as a physical or email
+ address, without their explicit permission
+* Other conduct which could reasonably be considered inappropriate in a
+ professional setting
+
+## Enforcement Responsibilities
+
+Community leaders are responsible for clarifying and enforcing our standards of
+acceptable behavior and will take appropriate and fair corrective action in
+response to any behavior that they deem inappropriate, threatening, offensive,
+or harmful.
+
+Community leaders have the right and responsibility to remove, edit, or reject
+comments, commits, code, wiki edits, issues, and other contributions that are
+not aligned to this Code of Conduct, and will communicate reasons for moderation
+decisions when appropriate.
+
+## Scope
+
+This Code of Conduct applies within all community spaces, and also applies when
+an individual is officially representing the community in public spaces.
+Examples of representing our community include using an official e-mail address,
+posting via an official social media account, or acting as an appointed
+representative at an online or offline event.
+
+## Enforcement
+
+Instances of abusive, harassing, or otherwise unacceptable behavior may be
+reported to the community leaders responsible for enforcement at
+xcodebuildmcp@cameroncooke.com.
+All complaints will be reviewed and investigated promptly and fairly.
+
+All community leaders are obligated to respect the privacy and security of the
+reporter of any incident.
+
+## Enforcement Guidelines
+
+Community leaders will follow these Community Impact Guidelines in determining
+the consequences for any action they deem in violation of this Code of Conduct:
+
+### 1. Correction
+
+**Community Impact**: Use of inappropriate language or other behavior deemed
+unprofessional or unwelcome in the community.
+
+**Consequence**: A private, written warning from community leaders, providing
+clarity around the nature of the violation and an explanation of why the
+behavior was inappropriate. A public apology may be requested.
+
+### 2. Warning
+
+**Community Impact**: A violation through a single incident or series
+of actions.
+
+**Consequence**: A warning with consequences for continued behavior. No
+interaction with the people involved, including unsolicited interaction with
+those enforcing the Code of Conduct, for a specified period of time. This
+includes avoiding interactions in community spaces as well as external channels
+like social media. Violating these terms may lead to a temporary or
+permanent ban.
+
+### 3. Temporary Ban
+
+**Community Impact**: A serious violation of community standards, including
+sustained inappropriate behavior.
+
+**Consequence**: A temporary ban from any sort of interaction or public
+communication with the community for a specified period of time. No public or
+private interaction with the people involved, including unsolicited interaction
+with those enforcing the Code of Conduct, is allowed during this period.
+Violating these terms may lead to a permanent ban.
+
+### 4. Permanent Ban
+
+**Community Impact**: Demonstrating a pattern of violation of community
+standards, including sustained inappropriate behavior, harassment of an
+individual, or aggression toward or disparagement of classes of individuals.
+
+**Consequence**: A permanent ban from any sort of public interaction within
+the community.
+
+## Attribution
+
+This Code of Conduct is adapted from the [Contributor Covenant][homepage],
+version 2.0, available at
+https://www.contributor-covenant.org/version/2/0/code_of_conduct.html.
+
+Community Impact Guidelines were inspired by [Mozilla's code of conduct
+enforcement ladder](https://github.com/mozilla/diversity).
+
+[homepage]: https://www.contributor-covenant.org
+
+For answers to common questions about this code of conduct, see the FAQ at
+https://www.contributor-covenant.org/faq. Translations are available at
+https://www.contributor-covenant.org/translations.
diff --git a/Dockerfile b/Dockerfile
new file mode 100644
index 00000000..01694782
--- /dev/null
+++ b/Dockerfile
@@ -0,0 +1,38 @@
+# Generated by https://smithery.ai. See: https://smithery.ai/docs/build/project-config
+# Use a small base image with Node.js LTS
+FROM node:lts-alpine AS build
+
+# Install dependencies needed for building
+RUN apk add --no-cache python3 g++ make git
+
+# Create app directory
+WORKDIR /usr/src/app
+
+# Copy package manifests
+COPY package.json package-lock.json tsconfig.json eslint.config.js ./
+
+# Copy source
+COPY src ./src
+
+# Install dependencies ignoring any prepare scripts, then build
+RUN npm ci --ignore-scripts
+RUN npm run prebuild && npm run build
+
+# Stage for runtime
+FROM node:lts-alpine
+WORKDIR /usr/src/app
+
+# Install minimal runtime dependencies
+# No build tools needed, install production deps
+COPY package.json package-lock.json ./
+RUN npm ci --omit=dev --ignore-scripts
+
+# Copy built files
+COPY --from=build /usr/src/app/build ./build
+
+# Symlink binary
+RUN npm link
+
+# Default command
+ENTRYPOINT ["xcodebuildmcp"]
+CMD []
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 00000000..b9e3624f
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2025 Cameron Cooke
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/README.md b/README.md
index 2629824e..cf207407 100644
--- a/README.md
+++ b/README.md
@@ -2,29 +2,48 @@
A Model Context Protocol (MCP) server that provides Xcode-related tools for integration with AI assistants and other MCP clients.
+[](https://github.com/cameroncooke/XcodeBuildMCP/actions/workflows/ci.yml)
+[](https://badge.fury.io/js/xcodebuildmcp) [](https://opensource.org/licenses/MIT) [](https://nodejs.org/) [](https://developer.apple.com/xcode/) [](https://www.apple.com/macos/) [](https://modelcontextprotocol.io/) [](https://deepwiki.com/cameroncooke/XcodeBuildMCP)
+
## Table of contents
- [Overview](#overview)
- [Why?](#why)
- [Features](#features)
+ - [Xcode project management](#xcode-project-management)
+ - [Swift Package Manager](#swift-package-manager)
+ - [Simulator management](#simulator-management)
+ - [Device management](#device-management)
+ - [App utilities](#app-utilities)
+ - [MCP Resources](#mcp-resources)
- [Getting started](#getting-started)
- [Prerequisites](#prerequisites)
- - [One-line setup with mise x](#one-line-setup-with-mise-x)
- - [Configure MCP clients](#configure-mcp-clients)
+ - [One click install](#one-click-install)
+ - [General installation](#general-installation)
+ - [Specific client installation instructions](#specific-client-installation-instructions)
+ - [OpenAI Codex CLI](#openai-codex-cli)
+ - [Claude Code CLI](#claude-code-cli)
+ - [Smithery](#smithery)
+ - [MCP Compatibility](#mcp-compatibility)
+- [Incremental build support](#incremental-build-support)
+- [Workflow Selection](#workflow-selection)
+- [Session-aware opt-out](#session-aware-opt-out)
+- [Code Signing for Device Deployment](#code-signing-for-device-deployment)
+- [Troubleshooting](#troubleshooting)
+ - [Doctor Tool](#doctor-tool)
+- [Privacy](#privacy)
+ - [What is sent to Sentry?](#what-is-sent-to-sentry)
+ - [Opting Out of Sentry](#opting-out-of-sentry)
- [Demos](#demos)
- - [Building and running iOS app in Cursor](#building-and-running-ios-app-in-cursor)
- - [Building and running iOS app in Claude Code](#building-and-running-ios-app-in-claude-code)
-- [Local development setup](#local-development-setup)
- - [Prerequisites](#prerequisites-1)
- - [Installation](#installation)
- - [Configure your MCP client](#configure-your-mcp-client)
- - [Debugging](#debugging)
+ - [Autonomously fixing build errors in Cursor](#autonomously-fixing-build-errors-in-cursor)
+ - [Utilising the new UI automation and screen capture features](#utilising-the-new-ui-automation-and-screen-capture-features)
+ - [Building and running iOS app in Claude Desktop](#building-and-running-ios-app-in-claude-desktop)
+- [Contributing](#contributing)
- [Licence](#licence)
-
## Overview
-This project implements an MCP server that exposes Xcode operations as tools that can be invoked by AI agents via the MCP protocol. It enables programmatic interaction with Xcode projects through a standardised interface, optimised for agent-driven development workflows.
+XcodeBuildMCP is a Model Context Protocol (MCP) server that exposes Xcode operations as tools and resources for AI assistants and other MCP clients. Built with a modern plugin architecture, it provides a comprehensive set of self-contained tools organized into workflow-based directories, plus MCP resources for efficient data access, enabling programmatic interaction with Xcode projects, simulators, devices, and Swift packages through a standardized interface.

Using Cursor to build, install, and launch an app on the iOS simulator while capturing logs at run-time.
@@ -46,134 +65,276 @@ The XcodeBuildMCP server provides the following tool capabilities:
- **Build Operations**: Platform-specific build tools for macOS, iOS simulator, and iOS device targets
- **Project Information**: Tools to list schemes and show build settings for Xcode projects and workspaces
- **Clean Operations**: Clean build products using xcodebuild's native clean action
+- **Incremental build support**: Lightning fast builds using incremental build support (experimental, opt-in required)
+- **Project Scaffolding**: Create new iOS and macOS projects from modern templates with workspace + SPM package architecture, customizable bundle identifiers, deployment targets, and device families
+
+### Swift Package Manager
+- **Build Packages**: Build Swift packages with configuration and architecture options
+- **Run Tests**: Execute Swift package test suites with filtering and parallel execution
+- **Run Executables**: Execute package binaries with timeout handling and background execution support
+- **Process Management**: List and stop long-running executables started with Swift Package tools
+- **Clean Artifacts**: Remove build artifacts and derived data for fresh builds
### Simulator management
-- **Simulator Control**: List, boot, and open iOS simulators
-- **App Deployment**: Install and launch apps on iOS simulators
+- **Simulator Control**: List, boot, and open simulators
+- **App Lifecycle**: Complete app management - install, launch, and stop apps on simulators
- **Log Capture**: Capture run-time logs from a simulator
+- **UI Automation**: Interact with simulator UI elements
+- **Screenshot**: Capture screenshots from a simulator
+- **Video Capture**: Start/stop simulator video capture to MP4 (AXe v1.1.0+)
+
+### Device management
+- **Device Discovery**: List connected physical Apple devices over USB or Wi-Fi
+- **App Lifecycle**: Complete app management - build, install, launch, and stop apps on physical devices
+- **Testing**: Run test suites on physical devices with detailed results and cross-platform support
+- **Log Capture**: Capture console output from apps running on physical Apple devices
+- **Wireless Connectivity**: Support for devices connected over Wi-Fi networks
### App utilities
-- **Bundle ID Extraction**: Extract bundle identifiers from iOS and macOS app bundles
-- **App Launching**: Launch built applications on both simulators and macOS
+- **Bundle ID Extraction**: Extract bundle identifiers from app bundles across all Apple platforms
+- **App Lifecycle Management**: Complete app lifecycle control across all platforms
+ - Launch apps on simulators, physical devices, and macOS
+ - Stop running apps with process ID or bundle ID management
+ - Process monitoring and control for comprehensive app management
+
+### MCP Resources
+
+For clients that support MCP resources XcodeBuildMCP provides efficient URI-based data access:
+
+- **Simulators Resource** (`xcodebuildmcp://simulators`): Direct access to available iOS simulators with UUIDs and states
+- **Devices Resource** (`xcodebuildmcp://devices`): Direct access to connected physical Apple devices with UDIDs and states
+- **Doctor Resource** (`xcodebuildmcp://doctor`): Direct access to environment information such as Xcode version, macOS version, and Node.js version
## Getting started
### Prerequisites
-- Xcode command-line tools
-- Node.js (v16 or later)
-- npm
+- macOS 14.5 or later
+- Xcode 16.x or later
+- Node 18.x or later
+
+> Video capture requires the bundled AXe binary (v1.1.0+). Run `npm run bundle:axe` once locally before using `record_sim_video`. This is not required for unit tests.
+
+Configure your MCP client
-> [!NOTE]
-> If you are using mise, you can skip the Node.js and npm installation steps.
+#### One click install
-### One-line setup with mise x
+For a quick install, you can use the following links:
+
+[](https://cursor.com/en/install-mcp?name=XcodeBuildMCP&config=eyJ0eXBlIjoic3RkaW8iLCJjb21tYW5kIjoibnB4IC15IHhjb2RlYnVpbGRtY3BAbGF0ZXN0IiwiZW52Ijp7IklOQ1JFTUVOVEFMX0JVSUxEU19FTkFCTEVEIjoiZmFsc2UiLCJYQ09ERUJVSUxETUNQX1NFTlRSWV9ESVNBQkxFRCI6ImZhbHNlIn19)
+
+[
](https://insiders.vscode.dev/redirect/mcp/install?name=XcodeBuildMCP&config=%7B%22command%22%3A%22npx%22%2C%22args%22%3A%5B%22-y%22%2C%22xcodebuildmcp%40latest%22%5D%7D)
+
+[
](https://insiders.vscode.dev/redirect/mcp/install?name=XcodeBuildMCP&config=%7B%22command%22%3A%22npx%22%2C%22args%22%3A%5B%22-y%22%2C%22xcodebuildmcp%40latest%22%5D%7D&quality=insiders)
+
+#### General installation
+
+Most MCP clients (Cursor, VS Code, Windsurf, Claude Desktop etc) have standardised on the following JSON configuration format, just add the the following to your client's JSON configuration's `mcpServers` object:
+
+```json
+"XcodeBuildMCP": {
+ "command": "npx",
+ "args": [
+ "-y",
+ "xcodebuildmcp@latest"
+ ]
+}
+```
+
+#### Specific client installation instructions
+
+##### OpenAI Codex CLI
+
+Codex uses a toml configuration file to configure MCP servers. To configure XcodeBuildMCP with [OpenAI's Codex CLI](https://github.com/openai/codex), add the following configuration to your Codex CLI config file:
+
+```toml
+[mcp_servers.XcodeBuildMCP]
+command = "npx"
+args = ["-y", "xcodebuildmcp@latest"]
+env = { "INCREMENTAL_BUILDS_ENABLED" = "false", "XCODEBUILDMCP_SENTRY_DISABLED" = "false" }
+```
+
+For more information see [OpenAI Codex MCP Server Configuration](https://github.com/openai/codex/blob/main/codex-rs/config.md#mcp_servers) documentation.
+
+##### Claude Code CLI
+
+To use XcodeBuildMCP with [Claude Code](https://code.anthropic.com), you can add it via the command line:
-To install mise:
```bash
-# macOS (Homebrew)
-brew install mise
+# Add XcodeBuildMCP server to Claude Code
+claude mcp add XcodeBuildMCP npx xcodebuildmcp@latest
+
+# Or with environment variables
+claude mcp add XcodeBuildMCP npx xcodebuildmcp@latest -e INCREMENTAL_BUILDS_ENABLED=false -e XCODEBUILDMCP_SENTRY_DISABLED=false
+```
+
+##### Smithery
-# Other installation methods
-# See https://mise.jdx.dev/getting-started.html
+To install XcodeBuildMCP Server for Claude Desktop automatically via [Smithery](https://smithery.ai/server/@cameroncooke/XcodeBuildMCP):
+
+```bash
+npx -y @smithery/cli install @cameroncooke/XcodeBuildMCP --client claude
```
-For more information about mise, visit the [official documentation](https://mise.jdx.dev/).
+> [!IMPORTANT]
+> Please note that XcodeBuildMCP will request xcodebuild to skip macro validation. This is to avoid errors when building projects that use Swift Macros.
+
+#### MCP Compatibility
+
+XcodeBuildMCP supports both MCP tools, resources and sampling. At time of writing the following editors have varying levels of MCP feature support:
-### Configure MCP clients
+| Editor | Tools | Resources | Samplng |
+|--------|-------|-----------|---------|
+| **VS Code** | ✅ | ✅ | ✅ |
+| **Cursor** | ✅ | ❌ | ❌ |
+| **Windsurf** | ✅ | ❌ | ❌ |
+| **Claude Code** | ✅ | ✅ | ❌ |
+| **Claude Desktop** | ✅ | ✅ | ❌ |
-Configure your MCP client (Windsurf, Cursor, Claude Desktop, etc.) to use the XcodeBuildMCP server by adding the following configuration:
+## Incremental build support
+XcodeBuildMCP includes experimental support for incremental builds. This feature is disabled by default and can be enabled by setting the `INCREMENTAL_BUILDS_ENABLED` environment variable to `true`:
+
+To enable incremental builds, set the `INCREMENTAL_BUILDS_ENABLED` environment variable to `true`:
+
+Example MCP configuration:
```json
-{
- "mcpServers": {
- "XcodeBuildMCP": {
- "command": "mise",
- "args": [
- "x",
- "npm:xcodebuildmcp@latest",
- "--",
- "xcodebuildmcp"
- ]
- }
+"XcodeBuildMCP": {
+ ...
+ "env": {
+ "INCREMENTAL_BUILDS_ENABLED": "true"
}
}
```
-Or, if you have an existing Node.js environment, you can use npx instead of mise:
+> [!IMPORTANT]
+> Please note that incremental builds support is currently highly experimental and your mileage may vary. Please report any issues you encounter to the [issue tracker](https://github.com/cameroncooke/XcodeBuildMCP/issues).
+
+## Workflow Selection
+
+By default, XcodeBuildMCP loads all tools at startup. If you want a smaller tool surface for a specific workflow, set `XCODEBUILDMCP_ENABLED_WORKFLOWS` to a comma-separated list of workflow directory names. The `session-management` workflow is always auto-included since other tools depend on it.
+Example MCP client configuration:
```json
-{
- "mcpServers": {
- "XcodeBuildMCP": {
- "command": "npx",
- "args": [
- "xcodebuildmcp"
- ]
- }
+"XcodeBuildMCP": {
+ ...
+ "env": {
+ "XCODEBUILDMCP_ENABLED_WORKFLOWS": "simulator,device,project-discovery"
}
}
```
-## Demos
+**Available Workflows:**
+- `device` (7 tools) - iOS Device Development
+- `simulator` (12 tools) - iOS Simulator Development
+- `simulator-management` (5 tools) - Simulator Management
+- `swift-package` (6 tools) - Swift Package Manager
+- `project-discovery` (5 tools) - Project Discovery
+- `macos` (6 tools) - macOS Development
+- `ui-testing` (11 tools) - UI Testing & Automation
+- `logging` (4 tools) - Log Capture & Management
+- `project-scaffolding` (2 tools) - Project Scaffolding
+- `utilities` (1 tool) - Project Utilities
+- `doctor` (1 tool) - System Doctor
-### Building and running iOS app in Cursor
-https://github.com/user-attachments/assets/b9d334b5-7f28-47fc-9d66-28061bc701b4
+## Session-aware opt-out
+By default, XcodeBuildMCP uses a session-aware mode: the LLM (or client) sets shared defaults once (simulator, device, project/workspace, scheme, etc.), and all tools reuse them—similar to choosing a scheme and simulator in Xcode’s UI so you don’t repeat them on every action. This cuts context bloat not just in each call payload, but also in the tool schemas themselves (those parameters don’t have to be described on every tool).
-### Building and running iOS app in Claude Code
-https://github.com/user-attachments/assets/e3c08d75-8be6-4857-b4d0-9350b26ef086
+If you prefer the older, explicit style where each tool requires its own parameters, set `XCODEBUILDMCP_DISABLE_SESSION_DEFAULTS=true`. This restores the legacy schemas with per-call parameters while still honoring any session defaults you choose to set.
+
+Example MCP client configuration:
+```json
+"XcodeBuildMCP": {
+ ...
+ "env": {
+ "XCODEBUILDMCP_DISABLE_SESSION_DEFAULTS": "true"
+ }
+}
+```
+Leave this unset for the streamlined session-aware experience; enable it to force explicit parameters on each tool call.
-## Local development setup
+## Code Signing for Device Deployment
-### Prerequisites
+For device deployment features to work, code signing must be properly configured in Xcode **before** using XcodeBuildMCP device tools:
+
+1. Open your project in Xcode
+2. Select your project target
+3. Go to "Signing & Capabilities" tab
+4. Configure "Automatically manage signing" and select your development team
+5. Ensure a valid provisioning profile is selected
+
+> **Note**: XcodeBuildMCP cannot configure code signing automatically. This initial setup must be done once in Xcode, after which the MCP device tools can build, install, and test apps on physical devices.
+
+## Troubleshooting
+
+If you encounter issues with XcodeBuildMCP, the doctor tool can help identify the problem by providing detailed information about your environment and dependencies.
-- Node.js (v16 or later)
-- npm
-- Xcode command-line tools
+### Doctor Tool
-### Installation
+The doctor tool is a standalone utility that checks your system configuration and reports on the status of all dependencies required by XcodeBuildMCP. It's particularly useful when reporting issues.
-1. Clone the repository
-2. Install dependencies:
- ```
- npm install
- ```
-3. Build the project:
- ```
- npm run build
- ```
-4. Start the server:
- ```
- node build/index.js
- ```
+```bash
+# Run the doctor tool using npx
+npx --package xcodebuildmcp@latest xcodebuildmcp-doctor
+```
+
+The doctor tool will output comprehensive information about:
+
+- System and Node.js environment
+- Xcode installation and configuration
+- Required dependencies (xcodebuild, AXe, etc.)
+- Environment variables affecting XcodeBuildMCP
+- Feature availability status
-### Configure your MCP client
+When reporting issues on GitHub, please include the full output from the doctor tool to help with troubleshooting.
-To configure your MCP client to use the local XcodeBuildMCP server, add the following configuration:
+## Privacy
+This project uses [Sentry](https://sentry.io/) for error monitoring and diagnostics. Sentry helps us track issues, crashes, and unexpected errors to improve the reliability and stability of XcodeBuildMCP.
+
+### What is sent to Sentry?
+- Only error-level logs and diagnostic information are sent to Sentry by default.
+- Error logs may include details such as error messages, stack traces, and (in some cases) file paths or project names. You can review the sources in this repository to see exactly what is logged.
+
+### Opting Out of Sentry
+- If you do not wish to send error logs to Sentry, you can opt out by setting the environment variable `XCODEBUILDMCP_SENTRY_DISABLED=true`.
+
+Example MCP client configuration:
```json
-{
- "mcpServers": {
- "XcodeBuildMCP": {
- "command": "node",
- "args": [
- "/path_to/XcodeBuildMCP/build/index.js"
- ]
- }
+"XcodeBuildMCP": {
+ ...
+ "env": {
+ "XCODEBUILDMCP_SENTRY_DISABLED": "true"
}
}
```
-### Debugging
+## Demos
+
+### Autonomously fixing build errors in Cursor
+
-You can use MCP Inspector via:
+### Utilising the new UI automation and screen capture features
-```bash
-npx @modelcontextprotocol/inspector node build/index.js
-```
+
+
+### Building and running iOS app in Claude Desktop
+https://github.com/user-attachments/assets/e3c08d75-8be6-4857-b4d0-9350b26ef086
+
+## Contributing
+
+[](https://www.typescriptlang.org/) [](https://nodejs.org/)
+
+Contributions are welcome! Here's how you can help improve XcodeBuildMCP.
+
+See our documentation for development:
+- [CONTRIBUTING](docs/CONTRIBUTING.md) - Contribution guidelines and development setup
+- [CODE_QUALITY](docs/CODE_QUALITY.md) - Code quality standards, linting, and architectural rules
+- [TESTING](docs/TESTING.md) - Testing principles and patterns
+- [ARCHITECTURE](docs/ARCHITECTURE.md) - System architecture and design principles
## Licence
-This project is licensed under the MIT License - see the LICENSE file for details.
+This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
diff --git a/XcodeBuildMCP.code-workspace b/XcodeBuildMCP.code-workspace
new file mode 100644
index 00000000..d6f91c86
--- /dev/null
+++ b/XcodeBuildMCP.code-workspace
@@ -0,0 +1,13 @@
+{
+ "folders": [
+ {
+ "path": "."
+ },
+ {
+ "path": "../XcodeBuildMCP-iOS-Template"
+ },
+ {
+ "path": "../XcodeBuildMCP-macOS-Template"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/banner.png b/banner.png
index d98fad5a..b5db3644 100644
Binary files a/banner.png and b/banner.png differ
diff --git a/build-plugins/plugin-discovery.js b/build-plugins/plugin-discovery.js
new file mode 100644
index 00000000..d192fcda
--- /dev/null
+++ b/build-plugins/plugin-discovery.js
@@ -0,0 +1,250 @@
+import { readdirSync, readFileSync, existsSync } from 'fs';
+import { join } from 'path';
+import path from 'path';
+
+export function createPluginDiscoveryPlugin() {
+ return {
+ name: 'plugin-discovery',
+ setup(build) {
+ // Generate the workflow loaders file before build starts
+ build.onStart(async () => {
+ try {
+ await generateWorkflowLoaders();
+ await generateResourceLoaders();
+ } catch (error) {
+ console.error('Failed to generate loaders:', error);
+ throw error;
+ }
+ });
+ },
+ };
+}
+
+async function generateWorkflowLoaders() {
+ const pluginsDir = path.resolve(process.cwd(), 'src/mcp/tools');
+
+ if (!existsSync(pluginsDir)) {
+ throw new Error(`Plugins directory not found: ${pluginsDir}`);
+ }
+
+ // Scan for workflow directories
+ const workflowDirs = readdirSync(pluginsDir, { withFileTypes: true })
+ .filter((dirent) => dirent.isDirectory())
+ .map((dirent) => dirent.name);
+
+ const workflowLoaders = {};
+ const workflowMetadata = {};
+
+ for (const dirName of workflowDirs) {
+ const dirPath = join(pluginsDir, dirName);
+ const indexPath = join(dirPath, 'index.ts');
+
+ // Check if workflow has index.ts file
+ if (!existsSync(indexPath)) {
+ console.warn(`Skipping ${dirName}: no index.ts file found`);
+ continue;
+ }
+
+ // Try to extract workflow metadata from index.ts
+ try {
+ const indexContent = readFileSync(indexPath, 'utf8');
+ const metadata = extractWorkflowMetadata(indexContent);
+
+ if (metadata) {
+ // Find all tool files in this workflow directory
+ const toolFiles = readdirSync(dirPath, { withFileTypes: true })
+ .filter((dirent) => dirent.isFile())
+ .map((dirent) => dirent.name)
+ .filter(
+ (name) =>
+ (name.endsWith('.ts') || name.endsWith('.js')) &&
+ name !== 'index.ts' &&
+ name !== 'index.js' &&
+ !name.endsWith('.test.ts') &&
+ !name.endsWith('.test.js') &&
+ name !== 'active-processes.ts', // Special exclusion for swift-package
+ );
+
+ // Generate dynamic loader function that loads workflow and all its tools
+ workflowLoaders[dirName] = generateWorkflowLoader(dirName, toolFiles);
+ workflowMetadata[dirName] = metadata;
+
+ console.log(
+ `✅ Discovered workflow: ${dirName} - ${metadata.name} (${toolFiles.length} tools)`,
+ );
+ } else {
+ console.warn(`⚠️ Skipping ${dirName}: invalid workflow metadata`);
+ }
+ } catch (error) {
+ console.warn(`⚠️ Error processing ${dirName}:`, error);
+ }
+ }
+
+ // Generate the content for generated-plugins.ts
+ const generatedContent = generatePluginsFileContent(workflowLoaders, workflowMetadata);
+
+ // Write to the generated file
+ const outputPath = path.resolve(process.cwd(), 'src/core/generated-plugins.ts');
+
+ const fs = await import('fs');
+ await fs.promises.writeFile(outputPath, generatedContent, 'utf8');
+
+ console.log(`🔧 Generated workflow loaders for ${Object.keys(workflowLoaders).length} workflows`);
+}
+
+function generateWorkflowLoader(workflowName, toolFiles) {
+ const toolImports = toolFiles
+ .map((file, index) => {
+ const toolName = file.replace(/\.(ts|js)$/, '');
+ return `const tool_${index} = await import('../mcp/tools/${workflowName}/${toolName}.js').then(m => m.default)`;
+ })
+ .join(';\n ');
+
+ const toolExports = toolFiles
+ .map((file, index) => {
+ const toolName = file.replace(/\.(ts|js)$/, '');
+ return `'${toolName}': tool_${index}`;
+ })
+ .join(',\n ');
+
+ return `async () => {
+ const { workflow } = await import('../mcp/tools/${workflowName}/index.js');
+ ${toolImports ? toolImports + ';\n ' : ''}
+ return {
+ workflow,
+ ${toolExports ? toolExports : ''}
+ };
+ }`;
+}
+
+function extractWorkflowMetadata(content) {
+ try {
+ // Simple regex to extract workflow export object
+ const workflowMatch = content.match(/export\s+const\s+workflow\s*=\s*({[\s\S]*?});/);
+
+ if (!workflowMatch) {
+ return null;
+ }
+
+ const workflowObj = workflowMatch[1];
+
+ // Extract name
+ const nameMatch = workflowObj.match(/name\s*:\s*['"`]([^'"`]+)['"`]/);
+ if (!nameMatch) return null;
+
+ // Extract description
+ const descMatch = workflowObj.match(/description\s*:\s*['"`]([\s\S]*?)['"`]/);
+ if (!descMatch) return null;
+
+ const result = {
+ name: nameMatch[1],
+ description: descMatch[1],
+ };
+
+ return result;
+ } catch (error) {
+ console.warn('Failed to extract workflow metadata:', error);
+ return null;
+ }
+}
+
+function generatePluginsFileContent(workflowLoaders, workflowMetadata) {
+ const loaderEntries = Object.entries(workflowLoaders)
+ .map(([key, loader]) => {
+ // Indent the loader function properly
+ const indentedLoader = loader
+ .split('\n')
+ .map((line, index) => (index === 0 ? ` '${key}': ${line}` : ` ${line}`))
+ .join('\n');
+ return indentedLoader;
+ })
+ .join(',\n');
+
+ const metadataEntries = Object.entries(workflowMetadata)
+ .map(([key, metadata]) => {
+ const metadataJson = JSON.stringify(metadata, null, 4)
+ .split('\n')
+ .map((line) => ` ${line}`)
+ .join('\n');
+ return ` '${key}': ${metadataJson.trim()}`;
+ })
+ .join(',\n');
+
+ return `// AUTO-GENERATED - DO NOT EDIT
+// This file is generated by the plugin discovery esbuild plugin
+
+// Generated based on filesystem scan
+export const WORKFLOW_LOADERS = {
+${loaderEntries}
+};
+
+export type WorkflowName = keyof typeof WORKFLOW_LOADERS;
+
+// Optional: Export workflow metadata for quick access
+export const WORKFLOW_METADATA = {
+${metadataEntries}
+};
+`;
+}
+
+async function generateResourceLoaders() {
+ const resourcesDir = path.resolve(process.cwd(), 'src/mcp/resources');
+
+ if (!existsSync(resourcesDir)) {
+ console.log('Resources directory not found, skipping resource generation');
+ return;
+ }
+
+ // Scan for resource files
+ const resourceFiles = readdirSync(resourcesDir, { withFileTypes: true })
+ .filter((dirent) => dirent.isFile())
+ .map((dirent) => dirent.name)
+ .filter(
+ (name) =>
+ (name.endsWith('.ts') || name.endsWith('.js')) &&
+ !name.endsWith('.test.ts') &&
+ !name.endsWith('.test.js') &&
+ !name.startsWith('__'), // Exclude test directories
+ );
+
+ const resourceLoaders = {};
+
+ for (const fileName of resourceFiles) {
+ const resourceName = fileName.replace(/\.(ts|js)$/, '');
+
+ // Generate dynamic loader for this resource
+ resourceLoaders[resourceName] = `async () => {
+ const module = await import('../mcp/resources/${resourceName}.js');
+ return module.default;
+ }`;
+
+ console.log(`✅ Discovered resource: ${resourceName}`);
+ }
+
+ // Generate the content for generated-resources.ts
+ const generatedContent = generateResourcesFileContent(resourceLoaders);
+
+ // Write to the generated file
+ const outputPath = path.resolve(process.cwd(), 'src/core/generated-resources.ts');
+
+ const fs = await import('fs');
+ await fs.promises.writeFile(outputPath, generatedContent, 'utf8');
+
+ console.log(`🔧 Generated resource loaders for ${Object.keys(resourceLoaders).length} resources`);
+}
+
+function generateResourcesFileContent(resourceLoaders) {
+ const loaderEntries = Object.entries(resourceLoaders)
+ .map(([key, loader]) => ` '${key}': ${loader}`)
+ .join(',\n');
+
+ return `// AUTO-GENERATED - DO NOT EDIT
+// This file is generated by the plugin discovery esbuild plugin
+
+export const RESOURCE_LOADERS = {
+${loaderEntries}
+};
+
+export type ResourceName = keyof typeof RESOURCE_LOADERS;
+`;
+}
diff --git a/build-plugins/plugin-discovery.ts b/build-plugins/plugin-discovery.ts
new file mode 100644
index 00000000..a7810303
--- /dev/null
+++ b/build-plugins/plugin-discovery.ts
@@ -0,0 +1,145 @@
+import { Plugin } from 'esbuild';
+import { readdirSync, readFileSync, existsSync } from 'fs';
+import { join } from 'path';
+import path from 'path';
+
+export interface WorkflowMetadata {
+ name: string;
+ description: string;
+}
+
+export function createPluginDiscoveryPlugin(): Plugin {
+ return {
+ name: 'plugin-discovery',
+ setup(build) {
+ // Generate the workflow loaders file before build starts
+ build.onStart(async () => {
+ try {
+ await generateWorkflowLoaders();
+ } catch (error) {
+ console.error('Failed to generate workflow loaders:', error);
+ throw error;
+ }
+ });
+ },
+ };
+}
+
+async function generateWorkflowLoaders(): Promise {
+ const pluginsDir = path.resolve(process.cwd(), 'src/plugins');
+
+ if (!existsSync(pluginsDir)) {
+ throw new Error(`Plugins directory not found: ${pluginsDir}`);
+ }
+
+ // Scan for workflow directories
+ const workflowDirs = readdirSync(pluginsDir, { withFileTypes: true })
+ .filter((dirent) => dirent.isDirectory())
+ .map((dirent) => dirent.name);
+
+ const workflowLoaders: Record = {};
+ const workflowMetadata: Record = {};
+
+ for (const dirName of workflowDirs) {
+ const indexPath = join(pluginsDir, dirName, 'index.ts');
+
+ // Check if workflow has index.ts file
+ if (!existsSync(indexPath)) {
+ console.warn(`Skipping ${dirName}: no index.ts file found`);
+ continue;
+ }
+
+ // Try to extract workflow metadata from index.ts
+ try {
+ const indexContent = readFileSync(indexPath, 'utf8');
+ const metadata = extractWorkflowMetadata(indexContent);
+
+ if (metadata) {
+ // Generate dynamic import for this workflow
+ workflowLoaders[dirName] = `() => import('../plugins/${dirName}/index.js')`;
+ workflowMetadata[dirName] = metadata;
+
+ console.log(`✅ Discovered workflow: ${dirName} - ${metadata.name}`);
+ } else {
+ console.warn(`⚠️ Skipping ${dirName}: invalid workflow metadata`);
+ }
+ } catch (error) {
+ console.warn(`⚠️ Error processing ${dirName}:`, error);
+ }
+ }
+
+ // Generate the content for generated-plugins.ts
+ const generatedContent = generatePluginsFileContent(workflowLoaders, workflowMetadata);
+
+ // Write to the generated file
+ const outputPath = path.resolve(process.cwd(), 'src/core/generated-plugins.ts');
+
+ const fs = await import('fs');
+ await fs.promises.writeFile(outputPath, generatedContent, 'utf8');
+
+ console.log(`🔧 Generated workflow loaders for ${Object.keys(workflowLoaders).length} workflows`);
+}
+
+function extractWorkflowMetadata(content: string): WorkflowMetadata | null {
+ try {
+ // Simple regex to extract workflow export object
+ const workflowMatch = content.match(/export\s+const\s+workflow\s*=\s*({[\s\S]*?});/);
+
+ if (!workflowMatch) {
+ return null;
+ }
+
+ const workflowObj = workflowMatch[1];
+
+ // Extract name
+ const nameMatch = workflowObj.match(/name\s*:\s*['"`]([^'"`]+)['"`]/);
+ if (!nameMatch) return null;
+
+ // Extract description
+ const descMatch = workflowObj.match(/description\s*:\s*['"`]([\s\S]*?)['"`]/);
+ if (!descMatch) return null;
+
+ return {
+ name: nameMatch[1],
+ description: descMatch[1],
+ };
+ } catch (error) {
+ console.warn('Failed to extract workflow metadata:', error);
+ return null;
+ }
+}
+
+function generatePluginsFileContent(
+ workflowLoaders: Record,
+ workflowMetadata: Record,
+): string {
+ const loaderEntries = Object.entries(workflowLoaders)
+ .map(([key, loader]) => ` '${key}': ${loader}`)
+ .join(',\n');
+
+ const metadataEntries = Object.entries(workflowMetadata)
+ .map(([key, metadata]) => {
+ const metadataJson = JSON.stringify(metadata, null, 4)
+ .split('\n')
+ .map((line) => ` ${line}`)
+ .join('\n');
+ return ` '${key}': ${metadataJson.trim()}`;
+ })
+ .join(',\n');
+
+ return `// AUTO-GENERATED - DO NOT EDIT
+// This file is generated by the plugin discovery esbuild plugin
+
+// Generated based on filesystem scan
+export const WORKFLOW_LOADERS = {
+${loaderEntries}
+};
+
+export type WorkflowName = keyof typeof WORKFLOW_LOADERS;
+
+// Optional: Export workflow metadata for quick access
+export const WORKFLOW_METADATA = {
+${metadataEntries}
+};
+`;
+}
diff --git a/build-plugins/tsconfig.json b/build-plugins/tsconfig.json
new file mode 100644
index 00000000..c7c2ce0a
--- /dev/null
+++ b/build-plugins/tsconfig.json
@@ -0,0 +1,13 @@
+{
+ "extends": "../tsconfig.json",
+ "compilerOptions": {
+ "module": "ESNext",
+ "target": "ES2022",
+ "outDir": "../build-plugins-dist",
+ "rootDir": ".",
+ "allowSyntheticDefaultImports": true,
+ "esModuleInterop": true
+ },
+ "include": ["**/*.ts"],
+ "exclude": ["node_modules", "dist"]
+}
\ No newline at end of file
diff --git a/docs/ARCHITECTURE.md b/docs/ARCHITECTURE.md
new file mode 100644
index 00000000..0655827c
--- /dev/null
+++ b/docs/ARCHITECTURE.md
@@ -0,0 +1,558 @@
+# XcodeBuildMCP Architecture
+
+## Table of Contents
+
+1. [Overview](#overview)
+2. [Core Architecture](#core-architecture)
+3. [Design Principles](#design-principles)
+4. [Component Details](#component-details)
+5. [Registration System](#registration-system)
+6. [Tool Naming Conventions & Glossary](#tool-naming-conventions--glossary)
+7. [Testing Architecture](#testing-architecture)
+8. [Build and Deployment](#build-and-deployment)
+9. [Extension Guidelines](#extension-guidelines)
+10. [Performance Considerations](#performance-considerations)
+11. [Security Considerations](#security-considerations)
+
+## Overview
+
+XcodeBuildMCP is a Model Context Protocol (MCP) server that exposes Xcode operations as tools for AI assistants. The architecture emphasizes modularity, type safety, and selective enablement to support diverse development workflows.
+
+### High-Level Objectives
+
+- Expose Xcode-related tools (build, test, deploy, UI automation, etc.) through MCP
+- Run as a long-lived stdio-based server for LLM agents, CLIs, or editors
+- Enable fine-grained, opt-in activation of individual tools or tool groups
+- Support incremental builds via experimental xcodemake with xcodebuild fallback
+
+## Core Architecture
+
+### Runtime Flow
+
+1. **Initialization**
+ - The `xcodebuildmcp` executable, as defined in `package.json`, points to the compiled `build/index.js` which executes the main logic from `src/index.ts`.
+ - Sentry initialized for error tracking (optional)
+ - Version information loaded from `package.json`
+
+2. **Server Creation**
+ - MCP server created with stdio transport
+ - Plugin discovery system initialized
+
+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
+ - All workflow loaders are executed at startup to register tools
+ - If `XCODEBUILDMCP_ENABLED_WORKFLOWS` is set, only those workflows (plus `session-management`) are registered
+
+5. **Tool Registration**
+ - Discovered tools automatically registered with server using pre-generated maps
+ - No manual registration or configuration required
+ - Environment variables control workflow selection behavior
+
+5. **Request Handling**
+ - MCP client calls tool → server routes to tool handler
+ - Zod validates parameters before execution
+ - Tool handler uses shared utilities (build, simctl, etc.)
+ - Returns standardized `ToolResponse`
+
+6. **Response Streaming**
+ - Server streams response back to client
+ - Consistent error handling with `isError` flag
+
+## Design Principles
+
+### 1. **Plugin Autonomy**
+Tools are self-contained units that export a standardized interface. They don't know about the server implementation, ensuring loose coupling and high testability.
+
+### 2. **Pure Functions vs Stateful Components**
+- Most utilities are stateless pure functions
+- Stateful components (e.g., process tracking) isolated in specific tool modules
+- Clear separation between computation and side effects
+
+### 3. **Single Source of Truth**
+- Version from `package.json` drives all version references
+- Tool directory structure is authoritative tool source
+- Environment variables provide consistent configuration interface
+
+### 4. **Feature Isolation**
+- Experimental features behind environment flags
+- Optional dependencies (Sentry, xcodemake) gracefully degrade
+- Tool directory structure enables workflow-specific organization
+
+### 5. **Type Safety Throughout**
+- TypeScript strict mode enabled
+- 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
+
+#### `src/index.ts`
+Main server entry point responsible for:
+- Sentry initialization (if enabled)
+- xcodemake availability check
+- Server creation and startup
+- Process lifecycle management (SIGTERM, SIGINT)
+- Error handling and logging
+
+#### `src/doctor-cli.ts`
+Standalone doctor tool for:
+- Environment validation
+- Dependency checking
+- Configuration verification
+- Troubleshooting assistance
+
+### Server Layer
+
+#### `src/server/server.ts`
+MCP server wrapper providing:
+- Server instance creation
+- stdio transport configuration
+- Request/response handling
+- Error boundary implementation
+
+### Tool Discovery System
+
+#### `src/core/plugin-registry.ts`
+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:
+- `PluginMeta` interface for plugin structure
+- `WorkflowMeta` interface for workflow metadata
+- `WorkflowGroup` interface for directory organization
+
+### Tool Implementation
+
+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.
+
+**Standard Tool Pattern** (`src/mcp/tools/some-workflow/some_tool.ts`):
+
+```typescript
+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 { 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. 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}`);
+
+ 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 **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
+
+```
+src/mcp/resources/
+├── simulators.ts # Simulator data resource
+└── __tests__/ # Resource-specific tests
+```
+
+#### Client Capability Detection
+
+The system automatically detects client MCP capabilities:
+
+```typescript
+// src/core/resources.ts
+export function supportsResources(server?: unknown): boolean {
+ // Detects client capabilities via getClientCapabilities()
+ // Conservative fallback: assumes resource support
+}
+```
+
+#### Resource Implementation Pattern
+
+Resources can reuse existing tool logic for consistency:
+
+```typescript
+// src/mcp/resources/some_resource.ts
+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
+export async function someResourceResourceLogic(
+ executor: CommandExecutor = getDefaultCommandExecutor(),
+): Promise<{ contents: Array<{ text: string }> }> {
+ try {
+ log('info', 'Processing some resource request');
+
+ const result = await getSomeResourceLogic({}, executor);
+
+ if (result.isError) {
+ const errorText = result.content[0]?.text;
+ throw new Error(
+ typeof errorText === 'string' ? errorText : 'Failed to retrieve some resource data',
+ );
+ }
+
+ return {
+ contents: [
+ {
+ text:
+ typeof result.content[0]?.text === 'string'
+ ? result.content[0].text
+ : 'No data for that resource is available',
+ },
+ ],
+ };
+ } catch (error) {
+ const errorMessage = error instanceof Error ? error.message : String(error);
+ log('error', `Error in some_resource resource handler: ${errorMessage}`);
+
+ return {
+ contents: [
+ {
+ text: `Error retrieving resource data: ${errorMessage}`,
+ },
+ ],
+ };
+ }
+}
+
+export default {
+ uri: 'xcodebuildmcp://some_resource',
+ name: 'some_resource',
+ description: 'Returns some resource information',
+ mimeType: 'text/plain',
+ async handler(_uri: URL): Promise<{ contents: Array<{ text: string }> }> {
+ return someResourceResourceLogic();
+ },
+};
+```
+
+## Registration System
+
+XcodeBuildMCP registers tools at startup using the generated workflow loaders. Tool selection can be narrowed using the `XCODEBUILDMCP_ENABLED_WORKFLOWS` environment variable.
+
+### Full Registration (Default)
+
+- **Environment**: `XCODEBUILDMCP_ENABLED_WORKFLOWS` is not set.
+- **Behavior**: All available tools are loaded and registered with the MCP server at startup.
+- **Use Case**: Use this mode when you want the full suite of tools immediately available.
+
+### Selective Workflow Registration
+
+- **Environment**: `XCODEBUILDMCP_ENABLED_WORKFLOWS=simulator,device,project-discovery` (comma-separated)
+- **Behavior**: Only tools from the selected workflows are registered, plus the required `session-management` workflow.
+- **Use Case**: Use this mode to reduce tool surface area for focused workflows.
+
+## Tool Naming Conventions & Glossary
+
+Tools follow a consistent naming pattern to ensure predictability and clarity. Understanding this convention is crucial for both using and developing tools.
+
+### Naming Pattern
+
+The standard naming convention for tools is:
+
+`{action}_{target}_{specifier}_{projectType}`
+
+- **action**: The primary verb describing the tool's function (e.g., `build`, `test`, `get`, `list`).
+- **target**: The main subject of the action (e.g., `sim` for simulator, `dev` for device, `mac` for macOS).
+- **specifier**: A variant that specifies *how* the target is identified (e.g., `id` for UUID, `name` for by-name).
+- **projectType**: The type of Xcode project the tool operates on (e.g., `ws` for workspace, `proj` for project).
+
+Not all parts are required for every tool. For example, `swift_package_build` has an action and a target, but no specifier or project type.
+
+### Examples
+
+- `build_sim_id_ws`: **Build** for a **simulator** identified by its **ID (UUID)** from a **workspace**.
+- `test_dev_proj`: **Test** on a **device** from a **project**.
+- `get_mac_app_path_ws`: **Get** the app path for a **macOS** application from a **workspace**.
+- `list_sims`: **List** all **simulators**.
+
+### Glossary
+
+| Term/Abbreviation | Meaning | Description |
+|---|---|---|
+| `ws` | Workspace | Refers to an `.xcworkspace` file. Used for projects with multiple `.xcodeproj` files or dependencies managed by CocoaPods or SPM. |
+| `proj` | Project | Refers to an `.xcodeproj` file. Used for single-project setups. |
+| `sim` | Simulator | Refers to the iOS, watchOS, tvOS, or visionOS simulator. |
+| `dev` | Device | Refers to a physical Apple device (iPhone, iPad, etc.). |
+| `mac` | macOS | Refers to a native macOS application target. |
+| `id` | Identifier | Refers to the unique identifier (UUID/UDID) of a simulator or device. |
+| `name` | Name | Refers to the human-readable name of a simulator (e.g., "iPhone 15 Pro"). |
+| `cap` | Capture | Used in logging tools, e.g., `start_sim_log_cap`. |
+
+## Testing Architecture
+
+### Framework and Configuration
+
+- **Test Runner**: Vitest 3.x
+- **Environment**: Node.js
+- **Configuration**: `vitest.config.ts`
+- **Test Pattern**: `*.test.ts` files alongside implementation
+
+### Testing Principles
+
+XcodeBuildMCP uses a strict **Dependency Injection (DI)** pattern for testing, which completely bans the use of traditional mocking libraries like Vitest's `vi.mock` or `vi.fn`. This ensures that tests are robust, maintainable, and verify the actual integration between components.
+
+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. 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 { 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 () => {
+ // 1. Create a mock executor to simulate command-line results
+ const mockExecutor = createMockExecutor({
+ success: true,
+ output: 'Command output'
+ });
+
+ // 2. Call the tool's logic function, injecting the mock executor
+ const result = await someToolLogic({ requiredParam: 'value' }, mockExecutor);
+
+ // 3. Assert the final result
+ expect(result).toEqual({
+ content: [{ type: 'text', text: 'Expected output' }],
+ isError: false
+ });
+ });
+});
+```
+
+## Build and Deployment
+
+### Build Process
+
+1. **Version Generation**
+ ```bash
+ npm run build
+ ```
+ - 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
+
+4. **Build Configuration** (`tsup.config.ts`)
+ - Entry points: `index.ts`, `doctor-cli.ts`
+ - Output format: ESM
+ - Target: Node 18+
+ - Source maps enabled
+
+5. **Distribution Structure**
+ ```
+ build/
+ ├── index.js # Main server executable
+ ├── doctor-cli.js # Doctor tool
+ └── *.js.map # Source maps
+ ```
+
+### npm Package
+
+- **Name**: `xcodebuildmcp`
+- **Executables**:
+ - `xcodebuildmcp` → Main server
+ - `xcodebuildmcp-doctor` → Doctor tool
+- **Dependencies**: Minimal runtime dependencies
+- **Platform**: macOS only (due to Xcode requirement)
+
+### Bundled Resources
+
+```
+bundled/
+├── axe # UI automation binary
+└── Frameworks/ # Facebook device frameworks
+ ├── FBControlCore.framework
+ ├── FBDeviceControl.framework
+ └── FBSimulatorControl.framework
+```
+
+## Extension Guidelines
+
+This project is designed to be extensible. For comprehensive instructions on creating new tools, workflow groups, and resources, please refer to the dedicated [**Plugin Development Guide**](docs/PLUGIN_DEVELOPMENT.md).
+
+The guide covers:
+- The auto-discovery system architecture.
+- The dependency injection pattern required for all new tools.
+- How to organize tools into workflow groups.
+- Testing guidelines and patterns.
+
+## Performance Considerations
+
+### 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**: Workflow modules are loaded via dynamic imports when registration occurs, 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
+
+### Runtime Performance
+
+- **Stateless Operations**: Most tools complete quickly
+- **Process Management**: Long-running processes tracked separately
+- **Incremental Builds**: xcodemake provides significant speedup
+- **Parallel Execution**: Tools can run concurrently
+
+### Memory Management
+
+- **Process Cleanup**: Proper process termination handling
+- **Log Rotation**: Captured logs have size limits
+- **Resource Disposal**: Explicit cleanup in lifecycle hooks
+
+### Optimization Strategies
+
+1. **Use Tool Groups**: Enable only needed workflows
+2. **Enable Incremental Builds**: Set `INCREMENTAL_BUILDS_ENABLED=true`
+3. **Limit Log Capture**: Use structured logging when possible
+
+## Security Considerations
+
+### Input Validation
+
+- All tool inputs validated with Zod schemas
+- Command injection prevented via proper escaping
+- Path traversal protection in file operations
+
+### Process Isolation
+
+- Tools run with user permissions
+- No privilege escalation
+- Sandboxed execution environment
+
+### Error Handling
+
+- Sensitive information scrubbed from errors
+- Stack traces limited to application code
+- Sentry integration respects privacy settings
diff --git a/docs/CODE_QUALITY.md b/docs/CODE_QUALITY.md
new file mode 100644
index 00000000..274f5ab1
--- /dev/null
+++ b/docs/CODE_QUALITY.md
@@ -0,0 +1,303 @@
+# XcodeBuildMCP Code Quality Guide
+
+This guide consolidates all code quality, linting, and architectural compliance information for the XcodeBuildMCP project.
+
+## Table of Contents
+
+1. [Overview](#overview)
+2. [ESLint Configuration](#eslint-configuration)
+3. [Architectural Rules](#architectural-rules)
+4. [Development Scripts](#development-scripts)
+5. [Code Pattern Violations](#code-pattern-violations)
+6. [Type Safety Migration](#type-safety-migration)
+7. [Best Practices](#best-practices)
+
+## Overview
+
+XcodeBuildMCP enforces code quality through multiple layers:
+
+1. **ESLint**: Handles general code quality, TypeScript rules, and stylistic consistency
+2. **TypeScript**: Enforces type safety with strict mode
+3. **Pattern Checker**: Enforces XcodeBuildMCP-specific architectural rules
+4. **Migration Scripts**: Track progress on type safety improvements
+
+## ESLint Configuration
+
+### Current Configuration
+
+The project uses a comprehensive ESLint setup that covers:
+
+- TypeScript type safety rules
+- Code style consistency
+- Import ordering
+- Unused variable detection
+- Testing best practices
+
+### ESLint Rules
+
+For detailed ESLint rules and rationale, see [ESLINT_RULES.md](./ESLINT_RULES.md).
+
+### Running ESLint
+
+```bash
+# Check for linting issues
+npm run lint
+
+# Auto-fix linting issues
+npm run lint:fix
+```
+
+## Architectural Rules
+
+XcodeBuildMCP enforces several architectural patterns that cannot be expressed through ESLint:
+
+### 1. Dependency Injection Pattern
+
+**Rule**: All tools must use dependency injection for external interactions.
+
+✅ **Allowed**:
+- `createMockExecutor()` for command execution mocking
+- `createMockFileSystemExecutor()` for file system mocking
+- Logic functions accepting `executor?: CommandExecutor` parameter
+
+❌ **Forbidden**:
+- Direct use of `vi.mock()`, `vi.fn()`, or any Vitest mocking
+- Direct calls to `execSync`, `spawn`, or `exec` in production code
+- Testing handler functions directly
+
+### 2. Handler Signature Compliance
+
+**Rule**: MCP handlers must have exact signatures as required by the SDK.
+
+✅ **Tool Handler Signature**:
+```typescript
+async handler(args: Record): Promise
+```
+
+✅ **Resource Handler Signature**:
+```typescript
+async handler(uri: URL): Promise<{ contents: Array<{ text: string }> }>
+```
+
+❌ **Forbidden**:
+- Multiple parameters in handlers
+- Optional parameters
+- Dependency injection parameters in handlers
+
+### 3. Testing Architecture
+
+**Rule**: Tests must only call logic functions, never handlers directly.
+
+✅ **Correct Pattern**:
+```typescript
+const result = await myToolLogic(params, mockExecutor);
+```
+
+❌ **Forbidden Pattern**:
+```typescript
+const result = await myTool.handler(params);
+```
+
+### 4. Server Type Safety
+
+**Rule**: MCP server instances must use proper SDK types, not generic casts.
+
+✅ **Correct Pattern**:
+```typescript
+import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
+const server = (globalThis as { mcpServer?: McpServer }).mcpServer;
+server.server.createMessage({...});
+```
+
+❌ **Forbidden Pattern**:
+```typescript
+const server = (globalThis as { mcpServer?: Record }).mcpServer;
+const serverInstance = (server.server ?? server) as Record & {...};
+```
+
+## Development Scripts
+
+### Core Scripts
+
+```bash
+# Build the project
+npm run build
+
+# Run type checking
+npm run typecheck
+
+# Run tests
+npm run test
+
+# Check code patterns (architectural compliance)
+node scripts/check-code-patterns.js
+
+# Check type safety migration progress
+npm run check-migration
+```
+
+### Pattern Checker Usage
+
+The pattern checker enforces XcodeBuildMCP-specific architectural rules:
+
+```bash
+# Check all patterns
+node scripts/check-code-patterns.js
+
+# Check specific pattern type
+node scripts/check-code-patterns.js --pattern=vitest
+node scripts/check-code-patterns.js --pattern=execsync
+node scripts/check-code-patterns.js --pattern=handler
+node scripts/check-code-patterns.js --pattern=handler-testing
+node scripts/check-code-patterns.js --pattern=server-typing
+
+# Get help
+node scripts/check-code-patterns.js --help
+```
+
+### Tool Summary Scripts
+
+```bash
+# Show tool and resource summary
+npm run tools
+
+# List all tools
+npm run tools:list
+
+# List both tools and resources
+npm run tools:all
+```
+
+## Code Pattern Violations
+
+The pattern checker identifies the following violations:
+
+### 1. Vitest Mocking Violations
+
+**What**: Any use of Vitest mocking functions
+**Why**: Breaks dependency injection architecture
+**Fix**: Use `createMockExecutor()` instead
+
+### 2. ExecSync Violations
+
+**What**: Direct use of Node.js child_process functions in production code
+**Why**: Bypasses CommandExecutor dependency injection
+**Fix**: Accept `CommandExecutor` parameter and use it
+
+### 3. Handler Signature Violations
+
+**What**: Handlers with incorrect parameter signatures
+**Why**: MCP SDK requires exact signatures
+**Fix**: Move dependencies inside handler body
+
+### 4. Handler Testing Violations
+
+**What**: Tests calling `.handler()` directly
+**Why**: Violates dependency injection principle
+**Fix**: Test logic functions instead
+
+### 5. Improper Server Typing Violations
+
+**What**: Casting MCP server instances to `Record` or using custom interfaces instead of SDK types
+**Why**: Breaks type safety and prevents proper API usage
+**Fix**: Import `McpServer` from SDK and use proper typing instead of generic casts
+
+## Type Safety Migration
+
+The project is migrating to improved type safety using the `createTypedTool` factory:
+
+### Check Migration Status
+
+```bash
+# Show summary
+npm run check-migration
+
+# Show detailed analysis
+npm run check-migration:verbose
+
+# Show only unmigrated tools
+npm run check-migration:unfixed
+```
+
+### Migration Benefits
+
+1. **Compile-time type safety** for tool parameters
+2. **Automatic Zod schema validation**
+3. **Better IDE support** and autocomplete
+4. **Consistent error handling**
+
+## Best Practices
+
+### 1. Before Committing
+
+Always run these checks before committing:
+
+```bash
+npm run build # Ensure code compiles
+npm run typecheck # Check TypeScript types
+npm run lint # Check linting rules
+npm run test # Run tests
+node scripts/check-code-patterns.js # Check architectural compliance
+```
+
+### 2. Adding New Tools
+
+1. Use dependency injection pattern
+2. Follow handler signature requirements
+3. Create comprehensive tests (test logic, not handlers)
+4. Use `createTypedTool` factory for type safety
+5. Document parameter schemas clearly
+
+### 3. Writing Tests
+
+1. Import the logic function, not the default export
+2. Use `createMockExecutor()` for mocking
+3. Test three dimensions: validation, command generation, output processing
+4. Never test handlers directly
+
+### 4. Code Organization
+
+1. Keep tools in appropriate workflow directories
+2. Share common tools via `-shared` directories
+3. Re-export shared tools, don't duplicate
+4. Follow naming conventions for tools
+
+## Automated Enforcement
+
+The project uses multiple layers of automated enforcement:
+
+1. **Pre-commit**: ESLint and TypeScript checks (if configured)
+2. **CI Pipeline**: All checks run on every PR
+3. **PR Blocking**: Checks must pass before merge
+4. **Code Review**: Automated and manual review processes
+
+## Troubleshooting
+
+### ESLint False Positives
+
+If ESLint reports false positives in test files, check that:
+1. Test files are properly configured in `.eslintrc.json`
+2. Test-specific rules are applied correctly
+3. File patterns match your test file locations
+
+### Pattern Checker Issues
+
+If the pattern checker reports unexpected violations:
+1. Check if it's a legitimate architectural violation
+2. Verify the file is in the correct directory
+3. Ensure you're using the latest pattern definitions
+
+### Type Safety Migration
+
+If migration tooling reports incorrect status:
+1. Ensure the tool exports follow standard patterns
+2. Check that schema definitions are properly typed
+3. Verify the handler uses the schema correctly
+
+## Future Improvements
+
+1. **Automated Fixes**: Add auto-fix capability to pattern checker
+2. **IDE Integration**: Create VS Code extension for real-time checking
+3. **Performance Metrics**: Add build and test performance tracking
+4. **Complexity Analysis**: Add code complexity metrics
+5. **Documentation Linting**: Add documentation quality checks
\ No newline at end of file
diff --git a/docs/CONTRIBUTING.md b/docs/CONTRIBUTING.md
new file mode 100644
index 00000000..82aec783
--- /dev/null
+++ b/docs/CONTRIBUTING.md
@@ -0,0 +1,354 @@
+# Contributing
+
+Contributions are welcome! Here's how you can help improve XcodeBuildMCP.
+
+## Local development setup
+
+### Prerequisites
+
+In addition to the prerequisites mentioned in the [Getting started](README.md/#getting-started) section of the README, you will also need:
+
+- Node.js (v18 or later)
+- npm
+
+#### Optional: Enabling UI Automation
+
+When running locally, you'll need to install AXe for UI automation:
+
+```bash
+# Install axe (required for UI automation)
+brew tap cameroncooke/axe
+brew install axe
+```
+
+### Installation
+
+1. Clone the repository
+2. Install dependencies:
+ ```
+ npm install
+ ```
+3. Build the project:
+ ```
+ npm run build
+ ```
+4. Start the server:
+ ```
+ node build/index.js
+ ```
+
+### Configure your MCP client
+
+Most MCP clients (Cursor, VS Code, Windsurf, Claude Desktop etc) have standardised on the following JSON configuration format, just add the the following to your client's JSON configuration's `mcpServers` object:
+
+```json
+{
+ "mcpServers": {
+ "XcodeBuildMCP": {
+ "command": "node",
+ "args": [
+ "/path_to/XcodeBuildMCP/build/index.js"
+ ]
+ }
+ }
+}
+```
+
+### Developing using VS Code
+
+VS Code is especially good for developing XcodeBuildMCP as it has a built-in way to view MCP client/server logs as well as the ability to configure MCP servers at a project level. It probably has the most comprehensive support for MCP development.
+
+To make your development workflow in VS Code more efficient:
+
+1. **Start the MCP Server**: Open the `.vscode/mcp.json` file. You can start the `xcodebuildmcp-dev` server either by clicking the `Start` CodeLens that appears above the server definition, or by opening the Command Palette (`Cmd+Shift+P` or `Ctrl+Shift+P`), running `Mcp: List Servers`, selecting `xcodebuildmcp-dev`, and starting the server.
+2. **Launch the Debugger**: Press `F5` to attach the Node.js debugger.
+
+Once these steps are completed, you can utilize the tools from the MCP server you are developing within this repository in agent mode.
+For more details on how to work with MCP servers in VS Code see: https://code.visualstudio.com/docs/copilot/chat/mcp-servers
+
+### Debugging
+
+#### MCP Inspector (Basic Debugging)
+
+You can use MCP Inspector for basic debugging via:
+
+```bash
+npm run inspect
+```
+
+or if you prefer the explicit command:
+
+```bash
+npx @modelcontextprotocol/inspector node build/index.js
+```
+
+#### Reloaderoo (Advanced Debugging) - **RECOMMENDED**
+
+For development and debugging, we strongly recommend using **Reloaderoo**, which provides hot-reloading capabilities and advanced debugging features for MCP servers.
+
+Reloaderoo operates in two modes:
+
+##### 1. Proxy Mode (Hot-Reloading)
+Provides transparent hot-reloading without disconnecting your MCP client:
+
+```bash
+# Install reloaderoo globally
+npm install -g reloaderoo
+
+# Start XcodeBuildMCP through reloaderoo proxy
+reloaderoo -- node build/index.js
+```
+
+**Benefits**:
+- 🔄 Hot-reload server without restarting client
+- 🛠️ Automatic `restart_server` tool added to toolset
+- 🌊 Transparent MCP protocol forwarding
+- 📡 Full protocol support (tools, resources, prompts)
+
+**MCP Client Configuration for Proxy Mode**:
+```json
+"XcodeBuildMCP": {
+ "command": "reloaderoo",
+ "args": ["--", "node", "/path/to/XcodeBuildMCP/build/index.js"],
+ "env": {
+ "XCODEBUILDMCP_DEBUG": "true"
+ }
+}
+```
+
+##### 2. Inspection Mode (Raw MCP Debugging)
+Exposes debug tools for making raw MCP protocol calls and inspecting server responses:
+
+```bash
+# Start reloaderoo in inspection mode
+reloaderoo inspect mcp -- node build/index.js
+```
+
+**Available Debug Tools**:
+- `list_tools` - List all server tools
+- `call_tool` - Execute any server tool with parameters
+- `list_resources` - List all server resources
+- `read_resource` - Read any server resource
+- `list_prompts` - List all server prompts
+- `get_prompt` - Get any server prompt
+- `get_server_info` - Get comprehensive server information
+- `ping` - Test server connectivity
+
+**MCP Client Configuration for Inspection Mode**:
+```json
+"XcodeBuildMCP": {
+ "command": "node",
+ "args": [
+ "/path/to/reloaderoo/dist/bin/reloaderoo.js",
+ "inspect", "mcp",
+ "--working-dir", "/path/to/XcodeBuildMCP",
+ "--",
+ "node", "/path/to/XcodeBuildMCP/build/index.js"
+ ],
+ "env": {
+ "XCODEBUILDMCP_DEBUG": "true"
+ }
+}
+```
+
+#### Workflow Selection Testing
+
+Test full vs. selective workflow registration during development:
+
+```bash
+# Test full tool registration (default)
+reloaderoo inspect mcp -- node build/index.js
+
+# Test selective workflow registration
+XCODEBUILDMCP_ENABLED_WORKFLOWS=simulator,device reloaderoo inspect mcp -- node build/index.js
+```
+**Key Differences to Test**:
+- **Full Registration**: All tools are available immediately via `list_tools`
+- **Selective Registration**: Only tools from the selected workflows (plus `session-management`) are available
+
+#### Using XcodeBuildMCP doctor tool
+
+Running the XcodeBuildMCP server with the environmental variable `XCODEBUILDMCP_DEBUG=true` will expose a new doctor MCP tool called `doctor` which your agent can call to get information about the server's environment, available tools, and configuration status.
+
+> [!NOTE]
+> You can also call the doctor tool directly using the following command but be advised that the output may vary from that of the MCP tool call due to environmental differences:
+> ```bash
+> npm run doctor
+> ```
+
+#### Development Workflow with Reloaderoo
+
+1. **Start Development Session**:
+ ```bash
+ # Terminal 1: Start in hot-reload mode
+ reloaderoo -- node build/index.js
+
+ # Terminal 2: Start build watcher
+ npm run build:watch
+ ```
+
+2. **Make Changes**: Edit source code in `src/`
+
+3. **Test Changes**: Ask your AI client to restart the server:
+ ```
+ "Please restart the MCP server to load my changes"
+ ```
+ The AI will automatically call the `restart_server` tool provided by reloaderoo.
+
+4. **Verify Changes**: New functionality immediately available without reconnecting client
+
+## Architecture and Code Standards
+
+Before making changes, please familiarize yourself with:
+- [ARCHITECTURE.md](ARCHITECTURE.md) - Comprehensive architectural overview
+- [CLAUDE.md](CLAUDE.md) - AI assistant guidelines and testing principles
+- [TOOLS.md](TOOLS.md) - Complete tool documentation
+- [TOOL_OPTIONS.md](TOOL_OPTIONS.md) - Tool configuration options
+
+### Code Quality Requirements
+
+1. **Follow existing code patterns and structure**
+2. **Use TypeScript strictly** - no `any` types, proper typing throughout
+3. **Add proper error handling and logging** - all failures must set `isError: true`
+4. **Update documentation for new features**
+5. **Test with example projects before submitting**
+
+### Testing Standards
+
+All contributions must adhere to the testing standards outlined in the [**XcodeBuildMCP Plugin Testing Guidelines (docs/TESTING.md)**](docs/TESTING.md). This is the canonical source of truth for all testing practices.
+
+**Key Principles (Summary):**
+- **No Vitest Mocking**: All forms of `vi.mock`, `vi.fn`, `vi.spyOn`, etc., are strictly forbidden.
+- **Dependency Injection**: All external dependencies (command execution, file system access) must be injected into tool logic functions using the `CommandExecutor` and `FileSystemExecutor` patterns.
+- **Test Production Code**: Tests must import and execute the actual tool logic, not mock implementations.
+- **Comprehensive Coverage**: Tests must cover input validation, command generation, and output processing.
+
+Please read [docs/TESTING.md](docs/TESTING.md) in its entirety before writing tests.
+
+### Pre-Commit Checklist
+
+**MANDATORY**: Run these commands before any commit and ensure they all pass:
+
+```bash
+# 1. Run linting (must pass with 0 errors)
+npm run lint
+
+# 2. Run formatting (must format all files)
+npm run format
+
+# 3. Run build (must compile successfully)
+npm run build
+
+# 4. Run tests (all tests must pass)
+npm test
+```
+
+**NO EXCEPTIONS**: Code that fails any of these commands cannot be committed.
+
+## Making changes
+
+1. Fork the repository and create a new branch
+2. Follow the TypeScript best practices and existing code style
+3. Add proper parameter validation and error handling
+
+## Plugin Development
+
+For comprehensive instructions on creating new tools and workflow groups, see our dedicated [Plugin Development Guide](docs/PLUGIN_DEVELOPMENT.md).
+
+The plugin development guide covers:
+- Auto-discovery system architecture
+- Tool creation with dependency injection patterns
+- Workflow group organization
+- Testing guidelines and patterns
+- Workflow registration and selection
+
+### Quick Plugin Development Checklist
+
+1. Choose appropriate workflow directory in `src/mcp/tools/`
+2. Follow naming conventions: `{action}_{target}_{specifier}_{projectType}`
+3. Use dependency injection pattern with separate logic functions
+4. Create comprehensive tests using `createMockExecutor()`
+5. Add workflow metadata if creating new workflow group
+
+See [PLUGIN_DEVELOPMENT.md](docs/PLUGIN_DEVELOPMENT.md) for complete details.
+
+### Working with Project Templates
+
+XcodeBuildMCP uses external template repositories for the iOS and macOS project scaffolding features. These templates are maintained separately to allow independent versioning and updates.
+
+#### Template Repositories
+
+- **iOS Template**: [XcodeBuildMCP-iOS-Template](https://github.com/cameroncooke/XcodeBuildMCP-iOS-Template)
+- **macOS Template**: [XcodeBuildMCP-macOS-Template](https://github.com/cameroncooke/XcodeBuildMCP-macOS-Template)
+
+#### Local Template Development
+
+When developing or testing changes to the templates:
+
+1. Clone the template repository you want to work on:
+ ```bash
+ git clone https://github.com/cameroncooke/XcodeBuildMCP-iOS-Template.git
+ git clone https://github.com/cameroncooke/XcodeBuildMCP-macOS-Template.git
+ ```
+
+2. Set the appropriate environment variable to use your local template:
+ ```bash
+ # For iOS template development
+ export XCODEBUILDMCP_IOS_TEMPLATE_PATH=/path/to/XcodeBuildMCP-iOS-Template
+
+ # For macOS template development
+ export XCODEBUILDMCP_MACOS_TEMPLATE_PATH=/path/to/XcodeBuildMCP-macOS-Template
+ ```
+
+3. When using MCP clients, add these environment variables to your MCP configuration:
+```json
+"XcodeBuildMCP": {
+ "command": "node",
+ "args": ["/path_to/XcodeBuildMCP/build/index.js"],
+ "env": {
+ "XCODEBUILDMCP_IOS_TEMPLATE_PATH": "/path/to/XcodeBuildMCP-iOS-Template",
+ "XCODEBUILDMCP_MACOS_TEMPLATE_PATH": "/path/to/XcodeBuildMCP-macOS-Template"
+ }
+}
+```
+
+4. The scaffold tools will use your local templates instead of downloading from GitHub releases.
+
+#### Template Versioning
+
+- Templates are versioned independently from XcodeBuildMCP
+- The default template version is specified in `package.json` under `templateVersion`
+- You can override the template version with `XCODEBUILD_MCP_TEMPLATE_VERSION` environment variable
+- To update the default template version:
+ 1. Update `templateVersion` in `package.json`
+ 2. Run `npm run build` to regenerate version.ts
+ 3. Create a new XcodeBuildMCP release
+
+#### Testing Template Changes
+
+1. Make changes to your local template
+2. Test scaffolding with your changes using the local override
+3. Verify the scaffolded project builds and runs correctly
+4. Once satisfied, create a PR in the template repository
+5. After merging, create a new release in the template repository using the release script
+
+## Testing
+
+1. Build the project with `npm run build`
+2. Test your changes with MCP Inspector
+3. Verify tools work correctly with different MCP clients
+
+## Submitting
+
+1. Run `npm run lint` to check for linting issues (use `npm run lint:fix` to auto-fix)
+2. Run `npm run format:check` to verify formatting (use `npm run format` to fix)
+3. Update documentation if you've added or modified features
+4. Add your changes to the CHANGELOG.md file
+5. Push your changes and create a pull request with a clear description
+6. Link any related issues
+
+For major changes or new features, please open an issue first to discuss your proposed changes.
+
+## Code of Conduct
+
+Please follow our [Code of Conduct](CODE_OF_CONDUCT.md) and community guidelines.
diff --git a/docs/ESLINT_TYPE_SAFETY.md b/docs/ESLINT_TYPE_SAFETY.md
new file mode 100644
index 00000000..b0c4760c
--- /dev/null
+++ b/docs/ESLINT_TYPE_SAFETY.md
@@ -0,0 +1,136 @@
+# ESLint Type Safety Rules
+
+This document explains the ESLint rules added to prevent TypeScript anti-patterns and improve type safety.
+
+## Rules Added
+
+### Error-Level Rules (Block CI/Deployment)
+
+These rules prevent dangerous type casting patterns that can lead to runtime errors:
+
+#### `@typescript-eslint/consistent-type-assertions`
+- **Purpose**: Prevents dangerous object literal type assertions
+- **Example**: Prevents `{ foo: 'bar' } as ComplexType`
+- **Rationale**: Object literal assertions can hide missing properties
+
+#### `@typescript-eslint/no-unsafe-*` (5 rules)
+- **no-unsafe-argument**: Prevents passing `any` to typed parameters
+- **no-unsafe-assignment**: Prevents assigning `any` to typed variables
+- **no-unsafe-call**: Prevents calling `any` as a function
+- **no-unsafe-member-access**: Prevents accessing properties on `any`
+- **no-unsafe-return**: Prevents returning `any` from typed functions
+
+**Example of prevented anti-pattern:**
+```typescript
+// ❌ BAD - This would now be an ESLint error
+function handleParams(args: Record) {
+ const typedParams = args as MyToolParams; // Unsafe casting
+ return typedParams.someProperty as string; // Unsafe member access
+}
+
+// ✅ GOOD - Proper validation approach
+function handleParams(args: Record) {
+ const typedParams = MyToolParamsSchema.parse(args); // Runtime validation
+ return typedParams.someProperty; // Type-safe access
+}
+```
+
+#### `@typescript-eslint/ban-ts-comment`
+- **Purpose**: Prevents unsafe TypeScript comments
+- **Blocks**: `@ts-ignore`, `@ts-nocheck`
+- **Allows**: `@ts-expect-error` (with description)
+
+### Warning-Level Rules (Encourage Best Practices)
+
+These rules encourage modern TypeScript patterns but don't block builds:
+
+#### `@typescript-eslint/prefer-nullish-coalescing`
+- **Purpose**: Prefer `??` over `||` for default values
+- **Example**: `value ?? 'default'` instead of `value || 'default'`
+- **Rationale**: More precise handling of falsy values (0, '', false)
+
+#### `@typescript-eslint/prefer-optional-chain`
+- **Purpose**: Prefer `?.` for safe property access
+- **Example**: `obj?.prop` instead of `obj && obj.prop`
+- **Rationale**: More concise and readable
+
+#### `@typescript-eslint/prefer-as-const`
+- **Purpose**: Prefer `as const` for literal types
+- **Example**: `['a', 'b'] as const` instead of `['a', 'b'] as string[]`
+
+## Test File Exceptions
+
+Test files (`.test.ts`) have relaxed rules for flexibility:
+- All `no-unsafe-*` rules are disabled
+- `no-explicit-any` is disabled
+- Tests often need to test error conditions and edge cases
+
+## Impact on Codebase
+
+### Current Status (Post-Implementation)
+- **387 total issues detected**
+ - **207 errors**: Require fixing for type safety
+ - **180 warnings**: Can be gradually improved
+
+### Gradual Migration Strategy
+
+1. **Phase 1** (Immediate): Error-level rules prevent new anti-patterns
+2. **Phase 2** (Ongoing): Gradually fix warning-level violations
+3. **Phase 3** (Future): Consider promoting warnings to errors
+
+### Benefits
+
+1. **Prevents Regression**: New code can't introduce the anti-patterns we just fixed
+2. **Runtime Safety**: Catches potential runtime errors at compile time
+3. **Code Quality**: Encourages modern TypeScript best practices
+4. **Developer Experience**: Better IDE support and autocomplete
+
+## Related Issues Fixed
+
+These rules prevent the specific anti-patterns identified in PR review:
+
+1. **✅ Type Casting in Parameters**: `args as SomeType` patterns now flagged
+2. **✅ Unsafe Property Access**: `params.field as string` patterns prevented
+3. **✅ Missing Validation**: Encourages schema validation over casting
+4. **✅ Return Type Mismatches**: Function signature inconsistencies caught
+5. **✅ Nullish Coalescing**: Promotes safer default value handling
+
+## Agent Orchestration for ESLint Fixes
+
+### Parallel Agent Strategy
+
+When fixing ESLint issues across the codebase:
+
+1. **Deploy Multiple Agents**: Run agents in parallel on different files
+2. **Single File Focus**: Each agent works on ONE tool file at a time
+3. **Individual Linting**: Agents run `npm run lint path/to/single/file.ts` only
+4. **Immediate Commits**: Commit each agent's work as soon as they complete
+5. **Never Wait**: Don't wait for all agents to finish before committing
+6. **Avoid Full Linting**: Never run `npm run lint` without a file path (eats context)
+7. **Progress Tracking**: Update todo list and periodically check overall status
+8. **Loop Until Done**: Keep deploying agents until all issues are resolved
+
+### Example Commands for Agents
+
+```bash
+# Single file linting (what agents should run)
+npm run lint src/mcp/tools/device-project/test_device_proj.ts
+
+# NOT this (too much context)
+npm run lint
+```
+
+### Commit Strategy
+
+- **Individual commits**: One commit per agent completion
+- **Clear messages**: `fix: resolve ESLint errors in tool_name.ts`
+- **Never batch**: Don't wait to commit multiple files together
+- **Progress preservation**: Each fix is immediately saved
+
+## Future Improvements
+
+Consider adding these rules in future iterations:
+
+- `@typescript-eslint/strict-boolean-expressions`: Stricter boolean logic
+- `@typescript-eslint/prefer-reduce-type-parameter`: Better generic usage
+- `@typescript-eslint/switch-exhaustiveness-check`: Complete switch statements
\ No newline at end of file
diff --git a/docs/MANUAL_TESTING.md b/docs/MANUAL_TESTING.md
new file mode 100644
index 00000000..7b1ff02c
--- /dev/null
+++ b/docs/MANUAL_TESTING.md
@@ -0,0 +1,749 @@
+# XcodeBuildMCP Manual Testing Guidelines
+
+This document provides comprehensive guidelines for manual black-box testing of XcodeBuildMCP using Reloaderoo inspect commands. This is the authoritative guide for validating all tools through the Model Context Protocol interface.
+
+## Table of Contents
+
+1. [Testing Philosophy](#testing-philosophy)
+2. [Black Box Testing via Reloaderoo](#black-box-testing-via-reloaderoo)
+3. [Testing Psychology & Bias Prevention](#testing-psychology--bias-prevention)
+4. [Tool Dependency Graph Testing Strategy](#tool-dependency-graph-testing-strategy)
+5. [Prerequisites](#prerequisites)
+6. [Step-by-Step Testing Process](#step-by-step-testing-process)
+7. [Error Testing](#error-testing)
+8. [Testing Report Generation](#testing-report-generation)
+9. [Troubleshooting](#troubleshooting)
+
+## Testing Philosophy
+
+### 🚨 CRITICAL: THOROUGHNESS OVER EFFICIENCY - NO SHORTCUTS ALLOWED
+
+**ABSOLUTE PRINCIPLE: EVERY TOOL MUST BE TESTED INDIVIDUALLY**
+
+**🚨 MANDATORY TESTING SCOPE - NO EXCEPTIONS:**
+- **EVERY SINGLE TOOL** - All tools must be tested individually, one by one
+- **NO REPRESENTATIVE SAMPLING** - Testing similar tools does NOT validate other tools
+- **NO PATTERN RECOGNITION SHORTCUTS** - Similar-looking tools may have different behaviors
+- **NO EFFICIENCY OPTIMIZATIONS** - Thoroughness is more important than speed
+- **NO TIME CONSTRAINTS** - This is a long-running task with no deadline pressure
+
+**❌ FORBIDDEN EFFICIENCY SHORTCUTS:**
+- **NEVER** assume testing `build_sim_id_proj` validates `build_sim_name_proj`
+- **NEVER** skip tools because they "look similar" to tested ones
+- **NEVER** use representative sampling instead of complete coverage
+- **NEVER** stop testing due to time concerns or perceived redundancy
+- **NEVER** group tools together for batch testing
+- **NEVER** make assumptions about untested tools based on tested patterns
+
+**✅ REQUIRED COMPREHENSIVE APPROACH:**
+1. **Individual Tool Testing**: Each tool gets its own dedicated test execution
+2. **Complete Documentation**: Every tool result must be recorded, regardless of outcome
+3. **Systematic Progress**: Use TodoWrite to track every single tool as tested/untested
+4. **Failure Documentation**: Test tools that cannot work and mark them as failed/blocked
+5. **No Assumptions**: Treat each tool as potentially unique requiring individual validation
+
+**TESTING COMPLETENESS VALIDATION:**
+- **Start Count**: Record exact number of tools discovered using `npm run tools`
+- **End Count**: Verify same number of tools have been individually tested
+- **Missing Tools = Testing Failure**: If any tools remain untested, the testing is incomplete
+- **TodoWrite Tracking**: Every tool must appear in todo list and be marked completed
+
+## Black Box Testing via Reloaderoo
+
+### 🚨 CRITICAL: Black Box Testing via Reloaderoo Inspect
+
+**DEFINITION: Black Box Testing**
+Black Box Testing means testing ONLY through external interfaces without any knowledge of internal implementation. For XcodeBuildMCP, this means testing exclusively through the Model Context Protocol (MCP) interface using Reloaderoo as the MCP client.
+
+**🚨 MANDATORY: RELOADEROO INSPECT IS THE ONLY ALLOWED TESTING METHOD**
+
+**ABSOLUTE TESTING RULES - NO EXCEPTIONS:**
+
+1. **✅ ONLY ALLOWED: Reloaderoo Inspect Commands**
+ - `npx reloaderoo@latest inspect call-tool "TOOL_NAME" --params 'JSON' -- node build/index.js`
+ - `npx reloaderoo@latest inspect list-tools -- node build/index.js`
+ - `npx reloaderoo@latest inspect read-resource "URI" -- node build/index.js`
+ - `npx reloaderoo@latest inspect server-info -- node build/index.js`
+ - `npx reloaderoo@latest inspect ping -- node build/index.js`
+
+2. **❌ COMPLETELY FORBIDDEN ACTIONS:**
+ - **NEVER** call `mcp__XcodeBuildMCP__tool_name()` functions directly
+ - **NEVER** use MCP server tools as if they were native functions
+ - **NEVER** access internal server functionality
+ - **NEVER** read source code to understand how tools work
+ - **NEVER** examine implementation files during testing
+ - **NEVER** diagnose internal server issues or registration problems
+ - **NEVER** suggest code fixes or implementation changes
+
+3. **🚨 CRITICAL VIOLATION EXAMPLES:**
+ ```typescript
+ // ❌ FORBIDDEN - Direct MCP tool calls
+ await mcp__XcodeBuildMCP__list_devices();
+ await mcp__XcodeBuildMCP__build_sim_id_proj({ ... });
+
+ // ❌ FORBIDDEN - Using tools as native functions
+ const devices = await list_devices();
+ const result = await doctor();
+
+ // ✅ CORRECT - Only through Reloaderoo inspect
+ npx reloaderoo@latest inspect call-tool "list_devices" --params '{}' -- node build/index.js
+ npx reloaderoo@latest inspect call-tool "doctor" --params '{}' -- node build/index.js
+ ```
+
+**WHY RELOADEROO INSPECT IS MANDATORY:**
+- **Higher Fidelity**: Provides clear input/output visibility for each tool call
+- **Real-world Simulation**: Tests exactly how MCP clients interact with the server
+- **Interface Validation**: Ensures MCP protocol compliance and proper JSON formatting
+- **Black Box Enforcement**: Prevents accidental access to internal implementation details
+- **Clean State**: Each tool call runs with a fresh MCP server instance, preventing cross-contamination
+
+**IMPORTANT: STATEFUL TOOL LIMITATIONS**
+
+**Reloaderoo Inspect Behavior:**
+Reloaderoo starts a fresh MCP server instance for each individual tool call and terminates it immediately after the response. This ensures:
+- ✅ **Clean Testing Environment**: No state contamination between tool calls
+- ✅ **Isolated Testing**: Each tool test is independent and repeatable
+- ✅ **Real-world Accuracy**: Simulates how most MCP clients interact with servers
+
+**Expected False Negatives:**
+Some tools rely on in-memory state within the MCP server and will fail when tested via Reloaderoo inspect. These failures are **expected and acceptable** as false negatives:
+
+- **`swift_package_stop`** - Requires in-memory process tracking from `swift_package_run`
+- **`stop_app_device`** - Requires in-memory process tracking from `launch_app_device`
+- **`stop_app_sim`** - Requires in-memory process tracking from `launch_app_sim`
+- **`stop_device_log_cap`** - Requires in-memory session tracking from `start_device_log_cap`
+- **`stop_sim_log_cap`** - Requires in-memory session tracking from `start_sim_log_cap`
+- **`stop_mac_app`** - Requires in-memory process tracking from `launch_mac_app`
+
+**Testing Protocol for Stateful Tools:**
+1. **Test the tool anyway** - Execute the Reloaderoo inspect command
+2. **Expect failure** - Tool will likely fail due to missing state
+3. **Mark as false negative** - Document the failure as expected due to stateful limitations
+4. **Continue testing** - Do not attempt to fix or investigate the failure
+5. **Report as finding** - Note in testing report that stateful tools failed as expected
+
+**COMPLETE COVERAGE REQUIREMENTS:**
+- ✅ **Test ALL tools individually** - No exceptions, every tool gets manual verification
+- ✅ **Follow dependency graphs** - Test tools in correct order based on data dependencies
+- ✅ **Capture key outputs** - Record UUIDs, paths, schemes needed by dependent tools
+- ✅ **Test real workflows** - Complete end-to-end workflows from discovery to execution
+- ✅ **Use tool-summary.js script** - Accurate tool/resource counting and discovery
+- ✅ **Document all observations** - Record exactly what you see via testing
+- ✅ **Report discrepancies as findings** - Note unexpected results without investigation
+
+**MANDATORY INDIVIDUAL TOOL TESTING PROTOCOL:**
+
+**Step 1: Create Complete Tool Inventory**
+```bash
+# Use the official tool summary script to get accurate tool count and list
+npm run tools > /tmp/summary_output.txt
+TOTAL_TOOLS=$(grep "Tools:" /tmp/summary_output.txt | awk '{print $2}')
+echo "TOTAL TOOLS TO TEST: $TOTAL_TOOLS"
+
+# Generate detailed tool list and extract tool names
+npm run tools:list > /tmp/tools_detailed.txt
+grep "^ • " /tmp/tools_detailed.txt | sed 's/^ • //' > /tmp/tool_names.txt
+```
+
+**Step 2: Create TodoWrite Task List for Every Tool**
+```bash
+# Create individual todo items for each tool discovered
+# Use the actual tool count from step 1
+# Example for first few tools:
+# 1. [ ] Test tool: doctor
+# 2. [ ] Test tool: list_devices
+# 3. [ ] Test tool: list_sims
+# ... (continue for ALL $TOTAL_TOOLS tools)
+```
+
+**Step 3: Test Each Tool Individually**
+For EVERY tool in the list:
+```bash
+# Test each tool individually - NO BATCHING
+npx reloaderoo@latest inspect call-tool "TOOL_NAME" --params 'APPROPRIATE_PARAMS' -- node build/index.js
+
+# Mark tool as completed in TodoWrite IMMEDIATELY after testing
+# Record result (success/failure/blocked) for each tool
+```
+
+**Step 4: Validate Complete Coverage**
+```bash
+# Verify all tools tested
+COMPLETED_TOOLS=$(count completed todo items)
+if [ $COMPLETED_TOOLS -ne $TOTAL_TOOLS ]; then
+ echo "ERROR: Testing incomplete. $COMPLETED_TOOLS/$TOTAL_TOOLS tested"
+ exit 1
+fi
+```
+
+**CRITICAL: NO TOOL LEFT UNTESTED**
+- **Every tool name from the JSON list must be individually tested**
+- **Every tool must have a TodoWrite entry that gets marked completed**
+- **Tools that fail due to missing parameters should be tested anyway and marked as blocked**
+- **Tools that require setup (like running processes) should be tested and documented as requiring dependencies**
+- **NO ASSUMPTIONS**: Test tools even if they seem redundant or similar to others
+
+**BLACK BOX TESTING ENFORCEMENT:**
+- ✅ **Test only through Reloaderoo MCP interface** - Simulates real-world MCP client usage
+- ✅ **Use task lists** - Track progress with TodoWrite tool for every single tool
+- ✅ **Tick off each tool** - Mark completed in task list after manual verification
+- ✅ **Manual oversight** - Human verification of each tool's input and output
+- ❌ **Never examine source code** - No reading implementation files during testing
+- ❌ **Never diagnose internal issues** - No investigation of build processes or tool registration
+- ❌ **Never suggest implementation fixes** - Report issues as findings, don't solve them
+- ❌ **Never use scripts for tool testing** - Each tool must be manually executed and verified
+
+## Testing Psychology & Bias Prevention
+
+**COMMON ANTI-PATTERNS TO AVOID:**
+
+**1. Efficiency Bias (FORBIDDEN)**
+- **Symptom**: "These tools look similar, I'll test one to validate the others"
+- **Correction**: Every tool is unique and must be tested individually
+- **Enforcement**: Count tools at start, verify same count tested at end
+
+**2. Pattern Recognition Override (FORBIDDEN)**
+- **Symptom**: "I see the pattern, the rest will work the same way"
+- **Correction**: Patterns may hide edge cases, bugs, or different implementations
+- **Enforcement**: No assumptions allowed, test every tool regardless of apparent similarity
+
+**3. Time Pressure Shortcuts (FORBIDDEN)**
+- **Symptom**: "This is taking too long, let me speed up by sampling"
+- **Correction**: This is explicitly a long-running task with no time constraints
+- **Enforcement**: Thoroughness is the ONLY priority, efficiency is irrelevant
+
+**4. False Confidence (FORBIDDEN)**
+- **Symptom**: "The architecture is solid, so all tools must work"
+- **Correction**: Architecture validation does not guarantee individual tool functionality
+- **Enforcement**: Test tools to discover actual issues, not to confirm assumptions
+
+**MANDATORY MINDSET:**
+- **Every tool is potentially broken** until individually tested
+- **Every tool may have unique edge cases** not covered by similar tools
+- **Every tool deserves individual attention** regardless of apparent redundancy
+- **Testing completion means EVERY tool tested**, not "enough tools to validate patterns"
+- **The goal is discovering problems**, not confirming everything works
+
+**TESTING COMPLETENESS CHECKLIST:**
+- [ ] Generated complete tool list using `npm run tools:list`
+- [ ] Created TodoWrite entry for every single tool
+- [ ] Tested every tool individually via Reloaderoo inspect
+- [ ] Marked every tool as completed in TodoWrite
+- [ ] Verified tool count: tested_count == total_count
+- [ ] Documented all results, including failures and blocked tools
+- [ ] Created final report covering ALL tools, not just successful ones
+
+## Tool Dependency Graph Testing Strategy
+
+**CRITICAL: Tools must be tested in dependency order:**
+
+1. **Foundation Tools** (provide data for other tools):
+ - `doctor` - System info
+ - `list_devices` - Device UUIDs
+ - `list_sims` - Simulator UUIDs
+ - `discover_projs` - Project/workspace paths
+
+2. **Discovery Tools** (provide metadata for build tools):
+ - `list_schemes` - Scheme names
+ - `show_build_settings` - Build settings
+
+3. **Build Tools** (create artifacts for install tools):
+ - `build_*` tools - Create app bundles
+ - `get_*_app_path_*` tools - Locate built app bundles
+ - `get_*_bundle_id` tools - Extract bundle IDs
+
+4. **Installation Tools** (depend on built artifacts):
+ - `install_app_*` tools - Install built apps
+ - `launch_app_*` tools - Launch installed apps
+
+5. **Testing Tools** (depend on projects/schemes):
+ - `test_*` tools - Run test suites
+
+6. **UI Automation Tools** (depend on running apps):
+ - `describe_ui`, `screenshot`, `tap`, etc.
+
+**MANDATORY: Record Key Outputs**
+
+Must capture and document these values for dependent tools:
+- **Device UUIDs** from `list_devices`
+- **Simulator UUIDs** from `list_sims`
+- **Project/workspace paths** from `discover_projs`
+- **Scheme names** from `list_schems_*`
+- **App bundle paths** from `get_*_app_path_*`
+- **Bundle IDs** from `get_*_bundle_id`
+
+## Prerequisites
+
+1. **Build the server**: `npm run build`
+2. **Install jq**: `brew install jq` (required for JSON parsing)
+3. **System Requirements**: macOS with Xcode installed, connected devices/simulators optional
+
+## Step-by-Step Testing Process
+
+**Note**: All tool and resource discovery now uses the official `tool-summary.js` script (available as `npm run tools`, `npm run tools:list`, and `npm run tools:all`) instead of direct reloaderoo calls. This ensures accurate counts and lists without hardcoded values.
+
+### Step 1: Programmatic Discovery and Official Testing Lists
+
+#### Generate Official Tool and Resource Lists using tool-summary.js
+
+```bash
+# Use the official tool summary script to get accurate counts and lists
+npm run tools > /tmp/summary_output.txt
+
+# Extract tool and resource counts from summary
+TOOL_COUNT=$(grep "Tools:" /tmp/summary_output.txt | awk '{print $2}')
+RESOURCE_COUNT=$(grep "Resources:" /tmp/summary_output.txt | awk '{print $2}')
+echo "Official tool count: $TOOL_COUNT"
+echo "Official resource count: $RESOURCE_COUNT"
+
+# Generate detailed tool list for testing checklist
+npm run tools:list > /tmp/tools_detailed.txt
+
+# Extract tool names from the detailed output
+grep "^ • " /tmp/tools_detailed.txt | sed 's/^ • //' > /tmp/tool_names.txt
+echo "Tool names saved to /tmp/tool_names.txt"
+
+# Generate detailed resource list for testing checklist
+npm run tools:all > /tmp/tools_and_resources.txt
+
+# Extract resource URIs from the detailed output
+sed -n '/📚 Available Resources:/,/✅ Tool summary complete!/p' /tmp/tools_and_resources.txt | grep "^ • " | sed 's/^ • //' | cut -d' ' -f1 > /tmp/resource_uris.txt
+echo "Resource URIs saved to /tmp/resource_uris.txt"
+```
+
+#### Create Tool Testing Checklist
+
+```bash
+# Generate markdown checklist from actual tool list
+echo "# Official Tool Testing Checklist" > /tmp/tool_testing_checklist.md
+echo "" >> /tmp/tool_testing_checklist.md
+echo "Total Tools: $TOOL_COUNT" >> /tmp/tool_testing_checklist.md
+echo "" >> /tmp/tool_testing_checklist.md
+
+# Add each tool as unchecked item
+while IFS= read -r tool_name; do
+ echo "- [ ] $tool_name" >> /tmp/tool_testing_checklist.md
+done < /tmp/tool_names.txt
+
+echo "Tool testing checklist created at /tmp/tool_testing_checklist.md"
+```
+
+#### Create Resource Testing Checklist
+
+```bash
+# Generate markdown checklist from actual resource list
+echo "# Official Resource Testing Checklist" > /tmp/resource_testing_checklist.md
+echo "" >> /tmp/resource_testing_checklist.md
+echo "Total Resources: $RESOURCE_COUNT" >> /tmp/resource_testing_checklist.md
+echo "" >> /tmp/resource_testing_checklist.md
+
+# Add each resource as unchecked item
+while IFS= read -r resource_uri; do
+ echo "- [ ] $resource_uri" >> /tmp/resource_testing_checklist.md
+done < /tmp/resource_uris.txt
+
+echo "Resource testing checklist created at /tmp/resource_testing_checklist.md"
+```
+
+### Step 2: Tool Schema Discovery for Parameter Testing
+
+#### Extract Tool Schema Information
+
+```bash
+# Get schema for specific tool to understand required parameters
+TOOL_NAME="list_devices"
+jq --arg tool "$TOOL_NAME" '.tools[] | select(.name == $tool) | .inputSchema' /tmp/tools.json
+
+# Get tool description for usage guidance
+jq --arg tool "$TOOL_NAME" '.tools[] | select(.name == $tool) | .description' /tmp/tools.json
+
+# Generate parameter template for tool testing
+jq --arg tool "$TOOL_NAME" '.tools[] | select(.name == $tool) | .inputSchema.properties // {}' /tmp/tools.json
+```
+
+#### Batch Schema Extraction
+
+```bash
+# Create schema reference file for all tools
+echo "# Tool Schema Reference" > /tmp/tool_schemas.md
+echo "" >> /tmp/tool_schemas.md
+
+while IFS= read -r tool_name; do
+ echo "## $tool_name" >> /tmp/tool_schemas.md
+ echo "" >> /tmp/tool_schemas.md
+
+ # Get description
+ description=$(jq -r --arg tool "$tool_name" '.tools[] | select(.name == $tool) | .description' /tmp/tools.json)
+ echo "**Description:** $description" >> /tmp/tool_schemas.md
+ echo "" >> /tmp/tool_schemas.md
+
+ # Get required parameters
+ required=$(jq -r --arg tool "$tool_name" '.tools[] | select(.name == $tool) | .inputSchema.required // [] | join(", ")' /tmp/tools.json)
+ if [ "$required" != "" ]; then
+ echo "**Required Parameters:** $required" >> /tmp/tool_schemas.md
+ else
+ echo "**Required Parameters:** None" >> /tmp/tool_schemas.md
+ fi
+ echo "" >> /tmp/tool_schemas.md
+
+ # Get all parameters
+ echo "**All Parameters:**" >> /tmp/tool_schemas.md
+ jq --arg tool "$tool_name" '.tools[] | select(.name == $tool) | .inputSchema.properties // {} | keys[]' /tmp/tools.json | while read param; do
+ echo "- $param" >> /tmp/tool_schemas.md
+ done
+ echo "" >> /tmp/tool_schemas.md
+
+done < /tmp/tool_names.txt
+
+echo "Tool schema reference created at /tmp/tool_schemas.md"
+```
+
+### Step 3: Manual Tool-by-Tool Testing
+
+#### 🚨 CRITICAL: STEP-BY-STEP BLACK BOX TESTING PROCESS
+
+**ABSOLUTE RULE: ALL TESTING MUST BE DONE MANUALLY, ONE TOOL AT A TIME USING RELOADEROO INSPECT**
+
+**SYSTEMATIC TESTING PROCESS:**
+
+1. **Create TodoWrite Task List**
+ - Add all tools (from `npm run tools` count) to task list before starting
+ - Mark each tool as "pending" initially
+ - Update status to "in_progress" when testing begins
+ - Mark "completed" only after manual verification
+
+2. **Test Each Tool Individually**
+ - Execute ONLY via `npx reloaderoo@latest inspect call-tool "TOOL_NAME" --params 'JSON' -- node build/index.js`
+ - Wait for complete response before proceeding to next tool
+ - Read and verify each tool's output manually
+ - Record key outputs (UUIDs, paths, schemes) for dependent tools
+
+3. **Manual Verification Requirements**
+ - ✅ **Read each response** - Manually verify tool output makes sense
+ - ✅ **Check for errors** - Identify any tool failures or unexpected responses
+ - ✅ **Record UUIDs/paths** - Save outputs needed for dependent tools
+ - ✅ **Update task list** - Mark each tool complete after verification
+ - ✅ **Document issues** - Record any problems found during testing
+
+4. **FORBIDDEN SHORTCUTS:**
+ - ❌ **NO SCRIPTS** - Scripts hide what's happening and prevent proper verification
+ - ❌ **NO AUTOMATION** - Every tool call must be manually executed and verified
+ - ❌ **NO BATCHING** - Cannot test multiple tools simultaneously
+ - ❌ **NO MCP DIRECT CALLS** - Only Reloaderoo inspect commands allowed
+
+#### Phase 1: Infrastructure Validation
+
+**Manual Commands (execute individually):**
+
+```bash
+# Test server connectivity
+npx reloaderoo@latest inspect ping -- node build/index.js
+
+# Get server information
+npx reloaderoo@latest inspect server-info -- node build/index.js
+
+# Verify tool count manually
+npx reloaderoo@latest inspect list-tools -- node build/index.js 2>/dev/null | jq '.tools | length'
+
+# Verify resource count manually
+npx reloaderoo@latest inspect list-resources -- node build/index.js 2>/dev/null | jq '.resources | length'
+```
+
+#### Phase 2: Resource Testing
+
+```bash
+# Test each resource systematically
+while IFS= read -r resource_uri; do
+ echo "Testing resource: $resource_uri"
+ npx reloaderoo@latest inspect read-resource "$resource_uri" -- node build/index.js 2>/dev/null
+ echo "---"
+done < /tmp/resource_uris.txt
+```
+
+#### Phase 3: Foundation Tools (Data Collection)
+
+**CRITICAL: Capture ALL key outputs for dependent tools**
+
+```bash
+echo "=== FOUNDATION TOOL TESTING & DATA COLLECTION ==="
+
+# 1. Test doctor (no dependencies)
+echo "Testing doctor..."
+npx reloaderoo@latest inspect call-tool "doctor" --params '{}' -- node build/index.js 2>/dev/null
+
+# 2. Collect device data
+echo "Collecting device UUIDs..."
+npx reloaderoo@latest inspect call-tool "list_devices" --params '{}' -- node build/index.js 2>/dev/null > /tmp/devices_output.json
+DEVICE_UUIDS=$(jq -r '.content[0].text' /tmp/devices_output.json | grep -E "UDID: [A-F0-9-]+" | sed 's/.*UDID: //' | head -2)
+echo "Device UUIDs captured: $DEVICE_UUIDS"
+
+# 3. Collect simulator data
+echo "Collecting simulator UUIDs..."
+npx reloaderoo@latest inspect call-tool "list_sims" --params '{}' -- node build/index.js 2>/dev/null > /tmp/sims_output.json
+SIMULATOR_UUIDS=$(jq -r '.content[0].text' /tmp/sims_output.json | grep -E "\([A-F0-9-]+\)" | sed 's/.*(\([A-F0-9-]*\)).*/\1/' | head -3)
+echo "Simulator UUIDs captured: $SIMULATOR_UUIDS"
+
+# 4. Collect project data
+echo "Collecting project paths..."
+npx reloaderoo@latest inspect call-tool "discover_projs" --params '{"workspaceRoot": "/Volumes/Developer/XcodeBuildMCP"}' -- node build/index.js 2>/dev/null > /tmp/projects_output.json
+PROJECT_PATHS=$(jq -r '.content[1].text' /tmp/projects_output.json | grep -E "\.xcodeproj$" | sed 's/.*- //' | head -3)
+WORKSPACE_PATHS=$(jq -r '.content[2].text' /tmp/projects_output.json | grep -E "\.xcworkspace$" | sed 's/.*- //' | head -2)
+echo "Project paths captured: $PROJECT_PATHS"
+echo "Workspace paths captured: $WORKSPACE_PATHS"
+
+# Save key data for dependent tools
+echo "$DEVICE_UUIDS" > /tmp/device_uuids.txt
+echo "$SIMULATOR_UUIDS" > /tmp/simulator_uuids.txt
+echo "$PROJECT_PATHS" > /tmp/project_paths.txt
+echo "$WORKSPACE_PATHS" > /tmp/workspace_paths.txt
+```
+
+#### Phase 4: Discovery Tools (Metadata Collection)
+
+```bash
+echo "=== DISCOVERY TOOL TESTING & METADATA COLLECTION ==="
+
+# Collect schemes for each project
+while IFS= read -r project_path; do
+ if [ -n "$project_path" ]; then
+ echo "Getting schemes for: $project_path"
+ npx reloaderoo@latest inspect call-tool "list_schems_proj" --params "{\"projectPath\": \"$project_path\"}" -- node build/index.js 2>/dev/null > /tmp/schemes_$$.json
+ SCHEMES=$(jq -r '.content[1].text' /tmp/schemes_$$.json 2>/dev/null || echo "NoScheme")
+ echo "$project_path|$SCHEMES" >> /tmp/project_schemes.txt
+ echo "Schemes captured for $project_path: $SCHEMES"
+ fi
+done < /tmp/project_paths.txt
+
+# Collect schemes for each workspace
+while IFS= read -r workspace_path; do
+ if [ -n "$workspace_path" ]; then
+ echo "Getting schemes for: $workspace_path"
+ npx reloaderoo@latest inspect call-tool "list_schemes" --params "{\"workspacePath\": \"$workspace_path\"}" -- node build/index.js 2>/dev/null > /tmp/ws_schemes_$$.json
+ SCHEMES=$(jq -r '.content[1].text' /tmp/ws_schemes_$$.json 2>/dev/null || echo "NoScheme")
+ echo "$workspace_path|$SCHEMES" >> /tmp/workspace_schemes.txt
+ echo "Schemes captured for $workspace_path: $SCHEMES"
+ fi
+done < /tmp/workspace_paths.txt
+```
+
+#### Phase 5: Manual Individual Tool Testing (All Tools)
+
+**CRITICAL: Test every single tool manually, one at a time**
+
+**Manual Testing Process:**
+
+1. **Create task list** with TodoWrite tool for all tools (using count from `npm run tools`)
+2. **Test each tool individually** with proper parameters
+3. **Mark each tool complete** in task list after manual verification
+4. **Record results** and observations for each tool
+5. **NO SCRIPTS** - Each command executed manually
+
+**STEP-BY-STEP MANUAL TESTING COMMANDS:**
+
+```bash
+# STEP 1: Test foundation tools (no parameters required)
+# Execute each command individually, wait for response, verify manually
+npx reloaderoo@latest inspect call-tool "doctor" --params '{}' -- node build/index.js
+# [Wait for response, read output, mark tool complete in task list]
+
+npx reloaderoo@latest inspect call-tool "list_devices" --params '{}' -- node build/index.js
+# [Record device UUIDs from response for dependent tools]
+
+npx reloaderoo@latest inspect call-tool "list_sims" --params '{}' -- node build/index.js
+# [Record simulator UUIDs from response for dependent tools]
+
+# STEP 2: Test project discovery (use discovered project paths)
+npx reloaderoo@latest inspect call-tool "list_schems_proj" --params '{"projectPath": "/actual/path/from/discover_projs.xcodeproj"}' -- node build/index.js
+# [Record scheme names from response for build tools]
+
+# STEP 3: Test workspace tools (use discovered workspace paths)
+npx reloaderoo@latest inspect call-tool "list_schemes" --params '{"workspacePath": "/actual/path/from/discover_projs.xcworkspace"}' -- node build/index.js
+# [Record scheme names from response for build tools]
+
+# STEP 4: Test simulator tools (use captured simulator UUIDs from step 1)
+npx reloaderoo@latest inspect call-tool "boot_sim" --params '{"simulatorUuid": "ACTUAL_UUID_FROM_LIST_SIMS"}' -- node build/index.js
+# [Verify simulator boots successfully]
+
+# STEP 5: Test build tools (requires project + scheme + simulator from previous steps)
+npx reloaderoo@latest inspect call-tool "build_sim_id_proj" --params '{"projectPath": "/actual/project.xcodeproj", "scheme": "ActualSchemeName", "simulatorId": "ACTUAL_SIMULATOR_UUID"}' -- node build/index.js
+# [Verify build succeeds and record app bundle path]
+```
+
+**CRITICAL: EACH COMMAND MUST BE:**
+1. **Executed individually** - One command at a time, manually typed or pasted
+2. **Verified manually** - Read the complete response before continuing
+3. **Tracked in task list** - Mark tool complete only after verification
+4. **Use real data** - Replace placeholder values with actual captured data
+5. **Wait for completion** - Allow each command to finish before proceeding
+
+### TESTING VIOLATIONS AND ENFORCEMENT
+
+**🚨 CRITICAL VIOLATIONS THAT WILL TERMINATE TESTING:**
+
+1. **Direct MCP Tool Usage Violation:**
+ ```typescript
+ // ❌ IMMEDIATE TERMINATION - Using MCP tools directly
+ await mcp__XcodeBuildMCP__list_devices();
+ const result = await list_sims();
+ ```
+
+2. **Script-Based Testing Violation:**
+ ```bash
+ # ❌ IMMEDIATE TERMINATION - Using scripts to test tools
+ for tool in $(cat tool_list.txt); do
+ npx reloaderoo inspect call-tool "$tool" --params '{}' -- node build/index.js
+ done
+ ```
+
+3. **Batching/Automation Violation:**
+ ```bash
+ # ❌ IMMEDIATE TERMINATION - Testing multiple tools simultaneously
+ npx reloaderoo inspect call-tool "list_devices" & npx reloaderoo inspect call-tool "list_sims" &
+ ```
+
+4. **Source Code Examination Violation:**
+ ```typescript
+ // ❌ IMMEDIATE TERMINATION - Reading implementation during testing
+ const toolImplementation = await Read('/src/mcp/tools/device-shared/list_devices.ts');
+ ```
+
+**ENFORCEMENT PROCEDURE:**
+1. **First Violation**: Immediate correction and restart of testing process
+2. **Documentation Update**: Add explicit prohibition to prevent future violations
+3. **Method Validation**: Ensure all future testing uses only Reloaderoo inspect commands
+4. **Progress Reset**: Restart testing from foundation tools if direct MCP usage detected
+
+**VALID TESTING SEQUENCE EXAMPLE:**
+```bash
+# ✅ CORRECT - Step-by-step manual execution via Reloaderoo
+# Tool 1: Test doctor
+npx reloaderoo@latest inspect call-tool "doctor" --params '{}' -- node build/index.js
+# [Read response, verify, mark complete in TodoWrite]
+
+# Tool 2: Test list_devices
+npx reloaderoo@latest inspect call-tool "list_devices" --params '{}' -- node build/index.js
+# [Read response, capture UUIDs, mark complete in TodoWrite]
+
+# Tool 3: Test list_sims
+npx reloaderoo@latest inspect call-tool "list_sims" --params '{}' -- node build/index.js
+# [Read response, capture UUIDs, mark complete in TodoWrite]
+
+# Tool X: Test stateful tool (expected to fail)
+npx reloaderoo@latest inspect call-tool "swift_package_stop" --params '{"pid": 12345}' -- node build/index.js
+# [Tool fails as expected - no in-memory state available]
+# [Mark as "false negative - stateful tool limitation" in TodoWrite]
+# [Continue to next tool without investigation]
+
+# Continue individually for all tools (use count from npm run tools)...
+```
+
+**HANDLING STATEFUL TOOL FAILURES:**
+```bash
+# ✅ CORRECT Response to Expected Stateful Tool Failure
+# Tool fails with "No process found" or similar state-related error
+# Response: Mark tool as "tested - false negative (stateful)" in task list
+# Do NOT attempt to diagnose, fix, or investigate the failure
+# Continue immediately to next tool in sequence
+```
+
+## Error Testing
+
+```bash
+# Test error handling systematically
+echo "=== Error Testing ==="
+
+# Test with invalid JSON parameters
+echo "Testing invalid parameter types..."
+npx reloaderoo@latest inspect call-tool list_schems_proj --params '{"projectPath": 123}' -- node build/index.js 2>/dev/null
+
+# Test with non-existent paths
+echo "Testing non-existent paths..."
+npx reloaderoo@latest inspect call-tool list_schems_proj --params '{"projectPath": "/nonexistent/path.xcodeproj"}' -- node build/index.js 2>/dev/null
+
+# Test with invalid UUIDs
+echo "Testing invalid UUIDs..."
+npx reloaderoo@latest inspect call-tool boot_sim --params '{"simulatorUuid": "invalid-uuid"}' -- node build/index.js 2>/dev/null
+```
+
+## Testing Report Generation
+
+```bash
+# Create comprehensive testing session report
+cat > TESTING_SESSION_$(date +%Y-%m-%d).md << EOF
+# Manual Testing Session - $(date +%Y-%m-%d)
+
+## Environment
+- macOS Version: $(sw_vers -productVersion)
+- XcodeBuildMCP Version: $(jq -r '.version' package.json 2>/dev/null || echo "unknown")
+- Testing Method: Reloaderoo @latest via npx
+
+## Official Counts (Programmatically Verified)
+- Total Tools: $TOOL_COUNT
+- Total Resources: $RESOURCE_COUNT
+
+## Test Results
+[Document test results here]
+
+## Issues Found
+[Document any discrepancies or failures]
+
+## Performance Notes
+[Document response times and performance observations]
+EOF
+
+echo "Testing session template created: TESTING_SESSION_$(date +%Y-%m-%d).md"
+```
+
+### Key Commands Reference
+
+```bash
+# Essential testing commands
+npx reloaderoo@latest inspect ping -- node build/index.js
+npx reloaderoo@latest inspect server-info -- node build/index.js
+npx reloaderoo@latest inspect list-tools -- node build/index.js | jq '.tools | length'
+npx reloaderoo@latest inspect list-resources -- node build/index.js | jq '.resources | length'
+npx reloaderoo@latest inspect call-tool TOOL_NAME --params '{}' -- node build/index.js
+npx reloaderoo@latest inspect read-resource "xcodebuildmcp://RESOURCE" -- node build/index.js
+
+# Schema extraction
+jq --arg tool "TOOL_NAME" '.tools[] | select(.name == $tool) | .inputSchema' /tmp/tools.json
+jq --arg tool "TOOL_NAME" '.tools[] | select(.name == $tool) | .description' /tmp/tools.json
+```
+
+## Troubleshooting
+
+### Common Issues
+
+#### 1. Reloaderoo Command Timeouts
+**Symptoms**: Commands hang or timeout after extended periods
+**Cause**: Server startup issues or MCP protocol communication problems
+**Resolution**:
+- Verify server builds successfully: `npm run build`
+- Test direct server startup: `node build/index.js`
+- Check for TypeScript compilation errors
+
+#### 2. Tool Parameter Validation Errors
+**Symptoms**: Tools return parameter validation errors
+**Cause**: Missing or incorrect required parameters
+**Resolution**:
+- Check tool schema: `jq --arg tool "TOOL_NAME" '.tools[] | select(.name == $tool) | .inputSchema' /tmp/tools.json`
+- Verify parameter types and required fields
+- Use captured dependency data (UUIDs, paths, schemes)
+
+#### 3. "No Such Tool" Errors
+**Symptoms**: Reloaderoo reports tool not found
+**Cause**: Tool name mismatch or server registration issues
+**Resolution**:
+- Verify tool exists in list: `npx reloaderoo@latest inspect list-tools -- node build/index.js | jq '.tools[].name'`
+- Check exact tool name spelling and case sensitivity
+- Ensure server built successfully
+
+#### 4. Empty or Malformed Responses
+**Symptoms**: Tools return empty responses or JSON parsing errors
+**Cause**: Tool implementation issues or server errors
+**Resolution**:
+- Document as testing finding - do not investigate implementation
+- Mark tool as "failed - empty response" in task list
+- Continue with next tool in sequence
+
+This systematic approach ensures comprehensive, accurate testing using programmatic discovery and validation of all XcodeBuildMCP functionality through the MCP interface exclusively.
\ No newline at end of file
diff --git a/docs/NODEJS_2025.md b/docs/NODEJS_2025.md
new file mode 100644
index 00000000..a80723b2
--- /dev/null
+++ b/docs/NODEJS_2025.md
@@ -0,0 +1,550 @@
+# Modern Node.js Development Guide
+
+This guide provides actionable instructions for AI agents to apply modern Node.js patterns when the scenarios are applicable. Use these patterns when creating or modifying Node.js code that fits these use cases.
+
+## Core Principles
+
+**WHEN APPLICABLE** apply these modern patterns:
+
+1. **Use ES Modules** with `node:` prefix for built-in modules
+2. **Leverage built-in APIs** over external dependencies when the functionality matches
+3. **Use top-level await** instead of IIFE patterns when initialization is needed
+4. **Implement structured error handling** with proper context when handling application errors
+5. **Use built-in testing** over external test frameworks when adding tests
+6. **Apply modern async patterns** for better performance when dealing with async operations
+
+## 1. Module System Patterns
+
+### WHEN USING MODULES: ES Modules with node: Prefix
+
+**✅ DO THIS:**
+```javascript
+// Use ES modules with node: prefix for built-ins
+import { readFile } from 'node:fs/promises';
+import { createServer } from 'node:http';
+import { EventEmitter } from 'node:events';
+
+export function myFunction() {
+ return 'modern code';
+}
+```
+
+**❌ AVOID:**
+```javascript
+// Don't use CommonJS or bare imports for built-ins
+const fs = require('fs');
+const { readFile } = require('fs/promises');
+import { readFile } from 'fs/promises'; // Missing node: prefix
+```
+
+### WHEN INITIALIZING: Top-Level Await
+
+**✅ DO THIS:**
+```javascript
+// Use top-level await for initialization
+import { readFile } from 'node:fs/promises';
+
+const config = JSON.parse(await readFile('config.json', 'utf8'));
+const server = createServer(/* ... */);
+
+console.log('App started with config:', config.appName);
+```
+
+**❌ AVOID:**
+```javascript
+// Don't wrap in IIFE
+(async () => {
+ const config = JSON.parse(await readFile('config.json', 'utf8'));
+ // ...
+})();
+```
+
+### WHEN USING ES MODULES: Package.json Settings
+
+**✅ ENSURE package.json includes:**
+```json
+{
+ "type": "module",
+ "engines": {
+ "node": ">=20.0.0"
+ }
+}
+```
+
+## 2. HTTP and Network Patterns
+
+### WHEN MAKING HTTP REQUESTS: Use Built-in fetch
+
+**✅ DO THIS:**
+```javascript
+// Use built-in fetch with AbortSignal.timeout
+async function fetchData(url) {
+ try {
+ const response = await fetch(url, {
+ signal: AbortSignal.timeout(5000)
+ });
+
+ if (!response.ok) {
+ throw new Error(`HTTP ${response.status}: ${response.statusText}`);
+ }
+
+ return await response.json();
+ } catch (error) {
+ if (error.name === 'TimeoutError') {
+ throw new Error('Request timed out');
+ }
+ throw error;
+ }
+}
+```
+
+**❌ AVOID:**
+```javascript
+// Don't add axios, node-fetch, or similar dependencies
+const axios = require('axios');
+const response = await axios.get(url);
+```
+
+### WHEN NEEDING CANCELLATION: AbortController Pattern
+
+**✅ DO THIS:**
+```javascript
+// Implement proper cancellation
+const controller = new AbortController();
+setTimeout(() => controller.abort(), 10000);
+
+try {
+ const data = await fetch(url, { signal: controller.signal });
+ console.log('Data received:', data);
+} catch (error) {
+ if (error.name === 'AbortError') {
+ console.log('Request was cancelled');
+ } else {
+ console.error('Unexpected error:', error);
+ }
+}
+```
+
+## 3. Testing Patterns
+
+### WHEN ADDING TESTS: Use Built-in Test Runner
+
+**✅ DO THIS:**
+```javascript
+// Use node:test instead of external frameworks
+import { test, describe } from 'node:test';
+import assert from 'node:assert';
+
+describe('My Module', () => {
+ test('should work correctly', () => {
+ assert.strictEqual(myFunction(), 'expected');
+ });
+
+ test('should handle async operations', async () => {
+ const result = await myAsyncFunction();
+ assert.strictEqual(result, 'expected');
+ });
+
+ test('should throw on invalid input', () => {
+ assert.throws(() => myFunction('invalid'), /Expected error/);
+ });
+});
+```
+
+**✅ RECOMMENDED package.json scripts:**
+```json
+{
+ "scripts": {
+ "test": "node --test",
+ "test:watch": "node --test --watch",
+ "test:coverage": "node --test --experimental-test-coverage"
+ }
+}
+```
+
+**❌ AVOID:**
+```javascript
+// Don't add Jest, Mocha, or other test frameworks unless specifically required
+```
+
+## 4. Async Pattern Recommendations
+
+### WHEN HANDLING MULTIPLE ASYNC OPERATIONS: Parallel Execution with Promise.all
+
+**✅ DO THIS:**
+```javascript
+// Execute independent operations in parallel
+async function processData() {
+ try {
+ const [config, userData] = await Promise.all([
+ readFile('config.json', 'utf8'),
+ fetch('/api/user').then(r => r.json())
+ ]);
+
+ const processed = processUserData(userData, JSON.parse(config));
+ await writeFile('output.json', JSON.stringify(processed, null, 2));
+
+ return processed;
+ } catch (error) {
+ console.error('Processing failed:', {
+ error: error.message,
+ stack: error.stack,
+ timestamp: new Date().toISOString()
+ });
+ throw error;
+ }
+}
+```
+
+### WHEN PROCESSING EVENT STREAMS: AsyncIterators Pattern
+
+**✅ DO THIS:**
+```javascript
+// Use async iterators for event processing
+import { EventEmitter } from 'node:events';
+
+class DataProcessor extends EventEmitter {
+ async *processStream() {
+ for (let i = 0; i < 10; i++) {
+ this.emit('data', `chunk-${i}`);
+ yield `processed-${i}`;
+ await new Promise(resolve => setTimeout(resolve, 100));
+ }
+ this.emit('end');
+ }
+}
+
+// Consume with for-await-of
+const processor = new DataProcessor();
+for await (const result of processor.processStream()) {
+ console.log('Processed:', result);
+}
+```
+
+## 5. Stream Processing Patterns
+
+### WHEN PROCESSING STREAMS: Use pipeline with Promises
+
+**✅ DO THIS:**
+```javascript
+import { pipeline } from 'node:stream/promises';
+import { createReadStream, createWriteStream } from 'node:fs';
+import { Transform } from 'node:stream';
+
+// Always use pipeline for stream processing
+async function processFile(inputFile, outputFile) {
+ try {
+ await pipeline(
+ createReadStream(inputFile),
+ new Transform({
+ transform(chunk, encoding, callback) {
+ this.push(chunk.toString().toUpperCase());
+ callback();
+ }
+ }),
+ createWriteStream(outputFile)
+ );
+ console.log('File processed successfully');
+ } catch (error) {
+ console.error('Pipeline failed:', error);
+ throw error;
+ }
+}
+```
+
+### WHEN NEEDING BROWSER COMPATIBILITY: Web Streams
+
+**✅ DO THIS:**
+```javascript
+import { Readable } from 'node:stream';
+
+// Convert between Web Streams and Node streams when needed
+const webReadable = new ReadableStream({
+ start(controller) {
+ controller.enqueue('Hello ');
+ controller.enqueue('World!');
+ controller.close();
+ }
+});
+
+const nodeStream = Readable.fromWeb(webReadable);
+```
+
+## 6. CPU-Intensive Task Patterns
+
+### WHEN DOING HEAVY COMPUTATION: Worker Threads
+
+**✅ DO THIS:**
+```javascript
+// worker.js - Separate file for CPU-intensive tasks
+import { parentPort, workerData } from 'node:worker_threads';
+
+function heavyComputation(data) {
+ // CPU-intensive work here
+ return processedData;
+}
+
+const result = heavyComputation(workerData);
+parentPort.postMessage(result);
+```
+
+```javascript
+// main.js - Delegate to worker
+import { Worker } from 'node:worker_threads';
+import { fileURLToPath } from 'node:url';
+
+async function processHeavyTask(data) {
+ return new Promise((resolve, reject) => {
+ const worker = new Worker(
+ fileURLToPath(new URL('./worker.js', import.meta.url)),
+ { workerData: data }
+ );
+
+ worker.on('message', resolve);
+ worker.on('error', reject);
+ worker.on('exit', (code) => {
+ if (code !== 0) {
+ reject(new Error(`Worker stopped with exit code ${code}`));
+ }
+ });
+ });
+}
+```
+
+## 7. Development Configuration Patterns
+
+### FOR NEW PROJECTS: Modern package.json
+
+**✅ RECOMMENDED for new projects:**
+```json
+{
+ "name": "modern-node-app",
+ "type": "module",
+ "engines": {
+ "node": ">=20.0.0"
+ },
+ "scripts": {
+ "dev": "node --watch --env-file=.env app.js",
+ "test": "node --test --watch",
+ "start": "node app.js"
+ }
+}
+```
+
+### WHEN LOADING ENVIRONMENT VARIABLES: Built-in Support
+
+**✅ DO THIS:**
+```javascript
+// Use --env-file flag instead of dotenv package
+// Environment variables are automatically available
+console.log('Database URL:', process.env.DATABASE_URL);
+console.log('API Key loaded:', process.env.API_KEY ? 'Yes' : 'No');
+```
+
+**❌ AVOID:**
+```javascript
+// Don't add dotenv dependency
+require('dotenv').config();
+```
+
+## 8. Error Handling Patterns
+
+### WHEN CREATING CUSTOM ERRORS: Structured Error Classes
+
+**✅ DO THIS:**
+```javascript
+class AppError extends Error {
+ constructor(message, code, statusCode = 500, context = {}) {
+ super(message);
+ this.name = 'AppError';
+ this.code = code;
+ this.statusCode = statusCode;
+ this.context = context;
+ this.timestamp = new Date().toISOString();
+ }
+
+ toJSON() {
+ return {
+ name: this.name,
+ message: this.message,
+ code: this.code,
+ statusCode: this.statusCode,
+ context: this.context,
+ timestamp: this.timestamp,
+ stack: this.stack
+ };
+ }
+}
+
+// Usage with rich context
+throw new AppError(
+ 'Database connection failed',
+ 'DB_CONNECTION_ERROR',
+ 503,
+ { host: 'localhost', port: 5432, retryAttempt: 3 }
+);
+```
+
+## 9. Performance Monitoring Patterns
+
+### WHEN MONITORING PERFORMANCE: Built-in Performance APIs
+
+**✅ DO THIS:**
+```javascript
+import { PerformanceObserver, performance } from 'node:perf_hooks';
+
+// Set up performance monitoring
+const obs = new PerformanceObserver((list) => {
+ for (const entry of list.getEntries()) {
+ if (entry.duration > 100) {
+ console.log(`Slow operation: ${entry.name} took ${entry.duration}ms`);
+ }
+ }
+});
+obs.observe({ entryTypes: ['function', 'http', 'dns'] });
+
+// Instrument operations
+async function processLargeDataset(data) {
+ performance.mark('processing-start');
+
+ const result = await heavyProcessing(data);
+
+ performance.mark('processing-end');
+ performance.measure('data-processing', 'processing-start', 'processing-end');
+
+ return result;
+}
+```
+
+## 10. Module Organization Patterns
+
+### WHEN ORGANIZING INTERNAL MODULES: Import Maps
+
+**✅ DO THIS in package.json:**
+```json
+{
+ "imports": {
+ "#config": "./src/config/index.js",
+ "#utils/*": "./src/utils/*.js",
+ "#db": "./src/database/connection.js"
+ }
+}
+```
+
+**✅ Use in code:**
+```javascript
+// Clean internal imports
+import config from '#config';
+import { logger, validator } from '#utils/common';
+import db from '#db';
+```
+
+### WHEN LOADING CONDITIONALLY: Dynamic Imports
+
+**✅ DO THIS:**
+```javascript
+// Load features based on environment
+async function loadDatabaseAdapter() {
+ const dbType = process.env.DATABASE_TYPE || 'sqlite';
+
+ try {
+ const adapter = await import(`#db/adapters/${dbType}`);
+ return adapter.default;
+ } catch (error) {
+ console.warn(`Database adapter ${dbType} not available, falling back to sqlite`);
+ const fallback = await import('#db/adapters/sqlite');
+ return fallback.default;
+ }
+}
+```
+
+## 11. Diagnostic Patterns
+
+### WHEN ADDING OBSERVABILITY: Diagnostic Channels
+
+**✅ DO THIS:**
+```javascript
+import diagnostics_channel from 'node:diagnostics_channel';
+
+// Create diagnostic channels
+const dbChannel = diagnostics_channel.channel('app:database');
+
+// Subscribe to events
+dbChannel.subscribe((message) => {
+ console.log('Database operation:', {
+ operation: message.operation,
+ duration: message.duration,
+ query: message.query
+ });
+});
+
+// Publish diagnostic information
+async function queryDatabase(sql, params) {
+ const start = performance.now();
+
+ try {
+ const result = await db.query(sql, params);
+
+ dbChannel.publish({
+ operation: 'query',
+ sql,
+ params,
+ duration: performance.now() - start,
+ success: true
+ });
+
+ return result;
+ } catch (error) {
+ dbChannel.publish({
+ operation: 'query',
+ sql,
+ params,
+ duration: performance.now() - start,
+ success: false,
+ error: error.message
+ });
+ throw error;
+ }
+}
+```
+
+## Modernization Checklist
+
+When working with Node.js code, consider applying these patterns where applicable:
+
+- [ ] `"type": "module"` in package.json
+- [ ] `"engines": {"node": ">=20.0.0"}` specified
+- [ ] All built-in imports use `node:` prefix
+- [ ] Using `fetch()` instead of HTTP libraries
+- [ ] Using `node --test` instead of external test frameworks
+- [ ] Using `--watch` and `--env-file` flags
+- [ ] Implementing structured error handling
+- [ ] Using `Promise.all()` for parallel operations
+- [ ] Using `pipeline()` for stream processing
+- [ ] Implementing performance monitoring where appropriate
+- [ ] Using worker threads for CPU-intensive tasks
+- [ ] Using import maps for internal modules
+
+## Dependencies to Remove
+
+When modernizing, remove these dependencies if present:
+
+- `axios`, `node-fetch`, `got` → Use built-in `fetch()`
+- `jest`, `mocha`, `ava` → Use `node:test`
+- `nodemon` → Use `node --watch`
+- `dotenv` → Use `--env-file`
+- `cross-env` → Use native environment handling
+
+## Security Patterns
+
+**WHEN SECURITY IS A CONCERN** apply these practices:
+
+```bash
+# Use permission model for enhanced security
+node --experimental-permission --allow-fs-read=./data --allow-fs-write=./logs app.js
+
+# Network restrictions
+node --experimental-permission --allow-net=api.example.com app.js
+```
+
+This guide provides modern Node.js patterns to apply when the specific scenarios are encountered, ensuring code follows 2025 best practices for performance, security, and maintainability without forcing unnecessary changes.
\ No newline at end of file
diff --git a/docs/PLUGIN_DEVELOPMENT.md b/docs/PLUGIN_DEVELOPMENT.md
new file mode 100644
index 00000000..9754b6f9
--- /dev/null
+++ b/docs/PLUGIN_DEVELOPMENT.md
@@ -0,0 +1,769 @@
+# XcodeBuildMCP Plugin Development Guide
+
+This guide provides comprehensive instructions for creating new tools and workflow groups in XcodeBuildMCP using the filesystem-based auto-discovery system.
+
+## Table of Contents
+
+1. [Overview](#overview)
+2. [Plugin Architecture](#plugin-architecture)
+3. [Creating New Tools](#creating-new-tools)
+4. [Creating New Workflow Groups](#creating-new-workflow-groups)
+5. [Creating MCP Resources](#creating-mcp-resources)
+6. [Auto-Discovery System](#auto-discovery-system)
+7. [Testing Guidelines](#testing-guidelines)
+8. [Development Workflow](#development-workflow)
+9. [Best Practices](#best-practices)
+
+## Overview
+
+XcodeBuildMCP uses a **plugin-based architecture** with **filesystem-based auto-discovery**. Tools are automatically discovered and loaded without manual registration, and can be selectively enabled using `XCODEBUILDMCP_ENABLED_WORKFLOWS`.
+
+### Key Features
+
+- **Auto-Discovery**: Tools are automatically found by scanning `src/mcp/tools/` directory
+- **Selective Workflow Loading**: Limit startup tool registration with `XCODEBUILDMCP_ENABLED_WORKFLOWS`
+- **Dependency Injection**: All tools use testable patterns with mock-friendly executors
+- **Workflow Organization**: Tools are grouped into end-to-end development workflows
+
+## Plugin Architecture
+
+### Directory Structure
+
+```
+src/mcp/tools/
+├── simulator-workspace/ # iOS Simulator + Workspace tools
+├── simulator-project/ # iOS Simulator + Project tools (re-exports)
+├── simulator-shared/ # Shared simulator tools (canonical)
+├── device-workspace/ # iOS Device + Workspace tools
+├── device-project/ # iOS Device + Project tools (re-exports)
+├── device-shared/ # Shared device tools (canonical)
+├── macos-workspace/ # macOS + Workspace tools
+├── macos-project/ # macOS + Project tools (re-exports)
+├── macos-shared/ # Shared macOS tools (canonical)
+├── swift-package/ # Swift Package Manager tools
+├── ui-testing/ # UI automation tools
+├── project-discovery/ # Project analysis tools
+├── utilities/ # General utilities
+├── doctor/ # System health check tools
+└── logging/ # Log capture tools
+```
+
+### Plugin Tool Types
+
+1. **Canonical Workflows**: Standalone workflow groups (e.g., `swift-package`, `ui-testing`) defined as folders in the `src/mcp/tools/` directory
+2. **Shared Tools**: Common tools in `*-shared` directories (not exposed to clients)
+3. **Re-exported Tools**: Share tools to other workflow groups by re-exporting them
+
+## Creating New Tools
+
+### 1. Tool File Structure
+
+Every tool follows this standardized pattern:
+
+```typescript
+// src/mcp/tools/my-workflow/my_tool.ts
+import { z } from 'zod';
+import { ToolResponse } from '../../../types/common.js';
+import { CommandExecutor, getDefaultCommandExecutor } from '../../../utils/command.js';
+import { log, validateRequiredParam, createTextResponse, createErrorResponse } from '../../../utils/index.js';
+
+// 1. Define parameters type for clarity
+type MyToolParams = {
+ requiredParam: string;
+ optionalParam?: string;
+};
+
+// 2. Implement the core logic in a separate, testable function
+export async function my_toolLogic(
+ params: MyToolParams,
+ executor: CommandExecutor,
+): Promise {
+ // 3. Validate required parameters
+ const requiredValidation = validateRequiredParam('requiredParam', params.requiredParam);
+ if (!requiredValidation.isValid) {
+ return requiredValidation.errorResponse;
+ }
+
+ log('info', `Executing my_tool with param: ${params.requiredParam}`);
+
+ try {
+ // 4. Build and execute the command using the injected executor
+ const command = ['my-command', '--param', params.requiredParam];
+ if (params.optionalParam) {
+ command.push('--optional', params.optionalParam);
+ }
+
+ const result = await executor(command, 'My Tool Operation');
+
+ if (!result.success) {
+ return createErrorResponse('My Tool operation failed', result.error);
+ }
+
+ return createTextResponse(`✅ Success: ${result.output}`);
+ } catch (error) {
+ const errorMessage = error instanceof Error ? error.message : String(error);
+ log('error', `My Tool execution error: ${errorMessage}`);
+ return createErrorResponse('Tool execution failed', errorMessage);
+ }
+}
+
+// 5. Export the tool definition as the default export
+export default {
+ name: 'my_tool',
+ description: 'A brief description of what my_tool does, with a usage example. e.g. my_tool({ requiredParam: "value" })',
+ schema: {
+ requiredParam: z.string().describe('Description of the required parameter.'),
+ optionalParam: z.string().optional().describe('Description of the optional parameter.'),
+ },
+ // The handler wraps the logic function with the default executor for production use
+ handler: async (args: Record): Promise => {
+ return my_toolLogic(args as MyToolParams, getDefaultCommandExecutor());
+ },
+};
+```
+
+### 2. Required Tool Plugin Properties
+
+Every tool plugin **must** export a default object with these properties:
+
+| Property | Type | Description |
+|----------|------|-------------|
+| `name` | `string` | Tool name (must match filename without extension) |
+| `description` | `string` | Clear description with usage examples |
+| `schema` | `Record` | Zod validation schema for parameters |
+| `handler` | `function` | Async function: `(args) => Promise` |
+
+### 3. Naming Conventions
+
+Tools follow the pattern: `{action}_{target}_{specifier}_{projectType}`
+
+**Examples:**
+- `build_sim_id_ws` → Build + Simulator + ID + Workspace
+- `build_sim_name_proj` → Build + Simulator + Name + Project
+- `test_device_ws` → Test + Device + Workspace
+- `swift_package_build` → Swift Package + Build
+
+**Project Type Suffixes:**
+- `_ws` → Works with `.xcworkspace` files
+- `_proj` → Works with `.xcodeproj` files
+- No suffix → Generic or canonical tools
+
+### 4. Parameter Validation Patterns
+
+Use utility functions for consistent validation:
+
+```typescript
+// Required parameter validation
+const pathValidation = validateRequiredParam('workspacePath', params.workspacePath);
+if (!pathValidation.isValid) return pathValidation.errorResponse;
+
+// At-least-one parameter validation
+const identifierValidation = validateAtLeastOneParam(
+ 'simulatorId', params.simulatorId,
+ 'simulatorName', params.simulatorName
+);
+if (!identifierValidation.isValid) return identifierValidation.errorResponse;
+
+// File existence validation
+const fileValidation = validateFileExists(params.workspacePath as string);
+if (!fileValidation.isValid) return fileValidation.errorResponse;
+```
+
+### 5. Response Patterns
+
+Use utility functions for consistent responses:
+
+```typescript
+// Success responses
+return createTextResponse('✅ Operation succeeded');
+return createTextResponse('Operation completed', false); // Not an error
+
+// Error responses
+return createErrorResponse('Operation failed', errorDetails);
+return createErrorResponse('Validation failed', errorMessage, 'ValidationError');
+
+// Complex responses
+return {
+ content: [
+ { type: 'text', text: '✅ Build succeeded' },
+ { type: 'text', text: 'Next steps: Run install_app_sim...' }
+ ],
+ isError: false
+};
+```
+
+## Creating New Workflow Groups
+
+### 1. Workflow Group Structure
+
+Each workflow group requires:
+
+1. **Directory**: Following naming convention
+2. **Workflow Metadata**: `index.ts` file with workflow export
+3. **Tool Files**: Individual tool implementations
+4. **Tests**: Comprehensive test coverage
+
+### 2. Directory Naming Convention
+
+```
+[platform]-[projectType]/ # e.g., simulator-workspace, device-project
+[platform]-shared/ # e.g., simulator-shared, macos-shared
+[workflow-name]/ # e.g., swift-package, ui-testing
+```
+
+### 3. Workflow Metadata (index.ts)
+
+**Required for all workflow groups:**
+
+```typescript
+// Example: src/mcp/tools/simulator-workspace/index.ts
+export const workflow = {
+ name: 'iOS Simulator Workspace Development',
+ description: 'Complete iOS development workflow for .xcworkspace files including build, test, deploy, and debug capabilities',
+};
+```
+
+**Required Properties:**
+- `name`: Human-readable workflow name
+- `description`: Clear description of workflow purpose
+
+### 4. Tool Organization Patterns
+
+#### Canonical Workflow Groups
+Self-contained workflows that don't re-export from other groups:
+
+```
+swift-package/
+├── index.ts # Workflow metadata
+├── swift_package_build.ts # Build tool
+├── swift_package_test.ts # Test tool
+├── swift_package_run.ts # Run tool
+└── __tests__/ # Test directory
+ ├── index.test.ts # Workflow tests
+ ├── swift_package_build.test.ts
+ └── ...
+```
+
+#### Shared Workflow Groups
+Provide canonical tools for re-export by project/workspace variants:
+
+```
+simulator-shared/
+├── boot_sim.ts # Canonical simulator boot tool
+├── install_app_sim.ts # Canonical app install tool
+└── __tests__/ # Test directory
+ ├── boot_sim.test.ts
+ └── ...
+```
+
+#### Project/Workspace Workflow Groups
+Re-export shared tools and add variant-specific tools:
+
+```
+simulator-project/
+├── index.ts # Workflow metadata
+├── boot_sim.ts # Re-export: export { default } from '../simulator-shared/boot_sim.js';
+├── build_sim_id_proj.ts # Project-specific build tool
+└── __tests__/ # Test directory
+ ├── index.test.ts # Workflow tests
+ ├── re-exports.test.ts # Re-export validation
+ └── ...
+```
+
+### 5. Re-export Implementation
+
+For project/workspace groups that share tools:
+
+```typescript
+// simulator-project/boot_sim.ts
+export { default } from '../simulator-shared/boot_sim.js';
+```
+
+**Re-export Rules:**
+1. Re-exports come from canonical `-shared` groups
+2. No chained re-exports (re-exports from re-exports)
+3. Each tool maintains project or workspace specificity
+4. Implementation shared, interfaces remain unique
+
+## Creating MCP Resources
+
+MCP Resources provide efficient URI-based data access for clients that support the MCP resource specification
+
+### 1. Resource Structure
+
+Resources are located in `src/resources/` and follow this pattern:
+
+```typescript
+// src/resources/example.ts
+import { log, getDefaultCommandExecutor, CommandExecutor } from '../../utils/index.js';
+
+// Testable resource logic separated from MCP handler
+export async function exampleResourceLogic(
+ executor: CommandExecutor,
+): Promise<{ contents: Array<{ text: string }> }> {
+ try {
+ log('info', 'Processing example resource request');
+
+ // Use the executor to get data
+ const result = await executor(['some', 'command'], 'Example Resource Operation');
+
+ if (!result.success) {
+ throw new Error(result.error || 'Failed to get resource data');
+ }
+
+ return {
+ contents: [{ text: result.output || 'resource data' }]
+ };
+ } catch (error) {
+ const errorMessage = error instanceof Error ? error.message : String(error);
+ log('error', `Error in example resource handler: ${errorMessage}`);
+
+ return {
+ contents: [
+ {
+ text: `Error retrieving resource data: ${errorMessage}`,
+ },
+ ],
+ };
+ }
+}
+
+export default {
+ uri: 'xcodebuildmcp://example',
+ name: 'example',
+ description: 'Description of the resource data',
+ mimeType: 'text/plain',
+ async handler(_uri: URL): Promise<{ contents: Array<{ text: string }> }> {
+ return exampleResourceLogic(getDefaultCommandExecutor());
+ },
+};
+```
+
+### 2. Resource Implementation Guidelines
+
+**Reuse Existing Logic**: Resources that mirror tools should reuse existing tool logic for consistency:
+
+```typescript
+// src/mcp/resources/simulators.ts (simplified example)
+import { list_simsLogic } from '../tools/simulator-shared/list_sims.js';
+
+export default {
+ uri: 'xcodebuildmcp://simulators',
+ name: 'simulators'
+ description: 'Available iOS simulators with UUIDs and states',
+ mimeType: 'text/plain',
+ async handler(uri: URL): Promise<{ contents: Array<{ text: string }> }> {
+ const executor = getDefaultCommandExecutor();
+ const result = await list_simsLogic({}, executor);
+ return {
+ contents: [{ text: result.content[0].text }]
+ };
+ }
+};
+```
+
+As not all clients support resources it important that resource content that would be ideally be served by resources be mirroed as a tool as well. This ensurew clients that don't support this capability continue to will still have access to that resource data via a simple tool call.
+
+### 3. Resource Testing
+
+Create tests in `src/mcp/resources/__tests__/`:
+
+```typescript
+// src/mcp/resources/__tests__/example.test.ts
+import exampleResource, { exampleResourceLogic } from '../example.js';
+import { createMockExecutor } from '../../utils/test-common.js';
+
+describe('example resource', () => {
+ describe('Export Field Validation', () => {
+ it('should export correct uri', () => {
+ expect(exampleResource.uri).toBe('xcodebuildmcp://example');
+ });
+
+ it('should export correct description', () => {
+ expect(exampleResource.description).toBe('Description of the resource data');
+ });
+
+ it('should export correct mimeType', () => {
+ expect(exampleResource.mimeType).toBe('text/plain');
+ });
+
+ it('should export handler function', () => {
+ expect(typeof exampleResource.handler).toBe('function');
+ });
+ });
+
+ describe('Resource Logic Functionality', () => {
+ it('should return resource data successfully', async () => {
+ const mockExecutor = createMockExecutor({
+ success: true,
+ output: 'test data'
+ });
+
+ // Test the logic function directly, not the handler
+ const result = await exampleResourceLogic(mockExecutor);
+
+ expect(result.contents).toHaveLength(1);
+ expect(result.contents[0].text).toContain('expected data');
+ });
+
+ it('should handle command execution errors', async () => {
+ const mockExecutor = createMockExecutor({
+ success: false,
+ error: 'Command failed'
+ });
+
+ const result = await exampleResourceLogic(mockExecutor);
+
+ expect(result.contents[0].text).toContain('Error retrieving');
+ });
+ });
+});
+```
+
+### 4. Auto-Discovery
+
+Resources are automatically discovered and loaded by the build system. After creating a resource:
+
+1. Run `npm run build` to regenerate resource loaders
+2. The resource will be available at its URI for supported clients
+
+## Auto-Discovery System
+
+### How Auto-Discovery Works
+
+1. **Filesystem Scan**: `loadPlugins()` scans `src/mcp/tools/` directory
+2. **Workflow Loading**: Each subdirectory is treated as a potential workflow group
+3. **Metadata Validation**: `index.ts` files provide workflow metadata
+4. **Tool Discovery**: All `.ts` files (except tests and index) are loaded as tools
+5. **Registration**: Tools are automatically registered with the MCP server
+
+### Discovery Process
+
+```typescript
+// Simplified discovery flow
+const plugins = await loadPlugins();
+for (const plugin of plugins.values()) {
+ server.tool(plugin.name, plugin.description, plugin.schema, plugin.handler);
+}
+```
+
+### Selective Workflow Loading
+
+To limit which workflows are registered at startup, set `XCODEBUILDMCP_ENABLED_WORKFLOWS` to a comma-separated list of workflow directory names. The `session-management` workflow is always auto-included since other tools depend on it.
+
+Example:
+```bash
+XCODEBUILDMCP_ENABLED_WORKFLOWS=simulator,device,project-discovery
+```
+
+`XCODEBUILDMCP_DEBUG=true` can still be used to increase logging verbosity.
+
+## Testing Guidelines
+
+### Test Organization
+
+```
+__tests__/
+├── index.test.ts # Workflow metadata tests (canonical groups only)
+├── re-exports.test.ts # Re-export validation (project/workspace groups)
+└── tool_name.test.ts # Individual tool tests
+```
+
+### Dependency Injection Testing
+
+**✅ CORRECT Pattern:**
+```typescript
+import { createMockExecutor } from '../../../utils/test-common.js';
+
+describe('build_sim_name_ws', () => {
+ it('should build successfully', async () => {
+ const mockExecutor = createMockExecutor({
+ success: true,
+ output: 'BUILD SUCCEEDED'
+ });
+
+ const result = await build_sim_name_wsLogic(params, mockExecutor);
+ expect(result.isError).toBe(false);
+ });
+});
+```
+
+**❌ FORBIDDEN Pattern (Vitest Mocking Banned):**
+```typescript
+// ❌ ALL VITEST MOCKING IS COMPLETELY BANNED
+vi.mock('child_process');
+const mockSpawn = vi.fn();
+```
+
+### Three-Dimensional Testing
+
+Every tool test must cover:
+
+1. **Input Validation**: Parameter schema validation and error cases
+2. **Command Generation**: Verify correct CLI commands are built
+3. **Output Processing**: Test response formatting and error handling
+
+### Test Template
+
+```typescript
+import { describe, it, expect } from 'vitest';
+import { createMockExecutor } from '../../../utils/test-common.js';
+import tool, { toolNameLogic } from '../tool_name.js';
+
+describe('tool_name', () => {
+ describe('Export Validation', () => {
+ it('should export correct name', () => {
+ expect(tool.name).toBe('tool_name');
+ });
+
+ it('should export correct description', () => {
+ expect(tool.description).toContain('Expected description');
+ });
+
+ it('should export handler function', () => {
+ expect(typeof tool.handler).toBe('function');
+ });
+ });
+
+ describe('Parameter Validation', () => {
+ it('should validate required parameters', async () => {
+ const mockExecutor = createMockExecutor({ success: true, output: '' });
+
+ const result = await toolNameLogic({}, mockExecutor);
+
+ expect(result.isError).toBe(true);
+ expect(result.content[0].text).toContain("Required parameter");
+ });
+ });
+
+ describe('Command Generation', () => {
+ it('should generate correct command', async () => {
+ const mockExecutor = createMockExecutor({ success: true, output: 'SUCCESS' });
+
+ await toolNameLogic({ param: 'value' }, mockExecutor);
+
+ expect(mockExecutor).toHaveBeenCalledWith(
+ expect.arrayContaining(['expected', 'command']),
+ expect.any(String),
+ expect.any(Boolean)
+ );
+ });
+ });
+
+ describe('Response Processing', () => {
+ it('should handle successful execution', async () => {
+ const mockExecutor = createMockExecutor({ success: true, output: 'SUCCESS' });
+
+ const result = await toolNameLogic({ param: 'value' }, mockExecutor);
+
+ expect(result.isError).toBe(false);
+ expect(result.content[0].text).toContain('✅');
+ });
+
+ it('should handle execution errors', async () => {
+ const mockExecutor = createMockExecutor({ success: false, error: 'Command failed' });
+
+ const result = await toolNameLogic({ param: 'value' }, mockExecutor);
+
+ expect(result.isError).toBe(true);
+ expect(result.content[0].text).toContain('Command failed');
+ });
+ });
+});
+```
+
+## Development Workflow
+
+### Adding a New Tool
+
+1. **Choose Directory**: Select appropriate workflow group or create new one
+2. **Create Tool File**: Follow naming convention and structure
+3. **Implement Logic**: Use dependency injection pattern
+4. **Define Schema**: Add comprehensive Zod validation
+5. **Write Tests**: Cover all three dimensions
+6. **Test Integration**: Build and verify auto-discovery
+
+### Step-by-Step Tool Creation
+
+```bash
+# 1. Create tool file
+touch src/mcp/tools/simulator-workspace/my_new_tool_ws.ts
+
+# 2. Implement tool following patterns above
+
+# 3. Create test file
+touch src/mcp/tools/simulator-workspace/__tests__/my_new_tool_ws.test.ts
+
+# 4. Build project
+npm run build
+
+# 5. Verify tool is discovered (should appear in tools list)
+npm run inspect # Use MCP Inspector to verify
+```
+
+### Adding a New Workflow Group
+
+1. **Create Directory**: Follow naming convention
+2. **Add Workflow Metadata**: Create `index.ts` with workflow export
+3. **Implement Tools**: Add tool files following patterns
+4. **Create Tests**: Add comprehensive test coverage
+5. **Verify Discovery**: Test auto-discovery and tool registration
+
+### Step-by-Step Workflow Creation
+
+```bash
+# 1. Create workflow directory
+mkdir src/mcp/tools/my-new-workflow
+
+# 2. Create workflow metadata
+cat > src/mcp/tools/my-new-workflow/index.ts << 'EOF'
+export const workflow = {
+ name: 'My New Workflow',
+ description: 'Description of workflow capabilities',
+};
+EOF
+
+# 3. Create tools directory and test directory
+mkdir src/mcp/tools/my-new-workflow/__tests__
+
+# 4. Implement tools following patterns
+
+# 5. Build and verify
+npm run build
+npm run inspect
+```
+
+## Best Practices
+
+### Tool Design
+
+1. **Single Responsibility**: Each tool should have one clear purpose
+2. **Descriptive Names**: Follow naming conventions for discoverability
+3. **Clear Descriptions**: Include usage examples in tool descriptions
+4. **Comprehensive Validation**: Validate all parameters with helpful error messages
+5. **Consistent Responses**: Use utility functions for response formatting
+
+### Error Handling
+
+1. **Graceful Failures**: Always return ToolResponse, never throw from handlers
+2. **Descriptive Errors**: Provide actionable error messages
+3. **Error Types**: Use appropriate error types for different scenarios
+4. **Logging**: Log important events and errors for debugging
+
+### Testing
+
+1. **Dependency Injection**: Always test with mock executors
+2. **Complete Coverage**: Test all input, command, and output scenarios
+3. **Literal Assertions**: Use exact string expectations to catch changes
+4. **Fast Execution**: Tests should complete quickly without real system calls
+
+### Workflow Organization
+
+1. **End-to-End Workflows**: Groups should provide complete functionality
+2. **Logical Grouping**: Group related tools together
+3. **Clear Capabilities**: Document what each workflow can accomplish
+4. **Consistent Patterns**: Follow established patterns for maintainability
+
+### Workflow Metadata Considerations
+
+1. **Workflow Completeness**: Each group should be self-sufficient
+2. **Clear Descriptions**: Keep the `description` concise and user-focused
+
+## Updating TOOLS.md Documentation
+
+### Critical Documentation Maintenance
+
+**Every time you add, change, move, edit, or delete a tool, you MUST review and update the `docs/TOOLS.md` file to reflect the current state of the codebase.**
+
+### Documentation Update Process
+
+#### 1. Use Tree CLI for Accurate Discovery
+
+**Always use the `tree` command to get the actual filesystem representation of tools:**
+
+```bash
+# Get the definitive source of truth for all workflow groups and tools
+tree src/mcp/tools/ -I "__tests__" -I "*.test.ts"
+```
+
+This command:
+- Shows ALL workflow directories and their tools
+- Excludes test files (`__tests__` directories and `*.test.ts` files)
+- Provides the actual proof of what exists in the codebase
+- Gives an accurate count of tools per workflow group
+
+#### 2. Ignore Shared Groups in Documentation
+
+When updating `docs/TOOLS.md`:
+
+- **Ignore `*-shared` directories** (e.g., `simulator-shared`, `device-shared`, `macos-shared`)
+- These are implementation details, not user-facing workflow groups
+- Only document the main workflow groups that users interact with
+- The group count should exclude shared groups
+
+#### 3. List Actual Tool Names
+
+Instead of using generic descriptions like "Additional Tools: Simulator management, logging, UI testing tools":
+
+**❌ Wrong:**
+```markdown
+- **Additional Tools**: Simulator management, logging, UI testing tools
+```
+
+**✅ Correct:**
+```markdown
+- `boot_sim`, `install_app_sim`, `launch_app_sim`, `list_sims`, `open_sim`
+- `describe_ui`, `screenshot`, `start_sim_log_cap`, `stop_sim_log_cap`
+```
+
+#### 4. Systematic Documentation Update Steps
+
+1. **Run the tree command** to get current filesystem state
+2. **Identify all non-shared workflow directories**
+3. **Count actual tool files** in each directory (exclude `index.ts` and test files)
+4. **List all tool names** explicitly in the documentation
+5. **Update tool counts** to reflect actual numbers
+6. **Verify consistency** between filesystem and documentation
+
+#### 5. Documentation Formatting Requirements
+
+**Format: One Tool Per Bullet Point with Description**
+
+Each tool must be listed individually with its actual description from the tool file:
+
+```markdown
+### 1. My Awesome Workflow (`my-awesome-workflow`)
+**Purpose**: A short description of what this workflow is for. (2 tools)
+- `my_tool_one` - Description for my_tool_one from its definition file.
+- `my_tool_two` - Description for my_tool_two from its definition file.
+```
+
+**Description Sources:**
+- Use the actual `description` field from each tool's TypeScript file
+- Descriptions should be concise but informative for end users
+- Include platform/context information (iOS, macOS, simulator, device, etc.)
+- Mention required parameters when critical for usage
+
+#### 6. Validation Checklist
+
+After updating `docs/TOOLS.md`:
+
+- [ ] Tool counts match actual filesystem counts (from tree command)
+- [ ] Each tool has its own bullet point (one tool per line)
+- [ ] Each tool includes its actual description from the tool file
+- [ ] No generic descriptions like "Additional Tools: X, Y, Z"
+- [ ] Descriptions are user-friendly and informative
+- [ ] Shared groups (`*-shared`) are not included in main workflow list
+- [ ] Workflow group count reflects only user-facing groups (15 groups)
+- [ ] Tree command output was used as source of truth
+- [ ] Documentation is user-focused, not implementation-focused
+- [ ] Tool names are in alphabetical order within each workflow group
+
+### Why This Process Matters
+
+1. **Accuracy**: Tree command provides definitive proof of current state
+2. **Maintainability**: Systematic process prevents documentation drift
+3. **User Experience**: Accurate documentation helps users understand available tools
+4. **Development Confidence**: Developers can trust the documentation reflects reality
+
+**Remember**: The filesystem is the source of truth. Documentation must always reflect the actual codebase structure, and the tree command is the most reliable way to ensure accuracy.
diff --git a/docs/RELEASE_PROCESS.md b/docs/RELEASE_PROCESS.md
new file mode 100644
index 00000000..9751ee83
--- /dev/null
+++ b/docs/RELEASE_PROCESS.md
@@ -0,0 +1,213 @@
+# Release Process
+
+## Step-by-Step Development Workflow
+
+### 1. Starting New Work
+
+**Always start by syncing with main:**
+```bash
+git checkout main
+git pull origin main
+```
+
+**Create feature branch using standardized naming convention:**
+```bash
+git checkout -b feature/issue-123-add-new-feature
+git checkout -b bugfix/issue-456-fix-simulator-crash
+```
+
+### 2. Development & Commits
+
+**Before committing, ALWAYS run quality checks:**
+```bash
+npm run build # Ensure code compiles
+npm run typecheck # MANDATORY: Fix all TypeScript errors
+npm run lint # Fix linting issues
+npm run test # Ensure tests pass
+```
+
+**🚨 CRITICAL: TypeScript errors are BLOCKING:**
+- **ZERO tolerance** for TypeScript errors in commits
+- The `npm run typecheck` command must pass with no errors
+- Fix all `ts(XXXX)` errors before committing
+- Do not ignore or suppress TypeScript errors without explicit approval
+
+**Make logical, atomic commits:**
+- Each commit should represent a single logical change
+- Write short, descriptive commit summaries
+- Commit frequently to your feature branch
+
+```bash
+# Always run quality checks first
+npm run typecheck && npm run lint && npm run test
+
+# Then commit your changes
+git add .
+git commit -m "feat: add simulator boot validation logic"
+git commit -m "fix: handle null response in device list parser"
+```
+
+### 3. Pushing Changes
+
+**🚨 CRITICAL: Always ask permission before pushing**
+- **NEVER push without explicit user permission**
+- **NEVER force push without explicit permission**
+- Pushing without permission is a fatal error resulting in termination
+
+```bash
+# Only after getting permission:
+git push origin feature/your-branch-name
+```
+
+### 4. Pull Request Creation
+
+**Use GitHub CLI tool exclusively:**
+```bash
+gh pr create --title "feat: add simulator boot validation" --body "$(cat <<'EOF'
+## Summary
+Brief description of what this PR does and why.
+
+## Background/Details
+### For New Features:
+- Detailed explanation of the new feature
+- Context and requirements that led to this implementation
+- Design decisions and approach taken
+
+### For Bug Fixes:
+- **Root Cause Analysis**: Detailed explanation of what caused the bug
+- Specific conditions that trigger the issue
+- Why the current code fails in these scenarios
+
+## Solution
+- How the root cause was addressed
+- Technical approach and implementation details
+- Key changes made to resolve the issue
+
+## Testing
+- **Reproduction Steps**: How to reproduce the original issue (for bugs)
+- **Validation Method**: How you verified the fix works
+- **Test Coverage**: What tests were added or modified
+- **Manual Testing**: Steps taken to validate the solution
+- **Edge Cases**: Additional scenarios tested
+
+## Notes
+- Any important considerations for reviewers
+- Potential impacts or side effects
+- Future improvements or technical debt
+- Deployment considerations
+EOF
+)"
+```
+
+**After PR creation, add automated review trigger:**
+```bash
+gh pr comment --body "Cursor review"
+```
+
+### 5. Branch Management & Rebasing
+
+**Keep branch up to date with main:**
+```bash
+git checkout main
+git pull origin main
+git checkout your-feature-branch
+git rebase main
+```
+
+**If rebase creates conflicts:**
+- Resolve conflicts manually
+- `git add .` resolved files
+- `git rebase --continue`
+- **Ask permission before force pushing rebased branch**
+
+### 6. Merge Process
+
+**Only merge via Pull Requests:**
+- No direct merges to `main`
+- Maintain linear commit history through rebasing
+- Use "Squash and merge" or "Rebase and merge" as appropriate
+- Delete feature branch after successful merge
+
+## Pull Request Template Structure
+
+Every PR must include these sections in order:
+
+1. **Summary**: Brief overview of changes and purpose
+2. **Background/Details**:
+ - New Feature: Requirements, context, design decisions
+ - Bug Fix: Detailed root cause analysis
+3. **Solution**: Technical approach and implementation details
+4. **Testing**: Reproduction steps, validation methods, test coverage
+5. **Notes**: Additional considerations, impacts, future work
+
+## Critical Rules
+
+### ❌ FATAL ERRORS (Result in Termination)
+- **NEVER push to `main` directly**
+- **NEVER push without explicit user permission**
+- **NEVER force push without explicit permission**
+- **NEVER commit code with TypeScript errors**
+
+### ✅ Required Practices
+- Always pull from `main` before creating branches
+- **MANDATORY: Run `npm run typecheck` before every commit**
+- **MANDATORY: Fix all TypeScript errors before committing**
+- Use `gh` CLI tool for all PR operations
+- Add "Cursor review" comment after PR creation
+- Maintain linear commit history via rebasing
+- Ask permission before any push operation
+- Use standardized branch naming conventions
+
+## Branch Naming Conventions
+
+- `feature/issue-xxx-description` - New features
+- `bugfix/issue-xxx-description` - Bug fixes
+- `hotfix/critical-issue-description` - Critical production fixes
+- `docs/update-readme` - Documentation updates
+- `refactor/improve-error-handling` - Code refactoring
+
+## Automated Quality Gates
+
+### CI/CD Pipeline
+Our GitHub Actions CI pipeline automatically enforces these quality checks:
+1. `npm run build` - Compilation check
+2. `npm run lint` - ESLint validation
+3. `npm run format:check` - Prettier formatting check
+4. `npm run typecheck` - **TypeScript error validation**
+5. `npm run test` - Test suite execution
+
+**All checks must pass before PR merge is allowed.**
+
+### Optional: Pre-commit Hook Setup
+To catch TypeScript errors before committing locally:
+
+```bash
+# Create pre-commit hook
+cat > .git/hooks/pre-commit << 'EOF'
+#!/bin/sh
+echo "🔍 Running pre-commit checks..."
+
+# Run TypeScript type checking
+echo "📝 Checking TypeScript..."
+npm run typecheck
+if [ $? -ne 0 ]; then
+ echo "❌ TypeScript errors found. Please fix before committing."
+ exit 1
+fi
+
+# Run linting
+echo "🧹 Running linter..."
+npm run lint
+if [ $? -ne 0 ]; then
+ echo "❌ Linting errors found. Please fix before committing."
+ exit 1
+fi
+
+echo "✅ Pre-commit checks passed!"
+EOF
+
+# Make it executable
+chmod +x .git/hooks/pre-commit
+```
+
+This hook will automatically run `typecheck` and `lint` before every commit, preventing TypeScript errors from being committed.
\ No newline at end of file
diff --git a/docs/RELOADEROO.md b/docs/RELOADEROO.md
new file mode 100644
index 00000000..689425a7
--- /dev/null
+++ b/docs/RELOADEROO.md
@@ -0,0 +1,446 @@
+# Reloaderoo Integration Guide
+
+This guide explains how to use Reloaderoo v1.1.2+ for testing and developing XcodeBuildMCP with both CLI inspection tools and transparent proxy capabilities.
+
+## Overview
+
+**Reloaderoo** is a dual-mode MCP development tool that operates as both a CLI inspection tool and a transparent proxy server for the Model Context Protocol (MCP). It provides two distinct operational modes for different development workflows.
+
+## Installation
+
+Reloaderoo is available via npm and can be used with npx for universal compatibility.
+
+```bash
+# Use npx to run reloaderoo (works on any system)
+npx reloaderoo@latest --help
+
+# Or install globally if preferred
+npm install -g reloaderoo
+reloaderoo --help
+```
+
+## Two Operational Modes
+
+### 🔍 **CLI Mode** (Inspection & Testing)
+
+Direct command-line access to MCP servers without client setup - perfect for testing and debugging:
+
+**Key Benefits:**
+- ✅ **One-shot commands** - Test tools, list resources, get server info
+- ✅ **No MCP client required** - Perfect for testing and debugging
+- ✅ **Raw JSON output** - Ideal for scripts and automation
+- ✅ **8 inspection commands** - Complete MCP protocol coverage
+- ✅ **AI agent friendly** - Designed for terminal-based AI development workflows
+
+**Basic Commands:**
+
+```bash
+# List all available tools
+npx reloaderoo@latest inspect list-tools -- node build/index.js
+
+# Call any tool with parameters
+npx reloaderoo@latest inspect call-tool --params '' -- node build/index.js
+
+# Get server information
+npx reloaderoo@latest inspect server-info -- node build/index.js
+
+# List available resources
+npx reloaderoo@latest inspect list-resources -- node build/index.js
+
+# Read a specific resource
+npx reloaderoo@latest inspect read-resource "" -- node build/index.js
+
+# List available prompts
+npx reloaderoo@latest inspect list-prompts -- node build/index.js
+
+# Get a specific prompt
+npx reloaderoo@latest inspect get-prompt --args '' -- node build/index.js
+
+# Check server connectivity
+npx reloaderoo@latest inspect ping -- node build/index.js
+```
+
+**Example Tool Calls:**
+
+```bash
+# List connected devices
+npx reloaderoo@latest inspect call-tool list_devices --params '{}' -- node build/index.js
+
+# Get doctor information
+npx reloaderoo@latest inspect call-tool doctor --params '{}' -- node build/index.js
+
+# List iOS simulators
+npx reloaderoo@latest inspect call-tool list_sims --params '{}' -- node build/index.js
+
+# Read devices resource
+npx reloaderoo@latest inspect read-resource "xcodebuildmcp://devices" -- node build/index.js
+```
+
+### 🔄 **Proxy Mode** (Hot-Reload Development)
+
+Transparent MCP proxy server that enables seamless hot-reloading during development:
+
+**Key Benefits:**
+- ✅ **Hot-reload MCP servers** without disconnecting your AI client
+- ✅ **Session persistence** - Keep your development context intact
+- ✅ **Automatic `restart_server` tool** - AI agents can restart servers on demand
+- ✅ **Transparent forwarding** - Full MCP protocol passthrough
+- ✅ **Process management** - Spawns, monitors, and restarts your server process
+
+**Usage:**
+
+```bash
+# Start proxy mode (your AI client connects to this)
+npx reloaderoo@latest proxy -- node build/index.js
+
+# With debug logging
+npx reloaderoo@latest proxy --log-level debug -- node build/index.js
+
+# Then in your AI session, request:
+# "Please restart the MCP server to load my latest changes"
+```
+
+The AI agent will automatically call the `restart_server` tool, preserving your session while reloading code changes.
+
+## MCP Inspection Server Mode
+
+Start CLI mode as a persistent MCP server for interactive debugging through MCP clients:
+
+```bash
+# Start reloaderoo in CLI mode as an MCP server
+npx reloaderoo@latest inspect mcp -- node build/index.js
+```
+
+This runs CLI mode as a persistent MCP server, exposing 8 debug tools through the MCP protocol:
+- `list_tools` - List all server tools
+- `call_tool` - Call any server tool
+- `list_resources` - List all server resources
+- `read_resource` - Read any server resource
+- `list_prompts` - List all server prompts
+- `get_prompt` - Get any server prompt
+- `get_server_info` - Get comprehensive server information
+- `ping` - Test server connectivity
+
+## Claude Code Compatibility
+
+When running under Claude Code, XcodeBuildMCP automatically detects the environment and consolidates multiple content blocks into single responses with `---` separators.
+
+**Automatic Detection Methods:**
+1. **Environment Variables**: `CLAUDECODE=1` or `CLAUDE_CODE_ENTRYPOINT=cli`
+2. **Parent Process Analysis**: Checks if parent process contains 'claude'
+3. **Graceful Fallback**: Falls back to environment variables if process detection fails
+
+**No Configuration Required**: The consolidation happens automatically when Claude Code is detected.
+
+## Command Reference
+
+### Command Structure
+
+```bash
+npx reloaderoo@latest [options] [command]
+
+Two modes, one tool:
+• Proxy MCP server that adds support for hot-reloading MCP servers.
+• CLI tool for inspecting MCP servers.
+
+Global Options:
+ -V, --version Output the version number
+ -h, --help Display help for command
+
+Commands:
+ proxy [options] 🔄 Run as MCP proxy server (default behavior)
+ inspect 🔍 Inspect and debug MCP servers
+ info [options] 📊 Display version and configuration information
+ help [command] ❓ Display help for command
+```
+
+### 🔄 **Proxy Mode Commands**
+
+```bash
+npx reloaderoo@latest proxy [options] -- [child-args...]
+
+Options:
+ -w, --working-dir Working directory for the child process
+ -l, --log-level Log level (debug, info, notice, warning, error, critical)
+ -f, --log-file Custom log file path (logs to stderr by default)
+ -t, --restart-timeout Timeout for restart operations (default: 30000ms)
+ -m, --max-restarts Maximum restart attempts (0-10, default: 3)
+ -d, --restart-delay Delay between restart attempts (default: 1000ms)
+ -q, --quiet Suppress non-essential output
+ --no-auto-restart Disable automatic restart on crashes
+ --debug Enable debug mode with verbose logging
+ --dry-run Validate configuration without starting proxy
+
+Examples:
+ npx reloaderoo proxy -- node build/index.js
+ npx reloaderoo -- node build/index.js # Same as above (proxy is default)
+ npx reloaderoo proxy --log-level debug -- node build/index.js
+```
+
+### 🔍 **CLI Mode Commands**
+
+```bash
+npx reloaderoo@latest inspect [subcommand] [options] -- [child-args...]
+
+Subcommands:
+ server-info [options] Get server information and capabilities
+ list-tools [options] List all available tools
+ call-tool [options] Call a specific tool
+ list-resources [options] List all available resources
+ read-resource [options] Read a specific resource
+ list-prompts [options] List all available prompts
+ get-prompt [options] Get a specific prompt
+ ping [options] Check server connectivity
+
+Examples:
+ npx reloaderoo@latest inspect list-tools -- node build/index.js
+ npx reloaderoo@latest inspect call-tool list_devices --params '{}' -- node build/index.js
+ npx reloaderoo@latest inspect server-info -- node build/index.js
+```
+
+### **Info Command**
+
+```bash
+npx reloaderoo@latest info [options]
+
+Options:
+ -v, --verbose Show detailed information
+ -h, --help Display help for command
+
+Examples:
+ npx reloaderoo@latest info # Show basic system information
+ npx reloaderoo@latest info --verbose # Show detailed system information
+```
+
+### Response Format
+
+All CLI commands return structured JSON:
+
+```json
+{
+ "success": true,
+ "data": {
+ // Command-specific response data
+ },
+ "metadata": {
+ "command": "call-tool:list_devices",
+ "timestamp": "2025-07-25T08:32:47.042Z",
+ "duration": 1782
+ }
+}
+```
+
+### Error Handling
+
+When commands fail, you'll receive:
+
+```json
+{
+ "success": false,
+ "error": {
+ "message": "Error description",
+ "code": "ERROR_CODE"
+ },
+ "metadata": {
+ "command": "failed-command",
+ "timestamp": "2025-07-25T08:32:47.042Z",
+ "duration": 100
+ }
+}
+```
+
+## Development Workflow
+
+### 🔍 **CLI Mode Workflow** (Testing & Debugging)
+
+Perfect for testing individual tools or debugging server issues without MCP client setup:
+
+```bash
+# 1. Build XcodeBuildMCP
+npm run build
+
+# 2. Test your server quickly
+npx reloaderoo@latest inspect list-tools -- node build/index.js
+
+# 3. Call specific tools to verify behavior
+npx reloaderoo@latest inspect call-tool list_devices --params '{}' -- node build/index.js
+
+# 4. Check server health and resources
+npx reloaderoo@latest inspect ping -- node build/index.js
+npx reloaderoo@latest inspect list-resources -- node build/index.js
+```
+
+### 🔄 **Proxy Mode Workflow** (Hot-Reload Development)
+
+For full development sessions with AI clients that need persistent connections:
+
+#### 1. **Start Development Session**
+Configure your AI client to connect to reloaderoo proxy instead of your server directly:
+```bash
+npx reloaderoo@latest proxy -- node build/index.js
+# or with debug logging:
+npx reloaderoo@latest proxy --log-level debug -- node build/index.js
+```
+
+#### 2. **Develop Your MCP Server**
+Work on your XcodeBuildMCP code as usual - make changes, add tools, modify functionality.
+
+#### 3. **Test Changes Instantly**
+```bash
+# Rebuild your changes
+npm run build
+
+# Then ask your AI agent to restart the server:
+# "Please restart the MCP server to load my latest changes"
+```
+
+The agent will call the `restart_server` tool automatically. Your new capabilities are immediately available!
+
+#### 4. **Continue Development**
+Your AI session continues with the updated server capabilities. No connection loss, no context reset.
+
+### 🛠️ **MCP Inspection Server** (Interactive CLI Debugging)
+
+For interactive debugging through MCP clients:
+
+```bash
+# Start reloaderoo CLI mode as an MCP server
+npx reloaderoo@latest inspect mcp -- node build/index.js
+
+# Then connect with an MCP client to access debug tools
+# Available tools: list_tools, call_tool, list_resources, etc.
+```
+
+## Troubleshooting
+
+### 🔄 **Proxy Mode Issues**
+
+**Server won't start in proxy mode:**
+```bash
+# Check if XcodeBuildMCP runs independently first
+node build/index.js
+
+# Then try with reloaderoo proxy to validate configuration
+npx reloaderoo@latest proxy -- node build/index.js
+```
+
+**Connection problems with MCP clients:**
+```bash
+# Enable debug logging to see what's happening
+npx reloaderoo@latest proxy --log-level debug -- node build/index.js
+
+# Check system info and configuration
+npx reloaderoo@latest info --verbose
+```
+
+**Restart failures in proxy mode:**
+```bash
+# Increase restart timeout
+npx reloaderoo@latest proxy --restart-timeout 60000 -- node build/index.js
+
+# Check restart limits
+npx reloaderoo@latest proxy --max-restarts 5 -- node build/index.js
+```
+
+### 🔍 **CLI Mode Issues**
+
+**CLI commands failing:**
+```bash
+# Test basic connectivity first
+npx reloaderoo@latest inspect ping -- node build/index.js
+
+# Enable debug logging for CLI commands (via proxy debug mode)
+npx reloaderoo@latest proxy --log-level debug -- node build/index.js
+```
+
+**JSON parsing errors:**
+```bash
+# Check server information for troubleshooting
+npx reloaderoo@latest inspect server-info -- node build/index.js
+
+# Ensure your server outputs valid JSON
+node build/index.js | head -10
+```
+
+### **General Issues**
+
+**Command not found:**
+```bash
+# Ensure npx can find reloaderoo
+npx reloaderoo@latest --help
+
+# If that fails, try installing globally
+npm install -g reloaderoo
+```
+
+**Parameter validation:**
+```bash
+# Ensure JSON parameters are properly quoted
+npx reloaderoo@latest inspect call-tool list_devices --params '{}' -- node build/index.js
+```
+
+### **General Debug Mode**
+
+```bash
+# Get detailed information about what's happening
+npx reloaderoo@latest proxy --debug -- node build/index.js # For proxy mode
+npx reloaderoo@latest proxy --log-level debug -- node build/index.js # For detailed proxy logging
+
+# View system information
+npx reloaderoo@latest info --verbose
+```
+
+### Debug Tips
+
+1. **Always build first**: Run `npm run build` before testing
+2. **Check tool names**: Use `inspect list-tools` to see exact tool names
+3. **Validate JSON**: Ensure parameters are valid JSON strings
+4. **Enable debug logging**: Use `--log-level debug` or `--debug` for verbose output
+5. **Test connectivity**: Use `inspect ping` to verify server communication
+
+## Advanced Usage
+
+### Environment Variables
+
+Configure reloaderoo behavior via environment variables:
+
+```bash
+# Logging Configuration
+export MCPDEV_PROXY_LOG_LEVEL=debug # Log level (debug, info, notice, warning, error, critical)
+export MCPDEV_PROXY_LOG_FILE=/path/to/log # Custom log file path (default: stderr)
+export MCPDEV_PROXY_DEBUG_MODE=true # Enable debug mode (true/false)
+
+# Process Management
+export MCPDEV_PROXY_RESTART_LIMIT=5 # Maximum restart attempts (0-10, default: 3)
+export MCPDEV_PROXY_AUTO_RESTART=true # Enable/disable auto-restart (true/false)
+export MCPDEV_PROXY_TIMEOUT=30000 # Operation timeout in milliseconds
+export MCPDEV_PROXY_RESTART_DELAY=1000 # Delay between restart attempts in milliseconds
+export MCPDEV_PROXY_CWD=/path/to/directory # Default working directory
+```
+
+### Custom Working Directory
+
+```bash
+npx reloaderoo@latest proxy --working-dir /custom/path -- node build/index.js
+npx reloaderoo@latest inspect list-tools --working-dir /custom/path -- node build/index.js
+```
+
+### Timeout Configuration
+
+```bash
+npx reloaderoo@latest proxy --restart-timeout 60000 -- node build/index.js
+```
+
+## Integration with XcodeBuildMCP
+
+Reloaderoo is specifically configured to work with XcodeBuildMCP's:
+
+- **84+ Tools**: All workflow groups accessible via CLI
+- **4 Resources**: Direct access to devices, simulators, environment, swift-packages
+- **Claude Code Detection**: Automatic consolidation of multiple content blocks
+- **Hot-Reload Support**: Seamless development workflow with `restart_server`
+
+For more information about XcodeBuildMCP's architecture and capabilities, see:
+- [Architecture Guide](ARCHITECTURE.md)
+- [Plugin Development Guide](PLUGIN_DEVELOPMENT.md)
+- [Testing Guide](TESTING.md)
diff --git a/docs/RELOADEROO_FOR_XCODEBUILDMCP.md b/docs/RELOADEROO_FOR_XCODEBUILDMCP.md
new file mode 100644
index 00000000..a3ad909a
--- /dev/null
+++ b/docs/RELOADEROO_FOR_XCODEBUILDMCP.md
@@ -0,0 +1,302 @@
+# Reloaderoo Usage Guide for XcodeBuildMCP
+
+This guide explains how to use Reloaderoo for interacting with XcodeBuildMCP as a CLI to save context window space.
+
+You can use this guide to prompt your agent, but providing the entire document will give you no actual benefits. You will end up using more context than just using MCP server directly. So it's recommended that you curate this document by removing the example commands that you don't need and just keeping the ones that are right for your project. You'll then want to keep this file within your project workspace and then include it in the context window when you need to interact your agent to use XcodeBuildMCP tools.
+
+> [!IMPORTANT]
+> Please remove this introduction before you prompt your agent with this file or any derrived version of it.
+
+## Installation
+
+Reloaderoo is available via npm and can be used with npx for universal compatibility.
+
+```bash
+# Use npx to run reloaderoo
+npx reloaderoo@latest --help
+```
+
+**Example Tool Calls:**
+
+### iOS Device Development
+
+- **`build_device`**: Builds an app for a physical device.
+ ```bash
+ npx reloaderoo@latest inspect call-tool build_device --params '{"projectPath": "/path/to/MyProject.xcodeproj", "scheme": "MyScheme"}' -- node build/index.js
+ ```
+- **`get_device_app_path`**: Gets the `.app` bundle path for a device build.
+ ```bash
+ npx reloaderoo@latest inspect call-tool get_device_app_path --params '{"projectPath": "/path/to/MyProject.xcodeproj", "scheme": "MyScheme"}' -- node build/index.js
+ ```
+- **`install_app_device`**: Installs an app on a physical device.
+ ```bash
+ npx reloaderoo@latest inspect call-tool install_app_device --params '{"deviceId": "DEVICE_UDID", "appPath": "/path/to/MyApp.app"}' -- node build/index.js
+ ```
+- **`launch_app_device`**: Launches an app on a physical device.
+ ```bash
+ npx reloaderoo@latest inspect call-tool launch_app_device --params '{"deviceId": "DEVICE_UDID", "bundleId": "com.example.MyApp"}' -- node build/index.js
+ ```
+- **`list_devices`**: Lists connected physical devices.
+ ```bash
+ npx reloaderoo@latest inspect call-tool list_devices --params '{}' -- node build/index.js
+ ```
+- **`stop_app_device`**: Stops an app on a physical device.
+ ```bash
+ npx reloaderoo@latest inspect call-tool stop_app_device --params '{"deviceId": "DEVICE_UDID", "processId": 12345}' -- node build/index.js
+ ```
+- **`test_device`**: Runs tests on a physical device.
+ ```bash
+ npx reloaderoo@latest inspect call-tool test_device --params '{"projectPath": "/path/to/MyProject.xcodeproj", "scheme": "MyScheme", "deviceId": "DEVICE_UDID"}' -- node build/index.js
+ ```
+
+### iOS Simulator Development
+
+- **`boot_sim`**: Boots a simulator.
+ ```bash
+ npx reloaderoo@latest inspect call-tool boot_sim --params '{"simulatorId": "SIMULATOR_UUID"}' -- node build/index.js
+ ```
+- **`build_run_sim`**: Builds and runs an app on a simulator.
+ ```bash
+ npx reloaderoo@latest inspect call-tool build_run_sim --params '{"projectPath": "/path/to/MyProject.xcodeproj", "scheme": "MyScheme", "simulatorName": "iPhone 16"}' -- node build/index.js
+ ```
+- **`build_sim`**: Builds an app for a simulator.
+ ```bash
+ npx reloaderoo@latest inspect call-tool build_sim --params '{"projectPath": "/path/to/MyProject.xcodeproj", "scheme": "MyScheme", "simulatorName": "iPhone 16"}' -- node build/index.js
+ ```
+- **`get_sim_app_path`**: Gets the `.app` bundle path for a simulator build.
+ ```bash
+ npx reloaderoo@latest inspect call-tool get_sim_app_path --params '{"projectPath": "/path/to/MyProject.xcodeproj", "scheme": "MyScheme", "platform": "iOS Simulator", "simulatorName": "iPhone 16"}' -- node build/index.js
+ ```
+- **`install_app_sim`**: Installs an app on a simulator.
+ ```bash
+ npx reloaderoo@latest inspect call-tool install_app_sim --params '{"simulatorId": "SIMULATOR_UUID", "appPath": "/path/to/MyApp.app"}' -- node build/index.js
+ ```
+- **`launch_app_logs_sim`**: Launches an app on a simulator with log capture.
+ ```bash
+ npx reloaderoo@latest inspect call-tool launch_app_logs_sim --params '{"simulatorId": "SIMULATOR_UUID", "bundleId": "com.example.MyApp"}' -- node build/index.js
+ ```
+- **`launch_app_sim`**: Launches an app on a simulator.
+ ```bash
+ npx reloaderoo@latest inspect call-tool launch_app_sim --params '{"simulatorName": "iPhone 16", "bundleId": "com.example.MyApp"}' -- node build/index.js
+ ```
+- **`list_sims`**: Lists available simulators.
+ ```bash
+ npx reloaderoo@latest inspect call-tool list_sims --params '{}' -- node build/index.js
+ ```
+- **`open_sim`**: Opens the Simulator application.
+ ```bash
+ npx reloaderoo@latest inspect call-tool open_sim --params '{}' -- node build/index.js
+ ```
+- **`stop_app_sim`**: Stops an app on a simulator.
+ ```bash
+ npx reloaderoo@latest inspect call-tool stop_app_sim --params '{"simulatorName": "iPhone 16", "bundleId": "com.example.MyApp"}' -- node build/index.js
+ ```
+- **`test_sim`**: Runs tests on a simulator.
+ ```bash
+ npx reloaderoo@latest inspect call-tool test_sim --params '{"projectPath": "/path/to/MyProject.xcodeproj", "scheme": "MyScheme", "simulatorName": "iPhone 16"}' -- node build/index.js
+ ```
+
+### Log Capture & Management
+
+- **`start_device_log_cap`**: Starts log capture for a physical device.
+ ```bash
+ npx reloaderoo@latest inspect call-tool start_device_log_cap --params '{"deviceId": "DEVICE_UDID", "bundleId": "com.example.MyApp"}' -- node build/index.js
+ ```
+- **`start_sim_log_cap`**: Starts log capture for a simulator.
+ ```bash
+ npx reloaderoo@latest inspect call-tool start_sim_log_cap --params '{"simulatorUuid": "SIMULATOR_UUID", "bundleId": "com.example.MyApp"}' -- node build/index.js
+ ```
+- **`stop_device_log_cap`**: Stops log capture for a physical device.
+ ```bash
+ npx reloaderoo@latest inspect call-tool stop_device_log_cap --params '{"logSessionId": "SESSION_ID"}' -- node build/index.js
+ ```
+- **`stop_sim_log_cap`**: Stops log capture for a simulator.
+ ```bash
+ npx reloaderoo@latest inspect call-tool stop_sim_log_cap --params '{"logSessionId": "SESSION_ID"}' -- node build/index.js
+ ```
+
+### macOS Development
+
+- **`build_macos`**: Builds a macOS app.
+ ```bash
+ npx reloaderoo@latest inspect call-tool build_macos --params '{"projectPath": "/path/to/MyProject.xcodeproj", "scheme": "MyScheme"}' -- node build/index.js
+ ```
+- **`build_run_macos`**: Builds and runs a macOS app.
+ ```bash
+ npx reloaderoo@latest inspect call-tool build_run_macos --params '{"projectPath": "/path/to/MyProject.xcodeproj", "scheme": "MyScheme"}' -- node build/index.js
+ ```
+- **`get_mac_app_path`**: Gets the `.app` bundle path for a macOS build.
+ ```bash
+ npx reloaderoo@latest inspect call-tool get_mac_app_path --params '{"projectPath": "/path/to/MyProject.xcodeproj", "scheme": "MyScheme"}' -- node build/index.js
+ ```
+- **`launch_mac_app`**: Launches a macOS app.
+ ```bash
+ npx reloaderoo@latest inspect call-tool launch_mac_app --params '{"appPath": "/Applications/Calculator.app"}' -- node build/index.js
+ ```
+- **`stop_mac_app`**: Stops a macOS app.
+ ```bash
+ npx reloaderoo@latest inspect call-tool stop_mac_app --params '{"appName": "Calculator"}' -- node build/index.js
+ ```
+- **`test_macos`**: Runs tests for a macOS project.
+ ```bash
+ npx reloaderoo@latest inspect call-tool test_macos --params '{"projectPath": "/path/to/MyProject.xcodeproj", "scheme": "MyScheme"}' -- node build/index.js
+ ```
+
+### Project Discovery
+
+- **`discover_projs`**: Discovers Xcode projects and workspaces.
+ ```bash
+ npx reloaderoo@latest inspect call-tool discover_projs --params '{"workspaceRoot": "/path/to/workspace"}' -- node build/index.js
+ ```
+- **`get_app_bundle_id`**: Gets an app's bundle identifier.
+ ```bash
+ npx reloaderoo@latest inspect call-tool get_app_bundle_id --params '{"appPath": "/path/to/MyApp.app"}' -- node build/index.js
+ ```
+- **`get_mac_bundle_id`**: Gets a macOS app's bundle identifier.
+ ```bash
+ npx reloaderoo@latest inspect call-tool get_mac_bundle_id --params '{"appPath": "/Applications/Calculator.app"}' -- node build/index.js
+ ```
+- **`list_schemes`**: Lists schemes in a project or workspace.
+ ```bash
+ npx reloaderoo@latest inspect call-tool list_schemes --params '{"projectPath": "/path/to/MyProject.xcodeproj"}' -- node build/index.js
+ ```
+- **`show_build_settings`**: Shows build settings for a scheme.
+ ```bash
+ npx reloaderoo@latest inspect call-tool show_build_settings --params '{"projectPath": "/path/to/MyProject.xcodeproj", "scheme": "MyScheme"}' -- node build/index.js
+ ```
+
+### Project Scaffolding
+
+- **`scaffold_ios_project`**: Scaffolds a new iOS project.
+ ```bash
+ npx reloaderoo@latest inspect call-tool scaffold_ios_project --params '{"projectName": "MyNewApp", "outputPath": "/path/to/projects"}' -- node build/index.js
+ ```
+- **`scaffold_macos_project`**: Scaffolds a new macOS project.
+ ```bash
+ npx reloaderoo@latest inspect call-tool scaffold_macos_project --params '{"projectName": "MyNewMacApp", "outputPath": "/path/to/projects"}' -- node build/index.js
+ ```
+
+### Project Utilities
+
+- **`clean`**: Cleans build artifacts.
+ ```bash
+ # For a project
+ npx reloaderoo@latest inspect call-tool clean --params '{"projectPath": "/path/to/MyProject.xcodeproj"}' -- node build/index.js
+ # For a workspace
+ npx reloaderoo@latest inspect call-tool clean --params '{"workspacePath": "/path/to/MyWorkspace.xcworkspace", "scheme": "MyScheme"}' -- node build/index.js
+ ```
+
+### Simulator Management
+
+- **`reset_sim_location`**: Resets a simulator's location.
+ ```bash
+ npx reloaderoo@latest inspect call-tool reset_sim_location --params '{"simulatorUuid": "SIMULATOR_UUID"}' -- node build/index.js
+ ```
+- **`set_sim_appearance`**: Sets a simulator's appearance (dark/light mode).
+ ```bash
+ npx reloaderoo@latest inspect call-tool set_sim_appearance --params '{"simulatorUuid": "SIMULATOR_UUID", "mode": "dark"}' -- node build/index.js
+ ```
+- **`set_sim_location`**: Sets a simulator's GPS location.
+ ```bash
+ npx reloaderoo@latest inspect call-tool set_sim_location --params '{"simulatorUuid": "SIMULATOR_UUID", "latitude": 37.7749, "longitude": -122.4194}' -- node build/index.js
+ ```
+- **`sim_statusbar`**: Overrides a simulator's status bar.
+ ```bash
+ npx reloaderoo@latest inspect call-tool sim_statusbar --params '{"simulatorUuid": "SIMULATOR_UUID", "dataNetwork": "wifi"}' -- node build/index.js
+ ```
+
+### Swift Package Manager
+
+- **`swift_package_build`**: Builds a Swift package.
+ ```bash
+ npx reloaderoo@latest inspect call-tool swift_package_build --params '{"packagePath": "/path/to/package"}' -- node build/index.js
+ ```
+- **`swift_package_clean`**: Cleans a Swift package.
+ ```bash
+ npx reloaderoo@latest inspect call-tool swift_package_clean --params '{"packagePath": "/path/to/package"}' -- node build/index.js
+ ```
+- **`swift_package_list`**: Lists running Swift package processes.
+ ```bash
+ npx reloaderoo@latest inspect call-tool swift_package_list --params '{}' -- node build/index.js
+ ```
+- **`swift_package_run`**: Runs a Swift package executable.
+ ```bash
+ npx reloaderoo@latest inspect call-tool swift_package_run --params '{"packagePath": "/path/to/package"}' -- node build/index.js
+ ```
+- **`swift_package_stop`**: Stops a running Swift package process.
+ ```bash
+ npx reloaderoo@latest inspect call-tool swift_package_stop --params '{"pid": 12345}' -- node build/index.js
+ ```
+- **`swift_package_test`**: Tests a Swift package.
+ ```bash
+ npx reloaderoo@latest inspect call-tool swift_package_test --params '{"packagePath": "/path/to/package"}' -- node build/index.js
+ ```
+
+### System Doctor
+
+- **`doctor`**: Runs system diagnostics.
+ ```bash
+ npx reloaderoo@latest inspect call-tool doctor --params '{}' -- node build/index.js
+ ```
+
+### UI Testing & Automation
+
+- **`button`**: Simulates a hardware button press.
+ ```bash
+ npx reloaderoo@latest inspect call-tool button --params '{"simulatorUuid": "SIMULATOR_UUID", "buttonType": "home"}' -- node build/index.js
+ ```
+- **`describe_ui`**: Gets the UI hierarchy of the current screen.
+ ```bash
+ npx reloaderoo@latest inspect call-tool describe_ui --params '{"simulatorUuid": "SIMULATOR_UUID"}' -- node build/index.js
+ ```
+- **`gesture`**: Performs a pre-defined gesture.
+ ```bash
+ npx reloaderoo@latest inspect call-tool gesture --params '{"simulatorUuid": "SIMULATOR_UUID", "preset": "scroll-up"}' -- node build/index.js
+ ```
+- **`key_press`**: Simulates a key press.
+ ```bash
+ npx reloaderoo@latest inspect call-tool key_press --params '{"simulatorUuid": "SIMULATOR_UUID", "keyCode": 40}' -- node build/index.js
+ ```
+- **`key_sequence`**: Simulates a sequence of key presses.
+ ```bash
+ npx reloaderoo@latest inspect call-tool key_sequence --params '{"simulatorUuid": "SIMULATOR_UUID", "keyCodes": [40, 42, 44]}' -- node build/index.js
+ ```
+- **`long_press`**: Performs a long press at coordinates.
+ ```bash
+ npx reloaderoo@latest inspect call-tool long_press --params '{"simulatorUuid": "SIMULATOR_UUID", "x": 100, "y": 200, "duration": 1500}' -- node build/index.js
+ ```
+- **`screenshot`**: Takes a screenshot.
+ ```bash
+ npx reloaderoo@latest inspect call-tool screenshot --params '{"simulatorUuid": "SIMULATOR_UUID"}' -- node build/index.js
+ ```
+- **`swipe`**: Performs a swipe gesture.
+ ```bash
+ npx reloaderoo@latest inspect call-tool swipe --params '{"simulatorUuid": "SIMULATOR_UUID", "x1": 100, "y1": 200, "x2": 100, "y2": 400}' -- node build/index.js
+ ```
+- **`tap`**: Performs a tap at coordinates.
+ ```bash
+ npx reloaderoo@latest inspect call-tool tap --params '{"simulatorUuid": "SIMULATOR_UUID", "x": 100, "y": 200}' -- node build/index.js
+ ```
+- **`touch`**: Simulates a touch down or up event.
+ ```bash
+ npx reloaderoo@latest inspect call-tool touch --params '{"simulatorUuid": "SIMULATOR_UUID", "x": 100, "y": 200, "down": true}' -- node build/index.js
+ ```
+- **`type_text`**: Types text into the focused element.
+ ```bash
+ npx reloaderoo@latest inspect call-tool type_text --params '{"simulatorUuid": "SIMULATOR_UUID", "text": "Hello, World!"}' -- node build/index.js
+ ```
+
+### Resources
+
+- **Read devices resource**:
+ ```bash
+ npx reloaderoo@latest inspect read-resource "xcodebuildmcp://devices" -- node build/index.js
+ ```
+- **Read simulators resource**:
+ ```bash
+ npx reloaderoo@latest inspect read-resource "xcodebuildmcp://simulators" -- node build/index.js
+ ```
+- **Read doctor resource**:
+ ```bash
+ npx reloaderoo@latest inspect read-resource "xcodebuildmcp://doctor" -- node build/index.js
+ ```
diff --git a/docs/RELOADEROO_XCODEBUILDMCP_PRIMER.md b/docs/RELOADEROO_XCODEBUILDMCP_PRIMER.md
new file mode 100644
index 00000000..eefada1d
--- /dev/null
+++ b/docs/RELOADEROO_XCODEBUILDMCP_PRIMER.md
@@ -0,0 +1,325 @@
+# Reloaderoo + XcodeBuildMCP: Curated CLI Primer
+
+Use this primer to drive XcodeBuildMCP entirely through Reloaderoo—treating it like a CLI. It is designed to be included in your agent’s context to show exactly how to invoke the specific tools your project needs.
+
+Why this file:
+- XcodeBuildMCP exposes many tools. Dumping the full tool surface into the context wastes tokens.
+- Instead, copy this file into your project and delete everything you don’t need. Keep only the commands relevant to your workflow (e.g., just Simulator tools).
+- Your trimmed version becomes a small, project‑specific reference that tells your agent precisely which Reloaderoo tool calls to make.
+
+How to use this primer:
+1. Copy this file into your repo (e.g., docs/xcodebuildmcp_primer.md or AGENTS.md).
+2. Remove all sections and commands you don’t use. Keep it minimal.
+3. Replace placeholders with your real values (paths, schemes, simulator UUIDs/Names, bundle IDs, etc.).
+4. Use the quiet (-q) examples to reduce noise; pipe output to jq when you only need the content.
+5. Include your curated file in the agent context whenever you want it to call XcodeBuildMCP via Reloaderoo.
+
+Conventions in the examples:
+- Calls use: npx reloaderoo@latest inspect … -q -- npx xcodebuildmcp@latest
+- Parameters are passed as JSON via --params.
+- Resources are read with read-resource (e.g., xcodebuildmcp://simulators).
+- Use jq -r '.contents[].text' to extract the textual results when needed.
+
+Keep it small. The smaller your curated primer, the less context your agent needs—and the cheaper, faster, and more reliable your interactions will be.
+
+## Installation
+
+Reloaderoo is available via npm and can be used with npx for universal compatibility.
+
+```bash
+# Use npx to run reloaderoo
+npx reloaderoo@latest --help
+```
+
+## Hint
+
+Use jq to parse the output to get just the content response:
+
+```bash
+ npx reloaderoo@latest inspect read-resource "xcodebuildmcp://simulators" -q -- npx xcodebuildmcp@latest | jq -r '.contents[].text'
+ ```
+
+**Example Tool Calls:**
+
+## iOS Device Development
+
+- **`build_device`**: Builds an app for a physical device.
+ ```bash
+ npx reloaderoo@latest inspect -q call-tool build_device --params '{"projectPath": "/path/to/MyProject.xcodeproj", "scheme": "MyScheme"}' -q -- npx xcodebuildmcp@latest
+ ```
+- **`get_device_app_path`**: Gets the `.app` bundle path for a device build.
+ ```bash
+ npx reloaderoo@latest inspect call-tool get_device_app_path --params '{"projectPath": "/path/to/MyProject.xcodeproj", "scheme": "MyScheme"}' -q -- npx xcodebuildmcp@latest
+ ```
+- **`install_app_device`**: Installs an app on a physical device.
+ ```bash
+ npx reloaderoo@latest inspect call-tool install_app_device --params '{"deviceId": "DEVICE_UDID", "appPath": "/path/to/MyApp.app"}' -q -- npx xcodebuildmcp@latest
+ ```
+- **`launch_app_device`**: Launches an app on a physical device.
+ ```bash
+ npx reloaderoo@latest inspect call-tool launch_app_device --params '{"deviceId": "DEVICE_UDID", "bundleId": "com.example.MyApp"}' -q -- npx xcodebuildmcp@latest
+ ```
+- **`list_devices`**: Lists connected physical devices.
+ ```bash
+ npx reloaderoo@latest inspect call-tool list_devices --params '{}' -q -- npx xcodebuildmcp@latest
+ ```
+- **`stop_app_device`**: Stops an app on a physical device.
+ ```bash
+ npx reloaderoo@latest inspect call-tool stop_app_device --params '{"deviceId": "DEVICE_UDID", "processId": 12345}' -q -- npx xcodebuildmcp@latest
+ ```
+- **`test_device`**: Runs tests on a physical device.
+ ```bash
+ npx reloaderoo@latest inspect call-tool test_device --params '{"projectPath": "/path/to/MyProject.xcodeproj", "scheme": "MyScheme", "deviceId": "DEVICE_UDID"}' -q -- npx xcodebuildmcp@latest
+ ```
+
+## iOS Simulator Development
+
+- **`boot_sim`**: Boots a simulator.
+ ```bash
+ npx reloaderoo@latest inspect call-tool boot_sim --params '{"simulatorUuid": "SIMULATOR_UUID"}' -q -- npx xcodebuildmcp@latest
+ ```
+- **`build_run_sim`**: Builds and runs an app on a simulator.
+ ```bash
+ npx reloaderoo@latest inspect call-tool build_run_sim --params '{"projectPath": "/path/to/MyProject.xcodeproj", "scheme": "MyScheme", "simulatorName": "iPhone 16"}' -q -- npx xcodebuildmcp@latest
+ ```
+- **`build_sim`**: Builds an app for a simulator.
+ ```bash
+ npx reloaderoo@latest inspect call-tool build_sim --params '{"projectPath": "/path/to/MyProject.xcodeproj", "scheme": "MyScheme", "simulatorName": "iPhone 16"}' -q -- npx xcodebuildmcp@latest
+ ```
+- **`get_sim_app_path`**: Gets the `.app` bundle path for a simulator build.
+ ```bash
+ npx reloaderoo@latest inspect call-tool get_sim_app_path --params '{"projectPath": "/path/to/MyProject.xcodeproj", "scheme": "MyScheme", "platform": "iOS Simulator", "simulatorName": "iPhone 16"}' -q -- npx xcodebuildmcp@latest
+ ```
+- **`install_app_sim`**: Installs an app on a simulator.
+ ```bash
+ npx reloaderoo@latest inspect call-tool install_app_sim --params '{"simulatorUuid": "SIMULATOR_UUID", "appPath": "/path/to/MyApp.app"}' -q -- npx xcodebuildmcp@latest
+ ```
+- **`launch_app_logs_sim`**: Launches an app on a simulator with log capture.
+ ```bash
+ npx reloaderoo@latest inspect call-tool launch_app_logs_sim --params '{"simulatorUuid": "SIMULATOR_UUID", "bundleId": "com.example.MyApp"}' -q -- npx xcodebuildmcp@latest
+ ```
+- **`launch_app_sim`**: Launches an app on a simulator.
+ ```bash
+ npx reloaderoo@latest inspect call-tool launch_app_sim --params '{"simulatorName": "iPhone 16", "bundleId": "com.example.MyApp"}' -q -- npx xcodebuildmcp@latest
+ ```
+- **`list_sims`**: Lists available simulators.
+ ```bash
+ npx reloaderoo@latest inspect call-tool list_sims --params '{}' -q -- npx xcodebuildmcp@latest
+ ```
+- **`open_sim`**: Opens the Simulator application.
+ ```bash
+ npx reloaderoo@latest inspect call-tool open_sim --params '{}' -q -- npx xcodebuildmcp@latest
+ ```
+- **`stop_app_sim`**: Stops an app on a simulator.
+ ```bash
+ npx reloaderoo@latest inspect call-tool stop_app_sim --params '{"simulatorName": "iPhone 16", "bundleId": "com.example.MyApp"}' -q -- npx xcodebuildmcp@latest
+ ```
+- **`test_sim`**: Runs tests on a simulator.
+ ```bash
+ npx reloaderoo@latest inspect call-tool test_sim --params '{"projectPath": "/path/to/MyProject.xcodeproj", "scheme": "MyScheme", "simulatorName": "iPhone 16"}' -q -- npx xcodebuildmcp@latest
+ ```
+
+## Log Capture & Management
+
+- **`start_device_log_cap`**: Starts log capture for a physical device.
+ ```bash
+ npx reloaderoo@latest inspect call-tool start_device_log_cap --params '{"deviceId": "DEVICE_UDID", "bundleId": "com.example.MyApp"}' -q -- npx xcodebuildmcp@latest
+ ```
+- **`start_sim_log_cap`**: Starts log capture for a simulator.
+ ```bash
+ npx reloaderoo@latest inspect call-tool start_sim_log_cap --params '{"simulatorUuid": "SIMULATOR_UUID", "bundleId": "com.example.MyApp"}' -q -- npx xcodebuildmcp@latest
+ ```
+- **`stop_device_log_cap`**: Stops log capture for a physical device.
+ ```bash
+ npx reloaderoo@latest inspect call-tool stop_device_log_cap --params '{"logSessionId": "SESSION_ID"}' -q -- npx xcodebuildmcp@latest
+ ```
+- **`stop_sim_log_cap`**: Stops log capture for a simulator.
+ ```bash
+ npx reloaderoo@latest inspect call-tool stop_sim_log_cap --params '{"logSessionId": "SESSION_ID"}' -q -- npx xcodebuildmcp@latest
+ ```
+
+## macOS Development
+
+- **`build_macos`**: Builds a macOS app.
+ ```bash
+ npx reloaderoo@latest inspect call-tool build_macos --params '{"projectPath": "/path/to/MyProject.xcodeproj", "scheme": "MyScheme"}' -q -- npx xcodebuildmcp@latest
+ ```
+- **`build_run_macos`**: Builds and runs a macOS app.
+ ```bash
+ npx reloaderoo@latest inspect call-tool build_run_macos --params '{"projectPath": "/path/to/MyProject.xcodeproj", "scheme": "MyScheme"}' -q -- npx xcodebuildmcp@latest
+ ```
+- **`get_mac_app_path`**: Gets the `.app` bundle path for a macOS build.
+ ```bash
+ npx reloaderoo@latest inspect call-tool get_mac_app_path --params '{"projectPath": "/path/to/MyProject.xcodeproj", "scheme": "MyScheme"}' -q -- npx xcodebuildmcp@latest
+ ```
+- **`launch_mac_app`**: Launches a macOS app.
+ ```bash
+ npx reloaderoo@latest inspect call-tool launch_mac_app --params '{"appPath": "/Applications/Calculator.app"}' -q -- npx xcodebuildmcp@latest
+ ```
+- **`stop_mac_app`**: Stops a macOS app.
+ ```bash
+ npx reloaderoo@latest inspect call-tool stop_mac_app --params '{"appName": "Calculator"}' -q -- npx xcodebuildmcp@latest
+ ```
+- **`test_macos`**: Runs tests for a macOS project.
+ ```bash
+ npx reloaderoo@latest inspect call-tool test_macos --params '{"projectPath": "/path/to/MyProject.xcodeproj", "scheme": "MyScheme"}' -q -- npx xcodebuildmcp@latest
+ ```
+
+## Project Discovery
+
+- **`discover_projs`**: Discovers Xcode projects and workspaces.
+ ```bash
+ npx reloaderoo@latest inspect call-tool discover_projs --params '{"workspaceRoot": "/path/to/workspace"}' -q -- npx xcodebuildmcp@latest
+ ```
+- **`get_app_bundle_id`**: Gets an app's bundle identifier.
+ ```bash
+ npx reloaderoo@latest inspect call-tool get_app_bundle_id --params '{"appPath": "/path/to/MyApp.app"}' -q -- npx xcodebuildmcp@latest
+ ```
+- **`get_mac_bundle_id`**: Gets a macOS app's bundle identifier.
+ ```bash
+ npx reloaderoo@latest inspect call-tool get_mac_bundle_id --params '{"appPath": "/Applications/Calculator.app"}' -q -- npx xcodebuildmcp@latest
+ ```
+- **`list_schemes`**: Lists schemes in a project or workspace.
+ ```bash
+ npx reloaderoo@latest inspect call-tool list_schemes --params '{"projectPath": "/path/to/MyProject.xcodeproj"}' -q -- npx xcodebuildmcp@latest
+ ```
+- **`show_build_settings`**: Shows build settings for a scheme.
+ ```bash
+ npx reloaderoo@latest inspect call-tool show_build_settings --params '{"projectPath": "/path/to/MyProject.xcodeproj", "scheme": "MyScheme"}' -q -- npx xcodebuildmcp@latest
+ ```
+
+## Project Scaffolding
+
+- **`scaffold_ios_project`**: Scaffolds a new iOS project.
+ ```bash
+ npx reloaderoo@latest inspect call-tool scaffold_ios_project --params '{"projectName": "MyNewApp", "outputPath": "/path/to/projects"}' -q -- npx xcodebuildmcp@latest
+ ```
+- **`scaffold_macos_project`**: Scaffolds a new macOS project.
+ ```bash
+ npx reloaderoo@latest inspect call-tool scaffold_macos_project --params '{"projectName": "MyNewMacApp", "outputPath": "/path/to/projects"}' -q -- npx xcodebuildmcp@latest
+ ```
+
+## Project Utilities
+
+- **`clean`**: Cleans build artifacts.
+ ```bash
+ # For a project
+ npx reloaderoo@latest inspect call-tool clean --params '{"projectPath": "/path/to/MyProject.xcodeproj"}' -q -- npx xcodebuildmcp@latest
+ # For a workspace
+ npx reloaderoo@latest inspect call-tool clean --params '{"workspacePath": "/path/to/MyWorkspace.xcworkspace", "scheme": "MyScheme"}' -q -- npx xcodebuildmcp@latest
+ ```
+
+## Simulator Management
+
+- **`reset_sim_location`**: Resets a simulator's location.
+ ```bash
+ npx reloaderoo@latest inspect call-tool reset_sim_location --params '{"simulatorUuid": "SIMULATOR_UUID"}' -q -- npx xcodebuildmcp@latest
+ ```
+- **`set_sim_appearance`**: Sets a simulator's appearance (dark/light mode).
+ ```bash
+ npx reloaderoo@latest inspect call-tool set_sim_appearance --params '{"simulatorUuid": "SIMULATOR_UUID", "mode": "dark"}' -q -- npx xcodebuildmcp@latest
+ ```
+- **`set_sim_location`**: Sets a simulator's GPS location.
+ ```bash
+ npx reloaderoo@latest inspect call-tool set_sim_location --params '{"simulatorUuid": "SIMULATOR_UUID", "latitude": 37.7749, "longitude": -122.4194}' -q -- npx xcodebuildmcp@latest
+ ```
+- **`sim_statusbar`**: Overrides a simulator's status bar.
+ ```bash
+ npx reloaderoo@latest inspect call-tool sim_statusbar --params '{"simulatorUuid": "SIMULATOR_UUID", "dataNetwork": "wifi"}' -q -- npx xcodebuildmcp@latest
+ ```
+
+## Swift Package Manager
+
+- **`swift_package_build`**: Builds a Swift package.
+ ```bash
+ npx reloaderoo@latest inspect call-tool swift_package_build --params '{"packagePath": "/path/to/package"}' -q -- npx xcodebuildmcp@latest
+ ```
+- **`swift_package_clean`**: Cleans a Swift package.
+ ```bash
+ npx reloaderoo@latest inspect call-tool swift_package_clean --params '{"packagePath": "/path/to/package"}' -q -- npx xcodebuildmcp@latest
+ ```
+- **`swift_package_list`**: Lists running Swift package processes.
+ ```bash
+ npx reloaderoo@latest inspect call-tool swift_package_list --params '{}' -q -- npx xcodebuildmcp@latest
+ ```
+- **`swift_package_run`**: Runs a Swift package executable.
+ ```bash
+ npx reloaderoo@latest inspect call-tool swift_package_run --params '{"packagePath": "/path/to/package"}' -q -- npx xcodebuildmcp@latest
+ ```
+- **`swift_package_stop`**: Stops a running Swift package process.
+ ```bash
+ npx reloaderoo@latest inspect call-tool swift_package_stop --params '{"pid": 12345}' -q -- npx xcodebuildmcp@latest
+ ```
+- **`swift_package_test`**: Tests a Swift package.
+ ```bash
+ npx reloaderoo@latest inspect call-tool swift_package_test --params '{"packagePath": "/path/to/package"}' -q -- npx xcodebuildmcp@latest
+ ```
+
+## System Doctor
+
+- **`doctor`**: Runs system diagnostics.
+ ```bash
+ npx reloaderoo@latest inspect call-tool doctor --params '{}' -q -- npx xcodebuildmcp@latest
+ ```
+
+## UI Testing & Automation
+
+- **`button`**: Simulates a hardware button press.
+ ```bash
+ npx reloaderoo@latest inspect call-tool button --params '{"simulatorUuid": "SIMULATOR_UUID", "buttonType": "home"}' -q -- npx xcodebuildmcp@latest
+ ```
+- **`describe_ui`**: Gets the UI hierarchy of the current screen.
+ ```bash
+ npx reloaderoo@latest inspect call-tool describe_ui --params '{"simulatorUuid": "SIMULATOR_UUID"}' -q -- npx xcodebuildmcp@latest
+ ```
+- **`gesture`**: Performs a pre-defined gesture.
+ ```bash
+ npx reloaderoo@latest inspect call-tool gesture --params '{"simulatorUuid": "SIMULATOR_UUID", "preset": "scroll-up"}' -q -- npx xcodebuildmcp@latest
+ ```
+- **`key_press`**: Simulates a key press.
+ ```bash
+ npx reloaderoo@latest inspect call-tool key_press --params '{"simulatorUuid": "SIMULATOR_UUID", "keyCode": 40}' -q -- npx xcodebuildmcp@latest
+ ```
+- **`key_sequence`**: Simulates a sequence of key presses.
+ ```bash
+ npx reloaderoo@latest inspect call-tool key_sequence --params '{"simulatorUuid": "SIMULATOR_UUID", "keyCodes": [40, 42, 44]}' -q -- npx xcodebuildmcp@latest
+ ```
+- **`long_press`**: Performs a long press at coordinates.
+ ```bash
+ npx reloaderoo@latest inspect call-tool long_press --params '{"simulatorUuid": "SIMULATOR_UUID", "x": 100, "y": 200, "duration": 1500}' -q -- npx xcodebuildmcp@latest
+ ```
+- **`screenshot`**: Takes a screenshot.
+ ```bash
+ npx reloaderoo@latest inspect call-tool screenshot --params '{"simulatorUuid": "SIMULATOR_UUID"}' -q -- npx xcodebuildmcp@latest
+ ```
+- **`swipe`**: Performs a swipe gesture.
+ ```bash
+ npx reloaderoo@latest inspect call-tool swipe --params '{"simulatorUuid": "SIMULATOR_UUID", "x1": 100, "y1": 200, "x2": 100, "y2": 400}' -q -- npx xcodebuildmcp@latest
+ ```
+- **`tap`**: Performs a tap at coordinates.
+ ```bash
+ npx reloaderoo@latest inspect call-tool tap --params '{"simulatorUuid": "SIMULATOR_UUID", "x": 100, "y": 200}' -q -- npx xcodebuildmcp@latest
+ ```
+- **`touch`**: Simulates a touch down or up event.
+ ```bash
+ npx reloaderoo@latest inspect call-tool touch --params '{"simulatorUuid": "SIMULATOR_UUID", "x": 100, "y": 200, "down": true}' -q -- npx xcodebuildmcp@latest
+ ```
+- **`type_text`**: Types text into the focused element.
+ ```bash
+ npx reloaderoo@latest inspect call-tool type_text --params '{"simulatorUuid": "SIMULATOR_UUID", "text": "Hello, World!"}' -q -- npx xcodebuildmcp@latest
+ ```
+
+## Resources
+
+- **Read devices resource**:
+ ```bash
+ npx reloaderoo@latest inspect read-resource "xcodebuildmcp://devices" -q -- npx xcodebuildmcp@latest
+ ```
+- **Read simulators resource**:
+ ```bash
+ npx reloaderoo@latest inspect read-resource "xcodebuildmcp://simulators" -q -- npx xcodebuildmcp@latest
+ ```
+- **Read doctor resource**:
+ ```bash
+ npx reloaderoo@latest inspect read-resource "xcodebuildmcp://doctor" -q -- npx xcodebuildmcp@latest
+ ```
diff --git a/docs/TESTING.md b/docs/TESTING.md
new file mode 100644
index 00000000..ec8756be
--- /dev/null
+++ b/docs/TESTING.md
@@ -0,0 +1,1289 @@
+# XcodeBuildMCP Plugin Testing Guidelines
+
+This document provides comprehensive testing guidelines for XcodeBuildMCP plugins, ensuring consistent, robust, and maintainable test coverage across the entire codebase.
+
+## Table of Contents
+
+1. [Testing Philosophy](#testing-philosophy)
+2. [Test Architecture](#test-architecture)
+3. [Dependency Injection Strategy](#dependency-injection-strategy)
+4. [Three-Dimensional Testing](#three-dimensional-testing)
+5. [Test Organization](#test-organization)
+6. [Test Patterns](#test-patterns)
+7. [Performance Requirements](#performance-requirements)
+8. [Coverage Standards](#coverage-standards)
+9. [Common Patterns](#common-patterns)
+10. [Manual Testing with Reloaderoo](#manual-testing-with-reloaderoo)
+11. [Troubleshooting](#troubleshooting)
+
+## Testing Philosophy
+
+### 🚨 CRITICAL: No Vitest Mocking Allowed
+
+### ABSOLUTE RULE: ALL VITEST MOCKING IS COMPLETELY BANNED
+
+### FORBIDDEN PATTERNS (will cause immediate test failure):
+
+#### Vitest Mocking (COMPLETELY BANNED):
+- `vi.mock()` - BANNED
+- `vi.fn()` - BANNED
+- `vi.mocked()` - BANNED
+- `vi.spyOn()` - BANNED
+- `.mockResolvedValue()` - BANNED
+- `.mockRejectedValue()` - BANNED
+- `.mockReturnValue()` - BANNED
+- `.mockImplementation()` - BANNED
+- `.toHaveBeenCalled()` - BANNED
+- `.toHaveBeenCalledWith()` - BANNED
+- `MockedFunction` type - BANNED
+
+#### Manual Mock Implementations (BANNED - use our utilities instead):
+- `const mockExecutor = async (...) => { ... }` - Use `createMockExecutor()` instead
+- `const mockFsDeps = { readFile: async () => ... }` - Use `createMockFileSystemExecutor()` instead
+- `const mockServer = { ... }` - Refactor to use dependency injection pattern
+- Any manual async function implementations for mocking behavior
+
+### ONLY ALLOWED MOCKING:
+- `createMockExecutor({ success: true, output: 'result' })` - command execution
+- `createMockFileSystemExecutor({ readFile: async () => 'content' })` - file system operations
+
+### OUR CORE PRINCIPLE
+
+**Simple Rule**: No mocking other than `createMockExecutor()` and `createMockFileSystemExecutor()` (and their noop variants).
+
+**Why This Rule Exists**:
+1. **Consistency**: All tests use the same mocking utilities, making them predictable and maintainable
+2. **Reliability**: Our utilities are thoroughly tested and handle edge cases properly
+3. **Architectural Enforcement**: Prevents bypassing our dependency injection patterns
+4. **Simplicity**: One clear rule instead of complex guidelines about what mocking is acceptable
+
+### Integration Testing with Dependency Injection
+
+XcodeBuildMCP follows a **pure dependency injection** testing philosophy that eliminates vitest mocking:
+
+- ✅ **Test plugin interfaces** (public API contracts)
+- ✅ **Test integration flows** (plugin → utilities → external tools)
+- ✅ **Use dependency injection** with createMockExecutor()
+- ❌ **Never mock vitest functions** (vi.mock, vi.fn, etc.)
+
+### Benefits
+
+1. **Implementation Independence**: Internal refactoring doesn't break tests
+2. **Real Coverage**: Tests verify actual user data flows
+3. **Maintainability**: No brittle vitest mocks that break on implementation changes
+4. **True Integration**: Catches integration bugs between layers
+5. **Test Safety**: Default executors throw errors in test environment
+
+### Automated Violation Checking
+
+To enforce the no-mocking policy, the project includes a script that automatically checks for banned testing patterns.
+
+```bash
+# Run the script to check for violations
+node scripts/check-code-patterns.js
+```
+
+This script is part of the standard development workflow and should be run before committing changes to ensure compliance with the testing standards.
+
+### What the Script Flags vs. What It Should NOT Flag
+
+#### ✅ LEGITIMATE VIOLATIONS (correctly flagged):
+- Manual mock executors: `const mockExecutor = async (...) => { ... }`
+- Manual filesystem mocks: `const mockFsDeps = { readFile: async () => ... }`
+- Manual server mocks: `const mockServer = { ... }`
+- Vitest mocking patterns: `vi.mock()`, `vi.fn()`, etc.
+
+#### ❌ FALSE POSITIVES (should NOT be flagged):
+- Test data tracking: `commandCalls.push({ ... })` - This is just collecting test data, not mocking behavior
+- Regular variables: `const testData = { ... }` - Non-mocking object assignments
+- Test setup: Regular const assignments that don't implement mock behavior
+
+The script has been refined to minimize false positives while catching all legitimate violations of our core rule.
+
+## Test Architecture
+
+### Correct Test Flow
+```
+Test → Plugin Handler → utilities → [DEPENDENCY INJECTION] createMockExecutor()
+```
+
+### What Gets Tested
+- Plugin parameter validation
+- Business logic execution
+- Command generation
+- Response formatting
+- Error handling
+- Integration between layers
+
+### What Gets Mocked
+- Command execution via `createMockExecutor()`
+- File system operations via `createMockFileSystemExecutor()`
+- Nothing else - all vitest mocking is banned
+
+## Dependency Injection Strategy
+
+### Handler Requirements
+
+All plugin handlers must support dependency injection:
+
+```typescript
+export function tool_nameLogic(
+ args: Record,
+ commandExecutor: CommandExecutor,
+ fileSystemExecutor?: FileSystemExecutor
+): Promise {
+ // Use injected executors
+ const result = await executeCommand(['xcrun', 'simctl', 'list'], commandExecutor);
+ return createTextResponse(result.output);
+}
+
+export default {
+ name: 'tool_name',
+ description: 'Tool description',
+ schema: { /* zod schema */ },
+ async handler(args: Record): Promise {
+ return tool_nameLogic(args, getDefaultCommandExecutor(), getDefaultFileSystemExecutor());
+ },
+};
+```
+
+**Important**: The dependency injection pattern applies to ALL handlers, including:
+- Tool handlers
+- Resource handlers
+- Any future handler types (prompts, etc.)
+
+Always use default parameter values (e.g., `= getDefaultCommandExecutor()`) to ensure production code works without explicit executor injection, while tests can override with mock executors.
+
+### Test Requirements
+
+All tests must explicitly provide mock executors:
+
+```typescript
+it('should handle successful command execution', async () => {
+ const mockExecutor = createMockExecutor({
+ success: true,
+ output: 'BUILD SUCCEEDED'
+ });
+
+ const result = await tool_nameLogic(
+ { projectPath: '/test.xcodeproj', scheme: 'MyApp' },
+ mockExecutor
+ );
+
+ expect(result.content[0].text).toContain('Build succeeded');
+});
+```
+
+## Three-Dimensional Testing
+
+Every plugin test suite must validate three critical dimensions:
+
+### 1. Input Validation (Schema Testing)
+
+Test parameter validation and schema compliance:
+
+```typescript
+describe('Parameter Validation', () => {
+ it('should accept valid parameters', () => {
+ const schema = z.object(tool.schema);
+ expect(schema.safeParse({
+ projectPath: '/valid/path.xcodeproj',
+ scheme: 'ValidScheme'
+ }).success).toBe(true);
+ });
+
+ it('should reject invalid parameters', () => {
+ const schema = z.object(tool.schema);
+ expect(schema.safeParse({
+ projectPath: 123, // Wrong type
+ scheme: 'ValidScheme'
+ }).success).toBe(false);
+ });
+
+ it('should handle missing required parameters', async () => {
+ const mockExecutor = createMockExecutor({ success: true });
+
+ const result = await tool.handler({ scheme: 'MyApp' }, mockExecutor); // Missing projectPath
+
+ expect(result).toEqual({
+ content: [{
+ type: 'text',
+ text: "Required parameter 'projectPath' is missing. Please provide a value for this parameter."
+ }],
+ isError: true
+ });
+ });
+});
+```
+
+### 2. Command Generation (CLI Testing)
+
+### CRITICAL: No command spying allowed. Test command generation through response validation.
+
+```typescript
+describe('Command Generation', () => {
+ it('should execute correct command with minimal parameters', async () => {
+ const mockExecutor = createMockExecutor({
+ success: true,
+ output: 'BUILD SUCCEEDED'
+ });
+
+ const result = await tool.handler({
+ projectPath: '/test.xcodeproj',
+ scheme: 'MyApp'
+ }, mockExecutor);
+
+ // Verify through successful response - command was executed correctly
+ expect(result.content[0].text).toContain('Build succeeded');
+ });
+
+ it('should handle paths with spaces correctly', async () => {
+ const mockExecutor = createMockExecutor({
+ success: true,
+ output: 'BUILD SUCCEEDED'
+ });
+
+ const result = await tool.handler({
+ projectPath: '/Users/dev/My Project/app.xcodeproj',
+ scheme: 'MyApp'
+ }, mockExecutor);
+
+ // Verify successful execution (proper path handling)
+ expect(result.content[0].text).toContain('Build succeeded');
+ });
+});
+```
+
+### 3. Output Processing (Response Testing)
+
+Test response formatting and error handling:
+
+```typescript
+describe('Response Processing', () => {
+ it('should format successful response', async () => {
+ const mockExecutor = createMockExecutor({
+ success: true,
+ output: 'BUILD SUCCEEDED'
+ });
+
+ const result = await tool.handler({ projectPath: '/test', scheme: 'MyApp' }, mockExecutor);
+
+ expect(result).toEqual({
+ content: [{ type: 'text', text: '✅ Build succeeded for scheme MyApp' }]
+ });
+ });
+
+ it('should handle command failures', async () => {
+ const mockExecutor = createMockExecutor({
+ success: false,
+ output: 'Build failed with errors',
+ error: 'Compilation error'
+ });
+
+ const result = await tool.handler({ projectPath: '/test', scheme: 'MyApp' }, mockExecutor);
+
+ expect(result.isError).toBe(true);
+ expect(result.content[0].text).toContain('Build failed');
+ });
+
+ it('should handle executor errors', async () => {
+ const mockExecutor = createMockExecutor(new Error('spawn xcodebuild ENOENT'));
+
+ const result = await tool.handler({ projectPath: '/test', scheme: 'MyApp' }, mockExecutor);
+
+ expect(result).toEqual({
+ content: [{ type: 'text', text: 'Error during build: spawn xcodebuild ENOENT' }],
+ isError: true
+ });
+ });
+});
+```
+
+## Test Organization
+
+### Directory Structure
+
+```
+src/plugins/[workflow-group]/
+├── __tests__/
+│ ├── index.test.ts # Workflow metadata tests (canonical groups only)
+│ ├── re-exports.test.ts # Re-export validation (project/workspace groups only)
+│ ├── tool1.test.ts # Individual tool tests
+│ ├── tool2.test.ts
+│ └── ...
+├── tool1.ts
+├── tool2.ts
+├── index.ts # Workflow metadata
+└── ...
+```
+
+### Test File Types
+
+#### 1. Tool Tests (`tool_name.test.ts`)
+Test individual plugin tools with full three-dimensional coverage.
+
+#### 2. Workflow Tests (`index.test.ts`)
+Test workflow metadata for canonical groups:
+
+```typescript
+describe('simulator-workspace workflow metadata', () => {
+ it('should have correct workflow name', () => {
+ expect(workflow.name).toBe('iOS Simulator Workspace Development');
+ });
+
+ it('should have correct description', () => {
+ expect(workflow.description).toBe(
+ 'Complete iOS development workflow for .xcworkspace files including build, test, deploy, and debug capabilities',
+ );
+ });
+});
+```
+
+#### 3. Re-export Tests (`re-exports.test.ts`)
+Test re-export integrity for project/workspace groups:
+
+```typescript
+describe('simulator-project re-exports', () => {
+ it('should re-export boot_sim from simulator-shared', () => {
+ expect(bootSim.name).toBe('boot_sim');
+ expect(typeof bootSim.handler).toBe('function');
+ });
+});
+```
+
+## Test Patterns
+
+### Standard Test Template
+
+```typescript
+import { vi, describe, it, expect, beforeEach } from 'vitest';
+import { z } from 'zod';
+
+// CRITICAL: NO VITEST MOCKING ALLOWED
+// Import ONLY what you need - no mock setup
+
+import tool from '../tool_name.ts';
+import { createMockExecutor } from '../../utils/command.js';
+
+describe('tool_name', () => {
+
+ describe('Export Field Validation (Literal)', () => {
+ it('should export correct name', () => {
+ expect(tool.name).toBe('tool_name');
+ });
+
+ it('should export correct description', () => {
+ expect(tool.description).toBe('Expected literal description');
+ });
+
+ it('should export handler function', () => {
+ expect(typeof tool.handler).toBe('function');
+ });
+
+ // Schema validation tests...
+ });
+
+ describe('Command Generation', () => {
+ it('should execute commands successfully', async () => {
+ const mockExecutor = createMockExecutor({
+ success: true,
+ output: 'Expected output'
+ });
+
+ const result = await tool.handler(validParams, mockExecutor);
+
+ expect(result.content[0].text).toContain('Expected result');
+ });
+ });
+
+ describe('Response Processing', () => {
+ // Output handling tests...
+ });
+});
+```
+
+## Performance Requirements
+
+### Test Execution Speed
+
+- **Individual test**: < 100ms
+- **Test file**: < 5 seconds
+- **Full test suite**: < 20 seconds
+- **No real system calls**: Tests must use mocks
+
+### Performance Anti-Patterns
+
+❌ **Real command execution**:
+```
+[INFO] Executing command: xcodebuild -showBuildSettings...
+```
+
+❌ **Long timeouts** (indicates real calls)
+❌ **File system operations** (unless testing file utilities)
+❌ **Network requests** (unless testing network utilities)
+
+## Coverage Standards
+
+### Target Coverage
+- **Overall**: 95%+
+- **Plugin handlers**: 100%
+- **Command generation**: 100%
+- **Error paths**: 100%
+
+### Coverage Validation
+```bash
+# Check coverage for specific plugin group
+npm run test:coverage -- plugins/simulator-workspace/
+
+# Ensure all code paths are tested
+npm run test:coverage -- --reporter=lcov
+```
+
+### Required Test Paths
+
+Every plugin test must cover:
+
+- ✅ **Valid parameter combinations**
+- ✅ **Invalid parameter rejection**
+- ✅ **Missing required parameters**
+- ✅ **Successful command execution**
+- ✅ **Command failure scenarios**
+- ✅ **Executor error handling**
+- ✅ **Output parsing edge cases**
+
+## Common Patterns
+
+### Testing Parameter Defaults
+
+```typescript
+it('should use default configuration when not provided', async () => {
+ const mockExecutor = createMockExecutor({
+ success: true,
+ output: 'BUILD SUCCEEDED'
+ });
+
+ const result = await tool.handler({
+ projectPath: '/test.xcodeproj',
+ scheme: 'MyApp'
+ // configuration intentionally omitted
+ }, mockExecutor);
+
+ // Verify default behavior through successful response
+ expect(result.content[0].text).toContain('Build succeeded');
+});
+```
+
+### Testing Complex Output Parsing
+
+```typescript
+it('should extract app path from build settings', async () => {
+ const mockExecutor = createMockExecutor({
+ success: true,
+ output: `
+ CONFIGURATION_BUILD_DIR = /path/to/build
+ BUILT_PRODUCTS_DIR = /path/to/products
+ FULL_PRODUCT_NAME = MyApp.app
+ OTHER_SETTING = ignored_value
+ `
+ });
+
+ const result = await tool.handler({ projectPath: '/test', scheme: 'MyApp' }, mockExecutor);
+
+ expect(result.content[0].text).toContain('/path/to/products/MyApp.app');
+});
+```
+
+### Testing Error Message Formatting
+
+```typescript
+it('should format validation errors correctly', async () => {
+ const mockExecutor = createMockExecutor({ success: true });
+
+ const result = await tool.handler({}, mockExecutor); // Missing required params
+
+ expect(result).toEqual({
+ content: [{
+ type: 'text',
+ text: "Required parameter 'projectPath' is missing. Please provide a value for this parameter."
+ }],
+ isError: true
+ });
+});
+```
+
+## Manual Testing with Reloaderoo
+
+### 🚨 CRITICAL: THOROUGHNESS OVER EFFICIENCY - NO SHORTCUTS ALLOWED
+
+### ABSOLUTE PRINCIPLE: EVERY TOOL MUST BE TESTED INDIVIDUALLY
+
+### 🚨 MANDATORY TESTING SCOPE - NO EXCEPTIONS
+- **EVERY SINGLE TOOL** - All 83+ tools must be tested individually, one by one
+- **NO REPRESENTATIVE SAMPLING** - Testing similar tools does NOT validate other tools
+- **NO PATTERN RECOGNITION SHORTCUTS** - Similar-looking tools may have different behaviors
+- **NO EFFICIENCY OPTIMIZATIONS** - Thoroughness is more important than speed
+- **NO TIME CONSTRAINTS** - This is a long-running task with no deadline pressure
+
+### ❌ FORBIDDEN EFFICIENCY SHORTCUTS
+- **NEVER** assume testing `build_sim_id_proj` validates `build_sim_name_proj`
+- **NEVER** skip tools because they "look similar" to tested ones
+- **NEVER** use representative sampling instead of complete coverage
+- **NEVER** stop testing due to time concerns or perceived redundancy
+- **NEVER** group tools together for batch testing
+- **NEVER** make assumptions about untested tools based on tested patterns
+
+### ✅ REQUIRED COMPREHENSIVE APPROACH
+1. **Individual Tool Testing**: Each tool gets its own dedicated test execution
+2. **Complete Documentation**: Every tool result must be recorded, regardless of outcome
+3. **Systematic Progress**: Use TodoWrite to track every single tool as tested/untested
+4. **Failure Documentation**: Test tools that cannot work and mark them as failed/blocked
+5. **No Assumptions**: Treat each tool as potentially unique requiring individual validation
+
+### TESTING COMPLETENESS VALIDATION
+- **Start Count**: Record exact number of tools discovered (e.g., 83 tools)
+- **End Count**: Verify same number of tools have been individually tested
+- **Missing Tools = Testing Failure**: If any tools remain untested, the testing is incomplete
+- **TodoWrite Tracking**: Every tool must appear in todo list and be marked completed
+
+### 🚨 CRITICAL: Black Box Testing via Reloaderoo Inspect
+
+### DEFINITION: Black Box Testing
+Black Box Testing means testing ONLY through external interfaces without any knowledge of internal implementation. For XcodeBuildMCP, this means testing exclusively through the Model Context Protocol (MCP) interface using Reloaderoo as the MCP client.
+
+### 🚨 MANDATORY: RELOADEROO INSPECT IS THE ONLY ALLOWED TESTING METHOD
+
+### ABSOLUTE TESTING RULES - NO EXCEPTIONS
+
+1. **✅ ONLY ALLOWED: Reloaderoo Inspect Commands**
+ - `npx reloaderoo@latest inspect call-tool "TOOL_NAME" --params 'JSON' -- node build/index.js`
+ - `npx reloaderoo@latest inspect list-tools -- node build/index.js`
+ - `npx reloaderoo@latest inspect read-resource "URI" -- node build/index.js`
+ - `npx reloaderoo@latest inspect server-info -- node build/index.js`
+ - `npx reloaderoo@latest inspect ping -- node build/index.js`
+
+2. **❌ COMPLETELY FORBIDDEN ACTIONS:**
+ - **NEVER** call `mcp__XcodeBuildMCP__tool_name()` functions directly
+ - **NEVER** use MCP server tools as if they were native functions
+ - **NEVER** access internal server functionality
+ - **NEVER** read source code to understand how tools work
+ - **NEVER** examine implementation files during testing
+ - **NEVER** diagnose internal server issues or registration problems
+ - **NEVER** suggest code fixes or implementation changes
+
+3. **🚨 CRITICAL VIOLATION EXAMPLES:**
+ ```typescript
+ // ❌ FORBIDDEN - Direct MCP tool calls
+ await mcp__XcodeBuildMCP__list_devices();
+ await mcp__XcodeBuildMCP__build_sim_id_proj({ ... });
+
+ // ❌ FORBIDDEN - Using tools as native functions
+ const devices = await list_devices();
+ const result = await doctor();
+
+ // ✅ CORRECT - Only through Reloaderoo inspect
+ npx reloaderoo@latest inspect call-tool "list_devices" --params '{}' -- node build/index.js
+ npx reloaderoo@latest inspect call-tool "doctor" --params '{}' -- node build/index.js
+ ```
+
+### WHY RELOADEROO INSPECT IS MANDATORY
+- **Higher Fidelity**: Provides clear input/output visibility for each tool call
+- **Real-world Simulation**: Tests exactly how MCP clients interact with the server
+- **Interface Validation**: Ensures MCP protocol compliance and proper JSON formatting
+- **Black Box Enforcement**: Prevents accidental access to internal implementation details
+- **Clean State**: Each tool call runs with a fresh MCP server instance, preventing cross-contamination
+
+### IMPORTANT: STATEFUL TOOL LIMITATIONS
+
+#### Reloaderoo Inspect Behavior:
+Reloaderoo starts a fresh MCP server instance for each individual tool call and terminates it immediately after the response. This ensures:
+- ✅ **Clean Testing Environment**: No state contamination between tool calls
+- ✅ **Isolated Testing**: Each tool test is independent and repeatable
+- ✅ **Real-world Accuracy**: Simulates how most MCP clients interact with servers
+
+#### Expected False Negatives:
+Some tools rely on in-memory state within the MCP server and will fail when tested via Reloaderoo inspect. These failures are **expected and acceptable** as false negatives:
+
+- **`swift_package_stop`** - Requires in-memory process tracking from `swift_package_run`
+- **`stop_app_device`** - Requires in-memory process tracking from `launch_app_device`
+- **`stop_app_sim`** - Requires in-memory process tracking from `launch_app_sim`
+- **`stop_device_log_cap`** - Requires in-memory session tracking from `start_device_log_cap`
+- **`stop_sim_log_cap`** - Requires in-memory session tracking from `start_sim_log_cap`
+- **`stop_mac_app`** - Requires in-memory process tracking from `launch_mac_app`
+
+#### Testing Protocol for Stateful Tools:
+1. **Test the tool anyway** - Execute the Reloaderoo inspect command
+2. **Expect failure** - Tool will likely fail due to missing state
+3. **Mark as false negative** - Document the failure as expected due to stateful limitations
+4. **Continue testing** - Do not attempt to fix or investigate the failure
+5. **Report as finding** - Note in testing report that stateful tools failed as expected
+
+### COMPLETE COVERAGE REQUIREMENTS
+- ✅ **Test ALL 83+ tools individually** - No exceptions, every tool gets manual verification
+- ✅ **Follow dependency graphs** - Test tools in correct order based on data dependencies
+- ✅ **Capture key outputs** - Record UUIDs, paths, schemes needed by dependent tools
+- ✅ **Test real workflows** - Complete end-to-end workflows from discovery to execution
+- ✅ **Use programmatic JSON parsing** - Accurate tool/resource counting and discovery
+- ✅ **Document all observations** - Record exactly what you see via testing
+- ✅ **Report discrepancies as findings** - Note unexpected results without investigation
+
+### MANDATORY INDIVIDUAL TOOL TESTING PROTOCOL
+
+#### Step 1: Create Complete Tool Inventory
+```bash
+# Generate complete list of all tools
+npx reloaderoo@latest inspect list-tools -- node build/index.js > /tmp/all_tools.json
+TOTAL_TOOLS=$(jq '.tools | length' /tmp/all_tools.json)
+echo "TOTAL TOOLS TO TEST: $TOTAL_TOOLS"
+
+# Extract all tool names for systematic testing
+jq -r '.tools[].name' /tmp/all_tools.json > /tmp/tool_names.txt
+```
+
+#### Step 2: Create TodoWrite Task List for Every Tool
+```bash
+# Create individual todo items for each of the 83+ tools
+# Example for first few tools:
+# 1. [ ] Test tool: doctor
+# 2. [ ] Test tool: list_devices
+# 3. [ ] Test tool: list_sims
+# ... (continue for ALL 83+ tools)
+```
+
+#### Step 3: Test Each Tool Individually
+For EVERY tool in the list:
+```bash
+# Test each tool individually - NO BATCHING
+npx reloaderoo@latest inspect call-tool "TOOL_NAME" --params 'APPROPRIATE_PARAMS' -- node build/index.js
+
+# Mark tool as completed in TodoWrite IMMEDIATELY after testing
+# Record result (success/failure/blocked) for each tool
+```
+
+#### Step 4: Validate Complete Coverage
+```bash
+# Verify all tools tested
+COMPLETED_TOOLS=$(count completed todo items)
+if [ $COMPLETED_TOOLS -ne $TOTAL_TOOLS ]; then
+ echo "ERROR: Testing incomplete. $COMPLETED_TOOLS/$TOTAL_TOOLS tested"
+ exit 1
+fi
+```
+
+### CRITICAL: NO TOOL LEFT UNTESTED
+- **Every tool name from the JSON list must be individually tested**
+- **Every tool must have a TodoWrite entry that gets marked completed**
+- **Tools that fail due to missing parameters should be tested anyway and marked as blocked**
+- **Tools that require setup (like running processes) should be tested and documented as requiring dependencies**
+- **NO ASSUMPTIONS**: Test tools even if they seem redundant or similar to others
+
+### BLACK BOX TESTING ENFORCEMENT
+- ✅ **Test only through Reloaderoo MCP interface** - Simulates real-world MCP client usage
+- ✅ **Use task lists** - Track progress with TodoWrite tool for every single tool
+- ✅ **Tick off each tool** - Mark completed in task list after manual verification
+- ✅ **Manual oversight** - Human verification of each tool's input and output
+- ❌ **Never examine source code** - No reading implementation files during testing
+- ❌ **Never diagnose internal issues** - No investigation of build processes or tool registration
+- ❌ **Never suggest implementation fixes** - Report issues as findings, don't solve them
+- ❌ **Never use scripts for tool testing** - Each tool must be manually executed and verified
+
+### 🚨 TESTING PSYCHOLOGY & BIAS PREVENTION
+
+### COMMON ANTI-PATTERNS TO AVOID
+
+#### 1. Efficiency Bias (FORBIDDEN)
+- **Symptom**: "These tools look similar, I'll test one to validate the others"
+- **Correction**: Every tool is unique and must be tested individually
+- **Enforcement**: Count tools at start, verify same count tested at end
+
+#### 2. Pattern Recognition Override (FORBIDDEN)
+- **Symptom**: "I see the pattern, the rest will work the same way"
+- **Correction**: Patterns may hide edge cases, bugs, or different implementations
+- **Enforcement**: No assumptions allowed, test every tool regardless of apparent similarity
+
+#### 3. Time Pressure Shortcuts (FORBIDDEN)
+- **Symptom**: "This is taking too long, let me speed up by sampling"
+- **Correction**: This is explicitly a long-running task with no time constraints
+- **Enforcement**: Thoroughness is the ONLY priority, efficiency is irrelevant
+
+#### 4. False Confidence (FORBIDDEN)
+- **Symptom**: "The architecture is solid, so all tools must work"
+- **Correction**: Architecture validation does not guarantee individual tool functionality
+- **Enforcement**: Test tools to discover actual issues, not to confirm assumptions
+
+### MANDATORY MINDSET
+- **Every tool is potentially broken** until individually tested
+- **Every tool may have unique edge cases** not covered by similar tools
+- **Every tool deserves individual attention** regardless of apparent redundancy
+- **Testing completion means EVERY tool tested**, not "enough tools to validate patterns"
+- **The goal is discovering problems**, not confirming everything works
+
+### TESTING COMPLETENESS CHECKLIST
+- [ ] Generated complete tool list (83+ tools)
+- [ ] Created TodoWrite entry for every single tool
+- [ ] Tested every tool individually via Reloaderoo inspect
+- [ ] Marked every tool as completed in TodoWrite
+- [ ] Verified tool count: tested_count == total_count
+- [ ] Documented all results, including failures and blocked tools
+- [ ] Created final report covering ALL tools, not just successful ones
+
+### Tool Dependency Graph Testing Strategy
+
+**CRITICAL: Tools must be tested in dependency order:**
+
+1. **Foundation Tools** (provide data for other tools):
+ - `doctor` - System info
+ - `list_devices` - Device UUIDs
+ - `list_sims` - Simulator UUIDs
+ - `discover_projs` - Project/workspace paths
+
+2. **Discovery Tools** (provide metadata for build tools):
+ - `list_schemes` - Scheme names
+ - `show_build_settings` - Build settings
+
+3. **Build Tools** (create artifacts for install tools):
+ - `build_*` tools - Create app bundles
+ - `get_*_app_path_*` tools - Locate built app bundles
+ - `get_*_bundle_id` tools - Extract bundle IDs
+
+4. **Installation Tools** (depend on built artifacts):
+ - `install_app_*` tools - Install built apps
+ - `launch_app_*` tools - Launch installed apps
+
+5. **Testing Tools** (depend on projects/schemes):
+ - `test_*` tools - Run test suites
+
+6. **UI Automation Tools** (depend on running apps):
+ - `describe_ui`, `screenshot`, `tap`, etc.
+
+### MANDATORY: Record Key Outputs
+
+Must capture and document these values for dependent tools:
+- **Device UUIDs** from `list_devices`
+- **Simulator UUIDs** from `list_sims`
+- **Project/workspace paths** from `discover_projs`
+- **Scheme names** from `list_schems_*`
+- **App bundle paths** from `get_*_app_path_*`
+- **Bundle IDs** from `get_*_bundle_id`
+
+### Prerequisites
+
+1. **Build the server**: `npm run build`
+2. **Install jq**: `brew install jq` (required for JSON parsing)
+3. **System Requirements**: macOS with Xcode installed, connected devices/simulators optional
+
+### Step 1: Programmatic Discovery and Official Testing Lists
+
+#### Generate Official Tool List
+
+```bash
+# Generate complete tool list with accurate count
+npx reloaderoo@latest inspect list-tools -- node build/index.js 2>/dev/null > /tmp/tools.json
+
+# Get accurate tool count
+TOOL_COUNT=$(jq '.tools | length' /tmp/tools.json)
+echo "Official tool count: $TOOL_COUNT"
+
+# Generate tool names list for testing checklist
+jq -r '.tools[] | .name' /tmp/tools.json > /tmp/tool_names.txt
+echo "Tool names saved to /tmp/tool_names.txt"
+```
+
+#### Generate Official Resource List
+
+```bash
+# Generate complete resource list
+npx reloaderoo@latest inspect list-resources -- node build/index.js 2>/dev/null > /tmp/resources.json
+
+# Get accurate resource count
+RESOURCE_COUNT=$(jq '.resources | length' /tmp/resources.json)
+echo "Official resource count: $RESOURCE_COUNT"
+
+# Generate resource URIs for testing checklist
+jq -r '.resources[] | .uri' /tmp/resources.json > /tmp/resource_uris.txt
+echo "Resource URIs saved to /tmp/resource_uris.txt"
+```
+
+#### Create Tool Testing Checklist
+
+```bash
+# Generate markdown checklist from actual tool list
+echo "# Official Tool Testing Checklist" > /tmp/tool_testing_checklist.md
+echo "" >> /tmp/tool_testing_checklist.md
+echo "Total Tools: $TOOL_COUNT" >> /tmp/tool_testing_checklist.md
+echo "" >> /tmp/tool_testing_checklist.md
+
+# Add each tool as unchecked item
+while IFS= read -r tool_name; do
+ echo "- [ ] $tool_name" >> /tmp/tool_testing_checklist.md
+done < /tmp/tool_names.txt
+
+echo "Tool testing checklist created at /tmp/tool_testing_checklist.md"
+```
+
+#### Create Resource Testing Checklist
+
+```bash
+# Generate markdown checklist from actual resource list
+echo "# Official Resource Testing Checklist" > /tmp/resource_testing_checklist.md
+echo "" >> /tmp/resource_testing_checklist.md
+echo "Total Resources: $RESOURCE_COUNT" >> /tmp/resource_testing_checklist.md
+echo "" >> /tmp/resource_testing_checklist.md
+
+# Add each resource as unchecked item
+while IFS= read -r resource_uri; do
+ echo "- [ ] $resource_uri" >> /tmp/resource_testing_checklist.md
+done < /tmp/resource_uris.txt
+
+echo "Resource testing checklist created at /tmp/resource_testing_checklist.md"
+```
+
+### Step 2: Tool Schema Discovery for Parameter Testing
+
+#### Extract Tool Schema Information
+
+```bash
+# Get schema for specific tool to understand required parameters
+TOOL_NAME="list_devices"
+jq --arg tool "$TOOL_NAME" '.tools[] | select(.name == $tool) | .inputSchema' /tmp/tools.json
+
+# Get tool description for usage guidance
+jq --arg tool "$TOOL_NAME" '.tools[] | select(.name == $tool) | .description' /tmp/tools.json
+
+# Generate parameter template for tool testing
+jq --arg tool "$TOOL_NAME" '.tools[] | select(.name == $tool) | .inputSchema.properties // {}' /tmp/tools.json
+```
+
+#### Batch Schema Extraction
+
+```bash
+# Create schema reference file for all tools
+echo "# Tool Schema Reference" > /tmp/tool_schemas.md
+echo "" >> /tmp/tool_schemas.md
+
+while IFS= read -r tool_name; do
+ echo "## $tool_name" >> /tmp/tool_schemas.md
+ echo "" >> /tmp/tool_schemas.md
+
+ # Get description
+ description=$(jq -r --arg tool "$tool_name" '.tools[] | select(.name == $tool) | .description' /tmp/tools.json)
+ echo "**Description:** $description" >> /tmp/tool_schemas.md
+ echo "" >> /tmp/tool_schemas.md
+
+ # Get required parameters
+ required=$(jq -r --arg tool "$tool_name" '.tools[] | select(.name == $tool) | .inputSchema.required // [] | join(", ")' /tmp/tools.json)
+ if [ "$required" != "" ]; then
+ echo "**Required Parameters:** $required" >> /tmp/tool_schemas.md
+ else
+ echo "**Required Parameters:** None" >> /tmp/tool_schemas.md
+ fi
+ echo "" >> /tmp/tool_schemas.md
+
+ # Get all parameters
+ echo "**All Parameters:**" >> /tmp/tool_schemas.md
+ jq --arg tool "$tool_name" '.tools[] | select(.name == $tool) | .inputSchema.properties // {} | keys[]' /tmp/tools.json | while read param; do
+ echo "- $param" >> /tmp/tool_schemas.md
+ done
+ echo "" >> /tmp/tool_schemas.md
+
+done < /tmp/tool_names.txt
+
+echo "Tool schema reference created at /tmp/tool_schemas.md"
+```
+
+### Step 3: Manual Tool-by-Tool Testing
+
+#### 🚨 CRITICAL: STEP-BY-STEP BLACK BOX TESTING PROCESS
+
+### ABSOLUTE RULE: ALL TESTING MUST BE DONE MANUALLY, ONE TOOL AT A TIME USING RELOADEROO INSPECT
+
+### SYSTEMATIC TESTING PROCESS
+
+1. **Create TodoWrite Task List**
+ - Add all 83 tools to task list before starting
+ - Mark each tool as "pending" initially
+ - Update status to "in_progress" when testing begins
+ - Mark "completed" only after manual verification
+
+2. **Test Each Tool Individually**
+ - Execute ONLY via `npx reloaderoo@latest inspect call-tool "TOOL_NAME" --params 'JSON' -- node build/index.js`
+ - Wait for complete response before proceeding to next tool
+ - Read and verify each tool's output manually
+ - Record key outputs (UUIDs, paths, schemes) for dependent tools
+
+3. **Manual Verification Requirements**
+ - ✅ **Read each response** - Manually verify tool output makes sense
+ - ✅ **Check for errors** - Identify any tool failures or unexpected responses
+ - ✅ **Record UUIDs/paths** - Save outputs needed for dependent tools
+ - ✅ **Update task list** - Mark each tool complete after verification
+ - ✅ **Document issues** - Record any problems found during testing
+
+4. **FORBIDDEN SHORTCUTS:**
+ - ❌ **NO SCRIPTS** - Scripts hide what's happening and prevent proper verification
+ - ❌ **NO AUTOMATION** - Every tool call must be manually executed and verified
+ - ❌ **NO BATCHING** - Cannot test multiple tools simultaneously
+ - ❌ **NO MCP DIRECT CALLS** - Only Reloaderoo inspect commands allowed
+
+#### Phase 1: Infrastructure Validation
+
+#### Manual Commands (execute individually):
+
+```bash
+# Test server connectivity
+npx reloaderoo@latest inspect ping -- node build/index.js
+
+# Get server information
+npx reloaderoo@latest inspect server-info -- node build/index.js
+
+# Verify tool count manually
+npx reloaderoo@latest inspect list-tools -- node build/index.js 2>/dev/null | jq '.tools | length'
+
+# Verify resource count manually
+npx reloaderoo@latest inspect list-resources -- node build/index.js 2>/dev/null | jq '.resources | length'
+```
+
+#### Phase 2: Resource Testing
+
+```bash
+# Test each resource systematically
+while IFS= read -r resource_uri; do
+ echo "Testing resource: $resource_uri"
+ npx reloaderoo@latest inspect read-resource "$resource_uri" -- node build/index.js 2>/dev/null
+ echo "---"
+done < /tmp/resource_uris.txt
+```
+
+#### Phase 3: Foundation Tools (Data Collection)
+
+### CRITICAL: Capture ALL key outputs for dependent tools
+
+```bash
+echo "=== FOUNDATION TOOL TESTING & DATA COLLECTION ==="
+
+# 1. Test doctor (no dependencies)
+echo "Testing doctor..."
+npx reloaderoo@latest inspect call-tool "doctor" --params '{}' -- node build/index.js 2>/dev/null
+
+# 2. Collect device data
+echo "Collecting device UUIDs..."
+npx reloaderoo@latest inspect call-tool "list_devices" --params '{}' -- node build/index.js 2>/dev/null > /tmp/devices_output.json
+DEVICE_UUIDS=$(jq -r '.content[0].text' /tmp/devices_output.json | grep -E "UDID: [A-F0-9-]+" | sed 's/.*UDID: //' | head -2)
+echo "Device UUIDs captured: $DEVICE_UUIDS"
+
+# 3. Collect simulator data
+echo "Collecting simulator UUIDs..."
+npx reloaderoo@latest inspect call-tool "list_sims" --params '{}' -- node build/index.js 2>/dev/null > /tmp/sims_output.json
+SIMULATOR_UUIDS=$(jq -r '.content[0].text' /tmp/sims_output.json | grep -E "\([A-F0-9-]+\)" | sed 's/.*(\([A-F0-9-]*\)).*/\1/' | head -3)
+echo "Simulator UUIDs captured: $SIMULATOR_UUIDS"
+
+# 4. Collect project data
+echo "Collecting project paths..."
+npx reloaderoo@latest inspect call-tool "discover_projs" --params '{"workspaceRoot": "/Volumes/Developer/XcodeBuildMCP"}' -- node build/index.js 2>/dev/null > /tmp/projects_output.json
+PROJECT_PATHS=$(jq -r '.content[1].text' /tmp/projects_output.json | grep -E "\.xcodeproj$" | sed 's/.*- //' | head -3)
+WORKSPACE_PATHS=$(jq -r '.content[2].text' /tmp/projects_output.json | grep -E "\.xcworkspace$" | sed 's/.*- //' | head -2)
+echo "Project paths captured: $PROJECT_PATHS"
+echo "Workspace paths captured: $WORKSPACE_PATHS"
+
+# Save key data for dependent tools
+echo "$DEVICE_UUIDS" > /tmp/device_uuids.txt
+echo "$SIMULATOR_UUIDS" > /tmp/simulator_uuids.txt
+echo "$PROJECT_PATHS" > /tmp/project_paths.txt
+echo "$WORKSPACE_PATHS" > /tmp/workspace_paths.txt
+```
+
+#### Phase 4: Discovery Tools (Metadata Collection)
+
+```bash
+echo "=== DISCOVERY TOOL TESTING & METADATA COLLECTION ==="
+
+# Collect schemes for each project
+while IFS= read -r project_path; do
+ if [ -n "$project_path" ]; then
+ echo "Getting schemes for: $project_path"
+ npx reloaderoo@latest inspect call-tool "list_schems_proj" --params "{\"projectPath\": \"$project_path\"}" -- node build/index.js 2>/dev/null > /tmp/schemes_$$.json
+ SCHEMES=$(jq -r '.content[1].text' /tmp/schemes_$$.json 2>/dev/null || echo "NoScheme")
+ echo "$project_path|$SCHEMES" >> /tmp/project_schemes.txt
+ echo "Schemes captured for $project_path: $SCHEMES"
+ fi
+done < /tmp/project_paths.txt
+
+# Collect schemes for each workspace
+while IFS= read -r workspace_path; do
+ if [ -n "$workspace_path" ]; then
+ echo "Getting schemes for: $workspace_path"
+ npx reloaderoo@latest inspect call-tool "list_schemes" --params "{\"workspacePath\": \"$workspace_path\"}" -- node build/index.js 2>/dev/null > /tmp/ws_schemes_$$.json
+ SCHEMES=$(jq -r '.content[1].text' /tmp/ws_schemes_$$.json 2>/dev/null || echo "NoScheme")
+ echo "$workspace_path|$SCHEMES" >> /tmp/workspace_schemes.txt
+ echo "Schemes captured for $workspace_path: $SCHEMES"
+ fi
+done < /tmp/workspace_paths.txt
+```
+
+#### Phase 5: Manual Individual Tool Testing (All 83 Tools)
+
+### CRITICAL: Test every single tool manually, one at a time
+
+#### Manual Testing Process:
+
+1. **Create task list** with TodoWrite tool for all 83 tools
+2. **Test each tool individually** with proper parameters
+3. **Mark each tool complete** in task list after manual verification
+4. **Record results** and observations for each tool
+5. **NO SCRIPTS** - Each command executed manually
+
+### STEP-BY-STEP MANUAL TESTING COMMANDS
+
+```bash
+# STEP 1: Test foundation tools (no parameters required)
+# Execute each command individually, wait for response, verify manually
+npx reloaderoo@latest inspect call-tool "doctor" --params '{}' -- node build/index.js
+# [Wait for response, read output, mark tool complete in task list]
+
+npx reloaderoo@latest inspect call-tool "list_devices" --params '{}' -- node build/index.js
+# [Record device UUIDs from response for dependent tools]
+
+npx reloaderoo@latest inspect call-tool "list_sims" --params '{}' -- node build/index.js
+# [Record simulator UUIDs from response for dependent tools]
+
+# STEP 2: Test project discovery (use discovered project paths)
+npx reloaderoo@latest inspect call-tool "list_schems_proj" --params '{"projectPath": "/actual/path/from/discover_projs.xcodeproj"}' -- node build/index.js
+# [Record scheme names from response for build tools]
+
+# STEP 3: Test workspace tools (use discovered workspace paths)
+npx reloaderoo@latest inspect call-tool "list_schemes" --params '{"workspacePath": "/actual/path/from/discover_projs.xcworkspace"}' -- node build/index.js
+# [Record scheme names from response for build tools]
+
+# STEP 4: Test simulator tools (use captured simulator UUIDs from step 1)
+npx reloaderoo@latest inspect call-tool "boot_sim" --params '{"simulatorUuid": "ACTUAL_UUID_FROM_LIST_SIMS"}' -- node build/index.js
+# [Verify simulator boots successfully]
+
+# STEP 5: Test build tools (requires project + scheme + simulator from previous steps)
+npx reloaderoo@latest inspect call-tool "build_sim_id_proj" --params '{"projectPath": "/actual/project.xcodeproj", "scheme": "ActualSchemeName", "simulatorId": "ACTUAL_SIMULATOR_UUID"}' -- node build/index.js
+# [Verify build succeeds and record app bundle path]
+```
+
+### CRITICAL: EACH COMMAND MUST BE
+1. **Executed individually** - One command at a time, manually typed or pasted
+2. **Verified manually** - Read the complete response before continuing
+3. **Tracked in task list** - Mark tool complete only after verification
+4. **Use real data** - Replace placeholder values with actual captured data
+5. **Wait for completion** - Allow each command to finish before proceeding
+
+### TESTING VIOLATIONS AND ENFORCEMENT
+
+### 🚨 CRITICAL VIOLATIONS THAT WILL TERMINATE TESTING
+
+1. **Direct MCP Tool Usage Violation:**
+ ```typescript
+ // ❌ IMMEDIATE TERMINATION - Using MCP tools directly
+ await mcp__XcodeBuildMCP__list_devices();
+ const result = await list_sims();
+ ```
+
+2. **Script-Based Testing Violation:**
+ ```bash
+ # ❌ IMMEDIATE TERMINATION - Using scripts to test tools
+ for tool in $(cat tool_list.txt); do
+ npx reloaderoo inspect call-tool "$tool" --params '{}' -- node build/index.js
+ done
+ ```
+
+3. **Batching/Automation Violation:**
+ ```bash
+ # ❌ IMMEDIATE TERMINATION - Testing multiple tools simultaneously
+ npx reloaderoo inspect call-tool "list_devices" & npx reloaderoo inspect call-tool "list_sims" &
+ ```
+
+4. **Source Code Examination Violation:**
+ ```typescript
+ // ❌ IMMEDIATE TERMINATION - Reading implementation during testing
+ const toolImplementation = await Read('/src/mcp/tools/device-shared/list_devices.ts');
+ ```
+
+### ENFORCEMENT PROCEDURE
+1. **First Violation**: Immediate correction and restart of testing process
+2. **Documentation Update**: Add explicit prohibition to prevent future violations
+3. **Method Validation**: Ensure all future testing uses only Reloaderoo inspect commands
+4. **Progress Reset**: Restart testing from foundation tools if direct MCP usage detected
+
+### VALID TESTING SEQUENCE EXAMPLE
+```bash
+# ✅ CORRECT - Step-by-step manual execution via Reloaderoo
+# Tool 1: Test doctor
+npx reloaderoo@latest inspect call-tool "doctor" --params '{}' -- node build/index.js
+# [Read response, verify, mark complete in TodoWrite]
+
+# Tool 2: Test list_devices
+npx reloaderoo@latest inspect call-tool "list_devices" --params '{}' -- node build/index.js
+# [Read response, capture UUIDs, mark complete in TodoWrite]
+
+# Tool 3: Test list_sims
+npx reloaderoo@latest inspect call-tool "list_sims" --params '{}' -- node build/index.js
+# [Read response, capture UUIDs, mark complete in TodoWrite]
+
+# Tool X: Test stateful tool (expected to fail)
+npx reloaderoo@latest inspect call-tool "swift_package_stop" --params '{"pid": 12345}' -- node build/index.js
+# [Tool fails as expected - no in-memory state available]
+# [Mark as "false negative - stateful tool limitation" in TodoWrite]
+# [Continue to next tool without investigation]
+
+# Continue individually for all 83 tools...
+```
+
+### HANDLING STATEFUL TOOL FAILURES
+```bash
+# ✅ CORRECT Response to Expected Stateful Tool Failure
+# Tool fails with "No process found" or similar state-related error
+# Response: Mark tool as "tested - false negative (stateful)" in task list
+# Do NOT attempt to diagnose, fix, or investigate the failure
+# Continue immediately to next tool in sequence
+```
+
+### Step 4: Error Testing
+
+```bash
+# Test error handling systematically
+echo "=== Error Testing ==="
+
+# Test with invalid JSON parameters
+echo "Testing invalid parameter types..."
+npx reloaderoo@latest inspect call-tool list_schems_proj --params '{"projectPath": 123}' -- node build/index.js 2>/dev/null
+
+# Test with non-existent paths
+echo "Testing non-existent paths..."
+npx reloaderoo@latest inspect call-tool list_schems_proj --params '{"projectPath": "/nonexistent/path.xcodeproj"}' -- node build/index.js 2>/dev/null
+
+# Test with invalid UUIDs
+echo "Testing invalid UUIDs..."
+npx reloaderoo@latest inspect call-tool boot_sim --params '{"simulatorUuid": "invalid-uuid"}' -- node build/index.js 2>/dev/null
+```
+
+### Step 5: Generate Testing Report
+
+```bash
+# Create comprehensive testing session report
+cat > TESTING_SESSION_$(date +%Y-%m-%d).md << EOF
+# Manual Testing Session - $(date +%Y-%m-%d)
+
+## Environment
+- macOS Version: $(sw_vers -productVersion)
+- XcodeBuildMCP Version: $(jq -r '.version' package.json 2>/dev/null || echo "unknown")
+- Testing Method: Reloaderoo @latest via npx
+
+## Official Counts (Programmatically Verified)
+- Total Tools: $TOOL_COUNT
+- Total Resources: $RESOURCE_COUNT
+
+## Test Results
+[Document test results here]
+
+## Issues Found
+[Document any discrepancies or failures]
+
+## Performance Notes
+[Document response times and performance observations]
+EOF
+
+echo "Testing session template created: TESTING_SESSION_$(date +%Y-%m-%d).md"
+```
+
+### Key Commands Reference
+
+```bash
+# Essential testing commands
+npx reloaderoo@latest inspect ping -- node build/index.js
+npx reloaderoo@latest inspect server-info -- node build/index.js
+npx reloaderoo@latest inspect list-tools -- node build/index.js | jq '.tools | length'
+npx reloaderoo@latest inspect list-resources -- node build/index.js | jq '.resources | length'
+npx reloaderoo@latest inspect call-tool TOOL_NAME --params '{}' -- node build/index.js
+npx reloaderoo@latest inspect read-resource "xcodebuildmcp://RESOURCE" -- node build/index.js
+
+# Schema extraction
+jq --arg tool "TOOL_NAME" '.tools[] | select(.name == $tool) | .inputSchema' /tmp/tools.json
+jq --arg tool "TOOL_NAME" '.tools[] | select(.name == $tool) | .description' /tmp/tools.json
+```
+
+This systematic approach ensures comprehensive, accurate testing using programmatic discovery and validation of all XcodeBuildMCP functionality.
+
+## Troubleshooting
+
+### Common Issues
+
+#### 1. "Real System Executor Detected" Error
+**Symptoms**: Test fails with error about real system executor being used
+**Cause**: Handler not receiving mock executor parameter
+**Fix**: Ensure test passes createMockExecutor() to handler:
+
+```typescript
+// ❌ WRONG
+const result = await tool.handler(params);
+
+// ✅ CORRECT
+const mockExecutor = createMockExecutor({ success: true });
+const result = await tool.handler(params, mockExecutor);
+```
+
+#### 2. "Real Filesystem Executor Detected" Error
+**Symptoms**: Test fails when trying to access file system
+**Cause**: Handler not receiving mock file system executor
+**Fix**: Pass createMockFileSystemExecutor():
+
+```typescript
+const mockCmd = createMockExecutor({ success: true });
+const mockFS = createMockFileSystemExecutor({ readFile: async () => 'content' });
+const result = await tool.handler(params, mockCmd, mockFS);
+```
+
+#### 3. Handler Signature Errors
+**Symptoms**: TypeScript errors about handler parameters
+**Cause**: Handler doesn't support dependency injection
+**Fix**: Update handler signature:
+
+```typescript
+async handler(args: Record): Promise {
+ return tool_nameLogic(args, getDefaultCommandExecutor(), getDefaultFileSystemExecutor());
+}
+```
+
+### Debug Commands
+
+```bash
+# Run specific test file
+npm test -- src/plugins/simulator-workspace/__tests__/tool_name.test.ts
+
+# Run with verbose output
+npm test -- --reporter=verbose
+
+# Check for banned patterns
+node scripts/check-code-patterns.js
+
+# Verify dependency injection compliance
+node scripts/audit-dependency-container.js
+
+# Coverage for specific directory
+npm run test:coverage -- src/plugins/simulator-workspace/
+```
+
+### Validation Scripts
+
+```bash
+# Check for vitest mocking violations
+node scripts/check-code-patterns.js --pattern=vitest
+
+# Check dependency injection compliance
+node scripts/audit-dependency-container.js
+
+# Both scripts must pass before committing
+```
+
+## Best Practices Summary
+
+1. **Dependency injection**: Always use createMockExecutor() and createMockFileSystemExecutor()
+2. **No vitest mocking**: All vi.mock, vi.fn, etc. patterns are banned
+3. **Three dimensions**: Test input validation, command execution, and output processing
+4. **Literal expectations**: Use exact strings in assertions to catch regressions
+5. **Performance**: Ensure fast execution through proper mocking
+6. **Coverage**: Aim for 95%+ with focus on error paths
+7. **Consistency**: Follow standard patterns across all plugin tests
+8. **Test safety**: Default executors prevent accidental real system calls
+
+This testing strategy ensures robust, maintainable tests that provide confidence in plugin functionality while remaining resilient to implementation changes and completely eliminating vitest mocking dependencies.
diff --git a/docs/TEST_RUNNER_ENV_IMPLEMENTATION_PLAN.md b/docs/TEST_RUNNER_ENV_IMPLEMENTATION_PLAN.md
new file mode 100644
index 00000000..e294f9e8
--- /dev/null
+++ b/docs/TEST_RUNNER_ENV_IMPLEMENTATION_PLAN.md
@@ -0,0 +1,423 @@
+# TEST_RUNNER_ Environment Variables Implementation Plan
+
+## Problem Statement
+
+**GitHub Issue**: [#101 - Support TEST_RUNNER_ prefixed env vars](https://github.com/cameroncooke/XcodeBuildMCP/issues/101)
+
+**Core Need**: Enable conditional test behavior by passing TEST_RUNNER_ prefixed environment variables from MCP client configurations to xcodebuild test processes. This addresses the specific use case of disabling `runsForEachTargetApplicationUIConfiguration` for faster development testing.
+
+## Background Context
+
+### xcodebuild Environment Variable Support
+
+From the xcodebuild man page:
+```
+TEST_RUNNER_ Set an environment variable whose name is prefixed
+ with TEST_RUNNER_ to have that variable passed, with
+ its prefix stripped, to all test runner processes
+ launched during a test action. For example,
+ TEST_RUNNER_Foo=Bar xcodebuild test ... sets the
+ environment variable Foo=Bar in the test runner's
+ environment.
+```
+
+### User Requirements
+
+Users want to configure their MCP server with TEST_RUNNER_ prefixed environment variables:
+
+```json
+{
+ "mcpServers": {
+ "XcodeBuildMCP": {
+ "type": "stdio",
+ "command": "npx",
+ "args": ["-y", "xcodebuildmcp@latest"],
+ "env": {
+ "TEST_RUNNER_USE_DEV_MODE": "YES"
+ }
+ }
+ }
+}
+```
+
+And have tests that can conditionally execute based on these variables:
+
+```swift
+func testFoo() throws {
+ let useDevMode = ProcessInfo.processInfo.environment["USE_DEV_MODE"] == "YES"
+ guard useDevMode else {
+ XCTFail("Test requires USE_DEV_MODE to be true")
+ return
+ }
+ // Test logic here...
+}
+```
+
+## Current Architecture Analysis
+
+### XcodeBuildMCP Execution Flow
+1. All Xcode commands flow through `executeXcodeBuildCommand()` function
+2. Generic `CommandExecutor` interface handles all command execution
+3. Test tools exist for device/simulator/macOS platforms
+4. Zod schemas provide parameter validation and type safety
+
+### Key Files in Current Architecture
+- `src/utils/CommandExecutor.ts` - Command execution interface
+- `src/utils/build-utils.ts` - Contains `executeXcodeBuildCommand`
+- `src/mcp/tools/device/test_device.ts` - Device testing tool
+- `src/mcp/tools/simulator/test_sim.ts` - Simulator testing tool
+- `src/mcp/tools/macos/test_macos.ts` - macOS testing tool
+- `src/utils/test/index.ts` - Shared test logic for simulator
+
+## Solution Analysis
+
+### Design Options Considered
+
+1. **Automatic Detection** (❌ Rejected)
+ - Scan `process.env` for TEST_RUNNER_ variables and always pass them
+ - **Issue**: Security risk of environment variable leakage
+ - **Issue**: Unpredictable behavior based on server environment
+
+2. **Explicit Parameter** (✅ Chosen)
+ - Add `testRunnerEnv` parameter to test tools
+ - Users explicitly specify which variables to pass
+ - **Benefits**: Secure, predictable, well-validated
+
+3. **Hybrid Approach** (🤔 Future Enhancement)
+ - Both automatic + explicit with explicit overriding
+ - **Issue**: Adds complexity, deferred for future consideration
+
+### Expert Analysis Summary
+
+**RepoPrompt Analysis**: Comprehensive architectural plan emphasizing security, type safety, and integration with existing patterns.
+
+**Gemini Analysis**: Confirmed explicit approach as optimal, highlighting:
+- Security benefits of explicit allow-list approach
+- Architectural soundness of extending CommandExecutor
+- Recommendation for automatic prefix handling for better UX
+
+## Recommended Solution: Explicit Parameter with Automatic Prefix Handling
+
+### Key Design Decisions
+
+1. **Security-First**: Only explicitly provided variables are passed (no automatic process.env scanning)
+2. **User Experience**: Automatic prefix handling - users provide unprefixed keys
+3. **Architecture**: Extend execution layer generically for future extensibility
+4. **Validation**: Zod schema enforcement with proper type safety
+
+### User Experience Design
+
+**Input** (what users specify):
+```json
+{
+ "testRunnerEnv": {
+ "USE_DEV_MODE": "YES",
+ "runsForEachTargetApplicationUIConfiguration": "NO"
+ }
+}
+```
+
+**Output** (what gets passed to xcodebuild):
+```bash
+TEST_RUNNER_USE_DEV_MODE=YES \
+TEST_RUNNER_runsForEachTargetApplicationUIConfiguration=NO \
+xcodebuild test ...
+```
+
+## Implementation Plan
+
+### Phase 0: Test-Driven Development Setup
+
+**Objective**: Create reproduction test to validate issue and later prove fix works
+
+#### Tasks:
+- [ ] Create test in `example_projects/iOS/MCPTest` that checks for environment variable
+- [ ] Run current test tools to demonstrate limitation (test should fail)
+- [ ] Document baseline behavior
+
+**Test Code Example**:
+```swift
+func testEnvironmentVariablePassthrough() throws {
+ let useDevMode = ProcessInfo.processInfo.environment["USE_DEV_MODE"] == "YES"
+ guard useDevMode else {
+ XCTFail("Test requires USE_DEV_MODE=YES via TEST_RUNNER_USE_DEV_MODE")
+ return
+ }
+ XCTAssertTrue(true, "Environment variable successfully passed through")
+}
+```
+
+### Phase 1: Core Infrastructure Updates
+
+**Objective**: Extend CommandExecutor and build utilities to support environment variables
+
+#### 1.1 Update CommandExecutor Interface
+
+**File**: `src/utils/CommandExecutor.ts`
+
+**Changes**:
+- Add `CommandExecOptions` type for execution options
+- Update `CommandExecutor` type signature to accept optional execution options
+
+```typescript
+export type CommandExecOptions = {
+ cwd?: string;
+ env?: Record;
+};
+
+export type CommandExecutor = (
+ args: string[],
+ description?: string,
+ quiet?: boolean,
+ opts?: CommandExecOptions
+) => Promise;
+```
+
+#### 1.2 Update Execution Facade
+
+**File**: `src/utils/execution/index.ts`
+
+**Changes**:
+- Re-export `CommandExecOptions` type
+
+```typescript
+export type { CommandExecutor, CommandResponse, CommandExecOptions } from '../CommandExecutor.js';
+```
+
+#### 1.3 Update Default Command Executor
+
+**File**: `src/utils/command.ts`
+
+**Changes**:
+- Modify `getDefaultCommandExecutor` to merge `opts.env` with `process.env` when spawning
+
+```typescript
+// In the returned function:
+const env = { ...process.env, ...(opts?.env ?? {}) };
+// Pass env and opts?.cwd to spawn/exec call
+```
+
+#### 1.4 Create Environment Variable Utility
+
+**File**: `src/utils/environment.ts`
+
+**Changes**:
+- Add `normalizeTestRunnerEnv` function
+
+```typescript
+export function normalizeTestRunnerEnv(
+ userVars?: Record
+): Record {
+ const result: Record = {};
+ if (userVars) {
+ for (const [key, value] of Object.entries(userVars)) {
+ if (value !== undefined) {
+ result[`TEST_RUNNER_${key}`] = value;
+ }
+ }
+ }
+ return result;
+}
+```
+
+#### 1.5 Update executeXcodeBuildCommand
+
+**File**: `src/utils/build-utils.ts`
+
+**Changes**:
+- Add optional `execOpts?: CommandExecOptions` parameter (6th parameter)
+- Pass execution options through to `CommandExecutor` calls
+
+```typescript
+export async function executeXcodeBuildCommand(
+ build: { /* existing fields */ },
+ runtime: { /* existing fields */ },
+ preferXcodebuild = false,
+ action: 'build' | 'test' | 'archive' | 'analyze' | string,
+ executor: CommandExecutor = getDefaultCommandExecutor(),
+ execOpts?: CommandExecOptions, // NEW
+): Promise
+```
+
+### Phase 2: Test Tool Integration
+
+**Objective**: Add `testRunnerEnv` parameter to all test tools and wire through execution
+
+#### 2.1 Update Device Test Tool
+
+**File**: `src/mcp/tools/device/test_device.ts`
+
+**Changes**:
+- Add `testRunnerEnv` to Zod schema with validation
+- Import and use `normalizeTestRunnerEnv`
+- Pass execution options to `executeXcodeBuildCommand`
+
+**Schema Addition**:
+```typescript
+testRunnerEnv: z
+ .record(z.string(), z.string().optional())
+ .optional()
+ .describe('Test runner environment variables (TEST_RUNNER_ prefix added automatically)')
+```
+
+**Usage**:
+```typescript
+const execEnv = normalizeTestRunnerEnv(params.testRunnerEnv);
+const testResult = await executeXcodeBuildCommand(
+ { /* build params */ },
+ { /* runtime params */ },
+ params.preferXcodebuild ?? false,
+ 'test',
+ executor,
+ { env: execEnv } // NEW
+);
+```
+
+#### 2.2 Update macOS Test Tool
+
+**File**: `src/mcp/tools/macos/test_macos.ts`
+
+**Changes**: Same pattern as device test tool
+- Schema addition for `testRunnerEnv`
+- Import `normalizeTestRunnerEnv`
+- Pass execution options to `executeXcodeBuildCommand`
+
+#### 2.3 Update Simulator Test Tool and Logic
+
+**File**: `src/mcp/tools/simulator/test_sim.ts`
+
+**Changes**:
+- Add `testRunnerEnv` to schema
+- Pass through to `handleTestLogic`
+
+**File**: `src/utils/test/index.ts`
+
+**Changes**:
+- Update `handleTestLogic` signature to accept `testRunnerEnv?: Record`
+- Import and use `normalizeTestRunnerEnv`
+- Pass execution options to `executeXcodeBuildCommand`
+
+### Phase 3: Testing and Validation
+
+**Objective**: Comprehensive testing coverage for new functionality
+
+#### 3.1 Unit Tests
+
+**File**: `src/utils/__tests__/environment.test.ts`
+
+**Tests**:
+- Test `normalizeTestRunnerEnv` with various inputs
+- Verify prefix addition
+- Verify undefined filtering
+- Verify empty input handling
+
+#### 3.2 Integration Tests
+
+**Files**: Update existing test files for test tools
+
+**Tests**:
+- Verify `testRunnerEnv` parameter is properly validated
+- Verify environment variables are passed through `CommandExecutor`
+- Mock executor to verify correct env object construction
+
+#### 3.3 Tool Export Validation
+
+**Files**: Test files in each tool directory
+
+**Tests**:
+- Verify schema exports include new `testRunnerEnv` field
+- Verify parameter typing is correct
+
+### Phase 4: End-to-End Validation
+
+**Objective**: Prove the fix works with real xcodebuild scenarios
+
+#### 4.1 Reproduction Test Validation
+
+**Tasks**:
+- Run reproduction test from Phase 0 with new `testRunnerEnv` parameter
+- Verify test passes (proving env var was successfully passed)
+- Document the before/after behavior
+
+#### 4.2 Real-World Scenario Testing
+
+**Tasks**:
+- Test with actual iOS project using `runsForEachTargetApplicationUIConfiguration`
+- Verify performance difference when variable is set
+- Test with multiple environment variables
+- Test edge cases (empty values, special characters)
+
+## Security Considerations
+
+### Security Benefits
+- **No Environment Leakage**: Only explicit user-provided variables are passed
+- **Command Injection Prevention**: Environment variables passed as separate object, not interpolated into command string
+- **Input Validation**: Zod schemas prevent malformed inputs
+- **Prefix Enforcement**: Only TEST_RUNNER_ prefixed variables can be set
+
+### Security Best Practices
+- Never log environment variable values (keys only for debugging)
+- Filter out undefined values to prevent accidental exposure
+- Validate all user inputs through Zod schemas
+- Document supported TEST_RUNNER_ variables from Apple's documentation
+
+## Architectural Benefits
+
+### Clean Integration
+- Extends existing `CommandExecutor` pattern generically
+- Maintains backward compatibility (all existing calls remain valid)
+- Follows established Zod validation patterns
+- Consistent API across all test tools
+
+### Future Extensibility
+- `CommandExecOptions` can support additional execution options (timeout, cwd, etc.)
+- Pattern can be extended to other tools that need environment variables
+- Generic approach allows for non-TEST_RUNNER_ use cases in the future
+
+## File Modification Summary
+
+### New Files
+- `src/utils/__tests__/environment.test.ts` - Unit tests for environment utilities
+
+### Modified Files
+- `src/utils/CommandExecutor.ts` - Add execution options types
+- `src/utils/execution/index.ts` - Re-export new types
+- `src/utils/command.ts` - Update default executor to handle env
+- `src/utils/environment.ts` - Add `normalizeTestRunnerEnv` utility
+- `src/utils/build-utils.ts` - Update `executeXcodeBuildCommand` signature
+- `src/mcp/tools/device/test_device.ts` - Add schema and integration
+- `src/mcp/tools/macos/test_macos.ts` - Add schema and integration
+- `src/mcp/tools/simulator/test_sim.ts` - Add schema and pass-through
+- `src/utils/test/index.ts` - Update `handleTestLogic` for simulator path
+- Test files for each modified tool - Add validation tests
+
+## Success Criteria
+
+1. **Functionality**: Users can pass `testRunnerEnv` parameter to test tools and have variables appear in test runner environment
+2. **Security**: No unintended environment variable leakage from server process
+3. **Usability**: Users specify unprefixed variable names for better UX
+4. **Compatibility**: All existing test tool calls continue to work unchanged
+5. **Validation**: Comprehensive test coverage proves the feature works end-to-end
+
+## Future Enhancements (Out of Scope)
+
+1. **Configuration Profiles**: Allow users to define common TEST_RUNNER_ variable sets in config files
+2. **Variable Discovery**: Help users discover available TEST_RUNNER_ variables
+3. **Build Tool Support**: Extend to build tools if Apple adds similar BUILD_RUNNER_ support
+4. **Performance Monitoring**: Track impact of environment variable passing on build times
+
+## Implementation Timeline
+
+- **Phase 0**: 1-2 hours (reproduction test setup)
+- **Phase 1**: 4-6 hours (infrastructure changes)
+- **Phase 2**: 3-4 hours (tool integration)
+- **Phase 3**: 4-5 hours (testing)
+- **Phase 4**: 2-3 hours (validation)
+
+**Total Estimated Time**: 14-20 hours
+
+## Conclusion
+
+This implementation plan provides a secure, user-friendly, and architecturally sound solution for TEST_RUNNER_ environment variable support. The explicit parameter approach with automatic prefix handling balances security concerns with user experience, while the test-driven development approach ensures we can prove the solution works as intended.
+
+The plan leverages XcodeBuildMCP's existing patterns and provides a foundation for future environment variable needs across the tool ecosystem.
\ No newline at end of file
diff --git a/docs/TOOLS.md b/docs/TOOLS.md
new file mode 100644
index 00000000..962e3cff
--- /dev/null
+++ b/docs/TOOLS.md
@@ -0,0 +1,114 @@
+# XcodeBuildMCP Tools Reference
+
+XcodeBuildMCP provides 63 tools organized into 12 workflow groups for comprehensive Apple development workflows.
+
+## Workflow Groups
+
+### 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)
+
+- `build_device` - Builds an app for a connected device.
+- `get_device_app_path` - Retrieves the built app path for a connected device.
+- `install_app_device` - Installs an app on a connected device.
+- `launch_app_device` - Launches an app on a connected device.
+- `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 a running app on a connected device.
+- `test_device` - Runs tests on a physical Apple device.
+### 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. (12 tools)
+
+- `boot_sim` - Boots an iOS simulator.
+- `build_run_sim` - Builds and runs an app on an iOS simulator.
+- `build_sim` - Builds an app for an iOS simulator.
+- `get_sim_app_path` - Retrieves the built app path for an iOS simulator.
+- `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.
+- `list_sims` - Lists available iOS simulators with their UUIDs.
+- `open_sim` - Opens the iOS Simulator app.
+- `record_sim_video` - Starts or stops video capture for an iOS simulator.
+- `stop_app_sim` - Stops an app running in an iOS simulator.
+- `test_sim` - Runs tests on an iOS simulator.
+### 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)
+
+- `start_device_log_cap` - Starts log capture on a connected device.
+- `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.
+- `build_run_macos` - Builds and runs a macOS app.
+- `get_mac_app_path` - Retrieves the built macOS app bundle path.
+- `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 target.
+### 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)
+
+- `discover_projs` - Scans a directory (defaults to workspace root) to find Xcode project (.xcodeproj) and workspace (.xcworkspace) files.
+- `get_app_bundle_id` - Extracts the bundle identifier from an app bundle (.app) for any Apple platform (iOS, iPadOS, watchOS, tvOS, visionOS).
+- `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 schemes for a project or workspace.
+- `show_build_settings` - Shows xcodebuild build settings.
+### 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 with xcodebuild.
+### session-management (`session-management`)
+**Purpose**: Manage session defaults for projectPath/workspacePath, scheme, configuration, simulatorName/simulatorId, deviceId, useLatestOS and arch. These defaults are required by many tools and must be set before attempting to call tools that would depend on these values. (3 tools)
+
+- `session_clear_defaults` - Clear selected or all session defaults.
+- `session_set_defaults` - Set the session defaults needed by many tools. Most tools require one or more session defaults to be set before they can be used. Agents should set all relevant defaults up front in a single call (e.g., project/workspace, scheme, simulator or device ID, useLatestOS) to avoid iterative prompts; only set the keys your workflow needs.
+- `session_show_defaults` - Show current session defaults.
+### Simulator Management (`simulator-management`)
+**Purpose**: Tools for managing simulators from booting, opening simulators, listing simulators, stopping simulators, erasing simulator content and settings, and setting simulator environment options like location, network, statusbar and appearance. (5 tools)
+
+- `erase_sims` - Erases a simulator by UDID.
+- `reset_sim_location` - Resets the simulator's location to default.
+- `set_sim_appearance` - Sets the appearance mode (dark/light) of an iOS 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)
+
+- `swift_package_build` - Builds a Swift Package with swift build
+- `swift_package_clean` - Cleans Swift Package build artifacts and derived data
+- `swift_package_list` - Lists currently running Swift Package processes
+- `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)
+
+- `button` - Press hardware button on iOS simulator. Supported buttons: apple-pay, home, lock, side-button, siri
+- `describe_ui` - Gets entire view hierarchy with precise frame coordinates (x, y, width, height) for all visible elements. Use this before UI interactions or after layout changes - do NOT guess coordinates from screenshots. Returns JSON tree with frame data for accurate automation.
+- `gesture` - Perform gesture on iOS simulator using preset gestures: scroll-up, scroll-down, scroll-left, scroll-right, swipe-from-left-edge, swipe-from-right-edge, swipe-from-top-edge, swipe-from-bottom-edge
+- `key_press` - Press a single key by keycode on the simulator. Common keycodes: 40=Return, 42=Backspace, 43=Tab, 44=Space, 58-67=F1-F10.
+- `key_sequence` - Press key sequence using HID keycodes on iOS simulator with configurable delay
+- `long_press` - Long press at specific coordinates for given duration (ms). Use describe_ui for precise coordinates (don't guess from screenshots).
+- `screenshot` - Captures screenshot for visual verification. For UI coordinates, use describe_ui instead (don't determine coordinates from screenshots).
+- `swipe` - Swipe from one point to another. Use describe_ui for precise coordinates (don't guess from screenshots). Supports configurable timing.
+- `tap` - Tap at specific coordinates or target elements by accessibility id or label. Use describe_ui to get precise element coordinates prior to using x/y parameters (don't guess from screenshots). Supports optional timing delays.
+- `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**: 63 canonical tools + 22 re-exports = 85 total
+- **Workflow Groups**: 12
+
+---
+
+*This documentation is automatically generated by `scripts/update-tools-docs.ts` using static analysis. Last updated: 2025-12-30*
diff --git a/docs/session-aware-migration-todo.md b/docs/session-aware-migration-todo.md
new file mode 100644
index 00000000..0aee3a22
--- /dev/null
+++ b/docs/session-aware-migration-todo.md
@@ -0,0 +1,64 @@
+# Session-Aware Migration TODO
+
+_Audit date: October 6, 2025_
+
+Reference: `docs/session_management_plan.md`
+
+## Utilities
+- [x] `src/mcp/tools/utilities/clean.ts` — session defaults: `projectPath`, `workspacePath`, `scheme`, `configuration`.
+
+## Project Discovery
+- [x] `src/mcp/tools/project-discovery/list_schemes.ts` — session defaults: `projectPath`, `workspacePath`.
+- [x] `src/mcp/tools/project-discovery/show_build_settings.ts` — session defaults: `projectPath`, `workspacePath`, `scheme`.
+
+## Device Workflows
+- [x] `src/mcp/tools/device/build_device.ts` — session defaults: `projectPath`, `workspacePath`, `scheme`, `configuration`.
+- [x] `src/mcp/tools/device/test_device.ts` — session defaults: `projectPath`, `workspacePath`, `scheme`, `deviceId`, `configuration`.
+- [x] `src/mcp/tools/device/get_device_app_path.ts` — session defaults: `projectPath`, `workspacePath`, `scheme`, `configuration`.
+- [x] `src/mcp/tools/device/install_app_device.ts` — session defaults: `deviceId`.
+- [x] `src/mcp/tools/device/launch_app_device.ts` — session defaults: `deviceId`.
+- [x] `src/mcp/tools/device/stop_app_device.ts` — session defaults: `deviceId`.
+
+## Device Logging
+- [x] `src/mcp/tools/logging/start_device_log_cap.ts` — session defaults: `deviceId`.
+
+## macOS Workflows
+- [x] `src/mcp/tools/macos/build_macos.ts` — session defaults: `projectPath`, `workspacePath`, `scheme`, `configuration`, `arch`.
+- [x] `src/mcp/tools/macos/build_run_macos.ts` — session defaults: `projectPath`, `workspacePath`, `scheme`, `configuration`, `arch`.
+- [x] `src/mcp/tools/macos/test_macos.ts` — session defaults: `projectPath`, `workspacePath`, `scheme`, `configuration`.
+- [x] `src/mcp/tools/macos/get_mac_app_path.ts` — session defaults: `projectPath`, `workspacePath`, `scheme`, `configuration`, `arch`.
+
+## Simulator Build/Test/Path
+- [x] `src/mcp/tools/simulator/test_sim.ts` — session defaults: `projectPath`, `workspacePath`, `scheme`, `simulatorId`, `simulatorName`, `configuration`, `useLatestOS`.
+- [x] `src/mcp/tools/simulator/get_sim_app_path.ts` — session defaults: `projectPath`, `workspacePath`, `scheme`, `simulatorId`, `simulatorName`, `configuration`, `useLatestOS`, `arch`.
+
+## Simulator Runtime Actions
+- [x] `src/mcp/tools/simulator/boot_sim.ts` — session defaults: `simulatorId` (hydrate `simulatorUuid`).
+- [x] `src/mcp/tools/simulator/install_app_sim.ts` — session defaults: `simulatorId` (hydrate `simulatorUuid`).
+- [x] `src/mcp/tools/simulator/launch_app_sim.ts` — session defaults: `simulatorId`, `simulatorName` (hydrate `simulatorUuid`).
+- [x] `src/mcp/tools/simulator/launch_app_logs_sim.ts` — session defaults: `simulatorId` (hydrate `simulatorUuid`).
+- [x] `src/mcp/tools/simulator/stop_app_sim.ts` — session defaults: `simulatorId`, `simulatorName` (hydrate `simulatorUuid`).
+- [x] `src/mcp/tools/simulator/record_sim_video.ts` — session defaults: `simulatorId` (hydrate `simulatorUuid`).
+
+## Simulator Management
+- [x] `src/mcp/tools/simulator-management/erase_sims.ts` — session defaults: `simulatorId` (covers `simulatorUdid`).
+- [x] `src/mcp/tools/simulator-management/set_sim_location.ts` — session defaults: `simulatorId` (hydrate `simulatorUuid`).
+- [x] `src/mcp/tools/simulator-management/reset_sim_location.ts` — session defaults: `simulatorId` (hydrate `simulatorUuid`).
+- [x] `src/mcp/tools/simulator-management/set_sim_appearance.ts` — session defaults: `simulatorId` (hydrate `simulatorUuid`).
+- [x] `src/mcp/tools/simulator-management/sim_statusbar.ts` — session defaults: `simulatorId` (hydrate `simulatorUuid`).
+
+## Simulator Logging
+- [x] `src/mcp/tools/logging/start_sim_log_cap.ts` — session defaults: `simulatorId` (hydrate `simulatorUuid`).
+
+## AXe UI Testing Tools
+- [x] `src/mcp/tools/ui-testing/button.ts` — session defaults: `simulatorId` (hydrate `simulatorUuid`).
+- [x] `src/mcp/tools/ui-testing/describe_ui.ts` — session defaults: `simulatorId` (hydrate `simulatorUuid`).
+- [x] `src/mcp/tools/ui-testing/gesture.ts` — session defaults: `simulatorId` (hydrate `simulatorUuid`).
+- [x] `src/mcp/tools/ui-testing/key_press.ts` — session defaults: `simulatorId` (hydrate `simulatorUuid`).
+- [x] `src/mcp/tools/ui-testing/key_sequence.ts` — session defaults: `simulatorId` (hydrate `simulatorUuid`).
+- [x] `src/mcp/tools/ui-testing/long_press.ts` — session defaults: `simulatorId` (hydrate `simulatorUuid`).
+- [x] `src/mcp/tools/ui-testing/screenshot.ts` — session defaults: `simulatorId` (hydrate `simulatorUuid`).
+- [x] `src/mcp/tools/ui-testing/swipe.ts` — session defaults: `simulatorId` (hydrate `simulatorUuid`).
+- [x] `src/mcp/tools/ui-testing/tap.ts` — session defaults: `simulatorId` (hydrate `simulatorUuid`).
+- [x] `src/mcp/tools/ui-testing/touch.ts` — session defaults: `simulatorId` (hydrate `simulatorUuid`).
+- [x] `src/mcp/tools/ui-testing/type_text.ts` — session defaults: `simulatorId` (hydrate `simulatorUuid`).
diff --git a/docs/session_management_plan.md b/docs/session_management_plan.md
new file mode 100644
index 00000000..ce67d58f
--- /dev/null
+++ b/docs/session_management_plan.md
@@ -0,0 +1,482 @@
+# Stateful Session Defaults for MCP Tools — Design, Middleware, and Plan
+
+Below is a concise architecture and implementation plan to introduce a session-aware defaults layer that removes repeated tool parameters from public schemas, while keeping all tool logic and tests unchanged.
+
+## Architecture Overview
+
+- **Core idea**: keep logic functions and tests untouched; move argument consolidation into a session-aware interop layer and expose minimal public schemas.
+- **Data flow**:
+ - Client calls a tool with zero or few args → session middleware merges session defaults → validates with the internal schema → calls the existing logic function.
+- **Components**:
+ - `SessionStore` (singleton, in-memory): set/get/clear/show defaults.
+ - Session-aware tool factory: merges defaults, performs preflight requirement checks (allOf/oneOf), then validates with the tool's internal zod schema.
+ - Public vs internal schema: plugins register a minimal "public" input schema; handlers validate with the unchanged "internal" schema.
+
+## Core Types
+
+```typescript
+// src/utils/session-store.ts
+export type SessionDefaults = {
+ projectPath?: string;
+ workspacePath?: string;
+ scheme?: string;
+ configuration?: string;
+ simulatorName?: string;
+ simulatorId?: string;
+ deviceId?: string;
+ useLatestOS?: boolean;
+ arch?: 'arm64' | 'x86_64';
+};
+```
+
+## Session Store (singleton)
+
+```typescript
+// src/utils/session-store.ts
+import { log } from './logger.ts';
+
+class SessionStore {
+ private defaults: SessionDefaults = {};
+
+ setDefaults(partial: Partial): void {
+ this.defaults = { ...this.defaults, ...partial };
+ log('info', '[Session] Defaults set', { keys: Object.keys(partial) });
+ }
+
+ clear(keys?: (keyof SessionDefaults)[]): void {
+ if (!keys || keys.length === 0) {
+ this.defaults = {};
+ log('info', '[Session] All defaults cleared');
+ return;
+ }
+ for (const k of keys) delete this.defaults[k];
+ log('info', '[Session] Defaults cleared', { keys });
+ }
+
+ get(key: K): SessionDefaults[K] {
+ return this.defaults[key];
+ }
+
+ getAll(): SessionDefaults {
+ return { ...this.defaults };
+ }
+}
+
+export const sessionStore = new SessionStore();
+```
+
+## Session-Aware Tool Factory
+
+```typescript
+// src/utils/typed-tool-factory.ts (add new helper, keep createTypedTool as-is)
+import { z } from 'zod';
+import { sessionStore, type SessionDefaults } from './session-store.ts';
+import type { CommandExecutor } from './execution/index.ts';
+import { createErrorResponse } from './responses/index.ts';
+import type { ToolResponse } from '../types/common.ts';
+
+export type SessionRequirement =
+ | { allOf: (keyof SessionDefaults)[]; message?: string }
+ | { oneOf: (keyof SessionDefaults)[]; message?: string };
+
+function missingFromArgsAndSession(
+ keys: (keyof SessionDefaults)[],
+ args: Record,
+): string[] {
+ return keys.filter((k) => args[k] == null && sessionStore.get(k) == null);
+}
+
+export function createSessionAwareTool(opts: {
+ internalSchema: z.ZodType;
+ logicFunction: (params: TParams, executor: CommandExecutor) => Promise;
+ getExecutor: () => CommandExecutor;
+ requirements?: SessionRequirement[]; // preflight, friendlier than raw zod errors
+}) {
+ const { internalSchema, logicFunction, getExecutor, requirements = [] } = opts;
+
+ return async (rawArgs: Record): Promise => {
+ try {
+ // Merge: explicit args take precedence over session defaults
+ const merged: Record = { ...sessionStore.getAll(), ...rawArgs };
+
+ // Preflight requirement checks (clear message how to fix)
+ for (const req of requirements) {
+ if ('allOf' in req) {
+ const missing = missingFromArgsAndSession(req.allOf, rawArgs);
+ if (missing.length > 0) {
+ return createErrorResponse(
+ 'Missing required session defaults',
+ `${req.message ?? `Required: ${req.allOf.join(', ')}`}\n` +
+ `Set with: session-set-defaults { ${missing.map((k) => `"${k}": "..."`).join(', ')} }`,
+ );
+ }
+ } else if ('oneOf' in req) {
+ const missing = missingFromArgsAndSession(req.oneOf, rawArgs);
+ // oneOf satisfied if at least one is present in merged
+ const satisfied = req.oneOf.some((k) => merged[k] != null);
+ if (!satisfied) {
+ return createErrorResponse(
+ 'Missing required session defaults',
+ `${req.message ?? `Provide one of: ${req.oneOf.join(', ')}`}\n` +
+ `Set with: session-set-defaults { "${req.oneOf[0]}": "..." }`,
+ );
+ }
+ }
+ }
+
+ // Validate against unchanged internal schema (logic/api untouched)
+ const validated = internalSchema.parse(merged);
+ return await logicFunction(validated, getExecutor());
+ } catch (error) {
+ if (error instanceof z.ZodError) {
+ const msgs = error.errors.map((e) => `${e.path.join('.') || 'root'}: ${e.message}`);
+ return createErrorResponse(
+ 'Parameter validation failed',
+ `Invalid parameters:\n${msgs.join('\n')}\n` +
+ `Tip: set session defaults via session-set-defaults`,
+ );
+ }
+ throw error;
+ }
+ };
+}
+```
+
+## Plugin Migration Pattern (Example: build_sim)
+
+Public schema hides session fields; handler uses session-aware factory with internal schema and requirements; logic function unchanged.
+
+```typescript
+// src/mcp/tools/simulator/build_sim.ts (key parts only)
+import { z } from 'zod';
+import { createSessionAwareTool } from '../../../utils/typed-tool-factory.ts';
+import { getDefaultCommandExecutor } from '../../../utils/execution/index.ts';
+
+// Existing internal schema (unchanged)…
+const baseOptions = { /* as-is (scheme, simulatorId, simulatorName, configuration, …) */ };
+const baseSchemaObject = z.object({
+ projectPath: z.string().optional(),
+ workspacePath: z.string().optional(),
+ ...baseOptions,
+});
+const baseSchema = z.preprocess(nullifyEmptyStrings, baseSchemaObject);
+const buildSimulatorSchema = baseSchema
+ .refine(/* as-is: projectPath XOR workspacePath */)
+ .refine(/* as-is: simulatorId XOR simulatorName */);
+
+export type BuildSimulatorParams = z.infer;
+
+// Public schema = internal minus session-managed fields
+const sessionManaged = [
+ 'projectPath',
+ 'workspacePath',
+ 'scheme',
+ 'configuration',
+ 'simulatorId',
+ 'simulatorName',
+ 'useLatestOS',
+] as const;
+
+const publicSchemaObject = baseSchemaObject.omit(
+ Object.fromEntries(sessionManaged.map((k) => [k, true])) as Record,
+);
+
+export default {
+ name: 'build_sim',
+ description: 'Builds an app for an iOS simulator.',
+ schema: publicSchemaObject.shape, // what the MCP client sees
+ handler: createSessionAwareTool({
+ internalSchema: buildSimulatorSchema,
+ logicFunction: build_simLogic,
+ getExecutor: getDefaultCommandExecutor,
+ requirements: [
+ { allOf: ['scheme'], message: 'scheme is required' },
+ { oneOf: ['projectPath', 'workspacePath'], message: 'Provide a project or workspace' },
+ { oneOf: ['simulatorId', 'simulatorName'], message: 'Provide simulatorId or simulatorName' },
+ ],
+ }),
+};
+```
+
+This same pattern applies to `build_run_sim`, `test_sim`, device/macos tools, etc. Public schemas become minimal, while internal schemas and logic remain unchanged.
+
+## New Tool Group: session-management
+
+### session_set_defaults.ts
+
+```typescript
+// src/mcp/tools/session-management/session_set_defaults.ts
+import { z } from 'zod';
+import { sessionStore, type SessionDefaults } from '../../../utils/session-store.ts';
+import { createTypedTool } from '../../../utils/typed-tool-factory.ts';
+import { getDefaultCommandExecutor } from '../../../utils/execution/index.ts';
+
+const schemaObj = z.object({
+ projectPath: z.string().optional(),
+ workspacePath: z.string().optional(),
+ scheme: z.string().optional(),
+ configuration: z.string().optional(),
+ simulatorName: z.string().optional(),
+ simulatorId: z.string().optional(),
+ deviceId: z.string().optional(),
+ useLatestOS: z.boolean().optional(),
+ arch: z.enum(['arm64', 'x86_64']).optional(),
+});
+type Params = z.infer;
+
+async function logic(params: Params): Promise {
+ sessionStore.setDefaults(params as Partial);
+ const current = sessionStore.getAll();
+ return { content: [{ type: 'text', text: `Defaults updated:\n${JSON.stringify(current, null, 2)}` }] };
+}
+
+export default {
+ name: 'session-set-defaults',
+ description: 'Set session defaults used by other tools.',
+ schema: schemaObj.shape,
+ handler: createTypedTool(schemaObj, logic, getDefaultCommandExecutor),
+};
+```
+
+### session_clear_defaults.ts
+
+```typescript
+// src/mcp/tools/session-management/session_clear_defaults.ts
+import { z } from 'zod';
+import { sessionStore } from '../../../utils/session-store.ts';
+import { createTypedTool } from '../../../utils/typed-tool-factory.ts';
+import { getDefaultCommandExecutor } from '../../../utils/execution/index.ts';
+
+const keys = [
+ 'projectPath','workspacePath','scheme','configuration',
+ 'simulatorName','simulatorId','deviceId','useLatestOS','arch',
+] as const;
+const schemaObj = z.object({
+ keys: z.array(z.enum(keys)).optional(),
+ all: z.boolean().optional(),
+});
+
+async function logic(params: z.infer) {
+ if (params.all || !params.keys) sessionStore.clear();
+ else sessionStore.clear(params.keys);
+ return { content: [{ type: 'text', text: 'Session defaults cleared' }] };
+}
+
+export default {
+ name: 'session-clear-defaults',
+ description: 'Clear selected or all session defaults.',
+ schema: schemaObj.shape,
+ handler: createTypedTool(schemaObj, logic, getDefaultCommandExecutor),
+};
+```
+
+### session_show_defaults.ts
+
+```typescript
+// src/mcp/tools/session-management/session_show_defaults.ts
+import { sessionStore } from '../../../utils/session-store.ts';
+
+export default {
+ name: 'session-show-defaults',
+ description: 'Show current session defaults.',
+ schema: {}, // no args
+ handler: async () => {
+ const current = sessionStore.getAll();
+ return { content: [{ type: 'text', text: JSON.stringify(current, null, 2) }] };
+ },
+};
+```
+
+## Step-by-Step Implementation Plan (Incremental, buildable at each step)
+
+1. **Add SessionStore** ✅ **DONE**
+ - New file: `src/utils/session-store.ts`.
+ - No existing code changes; run: `npm run build`, `lint`, `test`.
+ - Commit checkpoint (after review): see Commit & Review Protocol below.
+
+2. **Add session-management tools** ✅ **DONE**
+ - New folder: `src/mcp/tools/session-management` with the three tools above.
+ - Register via existing plugin discovery (same pattern as others).
+ - Build and test.
+ - Commit checkpoint (after review).
+
+3. **Add session-aware tool factory** ✅ **DONE**
+ - Add `createSessionAwareTool` to `src/utils/typed-tool-factory.ts` (keep `createTypedTool` intact).
+ - Unit tests for requirement preflight and merge precedence.
+ - Commit checkpoint (after review).
+
+4. **Migrate 2-3 representative tools**
+ - Example: `simulator/build_sim`, `macos/build_macos`, `device/build_device`.
+ - Create `publicSchemaObject` (omit session fields), switch handler to `createSessionAwareTool` with requirements.
+ - Keep internal schema and logic unchanged. Build and test.
+ - Commit checkpoint (after review).
+
+5. **Migrate remaining tools in small batches**
+ - Apply the same pattern across simulator/device/macos/test utilities.
+ - After each batch: `npm run typecheck`, `lint`, `test`.
+ - Commit checkpoint (after review).
+
+6. **Final polish**
+ - Add tests for session tools and session-aware preflight error messages.
+ - Ensure public schemas no longer expose session parameters globally.
+ - Commit checkpoint (after review).
+
+## Standard Testing & DI Checklist (Mandatory)
+
+- Handlers must use dependency injection; tests must never call real executors.
+- For validation-only tests, calling the handler is acceptable because Zod validation occurs before executor acquisition.
+- For logic tests that would otherwise trigger `getDefaultCommandExecutor`, export the logic function and test it directly (no executor needed if logic doesn’t use one):
+
+```ts
+// Example: src/mcp/tools/session-management/session_clear_defaults.ts
+export async function sessionClearDefaultsLogic(params: Params): Promise { /* ... */ }
+export default {
+ name: 'session-clear-defaults',
+ handler: createTypedTool(schemaObj, sessionClearDefaultsLogic, getDefaultCommandExecutor),
+};
+
+// Test: import logic and call directly to avoid real executor
+import plugin, { sessionClearDefaultsLogic } from '../session_clear_defaults.ts';
+```
+
+- Add tests for the new group and tools:
+ - Group metadata test: `src/mcp/tools/session-management/__tests__/index.test.ts`
+ - Tool tests: `session_set_defaults.test.ts`, `session_clear_defaults.test.ts`, `session_show_defaults.test.ts`
+ - Utils tests: `src/utils/__tests__/session-store.test.ts`
+ - Factory tests: `src/utils/__tests__/session-aware-tool-factory.test.ts` covering:
+ - Preflight requirements (allOf/oneOf)
+ - Merge precedence (explicit args override session defaults)
+ - Zod error reporting with helpful tips
+
+- Always run locally before requesting review:
+ - `npm run typecheck`
+ - `npm run lint`
+ - `npm run format:check`
+ - `npm run build`
+ - `npm run test`
+ - Perform a quick manual CLI check (mcpli or reloaderoo) per the Manual Testing section
+
+### Minimal Changes Policy for Tests (Enforced)
+
+- Only make material, essential edits to tests required by the code change (e.g., new preflight error messages or added/removed fields).
+- Do not change sample input values or defaults in tests (e.g., flipping a boolean like `preferXcodebuild`) unless strictly necessary to validate behavior.
+- Preserve the original intent and coverage of logic-function tests; keep handler vs logic boundaries intact.
+- When session-awareness is added, prefer setting/clearing session defaults around tests rather than altering existing assertions or sample inputs.
+
+### Tool Description Policy (Enforced)
+
+- Keep tool descriptions concise (maximum one short sentence).
+- Do not mention session defaults, setup steps, examples, or parameter relationships in descriptions.
+- Use clear, imperative phrasing (e.g., "Builds an app for an iOS simulator.").
+- Apply consistently across all migrated tools; update any tests that assert `description` to match the concise string only.
+
+## Commit & Review Protocol (Enforced)
+
+At the end of each numbered step above:
+
+1. Ensure all checks pass: `typecheck`, `lint`, `format:check`, `build`, `test`; then perform a quick manual CLI test (mcpli or reloaderoo) per the Manual Testing section.
+ - Verify tool descriptions comply with the Tool Description Policy (concise, no session-defaults mention).
+2. Stage only the files for that step.
+3. Prepare a concise commit message focused on the “why”.
+4. Request manual review and approval before committing. Do not push.
+
+Example messages per step:
+
+- Step 1 (SessionStore)
+ - `chore(utils): add in-memory SessionStore for session defaults`
+ - Body: “Introduces singleton SessionStore with set/get/clear/show for session defaults; no behavior changes.”
+
+- Step 2 (session-management tools)
+ - `feat(session-management): add set/clear/show session defaults tools and workflow metadata`
+ - Body: “Adds tools to manage session defaults and exposes workflow metadata; minimal schemas via typed factory.”
+
+- Step 3 (middleware)
+ - `feat(utils): add createSessionAwareTool with preflight requirements and args>session merge`
+ - Body: “Session-aware interop layer performing requirements checks and Zod validation against internal schema.”
+
+- Step 6 (tests/final polish)
+ - `test(session-management): add tool, store, and middleware tests; export logic for DI`
+ - Body: “Covers group metadata, tools, SessionStore, and factory (requirements/merge/errors). No production behavior changes.”
+
+Approval flow:
+- After preparing messages and confirming checks, request maintainer approval.
+- On approval: commit locally (no push).
+- On rejection: revise and re-run checks.
+
+Note on commit hooks and selective commits:
+- The pre-commit hook runs format/lint/build and can auto-add or modify files, causing additional files to be included in the commit. If you must commit a minimal subset, skip hooks with: `git commit --no-verify` (use sparingly and run `npm run typecheck && npm run lint && npm run test` manually first).
+
+## Safety, Buildability, Testability
+
+- Logic functions and their types remain unchanged; existing unit tests that import logic directly continue to pass.
+- Public schemas shrink; MCP clients see smaller input schemas without session fields.
+- Handlers validate with internal schemas after session-defaults merge, preserving runtime guarantees.
+- Preflight requirement checks return clear guidance, e.g., "Provide one of: projectPath or workspacePath" + "Set with: session-set-defaults { "projectPath": "..." }".
+
+## Developer Usage
+
+- **Set defaults once**:
+ - `session-set-defaults { "workspacePath": "...", "scheme": "App", "simulatorName": "iPhone 16" }`
+- **Run tools without args**:
+ - `build_sim {}`
+- **Inspect/reset**:
+ - `session-show-defaults {}`
+ - `session-clear-defaults { "all": true }`
+
+## Manual Testing with mcpli (CLI)
+
+The following commands exercise the session workflow end‑to‑end using the built server.
+
+1) Build the server (required after code changes):
+
+```bash
+npm run build
+```
+
+2) Discover a scheme (optional helper):
+
+```bash
+mcpli --raw list-schemes --projectPath "/Volumes/Developer/XcodeBuildMCP/example_projects/iOS/MCPTest.xcodeproj" -- node build/index.js
+```
+
+3) Set the session defaults (project/workspace, scheme, and simulator):
+
+```bash
+mcpli --raw session-set-defaults \
+ --projectPath "/Volumes/Developer/XcodeBuildMCP/example_projects/iOS/MCPTest.xcodeproj" \
+ --scheme MCPTest \
+ --simulatorName "iPhone 16" \
+ -- node build/index.js
+```
+
+4) Verify defaults are stored:
+
+```bash
+mcpli --raw session-show-defaults -- node build/index.js
+```
+
+5) Run a session‑aware tool with zero or minimal args (defaults are merged automatically):
+
+```bash
+# Optionally provide a scratch derived data path and a short timeout
+mcpli --tool-timeout=60 --raw build-sim --derivedDataPath "/tmp/XBMCP_DD" -- node build/index.js
+```
+
+Troubleshooting:
+
+- If you see validation errors like “Missing required session defaults …”, (re)run step 3 with the missing keys.
+- If you see connect ECONNREFUSED or the daemon appears flaky:
+ - Check logs: `mcpli daemon log --since=10m -- node build/index.js`
+ - Restart daemon: `mcpli daemon restart -- node build/index.js`
+ - Clean daemon state: `mcpli daemon clean -- node build/index.js` then `mcpli daemon start -- node build/index.js`
+ - After code changes, always: `npm run build` then `mcpli daemon restart -- node build/index.js`
+
+Notes:
+
+- Public schemas for session‑aware tools intentionally omit session fields (e.g., `scheme`, `projectPath`, `simulatorName`). Provide them once via `session-set-defaults` and then call the tool with zero/minimal flags.
+- Use `--tool-timeout=` to cap long‑running builds during manual testing.
+- mcpli CLI normalizes tool names: tools exported with underscores (e.g., `build_sim`) can be invoked with hyphens (e.g., `build-sim`). Copy/paste samples using hyphens are valid because mcpli converts underscores to dashes.
+
+## Next Steps
+
+Would you like me to proceed with Phase 1–3 implementation (store + session tools + middleware), then migrate a first tool (build_sim) and run the test suite?
diff --git a/eslint.config.js b/eslint.config.js
index 6831c0bc..26677ec3 100644
--- a/eslint.config.js
+++ b/eslint.config.js
@@ -6,14 +6,17 @@ export default [
eslint.configs.recommended,
...tseslint.configs.recommended,
{
- files: ['**/*.{js,ts}'],
- ignores: ['node_modules/**', 'build/**', 'dist/**', 'coverage/**'],
+ ignores: ['node_modules/**', 'build/**', 'dist/**', 'coverage/**', 'src/core/generated-plugins.ts', 'src/core/generated-resources.ts'],
+ },
+ {
+ // TypeScript files in src/ directory (covered by tsconfig.json)
+ files: ['src/**/*.ts'],
languageOptions: {
ecmaVersion: 2020,
sourceType: 'module',
parser: tseslint.parser,
parserOptions: {
- project: './tsconfig.json',
+ project: ['./tsconfig.json'],
},
},
plugins: {
@@ -23,12 +26,107 @@ export default [
rules: {
'prettier/prettier': 'error',
'@typescript-eslint/explicit-function-return-type': 'warn',
- '@typescript-eslint/no-explicit-any': 'warn',
+ '@typescript-eslint/no-explicit-any': 'error',
'@typescript-eslint/no-unused-vars': ['error', {
- argsIgnorePattern: '^_',
- varsIgnorePattern: '^_'
+ argsIgnorePattern: 'never',
+ varsIgnorePattern: 'never'
+ }],
+ 'no-console': ['warn', { allow: ['error'] }],
+
+ // Prevent dangerous type casting anti-patterns (errors)
+ '@typescript-eslint/consistent-type-assertions': ['error', {
+ assertionStyle: 'as',
+ objectLiteralTypeAssertions: 'never'
}],
- 'no-console': ['warn', { allow: ['warn', 'error'] }],
+ '@typescript-eslint/no-unsafe-argument': 'error',
+ '@typescript-eslint/no-unsafe-assignment': 'error',
+ '@typescript-eslint/no-unsafe-call': 'error',
+ '@typescript-eslint/no-unsafe-member-access': 'error',
+ '@typescript-eslint/no-unsafe-return': 'error',
+
+ // Prevent specific anti-patterns we found
+ '@typescript-eslint/ban-ts-comment': ['error', {
+ 'ts-expect-error': 'allow-with-description',
+ 'ts-ignore': true,
+ 'ts-nocheck': true,
+ 'ts-check': false,
+ }],
+
+ // Encourage best practices (warnings - can be gradually fixed)
+ '@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', '**/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.'
+ }
+ ]
+ }],
+ },
+ },
+ {
+ // JavaScript and TypeScript files outside the main project (scripts/, etc.)
+ files: ['**/*.{js,ts}'],
+ ignores: ['src/**/*', '**/*.test.ts'],
+ languageOptions: {
+ ecmaVersion: 2020,
+ sourceType: 'module',
+ parser: tseslint.parser,
+ // No project reference for scripts - use standalone parsing
+ },
+ plugins: {
+ '@typescript-eslint': tseslint.plugin,
+ 'prettier': prettierPlugin,
+ },
+ rules: {
+ 'prettier/prettier': 'error',
+ // Relaxed TypeScript rules for scripts since they're not in the main project
+ '@typescript-eslint/explicit-function-return-type': 'off',
+ '@typescript-eslint/no-explicit-any': 'warn',
+ '@typescript-eslint/no-unused-vars': ['warn', {
+ argsIgnorePattern: 'never',
+ varsIgnorePattern: 'never'
+ }],
+ 'no-console': 'off', // Scripts are allowed to use console
+
+ // Disable project-dependent rules for scripts
+ '@typescript-eslint/no-unsafe-argument': 'off',
+ '@typescript-eslint/no-unsafe-assignment': 'off',
+ '@typescript-eslint/no-unsafe-call': 'off',
+ '@typescript-eslint/no-unsafe-member-access': 'off',
+ '@typescript-eslint/no-unsafe-return': 'off',
+ '@typescript-eslint/prefer-nullish-coalescing': 'off',
+ '@typescript-eslint/prefer-optional-chain': 'off',
+ },
+ },
+ {
+ files: ['**/*.test.ts'],
+ languageOptions: {
+ parser: tseslint.parser,
+ parserOptions: {
+ project: './tsconfig.test.json',
+ },
+ },
+ rules: {
+ '@typescript-eslint/no-explicit-any': 'off',
+ '@typescript-eslint/no-unused-vars': 'off',
+ '@typescript-eslint/explicit-function-return-type': 'off',
+ 'prefer-const': 'off',
+
+ // Relax unsafe rules for tests - tests often need more flexibility
+ '@typescript-eslint/no-unsafe-argument': 'off',
+ '@typescript-eslint/no-unsafe-assignment': 'off',
+ '@typescript-eslint/no-unsafe-call': 'off',
+ '@typescript-eslint/no-unsafe-member-access': 'off',
+ '@typescript-eslint/no-unsafe-return': 'off',
},
},
];
diff --git a/example_projects/.vscode/launch.json b/example_projects/.vscode/launch.json
new file mode 100644
index 00000000..e2df4ff8
--- /dev/null
+++ b/example_projects/.vscode/launch.json
@@ -0,0 +1,58 @@
+{
+ "configurations": [
+ {
+ "type": "swift",
+ "request": "launch",
+ "args": [],
+ "cwd": "${workspaceFolder:example_projects}/spm",
+ "name": "Debug spm (spm)",
+ "program": "${workspaceFolder:example_projects}/spm/.build/debug/spm",
+ "preLaunchTask": "swift: Build Debug spm (spm)"
+ },
+ {
+ "type": "swift",
+ "request": "launch",
+ "args": [],
+ "cwd": "${workspaceFolder:example_projects}/spm",
+ "name": "Release spm (spm)",
+ "program": "${workspaceFolder:example_projects}/spm/.build/release/spm",
+ "preLaunchTask": "swift: Build Release spm (spm)"
+ },
+ {
+ "type": "swift",
+ "request": "launch",
+ "args": [],
+ "cwd": "${workspaceFolder:example_projects}/spm",
+ "name": "Debug quick-task (spm)",
+ "program": "${workspaceFolder:example_projects}/spm/.build/debug/quick-task",
+ "preLaunchTask": "swift: Build Debug quick-task (spm)"
+ },
+ {
+ "type": "swift",
+ "request": "launch",
+ "args": [],
+ "cwd": "${workspaceFolder:example_projects}/spm",
+ "name": "Release quick-task (spm)",
+ "program": "${workspaceFolder:example_projects}/spm/.build/release/quick-task",
+ "preLaunchTask": "swift: Build Release quick-task (spm)"
+ },
+ {
+ "type": "swift",
+ "request": "launch",
+ "args": [],
+ "cwd": "${workspaceFolder:example_projects}/spm",
+ "name": "Debug long-server (spm)",
+ "program": "${workspaceFolder:example_projects}/spm/.build/debug/long-server",
+ "preLaunchTask": "swift: Build Debug long-server (spm)"
+ },
+ {
+ "type": "swift",
+ "request": "launch",
+ "args": [],
+ "cwd": "${workspaceFolder:example_projects}/spm",
+ "name": "Release long-server (spm)",
+ "program": "${workspaceFolder:example_projects}/spm/.build/release/long-server",
+ "preLaunchTask": "swift: Build Release long-server (spm)"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/example_projects/iOS/.cursor/rules/errors.mdc b/example_projects/iOS/.cursor/rules/errors.mdc
new file mode 100644
index 00000000..537a3d4b
--- /dev/null
+++ b/example_projects/iOS/.cursor/rules/errors.mdc
@@ -0,0 +1,6 @@
+---
+description:
+globs:
+alwaysApply: true
+---
+Please don't fix any code errors unless reported by XcodeBuildMCP server tool responses.
\ No newline at end of file
diff --git a/example_projects/iOS/.vscode/settings.json b/example_projects/iOS/.vscode/settings.json
new file mode 100644
index 00000000..9e26dfee
--- /dev/null
+++ b/example_projects/iOS/.vscode/settings.json
@@ -0,0 +1 @@
+{}
\ No newline at end of file
diff --git a/example_projects/iOS/MCPTest.xcodeproj/project.pbxproj b/example_projects/iOS/MCPTest.xcodeproj/project.pbxproj
index a8686f7f..a2827747 100644
--- a/example_projects/iOS/MCPTest.xcodeproj/project.pbxproj
+++ b/example_projects/iOS/MCPTest.xcodeproj/project.pbxproj
@@ -7,14 +7,7 @@
objects = {
/* Begin PBXContainerItemProxy section */
- 8BA9F7FB2D62A14500C22D5D /* PBXContainerItemProxy */ = {
- isa = PBXContainerItemProxy;
- containerPortal = 8BA9F7E22D62A14300C22D5D /* Project object */;
- proxyType = 1;
- remoteGlobalIDString = 8BA9F7E92D62A14300C22D5D;
- remoteInfo = MCPTest;
- };
- 8BA9F8052D62A14500C22D5D /* PBXContainerItemProxy */ = {
+ 8BC6F1572E58FBAD008DD7EC /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 8BA9F7E22D62A14300C22D5D /* Project object */;
proxyType = 1;
@@ -25,8 +18,7 @@
/* Begin PBXFileReference section */
8BA9F7EA2D62A14300C22D5D /* MCPTest.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = MCPTest.app; sourceTree = BUILT_PRODUCTS_DIR; };
- 8BA9F7FA2D62A14500C22D5D /* MCPTestTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = MCPTestTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
- 8BA9F8042D62A14500C22D5D /* MCPTestUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = MCPTestUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
+ 8BC6F1512E58FBAD008DD7EC /* MCPTestUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = MCPTestUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
/* End PBXFileReference section */
/* Begin PBXFileSystemSynchronizedRootGroup section */
@@ -35,12 +27,7 @@
path = MCPTest;
sourceTree = "";
};
- 8BA9F7FD2D62A14500C22D5D /* MCPTestTests */ = {
- isa = PBXFileSystemSynchronizedRootGroup;
- path = MCPTestTests;
- sourceTree = "";
- };
- 8BA9F8072D62A14500C22D5D /* MCPTestUITests */ = {
+ 8BC6F1522E58FBAD008DD7EC /* MCPTestUITests */ = {
isa = PBXFileSystemSynchronizedRootGroup;
path = MCPTestUITests;
sourceTree = "";
@@ -55,14 +42,7 @@
);
runOnlyForDeploymentPostprocessing = 0;
};
- 8BA9F7F72D62A14500C22D5D /* Frameworks */ = {
- isa = PBXFrameworksBuildPhase;
- buildActionMask = 2147483647;
- files = (
- );
- runOnlyForDeploymentPostprocessing = 0;
- };
- 8BA9F8012D62A14500C22D5D /* Frameworks */ = {
+ 8BC6F14E2E58FBAD008DD7EC /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
@@ -76,8 +56,7 @@
isa = PBXGroup;
children = (
8BA9F7EC2D62A14300C22D5D /* MCPTest */,
- 8BA9F7FD2D62A14500C22D5D /* MCPTestTests */,
- 8BA9F8072D62A14500C22D5D /* MCPTestUITests */,
+ 8BC6F1522E58FBAD008DD7EC /* MCPTestUITests */,
8BA9F7EB2D62A14300C22D5D /* Products */,
);
sourceTree = "";
@@ -86,8 +65,7 @@
isa = PBXGroup;
children = (
8BA9F7EA2D62A14300C22D5D /* MCPTest.app */,
- 8BA9F7FA2D62A14500C22D5D /* MCPTestTests.xctest */,
- 8BA9F8042D62A14500C22D5D /* MCPTestUITests.xctest */,
+ 8BC6F1512E58FBAD008DD7EC /* MCPTestUITests.xctest */,
);
name = Products;
sourceTree = "";
@@ -117,50 +95,27 @@
productReference = 8BA9F7EA2D62A14300C22D5D /* MCPTest.app */;
productType = "com.apple.product-type.application";
};
- 8BA9F7F92D62A14500C22D5D /* MCPTestTests */ = {
- isa = PBXNativeTarget;
- buildConfigurationList = 8BA9F8112D62A14500C22D5D /* Build configuration list for PBXNativeTarget "MCPTestTests" */;
- buildPhases = (
- 8BA9F7F62D62A14500C22D5D /* Sources */,
- 8BA9F7F72D62A14500C22D5D /* Frameworks */,
- 8BA9F7F82D62A14500C22D5D /* Resources */,
- );
- buildRules = (
- );
- dependencies = (
- 8BA9F7FC2D62A14500C22D5D /* PBXTargetDependency */,
- );
- fileSystemSynchronizedGroups = (
- 8BA9F7FD2D62A14500C22D5D /* MCPTestTests */,
- );
- name = MCPTestTests;
- packageProductDependencies = (
- );
- productName = MCPTestTests;
- productReference = 8BA9F7FA2D62A14500C22D5D /* MCPTestTests.xctest */;
- productType = "com.apple.product-type.bundle.unit-test";
- };
- 8BA9F8032D62A14500C22D5D /* MCPTestUITests */ = {
+ 8BC6F1502E58FBAD008DD7EC /* MCPTestUITests */ = {
isa = PBXNativeTarget;
- buildConfigurationList = 8BA9F8142D62A14500C22D5D /* Build configuration list for PBXNativeTarget "MCPTestUITests" */;
+ buildConfigurationList = 8BC6F15B2E58FBAD008DD7EC /* Build configuration list for PBXNativeTarget "MCPTestUITests" */;
buildPhases = (
- 8BA9F8002D62A14500C22D5D /* Sources */,
- 8BA9F8012D62A14500C22D5D /* Frameworks */,
- 8BA9F8022D62A14500C22D5D /* Resources */,
+ 8BC6F14D2E58FBAD008DD7EC /* Sources */,
+ 8BC6F14E2E58FBAD008DD7EC /* Frameworks */,
+ 8BC6F14F2E58FBAD008DD7EC /* Resources */,
);
buildRules = (
);
dependencies = (
- 8BA9F8062D62A14500C22D5D /* PBXTargetDependency */,
+ 8BC6F1582E58FBAD008DD7EC /* PBXTargetDependency */,
);
fileSystemSynchronizedGroups = (
- 8BA9F8072D62A14500C22D5D /* MCPTestUITests */,
+ 8BC6F1522E58FBAD008DD7EC /* MCPTestUITests */,
);
name = MCPTestUITests;
packageProductDependencies = (
);
productName = MCPTestUITests;
- productReference = 8BA9F8042D62A14500C22D5D /* MCPTestUITests.xctest */;
+ productReference = 8BC6F1512E58FBAD008DD7EC /* MCPTestUITests.xctest */;
productType = "com.apple.product-type.bundle.ui-testing";
};
/* End PBXNativeTarget section */
@@ -170,18 +125,14 @@
isa = PBXProject;
attributes = {
BuildIndependentTargetsInParallel = 1;
- LastSwiftUpdateCheck = 1620;
+ LastSwiftUpdateCheck = 2600;
LastUpgradeCheck = 1620;
TargetAttributes = {
8BA9F7E92D62A14300C22D5D = {
CreatedOnToolsVersion = 16.2;
};
- 8BA9F7F92D62A14500C22D5D = {
- CreatedOnToolsVersion = 16.2;
- TestTargetID = 8BA9F7E92D62A14300C22D5D;
- };
- 8BA9F8032D62A14500C22D5D = {
- CreatedOnToolsVersion = 16.2;
+ 8BC6F1502E58FBAD008DD7EC = {
+ CreatedOnToolsVersion = 26.0;
TestTargetID = 8BA9F7E92D62A14300C22D5D;
};
};
@@ -201,8 +152,7 @@
projectRoot = "";
targets = (
8BA9F7E92D62A14300C22D5D /* MCPTest */,
- 8BA9F7F92D62A14500C22D5D /* MCPTestTests */,
- 8BA9F8032D62A14500C22D5D /* MCPTestUITests */,
+ 8BC6F1502E58FBAD008DD7EC /* MCPTestUITests */,
);
};
/* End PBXProject section */
@@ -215,14 +165,7 @@
);
runOnlyForDeploymentPostprocessing = 0;
};
- 8BA9F7F82D62A14500C22D5D /* Resources */ = {
- isa = PBXResourcesBuildPhase;
- buildActionMask = 2147483647;
- files = (
- );
- runOnlyForDeploymentPostprocessing = 0;
- };
- 8BA9F8022D62A14500C22D5D /* Resources */ = {
+ 8BC6F14F2E58FBAD008DD7EC /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
@@ -239,14 +182,7 @@
);
runOnlyForDeploymentPostprocessing = 0;
};
- 8BA9F7F62D62A14500C22D5D /* Sources */ = {
- isa = PBXSourcesBuildPhase;
- buildActionMask = 2147483647;
- files = (
- );
- runOnlyForDeploymentPostprocessing = 0;
- };
- 8BA9F8002D62A14500C22D5D /* Sources */ = {
+ 8BC6F14D2E58FBAD008DD7EC /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
@@ -256,15 +192,10 @@
/* End PBXSourcesBuildPhase section */
/* Begin PBXTargetDependency section */
- 8BA9F7FC2D62A14500C22D5D /* PBXTargetDependency */ = {
- isa = PBXTargetDependency;
- target = 8BA9F7E92D62A14300C22D5D /* MCPTest */;
- targetProxy = 8BA9F7FB2D62A14500C22D5D /* PBXContainerItemProxy */;
- };
- 8BA9F8062D62A14500C22D5D /* PBXTargetDependency */ = {
+ 8BC6F1582E58FBAD008DD7EC /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = 8BA9F7E92D62A14300C22D5D /* MCPTest */;
- targetProxy = 8BA9F8052D62A14500C22D5D /* PBXContainerItemProxy */;
+ targetProxy = 8BC6F1572E58FBAD008DD7EC /* PBXContainerItemProxy */;
};
/* End PBXTargetDependency section */
@@ -396,7 +327,7 @@
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1;
DEVELOPMENT_ASSET_PATHS = "\"MCPTest/Preview Content\"";
- DEVELOPMENT_TEAM = "";
+ DEVELOPMENT_TEAM = BR6WD3M6ZD;
ENABLE_PREVIEWS = YES;
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES;
@@ -425,7 +356,7 @@
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1;
DEVELOPMENT_ASSET_PATHS = "\"MCPTest/Preview Content\"";
- DEVELOPMENT_TEAM = "";
+ DEVELOPMENT_TEAM = BR6WD3M6ZD;
ENABLE_PREVIEWS = YES;
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES;
@@ -446,72 +377,42 @@
};
name = Release;
};
- 8BA9F8122D62A14500C22D5D /* Debug */ = {
- isa = XCBuildConfiguration;
- buildSettings = {
- BUNDLE_LOADER = "$(TEST_HOST)";
- CODE_SIGN_STYLE = Automatic;
- CURRENT_PROJECT_VERSION = 1;
- DEVELOPMENT_TEAM = BR6WD3M6ZD;
- GENERATE_INFOPLIST_FILE = YES;
- IPHONEOS_DEPLOYMENT_TARGET = 18.2;
- MARKETING_VERSION = 1.0;
- PRODUCT_BUNDLE_IDENTIFIER = com.cameroncooke.MCPTestTests;
- PRODUCT_NAME = "$(TARGET_NAME)";
- SWIFT_EMIT_LOC_STRINGS = NO;
- SWIFT_VERSION = 5.0;
- TARGETED_DEVICE_FAMILY = "1,2";
- TEST_HOST = "$(BUILT_PRODUCTS_DIR)/MCPTest.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/MCPTest";
- };
- name = Debug;
- };
- 8BA9F8132D62A14500C22D5D /* Release */ = {
- isa = XCBuildConfiguration;
- buildSettings = {
- BUNDLE_LOADER = "$(TEST_HOST)";
- CODE_SIGN_STYLE = Automatic;
- CURRENT_PROJECT_VERSION = 1;
- DEVELOPMENT_TEAM = BR6WD3M6ZD;
- GENERATE_INFOPLIST_FILE = YES;
- IPHONEOS_DEPLOYMENT_TARGET = 18.2;
- MARKETING_VERSION = 1.0;
- PRODUCT_BUNDLE_IDENTIFIER = com.cameroncooke.MCPTestTests;
- PRODUCT_NAME = "$(TARGET_NAME)";
- SWIFT_EMIT_LOC_STRINGS = NO;
- SWIFT_VERSION = 5.0;
- TARGETED_DEVICE_FAMILY = "1,2";
- TEST_HOST = "$(BUILT_PRODUCTS_DIR)/MCPTest.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/MCPTest";
- };
- name = Release;
- };
- 8BA9F8152D62A14500C22D5D /* Debug */ = {
+ 8BC6F1592E58FBAD008DD7EC /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1;
DEVELOPMENT_TEAM = BR6WD3M6ZD;
GENERATE_INFOPLIST_FILE = YES;
+ IPHONEOS_DEPLOYMENT_TARGET = 26.0;
MARKETING_VERSION = 1.0;
- PRODUCT_BUNDLE_IDENTIFIER = com.cameroncooke.MCPTestUITests;
+ PRODUCT_BUNDLE_IDENTIFIER = com.cameroncooke.test.MCPTestUITests;
PRODUCT_NAME = "$(TARGET_NAME)";
+ STRING_CATALOG_GENERATE_SYMBOLS = NO;
+ SWIFT_APPROACHABLE_CONCURRENCY = YES;
SWIFT_EMIT_LOC_STRINGS = NO;
+ SWIFT_UPCOMING_FEATURE_MEMBER_IMPORT_VISIBILITY = YES;
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
TEST_TARGET_NAME = MCPTest;
};
name = Debug;
};
- 8BA9F8162D62A14500C22D5D /* Release */ = {
+ 8BC6F15A2E58FBAD008DD7EC /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1;
DEVELOPMENT_TEAM = BR6WD3M6ZD;
GENERATE_INFOPLIST_FILE = YES;
+ IPHONEOS_DEPLOYMENT_TARGET = 26.0;
MARKETING_VERSION = 1.0;
- PRODUCT_BUNDLE_IDENTIFIER = com.cameroncooke.MCPTestUITests;
+ PRODUCT_BUNDLE_IDENTIFIER = com.cameroncooke.test.MCPTestUITests;
PRODUCT_NAME = "$(TARGET_NAME)";
+ STRING_CATALOG_GENERATE_SYMBOLS = NO;
+ SWIFT_APPROACHABLE_CONCURRENCY = YES;
SWIFT_EMIT_LOC_STRINGS = NO;
+ SWIFT_UPCOMING_FEATURE_MEMBER_IMPORT_VISIBILITY = YES;
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
TEST_TARGET_NAME = MCPTest;
@@ -539,20 +440,11 @@
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
- 8BA9F8112D62A14500C22D5D /* Build configuration list for PBXNativeTarget "MCPTestTests" */ = {
- isa = XCConfigurationList;
- buildConfigurations = (
- 8BA9F8122D62A14500C22D5D /* Debug */,
- 8BA9F8132D62A14500C22D5D /* Release */,
- );
- defaultConfigurationIsVisible = 0;
- defaultConfigurationName = Release;
- };
- 8BA9F8142D62A14500C22D5D /* Build configuration list for PBXNativeTarget "MCPTestUITests" */ = {
+ 8BC6F15B2E58FBAD008DD7EC /* Build configuration list for PBXNativeTarget "MCPTestUITests" */ = {
isa = XCConfigurationList;
buildConfigurations = (
- 8BA9F8152D62A14500C22D5D /* Debug */,
- 8BA9F8162D62A14500C22D5D /* Release */,
+ 8BC6F1592E58FBAD008DD7EC /* Debug */,
+ 8BC6F15A2E58FBAD008DD7EC /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
diff --git a/example_projects/iOS/MCPTest.xcodeproj/xcshareddata/xcschemes/MCPTest.xcscheme b/example_projects/iOS/MCPTest.xcodeproj/xcshareddata/xcschemes/MCPTest.xcscheme
new file mode 100644
index 00000000..6d24981d
--- /dev/null
+++ b/example_projects/iOS/MCPTest.xcodeproj/xcshareddata/xcschemes/MCPTest.xcscheme
@@ -0,0 +1,91 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/example_projects/iOS/MCPTest/ContentView.swift b/example_projects/iOS/MCPTest/ContentView.swift
index 949c33f0..44ae826d 100644
--- a/example_projects/iOS/MCPTest/ContentView.swift
+++ b/example_projects/iOS/MCPTest/ContentView.swift
@@ -9,20 +9,27 @@ import SwiftUI
import OSLog
struct ContentView: View {
+ @State private var text: String = ""
+
var body: some View {
VStack {
Image(systemName: "globe")
.imageScale(.large)
.foregroundStyle(.tint)
- Text("Hello, world!")
+ TextField("Enter text", text: $text)
+ .textFieldStyle(RoundedBorderTextFieldStyle())
+ .padding(.horizontal)
+ Text(text)
Button("Log something") {
- Logger.myApp.debug("Oh this is structured logging")
- debugPrint("I'm just plain old std out :-(")
+ let message = ProcessInfo.processInfo.environment.map { "\($0.key): \($0.value)" }.joined(separator: "\n")
+ Logger.myApp.debug("Environment: \(message)")
+ debugPrint("Button was pressed.")
+
+ text = "You just pressed the button!"
}
}
.padding()
-
}
}
@@ -37,4 +44,4 @@ extension Logger {
category: "default"
)
}
-
\ No newline at end of file
+
diff --git a/example_projects/iOS/MCPTestTests/MCPTestTests.swift b/example_projects/iOS/MCPTestTests/MCPTestTests.swift
deleted file mode 100644
index f244a4e0..00000000
--- a/example_projects/iOS/MCPTestTests/MCPTestTests.swift
+++ /dev/null
@@ -1,17 +0,0 @@
-//
-// MCPTestTests.swift
-// MCPTestTests
-//
-// Created by Cameron on 16/02/2025.
-//
-
-import Testing
-@testable import MCPTest
-
-struct MCPTestTests {
-
- @Test func example() async throws {
- // Write your test here and use APIs like `#expect(...)` to check expected conditions.
- }
-
-}
diff --git a/example_projects/iOS/MCPTestUITests/MCPTestUITests.swift b/example_projects/iOS/MCPTestUITests/MCPTestUITests.swift
index ecc9df3e..b1c30c97 100644
--- a/example_projects/iOS/MCPTestUITests/MCPTestUITests.swift
+++ b/example_projects/iOS/MCPTestUITests/MCPTestUITests.swift
@@ -1,43 +1,41 @@
-//
-// MCPTestUITests.swift
-// MCPTestUITests
-//
-// Created by Cameron on 16/02/2025.
-//
-
import XCTest
+/// Reproduction tests for TEST_RUNNER_ environment variable passthrough.
+/// GitHub Issue: https://github.com/cameroncooke/XcodeBuildMCP/issues/101
+///
+/// Expected behavior:
+/// - When invoking xcodebuild test with TEST_RUNNER_USE_DEV_MODE=YES,
+/// the test runner environment should contain USE_DEV_MODE=YES
+/// (the TEST_RUNNER_ prefix is stripped by xcodebuild).
+///
+/// Current behavior (before implementation in Node layer):
+/// - Running via XcodeBuildMCP test tools does not yet pass TEST_RUNNER_
+/// variables through, so this test will fail and serve as a repro.
final class MCPTestUITests: XCTestCase {
override func setUpWithError() throws {
- // Put setup code here. This method is called before the invocation of each test method in the class.
-
- // In UI tests it is usually best to stop immediately when a failure occurs.
continueAfterFailure = false
-
- // In UI tests it’s important to set the initial state - such as interface orientation - required for your tests before they run. The setUp method is a good place to do this.
}
- override func tearDownWithError() throws {
- // Put teardown code here. This method is called after the invocation of each test method in the class.
- }
-
- @MainActor
- func testExample() throws {
- // UI tests must launch the application that they test.
- let app = XCUIApplication()
- app.launch()
-
- // Use XCTAssert and related functions to verify your tests produce the correct results.
+ /// Verifies that USE_DEV_MODE=YES is present in the test runner environment.
+ /// This proves TEST_RUNNER_USE_DEV_MODE=YES was passed to xcodebuild.
+ func testEnvironmentVariablePassthrough() throws {
+ let env = ProcessInfo.processInfo.environment
+ let value = env["USE_DEV_MODE"] ?? ""
+ XCTAssertEqual(
+ value,
+ "YES",
+ "Expected USE_DEV_MODE=YES via TEST_RUNNER_USE_DEV_MODE. Actual: \(value)"
+ )
}
- @MainActor
- func testLaunchPerformance() throws {
- if #available(macOS 10.15, iOS 13.0, tvOS 13.0, watchOS 7.0, *) {
- // This measures how long it takes to launch your application.
- measure(metrics: [XCTApplicationLaunchMetric()]) {
- XCUIApplication().launch()
- }
+ /// Example of how a project might use the env var to alter behavior in dev mode.
+ /// This does not change test runner configuration; it simply demonstrates conditional logic.
+ func testDevModeBehaviorPlaceholder() throws {
+ let isDevMode = ProcessInfo.processInfo.environment["USE_DEV_MODE"] == "YES"
+ if isDevMode {
+ XCTSkip("Dev mode: skipping heavy or duplicated UI configuration runs")
}
+ XCTAssertTrue(true)
}
-}
+}
\ No newline at end of file
diff --git a/example_projects/iOS/MCPTestUITests/MCPTestUITestsLaunchTests.swift b/example_projects/iOS/MCPTestUITests/MCPTestUITestsLaunchTests.swift
deleted file mode 100644
index cfc46046..00000000
--- a/example_projects/iOS/MCPTestUITests/MCPTestUITestsLaunchTests.swift
+++ /dev/null
@@ -1,33 +0,0 @@
-//
-// MCPTestUITestsLaunchTests.swift
-// MCPTestUITests
-//
-// Created by Cameron on 16/02/2025.
-//
-
-import XCTest
-
-final class MCPTestUITestsLaunchTests: XCTestCase {
-
- override class var runsForEachTargetApplicationUIConfiguration: Bool {
- true
- }
-
- override func setUpWithError() throws {
- continueAfterFailure = false
- }
-
- @MainActor
- func testLaunch() throws {
- let app = XCUIApplication()
- app.launch()
-
- // Insert steps here to perform after app launch but before taking a screenshot,
- // such as logging into a test account or navigating somewhere in the app
-
- let attachment = XCTAttachment(screenshot: app.screenshot())
- attachment.name = "Launch Screen"
- attachment.lifetime = .keepAlways
- add(attachment)
- }
-}
diff --git a/example_projects/iOS/Makefile b/example_projects/iOS/Makefile
new file mode 100644
index 00000000..26bcb626
--- /dev/null
+++ b/example_projects/iOS/Makefile
@@ -0,0 +1,339 @@
+#
+# Generated Wed May 7 23:04:17 2025 from
+# /usr/bin/xcodebuild ARCHS=arm64 -project MCPTest.xcodeproj -scheme MCPTest -configuration Debug -skipMacroValidation -destination platform=iOS Simulator,id=B34FF305-5EA8-412B-943F-1D0371CA17FF build -config Debug
+#
+
+default: main
+
+# Command line invocation:
+# /Applications/Xcode-16.3.0.app/Contents/Developer/usr/bin/xcodebuild -project MCPTest.xcodeproj -scheme MCPTest -configuration Debug -skipMacroValidation -destination "platform=iOS Simulator,id=B34FF305-5EA8-412B-943F-1D0371CA17FF" build
+#
+# ComputePackagePrebuildTargetDependencyGraph
+#
+# Prepare packages
+#
+# CreateBuildRequest
+#
+# SendProjectDescription
+#
+# CreateBuildOperation
+#
+# ComputeTargetDependencyGraph
+# note: Building targets in dependency order
+# note: Target dependency graph (1 target)
+# Target 'MCPTest' in project 'MCPTest' (no dependencies)
+#
+# GatherProvisioningInputs
+#
+# CreateBuildDescription
+#
+# ExecuteExternalTool /Applications/Xcode-16.3.0.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang -v -E -dM -isysroot /Applications/Xcode-16.3.0.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator18.4.sdk -x c -c /dev/null
+#
+# ExecuteExternalTool /Applications/Xcode-16.3.0.app/Contents/Developer/usr/bin/actool --print-asset-tag-combinations --output-format xml1 /Volumes/Developer/XcodeBuildMCP/example_projects/iOS/MCPTest/Assets.xcassets /Volumes/Developer/XcodeBuildMCP/example_projects/iOS/MCPTest/Preview Content/Preview Assets.xcassets
+#
+# ExecuteExternalTool /Applications/Xcode-16.3.0.app/Contents/Developer/usr/bin/actool --version --output-format xml1
+#
+# ExecuteExternalTool /Applications/Xcode-16.3.0.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/swiftc --version
+#
+# ExecuteExternalTool /Applications/Xcode-16.3.0.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ld -version_details
+#
+# Build description signature: 2234c1bc1c3f985320846b3f57a2be43
+# Build description path: /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Intermediates.noindex/XCBuildData/2234c1bc1c3f985320846b3f57a2be43.xcbuilddata
+# ClangStatCache /Applications/Xcode-16.3.0.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang-stat-cache /Applications/Xcode-16.3.0.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator18.4.sdk /Users/cameroncooke/Library/Developer/Xcode/DerivedData/SDKStatCaches.noindex/iphonesimulator18.4-22E235-43e5fd89280df366c77438703b8fa853.sdkstatcache
+# cd /Volumes/Developer/XcodeBuildMCP/example_projects/iOS/MCPTest.xcodeproj
+# /Applications/Xcode-16.3.0.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang-stat-cache /Applications/Xcode-16.3.0.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator18.4.sdk -o /Users/cameroncooke/Library/Developer/Xcode/DerivedData/SDKStatCaches.noindex/iphonesimulator18.4-22E235-43e5fd89280df366c77438703b8fa853.sdkstatcache
+#
+# CreateBuildDirectory /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Products
+# cd /Volumes/Developer/XcodeBuildMCP/example_projects/iOS/MCPTest.xcodeproj
+# builtin-create-build-directory /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Products
+#
+# CreateBuildDirectory /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Intermediates.noindex
+# cd /Volumes/Developer/XcodeBuildMCP/example_projects/iOS/MCPTest.xcodeproj
+# builtin-create-build-directory /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Intermediates.noindex
+#
+# CreateBuildDirectory /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Products/Debug-iphonesimulator
+# cd /Volumes/Developer/XcodeBuildMCP/example_projects/iOS/MCPTest.xcodeproj
+# builtin-create-build-directory /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Products/Debug-iphonesimulator
+#
+# CreateBuildDirectory /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Intermediates.noindex/EagerLinkingTBDs/Debug-iphonesimulator
+# cd /Volumes/Developer/XcodeBuildMCP/example_projects/iOS/MCPTest.xcodeproj
+# builtin-create-build-directory /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Intermediates.noindex/EagerLinkingTBDs/Debug-iphonesimulator
+#
+# WriteAuxiliaryFile /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Intermediates.noindex/MCPTest.build/Debug-iphonesimulator/MCPTest-4015ebf9d65117cac38478cba1863b71-VFS-iphonesimulator/all-product-headers.yaml
+# cd /Volumes/Developer/XcodeBuildMCP/example_projects/iOS/MCPTest.xcodeproj
+# write-file /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Intermediates.noindex/MCPTest.build/Debug-iphonesimulator/MCPTest-4015ebf9d65117cac38478cba1863b71-VFS-iphonesimulator/all-product-headers.yaml
+#
+# WriteAuxiliaryFile /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Intermediates.noindex/MCPTest.build/Debug-iphonesimulator/MCPTest.build/empty-MCPTest.plist (in target 'MCPTest' from project 'MCPTest')
+# cd /Volumes/Developer/XcodeBuildMCP/example_projects/iOS
+# write-file /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Intermediates.noindex/MCPTest.build/Debug-iphonesimulator/MCPTest.build/empty-MCPTest.plist
+#
+# WriteAuxiliaryFile /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Intermediates.noindex/MCPTest.build/Debug-iphonesimulator/MCPTest.build/MCPTest.hmap (in target 'MCPTest' from project 'MCPTest')
+# cd /Volumes/Developer/XcodeBuildMCP/example_projects/iOS
+# write-file /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Intermediates.noindex/MCPTest.build/Debug-iphonesimulator/MCPTest.build/MCPTest.hmap
+#
+# WriteAuxiliaryFile /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Intermediates.noindex/MCPTest.build/Debug-iphonesimulator/MCPTest.build/MCPTest-project-headers.hmap (in target 'MCPTest' from project 'MCPTest')
+# cd /Volumes/Developer/XcodeBuildMCP/example_projects/iOS
+# write-file /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Intermediates.noindex/MCPTest.build/Debug-iphonesimulator/MCPTest.build/MCPTest-project-headers.hmap
+#
+# WriteAuxiliaryFile /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Intermediates.noindex/MCPTest.build/Debug-iphonesimulator/MCPTest.build/MCPTest.DependencyMetadataFileList (in target 'MCPTest' from project 'MCPTest')
+# cd /Volumes/Developer/XcodeBuildMCP/example_projects/iOS
+# write-file /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Intermediates.noindex/MCPTest.build/Debug-iphonesimulator/MCPTest.build/MCPTest.DependencyMetadataFileList
+#
+# WriteAuxiliaryFile /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Intermediates.noindex/MCPTest.build/Debug-iphonesimulator/MCPTest.build/MCPTest-own-target-headers.hmap (in target 'MCPTest' from project 'MCPTest')
+# cd /Volumes/Developer/XcodeBuildMCP/example_projects/iOS
+# write-file /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Intermediates.noindex/MCPTest.build/Debug-iphonesimulator/MCPTest.build/MCPTest-own-target-headers.hmap
+#
+# WriteAuxiliaryFile /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Intermediates.noindex/MCPTest.build/Debug-iphonesimulator/MCPTest.build/MCPTest.DependencyStaticMetadataFileList (in target 'MCPTest' from project 'MCPTest')
+# cd /Volumes/Developer/XcodeBuildMCP/example_projects/iOS
+# write-file /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Intermediates.noindex/MCPTest.build/Debug-iphonesimulator/MCPTest.build/MCPTest.DependencyStaticMetadataFileList
+#
+# WriteAuxiliaryFile /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Intermediates.noindex/MCPTest.build/Debug-iphonesimulator/MCPTest.build/Objects-normal/arm64/MCPTest-OutputFileMap.json (in target 'MCPTest' from project 'MCPTest')
+# cd /Volumes/Developer/XcodeBuildMCP/example_projects/iOS
+# write-file /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Intermediates.noindex/MCPTest.build/Debug-iphonesimulator/MCPTest.build/Objects-normal/arm64/MCPTest-OutputFileMap.json
+#
+# WriteAuxiliaryFile /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Intermediates.noindex/MCPTest.build/Debug-iphonesimulator/MCPTest.build/Objects-normal/arm64/MCPTest_const_extract_protocols.json (in target 'MCPTest' from project 'MCPTest')
+# cd /Volumes/Developer/XcodeBuildMCP/example_projects/iOS
+# write-file /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Intermediates.noindex/MCPTest.build/Debug-iphonesimulator/MCPTest.build/Objects-normal/arm64/MCPTest_const_extract_protocols.json
+#
+# WriteAuxiliaryFile /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Intermediates.noindex/MCPTest.build/Debug-iphonesimulator/MCPTest.build/Objects-normal/arm64/MCPTest.SwiftFileList (in target 'MCPTest' from project 'MCPTest')
+# cd /Volumes/Developer/XcodeBuildMCP/example_projects/iOS
+# write-file /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Intermediates.noindex/MCPTest.build/Debug-iphonesimulator/MCPTest.build/Objects-normal/arm64/MCPTest.SwiftFileList
+#
+# WriteAuxiliaryFile /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Intermediates.noindex/MCPTest.build/Debug-iphonesimulator/MCPTest.build/Objects-normal/arm64/MCPTest.SwiftConstValuesFileList (in target 'MCPTest' from project 'MCPTest')
+# cd /Volumes/Developer/XcodeBuildMCP/example_projects/iOS
+# write-file /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Intermediates.noindex/MCPTest.build/Debug-iphonesimulator/MCPTest.build/Objects-normal/arm64/MCPTest.SwiftConstValuesFileList
+#
+# WriteAuxiliaryFile /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Intermediates.noindex/MCPTest.build/Debug-iphonesimulator/MCPTest.build/Objects-normal/arm64/MCPTest.LinkFileList (in target 'MCPTest' from project 'MCPTest')
+# cd /Volumes/Developer/XcodeBuildMCP/example_projects/iOS
+# write-file /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Intermediates.noindex/MCPTest.build/Debug-iphonesimulator/MCPTest.build/Objects-normal/arm64/MCPTest.LinkFileList
+#
+# WriteAuxiliaryFile /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Intermediates.noindex/MCPTest.build/Debug-iphonesimulator/MCPTest.build/MCPTest-generated-files.hmap (in target 'MCPTest' from project 'MCPTest')
+# cd /Volumes/Developer/XcodeBuildMCP/example_projects/iOS
+# write-file /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Intermediates.noindex/MCPTest.build/Debug-iphonesimulator/MCPTest.build/MCPTest-generated-files.hmap
+#
+# WriteAuxiliaryFile /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Intermediates.noindex/MCPTest.build/Debug-iphonesimulator/MCPTest.build/MCPTest-all-target-headers.hmap (in target 'MCPTest' from project 'MCPTest')
+# cd /Volumes/Developer/XcodeBuildMCP/example_projects/iOS
+# write-file /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Intermediates.noindex/MCPTest.build/Debug-iphonesimulator/MCPTest.build/MCPTest-all-target-headers.hmap
+#
+# WriteAuxiliaryFile /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Intermediates.noindex/MCPTest.build/Debug-iphonesimulator/MCPTest.build/MCPTest-all-non-framework-target-headers.hmap (in target 'MCPTest' from project 'MCPTest')
+# cd /Volumes/Developer/XcodeBuildMCP/example_projects/iOS
+# write-file /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Intermediates.noindex/MCPTest.build/Debug-iphonesimulator/MCPTest.build/MCPTest-all-non-framework-target-headers.hmap
+#
+# WriteAuxiliaryFile /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Intermediates.noindex/MCPTest.build/Debug-iphonesimulator/MCPTest.build/MCPTest-DebugDylibPath-normal-arm64.txt (in target 'MCPTest' from project 'MCPTest')
+# cd /Volumes/Developer/XcodeBuildMCP/example_projects/iOS
+# write-file /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Intermediates.noindex/MCPTest.build/Debug-iphonesimulator/MCPTest.build/MCPTest-DebugDylibPath-normal-arm64.txt
+#
+# WriteAuxiliaryFile /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Intermediates.noindex/MCPTest.build/Debug-iphonesimulator/MCPTest.build/MCPTest-DebugDylibInstallName-normal-arm64.txt (in target 'MCPTest' from project 'MCPTest')
+# cd /Volumes/Developer/XcodeBuildMCP/example_projects/iOS
+# write-file /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Intermediates.noindex/MCPTest.build/Debug-iphonesimulator/MCPTest.build/MCPTest-DebugDylibInstallName-normal-arm64.txt
+#
+# MkDir /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Products/Debug-iphonesimulator/MCPTest.app (in target 'MCPTest' from project 'MCPTest')
+# cd /Volumes/Developer/XcodeBuildMCP/example_projects/iOS
+# /bin/mkdir -p /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Products/Debug-iphonesimulator/MCPTest.app
+#
+# WriteAuxiliaryFile /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Intermediates.noindex/MCPTest.build/Debug-iphonesimulator/MCPTest.build/DerivedSources/Entitlements-Simulated.plist (in target 'MCPTest' from project 'MCPTest')
+# cd /Volumes/Developer/XcodeBuildMCP/example_projects/iOS
+# write-file /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Intermediates.noindex/MCPTest.build/Debug-iphonesimulator/MCPTest.build/DerivedSources/Entitlements-Simulated.plist
+#
+# ValidateDevelopmentAssets /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Intermediates.noindex/MCPTest.build/Debug-iphonesimulator/MCPTest.build (in target 'MCPTest' from project 'MCPTest')
+# cd /Volumes/Developer/XcodeBuildMCP/example_projects/iOS
+# builtin-validate-development-assets --validate YES_ERROR /Volumes/Developer/XcodeBuildMCP/example_projects/iOS/MCPTest/Preview\ Content
+#
+# ProcessProductPackaging "" /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Intermediates.noindex/MCPTest.build/Debug-iphonesimulator/MCPTest.build/MCPTest.app-Simulated.xcent (in target 'MCPTest' from project 'MCPTest')
+# cd /Volumes/Developer/XcodeBuildMCP/example_projects/iOS
+#
+# Entitlements:
+#
+# {
+# "application-identifier" = "BR6WD3M6ZD.com.cameroncooke.MCPTest";
+# }
+#
+# builtin-productPackagingUtility -entitlements -format xml -o /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Intermediates.noindex/MCPTest.build/Debug-iphonesimulator/MCPTest.build/MCPTest.app-Simulated.xcent
+#
+# ProcessProductPackagingDER /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Intermediates.noindex/MCPTest.build/Debug-iphonesimulator/MCPTest.build/MCPTest.app-Simulated.xcent /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Intermediates.noindex/MCPTest.build/Debug-iphonesimulator/MCPTest.build/MCPTest.app-Simulated.xcent.der (in target 'MCPTest' from project 'MCPTest')
+# cd /Volumes/Developer/XcodeBuildMCP/example_projects/iOS
+# /usr/bin/derq query -f xml -i /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Intermediates.noindex/MCPTest.build/Debug-iphonesimulator/MCPTest.build/MCPTest.app-Simulated.xcent -o /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Intermediates.noindex/MCPTest.build/Debug-iphonesimulator/MCPTest.build/MCPTest.app-Simulated.xcent.der --raw
+#
+# Ld /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Products/Debug-iphonesimulator/MCPTest.app/__preview.dylib normal (in target 'MCPTest' from project 'MCPTest')
+
+/Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Products/Debug-iphonesimulator/MCPTest.app/__preview.dylib:
+ cd /Volumes/Developer/XcodeBuildMCP/example_projects/iOS
+ /Applications/Xcode-16.3.0.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang -Xlinker -reproducible -target arm64-apple-ios18.2-simulator -dynamiclib -isysroot /Applications/Xcode-16.3.0.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator18.4.sdk -O0 -L/Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Products/Debug-iphonesimulator -F/Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Products/Debug-iphonesimulator -install_name @rpath/MCPTest.debug.dylib -dead_strip -rdynamic -Xlinker -no_deduplicate -Xlinker -objc_abi_version -Xlinker 2 -Xlinker -dependency_info -Xlinker /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Intermediates.noindex/MCPTest.build/Debug-iphonesimulator/MCPTest.build/Objects-normal/arm64/MCPTest_dependency_info.dat -Xlinker -sectcreate -Xlinker __TEXT -Xlinker __entitlements -Xlinker /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Intermediates.noindex/MCPTest.build/Debug-iphonesimulator/MCPTest.build/MCPTest.app-Simulated.xcent -Xlinker -sectcreate -Xlinker __TEXT -Xlinker __ents_der -Xlinker /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Intermediates.noindex/MCPTest.build/Debug-iphonesimulator/MCPTest.build/MCPTest.app-Simulated.xcent.der -Xlinker -no_adhoc_codesign -o /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Products/Debug-iphonesimulator/MCPTest.app/__preview.dylib
+
+#
+# GenerateAssetSymbols /Volumes/Developer/XcodeBuildMCP/example_projects/iOS/MCPTest/Assets.xcassets /Volumes/Developer/XcodeBuildMCP/example_projects/iOS/MCPTest/Preview\ Content/Preview\ Assets.xcassets (in target 'MCPTest' from project 'MCPTest')
+# cd /Volumes/Developer/XcodeBuildMCP/example_projects/iOS
+# /Applications/Xcode-16.3.0.app/Contents/Developer/usr/bin/actool /Volumes/Developer/XcodeBuildMCP/example_projects/iOS/MCPTest/Assets.xcassets /Volumes/Developer/XcodeBuildMCP/example_projects/iOS/MCPTest/Preview\ Content/Preview\ Assets.xcassets --compile /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Products/Debug-iphonesimulator/MCPTest.app --output-format human-readable-text --notices --warnings --export-dependency-info /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Intermediates.noindex/MCPTest.build/Debug-iphonesimulator/MCPTest.build/assetcatalog_dependencies --output-partial-info-plist /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Intermediates.noindex/MCPTest.build/Debug-iphonesimulator/MCPTest.build/assetcatalog_generated_info.plist --app-icon AppIcon --accent-color AccentColor --compress-pngs --enable-on-demand-resources YES --development-region en --target-device iphone --target-device ipad --minimum-deployment-target 18.2 --platform iphonesimulator --bundle-identifier com.cameroncooke.MCPTest --generate-swift-asset-symbols /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Intermediates.noindex/MCPTest.build/Debug-iphonesimulator/MCPTest.build/DerivedSources/GeneratedAssetSymbols.swift --generate-objc-asset-symbols /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Intermediates.noindex/MCPTest.build/Debug-iphonesimulator/MCPTest.build/DerivedSources/GeneratedAssetSymbols.h --generate-asset-symbol-index /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Intermediates.noindex/MCPTest.build/Debug-iphonesimulator/MCPTest.build/DerivedSources/GeneratedAssetSymbols-Index.plist
+# /* com.apple.actool.compilation-results */
+# /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Intermediates.noindex/MCPTest.build/Debug-iphonesimulator/MCPTest.build/DerivedSources/GeneratedAssetSymbols-Index.plist
+# /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Intermediates.noindex/MCPTest.build/Debug-iphonesimulator/MCPTest.build/DerivedSources/GeneratedAssetSymbols.h
+# /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Intermediates.noindex/MCPTest.build/Debug-iphonesimulator/MCPTest.build/DerivedSources/GeneratedAssetSymbols.swift
+#
+#
+# MkDir /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Intermediates.noindex/MCPTest.build/Debug-iphonesimulator/MCPTest.build/assetcatalog_output/thinned (in target 'MCPTest' from project 'MCPTest')
+# cd /Volumes/Developer/XcodeBuildMCP/example_projects/iOS
+# /bin/mkdir -p /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Intermediates.noindex/MCPTest.build/Debug-iphonesimulator/MCPTest.build/assetcatalog_output/thinned
+#
+# MkDir /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Intermediates.noindex/MCPTest.build/Debug-iphonesimulator/MCPTest.build/assetcatalog_output/unthinned (in target 'MCPTest' from project 'MCPTest')
+# cd /Volumes/Developer/XcodeBuildMCP/example_projects/iOS
+# /bin/mkdir -p /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Intermediates.noindex/MCPTest.build/Debug-iphonesimulator/MCPTest.build/assetcatalog_output/unthinned
+#
+# CompileAssetCatalogVariant thinned /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Products/Debug-iphonesimulator/MCPTest.app /Volumes/Developer/XcodeBuildMCP/example_projects/iOS/MCPTest/Assets.xcassets /Volumes/Developer/XcodeBuildMCP/example_projects/iOS/MCPTest/Preview\ Content/Preview\ Assets.xcassets (in target 'MCPTest' from project 'MCPTest')
+# cd /Volumes/Developer/XcodeBuildMCP/example_projects/iOS
+# /Applications/Xcode-16.3.0.app/Contents/Developer/usr/bin/actool /Volumes/Developer/XcodeBuildMCP/example_projects/iOS/MCPTest/Assets.xcassets /Volumes/Developer/XcodeBuildMCP/example_projects/iOS/MCPTest/Preview\ Content/Preview\ Assets.xcassets --compile /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Intermediates.noindex/MCPTest.build/Debug-iphonesimulator/MCPTest.build/assetcatalog_output/thinned --output-format human-readable-text --notices --warnings --export-dependency-info /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Intermediates.noindex/MCPTest.build/Debug-iphonesimulator/MCPTest.build/assetcatalog_dependencies_thinned --output-partial-info-plist /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Intermediates.noindex/MCPTest.build/Debug-iphonesimulator/MCPTest.build/assetcatalog_generated_info.plist_thinned --app-icon AppIcon --accent-color AccentColor --compress-pngs --enable-on-demand-resources YES --filter-for-thinning-device-configuration iPhone17,3 --filter-for-device-os-version 18.4 --development-region en --target-device iphone --target-device ipad --minimum-deployment-target 18.2 --platform iphonesimulator
+# /* com.apple.actool.compilation-results */
+# /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Intermediates.noindex/MCPTest.build/Debug-iphonesimulator/MCPTest.build/assetcatalog_generated_info.plist_thinned
+#
+#
+# LinkAssetCatalog /Volumes/Developer/XcodeBuildMCP/example_projects/iOS/MCPTest/Assets.xcassets /Volumes/Developer/XcodeBuildMCP/example_projects/iOS/MCPTest/Preview\ Content/Preview\ Assets.xcassets (in target 'MCPTest' from project 'MCPTest')
+# cd /Volumes/Developer/XcodeBuildMCP/example_projects/iOS
+# builtin-linkAssetCatalog --thinned /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Intermediates.noindex/MCPTest.build/Debug-iphonesimulator/MCPTest.build/assetcatalog_output/thinned --thinned-dependencies /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Intermediates.noindex/MCPTest.build/Debug-iphonesimulator/MCPTest.build/assetcatalog_dependencies_thinned --thinned-info-plist-content /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Intermediates.noindex/MCPTest.build/Debug-iphonesimulator/MCPTest.build/assetcatalog_generated_info.plist_thinned --unthinned /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Intermediates.noindex/MCPTest.build/Debug-iphonesimulator/MCPTest.build/assetcatalog_output/unthinned --unthinned-dependencies /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Intermediates.noindex/MCPTest.build/Debug-iphonesimulator/MCPTest.build/assetcatalog_dependencies_unthinned --unthinned-info-plist-content /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Intermediates.noindex/MCPTest.build/Debug-iphonesimulator/MCPTest.build/assetcatalog_generated_info.plist_unthinned --output /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Products/Debug-iphonesimulator/MCPTest.app --plist-output /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Intermediates.noindex/MCPTest.build/Debug-iphonesimulator/MCPTest.build/assetcatalog_generated_info.plist
+#
+# ProcessInfoPlistFile /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Products/Debug-iphonesimulator/MCPTest.app/Info.plist /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Intermediates.noindex/MCPTest.build/Debug-iphonesimulator/MCPTest.build/empty-MCPTest.plist (in target 'MCPTest' from project 'MCPTest')
+# cd /Volumes/Developer/XcodeBuildMCP/example_projects/iOS
+# builtin-infoPlistUtility /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Intermediates.noindex/MCPTest.build/Debug-iphonesimulator/MCPTest.build/empty-MCPTest.plist -producttype com.apple.product-type.application -genpkginfo /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Products/Debug-iphonesimulator/MCPTest.app/PkgInfo -expandbuildsettings -format binary -platform iphonesimulator -additionalcontentfile /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Intermediates.noindex/MCPTest.build/Debug-iphonesimulator/MCPTest.build/assetcatalog_generated_info.plist -o /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Products/Debug-iphonesimulator/MCPTest.app/Info.plist
+#
+# SwiftDriver MCPTest normal arm64 com.apple.xcode.tools.swift.compiler (in target 'MCPTest' from project 'MCPTest')
+
+/Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Intermediates.noindex/MCPTest.build/Debug-iphonesimulator/MCPTest.build/Objects-normal/arm64/ContentView.o: /Volumes/Developer/XcodeBuildMCP/example_projects/iOS/MCPTest/ContentView.swift
+ cd /Volumes/Developer/XcodeBuildMCP/example_projects/iOS
+ /Applications/Xcode-16.3.0.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/swiftc -module-name MCPTest -Onone -enforce-exclusivity\=checked @/Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Intermediates.noindex/MCPTest.build/Debug-iphonesimulator/MCPTest.build/Objects-normal/arm64/MCPTest.SwiftFileList -DDEBUG -enable-bare-slash-regex -enable-experimental-feature DebugDescriptionMacro -sdk /Applications/Xcode-16.3.0.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator18.4.sdk -target arm64-apple-ios18.2-simulator -g -module-cache-path /Users/cameroncooke/Library/Developer/Xcode/DerivedData/ModuleCache.noindex -Xfrontend -serialize-debugging-options -enable-testing -index-store-path /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Index.noindex/DataStore -swift-version 5 -I /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Products/Debug-iphonesimulator -F /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Products/Debug-iphonesimulator -emit-localized-strings -emit-localized-strings-path /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Intermediates.noindex/MCPTest.build/Debug-iphonesimulator/MCPTest.build/Objects-normal/arm64 -c -j12 -enable-batch-mode -incremental -Xcc -ivfsstatcache -Xcc /Users/cameroncooke/Library/Developer/Xcode/DerivedData/SDKStatCaches.noindex/iphonesimulator18.4-22E235-43e5fd89280df366c77438703b8fa853.sdkstatcache -output-file-map /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Intermediates.noindex/MCPTest.build/Debug-iphonesimulator/MCPTest.build/Objects-normal/arm64/MCPTest-OutputFileMap.json -save-temps -no-color-diagnostics -serialize-diagnostics -emit-dependencies -emit-module -emit-module-path /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Intermediates.noindex/MCPTest.build/Debug-iphonesimulator/MCPTest.build/Objects-normal/arm64/MCPTest.swiftmodule -validate-clang-modules-once -clang-build-session-file /Users/cameroncooke/Library/Developer/Xcode/DerivedData/ModuleCache.noindex/Session.modulevalidation -Xcc -I/Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Intermediates.noindex/MCPTest.build/Debug-iphonesimulator/MCPTest.build/swift-overrides.hmap -emit-const-values -Xfrontend -const-gather-protocols-file -Xfrontend /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Intermediates.noindex/MCPTest.build/Debug-iphonesimulator/MCPTest.build/Objects-normal/arm64/MCPTest_const_extract_protocols.json -Xcc -iquote -Xcc /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Intermediates.noindex/MCPTest.build/Debug-iphonesimulator/MCPTest.build/MCPTest-generated-files.hmap -Xcc -I/Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Intermediates.noindex/MCPTest.build/Debug-iphonesimulator/MCPTest.build/MCPTest-own-target-headers.hmap -Xcc -I/Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Intermediates.noindex/MCPTest.build/Debug-iphonesimulator/MCPTest.build/MCPTest-all-target-headers.hmap -Xcc -iquote -Xcc /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Intermediates.noindex/MCPTest.build/Debug-iphonesimulator/MCPTest.build/MCPTest-project-headers.hmap -Xcc -I/Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Products/Debug-iphonesimulator/include -Xcc -I/Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Intermediates.noindex/MCPTest.build/Debug-iphonesimulator/MCPTest.build/DerivedSources-normal/arm64 -Xcc -I/Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Intermediates.noindex/MCPTest.build/Debug-iphonesimulator/MCPTest.build/DerivedSources/arm64 -Xcc -I/Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Intermediates.noindex/MCPTest.build/Debug-iphonesimulator/MCPTest.build/DerivedSources -Xcc -DDEBUG\=1 -emit-objc-header -emit-objc-header-path /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Intermediates.noindex/MCPTest.build/Debug-iphonesimulator/MCPTest.build/Objects-normal/arm64/MCPTest-Swift.h -working-directory /Volumes/Developer/XcodeBuildMCP/example_projects/iOS -experimental-emit-module-separately -disable-cmo && touch /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Intermediates.noindex/MCPTest.build/Debug-iphonesimulator/MCPTest.build/Objects-normal/arm64/ContentView.o
+
+
+/Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Intermediates.noindex/MCPTest.build/Debug-iphonesimulator/MCPTest.build/Objects-normal/arm64/MCPTestApp.o: /Volumes/Developer/XcodeBuildMCP/example_projects/iOS/MCPTest/MCPTestApp.swift
+ cd /Volumes/Developer/XcodeBuildMCP/example_projects/iOS
+ /Applications/Xcode-16.3.0.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/swiftc -module-name MCPTest -Onone -enforce-exclusivity\=checked @/Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Intermediates.noindex/MCPTest.build/Debug-iphonesimulator/MCPTest.build/Objects-normal/arm64/MCPTest.SwiftFileList -DDEBUG -enable-bare-slash-regex -enable-experimental-feature DebugDescriptionMacro -sdk /Applications/Xcode-16.3.0.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator18.4.sdk -target arm64-apple-ios18.2-simulator -g -module-cache-path /Users/cameroncooke/Library/Developer/Xcode/DerivedData/ModuleCache.noindex -Xfrontend -serialize-debugging-options -enable-testing -index-store-path /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Index.noindex/DataStore -swift-version 5 -I /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Products/Debug-iphonesimulator -F /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Products/Debug-iphonesimulator -emit-localized-strings -emit-localized-strings-path /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Intermediates.noindex/MCPTest.build/Debug-iphonesimulator/MCPTest.build/Objects-normal/arm64 -c -j12 -enable-batch-mode -incremental -Xcc -ivfsstatcache -Xcc /Users/cameroncooke/Library/Developer/Xcode/DerivedData/SDKStatCaches.noindex/iphonesimulator18.4-22E235-43e5fd89280df366c77438703b8fa853.sdkstatcache -output-file-map /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Intermediates.noindex/MCPTest.build/Debug-iphonesimulator/MCPTest.build/Objects-normal/arm64/MCPTest-OutputFileMap.json -save-temps -no-color-diagnostics -serialize-diagnostics -emit-dependencies -emit-module -emit-module-path /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Intermediates.noindex/MCPTest.build/Debug-iphonesimulator/MCPTest.build/Objects-normal/arm64/MCPTest.swiftmodule -validate-clang-modules-once -clang-build-session-file /Users/cameroncooke/Library/Developer/Xcode/DerivedData/ModuleCache.noindex/Session.modulevalidation -Xcc -I/Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Intermediates.noindex/MCPTest.build/Debug-iphonesimulator/MCPTest.build/swift-overrides.hmap -emit-const-values -Xfrontend -const-gather-protocols-file -Xfrontend /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Intermediates.noindex/MCPTest.build/Debug-iphonesimulator/MCPTest.build/Objects-normal/arm64/MCPTest_const_extract_protocols.json -Xcc -iquote -Xcc /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Intermediates.noindex/MCPTest.build/Debug-iphonesimulator/MCPTest.build/MCPTest-generated-files.hmap -Xcc -I/Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Intermediates.noindex/MCPTest.build/Debug-iphonesimulator/MCPTest.build/MCPTest-own-target-headers.hmap -Xcc -I/Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Intermediates.noindex/MCPTest.build/Debug-iphonesimulator/MCPTest.build/MCPTest-all-target-headers.hmap -Xcc -iquote -Xcc /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Intermediates.noindex/MCPTest.build/Debug-iphonesimulator/MCPTest.build/MCPTest-project-headers.hmap -Xcc -I/Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Products/Debug-iphonesimulator/include -Xcc -I/Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Intermediates.noindex/MCPTest.build/Debug-iphonesimulator/MCPTest.build/DerivedSources-normal/arm64 -Xcc -I/Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Intermediates.noindex/MCPTest.build/Debug-iphonesimulator/MCPTest.build/DerivedSources/arm64 -Xcc -I/Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Intermediates.noindex/MCPTest.build/Debug-iphonesimulator/MCPTest.build/DerivedSources -Xcc -DDEBUG\=1 -emit-objc-header -emit-objc-header-path /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Intermediates.noindex/MCPTest.build/Debug-iphonesimulator/MCPTest.build/Objects-normal/arm64/MCPTest-Swift.h -working-directory /Volumes/Developer/XcodeBuildMCP/example_projects/iOS -experimental-emit-module-separately -disable-cmo && touch /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Intermediates.noindex/MCPTest.build/Debug-iphonesimulator/MCPTest.build/Objects-normal/arm64/MCPTestApp.o
+
+
+/Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Intermediates.noindex/MCPTest.build/Debug-iphonesimulator/MCPTest.build/Objects-normal/arm64/GeneratedAssetSymbols.o: /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Intermediates.noindex/MCPTest.build/Debug-iphonesimulator/MCPTest.build/DerivedSources/GeneratedAssetSymbols.swift
+ cd /Volumes/Developer/XcodeBuildMCP/example_projects/iOS
+ /Applications/Xcode-16.3.0.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/swiftc -module-name MCPTest -Onone -enforce-exclusivity\=checked @/Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Intermediates.noindex/MCPTest.build/Debug-iphonesimulator/MCPTest.build/Objects-normal/arm64/MCPTest.SwiftFileList -DDEBUG -enable-bare-slash-regex -enable-experimental-feature DebugDescriptionMacro -sdk /Applications/Xcode-16.3.0.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator18.4.sdk -target arm64-apple-ios18.2-simulator -g -module-cache-path /Users/cameroncooke/Library/Developer/Xcode/DerivedData/ModuleCache.noindex -Xfrontend -serialize-debugging-options -enable-testing -index-store-path /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Index.noindex/DataStore -swift-version 5 -I /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Products/Debug-iphonesimulator -F /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Products/Debug-iphonesimulator -emit-localized-strings -emit-localized-strings-path /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Intermediates.noindex/MCPTest.build/Debug-iphonesimulator/MCPTest.build/Objects-normal/arm64 -c -j12 -enable-batch-mode -incremental -Xcc -ivfsstatcache -Xcc /Users/cameroncooke/Library/Developer/Xcode/DerivedData/SDKStatCaches.noindex/iphonesimulator18.4-22E235-43e5fd89280df366c77438703b8fa853.sdkstatcache -output-file-map /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Intermediates.noindex/MCPTest.build/Debug-iphonesimulator/MCPTest.build/Objects-normal/arm64/MCPTest-OutputFileMap.json -save-temps -no-color-diagnostics -serialize-diagnostics -emit-dependencies -emit-module -emit-module-path /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Intermediates.noindex/MCPTest.build/Debug-iphonesimulator/MCPTest.build/Objects-normal/arm64/MCPTest.swiftmodule -validate-clang-modules-once -clang-build-session-file /Users/cameroncooke/Library/Developer/Xcode/DerivedData/ModuleCache.noindex/Session.modulevalidation -Xcc -I/Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Intermediates.noindex/MCPTest.build/Debug-iphonesimulator/MCPTest.build/swift-overrides.hmap -emit-const-values -Xfrontend -const-gather-protocols-file -Xfrontend /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Intermediates.noindex/MCPTest.build/Debug-iphonesimulator/MCPTest.build/Objects-normal/arm64/MCPTest_const_extract_protocols.json -Xcc -iquote -Xcc /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Intermediates.noindex/MCPTest.build/Debug-iphonesimulator/MCPTest.build/MCPTest-generated-files.hmap -Xcc -I/Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Intermediates.noindex/MCPTest.build/Debug-iphonesimulator/MCPTest.build/MCPTest-own-target-headers.hmap -Xcc -I/Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Intermediates.noindex/MCPTest.build/Debug-iphonesimulator/MCPTest.build/MCPTest-all-target-headers.hmap -Xcc -iquote -Xcc /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Intermediates.noindex/MCPTest.build/Debug-iphonesimulator/MCPTest.build/MCPTest-project-headers.hmap -Xcc -I/Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Products/Debug-iphonesimulator/include -Xcc -I/Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Intermediates.noindex/MCPTest.build/Debug-iphonesimulator/MCPTest.build/DerivedSources-normal/arm64 -Xcc -I/Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Intermediates.noindex/MCPTest.build/Debug-iphonesimulator/MCPTest.build/DerivedSources/arm64 -Xcc -I/Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Intermediates.noindex/MCPTest.build/Debug-iphonesimulator/MCPTest.build/DerivedSources -Xcc -DDEBUG\=1 -emit-objc-header -emit-objc-header-path /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Intermediates.noindex/MCPTest.build/Debug-iphonesimulator/MCPTest.build/Objects-normal/arm64/MCPTest-Swift.h -working-directory /Volumes/Developer/XcodeBuildMCP/example_projects/iOS -experimental-emit-module-separately -disable-cmo && touch /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Intermediates.noindex/MCPTest.build/Debug-iphonesimulator/MCPTest.build/Objects-normal/arm64/GeneratedAssetSymbols.o
+
+#
+# SwiftEmitModule normal arm64 Emitting\ module\ for\ MCPTest (in target 'MCPTest' from project 'MCPTest')
+#
+# EmitSwiftModule normal arm64 (in target 'MCPTest' from project 'MCPTest')
+# cd /Volumes/Developer/XcodeBuildMCP/example_projects/iOS
+#
+#
+# SwiftCompile normal arm64 Compiling\ GeneratedAssetSymbols.swift /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Intermediates.noindex/MCPTest.build/Debug-iphonesimulator/MCPTest.build/DerivedSources/GeneratedAssetSymbols.swift (in target 'MCPTest' from project 'MCPTest')
+# SwiftCompile normal arm64 /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Intermediates.noindex/MCPTest.build/Debug-iphonesimulator/MCPTest.build/DerivedSources/GeneratedAssetSymbols.swift (in target 'MCPTest' from project 'MCPTest')
+#
+# SwiftCompile normal arm64 Compiling\ ContentView.swift /Volumes/Developer/XcodeBuildMCP/example_projects/iOS/MCPTest/ContentView.swift (in target 'MCPTest' from project 'MCPTest')
+# cd /Volumes/Developer/XcodeBuildMCP/example_projects/iOS
+#
+#
+# SwiftCompile normal arm64 Compiling\ MCPTestApp.swift /Volumes/Developer/XcodeBuildMCP/example_projects/iOS/MCPTest/MCPTestApp.swift (in target 'MCPTest' from project 'MCPTest')
+# SwiftCompile normal arm64 /Volumes/Developer/XcodeBuildMCP/example_projects/iOS/MCPTest/MCPTestApp.swift (in target 'MCPTest' from project 'MCPTest')
+#
+# SwiftDriverJobDiscovery normal arm64 Compiling MCPTestApp.swift (in target 'MCPTest' from project 'MCPTest')
+#
+# SwiftDriverJobDiscovery normal arm64 Compiling GeneratedAssetSymbols.swift (in target 'MCPTest' from project 'MCPTest')
+#
+# SwiftDriverJobDiscovery normal arm64 Emitting module for MCPTest (in target 'MCPTest' from project 'MCPTest')
+#
+# SwiftDriver\ Compilation\ Requirements MCPTest normal arm64 com.apple.xcode.tools.swift.compiler (in target 'MCPTest' from project 'MCPTest')
+# cd /Volumes/Developer/XcodeBuildMCP/example_projects/iOS
+# builtin-Swift-Compilation-Requirements -- /Applications/Xcode-16.3.0.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/swiftc -module-name MCPTest -Onone -enforce-exclusivity\=checked @/Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Intermediates.noindex/MCPTest.build/Debug-iphonesimulator/MCPTest.build/Objects-normal/arm64/MCPTest.SwiftFileList -DDEBUG -enable-bare-slash-regex -enable-experimental-feature DebugDescriptionMacro -sdk /Applications/Xcode-16.3.0.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator18.4.sdk -target arm64-apple-ios18.2-simulator -g -module-cache-path /Users/cameroncooke/Library/Developer/Xcode/DerivedData/ModuleCache.noindex -Xfrontend -serialize-debugging-options -enable-testing -index-store-path /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Index.noindex/DataStore -swift-version 5 -I /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Products/Debug-iphonesimulator -F /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Products/Debug-iphonesimulator -emit-localized-strings -emit-localized-strings-path /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Intermediates.noindex/MCPTest.build/Debug-iphonesimulator/MCPTest.build/Objects-normal/arm64 -c -j12 -enable-batch-mode -incremental -Xcc -ivfsstatcache -Xcc /Users/cameroncooke/Library/Developer/Xcode/DerivedData/SDKStatCaches.noindex/iphonesimulator18.4-22E235-43e5fd89280df366c77438703b8fa853.sdkstatcache -output-file-map /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Intermediates.noindex/MCPTest.build/Debug-iphonesimulator/MCPTest.build/Objects-normal/arm64/MCPTest-OutputFileMap.json -use-frontend-parseable-output -save-temps -no-color-diagnostics -serialize-diagnostics -emit-dependencies -emit-module -emit-module-path /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Intermediates.noindex/MCPTest.build/Debug-iphonesimulator/MCPTest.build/Objects-normal/arm64/MCPTest.swiftmodule -validate-clang-modules-once -clang-build-session-file /Users/cameroncooke/Library/Developer/Xcode/DerivedData/ModuleCache.noindex/Session.modulevalidation -Xcc -I/Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Intermediates.noindex/MCPTest.build/Debug-iphonesimulator/MCPTest.build/swift-overrides.hmap -emit-const-values -Xfrontend -const-gather-protocols-file -Xfrontend /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Intermediates.noindex/MCPTest.build/Debug-iphonesimulator/MCPTest.build/Objects-normal/arm64/MCPTest_const_extract_protocols.json -Xcc -iquote -Xcc /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Intermediates.noindex/MCPTest.build/Debug-iphonesimulator/MCPTest.build/MCPTest-generated-files.hmap -Xcc -I/Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Intermediates.noindex/MCPTest.build/Debug-iphonesimulator/MCPTest.build/MCPTest-own-target-headers.hmap -Xcc -I/Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Intermediates.noindex/MCPTest.build/Debug-iphonesimulator/MCPTest.build/MCPTest-all-target-headers.hmap -Xcc -iquote -Xcc /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Intermediates.noindex/MCPTest.build/Debug-iphonesimulator/MCPTest.build/MCPTest-project-headers.hmap -Xcc -I/Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Products/Debug-iphonesimulator/include -Xcc -I/Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Intermediates.noindex/MCPTest.build/Debug-iphonesimulator/MCPTest.build/DerivedSources-normal/arm64 -Xcc -I/Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Intermediates.noindex/MCPTest.build/Debug-iphonesimulator/MCPTest.build/DerivedSources/arm64 -Xcc -I/Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Intermediates.noindex/MCPTest.build/Debug-iphonesimulator/MCPTest.build/DerivedSources -Xcc -DDEBUG\=1 -emit-objc-header -emit-objc-header-path /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Intermediates.noindex/MCPTest.build/Debug-iphonesimulator/MCPTest.build/Objects-normal/arm64/MCPTest-Swift.h -working-directory /Volumes/Developer/XcodeBuildMCP/example_projects/iOS -experimental-emit-module-separately -disable-cmo
+#
+# SwiftMergeGeneratedHeaders /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Intermediates.noindex/MCPTest.build/Debug-iphonesimulator/MCPTest.build/DerivedSources/MCPTest-Swift.h /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Intermediates.noindex/MCPTest.build/Debug-iphonesimulator/MCPTest.build/Objects-normal/arm64/MCPTest-Swift.h (in target 'MCPTest' from project 'MCPTest')
+# cd /Volumes/Developer/XcodeBuildMCP/example_projects/iOS
+# builtin-swiftHeaderTool -arch arm64 /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Intermediates.noindex/MCPTest.build/Debug-iphonesimulator/MCPTest.build/Objects-normal/arm64/MCPTest-Swift.h -o /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Intermediates.noindex/MCPTest.build/Debug-iphonesimulator/MCPTest.build/DerivedSources/MCPTest-Swift.h
+#
+# Copy /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Products/Debug-iphonesimulator/MCPTest.swiftmodule/arm64-apple-ios-simulator.swiftmodule /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Intermediates.noindex/MCPTest.build/Debug-iphonesimulator/MCPTest.build/Objects-normal/arm64/MCPTest.swiftmodule (in target 'MCPTest' from project 'MCPTest')
+# cd /Volumes/Developer/XcodeBuildMCP/example_projects/iOS
+# builtin-copy -exclude .DS_Store -exclude CVS -exclude .svn -exclude .git -exclude .hg -resolve-src-symlinks -rename /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Intermediates.noindex/MCPTest.build/Debug-iphonesimulator/MCPTest.build/Objects-normal/arm64/MCPTest.swiftmodule /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Products/Debug-iphonesimulator/MCPTest.swiftmodule/arm64-apple-ios-simulator.swiftmodule
+#
+# Copy /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Products/Debug-iphonesimulator/MCPTest.swiftmodule/arm64-apple-ios-simulator.swiftdoc /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Intermediates.noindex/MCPTest.build/Debug-iphonesimulator/MCPTest.build/Objects-normal/arm64/MCPTest.swiftdoc (in target 'MCPTest' from project 'MCPTest')
+# cd /Volumes/Developer/XcodeBuildMCP/example_projects/iOS
+# builtin-copy -exclude .DS_Store -exclude CVS -exclude .svn -exclude .git -exclude .hg -resolve-src-symlinks -rename /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Intermediates.noindex/MCPTest.build/Debug-iphonesimulator/MCPTest.build/Objects-normal/arm64/MCPTest.swiftdoc /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Products/Debug-iphonesimulator/MCPTest.swiftmodule/arm64-apple-ios-simulator.swiftdoc
+#
+# Copy /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Products/Debug-iphonesimulator/MCPTest.swiftmodule/arm64-apple-ios-simulator.abi.json /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Intermediates.noindex/MCPTest.build/Debug-iphonesimulator/MCPTest.build/Objects-normal/arm64/MCPTest.abi.json (in target 'MCPTest' from project 'MCPTest')
+# cd /Volumes/Developer/XcodeBuildMCP/example_projects/iOS
+# builtin-copy -exclude .DS_Store -exclude CVS -exclude .svn -exclude .git -exclude .hg -resolve-src-symlinks -rename /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Intermediates.noindex/MCPTest.build/Debug-iphonesimulator/MCPTest.build/Objects-normal/arm64/MCPTest.abi.json /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Products/Debug-iphonesimulator/MCPTest.swiftmodule/arm64-apple-ios-simulator.abi.json
+#
+# Copy /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Products/Debug-iphonesimulator/MCPTest.swiftmodule/Project/arm64-apple-ios-simulator.swiftsourceinfo /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Intermediates.noindex/MCPTest.build/Debug-iphonesimulator/MCPTest.build/Objects-normal/arm64/MCPTest.swiftsourceinfo (in target 'MCPTest' from project 'MCPTest')
+# cd /Volumes/Developer/XcodeBuildMCP/example_projects/iOS
+# builtin-copy -exclude .DS_Store -exclude CVS -exclude .svn -exclude .git -exclude .hg -resolve-src-symlinks -rename /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Intermediates.noindex/MCPTest.build/Debug-iphonesimulator/MCPTest.build/Objects-normal/arm64/MCPTest.swiftsourceinfo /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Products/Debug-iphonesimulator/MCPTest.swiftmodule/Project/arm64-apple-ios-simulator.swiftsourceinfo
+#
+# SwiftDriverJobDiscovery normal arm64 Compiling ContentView.swift (in target 'MCPTest' from project 'MCPTest')
+#
+# SwiftDriver\ Compilation MCPTest normal arm64 com.apple.xcode.tools.swift.compiler (in target 'MCPTest' from project 'MCPTest')
+# cd /Volumes/Developer/XcodeBuildMCP/example_projects/iOS
+# builtin-Swift-Compilation -- /Applications/Xcode-16.3.0.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/swiftc -module-name MCPTest -Onone -enforce-exclusivity\=checked @/Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Intermediates.noindex/MCPTest.build/Debug-iphonesimulator/MCPTest.build/Objects-normal/arm64/MCPTest.SwiftFileList -DDEBUG -enable-bare-slash-regex -enable-experimental-feature DebugDescriptionMacro -sdk /Applications/Xcode-16.3.0.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator18.4.sdk -target arm64-apple-ios18.2-simulator -g -module-cache-path /Users/cameroncooke/Library/Developer/Xcode/DerivedData/ModuleCache.noindex -Xfrontend -serialize-debugging-options -enable-testing -index-store-path /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Index.noindex/DataStore -swift-version 5 -I /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Products/Debug-iphonesimulator -F /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Products/Debug-iphonesimulator -emit-localized-strings -emit-localized-strings-path /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Intermediates.noindex/MCPTest.build/Debug-iphonesimulator/MCPTest.build/Objects-normal/arm64 -c -j12 -enable-batch-mode -incremental -Xcc -ivfsstatcache -Xcc /Users/cameroncooke/Library/Developer/Xcode/DerivedData/SDKStatCaches.noindex/iphonesimulator18.4-22E235-43e5fd89280df366c77438703b8fa853.sdkstatcache -output-file-map /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Intermediates.noindex/MCPTest.build/Debug-iphonesimulator/MCPTest.build/Objects-normal/arm64/MCPTest-OutputFileMap.json -use-frontend-parseable-output -save-temps -no-color-diagnostics -serialize-diagnostics -emit-dependencies -emit-module -emit-module-path /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Intermediates.noindex/MCPTest.build/Debug-iphonesimulator/MCPTest.build/Objects-normal/arm64/MCPTest.swiftmodule -validate-clang-modules-once -clang-build-session-file /Users/cameroncooke/Library/Developer/Xcode/DerivedData/ModuleCache.noindex/Session.modulevalidation -Xcc -I/Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Intermediates.noindex/MCPTest.build/Debug-iphonesimulator/MCPTest.build/swift-overrides.hmap -emit-const-values -Xfrontend -const-gather-protocols-file -Xfrontend /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Intermediates.noindex/MCPTest.build/Debug-iphonesimulator/MCPTest.build/Objects-normal/arm64/MCPTest_const_extract_protocols.json -Xcc -iquote -Xcc /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Intermediates.noindex/MCPTest.build/Debug-iphonesimulator/MCPTest.build/MCPTest-generated-files.hmap -Xcc -I/Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Intermediates.noindex/MCPTest.build/Debug-iphonesimulator/MCPTest.build/MCPTest-own-target-headers.hmap -Xcc -I/Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Intermediates.noindex/MCPTest.build/Debug-iphonesimulator/MCPTest.build/MCPTest-all-target-headers.hmap -Xcc -iquote -Xcc /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Intermediates.noindex/MCPTest.build/Debug-iphonesimulator/MCPTest.build/MCPTest-project-headers.hmap -Xcc -I/Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Products/Debug-iphonesimulator/include -Xcc -I/Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Intermediates.noindex/MCPTest.build/Debug-iphonesimulator/MCPTest.build/DerivedSources-normal/arm64 -Xcc -I/Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Intermediates.noindex/MCPTest.build/Debug-iphonesimulator/MCPTest.build/DerivedSources/arm64 -Xcc -I/Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Intermediates.noindex/MCPTest.build/Debug-iphonesimulator/MCPTest.build/DerivedSources -Xcc -DDEBUG\=1 -emit-objc-header -emit-objc-header-path /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Intermediates.noindex/MCPTest.build/Debug-iphonesimulator/MCPTest.build/Objects-normal/arm64/MCPTest-Swift.h -working-directory /Volumes/Developer/XcodeBuildMCP/example_projects/iOS -experimental-emit-module-separately -disable-cmo
+#
+# Ld /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Products/Debug-iphonesimulator/MCPTest.app/MCPTest.debug.dylib normal (in target 'MCPTest' from project 'MCPTest')
+
+/Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Products/Debug-iphonesimulator/MCPTest.app/MCPTest.debug.dylib: /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Intermediates.noindex/MCPTest.build/Debug-iphonesimulator/MCPTest.build/Objects-normal/arm64/ContentView.o /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Intermediates.noindex/MCPTest.build/Debug-iphonesimulator/MCPTest.build/Objects-normal/arm64/MCPTestApp.o /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Intermediates.noindex/MCPTest.build/Debug-iphonesimulator/MCPTest.build/Objects-normal/arm64/GeneratedAssetSymbols.o
+ cd /Volumes/Developer/XcodeBuildMCP/example_projects/iOS
+ /Applications/Xcode-16.3.0.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang -Xlinker -reproducible -target arm64-apple-ios18.2-simulator -dynamiclib -isysroot /Applications/Xcode-16.3.0.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator18.4.sdk -O0 -L/Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Intermediates.noindex/EagerLinkingTBDs/Debug-iphonesimulator -L/Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Products/Debug-iphonesimulator -F/Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Intermediates.noindex/EagerLinkingTBDs/Debug-iphonesimulator -F/Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Products/Debug-iphonesimulator -filelist /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Intermediates.noindex/MCPTest.build/Debug-iphonesimulator/MCPTest.build/Objects-normal/arm64/MCPTest.LinkFileList -install_name @rpath/MCPTest.debug.dylib -Xlinker -rpath -Xlinker @executable_path/Frameworks -dead_strip -Xlinker -object_path_lto -Xlinker /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Intermediates.noindex/MCPTest.build/Debug-iphonesimulator/MCPTest.build/Objects-normal/arm64/MCPTest_lto.o -rdynamic -Xlinker -no_deduplicate -Xlinker -objc_abi_version -Xlinker 2 -Xlinker -dependency_info -Xlinker /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Intermediates.noindex/MCPTest.build/Debug-iphonesimulator/MCPTest.build/Objects-normal/arm64/MCPTest_dependency_info.dat -fobjc-link-runtime -L/Applications/Xcode-16.3.0.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/swift/iphonesimulator -L/usr/lib/swift -Xlinker -add_ast_path -Xlinker /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Intermediates.noindex/MCPTest.build/Debug-iphonesimulator/MCPTest.build/Objects-normal/arm64/MCPTest.swiftmodule -Xlinker -alias -Xlinker _main -Xlinker ___debug_main_executable_dylib_entry_point -Xlinker -no_adhoc_codesign -o /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Products/Debug-iphonesimulator/MCPTest.app/MCPTest.debug.dylib
+
+#
+# ConstructStubExecutorLinkFileList /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Intermediates.noindex/MCPTest.build/Debug-iphonesimulator/MCPTest.build/MCPTest-ExecutorLinkFileList-normal-arm64.txt (in target 'MCPTest' from project 'MCPTest')
+# cd /Volumes/Developer/XcodeBuildMCP/example_projects/iOS
+# construct-stub-executor-link-file-list /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Products/Debug-iphonesimulator/MCPTest.app/MCPTest.debug.dylib /Applications/Xcode-16.3.0.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/usr/lib/libPreviewsJITStubExecutor_no_swift_entry_point.a /Applications/Xcode-16.3.0.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/usr/lib/libPreviewsJITStubExecutor.a --output /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Intermediates.noindex/MCPTest.build/Debug-iphonesimulator/MCPTest.build/MCPTest-ExecutorLinkFileList-normal-arm64.txt
+# note: Using stub executor library with Swift entry point. (in target 'MCPTest' from project 'MCPTest')
+#
+# Ld /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Products/Debug-iphonesimulator/MCPTest.app/MCPTest normal (in target 'MCPTest' from project 'MCPTest')
+
+/Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Products/Debug-iphonesimulator/MCPTest.app/MCPTest:
+ cd /Volumes/Developer/XcodeBuildMCP/example_projects/iOS
+ /Applications/Xcode-16.3.0.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang -Xlinker -reproducible -target arm64-apple-ios18.2-simulator -isysroot /Applications/Xcode-16.3.0.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator18.4.sdk -O0 -L/Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Products/Debug-iphonesimulator -F/Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Products/Debug-iphonesimulator -Xlinker -rpath -Xlinker @executable_path -Xlinker -rpath -Xlinker @executable_path/Frameworks -rdynamic -Xlinker -no_deduplicate -Xlinker -objc_abi_version -Xlinker 2 -e ___debug_blank_executor_main -Xlinker -sectcreate -Xlinker __TEXT -Xlinker __debug_dylib -Xlinker /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Intermediates.noindex/MCPTest.build/Debug-iphonesimulator/MCPTest.build/MCPTest-DebugDylibPath-normal-arm64.txt -Xlinker -sectcreate -Xlinker __TEXT -Xlinker __debug_instlnm -Xlinker /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Intermediates.noindex/MCPTest.build/Debug-iphonesimulator/MCPTest.build/MCPTest-DebugDylibInstallName-normal-arm64.txt -Xlinker -filelist -Xlinker /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Intermediates.noindex/MCPTest.build/Debug-iphonesimulator/MCPTest.build/MCPTest-ExecutorLinkFileList-normal-arm64.txt -Xlinker -sectcreate -Xlinker __TEXT -Xlinker __entitlements -Xlinker /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Intermediates.noindex/MCPTest.build/Debug-iphonesimulator/MCPTest.build/MCPTest.app-Simulated.xcent -Xlinker -sectcreate -Xlinker __TEXT -Xlinker __ents_der -Xlinker /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Intermediates.noindex/MCPTest.build/Debug-iphonesimulator/MCPTest.build/MCPTest.app-Simulated.xcent.der /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Products/Debug-iphonesimulator/MCPTest.app/MCPTest.debug.dylib -Xlinker -no_adhoc_codesign -o /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Products/Debug-iphonesimulator/MCPTest.app/MCPTest
+
+#
+# ExtractAppIntentsMetadata (in target 'MCPTest' from project 'MCPTest')
+# cd /Volumes/Developer/XcodeBuildMCP/example_projects/iOS
+# /Applications/Xcode-16.3.0.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/appintentsmetadataprocessor --toolchain-dir /Applications/Xcode-16.3.0.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain --module-name MCPTest --sdk-root /Applications/Xcode-16.3.0.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator18.4.sdk --xcode-version 16E140 --platform-family iOS --deployment-target 18.2 --bundle-identifier com.cameroncooke.MCPTest --output /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Products/Debug-iphonesimulator/MCPTest.app --target-triple arm64-apple-ios18.2-simulator --binary-file /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Products/Debug-iphonesimulator/MCPTest.app/MCPTest --dependency-file /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Intermediates.noindex/MCPTest.build/Debug-iphonesimulator/MCPTest.build/Objects-normal/arm64/MCPTest_dependency_info.dat --stringsdata-file /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Intermediates.noindex/MCPTest.build/Debug-iphonesimulator/MCPTest.build/Objects-normal/arm64/ExtractedAppShortcutsMetadata.stringsdata --source-file-list /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Intermediates.noindex/MCPTest.build/Debug-iphonesimulator/MCPTest.build/Objects-normal/arm64/MCPTest.SwiftFileList --metadata-file-list /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Intermediates.noindex/MCPTest.build/Debug-iphonesimulator/MCPTest.build/MCPTest.DependencyMetadataFileList --static-metadata-file-list /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Intermediates.noindex/MCPTest.build/Debug-iphonesimulator/MCPTest.build/MCPTest.DependencyStaticMetadataFileList --swift-const-vals-list /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Intermediates.noindex/MCPTest.build/Debug-iphonesimulator/MCPTest.build/Objects-normal/arm64/MCPTest.SwiftConstValuesFileList --compile-time-extraction --deployment-aware-processing --validate-assistant-intents --no-app-shortcuts-localization
+# 2025-05-07 23:04:17.933 appintentsmetadataprocessor[91964:6376835] Starting appintentsmetadataprocessor export
+# 2025-05-07 23:04:17.934 appintentsmetadataprocessor[91964:6376835] warning: Metadata extraction skipped. No AppIntents.framework dependency found.
+#
+# CopySwiftLibs /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Products/Debug-iphonesimulator/MCPTest.app (in target 'MCPTest' from project 'MCPTest')
+# cd /Volumes/Developer/XcodeBuildMCP/example_projects/iOS
+# builtin-swiftStdLibTool --copy --verbose --sign - --scan-executable /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Products/Debug-iphonesimulator/MCPTest.app/MCPTest.debug.dylib --scan-folder /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Products/Debug-iphonesimulator/MCPTest.app/Frameworks --scan-folder /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Products/Debug-iphonesimulator/MCPTest.app/PlugIns --scan-folder /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Products/Debug-iphonesimulator/MCPTest.app/SystemExtensions --scan-folder /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Products/Debug-iphonesimulator/MCPTest.app/Extensions --platform iphonesimulator --toolchain /Applications/Xcode-16.3.0.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain --destination /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Products/Debug-iphonesimulator/MCPTest.app/Frameworks --strip-bitcode --strip-bitcode-tool /Applications/Xcode-16.3.0.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/bitcode_strip --emit-dependency-info /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Intermediates.noindex/MCPTest.build/Debug-iphonesimulator/MCPTest.build/SwiftStdLibToolInputDependencies.dep --filter-for-swift-os
+#
+# AppIntentsSSUTraining (in target 'MCPTest' from project 'MCPTest')
+# cd /Volumes/Developer/XcodeBuildMCP/example_projects/iOS
+# /Applications/Xcode-16.3.0.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/appintentsnltrainingprocessor --infoplist-path /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Products/Debug-iphonesimulator/MCPTest.app/Info.plist --temp-dir-path /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Intermediates.noindex/MCPTest.build/Debug-iphonesimulator/MCPTest.build/ssu --bundle-id com.cameroncooke.MCPTest --product-path /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Products/Debug-iphonesimulator/MCPTest.app --extracted-metadata-path /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Products/Debug-iphonesimulator/MCPTest.app/Metadata.appintents --metadata-file-list /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Intermediates.noindex/MCPTest.build/Debug-iphonesimulator/MCPTest.build/MCPTest.DependencyMetadataFileList --archive-ssu-assets
+# 2025-05-07 23:04:17.943 appintentsnltrainingprocessor[91965:6376836] Parsing options for appintentsnltrainingprocessor
+# 2025-05-07 23:04:17.943 appintentsnltrainingprocessor[91965:6376836] No AppShortcuts found - Skipping.
+#
+# CodeSign /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Products/Debug-iphonesimulator/MCPTest.app/MCPTest.debug.dylib (in target 'MCPTest' from project 'MCPTest')
+# cd /Volumes/Developer/XcodeBuildMCP/example_projects/iOS
+#
+# Signing Identity: "Sign to Run Locally"
+#
+# /usr/bin/codesign --force --sign - --timestamp\=none --generate-entitlement-der /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Products/Debug-iphonesimulator/MCPTest.app/MCPTest.debug.dylib
+#
+# CodeSign /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Products/Debug-iphonesimulator/MCPTest.app/__preview.dylib (in target 'MCPTest' from project 'MCPTest')
+# cd /Volumes/Developer/XcodeBuildMCP/example_projects/iOS
+#
+# Signing Identity: "Sign to Run Locally"
+#
+# /usr/bin/codesign --force --sign - --timestamp\=none --generate-entitlement-der /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Products/Debug-iphonesimulator/MCPTest.app/__preview.dylib
+#
+# CodeSign /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Products/Debug-iphonesimulator/MCPTest.app (in target 'MCPTest' from project 'MCPTest')
+# cd /Volumes/Developer/XcodeBuildMCP/example_projects/iOS
+#
+# Signing Identity: "Sign to Run Locally"
+#
+# /usr/bin/codesign --force --sign - --timestamp\=none --generate-entitlement-der /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Products/Debug-iphonesimulator/MCPTest.app
+#
+# RegisterExecutionPolicyException /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Products/Debug-iphonesimulator/MCPTest.app (in target 'MCPTest' from project 'MCPTest')
+# cd /Volumes/Developer/XcodeBuildMCP/example_projects/iOS
+# builtin-RegisterExecutionPolicyException /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Products/Debug-iphonesimulator/MCPTest.app
+#
+# Validate /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Products/Debug-iphonesimulator/MCPTest.app (in target 'MCPTest' from project 'MCPTest')
+# cd /Volumes/Developer/XcodeBuildMCP/example_projects/iOS
+# builtin-validationUtility /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Products/Debug-iphonesimulator/MCPTest.app -infoplist-subpath Info.plist
+#
+# Touch /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Products/Debug-iphonesimulator/MCPTest.app (in target 'MCPTest' from project 'MCPTest')
+# cd /Volumes/Developer/XcodeBuildMCP/example_projects/iOS
+# /usr/bin/touch -c /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Products/Debug-iphonesimulator/MCPTest.app
+#
+# ** BUILD SUCCEEDED **
+#
+main: /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Products/Debug-iphonesimulator/MCPTest.app/__preview.dylib /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Products/Debug-iphonesimulator/MCPTest.app/MCPTest.debug.dylib /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Products/Debug-iphonesimulator/MCPTest.app/MCPTest
+ /usr/bin/codesign --force --sign - --timestamp\=none --generate-entitlement-der /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Products/Debug-iphonesimulator/MCPTest.app/MCPTest.debug.dylib
+ /usr/bin/codesign --force --sign - --timestamp\=none --generate-entitlement-der /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Products/Debug-iphonesimulator/MCPTest.app/__preview.dylib
+ /usr/bin/codesign --force --sign - --timestamp\=none --generate-entitlement-der /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Products/Debug-iphonesimulator/MCPTest.app
+ /usr/bin/touch -c /Users/cameroncooke/Library/Developer/Xcode/DerivedData/MCPTest-cjyizjpxebssczdhiklwkshchxpo/Build/Products/Debug-iphonesimulator/MCPTest.app
diff --git a/example_projects/iOS_Calculator/.gitignore b/example_projects/iOS_Calculator/.gitignore
new file mode 100644
index 00000000..ad146c76
--- /dev/null
+++ b/example_projects/iOS_Calculator/.gitignore
@@ -0,0 +1,7 @@
+
+# xcode-build-server files
+buildServer.json
+.compile
+
+# Local build artifacts
+.build/
diff --git a/example_projects/iOS_Calculator/CalculatorApp.xcodeproj/project.pbxproj b/example_projects/iOS_Calculator/CalculatorApp.xcodeproj/project.pbxproj
new file mode 100644
index 00000000..029a697a
--- /dev/null
+++ b/example_projects/iOS_Calculator/CalculatorApp.xcodeproj/project.pbxproj
@@ -0,0 +1,491 @@
+// !$*UTF8*$!
+{
+ archiveVersion = 1;
+ classes = {
+ };
+ objectVersion = 71;
+ objects = {
+
+/* Begin PBXBuildFile section */
+ 8B90933D2DF242EC008F026A /* CalculatorAppFeature in Frameworks */ = {isa = PBXBuildFile; productRef = 8B90933C2DF242EC008F026A /* CalculatorAppFeature */; };
+ 8B90936A2DF24868008F026A /* CalculatorAppFeature in Frameworks */ = {isa = PBXBuildFile; productRef = 8B9093692DF24868008F026A /* CalculatorAppFeature */; };
+/* End PBXBuildFile section */
+
+/* Begin PBXContainerItemProxy section */
+ 8B9093542DF246C0008F026A /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 8B41F63D2DEDD0D5001A66F9 /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = 8B41F6442DEDD0D5001A66F9;
+ remoteInfo = CalculatorApp;
+ };
+/* End PBXContainerItemProxy section */
+
+/* Begin PBXFileReference section */
+ 8B41F6452DEDD0D5001A66F9 /* CalculatorApp.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = CalculatorApp.app; sourceTree = BUILT_PRODUCTS_DIR; };
+ 8B41F65C2DEDD0D6001A66F9 /* TestingExampleApp.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = TestingExampleApp.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
+ 8B9093502DF246C0008F026A /* CalculatorAppTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = CalculatorAppTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
+/* End PBXFileReference section */
+
+/* Begin PBXFileSystemSynchronizedBuildFileExceptionSet section */
+ 8BD71C0A2DEE41E000CEDD92 /* PBXFileSystemSynchronizedBuildFileExceptionSet */ = {
+ isa = PBXFileSystemSynchronizedBuildFileExceptionSet;
+ membershipExceptions = (
+ Debug.xcconfig,
+ Release.xcconfig,
+ Shared.xcconfig,
+ Tests.xcconfig,
+ );
+ target = 8B41F6442DEDD0D5001A66F9 /* CalculatorApp */;
+ };
+/* End PBXFileSystemSynchronizedBuildFileExceptionSet section */
+
+/* Begin PBXFileSystemSynchronizedRootGroup section */
+ 8B41F6472DEDD0D5001A66F9 /* CalculatorApp */ = {isa = PBXFileSystemSynchronizedRootGroup; explicitFileTypes = {}; explicitFolders = (); path = CalculatorApp; sourceTree = ""; };
+ 8B9093512DF246C0008F026A /* CalculatorAppTests */ = {isa = PBXFileSystemSynchronizedRootGroup; explicitFileTypes = {}; explicitFolders = (); path = CalculatorAppTests; sourceTree = ""; };
+ 8BD71C052DEE41D800CEDD92 /* Config */ = {isa = PBXFileSystemSynchronizedRootGroup; exceptions = (8BD71C0A2DEE41E000CEDD92 /* PBXFileSystemSynchronizedBuildFileExceptionSet */, ); explicitFileTypes = {}; explicitFolders = (); path = Config; sourceTree = ""; };
+/* End PBXFileSystemSynchronizedRootGroup section */
+
+/* Begin PBXFrameworksBuildPhase section */
+ 8B41F6422DEDD0D5001A66F9 /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 8B90933D2DF242EC008F026A /* CalculatorAppFeature in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ 8B90934D2DF246C0008F026A /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 8B90936A2DF24868008F026A /* CalculatorAppFeature in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXFrameworksBuildPhase section */
+
+/* Begin PBXGroup section */
+ 8B41F63C2DEDD0D5001A66F9 = {
+ isa = PBXGroup;
+ children = (
+ 8BD71C052DEE41D800CEDD92 /* Config */,
+ 8B41F6472DEDD0D5001A66F9 /* CalculatorApp */,
+ 8B9093512DF246C0008F026A /* CalculatorAppTests */,
+ 8B41F6812DEDD23B001A66F9 /* Frameworks */,
+ 8B41F6462DEDD0D5001A66F9 /* Products */,
+ );
+ sourceTree = "";
+ };
+ 8B41F6462DEDD0D5001A66F9 /* Products */ = {
+ isa = PBXGroup;
+ children = (
+ 8B41F6452DEDD0D5001A66F9 /* CalculatorApp.app */,
+ 8B41F65C2DEDD0D6001A66F9 /* TestingExampleApp.xctest */,
+ 8B9093502DF246C0008F026A /* CalculatorAppTests.xctest */,
+ );
+ name = Products;
+ sourceTree = "";
+ };
+ 8B41F6812DEDD23B001A66F9 /* Frameworks */ = {
+ isa = PBXGroup;
+ children = (
+ );
+ name = Frameworks;
+ sourceTree = "";
+ };
+/* End PBXGroup section */
+
+/* Begin PBXNativeTarget section */
+ 8B41F6442DEDD0D5001A66F9 /* CalculatorApp */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = 8B41F6662DEDD0D6001A66F9 /* Build configuration list for PBXNativeTarget "CalculatorApp" */;
+ buildPhases = (
+ 8B41F6412DEDD0D5001A66F9 /* Sources */,
+ 8B41F6422DEDD0D5001A66F9 /* Frameworks */,
+ 8B41F6432DEDD0D5001A66F9 /* Resources */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ fileSystemSynchronizedGroups = (
+ 8B41F6472DEDD0D5001A66F9 /* CalculatorApp */,
+ 8BD71C052DEE41D800CEDD92 /* Config */,
+ );
+ name = CalculatorApp;
+ packageProductDependencies = (
+ 8B90933C2DF242EC008F026A /* CalculatorAppFeature */,
+ );
+ productName = TestingExampleApp;
+ productReference = 8B41F6452DEDD0D5001A66F9 /* CalculatorApp.app */;
+ productType = "com.apple.product-type.application";
+ };
+ 8B90934F2DF246C0008F026A /* CalculatorAppTests */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = 8B9093582DF246C0008F026A /* Build configuration list for PBXNativeTarget "CalculatorAppTests" */;
+ buildPhases = (
+ 8B90934C2DF246C0008F026A /* Sources */,
+ 8B90934D2DF246C0008F026A /* Frameworks */,
+ 8B90934E2DF246C0008F026A /* Resources */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ 8B9093552DF246C0008F026A /* PBXTargetDependency */,
+ );
+ fileSystemSynchronizedGroups = (
+ 8B9093512DF246C0008F026A /* CalculatorAppTests */,
+ );
+ name = CalculatorAppTests;
+ packageProductDependencies = (
+ 8B9093692DF24868008F026A /* CalculatorAppFeature */,
+ );
+ productName = CalculatorAppTests;
+ productReference = 8B9093502DF246C0008F026A /* CalculatorAppTests.xctest */;
+ productType = "com.apple.product-type.bundle.unit-test";
+ };
+/* End PBXNativeTarget section */
+
+/* Begin PBXProject section */
+ 8B41F63D2DEDD0D5001A66F9 /* Project object */ = {
+ isa = PBXProject;
+ attributes = {
+ BuildIndependentTargetsInParallel = 1;
+ LastSwiftUpdateCheck = 1540;
+ LastUpgradeCheck = 1540;
+ TargetAttributes = {
+ 8B41F6442DEDD0D5001A66F9 = {
+ CreatedOnToolsVersion = 15.4;
+ };
+ 8B90934F2DF246C0008F026A = {
+ CreatedOnToolsVersion = 15.4;
+ TestTargetID = 8B41F6442DEDD0D5001A66F9;
+ };
+ };
+ };
+ buildConfigurationList = 8B41F6402DEDD0D5001A66F9 /* Build configuration list for PBXProject "CalculatorApp" */;
+ compatibilityVersion = "Xcode 14.0";
+ developmentRegion = en;
+ hasScannedForEncodings = 0;
+ knownRegions = (
+ en,
+ Base,
+ );
+ mainGroup = 8B41F63C2DEDD0D5001A66F9;
+ minimizedProjectReferenceProxies = 1;
+ productRefGroup = 8B41F6462DEDD0D5001A66F9 /* Products */;
+ projectDirPath = "";
+ projectRoot = "";
+ targets = (
+ 8B41F6442DEDD0D5001A66F9 /* CalculatorApp */,
+ 8B90934F2DF246C0008F026A /* CalculatorAppTests */,
+ );
+ };
+/* End PBXProject section */
+
+/* Begin PBXResourcesBuildPhase section */
+ 8B41F6432DEDD0D5001A66F9 /* Resources */ = {
+ isa = PBXResourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ 8B90934E2DF246C0008F026A /* Resources */ = {
+ isa = PBXResourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXResourcesBuildPhase section */
+
+/* Begin PBXSourcesBuildPhase section */
+ 8B41F6412DEDD0D5001A66F9 /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ 8B90934C2DF246C0008F026A /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXSourcesBuildPhase section */
+
+/* Begin PBXTargetDependency section */
+ 8B9093552DF246C0008F026A /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = 8B41F6442DEDD0D5001A66F9 /* CalculatorApp */;
+ targetProxy = 8B9093542DF246C0008F026A /* PBXContainerItemProxy */;
+ };
+/* End PBXTargetDependency section */
+
+/* Begin XCBuildConfiguration section */
+ 8B41F6642DEDD0D6001A66F9 /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
+ CLANG_ANALYZER_NONNULL = YES;
+ CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
+ CLANG_ENABLE_MODULES = YES;
+ CLANG_ENABLE_OBJC_ARC = YES;
+ CLANG_ENABLE_OBJC_WEAK = YES;
+ CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
+ CLANG_WARN_BOOL_CONVERSION = YES;
+ CLANG_WARN_COMMA = YES;
+ CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
+ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+ CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
+ CLANG_WARN_EMPTY_BODY = YES;
+ CLANG_WARN_ENUM_CONVERSION = YES;
+ CLANG_WARN_INFINITE_RECURSION = YES;
+ CLANG_WARN_INT_CONVERSION = YES;
+ CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
+ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
+ CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
+ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+ CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
+ CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
+ CLANG_WARN_STRICT_PROTOTYPES = YES;
+ CLANG_WARN_SUSPICIOUS_MOVE = YES;
+ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
+ CLANG_WARN_UNREACHABLE_CODE = YES;
+ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+ COPY_PHASE_STRIP = NO;
+ DEBUG_INFORMATION_FORMAT = dwarf;
+ ENABLE_STRICT_OBJC_MSGSEND = YES;
+ ENABLE_TESTABILITY = YES;
+ ENABLE_USER_SCRIPT_SANDBOXING = YES;
+ GCC_C_LANGUAGE_STANDARD = gnu17;
+ GCC_DYNAMIC_NO_PIC = NO;
+ GCC_NO_COMMON_BLOCKS = YES;
+ GCC_OPTIMIZATION_LEVEL = 0;
+ GCC_PREPROCESSOR_DEFINITIONS = (
+ "DEBUG=1",
+ "$(inherited)",
+ );
+ GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+ GCC_WARN_UNDECLARED_SELECTOR = YES;
+ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+ GCC_WARN_UNUSED_FUNCTION = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ IPHONEOS_DEPLOYMENT_TARGET = 17.0;
+ LOCALIZATION_PREFERS_STRING_CATALOGS = YES;
+ MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
+ MTL_FAST_MATH = YES;
+ ONLY_ACTIVE_ARCH = YES;
+ SDKROOT = iphoneos;
+ SWIFT_ACTIVE_COMPILATION_CONDITIONS = "DEBUG $(inherited)";
+ SWIFT_OPTIMIZATION_LEVEL = "-Onone";
+ SWIFT_VERSION = 5.0;
+ };
+ name = Debug;
+ };
+ 8B41F6652DEDD0D6001A66F9 /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
+ CLANG_ANALYZER_NONNULL = YES;
+ CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
+ CLANG_ENABLE_MODULES = YES;
+ CLANG_ENABLE_OBJC_ARC = YES;
+ CLANG_ENABLE_OBJC_WEAK = YES;
+ CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
+ CLANG_WARN_BOOL_CONVERSION = YES;
+ CLANG_WARN_COMMA = YES;
+ CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
+ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+ CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
+ CLANG_WARN_EMPTY_BODY = YES;
+ CLANG_WARN_ENUM_CONVERSION = YES;
+ CLANG_WARN_INFINITE_RECURSION = YES;
+ CLANG_WARN_INT_CONVERSION = YES;
+ CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
+ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
+ CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
+ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+ CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
+ CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
+ CLANG_WARN_STRICT_PROTOTYPES = YES;
+ CLANG_WARN_SUSPICIOUS_MOVE = YES;
+ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
+ CLANG_WARN_UNREACHABLE_CODE = YES;
+ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+ COPY_PHASE_STRIP = NO;
+ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+ ENABLE_NS_ASSERTIONS = NO;
+ ENABLE_STRICT_OBJC_MSGSEND = YES;
+ ENABLE_USER_SCRIPT_SANDBOXING = YES;
+ GCC_C_LANGUAGE_STANDARD = gnu17;
+ GCC_NO_COMMON_BLOCKS = YES;
+ GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+ GCC_WARN_UNDECLARED_SELECTOR = YES;
+ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+ GCC_WARN_UNUSED_FUNCTION = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ IPHONEOS_DEPLOYMENT_TARGET = 17.0;
+ LOCALIZATION_PREFERS_STRING_CATALOGS = YES;
+ MTL_ENABLE_DEBUG_INFO = NO;
+ MTL_FAST_MATH = YES;
+ SDKROOT = iphoneos;
+ SWIFT_COMPILATION_MODE = wholemodule;
+ SWIFT_VERSION = 5.0;
+ VALIDATE_PRODUCT = YES;
+ };
+ name = Release;
+ };
+ 8B41F6672DEDD0D6001A66F9 /* Debug */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReferenceAnchor = 8BD71C052DEE41D800CEDD92 /* Config */;
+ baseConfigurationReferenceRelativePath = Debug.xcconfig;
+ buildSettings = {
+ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
+ ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
+ CODE_SIGN_IDENTITY = "Apple Development";
+ CODE_SIGN_STYLE = Automatic;
+ DEVELOPMENT_TEAM = BR6WD3M6ZD;
+ ENABLE_PREVIEWS = YES;
+ GENERATE_INFOPLIST_FILE = YES;
+ INFOPLIST_KEY_CFBundleDisplayName = "$(PRODUCT_DISPLAY_NAME)";
+ INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES;
+ INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES;
+ INFOPLIST_KEY_UILaunchScreen_Generation = YES;
+ LD_RUNPATH_SEARCH_PATHS = (
+ "$(inherited)",
+ "@executable_path/Frameworks",
+ );
+ PRODUCT_NAME = CalculatorApp;
+ PROVISIONING_PROFILE_SPECIFIER = "";
+ SWIFT_EMIT_LOC_STRINGS = YES;
+ SWIFT_VERSION = 5.0;
+ };
+ name = Debug;
+ };
+ 8B41F6682DEDD0D6001A66F9 /* Release */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReferenceAnchor = 8BD71C052DEE41D800CEDD92 /* Config */;
+ baseConfigurationReferenceRelativePath = Release.xcconfig;
+ buildSettings = {
+ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
+ ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
+ CODE_SIGN_IDENTITY = "Apple Development";
+ CODE_SIGN_STYLE = Automatic;
+ DEVELOPMENT_TEAM = BR6WD3M6ZD;
+ ENABLE_PREVIEWS = YES;
+ GENERATE_INFOPLIST_FILE = YES;
+ INFOPLIST_KEY_CFBundleDisplayName = "$(PRODUCT_DISPLAY_NAME)";
+ INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES;
+ INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES;
+ INFOPLIST_KEY_UILaunchScreen_Generation = YES;
+ LD_RUNPATH_SEARCH_PATHS = (
+ "$(inherited)",
+ "@executable_path/Frameworks",
+ );
+ PRODUCT_NAME = CalculatorApp;
+ PROVISIONING_PROFILE_SPECIFIER = "";
+ SWIFT_EMIT_LOC_STRINGS = YES;
+ SWIFT_VERSION = 5.0;
+ TARGETED_DEVICE_FAMILY = "1,2";
+ TEST_TARGET_NAME = TestingExampleApp;
+ };
+ name = Release;
+ };
+ 8B9093562DF246C0008F026A /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ BUNDLE_LOADER = "$(TEST_HOST)";
+ CODE_SIGN_IDENTITY = "Apple Development";
+ CODE_SIGN_STYLE = Automatic;
+ CURRENT_PROJECT_VERSION = 1;
+ DEVELOPMENT_TEAM = BR6WD3M6ZD;
+ GENERATE_INFOPLIST_FILE = YES;
+ MARKETING_VERSION = 1.0;
+ PRODUCT_BUNDLE_IDENTIFIER = com.mycompany.CalculatorAppTests;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ PROVISIONING_PROFILE_SPECIFIER = "";
+ SWIFT_EMIT_LOC_STRINGS = NO;
+ SWIFT_VERSION = 5.0;
+ TARGETED_DEVICE_FAMILY = "1,2";
+ TEST_HOST = "$(BUILT_PRODUCTS_DIR)/CalculatorApp.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/CalculatorApp";
+ };
+ name = Debug;
+ };
+ 8B9093572DF246C0008F026A /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ BUNDLE_LOADER = "$(TEST_HOST)";
+ CODE_SIGN_IDENTITY = "Apple Development";
+ CODE_SIGN_STYLE = Automatic;
+ CURRENT_PROJECT_VERSION = 1;
+ DEVELOPMENT_TEAM = BR6WD3M6ZD;
+ GENERATE_INFOPLIST_FILE = YES;
+ MARKETING_VERSION = 1.0;
+ PRODUCT_BUNDLE_IDENTIFIER = com.mycompany.CalculatorAppTests;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ PROVISIONING_PROFILE_SPECIFIER = "";
+ SWIFT_EMIT_LOC_STRINGS = NO;
+ SWIFT_VERSION = 5.0;
+ TARGETED_DEVICE_FAMILY = "1,2";
+ TEST_HOST = "$(BUILT_PRODUCTS_DIR)/CalculatorApp.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/CalculatorApp";
+ };
+ name = Release;
+ };
+/* End XCBuildConfiguration section */
+
+/* Begin XCConfigurationList section */
+ 8B41F6402DEDD0D5001A66F9 /* Build configuration list for PBXProject "CalculatorApp" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 8B41F6642DEDD0D6001A66F9 /* Debug */,
+ 8B41F6652DEDD0D6001A66F9 /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ 8B41F6662DEDD0D6001A66F9 /* Build configuration list for PBXNativeTarget "CalculatorApp" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 8B41F6672DEDD0D6001A66F9 /* Debug */,
+ 8B41F6682DEDD0D6001A66F9 /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ 8B9093582DF246C0008F026A /* Build configuration list for PBXNativeTarget "CalculatorAppTests" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 8B9093562DF246C0008F026A /* Debug */,
+ 8B9093572DF246C0008F026A /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+/* End XCConfigurationList section */
+
+/* Begin XCSwiftPackageProductDependency section */
+ 8B90933C2DF242EC008F026A /* CalculatorAppFeature */ = {
+ isa = XCSwiftPackageProductDependency;
+ productName = CalculatorAppFeature;
+ };
+ 8B9093692DF24868008F026A /* CalculatorAppFeature */ = {
+ isa = XCSwiftPackageProductDependency;
+ productName = CalculatorAppFeature;
+ };
+/* End XCSwiftPackageProductDependency section */
+ };
+ rootObject = 8B41F63D2DEDD0D5001A66F9 /* Project object */;
+}
diff --git a/example_projects/iOS_Calculator/CalculatorApp.xcodeproj/xcshareddata/xcschemes/CalculatorApp.xcscheme b/example_projects/iOS_Calculator/CalculatorApp.xcodeproj/xcshareddata/xcschemes/CalculatorApp.xcscheme
new file mode 100644
index 00000000..73f59940
--- /dev/null
+++ b/example_projects/iOS_Calculator/CalculatorApp.xcodeproj/xcshareddata/xcschemes/CalculatorApp.xcscheme
@@ -0,0 +1,96 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/example_projects/iOS_Calculator/CalculatorApp.xcworkspace/contents.xcworkspacedata b/example_projects/iOS_Calculator/CalculatorApp.xcworkspace/contents.xcworkspacedata
new file mode 100644
index 00000000..9157602c
--- /dev/null
+++ b/example_projects/iOS_Calculator/CalculatorApp.xcworkspace/contents.xcworkspacedata
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
diff --git a/example_projects/iOS_Calculator/CalculatorApp/Assets.xcassets/AccentColor.colorset/Contents.json b/example_projects/iOS_Calculator/CalculatorApp/Assets.xcassets/AccentColor.colorset/Contents.json
new file mode 100644
index 00000000..eb878970
--- /dev/null
+++ b/example_projects/iOS_Calculator/CalculatorApp/Assets.xcassets/AccentColor.colorset/Contents.json
@@ -0,0 +1,11 @@
+{
+ "colors" : [
+ {
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/example_projects/iOS_Calculator/CalculatorApp/Assets.xcassets/AppIcon.appiconset/Contents.json b/example_projects/iOS_Calculator/CalculatorApp/Assets.xcassets/AppIcon.appiconset/Contents.json
new file mode 100644
index 00000000..23058801
--- /dev/null
+++ b/example_projects/iOS_Calculator/CalculatorApp/Assets.xcassets/AppIcon.appiconset/Contents.json
@@ -0,0 +1,35 @@
+{
+ "images" : [
+ {
+ "idiom" : "universal",
+ "platform" : "ios",
+ "size" : "1024x1024"
+ },
+ {
+ "appearances" : [
+ {
+ "appearance" : "luminosity",
+ "value" : "dark"
+ }
+ ],
+ "idiom" : "universal",
+ "platform" : "ios",
+ "size" : "1024x1024"
+ },
+ {
+ "appearances" : [
+ {
+ "appearance" : "luminosity",
+ "value" : "tinted"
+ }
+ ],
+ "idiom" : "universal",
+ "platform" : "ios",
+ "size" : "1024x1024"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/example_projects/iOS_Calculator/CalculatorApp/Assets.xcassets/Contents.json b/example_projects/iOS_Calculator/CalculatorApp/Assets.xcassets/Contents.json
new file mode 100644
index 00000000..73c00596
--- /dev/null
+++ b/example_projects/iOS_Calculator/CalculatorApp/Assets.xcassets/Contents.json
@@ -0,0 +1,6 @@
+{
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/example_projects/iOS_Calculator/CalculatorApp/CalculatorApp.swift b/example_projects/iOS_Calculator/CalculatorApp/CalculatorApp.swift
new file mode 100644
index 00000000..d03531b4
--- /dev/null
+++ b/example_projects/iOS_Calculator/CalculatorApp/CalculatorApp.swift
@@ -0,0 +1,15 @@
+import SwiftUI
+import CalculatorAppFeature
+
+@main
+struct CalculatorApp: App {
+ var body: some Scene {
+ WindowGroup {
+ ContentView()
+ }
+ }
+}
+
+#Preview {
+ ContentView()
+}
diff --git a/example_projects/iOS_Calculator/CalculatorApp/CalculatorApp.xctestplan b/example_projects/iOS_Calculator/CalculatorApp/CalculatorApp.xctestplan
new file mode 100644
index 00000000..c5596638
--- /dev/null
+++ b/example_projects/iOS_Calculator/CalculatorApp/CalculatorApp.xctestplan
@@ -0,0 +1,36 @@
+{
+ "configurations" : [
+ {
+ "id" : "24499A57-8A8C-49DD-9DF6-FD06943246D4",
+ "name" : "Test Scheme Action",
+ "options" : {
+
+ }
+ }
+ ],
+ "defaultOptions" : {
+ "targetForVariableExpansion" : {
+ "containerPath" : "container:TestingExampleApp.xcodeproj",
+ "identifier" : "8B41F6442DEDD0D5001A66F9",
+ "name" : "TestingExampleApp"
+ }
+ },
+ "testTargets" : [
+ {
+ "target" : {
+ "containerPath" : "container:CalculatorAppPackage",
+ "identifier" : "CalculatorAppFeatureTests",
+ "name" : "CalculatorAppFeatureTests"
+ }
+ },
+ {
+ "parallelizable" : false,
+ "target" : {
+ "containerPath" : "container:CalculatorApp.xcodeproj",
+ "identifier" : "8B90934F2DF246C0008F026A",
+ "name" : "CalculatorAppTests"
+ }
+ }
+ ],
+ "version" : 1
+}
diff --git a/example_projects/iOS_Calculator/CalculatorAppPackage/.gitignore b/example_projects/iOS_Calculator/CalculatorAppPackage/.gitignore
new file mode 100644
index 00000000..0023a534
--- /dev/null
+++ b/example_projects/iOS_Calculator/CalculatorAppPackage/.gitignore
@@ -0,0 +1,8 @@
+.DS_Store
+/.build
+/Packages
+xcuserdata/
+DerivedData/
+.swiftpm/configuration/registries.json
+.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata
+.netrc
diff --git a/example_projects/iOS_Calculator/CalculatorAppPackage/Package.swift b/example_projects/iOS_Calculator/CalculatorAppPackage/Package.swift
new file mode 100644
index 00000000..96befa23
--- /dev/null
+++ b/example_projects/iOS_Calculator/CalculatorAppPackage/Package.swift
@@ -0,0 +1,29 @@
+// swift-tools-version: 5.10
+// The swift-tools-version declares the minimum version of Swift required to build this package.
+
+import PackageDescription
+
+let package = Package(
+ name: "CalculatorAppFeature",
+ platforms: [.iOS(.v17)],
+ products: [
+ // Products define the executables and libraries a package produces, making them visible to other packages.
+ .library(
+ name: "CalculatorAppFeature",
+ targets: ["CalculatorAppFeature"]
+ ),
+ ],
+ targets: [
+ // Targets are the basic building blocks of a package, defining a module or a test suite.
+ // Targets can depend on other targets in this package and products from dependencies.
+ .target(
+ name: "CalculatorAppFeature"
+ ),
+ .testTarget(
+ name: "CalculatorAppFeatureTests",
+ dependencies: [
+ "CalculatorAppFeature"
+ ]
+ ),
+ ]
+)
diff --git a/example_projects/iOS_Calculator/CalculatorAppPackage/Sources/CalculatorAppFeature/BackgroundEffect.swift b/example_projects/iOS_Calculator/CalculatorAppPackage/Sources/CalculatorAppFeature/BackgroundEffect.swift
new file mode 100644
index 00000000..d0ff0913
--- /dev/null
+++ b/example_projects/iOS_Calculator/CalculatorAppPackage/Sources/CalculatorAppFeature/BackgroundEffect.swift
@@ -0,0 +1,32 @@
+import SwiftUI
+
+// MARK: - Background State Management
+enum BackgroundState {
+ case normal, calculated, error
+
+ var colors: [Color] {
+ switch self {
+ case .normal:
+ return [Color.blue.opacity(0.8), Color.purple.opacity(0.8), Color.indigo.opacity(0.9)]
+ case .calculated:
+ return [Color.green.opacity(0.7), Color.mint.opacity(0.8), Color.teal.opacity(0.9)]
+ case .error:
+ return [Color.red.opacity(0.7), Color.pink.opacity(0.8), Color.orange.opacity(0.9)]
+ }
+ }
+}
+
+// MARK: - Animated Background Component
+struct AnimatedBackground: View {
+ let backgroundGradient: BackgroundState
+
+ var body: some View {
+ AngularGradient(
+ colors: backgroundGradient.colors,
+ center: .topLeading,
+ angle: .degrees(45)
+ )
+ .ignoresSafeArea()
+ .animation(.easeInOut(duration: 0.8), value: backgroundGradient)
+ }
+}
\ No newline at end of file
diff --git a/example_projects/iOS_Calculator/CalculatorAppPackage/Sources/CalculatorAppFeature/CalculatorButton.swift b/example_projects/iOS_Calculator/CalculatorAppPackage/Sources/CalculatorAppFeature/CalculatorButton.swift
new file mode 100644
index 00000000..70ccd4dd
--- /dev/null
+++ b/example_projects/iOS_Calculator/CalculatorAppPackage/Sources/CalculatorAppFeature/CalculatorButton.swift
@@ -0,0 +1,125 @@
+import SwiftUI
+
+// MARK: - Calculator Button Component
+struct CalculatorButton: View {
+ let title: String
+ let buttonType: CalculatorButtonType
+ let isWideButton: Bool
+ let action: () -> Void
+
+ @State private var isPressed = false
+
+ var body: some View {
+ if buttonType == .hidden {
+ // Empty space for layout
+ Color.clear
+ .frame(height: 80)
+ } else {
+ Button(action: {
+ withAnimation(.easeInOut(duration: 0.1)) {
+ isPressed = true
+ }
+ action()
+
+ Task {
+ try await Task.sleep(for: .seconds(0.1))
+ await MainActor.run {
+ withAnimation(.easeInOut(duration: 0.1)) {
+ isPressed = false
+ }
+ }
+ }
+ }) {
+ ZStack {
+ // Frosted glass background
+ RoundedRectangle(cornerRadius: 20)
+ .fill(.ultraThinMaterial)
+ .overlay(
+ RoundedRectangle(cornerRadius: 20)
+ .stroke(buttonType.borderColor, lineWidth: 1)
+ )
+ .overlay(
+ // Subtle inner glow
+ RoundedRectangle(cornerRadius: 20)
+ .fill(
+ RadialGradient(
+ colors: [buttonType.glowColor.opacity(0.3), Color.clear],
+ center: .topLeading,
+ startRadius: 0,
+ endRadius: 50
+ )
+ )
+ )
+ .scaleEffect(isPressed ? 0.95 : 1.0)
+ .shadow(color: buttonType.shadowColor.opacity(0.3), radius: isPressed ? 2 : 8, x: 0, y: isPressed ? 1 : 4)
+
+ // Button text
+ Text(title)
+ .font(.system(size: 32, weight: .medium, design: .rounded))
+ .foregroundColor(buttonType.textColor)
+ .scaleEffect(isPressed ? 0.9 : 1.0)
+ }
+ }
+ .frame(height: 80)
+ .gridCellColumns(isWideButton ? 2 : 1)
+ .buttonStyle(PlainButtonStyle())
+ }
+ }
+}
+
+// MARK: - Button Type Configuration
+enum CalculatorButtonType {
+ case number, operation, function, hidden
+
+ var textColor: Color {
+ switch self {
+ case .number:
+ return .white
+ case .operation:
+ return .white
+ case .function:
+ return .white
+ case .hidden:
+ return .clear
+ }
+ }
+
+ var borderColor: Color {
+ switch self {
+ case .number:
+ return .white.opacity(0.3)
+ case .operation:
+ return .orange.opacity(0.6)
+ case .function:
+ return .gray.opacity(0.5)
+ case .hidden:
+ return .clear
+ }
+ }
+
+ var glowColor: Color {
+ switch self {
+ case .number:
+ return .blue
+ case .operation:
+ return .orange
+ case .function:
+ return .gray
+ case .hidden:
+ return .clear
+ }
+ }
+
+ var shadowColor: Color {
+ switch self {
+ case .number:
+ return .blue
+ case .operation:
+ return .orange
+ case .function:
+ return .gray
+ case .hidden:
+ return .clear
+ }
+ }
+}
\ No newline at end of file
diff --git a/example_projects/iOS_Calculator/CalculatorAppPackage/Sources/CalculatorAppFeature/CalculatorDisplay.swift b/example_projects/iOS_Calculator/CalculatorAppPackage/Sources/CalculatorAppFeature/CalculatorDisplay.swift
new file mode 100644
index 00000000..5b40e669
--- /dev/null
+++ b/example_projects/iOS_Calculator/CalculatorAppPackage/Sources/CalculatorAppFeature/CalculatorDisplay.swift
@@ -0,0 +1,46 @@
+import SwiftUI
+
+// MARK: - Calculator Display Component
+struct CalculatorDisplay: View {
+ let expressionDisplay: String
+ let display: String
+ var onDeleteLastDigit: (() -> Void)? = nil
+
+ var body: some View {
+ VStack(alignment: .trailing, spacing: 8) {
+ // Expression display (smaller, secondary)
+ Text(expressionDisplay)
+ .font(.title2)
+ .foregroundColor(.white.opacity(0.7))
+ .frame(maxWidth: .infinity, alignment: .trailing)
+ .lineLimit(1)
+ .minimumScaleFactor(0.5)
+
+ // Main result display
+ Text(display)
+ .font(.system(size: 56, weight: .light, design: .rounded))
+ .foregroundColor(.white)
+ .frame(maxWidth: .infinity, alignment: .trailing)
+ .lineLimit(1)
+ .minimumScaleFactor(0.3)
+ .gesture(DragGesture(minimumDistance: 20, coordinateSpace: .local)
+ .onEnded { value in
+ if value.translation.width < -20 || value.translation.width > 20 {
+ onDeleteLastDigit?()
+ }
+ }
+ )
+ }
+ .padding(.horizontal, 24)
+ .padding(.bottom, 30)
+ .frame(height: 140)
+ }
+}
+
+struct CalculatorDisplay_Previews: PreviewProvider {
+ static var previews: some View {
+ CalculatorDisplay(expressionDisplay: "12 + 7", display: "19", onDeleteLastDigit: nil)
+ .background(Color.black)
+ .previewLayout(.sizeThatFits)
+ }
+}
diff --git a/example_projects/iOS_Calculator/CalculatorAppPackage/Sources/CalculatorAppFeature/CalculatorInputHandler.swift b/example_projects/iOS_Calculator/CalculatorAppPackage/Sources/CalculatorAppFeature/CalculatorInputHandler.swift
new file mode 100644
index 00000000..9a4c52a3
--- /dev/null
+++ b/example_projects/iOS_Calculator/CalculatorAppPackage/Sources/CalculatorAppFeature/CalculatorInputHandler.swift
@@ -0,0 +1,38 @@
+import Foundation
+
+// MARK: - Input Handling
+/// Handles input parsing and routing to the calculator service
+struct CalculatorInputHandler {
+ private let service: CalculatorService
+
+ init(service: CalculatorService) {
+ self.service = service
+ }
+
+ func handleInput(_ input: String) {
+ switch input {
+ case "C":
+ service.clear()
+ case "±":
+ service.toggleSign()
+ case "%":
+ service.percentage()
+ case "+", "-", "×", "÷":
+ if let operation = CalculatorService.Operation(rawValue: input) {
+ service.setOperation(operation)
+ }
+ case "=":
+ service.calculate()
+ case ".":
+ service.inputDecimal()
+ case "0"..."9":
+ service.inputNumber(input)
+ default:
+ break // Ignore unknown inputs
+ }
+ }
+
+ func deleteLastDigit() {
+ service.deleteLastDigit()
+ }
+}
diff --git a/example_projects/iOS_Calculator/CalculatorAppPackage/Sources/CalculatorAppFeature/CalculatorService.swift b/example_projects/iOS_Calculator/CalculatorAppPackage/Sources/CalculatorAppFeature/CalculatorService.swift
new file mode 100644
index 00000000..38c4929d
--- /dev/null
+++ b/example_projects/iOS_Calculator/CalculatorAppPackage/Sources/CalculatorAppFeature/CalculatorService.swift
@@ -0,0 +1,219 @@
+import Foundation
+
+// MARK: - Calculator Business Logic Service
+
+/// Handles all calculator operations and state management
+/// Separated from UI concerns for better testability and modularity
+@Observable
+public final class CalculatorService {
+ // MARK: - Public Properties
+
+ public private(set) var display: String = "0"
+ public private(set) var expressionDisplay: String = ""
+ public private(set) var hasError: Bool = false
+
+ // MARK: - Private State
+
+ private var currentNumber: Double = 0
+ private var previousNumber: Double = 0
+ private var operation: Operation?
+ private var shouldResetDisplay = false
+ private var isNewCalculation = true
+ private var lastOperation: Operation?
+ private var lastOperand: Double = 0
+
+ // MARK: - Operations
+
+ public enum Operation: String, CaseIterable, Sendable {
+ case add = "+"
+ case subtract = "-"
+ case multiply = "×"
+ case divide = "÷"
+
+ public func calculate(_ a: Double, _ b: Double) -> Double {
+ switch self {
+ case .add: return a + b
+ case .subtract: return a - b
+ case .multiply: return a * b
+ case .divide: return b != 0 ? a / b : 0
+ }
+ }
+ }
+
+ public init() {}
+
+ // MARK: - Public Interface
+
+ public func inputNumber(_ digit: String) {
+ guard !hasError else { clear(); return }
+
+ if shouldResetDisplay || isNewCalculation {
+ display = digit
+ shouldResetDisplay = false
+ isNewCalculation = false
+ } else if display.count < 12 {
+ display = display == "0" ? digit : display + digit
+ }
+
+ currentNumber = Double(display) ?? 0
+ updateExpressionDisplay()
+ }
+
+ /// Inputs a decimal point into the display
+ public func inputDecimal() {
+ guard !hasError else {
+ clear(); return
+ }
+
+ if shouldResetDisplay || isNewCalculation {
+ display = "0."
+ shouldResetDisplay = false
+ isNewCalculation = false
+ } else if !display.contains("."), display.count < 11 {
+ display += "."
+ }
+ updateExpressionDisplay()
+ }
+
+ public func setOperation(_ op: Operation) {
+ guard !hasError else { return }
+
+ if operation != nil, !shouldResetDisplay {
+ calculate()
+ if hasError { return }
+ }
+
+ previousNumber = currentNumber
+ operation = op
+ shouldResetDisplay = true
+ isNewCalculation = false
+ updateExpressionDisplay()
+ }
+
+ public func calculate() {
+ guard let op = operation ?? lastOperation else { return }
+ let operand = (operation != nil) ? currentNumber : lastOperand
+
+ let result = op.calculate(previousNumber, operand)
+
+ // Error handling
+ if result.isNaN || result.isInfinite {
+ setError("Cannot divide by zero")
+ return
+ }
+
+ if abs(result) > 1e12 {
+ setError("Number too large")
+ return
+ }
+
+ // Success path
+ let prevFormatted = formatNumber(previousNumber)
+ let currFormatted = formatNumber(operand)
+ display = formatNumber(result)
+ expressionDisplay = "\(prevFormatted) \(op.rawValue) \(currFormatted) ="
+
+ previousNumber = result
+ if operation != nil {
+ lastOperand = currentNumber
+ }
+
+ lastOperation = op
+ operation = nil
+ currentNumber = result
+ shouldResetDisplay = true
+ isNewCalculation = false
+ }
+
+ public func toggleSign() {
+ guard !hasError, currentNumber != 0 else { return }
+ currentNumber *= -1
+ display = formatNumber(currentNumber)
+ updateExpressionDisplay()
+ }
+
+ public func percentage() {
+ guard !hasError else { return }
+ currentNumber /= 100
+ display = formatNumber(currentNumber)
+ updateExpressionDisplay()
+ }
+
+ public func clear() {
+ display = "0"
+ expressionDisplay = ""
+ currentNumber = 0
+ previousNumber = 0
+ operation = nil
+ shouldResetDisplay = false
+ hasError = false
+ isNewCalculation = true
+ }
+
+ public func deleteLastDigit() {
+ guard !hasError else { clear(); return }
+
+ if shouldResetDisplay || isNewCalculation {
+ display = "0"
+ shouldResetDisplay = false
+ isNewCalculation = false
+ } else if display.count > 1 {
+ display.removeLast()
+ if display == "-" { display = "0" }
+ } else {
+ display = "0"
+ }
+ currentNumber = Double(display) ?? 0
+ updateExpressionDisplay()
+ }
+
+ // MARK: - Private Helpers
+
+ private func setError(_ message: String) {
+ hasError = true
+ display = "Error"
+ expressionDisplay = message
+ }
+
+ private func updateExpressionDisplay() {
+ guard !hasError else { return }
+
+ if let op = operation {
+ let prevFormatted = formatNumber(previousNumber)
+ expressionDisplay = "\(prevFormatted) \(op.rawValue)"
+ } else if isNewCalculation {
+ expressionDisplay = ""
+ }
+ }
+
+ private func formatNumber(_ number: Double) -> String {
+ guard !number.isNaN && !number.isInfinite else { return "Error" }
+
+ let formatter = NumberFormatter()
+ formatter.numberStyle = .decimal
+ formatter.maximumFractionDigits = 8
+ formatter.minimumFractionDigits = 0
+
+ // For integers, don't show decimal places
+ if number == floor(number) && abs(number) < 1e10 {
+ formatter.maximumFractionDigits = 0
+ }
+
+ // For very small decimals, use scientific notation
+ if abs(number) < 0.000001 && number != 0 {
+ formatter.numberStyle = .scientific
+ formatter.maximumFractionDigits = 2
+ }
+
+ return formatter.string(from: NSNumber(value: number)) ?? "0"
+ }
+}
+
+// MARK: - Testing Support
+
+public extension CalculatorService {
+ var currentValue: Double { currentNumber }
+ var previousValue: Double { previousNumber }
+ var currentOperation: Operation? { operation }
+ var willResetDisplay: Bool { shouldResetDisplay }
+}
diff --git a/example_projects/iOS_Calculator/CalculatorAppPackage/Sources/CalculatorAppFeature/ContentView.swift b/example_projects/iOS_Calculator/CalculatorAppPackage/Sources/CalculatorAppFeature/ContentView.swift
new file mode 100644
index 00000000..e7bbee37
--- /dev/null
+++ b/example_projects/iOS_Calculator/CalculatorAppPackage/Sources/CalculatorAppFeature/ContentView.swift
@@ -0,0 +1,102 @@
+import SwiftUI
+
+public struct ContentView: View {
+ @State private var calculatorService = CalculatorService()
+ @State private var backgroundGradient = BackgroundState.normal
+
+ private var inputHandler: CalculatorInputHandler {
+ CalculatorInputHandler(service: calculatorService)
+ }
+
+ public var body: some View {
+ GeometryReader { geometry in
+ ZStack {
+ // Dynamic gradient background
+ AnimatedBackground(backgroundGradient: backgroundGradient)
+
+ VStack(spacing: 0) {
+ Spacer()
+
+ // Display Section
+ CalculatorDisplay(
+ expressionDisplay: calculatorService.expressionDisplay,
+ display: calculatorService.display,
+ onDeleteLastDigit: {
+ inputHandler.deleteLastDigit()
+ }
+ )
+
+ // Button Grid
+ LazyVGrid(columns: Array(repeating: GridItem(.flexible(), spacing: 12), count: 4), spacing: 12) {
+ ForEach(calculatorButtons, id: \.self) { button in
+ CalculatorButton(
+ title: button,
+ buttonType: buttonType(for: button),
+ isWideButton: button == "0"
+ ) {
+ handleButtonPress(button)
+ }
+ }
+ }
+ .padding(.horizontal, 20)
+ .padding(.bottom, max(geometry.safeAreaInsets.bottom, 20))
+ }
+ }
+ }
+ }
+
+ // Calculator button layout (proper grid with = button in correct position)
+ private var calculatorButtons: [String] {
+ [
+ "C", "±", "%", "÷",
+ "7", "8", "9", "×",
+ "4", "5", "6", "-",
+ "1", "2", "3", "+",
+ "", "0", ".", "="
+ ]
+ }
+
+ private func buttonType(for button: String) -> CalculatorButtonType {
+ switch button {
+ case "C", "±", "%":
+ return .function
+ case "÷", "×", "-", "+", "=":
+ return .operation
+ case "":
+ return .hidden
+ default:
+ return .number
+ }
+ }
+
+ private func handleButtonPress(_ button: String) {
+ // Process input through the input handler
+ inputHandler.handleInput(button)
+
+ // Handle background state changes with modern animation
+ withAnimation(.easeInOut(duration: 0.3)) {
+ if button == "=" {
+ backgroundGradient = calculatorService.hasError ? .error : .calculated
+
+ // Reset to normal after a delay using structured concurrency
+ Task {
+ try await Task.sleep(for: .seconds(1.5))
+ await MainActor.run {
+ withAnimation(.easeInOut(duration: 0.5)) {
+ backgroundGradient = .normal
+ }
+ }
+ }
+ } else if button == "C" {
+ backgroundGradient = .normal
+ }
+ }
+ }
+
+ public init() {}
+}
+
+
+#Preview {
+ ContentView()
+}
diff --git a/example_projects/iOS_Calculator/CalculatorAppPackage/Tests/CalculatorAppFeatureTests/CalculatorServiceTests.swift b/example_projects/iOS_Calculator/CalculatorAppPackage/Tests/CalculatorAppFeatureTests/CalculatorServiceTests.swift
new file mode 100644
index 00000000..185dc18a
--- /dev/null
+++ b/example_projects/iOS_Calculator/CalculatorAppPackage/Tests/CalculatorAppFeatureTests/CalculatorServiceTests.swift
@@ -0,0 +1,481 @@
+import Testing
+import Foundation
+@testable import CalculatorAppFeature
+
+// MARK: - Calculator Basic Tests
+@Suite("Calculator Basic Functionality")
+struct CalculatorBasicTests {
+
+ @Test("Calculator initializes with correct default values")
+ func testInitialState() {
+ let calculator = CalculatorService()
+ #expect(calculator.display == "0")
+ #expect(calculator.currentValue == 0)
+ #expect(calculator.previousValue == 0)
+ #expect(calculator.currentOperation == nil)
+ #expect(calculator.willResetDisplay == false)
+ }
+
+ @Test("Clear function resets calculator to initial state")
+ func testClear() {
+ let calculator = CalculatorService()
+ calculator.inputNumber("5")
+ calculator.setOperation(.add)
+ calculator.inputNumber("3")
+
+ calculator.clear()
+
+ #expect(calculator.display == "0")
+ #expect(calculator.currentValue == 0)
+ #expect(calculator.previousValue == 0)
+ }
+
+ @Test("This test should fail to verify error reporting")
+ func testIntentionalFailure() {
+ let calculator = CalculatorService()
+ // This test is designed to fail to test error reporting
+ #expect(calculator.display == "999", "This should fail - display should be 0, not 999")
+ #expect(calculator.currentOperation == nil)
+ #expect(calculator.willResetDisplay == false)
+ }
+}
+
+// MARK: - Number Input Tests
+@Suite("Number Input")
+struct NumberInputTests {
+
+ @Test("Adding single digit numbers")
+ func testSingleDigitInput() {
+ let calculator = CalculatorService()
+
+ calculator.inputNumber("5")
+ #expect(calculator.display == "5")
+ #expect(calculator.currentValue == 5)
+ }
+
+ @Test("Adding multiple digit numbers")
+ func testMultipleDigitInput() {
+ let calculator = CalculatorService()
+
+ calculator.inputNumber("1")
+ calculator.inputNumber("2")
+ calculator.inputNumber("3")
+
+ #expect(calculator.display == "123")
+ #expect(calculator.currentValue == 123)
+ }
+
+ @Test("Adding decimal numbers")
+ func testDecimalInput() {
+ let calculator = CalculatorService()
+
+ calculator.inputNumber("1")
+ calculator.inputDecimal()
+ calculator.inputNumber("5")
+
+ #expect(calculator.display == "1.5")
+ #expect(calculator.currentValue == 1.5)
+ }
+
+ @Test("Multiple decimal points should be ignored")
+ func testMultipleDecimalPoints() {
+ let calculator = CalculatorService()
+
+ calculator.inputNumber("1")
+ calculator.inputDecimal()
+ calculator.inputNumber("5")
+ calculator.inputDecimal() // This should be ignored
+ calculator.inputNumber("2")
+
+ #expect(calculator.display == "1.52")
+ #expect(calculator.currentValue == 1.52)
+ }
+
+ @Test("Decimal point at start creates 0.")
+ func testDecimalAtStart() {
+ let calculator = CalculatorService()
+
+ calculator.inputDecimal()
+ calculator.inputNumber("5")
+
+ #expect(calculator.display == "0.5")
+ #expect(calculator.currentValue == 0.5)
+ }
+}
+
+// MARK: - Operation Tests
+@Suite("Mathematical Operations")
+struct OperationTests {
+
+ @Test("Addition operation", arguments: [
+ (5.0, 3.0, 8.0),
+ (10.0, -2.0, 8.0),
+ (0.0, 5.0, 5.0),
+ (-3.0, -7.0, -10.0)
+ ])
+ func testAddition(a: Double, b: Double, expected: Double) {
+ let result = CalculatorService.Operation.add.calculate(a, b)
+ #expect(result == expected)
+ }
+
+ @Test("Subtraction operation", arguments: [
+ (10.0, 3.0, 7.0),
+ (5.0, 8.0, -3.0),
+ (0.0, 5.0, -5.0),
+ (-3.0, -7.0, 4.0)
+ ])
+ func testSubtraction(a: Double, b: Double, expected: Double) {
+ let result = CalculatorService.Operation.subtract.calculate(a, b)
+ #expect(result == expected)
+ }
+
+ @Test("Multiplication operation", arguments: [
+ (5.0, 3.0, 15.0),
+ (4.0, -2.0, -8.0),
+ (0.0, 5.0, 0.0),
+ (-3.0, -7.0, 21.0)
+ ])
+ func testMultiplication(a: Double, b: Double, expected: Double) {
+ let result = CalculatorService.Operation.multiply.calculate(a, b)
+ #expect(result == expected)
+ }
+
+ @Test("Division operation", arguments: [
+ (10.0, 2.0, 5.0),
+ (15.0, 3.0, 5.0),
+ (-8.0, 2.0, -4.0),
+ (7.0, 2.0, 3.5)
+ ])
+ func testDivision(a: Double, b: Double, expected: Double) {
+ let result = CalculatorService.Operation.divide.calculate(a, b)
+ #expect(result == expected)
+ }
+
+ @Test("Division by zero returns zero")
+ func testDivisionByZero() {
+ let result = CalculatorService.Operation.divide.calculate(10.0, 0.0)
+ #expect(result == 0.0)
+ }
+}
+
+// MARK: - Calculator Integration Tests
+@Suite("Calculator Integration Tests")
+struct CalculatorIntegrationTests {
+
+ @Test("Simple addition calculation")
+ func testSimpleAddition() {
+ let calculator = CalculatorService()
+
+ calculator.inputNumber("5")
+ calculator.setOperation(.add)
+ calculator.inputNumber("3")
+ calculator.calculate()
+
+ #expect(calculator.display == "8")
+ #expect(calculator.currentValue == 8)
+ }
+
+ @Test("Chain calculations")
+ func testChainCalculations() {
+ let calculator = CalculatorService()
+
+ calculator.inputNumber("5")
+ calculator.setOperation(.add)
+ calculator.inputNumber("3")
+ calculator.setOperation(.multiply) // Should calculate 5+3=8 first
+ calculator.inputNumber("2")
+ calculator.calculate()
+
+ #expect(calculator.currentValue == 16) // (5+3) * 2 = 16
+ }
+
+ @Test("Complex calculation sequence")
+ func testComplexCalculation() {
+ let calculator = CalculatorService()
+
+ // Calculate: 10 + 5 * 2 - 3
+ calculator.inputNumber("1")
+ calculator.inputNumber("0")
+ calculator.setOperation(.add)
+ calculator.inputNumber("5")
+ calculator.setOperation(.multiply)
+ calculator.inputNumber("2")
+ calculator.setOperation(.subtract)
+ calculator.inputNumber("3")
+ calculator.calculate()
+
+ #expect(calculator.currentValue == 27) // ((10+5)*2)-3 = 27
+ }
+
+ @Test("Repetitive equals press repeats last operation")
+ func testRepetitiveEquals() {
+ let calculator = CalculatorService()
+
+ calculator.inputNumber("5")
+ calculator.setOperation(.add)
+ calculator.inputNumber("3")
+ calculator.calculate() // 5 + 3 = 8
+
+ #expect(calculator.currentValue == 8)
+
+ calculator.calculate() // Should be 8 + 3 = 11
+ #expect(calculator.currentValue == 11)
+
+ calculator.calculate() // Should be 11 + 3 = 14
+ #expect(calculator.currentValue == 14)
+ }
+
+ @Test("Expression display updates correctly")
+ func testExpressionDisplay() {
+ let calculator = CalculatorService()
+
+ calculator.inputNumber("1")
+ calculator.inputNumber("2")
+ #expect(calculator.expressionDisplay == "")
+
+ calculator.setOperation(.add)
+ #expect(calculator.expressionDisplay == "12 +")
+
+ calculator.inputNumber("3")
+ #expect(calculator.expressionDisplay == "12 +")
+
+ calculator.calculate()
+ #expect(calculator.expressionDisplay == "12 + 3 =")
+ }
+}
+
+// MARK: - Special Functions Tests
+@Suite("Special Functions")
+struct SpecialFunctionsTests {
+
+ @Test("Toggle sign on positive number")
+ func testToggleSignPositive() {
+ let calculator = CalculatorService()
+
+ calculator.inputNumber("5")
+ calculator.toggleSign()
+
+ #expect(calculator.display == "-5")
+ #expect(calculator.currentValue == -5)
+ }
+
+ @Test("Toggle sign on negative number")
+ func testToggleSignNegative() {
+ let calculator = CalculatorService()
+
+ calculator.inputNumber("5")
+ calculator.toggleSign()
+ calculator.toggleSign()
+
+ #expect(calculator.display == "5")
+ #expect(calculator.currentValue == 5)
+ }
+
+ @Test("Toggle sign on zero has no effect")
+ func testToggleSignZero() {
+ let calculator = CalculatorService()
+
+ calculator.toggleSign()
+
+ #expect(calculator.display == "0")
+ #expect(calculator.currentValue == 0)
+ }
+
+ @Test("Percentage calculation", arguments: [
+ ("100", 1.0),
+ ("50", 0.5),
+ ("25", 0.25),
+ ("200", 2.0)
+ ])
+ func testPercentage(input: String, expected: Double) {
+ let calculator = CalculatorService()
+
+ calculator.inputNumber(input)
+ calculator.percentage()
+
+ #expect(calculator.currentValue == expected)
+ }
+}
+
+// MARK: - Input Handler Tests
+@Suite("Input Handler Integration")
+struct InputHandlerTests {
+
+ @Test("Number input through handler")
+ func testNumberInputThroughHandler() {
+ let calculator = CalculatorService()
+ let handler = CalculatorInputHandler(service: calculator)
+
+ handler.handleInput("1")
+ handler.handleInput("2")
+ handler.handleInput("3")
+
+ #expect(calculator.display == "123")
+ }
+
+ @Test("Operation input through handler")
+ func testOperationInputThroughHandler() {
+ let calculator = CalculatorService()
+ let handler = CalculatorInputHandler(service: calculator)
+
+ handler.handleInput("5")
+ handler.handleInput("+")
+ handler.handleInput("3")
+ handler.handleInput("=")
+
+ #expect(calculator.currentValue == 8)
+ }
+
+ @Test("Clear input through handler")
+ func testClearInputThroughHandler() {
+ let calculator = CalculatorService()
+ let handler = CalculatorInputHandler(service: calculator)
+
+ handler.handleInput("5")
+ handler.handleInput("+")
+ handler.handleInput("3")
+ handler.handleInput("C")
+
+ #expect(calculator.display == "0")
+ #expect(calculator.currentValue == 0)
+ }
+
+ @Test("Decimal input through handler")
+ func testDecimalInputThroughHandler() {
+ let calculator = CalculatorService()
+ let handler = CalculatorInputHandler(service: calculator)
+
+ handler.handleInput("1")
+ handler.handleInput(".")
+ handler.handleInput("5")
+
+ #expect(calculator.display == "1.5")
+ }
+}
+
+// MARK: - Edge Cases Tests
+@Suite("Edge Cases")
+struct EdgeCaseTests {
+
+ @Test("Calculate without setting operation")
+ func testCalculateWithoutOperation() {
+ let calculator = CalculatorService()
+
+ calculator.inputNumber("5")
+ calculator.calculate()
+
+ #expect(calculator.currentValue == 5) // Should remain unchanged
+ }
+
+ @Test("Setting operation without previous number")
+ func testOperationWithoutPreviousNumber() {
+ let calculator = CalculatorService()
+
+ calculator.setOperation(.add)
+ calculator.inputNumber("5")
+ calculator.calculate()
+
+ #expect(calculator.currentValue == 5) // 0 + 5 = 5
+ }
+
+ @Test("Multiple equals presses")
+ func testMultipleEquals() {
+ let calculator = CalculatorService()
+
+ calculator.inputNumber("5")
+ calculator.setOperation(.add)
+ calculator.inputNumber("3")
+ calculator.calculate()
+
+ let firstResult = calculator.currentValue
+ calculator.calculate() // Second equals press
+
+ #expect(firstResult == 8)
+ #expect(calculator.currentValue == 11) // Should repeat last operation: 8 + 3 = 11
+ }
+}
+
+// MARK: - Error Handling Tests
+@Suite("Error Handling")
+struct ErrorHandlingTests {
+
+ @Test("Calculator handles invalid input gracefully")
+ func testInvalidInputHandling() {
+ let calculator = CalculatorService()
+ let handler = CalculatorInputHandler(service: calculator)
+
+ // Test pressing operation without any number
+ handler.handleInput("+")
+ handler.handleInput("5")
+ handler.handleInput("=")
+
+ #expect(calculator.currentValue == 5) // Should be 0 + 5 = 5
+ }
+
+ @Test("Calculator state after multiple clears")
+ func testMultipleClearOperations() {
+ let calculator = CalculatorService()
+
+ calculator.inputNumber("123")
+ calculator.setOperation(.add)
+ calculator.inputNumber("456")
+
+ // Multiple clear operations
+ calculator.clear()
+ calculator.clear()
+ calculator.clear()
+
+ #expect(calculator.display == "0")
+ #expect(calculator.currentValue == 0)
+ #expect(calculator.currentOperation == nil)
+ }
+
+ @Test("Large number error handling")
+ func testLargeNumberError() {
+ let calculator = CalculatorService()
+ calculator.inputNumber("1000000000000") // 1e12
+ calculator.setOperation(.multiply)
+ calculator.inputNumber("2")
+ calculator.calculate()
+
+ #expect(calculator.hasError == true)
+ #expect(calculator.display == "Error")
+ #expect(calculator.expressionDisplay == "Number too large")
+ }
+}
+
+// MARK: - Decimal Edge Cases
+@Suite("Decimal Edge Cases")
+struct DecimalEdgeCaseTests {
+
+ @Test("Very small decimal numbers")
+ func testVerySmallDecimals() {
+ let calculator = CalculatorService()
+
+ calculator.inputNumber("0")
+ calculator.inputDecimal()
+ calculator.inputNumber("0")
+ calculator.inputNumber("0")
+ calculator.inputNumber("1")
+
+ #expect(calculator.display == "0.001")
+ #expect(calculator.currentValue == 0.001)
+ }
+
+ @Test("Decimal operations precision")
+ func testDecimalPrecision() {
+ let calculator = CalculatorService()
+
+ calculator.inputNumber("0")
+ calculator.inputDecimal()
+ calculator.inputNumber("1")
+ calculator.setOperation(.add)
+ calculator.inputNumber("0")
+ calculator.inputDecimal()
+ calculator.inputNumber("2")
+ calculator.calculate()
+
+ // 0.1 + 0.2 should equal 0.3 (within floating point precision)
+ #expect(abs(calculator.currentValue - 0.3) < 0.0001)
+ }
+}
diff --git a/example_projects/iOS_Calculator/CalculatorAppTests/CalculatorAppTests.swift b/example_projects/iOS_Calculator/CalculatorAppTests/CalculatorAppTests.swift
new file mode 100644
index 00000000..4e359623
--- /dev/null
+++ b/example_projects/iOS_Calculator/CalculatorAppTests/CalculatorAppTests.swift
@@ -0,0 +1,314 @@
+//
+// CalculatorAppTests.swift
+// CalculatorAppTests
+//
+// Created by Cameron on 05/06/2025.
+//
+
+import XCTest
+import SwiftUI
+@testable import CalculatorApp
+import CalculatorAppFeature
+
+final class CalculatorAppTests: XCTestCase {
+
+ override func setUpWithError() throws {
+ continueAfterFailure = false
+ }
+
+ override func tearDownWithError() throws {
+ // Clean up after each test
+ }
+}
+
+// MARK: - App Lifecycle Tests
+extension CalculatorAppTests {
+
+ func testAppLaunch() throws {
+ // Test that the app launches without crashing
+ let app = CalculatorApp()
+ XCTAssertNotNil(app, "App should initialize successfully")
+ }
+
+ func testContentViewInitialization() throws {
+ // Test that ContentView initializes properly
+ let contentView = ContentView()
+ XCTAssertNotNil(contentView, "ContentView should initialize successfully")
+ }
+}
+
+// MARK: - Calculator Service Integration Tests
+extension CalculatorAppTests {
+
+ func testCalculatorServiceCreation() throws {
+ let service = CalculatorService()
+ XCTAssertEqual(service.display, "0", "Calculator should start with display showing 0")
+ XCTAssertEqual(service.expressionDisplay, "", "Calculator should start with empty expression")
+ }
+
+ func testCalculatorServiceFailure() throws {
+ let service = CalculatorService()
+ // This test is designed to fail to test error reporting
+ XCTAssertEqual(service.display, "999", "This test should fail - display should be 0, not 999")
+ }
+
+ func testCalculatorServiceBasicOperation() throws {
+ let service = CalculatorService()
+
+ // Test basic addition
+ service.inputNumber("5")
+ service.setOperation(.add)
+ service.inputNumber("3")
+ service.calculate()
+
+ XCTAssertEqual(service.display, "8", "5 + 3 should equal 8")
+ }
+
+ func testCalculatorServiceChainedOperations() throws {
+ let service = CalculatorService()
+
+ // Test chained operations: 10 + 5 * 2 = 30 (since calculator evaluates left to right)
+ service.inputNumber("10")
+ service.setOperation(.add)
+ service.inputNumber("5")
+ service.setOperation(.multiply)
+ service.inputNumber("2")
+ service.calculate()
+
+ XCTAssertEqual(service.display, "30", "10 + 5 * 2 should equal 30 (left-to-right evaluation)")
+ }
+
+ func testCalculatorServiceClear() throws {
+ let service = CalculatorService()
+
+ // Set up some state
+ service.inputNumber("123")
+ service.setOperation(.add)
+ service.inputNumber("456")
+
+ // Clear should reset everything
+ service.clear()
+
+ XCTAssertEqual(service.display, "0", "Display should be 0 after clear")
+ XCTAssertEqual(service.expressionDisplay, "", "Expression should be empty after clear")
+ }
+}
+
+// MARK: - API Surface Tests
+extension CalculatorAppTests {
+
+ func testCalculatorServicePublicInterface() throws {
+ let service = CalculatorService()
+
+ // Test that all expected public methods are available
+ XCTAssertNoThrow(service.inputNumber("5"))
+ XCTAssertNoThrow(service.inputDecimal())
+ XCTAssertNoThrow(service.setOperation(.add))
+ XCTAssertNoThrow(service.calculate())
+ XCTAssertNoThrow(service.toggleSign())
+ XCTAssertNoThrow(service.percentage())
+ XCTAssertNoThrow(service.clear())
+ }
+
+ func testCalculatorServicePublicProperties() throws {
+ let service = CalculatorService()
+
+ // Test that all expected public properties are accessible
+ XCTAssertNotNil(service.display)
+ XCTAssertNotNil(service.expressionDisplay)
+ XCTAssertEqual(service.hasError, false)
+
+ // Test testing support properties
+ XCTAssertEqual(service.currentValue, 0)
+ XCTAssertEqual(service.previousValue, 0)
+ XCTAssertNil(service.currentOperation)
+ XCTAssertEqual(service.willResetDisplay, false)
+ }
+
+ func testCalculatorOperationsEnum() throws {
+ // Test that all operations are available
+ XCTAssertEqual(CalculatorService.Operation.add.rawValue, "+")
+ XCTAssertEqual(CalculatorService.Operation.subtract.rawValue, "-")
+ XCTAssertEqual(CalculatorService.Operation.multiply.rawValue, "×")
+ XCTAssertEqual(CalculatorService.Operation.divide.rawValue, "÷")
+
+ // Test operation calculations
+ XCTAssertEqual(CalculatorService.Operation.add.calculate(5, 3), 8)
+ XCTAssertEqual(CalculatorService.Operation.subtract.calculate(5, 3), 2)
+ XCTAssertEqual(CalculatorService.Operation.multiply.calculate(5, 3), 15)
+ XCTAssertEqual(CalculatorService.Operation.divide.calculate(6, 3), 2)
+ XCTAssertEqual(CalculatorService.Operation.divide.calculate(5, 0), 0) // Division by zero
+ }
+}
+
+// MARK: - Edge Case and Error Handling Tests
+extension CalculatorAppTests {
+
+ func testDivisionByZero() throws {
+ let service = CalculatorService()
+
+ service.inputNumber("10")
+ service.setOperation(.divide)
+ service.inputNumber("0")
+ service.calculate()
+
+ XCTAssertEqual(service.display, "0", "Division by zero should return 0")
+ }
+
+ func testLargeNumbers() throws {
+ let service = CalculatorService()
+
+ // Test large number input
+ service.inputNumber("999999999")
+ XCTAssertEqual(service.display, "999999999", "Should handle large numbers")
+
+ // Test large number calculation
+ service.setOperation(.multiply)
+ service.inputNumber("2")
+ service.calculate()
+
+ // Should handle the result without crashing
+ XCTAssertNotEqual(service.display, "", "Should display some result for large calculations")
+ }
+
+ func testRepeatedEquals() throws {
+ let service = CalculatorService()
+
+ service.inputNumber("5")
+ service.setOperation(.add)
+ service.inputNumber("3")
+ service.calculate() // 5 + 3 = 8
+
+ let firstResult = service.display
+
+ service.calculate() // Should repeat last operation: 8 + 3 = 11
+ let secondResult = service.display
+
+ XCTAssertEqual(firstResult, "8", "First calculation should be correct")
+ XCTAssertEqual(secondResult, "11", "Repeated equals should repeat last operation")
+ }
+}
+
+// MARK: - Performance Tests
+extension CalculatorAppTests {
+
+ func testCalculationPerformance() throws {
+ let service = CalculatorService()
+
+ measure {
+ // Measure performance of 100 calculations
+ for i in 1...100 {
+ service.clear()
+ service.inputNumber("\(i)")
+ service.setOperation(.multiply)
+ service.inputNumber("2")
+ service.calculate()
+ }
+ }
+ }
+
+ func testLargeNumberInputPerformance() throws {
+ let service = CalculatorService()
+
+ measure {
+ // Measure performance of inputting large numbers
+ service.clear()
+ for digit in "123456789012345" {
+ service.inputNumber(String(digit))
+ }
+ }
+ }
+}
+
+// MARK: - State Consistency Tests
+extension CalculatorAppTests {
+
+ func testStateConsistencyAfterOperations() throws {
+ let service = CalculatorService()
+
+ // Perform a series of operations and verify state remains consistent
+ service.inputNumber("10")
+ XCTAssertEqual(service.display, "10")
+
+ service.setOperation(.add)
+ XCTAssertEqual(service.display, "10")
+ XCTAssertTrue(service.expressionDisplay.contains("10 +"))
+
+ service.inputNumber("5")
+ XCTAssertEqual(service.display, "5")
+
+ service.calculate()
+ XCTAssertEqual(service.display, "15")
+ }
+
+ func testStateConsistencyWithDecimalNumbers() throws {
+ let service = CalculatorService()
+
+ service.inputNumber("3")
+ service.inputDecimal()
+ service.inputNumber("14")
+ XCTAssertEqual(service.display, "3.14")
+
+ service.setOperation(.multiply)
+ service.inputNumber("2")
+ service.calculate()
+
+ XCTAssertEqual(service.display, "6.28")
+ }
+
+ func testMultipleDecimalPointsHandling() throws {
+ let service = CalculatorService()
+
+ service.inputNumber("1")
+ service.inputDecimal()
+ service.inputNumber("5")
+ service.inputDecimal() // This should be ignored
+ service.inputNumber("9")
+
+ XCTAssertEqual(service.display, "1.59", "Multiple decimal points should be ignored")
+ }
+}
+
+// MARK: - Component Integration Tests
+extension CalculatorAppTests {
+
+ func testComplexCalculationWorkflow() throws {
+ let service = CalculatorService()
+
+ // Test complex workflow through direct service calls
+ service.inputNumber("2")
+ service.inputNumber("5")
+ service.setOperation(.divide)
+ service.inputNumber("5")
+ service.calculate()
+
+ XCTAssertEqual(service.display, "5", "Complex workflow should work correctly")
+
+ // Test that we can continue with the result
+ service.setOperation(.multiply)
+ service.inputNumber("4")
+ service.calculate()
+
+ XCTAssertEqual(service.display, "20", "Should be able to continue with previous result")
+ }
+
+ func testPercentageCalculation() throws {
+ let service = CalculatorService()
+
+ service.inputNumber("50")
+ service.percentage()
+
+ XCTAssertEqual(service.display, "0.5", "50% should equal 0.5")
+ }
+
+ func testSignToggle() throws {
+ let service = CalculatorService()
+
+ service.inputNumber("42")
+ service.toggleSign()
+ XCTAssertEqual(service.display, "-42", "Should toggle to negative")
+
+ service.toggleSign()
+ XCTAssertEqual(service.display, "42", "Should toggle back to positive")
+ }
+}
diff --git a/example_projects/iOS_Calculator/Config/Debug.xcconfig b/example_projects/iOS_Calculator/Config/Debug.xcconfig
new file mode 100644
index 00000000..75b2eb20
--- /dev/null
+++ b/example_projects/iOS_Calculator/Config/Debug.xcconfig
@@ -0,0 +1,8 @@
+// Debug.xcconfig
+// Debug configuration for iOS projects - minimal overrides only
+// Generated by XcodeBuildMCP
+
+#include "Shared.xcconfig"
+
+// No additional debug-specific overrides needed
+// All debug settings use Xcode project defaults
\ No newline at end of file
diff --git a/example_projects/iOS_Calculator/Config/Release.xcconfig b/example_projects/iOS_Calculator/Config/Release.xcconfig
new file mode 100644
index 00000000..67bf1f04
--- /dev/null
+++ b/example_projects/iOS_Calculator/Config/Release.xcconfig
@@ -0,0 +1,8 @@
+// Release.xcconfig
+// Release configuration for iOS projects - minimal overrides only
+// Generated by XcodeBuildMCP
+
+#include "Shared.xcconfig"
+
+// No additional release-specific overrides needed
+// All release settings use Xcode project defaults
\ No newline at end of file
diff --git a/example_projects/iOS_Calculator/Config/Shared.xcconfig b/example_projects/iOS_Calculator/Config/Shared.xcconfig
new file mode 100644
index 00000000..2f68ec6a
--- /dev/null
+++ b/example_projects/iOS_Calculator/Config/Shared.xcconfig
@@ -0,0 +1,28 @@
+// Shared.xcconfig
+// Minimal shared configuration for scaffold tool customization
+// All other settings use Xcode project defaults
+// Generated by XcodeBuildMCP
+
+// ==========================================
+// Project Identity
+// ==========================================
+PRODUCT_NAME = CalculatorApp
+PRODUCT_DISPLAY_NAME = Calculator
+PRODUCT_BUNDLE_IDENTIFIER = com.example.calculatorapp
+MARKETING_VERSION = 1.0
+CURRENT_PROJECT_VERSION = 1
+
+// ==========================================
+// Platform Configuration
+// ==========================================
+IPHONEOS_DEPLOYMENT_TARGET = 17.0
+
+// (1 == iPhone, 2 == iPad)
+TARGETED_DEVICE_FAMILY = 1,2
+
+// ==========================================
+// Info PLIST
+// ==========================================
+GENERATE_INFOPLIST_FILE = YES
+INFOPLIST_KEY_UISupportedInterfaceOrientations = UIInterfaceOrientationLandscapeRight UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationPortrait
+INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = UIInterfaceOrientationLandscapeRight UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown
diff --git a/example_projects/iOS_Calculator/Config/Tests.xcconfig b/example_projects/iOS_Calculator/Config/Tests.xcconfig
new file mode 100644
index 00000000..974d79ec
--- /dev/null
+++ b/example_projects/iOS_Calculator/Config/Tests.xcconfig
@@ -0,0 +1,12 @@
+// Tests.xcconfig
+// Test configuration for iOS projects - minimal overrides only
+// Generated by XcodeBuildMCP
+
+#include "Shared.xcconfig"
+
+// ==========================================
+// Test Target Settings (Customizable by scaffold tool)
+// ==========================================
+PRODUCT_BUNDLE_IDENTIFIER = com.example.calculatorapp
+TEST_TARGET_NAME = CalculatorApp
+DEFINES_MODULE = NO
diff --git a/example_projects/macOS/MCPTest.xcodeproj/project.pbxproj b/example_projects/macOS/MCPTest.xcodeproj/project.pbxproj
index 6b3331a6..48863fab 100644
--- a/example_projects/macOS/MCPTest.xcodeproj/project.pbxproj
+++ b/example_projects/macOS/MCPTest.xcodeproj/project.pbxproj
@@ -7,14 +7,7 @@
objects = {
/* Begin PBXContainerItemProxy section */
- 8BA9F8322D62A18100C22D5D /* PBXContainerItemProxy */ = {
- isa = PBXContainerItemProxy;
- containerPortal = 8BA9F8182D62A17D00C22D5D /* Project object */;
- proxyType = 1;
- remoteGlobalIDString = 8BA9F81F2D62A17D00C22D5D;
- remoteInfo = MCPTest;
- };
- 8BA9F83C2D62A18100C22D5D /* PBXContainerItemProxy */ = {
+ 8BCB4E2B2EF00E2600D60AD2 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 8BA9F8182D62A17D00C22D5D /* Project object */;
proxyType = 1;
@@ -25,8 +18,7 @@
/* Begin PBXFileReference section */
8BA9F8202D62A17D00C22D5D /* MCPTest.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = MCPTest.app; sourceTree = BUILT_PRODUCTS_DIR; };
- 8BA9F8312D62A18100C22D5D /* MCPTestTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = MCPTestTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
- 8BA9F83B2D62A18100C22D5D /* MCPTestUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = MCPTestUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
+ 8BCB4E272EF00E2600D60AD2 /* MCPTestTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = MCPTestTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
/* End PBXFileReference section */
/* Begin PBXFileSystemSynchronizedRootGroup section */
@@ -35,16 +27,11 @@
path = MCPTest;
sourceTree = "";
};
- 8BA9F8342D62A18100C22D5D /* MCPTestTests */ = {
+ 8BCB4E282EF00E2600D60AD2 /* MCPTestTests */ = {
isa = PBXFileSystemSynchronizedRootGroup;
path = MCPTestTests;
sourceTree = "";
};
- 8BA9F83E2D62A18100C22D5D /* MCPTestUITests */ = {
- isa = PBXFileSystemSynchronizedRootGroup;
- path = MCPTestUITests;
- sourceTree = "";
- };
/* End PBXFileSystemSynchronizedRootGroup section */
/* Begin PBXFrameworksBuildPhase section */
@@ -55,14 +42,7 @@
);
runOnlyForDeploymentPostprocessing = 0;
};
- 8BA9F82E2D62A18100C22D5D /* Frameworks */ = {
- isa = PBXFrameworksBuildPhase;
- buildActionMask = 2147483647;
- files = (
- );
- runOnlyForDeploymentPostprocessing = 0;
- };
- 8BA9F8382D62A18100C22D5D /* Frameworks */ = {
+ 8BCB4E242EF00E2600D60AD2 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
@@ -76,8 +56,7 @@
isa = PBXGroup;
children = (
8BA9F8222D62A17D00C22D5D /* MCPTest */,
- 8BA9F8342D62A18100C22D5D /* MCPTestTests */,
- 8BA9F83E2D62A18100C22D5D /* MCPTestUITests */,
+ 8BCB4E282EF00E2600D60AD2 /* MCPTestTests */,
8BA9F8212D62A17D00C22D5D /* Products */,
);
sourceTree = "";
@@ -86,8 +65,7 @@
isa = PBXGroup;
children = (
8BA9F8202D62A17D00C22D5D /* MCPTest.app */,
- 8BA9F8312D62A18100C22D5D /* MCPTestTests.xctest */,
- 8BA9F83B2D62A18100C22D5D /* MCPTestUITests.xctest */,
+ 8BCB4E272EF00E2600D60AD2 /* MCPTestTests.xctest */,
);
name = Products;
sourceTree = "";
@@ -117,52 +95,29 @@
productReference = 8BA9F8202D62A17D00C22D5D /* MCPTest.app */;
productType = "com.apple.product-type.application";
};
- 8BA9F8302D62A18100C22D5D /* MCPTestTests */ = {
+ 8BCB4E262EF00E2600D60AD2 /* MCPTestTests */ = {
isa = PBXNativeTarget;
- buildConfigurationList = 8BA9F8482D62A18100C22D5D /* Build configuration list for PBXNativeTarget "MCPTestTests" */;
+ buildConfigurationList = 8BCB4E2F2EF00E2600D60AD2 /* Build configuration list for PBXNativeTarget "MCPTestTests" */;
buildPhases = (
- 8BA9F82D2D62A18100C22D5D /* Sources */,
- 8BA9F82E2D62A18100C22D5D /* Frameworks */,
- 8BA9F82F2D62A18100C22D5D /* Resources */,
+ 8BCB4E232EF00E2600D60AD2 /* Sources */,
+ 8BCB4E242EF00E2600D60AD2 /* Frameworks */,
+ 8BCB4E252EF00E2600D60AD2 /* Resources */,
);
buildRules = (
);
dependencies = (
- 8BA9F8332D62A18100C22D5D /* PBXTargetDependency */,
+ 8BCB4E2C2EF00E2600D60AD2 /* PBXTargetDependency */,
);
fileSystemSynchronizedGroups = (
- 8BA9F8342D62A18100C22D5D /* MCPTestTests */,
+ 8BCB4E282EF00E2600D60AD2 /* MCPTestTests */,
);
name = MCPTestTests;
packageProductDependencies = (
);
productName = MCPTestTests;
- productReference = 8BA9F8312D62A18100C22D5D /* MCPTestTests.xctest */;
+ productReference = 8BCB4E272EF00E2600D60AD2 /* MCPTestTests.xctest */;
productType = "com.apple.product-type.bundle.unit-test";
};
- 8BA9F83A2D62A18100C22D5D /* MCPTestUITests */ = {
- isa = PBXNativeTarget;
- buildConfigurationList = 8BA9F84B2D62A18100C22D5D /* Build configuration list for PBXNativeTarget "MCPTestUITests" */;
- buildPhases = (
- 8BA9F8372D62A18100C22D5D /* Sources */,
- 8BA9F8382D62A18100C22D5D /* Frameworks */,
- 8BA9F8392D62A18100C22D5D /* Resources */,
- );
- buildRules = (
- );
- dependencies = (
- 8BA9F83D2D62A18100C22D5D /* PBXTargetDependency */,
- );
- fileSystemSynchronizedGroups = (
- 8BA9F83E2D62A18100C22D5D /* MCPTestUITests */,
- );
- name = MCPTestUITests;
- packageProductDependencies = (
- );
- productName = MCPTestUITests;
- productReference = 8BA9F83B2D62A18100C22D5D /* MCPTestUITests.xctest */;
- productType = "com.apple.product-type.bundle.ui-testing";
- };
/* End PBXNativeTarget section */
/* Begin PBXProject section */
@@ -170,18 +125,14 @@
isa = PBXProject;
attributes = {
BuildIndependentTargetsInParallel = 1;
- LastSwiftUpdateCheck = 1620;
+ LastSwiftUpdateCheck = 2600;
LastUpgradeCheck = 1620;
TargetAttributes = {
8BA9F81F2D62A17D00C22D5D = {
CreatedOnToolsVersion = 16.2;
};
- 8BA9F8302D62A18100C22D5D = {
- CreatedOnToolsVersion = 16.2;
- TestTargetID = 8BA9F81F2D62A17D00C22D5D;
- };
- 8BA9F83A2D62A18100C22D5D = {
- CreatedOnToolsVersion = 16.2;
+ 8BCB4E262EF00E2600D60AD2 = {
+ CreatedOnToolsVersion = 26.0;
TestTargetID = 8BA9F81F2D62A17D00C22D5D;
};
};
@@ -201,8 +152,7 @@
projectRoot = "";
targets = (
8BA9F81F2D62A17D00C22D5D /* MCPTest */,
- 8BA9F8302D62A18100C22D5D /* MCPTestTests */,
- 8BA9F83A2D62A18100C22D5D /* MCPTestUITests */,
+ 8BCB4E262EF00E2600D60AD2 /* MCPTestTests */,
);
};
/* End PBXProject section */
@@ -215,14 +165,7 @@
);
runOnlyForDeploymentPostprocessing = 0;
};
- 8BA9F82F2D62A18100C22D5D /* Resources */ = {
- isa = PBXResourcesBuildPhase;
- buildActionMask = 2147483647;
- files = (
- );
- runOnlyForDeploymentPostprocessing = 0;
- };
- 8BA9F8392D62A18100C22D5D /* Resources */ = {
+ 8BCB4E252EF00E2600D60AD2 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
@@ -239,14 +182,7 @@
);
runOnlyForDeploymentPostprocessing = 0;
};
- 8BA9F82D2D62A18100C22D5D /* Sources */ = {
- isa = PBXSourcesBuildPhase;
- buildActionMask = 2147483647;
- files = (
- );
- runOnlyForDeploymentPostprocessing = 0;
- };
- 8BA9F8372D62A18100C22D5D /* Sources */ = {
+ 8BCB4E232EF00E2600D60AD2 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
@@ -256,15 +192,10 @@
/* End PBXSourcesBuildPhase section */
/* Begin PBXTargetDependency section */
- 8BA9F8332D62A18100C22D5D /* PBXTargetDependency */ = {
- isa = PBXTargetDependency;
- target = 8BA9F81F2D62A17D00C22D5D /* MCPTest */;
- targetProxy = 8BA9F8322D62A18100C22D5D /* PBXContainerItemProxy */;
- };
- 8BA9F83D2D62A18100C22D5D /* PBXTargetDependency */ = {
+ 8BCB4E2C2EF00E2600D60AD2 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = 8BA9F81F2D62A17D00C22D5D /* MCPTest */;
- targetProxy = 8BA9F83C2D62A18100C22D5D /* PBXContainerItemProxy */;
+ targetProxy = 8BCB4E2B2EF00E2600D60AD2 /* PBXContainerItemProxy */;
};
/* End PBXTargetDependency section */
@@ -441,7 +372,7 @@
};
name = Release;
};
- 8BA9F8492D62A18100C22D5D /* Debug */ = {
+ 8BCB4E2D2EF00E2600D60AD2 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
BUNDLE_LOADER = "$(TEST_HOST)";
@@ -449,17 +380,20 @@
CURRENT_PROJECT_VERSION = 1;
DEVELOPMENT_TEAM = BR6WD3M6ZD;
GENERATE_INFOPLIST_FILE = YES;
- MACOSX_DEPLOYMENT_TARGET = 15.2;
+ MACOSX_DEPLOYMENT_TARGET = 26.0;
MARKETING_VERSION = 1.0;
- PRODUCT_BUNDLE_IDENTIFIER = com.cameroncooke.MCPTestTests;
+ PRODUCT_BUNDLE_IDENTIFIER = com.cameroncooke.test.MCPTestTests;
PRODUCT_NAME = "$(TARGET_NAME)";
+ STRING_CATALOG_GENERATE_SYMBOLS = NO;
+ SWIFT_APPROACHABLE_CONCURRENCY = YES;
SWIFT_EMIT_LOC_STRINGS = NO;
+ SWIFT_UPCOMING_FEATURE_MEMBER_IMPORT_VISIBILITY = YES;
SWIFT_VERSION = 5.0;
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/MCPTest.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/MCPTest";
};
name = Debug;
};
- 8BA9F84A2D62A18100C22D5D /* Release */ = {
+ 8BCB4E2E2EF00E2600D60AD2 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
BUNDLE_LOADER = "$(TEST_HOST)";
@@ -467,48 +401,19 @@
CURRENT_PROJECT_VERSION = 1;
DEVELOPMENT_TEAM = BR6WD3M6ZD;
GENERATE_INFOPLIST_FILE = YES;
- MACOSX_DEPLOYMENT_TARGET = 15.2;
+ MACOSX_DEPLOYMENT_TARGET = 26.0;
MARKETING_VERSION = 1.0;
- PRODUCT_BUNDLE_IDENTIFIER = com.cameroncooke.MCPTestTests;
+ PRODUCT_BUNDLE_IDENTIFIER = com.cameroncooke.test.MCPTestTests;
PRODUCT_NAME = "$(TARGET_NAME)";
+ STRING_CATALOG_GENERATE_SYMBOLS = NO;
+ SWIFT_APPROACHABLE_CONCURRENCY = YES;
SWIFT_EMIT_LOC_STRINGS = NO;
+ SWIFT_UPCOMING_FEATURE_MEMBER_IMPORT_VISIBILITY = YES;
SWIFT_VERSION = 5.0;
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/MCPTest.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/MCPTest";
};
name = Release;
};
- 8BA9F84C2D62A18100C22D5D /* Debug */ = {
- isa = XCBuildConfiguration;
- buildSettings = {
- CODE_SIGN_STYLE = Automatic;
- CURRENT_PROJECT_VERSION = 1;
- DEVELOPMENT_TEAM = BR6WD3M6ZD;
- GENERATE_INFOPLIST_FILE = YES;
- MARKETING_VERSION = 1.0;
- PRODUCT_BUNDLE_IDENTIFIER = com.cameroncooke.MCPTestUITests;
- PRODUCT_NAME = "$(TARGET_NAME)";
- SWIFT_EMIT_LOC_STRINGS = NO;
- SWIFT_VERSION = 5.0;
- TEST_TARGET_NAME = MCPTest;
- };
- name = Debug;
- };
- 8BA9F84D2D62A18100C22D5D /* Release */ = {
- isa = XCBuildConfiguration;
- buildSettings = {
- CODE_SIGN_STYLE = Automatic;
- CURRENT_PROJECT_VERSION = 1;
- DEVELOPMENT_TEAM = BR6WD3M6ZD;
- GENERATE_INFOPLIST_FILE = YES;
- MARKETING_VERSION = 1.0;
- PRODUCT_BUNDLE_IDENTIFIER = com.cameroncooke.MCPTestUITests;
- PRODUCT_NAME = "$(TARGET_NAME)";
- SWIFT_EMIT_LOC_STRINGS = NO;
- SWIFT_VERSION = 5.0;
- TEST_TARGET_NAME = MCPTest;
- };
- name = Release;
- };
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
@@ -530,20 +435,11 @@
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
- 8BA9F8482D62A18100C22D5D /* Build configuration list for PBXNativeTarget "MCPTestTests" */ = {
- isa = XCConfigurationList;
- buildConfigurations = (
- 8BA9F8492D62A18100C22D5D /* Debug */,
- 8BA9F84A2D62A18100C22D5D /* Release */,
- );
- defaultConfigurationIsVisible = 0;
- defaultConfigurationName = Release;
- };
- 8BA9F84B2D62A18100C22D5D /* Build configuration list for PBXNativeTarget "MCPTestUITests" */ = {
+ 8BCB4E2F2EF00E2600D60AD2 /* Build configuration list for PBXNativeTarget "MCPTestTests" */ = {
isa = XCConfigurationList;
buildConfigurations = (
- 8BA9F84C2D62A18100C22D5D /* Debug */,
- 8BA9F84D2D62A18100C22D5D /* Release */,
+ 8BCB4E2D2EF00E2600D60AD2 /* Debug */,
+ 8BCB4E2E2EF00E2600D60AD2 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
diff --git a/example_projects/macOS/MCPTest.xcodeproj/xcshareddata/xcschemes/MCPTest.xcscheme b/example_projects/macOS/MCPTest.xcodeproj/xcshareddata/xcschemes/MCPTest.xcscheme
new file mode 100644
index 00000000..364cf9ef
--- /dev/null
+++ b/example_projects/macOS/MCPTest.xcodeproj/xcshareddata/xcschemes/MCPTest.xcscheme
@@ -0,0 +1,91 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/example_projects/macOS/MCPTestTests/MCPTestTests.swift b/example_projects/macOS/MCPTestTests/MCPTestTests.swift
index f244a4e0..afce860a 100644
--- a/example_projects/macOS/MCPTestTests/MCPTestTests.swift
+++ b/example_projects/macOS/MCPTestTests/MCPTestTests.swift
@@ -2,11 +2,10 @@
// MCPTestTests.swift
// MCPTestTests
//
-// Created by Cameron on 16/02/2025.
+// Created by Cameron on 15/12/2025.
//
import Testing
-@testable import MCPTest
struct MCPTestTests {
diff --git a/example_projects/macOS/MCPTestUITests/MCPTestUITests.swift b/example_projects/macOS/MCPTestUITests/MCPTestUITests.swift
deleted file mode 100644
index ecc9df3e..00000000
--- a/example_projects/macOS/MCPTestUITests/MCPTestUITests.swift
+++ /dev/null
@@ -1,43 +0,0 @@
-//
-// MCPTestUITests.swift
-// MCPTestUITests
-//
-// Created by Cameron on 16/02/2025.
-//
-
-import XCTest
-
-final class MCPTestUITests: XCTestCase {
-
- override func setUpWithError() throws {
- // Put setup code here. This method is called before the invocation of each test method in the class.
-
- // In UI tests it is usually best to stop immediately when a failure occurs.
- continueAfterFailure = false
-
- // In UI tests it’s important to set the initial state - such as interface orientation - required for your tests before they run. The setUp method is a good place to do this.
- }
-
- override func tearDownWithError() throws {
- // Put teardown code here. This method is called after the invocation of each test method in the class.
- }
-
- @MainActor
- func testExample() throws {
- // UI tests must launch the application that they test.
- let app = XCUIApplication()
- app.launch()
-
- // Use XCTAssert and related functions to verify your tests produce the correct results.
- }
-
- @MainActor
- func testLaunchPerformance() throws {
- if #available(macOS 10.15, iOS 13.0, tvOS 13.0, watchOS 7.0, *) {
- // This measures how long it takes to launch your application.
- measure(metrics: [XCTApplicationLaunchMetric()]) {
- XCUIApplication().launch()
- }
- }
- }
-}
diff --git a/example_projects/macOS/MCPTestUITests/MCPTestUITestsLaunchTests.swift b/example_projects/macOS/MCPTestUITests/MCPTestUITestsLaunchTests.swift
deleted file mode 100644
index cfc46046..00000000
--- a/example_projects/macOS/MCPTestUITests/MCPTestUITestsLaunchTests.swift
+++ /dev/null
@@ -1,33 +0,0 @@
-//
-// MCPTestUITestsLaunchTests.swift
-// MCPTestUITests
-//
-// Created by Cameron on 16/02/2025.
-//
-
-import XCTest
-
-final class MCPTestUITestsLaunchTests: XCTestCase {
-
- override class var runsForEachTargetApplicationUIConfiguration: Bool {
- true
- }
-
- override func setUpWithError() throws {
- continueAfterFailure = false
- }
-
- @MainActor
- func testLaunch() throws {
- let app = XCUIApplication()
- app.launch()
-
- // Insert steps here to perform after app launch but before taking a screenshot,
- // such as logging into a test account or navigating somewhere in the app
-
- let attachment = XCTAttachment(screenshot: app.screenshot())
- attachment.name = "Launch Screen"
- attachment.lifetime = .keepAlways
- add(attachment)
- }
-}
diff --git a/example_projects/spm/.gitignore b/example_projects/spm/.gitignore
new file mode 100644
index 00000000..0023a534
--- /dev/null
+++ b/example_projects/spm/.gitignore
@@ -0,0 +1,8 @@
+.DS_Store
+/.build
+/Packages
+xcuserdata/
+DerivedData/
+.swiftpm/configuration/registries.json
+.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata
+.netrc
diff --git a/example_projects/spm/Package.resolved b/example_projects/spm/Package.resolved
new file mode 100644
index 00000000..807d6b37
--- /dev/null
+++ b/example_projects/spm/Package.resolved
@@ -0,0 +1,15 @@
+{
+ "originHash" : "7cf18911c918103f9311fb24b72f425fd83fa1521b50c6eacd4a0f8ee0c18743",
+ "pins" : [
+ {
+ "identity" : "swift-argument-parser",
+ "kind" : "remoteSourceControl",
+ "location" : "https://github.com/apple/swift-argument-parser.git",
+ "state" : {
+ "revision" : "011f0c765fb46d9cac61bca19be0527e99c98c8b",
+ "version" : "1.5.1"
+ }
+ }
+ ],
+ "version" : 3
+}
diff --git a/example_projects/spm/Package.swift b/example_projects/spm/Package.swift
new file mode 100644
index 00000000..c608908f
--- /dev/null
+++ b/example_projects/spm/Package.swift
@@ -0,0 +1,40 @@
+// swift-tools-version: 6.1
+// The swift-tools-version declares the minimum version of Swift required to build this package.
+
+import PackageDescription
+
+let package = Package(
+ name: "spm",
+ platforms: [
+ .macOS(.v15),
+ ],
+ dependencies: [
+ .package(url: "https://github.com/apple/swift-argument-parser.git", from: "1.5.1"),
+ ],
+ targets: [
+ .executableTarget(
+ name: "spm"
+ ),
+ .executableTarget(
+ name: "quick-task",
+ dependencies: [
+ "TestLib",
+ .product(name: "ArgumentParser", package: "swift-argument-parser"),
+ ]
+ ),
+ .executableTarget(
+ name: "long-server",
+ dependencies: [
+ "TestLib",
+ .product(name: "ArgumentParser", package: "swift-argument-parser"),
+ ]
+ ),
+ .target(
+ name: "TestLib"
+ ),
+ .testTarget(
+ name: "TestLibTests",
+ dependencies: ["TestLib"]
+ ),
+ ]
+)
diff --git a/example_projects/spm/Sources/TestLib/TaskManager.swift b/example_projects/spm/Sources/TestLib/TaskManager.swift
new file mode 100644
index 00000000..ea11a81e
--- /dev/null
+++ b/example_projects/spm/Sources/TestLib/TaskManager.swift
@@ -0,0 +1,75 @@
+import Foundation
+
+public class TaskManager {
+ private var isServerRunning = false
+
+ public init() {}
+
+ public func executeQuickTask(name: String, duration: Int, verbose: Bool) async {
+ if verbose {
+ print("📝 Task '\(name)' started at \(Date())")
+ }
+
+ // Simulate work with periodic output using Swift Concurrency
+ for i in 1...duration {
+ if verbose {
+ print("⚙️ Working... step \(i)/\(duration)")
+ }
+ try? await Task.sleep(for: .seconds(1))
+ }
+
+ if verbose {
+ print("🎉 Task '\(name)' completed at \(Date())")
+ } else {
+ print("Task '\(name)' completed in \(duration)s")
+ }
+ }
+
+ public func startLongRunningServer(port: Int, verbose: Bool, autoShutdown: Int) async {
+ if verbose {
+ print("🔧 Initializing server on port \(port)...")
+ }
+
+ var secondsRunning = 0
+ let startTime = Date()
+ isServerRunning = true
+
+ // Simulate server startup
+ try? await Task.sleep(for: .milliseconds(500))
+ print("✅ Server running on port \(port)")
+
+ // Main server loop using Swift Concurrency
+ while isServerRunning {
+ try? await Task.sleep(for: .seconds(1))
+ secondsRunning += 1
+
+ if verbose && secondsRunning % 5 == 0 {
+ print("📊 Server heartbeat: \(secondsRunning)s uptime")
+ }
+
+ // Handle auto-shutdown
+ if autoShutdown > 0 && secondsRunning >= autoShutdown {
+ if verbose {
+ print("⏰ Auto-shutdown triggered after \(autoShutdown)s")
+ }
+ break
+ }
+ }
+
+ let uptime = Date().timeIntervalSince(startTime)
+ print("🛑 Server stopped after \(String(format: "%.1f", uptime))s uptime")
+ isServerRunning = false
+ }
+
+ public func stopServer() {
+ isServerRunning = false
+ }
+
+ public func calculateSum(_ a: Int, _ b: Int) -> Int {
+ return a + b
+ }
+
+ public func validateInput(_ input: String) -> Bool {
+ return !input.isEmpty && input.count <= 100
+ }
+}
\ No newline at end of file
diff --git a/example_projects/spm/Sources/long-server/main.swift b/example_projects/spm/Sources/long-server/main.swift
new file mode 100644
index 00000000..98b08b58
--- /dev/null
+++ b/example_projects/spm/Sources/long-server/main.swift
@@ -0,0 +1,51 @@
+import Foundation
+import TestLib
+import ArgumentParser
+
+@main
+struct LongServer: AsyncParsableCommand {
+ static let configuration = CommandConfiguration(
+ commandName: "long-server",
+ abstract: "A long-running server that runs indefinitely until stopped"
+ )
+
+ @Option(name: .shortAndLong, help: "Port to listen on (default: 8080)")
+ var port: Int = 8080
+
+ @Flag(name: .shortAndLong, help: "Enable verbose logging")
+ var verbose: Bool = false
+
+ @Option(name: .shortAndLong, help: "Auto-shutdown after N seconds (0 = run forever)")
+ var autoShutdown: Int = 0
+
+ func run() async throws {
+ let taskManager = TaskManager()
+
+ if verbose {
+ print("🚀 Starting long-running server...")
+ print("🌐 Port: \(port)")
+ if autoShutdown > 0 {
+ print("⏰ Auto-shutdown: \(autoShutdown) seconds")
+ } else {
+ print("♾️ Running indefinitely (use SIGTERM to stop)")
+ }
+ }
+
+ // Set up signal handling for graceful shutdown
+ let signalSource = DispatchSource.makeSignalSource(signal: SIGTERM, queue: .main)
+ signalSource.setEventHandler {
+ if verbose {
+ print("\n🛑 Received SIGTERM, shutting down gracefully...")
+ }
+ taskManager.stopServer()
+ }
+ signalSource.resume()
+ signal(SIGTERM, SIG_IGN)
+
+ await taskManager.startLongRunningServer(
+ port: port,
+ verbose: verbose,
+ autoShutdown: autoShutdown
+ )
+ }
+}
\ No newline at end of file
diff --git a/example_projects/spm/Sources/quick-task/main.swift b/example_projects/spm/Sources/quick-task/main.swift
new file mode 100644
index 00000000..1a22bb9e
--- /dev/null
+++ b/example_projects/spm/Sources/quick-task/main.swift
@@ -0,0 +1,36 @@
+import Foundation
+import TestLib
+import ArgumentParser
+
+@main
+struct QuickTask: AsyncParsableCommand {
+ static let configuration = CommandConfiguration(
+ commandName: "quick-task",
+ abstract: "A quick task that finishes within 5 seconds",
+ version: "1.0.0"
+ )
+
+ @Option(name: .shortAndLong, help: "Number of seconds to work (default: 3)")
+ var duration: Int = 3
+
+ @Flag(name: .shortAndLong, help: "Enable verbose output")
+ var verbose: Bool = false
+
+ @Option(name: .shortAndLong, help: "Task name to display")
+ var taskName: String = "DefaultTask"
+
+ func run() async throws {
+ let taskManager = TaskManager()
+
+ if verbose {
+ print("🚀 Starting quick task: \(taskName)")
+ print("⏱️ Duration: \(duration) seconds")
+ }
+
+ await taskManager.executeQuickTask(name: taskName, duration: duration, verbose: verbose)
+
+ if verbose {
+ print("✅ Quick task completed successfully!")
+ }
+ }
+}
\ No newline at end of file
diff --git a/example_projects/spm/Sources/spm/main.swift b/example_projects/spm/Sources/spm/main.swift
new file mode 100644
index 00000000..f7cf60e1
--- /dev/null
+++ b/example_projects/spm/Sources/spm/main.swift
@@ -0,0 +1 @@
+print("Hello, world!")
diff --git a/example_projects/spm/Tests/TestLibTests/SimpleTests.swift b/example_projects/spm/Tests/TestLibTests/SimpleTests.swift
new file mode 100644
index 00000000..27bf893f
--- /dev/null
+++ b/example_projects/spm/Tests/TestLibTests/SimpleTests.swift
@@ -0,0 +1,44 @@
+import Testing
+
+@Test("Basic truth assertions")
+func basicTruthTest() {
+ #expect(true == true)
+ #expect(false == false)
+ #expect(true != false)
+}
+
+@Test("Basic math operations")
+func basicMathTest() {
+ #expect(2 + 2 == 4)
+ #expect(5 - 3 == 2)
+ #expect(3 * 4 == 12)
+ #expect(10 / 2 == 5)
+}
+
+@Test("String operations")
+func stringTest() {
+ let greeting = "Hello"
+ let world = "World"
+ #expect(greeting + " " + world == "Hello World")
+ #expect(greeting.count == 5)
+ #expect(world.isEmpty == false)
+}
+
+@Test("Array operations")
+func arrayTest() {
+ let numbers = [1, 2, 3, 4, 5]
+ #expect(numbers.count == 5)
+ #expect(numbers.first == 1)
+ #expect(numbers.last == 5)
+ #expect(numbers.contains(3) == true)
+}
+
+@Test("Optional handling")
+func optionalTest() {
+ let someValue: Int? = 42
+ let nilValue: Int? = nil
+
+ #expect(someValue != nil)
+ #expect(nilValue == nil)
+ #expect(someValue! == 42)
+}
diff --git a/mcp-install-dark.png b/mcp-install-dark.png
new file mode 100644
index 00000000..e3d7af98
Binary files /dev/null and b/mcp-install-dark.png differ
diff --git a/package-lock.json b/package-lock.json
index 7576e3d9..7d684512 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,145 +1,613 @@
{
"name": "xcodebuildmcp",
- "version": "1.2.0",
+ "version": "1.15.1",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "xcodebuildmcp",
- "version": "1.2.0",
+ "version": "1.15.1",
"license": "MIT",
"dependencies": {
- "@expo/xcpretty": "^4.3.2",
- "@modelcontextprotocol/sdk": "^1.6.1",
- "@types/uuid": "^10.0.0",
+ "@modelcontextprotocol/sdk": "^1.25.1",
+ "@sentry/cli": "^2.43.1",
+ "@sentry/node": "^10.5.0",
"uuid": "^11.1.0",
"zod": "^3.24.2"
},
"bin": {
- "xcodebuildmcp": "build/index.js"
+ "xcodebuildmcp": "build/index.js",
+ "xcodebuildmcp-doctor": "build/doctor-cli.js"
},
"devDependencies": {
+ "@bacons/xcode": "^1.0.0-alpha.24",
"@eslint/eslintrc": "^3.3.1",
"@eslint/js": "^9.23.0",
"@types/node": "^22.13.6",
"@typescript-eslint/eslint-plugin": "^8.28.0",
"@typescript-eslint/parser": "^8.28.0",
+ "@vitest/coverage-v8": "^3.2.4",
+ "@vitest/ui": "^3.2.4",
"eslint": "^9.23.0",
"eslint-config-prettier": "^10.1.1",
"eslint-plugin-prettier": "^5.2.5",
- "prettier": "^3.5.3",
+ "playwright": "^1.53.0",
+ "prettier": "3.6.2",
+ "ts-node": "^10.9.2",
+ "tsup": "^8.5.0",
+ "tsx": "^4.20.4",
"typescript": "^5.8.2",
- "typescript-eslint": "^8.28.0"
+ "typescript-eslint": "^8.28.0",
+ "vitest": "^3.2.4",
+ "xcode": "^3.0.1"
}
},
- "node_modules/@babel/code-frame": {
- "version": "7.10.4",
- "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.4.tgz",
- "integrity": "sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg==",
- "license": "MIT",
+ "node_modules/@ampproject/remapping": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz",
+ "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==",
+ "dev": true,
+ "license": "Apache-2.0",
"dependencies": {
- "@babel/highlight": "^7.10.4"
+ "@jridgewell/gen-mapping": "^0.3.5",
+ "@jridgewell/trace-mapping": "^0.3.24"
+ },
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@babel/helper-string-parser": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz",
+ "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.9.0"
}
},
"node_modules/@babel/helper-validator-identifier": {
- "version": "7.25.9",
- "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.9.tgz",
- "integrity": "sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==",
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.27.1.tgz",
+ "integrity": "sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==",
+ "dev": true,
"license": "MIT",
"engines": {
"node": ">=6.9.0"
}
},
- "node_modules/@babel/highlight": {
- "version": "7.25.9",
- "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.25.9.tgz",
- "integrity": "sha512-llL88JShoCsth8fF8R4SJnIn+WLvR6ccFxu1H3FlMhDontdcmZWf2HgIZ7AIqV3Xcck1idlohrN4EUBQz6klbw==",
+ "node_modules/@babel/parser": {
+ "version": "7.28.0",
+ "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.28.0.tgz",
+ "integrity": "sha512-jVZGvOxOuNSsuQuLRTh13nU0AogFlw32w/MT+LV6D3sP5WdbW61E77RnkbaO2dUvmPAYrBDJXGn5gGS6tH4j8g==",
+ "dev": true,
"license": "MIT",
"dependencies": {
- "@babel/helper-validator-identifier": "^7.25.9",
- "chalk": "^2.4.2",
- "js-tokens": "^4.0.0",
- "picocolors": "^1.0.0"
+ "@babel/types": "^7.28.0"
+ },
+ "bin": {
+ "parser": "bin/babel-parser.js"
},
"engines": {
- "node": ">=6.9.0"
+ "node": ">=6.0.0"
}
},
- "node_modules/@babel/highlight/node_modules/ansi-styles": {
- "version": "3.2.1",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
- "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+ "node_modules/@babel/types": {
+ "version": "7.28.2",
+ "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.28.2.tgz",
+ "integrity": "sha512-ruv7Ae4J5dUYULmeXw1gmb7rYRz57OWCPM57pHojnLq/3Z1CK2lNSLTCVjxVk1F/TZHwOZZrOWi0ur95BbLxNQ==",
+ "dev": true,
"license": "MIT",
"dependencies": {
- "color-convert": "^1.9.0"
+ "@babel/helper-string-parser": "^7.27.1",
+ "@babel/helper-validator-identifier": "^7.27.1"
},
"engines": {
- "node": ">=4"
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@bacons/xcode": {
+ "version": "1.0.0-alpha.25",
+ "resolved": "https://registry.npmjs.org/@bacons/xcode/-/xcode-1.0.0-alpha.25.tgz",
+ "integrity": "sha512-HE/2UXkIFrKq/ZvxvB8b1OIk47Nf+jXDYJsAVfSoxCu3pNW/Zrws3ad/HbB/wWYb+bDvr4PD2wfGuNcTRbUQNQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@expo/plist": "^0.0.18",
+ "debug": "^4.3.4",
+ "uuid": "^8.3.2"
+ }
+ },
+ "node_modules/@bacons/xcode/node_modules/uuid": {
+ "version": "8.3.2",
+ "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz",
+ "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "uuid": "dist/bin/uuid"
+ }
+ },
+ "node_modules/@bcoe/v8-coverage": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-1.0.2.tgz",
+ "integrity": "sha512-6zABk/ECA/QYSCQ1NGiVwwbQerUCZ+TQbp64Q3AgmfNvurHH0j8TtXa1qbShXA6qqkpAj4V5W8pP6mLe1mcMqA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
}
},
- "node_modules/@babel/highlight/node_modules/chalk": {
- "version": "2.4.2",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
- "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
+ "node_modules/@cspotcode/source-map-support": {
+ "version": "0.8.1",
+ "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz",
+ "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==",
+ "dev": true,
"license": "MIT",
"dependencies": {
- "ansi-styles": "^3.2.1",
- "escape-string-regexp": "^1.0.5",
- "supports-color": "^5.3.0"
+ "@jridgewell/trace-mapping": "0.3.9"
},
"engines": {
- "node": ">=4"
+ "node": ">=12"
}
},
- "node_modules/@babel/highlight/node_modules/color-convert": {
- "version": "1.9.3",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
- "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
+ "node_modules/@cspotcode/source-map-support/node_modules/@jridgewell/trace-mapping": {
+ "version": "0.3.9",
+ "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz",
+ "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==",
+ "dev": true,
"license": "MIT",
"dependencies": {
- "color-name": "1.1.3"
+ "@jridgewell/resolve-uri": "^3.0.3",
+ "@jridgewell/sourcemap-codec": "^1.4.10"
}
},
- "node_modules/@babel/highlight/node_modules/color-name": {
- "version": "1.1.3",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
- "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==",
- "license": "MIT"
+ "node_modules/@esbuild/aix-ppc64": {
+ "version": "0.25.8",
+ "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.8.tgz",
+ "integrity": "sha512-urAvrUedIqEiFR3FYSLTWQgLu5tb+m0qZw0NBEasUeo6wuqatkMDaRT+1uABiGXEu5vqgPd7FGE1BhsAIy9QVA==",
+ "cpu": [
+ "ppc64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "aix"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
},
- "node_modules/@babel/highlight/node_modules/escape-string-regexp": {
- "version": "1.0.5",
- "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
- "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==",
+ "node_modules/@esbuild/android-arm": {
+ "version": "0.25.8",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.8.tgz",
+ "integrity": "sha512-RONsAvGCz5oWyePVnLdZY/HHwA++nxYWIX1atInlaW6SEkwq6XkP3+cb825EUcRs5Vss/lGh/2YxAb5xqc07Uw==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
"license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ],
"engines": {
- "node": ">=0.8.0"
+ "node": ">=18"
}
},
- "node_modules/@babel/highlight/node_modules/has-flag": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
- "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==",
+ "node_modules/@esbuild/android-arm64": {
+ "version": "0.25.8",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.8.tgz",
+ "integrity": "sha512-OD3p7LYzWpLhZEyATcTSJ67qB5D+20vbtr6vHlHWSQYhKtzUYrETuWThmzFpZtFsBIxRvhO07+UgVA9m0i/O1w==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
"license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ],
"engines": {
- "node": ">=4"
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/android-x64": {
+ "version": "0.25.8",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.8.tgz",
+ "integrity": "sha512-yJAVPklM5+4+9dTeKwHOaA+LQkmrKFX96BM0A/2zQrbS6ENCmxc4OVoBs5dPkCCak2roAD+jKCdnmOqKszPkjA==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=18"
}
},
- "node_modules/@babel/highlight/node_modules/supports-color": {
- "version": "5.5.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
- "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
+ "node_modules/@esbuild/darwin-arm64": {
+ "version": "0.25.8",
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.8.tgz",
+ "integrity": "sha512-Jw0mxgIaYX6R8ODrdkLLPwBqHTtYHJSmzzd+QeytSugzQ0Vg4c5rDky5VgkoowbZQahCbsv1rT1KW72MPIkevw==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
"license": "MIT",
- "dependencies": {
- "has-flag": "^3.0.0"
- },
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
"engines": {
- "node": ">=4"
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/darwin-x64": {
+ "version": "0.25.8",
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.8.tgz",
+ "integrity": "sha512-Vh2gLxxHnuoQ+GjPNvDSDRpoBCUzY4Pu0kBqMBDlK4fuWbKgGtmDIeEC081xi26PPjn+1tct+Bh8FjyLlw1Zlg==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/freebsd-arm64": {
+ "version": "0.25.8",
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.8.tgz",
+ "integrity": "sha512-YPJ7hDQ9DnNe5vxOm6jaie9QsTwcKedPvizTVlqWG9GBSq+BuyWEDazlGaDTC5NGU4QJd666V0yqCBL2oWKPfA==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/freebsd-x64": {
+ "version": "0.25.8",
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.8.tgz",
+ "integrity": "sha512-MmaEXxQRdXNFsRN/KcIimLnSJrk2r5H8v+WVafRWz5xdSVmWLoITZQXcgehI2ZE6gioE6HirAEToM/RvFBeuhw==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-arm": {
+ "version": "0.25.8",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.8.tgz",
+ "integrity": "sha512-FuzEP9BixzZohl1kLf76KEVOsxtIBFwCaLupVuk4eFVnOZfU+Wsn+x5Ryam7nILV2pkq2TqQM9EZPsOBuMC+kg==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-arm64": {
+ "version": "0.25.8",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.8.tgz",
+ "integrity": "sha512-WIgg00ARWv/uYLU7lsuDK00d/hHSfES5BzdWAdAig1ioV5kaFNrtK8EqGcUBJhYqotlUByUKz5Qo6u8tt7iD/w==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-ia32": {
+ "version": "0.25.8",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.8.tgz",
+ "integrity": "sha512-A1D9YzRX1i+1AJZuFFUMP1E9fMaYY+GnSQil9Tlw05utlE86EKTUA7RjwHDkEitmLYiFsRd9HwKBPEftNdBfjg==",
+ "cpu": [
+ "ia32"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-loong64": {
+ "version": "0.25.8",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.8.tgz",
+ "integrity": "sha512-O7k1J/dwHkY1RMVvglFHl1HzutGEFFZ3kNiDMSOyUrB7WcoHGf96Sh+64nTRT26l3GMbCW01Ekh/ThKM5iI7hQ==",
+ "cpu": [
+ "loong64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-mips64el": {
+ "version": "0.25.8",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.8.tgz",
+ "integrity": "sha512-uv+dqfRazte3BzfMp8PAQXmdGHQt2oC/y2ovwpTteqrMx2lwaksiFZ/bdkXJC19ttTvNXBuWH53zy/aTj1FgGw==",
+ "cpu": [
+ "mips64el"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-ppc64": {
+ "version": "0.25.8",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.8.tgz",
+ "integrity": "sha512-GyG0KcMi1GBavP5JgAkkstMGyMholMDybAf8wF5A70CALlDM2p/f7YFE7H92eDeH/VBtFJA5MT4nRPDGg4JuzQ==",
+ "cpu": [
+ "ppc64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-riscv64": {
+ "version": "0.25.8",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.8.tgz",
+ "integrity": "sha512-rAqDYFv3yzMrq7GIcen3XP7TUEG/4LK86LUPMIz6RT8A6pRIDn0sDcvjudVZBiiTcZCY9y2SgYX2lgK3AF+1eg==",
+ "cpu": [
+ "riscv64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-s390x": {
+ "version": "0.25.8",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.8.tgz",
+ "integrity": "sha512-Xutvh6VjlbcHpsIIbwY8GVRbwoviWT19tFhgdA7DlenLGC/mbc3lBoVb7jxj9Z+eyGqvcnSyIltYUrkKzWqSvg==",
+ "cpu": [
+ "s390x"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-x64": {
+ "version": "0.25.8",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.8.tgz",
+ "integrity": "sha512-ASFQhgY4ElXh3nDcOMTkQero4b1lgubskNlhIfJrsH5OKZXDpUAKBlNS0Kx81jwOBp+HCeZqmoJuihTv57/jvQ==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/netbsd-arm64": {
+ "version": "0.25.8",
+ "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.8.tgz",
+ "integrity": "sha512-d1KfruIeohqAi6SA+gENMuObDbEjn22olAR7egqnkCD9DGBG0wsEARotkLgXDu6c4ncgWTZJtN5vcgxzWRMzcw==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "netbsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/netbsd-x64": {
+ "version": "0.25.8",
+ "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.8.tgz",
+ "integrity": "sha512-nVDCkrvx2ua+XQNyfrujIG38+YGyuy2Ru9kKVNyh5jAys6n+l44tTtToqHjino2My8VAY6Lw9H7RI73XFi66Cg==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "netbsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/openbsd-arm64": {
+ "version": "0.25.8",
+ "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.8.tgz",
+ "integrity": "sha512-j8HgrDuSJFAujkivSMSfPQSAa5Fxbvk4rgNAS5i3K+r8s1X0p1uOO2Hl2xNsGFppOeHOLAVgYwDVlmxhq5h+SQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "openbsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/openbsd-x64": {
+ "version": "0.25.8",
+ "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.8.tgz",
+ "integrity": "sha512-1h8MUAwa0VhNCDp6Af0HToI2TJFAn1uqT9Al6DJVzdIBAd21m/G0Yfc77KDM3uF3T/YaOgQq3qTJHPbTOInaIQ==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "openbsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/openharmony-arm64": {
+ "version": "0.25.8",
+ "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.25.8.tgz",
+ "integrity": "sha512-r2nVa5SIK9tSWd0kJd9HCffnDHKchTGikb//9c7HX+r+wHYCpQrSgxhlY6KWV1nFo1l4KFbsMlHk+L6fekLsUg==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "openharmony"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/sunos-x64": {
+ "version": "0.25.8",
+ "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.8.tgz",
+ "integrity": "sha512-zUlaP2S12YhQ2UzUfcCuMDHQFJyKABkAjvO5YSndMiIkMimPmxA+BYSBikWgsRpvyxuRnow4nS5NPnf9fpv41w==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "sunos"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/win32-arm64": {
+ "version": "0.25.8",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.8.tgz",
+ "integrity": "sha512-YEGFFWESlPva8hGL+zvj2z/SaK+pH0SwOM0Nc/d+rVnW7GSTFlLBGzZkuSU9kFIGIo8q9X3ucpZhu8PDN5A2sQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/win32-ia32": {
+ "version": "0.25.8",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.8.tgz",
+ "integrity": "sha512-hiGgGC6KZ5LZz58OL/+qVVoZiuZlUYlYHNAmczOm7bs2oE1XriPFi5ZHHrS8ACpV5EjySrnoCKmcbQMN+ojnHg==",
+ "cpu": [
+ "ia32"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/win32-x64": {
+ "version": "0.25.8",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.8.tgz",
+ "integrity": "sha512-cn3Yr7+OaaZq1c+2pe+8yxC8E144SReCQjN6/2ynubzYjvyqZjTXfQJpAcQpsdJq3My7XADANiYGHoFC69pLQw==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=18"
}
},
"node_modules/@eslint-community/eslint-utils": {
- "version": "4.5.1",
- "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.5.1.tgz",
- "integrity": "sha512-soEIOALTfTK6EjmKMMoLugwaP0rzkad90iIWd1hMO9ARkSAyjfMfkRRhLvD5qH7vvM0Cg72pieUfR6yh6XxC4w==",
+ "version": "4.7.0",
+ "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.7.0.tgz",
+ "integrity": "sha512-dyybb3AcajC7uha6CvhdVRJqaKyn7w2YKqKyAN37NKYgZT36w+iRb0Dymmc5qEJ549c/S31cMMSFd75bteCpCw==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -166,9 +634,9 @@
}
},
"node_modules/@eslint/config-array": {
- "version": "0.20.0",
- "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.20.0.tgz",
- "integrity": "sha512-fxlS1kkIjx8+vy2SjuCB94q3htSNrufYTXubwiBFeaQHbH6Ipi43gFJq2zCMt6PHhImH3Xmr0NksKDvchWlpQQ==",
+ "version": "0.21.0",
+ "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.21.0.tgz",
+ "integrity": "sha512-ENIdc4iLu0d93HeYirvKmrzshzofPw6VkZRKQGe9Nv46ZnWUzcF1xV01dcvEg/1wXUR61OmmlSfyeyO7EvjLxQ==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
@@ -181,9 +649,9 @@
}
},
"node_modules/@eslint/config-helpers": {
- "version": "0.2.1",
- "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.2.1.tgz",
- "integrity": "sha512-RI17tsD2frtDu/3dmI7QRrD4bedNKPM08ziRYaC5AhkGrzIAJelm9kJU1TznK+apx6V+cqRz8tfpEeG3oIyjxw==",
+ "version": "0.3.1",
+ "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.3.1.tgz",
+ "integrity": "sha512-xR93k9WhrDYpXHORXpxVL5oHj3Era7wo6k/Wd8/IsQNnZUTzkGS29lyn3nAT05v6ltUuTFVCCYDEGfy2Or/sPA==",
"dev": true,
"license": "Apache-2.0",
"engines": {
@@ -191,9 +659,9 @@
}
},
"node_modules/@eslint/core": {
- "version": "0.12.0",
- "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.12.0.tgz",
- "integrity": "sha512-cmrR6pytBuSMTaBweKoGMwu3EiHiEC+DoyupPmlZ0HxBJBtIxwe+j/E4XPIKNx+Q74c8lXKPwYawBf5glsTkHg==",
+ "version": "0.15.2",
+ "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.15.2.tgz",
+ "integrity": "sha512-78Md3/Rrxh83gCxoUc0EiciuOHsIITzLy53m3d9UyiW8y9Dj2D29FeETqyKA+BRK76tnTp6RXWb3pCay8Oyomg==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
@@ -228,13 +696,16 @@
}
},
"node_modules/@eslint/js": {
- "version": "9.24.0",
- "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.24.0.tgz",
- "integrity": "sha512-uIY/y3z0uvOGX8cp1C2fiC4+ZmBhp6yZWkojtHL1YEMnRt1Y63HB9TM17proGEmeG7HeUY+UP36F0aknKYTpYA==",
+ "version": "9.33.0",
+ "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.33.0.tgz",
+ "integrity": "sha512-5K1/mKhWaMfreBGJTwval43JJmkip0RmM+3+IuqupeSKNC/Th2Kc7ucaq5ovTSra/OOKB9c58CGSz3QMVbWt0A==",
"dev": true,
"license": "MIT",
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "url": "https://eslint.org/donate"
}
},
"node_modules/@eslint/object-schema": {
@@ -248,45 +719,41 @@
}
},
"node_modules/@eslint/plugin-kit": {
- "version": "0.2.8",
- "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.2.8.tgz",
- "integrity": "sha512-ZAoA40rNMPwSm+AeHpCq8STiNAwzWLJuP8Xv4CHIc9wv/PSuExjMrmjfYNj682vW0OOiZ1HKxzvjQr9XZIisQA==",
+ "version": "0.3.5",
+ "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.3.5.tgz",
+ "integrity": "sha512-Z5kJ+wU3oA7MMIqVR9tyZRtjYPr4OC004Q4Rw7pgOKUOKkJfZ3O24nz3WYfGRpMDNmcOi3TwQOmgm7B7Tpii0w==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
- "@eslint/core": "^0.13.0",
+ "@eslint/core": "^0.15.2",
"levn": "^0.4.1"
},
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
}
},
- "node_modules/@eslint/plugin-kit/node_modules/@eslint/core": {
- "version": "0.13.0",
- "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.13.0.tgz",
- "integrity": "sha512-yfkgDw1KR66rkT5A8ci4irzDysN7FRpq3ttJolR88OqQikAWqwA8j5VZyas+vjyBNFIJ7MfybJ9plMILI2UrCw==",
+ "node_modules/@expo/plist": {
+ "version": "0.0.18",
+ "resolved": "https://registry.npmjs.org/@expo/plist/-/plist-0.0.18.tgz",
+ "integrity": "sha512-+48gRqUiz65R21CZ/IXa7RNBXgAI/uPSdvJqoN9x1hfL44DNbUoWHgHiEXTx7XelcATpDwNTz6sHLfy0iNqf+w==",
"dev": true,
- "license": "Apache-2.0",
+ "license": "MIT",
"dependencies": {
- "@types/json-schema": "^7.0.15"
- },
- "engines": {
- "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ "@xmldom/xmldom": "~0.7.0",
+ "base64-js": "^1.2.3",
+ "xmlbuilder": "^14.0.0"
}
},
- "node_modules/@expo/xcpretty": {
- "version": "4.3.2",
- "resolved": "https://registry.npmjs.org/@expo/xcpretty/-/xcpretty-4.3.2.tgz",
- "integrity": "sha512-ReZxZ8pdnoI3tP/dNnJdnmAk7uLT4FjsKDGW7YeDdvdOMz2XCQSmSCM9IWlrXuWtMF9zeSB6WJtEhCQ41gQOfw==",
- "license": "BSD-3-Clause",
- "dependencies": {
- "@babel/code-frame": "7.10.4",
- "chalk": "^4.1.0",
- "find-up": "^5.0.0",
- "js-yaml": "^4.1.0"
+ "node_modules/@hono/node-server": {
+ "version": "1.19.7",
+ "resolved": "https://registry.npmjs.org/@hono/node-server/-/node-server-1.19.7.tgz",
+ "integrity": "sha512-vUcD0uauS7EU2caukW8z5lJKtoGMokxNbJtBiwHgpqxEXokaHCBkQUmCHhjFB1VUTWdqj25QoMkMKzgjq+uhrw==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=18.14.1"
},
- "bin": {
- "excpretty": "build/cli.js"
+ "peerDependencies": {
+ "hono": "^4"
}
},
"node_modules/@humanfs/core": {
@@ -342,9 +809,9 @@
}
},
"node_modules/@humanwhocodes/retry": {
- "version": "0.4.2",
- "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.2.tgz",
- "integrity": "sha512-xeO57FpIu4p1Ri3Jq/EXq4ClRm86dVF2z/+kvFnyqVYRavTZmaFaUBbWCOuuTh0o/g7DSsk6kc2vrS4Vl5oPOQ==",
+ "version": "0.4.3",
+ "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.3.tgz",
+ "integrity": "sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==",
"dev": true,
"license": "Apache-2.0",
"engines": {
@@ -355,27 +822,134 @@
"url": "https://github.com/sponsors/nzakas"
}
},
+ "node_modules/@isaacs/cliui": {
+ "version": "8.0.2",
+ "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz",
+ "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "string-width": "^5.1.2",
+ "string-width-cjs": "npm:string-width@^4.2.0",
+ "strip-ansi": "^7.0.1",
+ "strip-ansi-cjs": "npm:strip-ansi@^6.0.1",
+ "wrap-ansi": "^8.1.0",
+ "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0"
+ },
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@istanbuljs/schema": {
+ "version": "0.1.3",
+ "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz",
+ "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/@jridgewell/gen-mapping": {
+ "version": "0.3.12",
+ "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.12.tgz",
+ "integrity": "sha512-OuLGC46TjB5BbN1dH8JULVVZY4WTdkF7tV9Ys6wLL1rubZnCMstOhNHueU5bLCrnRuDhKPDM4g6sw4Bel5Gzqg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jridgewell/sourcemap-codec": "^1.5.0",
+ "@jridgewell/trace-mapping": "^0.3.24"
+ }
+ },
+ "node_modules/@jridgewell/resolve-uri": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz",
+ "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@jridgewell/sourcemap-codec": {
+ "version": "1.5.4",
+ "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.4.tgz",
+ "integrity": "sha512-VT2+G1VQs/9oz078bLrYbecdZKs912zQlkelYpuf+SXF+QvZDYJlbx/LSx+meSAwdDFnF8FVXW92AVjjkVmgFw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@jridgewell/trace-mapping": {
+ "version": "0.3.29",
+ "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.29.tgz",
+ "integrity": "sha512-uw6guiW/gcAGPDhLmd77/6lW8QLeiV5RUTsAX46Db6oLhGaVj4lhnPwb184s1bkc8kdVg/+h988dro8GRDpmYQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jridgewell/resolve-uri": "^3.1.0",
+ "@jridgewell/sourcemap-codec": "^1.4.14"
+ }
+ },
"node_modules/@modelcontextprotocol/sdk": {
- "version": "1.9.0",
- "resolved": "https://registry.npmjs.org/@modelcontextprotocol/sdk/-/sdk-1.9.0.tgz",
- "integrity": "sha512-Jq2EUCQpe0iyO5FGpzVYDNFR6oR53AIrwph9yWl7uSc7IWUMsrmpmSaTGra5hQNunXpM+9oit85p924jWuHzUA==",
+ "version": "1.25.1",
+ "resolved": "https://registry.npmjs.org/@modelcontextprotocol/sdk/-/sdk-1.25.1.tgz",
+ "integrity": "sha512-yO28oVFFC7EBoiKdAn+VqRm+plcfv4v0xp6osG/VsCB0NlPZWi87ajbCZZ8f/RvOFLEu7//rSRmuZZ7lMoe3gQ==",
"license": "MIT",
"dependencies": {
+ "@hono/node-server": "^1.19.7",
+ "ajv": "^8.17.1",
+ "ajv-formats": "^3.0.1",
"content-type": "^1.0.5",
"cors": "^2.8.5",
- "cross-spawn": "^7.0.3",
+ "cross-spawn": "^7.0.5",
"eventsource": "^3.0.2",
+ "eventsource-parser": "^3.0.0",
"express": "^5.0.1",
"express-rate-limit": "^7.5.0",
+ "jose": "^6.1.1",
+ "json-schema-typed": "^8.0.2",
"pkce-challenge": "^5.0.0",
"raw-body": "^3.0.0",
- "zod": "^3.23.8",
- "zod-to-json-schema": "^3.24.1"
+ "zod": "^3.25 || ^4.0",
+ "zod-to-json-schema": "^3.25.0"
},
"engines": {
"node": ">=18"
+ },
+ "peerDependencies": {
+ "@cfworker/json-schema": "^4.1.1",
+ "zod": "^3.25 || ^4.0"
+ },
+ "peerDependenciesMeta": {
+ "@cfworker/json-schema": {
+ "optional": true
+ },
+ "zod": {
+ "optional": false
+ }
}
},
+ "node_modules/@modelcontextprotocol/sdk/node_modules/ajv": {
+ "version": "8.17.1",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz",
+ "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==",
+ "license": "MIT",
+ "dependencies": {
+ "fast-deep-equal": "^3.1.3",
+ "fast-uri": "^3.0.1",
+ "json-schema-traverse": "^1.0.0",
+ "require-from-string": "^2.0.2"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/epoberezkin"
+ }
+ },
+ "node_modules/@modelcontextprotocol/sdk/node_modules/json-schema-traverse": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz",
+ "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==",
+ "license": "MIT"
+ },
"node_modules/@nodelib/fs.scandir": {
"version": "2.1.5",
"resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
@@ -414,1090 +988,4007 @@
"node": ">= 8"
}
},
- "node_modules/@pkgr/core": {
- "version": "0.2.1",
- "resolved": "https://registry.npmjs.org/@pkgr/core/-/core-0.2.1.tgz",
- "integrity": "sha512-VzgHzGblFmUeBmmrk55zPyrQIArQN4vujc9shWytaPdB3P7qhi0cpaiKIr7tlCmFv2lYUwnLospIqjL9ZSAhhg==",
- "dev": true,
- "license": "MIT",
+ "node_modules/@opentelemetry/api": {
+ "version": "1.9.0",
+ "resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-1.9.0.tgz",
+ "integrity": "sha512-3giAOQvZiH5F9bMlMiv8+GSPMeqg0dbaeo58/0SlA9sxSqZhnUtxzX9/2FzyhS9sWQf5S0GJE0AKBrFqjpeYcg==",
+ "license": "Apache-2.0",
"engines": {
- "node": "^12.20.0 || ^14.18.0 || >=16.0.0"
- },
- "funding": {
- "url": "https://opencollective.com/unts"
+ "node": ">=8.0.0"
}
},
- "node_modules/@types/estree": {
- "version": "1.0.7",
- "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.7.tgz",
- "integrity": "sha512-w28IoSUCJpidD/TGviZwwMJckNESJZXFu7NBZ5YJ4mEUnNraUn9Pm8HSZm/jDF1pDWYKspWE7oVphigUPRakIQ==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/@types/json-schema": {
- "version": "7.0.15",
- "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz",
- "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/@types/node": {
- "version": "22.14.0",
- "resolved": "https://registry.npmjs.org/@types/node/-/node-22.14.0.tgz",
- "integrity": "sha512-Kmpl+z84ILoG+3T/zQFyAJsU6EPTmOCj8/2+83fSN6djd6I4o7uOuGIH6vq3PrjY5BGitSbFuMN18j3iknubbA==",
- "dev": true,
- "license": "MIT",
+ "node_modules/@opentelemetry/api-logs": {
+ "version": "0.203.0",
+ "resolved": "https://registry.npmjs.org/@opentelemetry/api-logs/-/api-logs-0.203.0.tgz",
+ "integrity": "sha512-9B9RU0H7Ya1Dx/Rkyc4stuBZSGVQF27WigitInx2QQoj6KUpEFYPKoWjdFTunJYxmXmh17HeBvbMa1EhGyPmqQ==",
+ "license": "Apache-2.0",
"dependencies": {
- "undici-types": "~6.21.0"
+ "@opentelemetry/api": "^1.3.0"
+ },
+ "engines": {
+ "node": ">=8.0.0"
}
},
- "node_modules/@types/uuid": {
- "version": "10.0.0",
- "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-10.0.0.tgz",
- "integrity": "sha512-7gqG38EyHgyP1S+7+xomFtL+ZNHcKv6DwNaCZmJmo1vgMugyF3TCnXVg4t1uk89mLNwnLtnY3TpOpCOyp1/xHQ==",
- "license": "MIT"
+ "node_modules/@opentelemetry/context-async-hooks": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/@opentelemetry/context-async-hooks/-/context-async-hooks-2.0.1.tgz",
+ "integrity": "sha512-XuY23lSI3d4PEqKA+7SLtAgwqIfc6E/E9eAQWLN1vlpC53ybO3o6jW4BsXo1xvz9lYyyWItfQDDLzezER01mCw==",
+ "license": "Apache-2.0",
+ "engines": {
+ "node": "^18.19.0 || >=20.6.0"
+ },
+ "peerDependencies": {
+ "@opentelemetry/api": ">=1.0.0 <1.10.0"
+ }
},
- "node_modules/@typescript-eslint/eslint-plugin": {
- "version": "8.29.1",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.29.1.tgz",
- "integrity": "sha512-ba0rr4Wfvg23vERs3eB+P3lfj2E+2g3lhWcCVukUuhtcdUx5lSIFZlGFEBHKr+3zizDa/TvZTptdNHVZWAkSBg==",
- "dev": true,
- "license": "MIT",
+ "node_modules/@opentelemetry/core": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-2.0.1.tgz",
+ "integrity": "sha512-MaZk9SJIDgo1peKevlbhP6+IwIiNPNmswNL4AF0WaQJLbHXjr9SrZMgS12+iqr9ToV4ZVosCcc0f8Rg67LXjxw==",
+ "license": "Apache-2.0",
"dependencies": {
- "@eslint-community/regexpp": "^4.10.0",
- "@typescript-eslint/scope-manager": "8.29.1",
- "@typescript-eslint/type-utils": "8.29.1",
- "@typescript-eslint/utils": "8.29.1",
- "@typescript-eslint/visitor-keys": "8.29.1",
- "graphemer": "^1.4.0",
- "ignore": "^5.3.1",
- "natural-compare": "^1.4.0",
- "ts-api-utils": "^2.0.1"
+ "@opentelemetry/semantic-conventions": "^1.29.0"
},
"engines": {
- "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/typescript-eslint"
+ "node": "^18.19.0 || >=20.6.0"
},
"peerDependencies": {
- "@typescript-eslint/parser": "^8.0.0 || ^8.0.0-alpha.0",
- "eslint": "^8.57.0 || ^9.0.0",
- "typescript": ">=4.8.4 <5.9.0"
+ "@opentelemetry/api": ">=1.0.0 <1.10.0"
}
},
- "node_modules/@typescript-eslint/parser": {
- "version": "8.29.1",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.29.1.tgz",
- "integrity": "sha512-zczrHVEqEaTwh12gWBIJWj8nx+ayDcCJs06yoNMY0kwjMWDM6+kppljY+BxWI06d2Ja+h4+WdufDcwMnnMEWmg==",
- "dev": true,
- "license": "MIT",
+ "node_modules/@opentelemetry/instrumentation": {
+ "version": "0.203.0",
+ "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation/-/instrumentation-0.203.0.tgz",
+ "integrity": "sha512-ke1qyM+3AK2zPuBPb6Hk/GCsc5ewbLvPNkEuELx/JmANeEp6ZjnZ+wypPAJSucTw0wvCGrUaibDSdcrGFoWxKQ==",
+ "license": "Apache-2.0",
"dependencies": {
- "@typescript-eslint/scope-manager": "8.29.1",
- "@typescript-eslint/types": "8.29.1",
- "@typescript-eslint/typescript-estree": "8.29.1",
- "@typescript-eslint/visitor-keys": "8.29.1",
- "debug": "^4.3.4"
+ "@opentelemetry/api-logs": "0.203.0",
+ "import-in-the-middle": "^1.8.1",
+ "require-in-the-middle": "^7.1.1"
},
"engines": {
- "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/typescript-eslint"
+ "node": "^18.19.0 || >=20.6.0"
},
"peerDependencies": {
- "eslint": "^8.57.0 || ^9.0.0",
- "typescript": ">=4.8.4 <5.9.0"
+ "@opentelemetry/api": "^1.3.0"
}
},
- "node_modules/@typescript-eslint/scope-manager": {
- "version": "8.29.1",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.29.1.tgz",
- "integrity": "sha512-2nggXGX5F3YrsGN08pw4XpMLO1Rgtnn4AzTegC2MDesv6q3QaTU5yU7IbS1tf1IwCR0Hv/1EFygLn9ms6LIpDA==",
- "dev": true,
- "license": "MIT",
+ "node_modules/@opentelemetry/instrumentation-amqplib": {
+ "version": "0.50.0",
+ "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-amqplib/-/instrumentation-amqplib-0.50.0.tgz",
+ "integrity": "sha512-kwNs/itehHG/qaQBcVrLNcvXVPW0I4FCOVtw3LHMLdYIqD7GJ6Yv2nX+a4YHjzbzIeRYj8iyMp0Bl7tlkidq5w==",
+ "license": "Apache-2.0",
"dependencies": {
- "@typescript-eslint/types": "8.29.1",
- "@typescript-eslint/visitor-keys": "8.29.1"
+ "@opentelemetry/core": "^2.0.0",
+ "@opentelemetry/instrumentation": "^0.203.0",
+ "@opentelemetry/semantic-conventions": "^1.27.0"
},
"engines": {
- "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ "node": "^18.19.0 || >=20.6.0"
},
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/typescript-eslint"
+ "peerDependencies": {
+ "@opentelemetry/api": "^1.3.0"
}
},
- "node_modules/@typescript-eslint/type-utils": {
- "version": "8.29.1",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.29.1.tgz",
- "integrity": "sha512-DkDUSDwZVCYN71xA4wzySqqcZsHKic53A4BLqmrWFFpOpNSoxX233lwGu/2135ymTCR04PoKiEEEvN1gFYg4Tw==",
- "dev": true,
- "license": "MIT",
+ "node_modules/@opentelemetry/instrumentation-connect": {
+ "version": "0.47.0",
+ "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-connect/-/instrumentation-connect-0.47.0.tgz",
+ "integrity": "sha512-pjenvjR6+PMRb6/4X85L4OtkQCootgb/Jzh/l/Utu3SJHBid1F+gk9sTGU2FWuhhEfV6P7MZ7BmCdHXQjgJ42g==",
+ "license": "Apache-2.0",
"dependencies": {
- "@typescript-eslint/typescript-estree": "8.29.1",
- "@typescript-eslint/utils": "8.29.1",
- "debug": "^4.3.4",
- "ts-api-utils": "^2.0.1"
+ "@opentelemetry/core": "^2.0.0",
+ "@opentelemetry/instrumentation": "^0.203.0",
+ "@opentelemetry/semantic-conventions": "^1.27.0",
+ "@types/connect": "3.4.38"
},
"engines": {
- "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/typescript-eslint"
+ "node": "^18.19.0 || >=20.6.0"
},
"peerDependencies": {
- "eslint": "^8.57.0 || ^9.0.0",
- "typescript": ">=4.8.4 <5.9.0"
+ "@opentelemetry/api": "^1.3.0"
}
},
- "node_modules/@typescript-eslint/types": {
- "version": "8.29.1",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.29.1.tgz",
- "integrity": "sha512-VT7T1PuJF1hpYC3AGm2rCgJBjHL3nc+A/bhOp9sGMKfi5v0WufsX/sHCFBfNTx2F+zA6qBc/PD0/kLRLjdt8mQ==",
- "dev": true,
- "license": "MIT",
+ "node_modules/@opentelemetry/instrumentation-dataloader": {
+ "version": "0.21.0",
+ "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-dataloader/-/instrumentation-dataloader-0.21.0.tgz",
+ "integrity": "sha512-Xu4CZ1bfhdkV3G6iVHFgKTgHx8GbKSqrTU01kcIJRGHpowVnyOPEv1CW5ow+9GU2X4Eki8zoNuVUenFc3RluxQ==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@opentelemetry/instrumentation": "^0.203.0"
+ },
"engines": {
- "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ "node": "^18.19.0 || >=20.6.0"
},
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/typescript-eslint"
+ "peerDependencies": {
+ "@opentelemetry/api": "^1.3.0"
}
},
- "node_modules/@typescript-eslint/typescript-estree": {
- "version": "8.29.1",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.29.1.tgz",
- "integrity": "sha512-l1enRoSaUkQxOQnbi0KPUtqeZkSiFlqrx9/3ns2rEDhGKfTa+88RmXqedC1zmVTOWrLc2e6DEJrTA51C9iLH5g==",
- "dev": true,
- "license": "MIT",
+ "node_modules/@opentelemetry/instrumentation-express": {
+ "version": "0.52.0",
+ "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-express/-/instrumentation-express-0.52.0.tgz",
+ "integrity": "sha512-W7pizN0Wh1/cbNhhTf7C62NpyYw7VfCFTYg0DYieSTrtPBT1vmoSZei19wfKLnrMsz3sHayCg0HxCVL2c+cz5w==",
+ "license": "Apache-2.0",
"dependencies": {
- "@typescript-eslint/types": "8.29.1",
- "@typescript-eslint/visitor-keys": "8.29.1",
- "debug": "^4.3.4",
- "fast-glob": "^3.3.2",
- "is-glob": "^4.0.3",
- "minimatch": "^9.0.4",
- "semver": "^7.6.0",
- "ts-api-utils": "^2.0.1"
+ "@opentelemetry/core": "^2.0.0",
+ "@opentelemetry/instrumentation": "^0.203.0",
+ "@opentelemetry/semantic-conventions": "^1.27.0"
},
"engines": {
- "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/typescript-eslint"
+ "node": "^18.19.0 || >=20.6.0"
},
"peerDependencies": {
- "typescript": ">=4.8.4 <5.9.0"
+ "@opentelemetry/api": "^1.3.0"
}
},
- "node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
- "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
- "dev": true,
- "license": "MIT",
+ "node_modules/@opentelemetry/instrumentation-fs": {
+ "version": "0.23.0",
+ "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-fs/-/instrumentation-fs-0.23.0.tgz",
+ "integrity": "sha512-Puan+QopWHA/KNYvDfOZN6M/JtF6buXEyD934vrb8WhsX1/FuM7OtoMlQyIqAadnE8FqqDL4KDPiEfCQH6pQcQ==",
+ "license": "Apache-2.0",
"dependencies": {
- "balanced-match": "^1.0.0"
+ "@opentelemetry/core": "^2.0.0",
+ "@opentelemetry/instrumentation": "^0.203.0"
+ },
+ "engines": {
+ "node": "^18.19.0 || >=20.6.0"
+ },
+ "peerDependencies": {
+ "@opentelemetry/api": "^1.3.0"
}
},
- "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": {
- "version": "9.0.5",
- "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz",
- "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==",
- "dev": true,
- "license": "ISC",
+ "node_modules/@opentelemetry/instrumentation-generic-pool": {
+ "version": "0.47.0",
+ "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-generic-pool/-/instrumentation-generic-pool-0.47.0.tgz",
+ "integrity": "sha512-UfHqf3zYK+CwDwEtTjaD12uUqGGTswZ7ofLBEdQ4sEJp9GHSSJMQ2hT3pgBxyKADzUdoxQAv/7NqvL42ZI+Qbw==",
+ "license": "Apache-2.0",
"dependencies": {
- "brace-expansion": "^2.0.1"
+ "@opentelemetry/instrumentation": "^0.203.0"
},
"engines": {
- "node": ">=16 || 14 >=14.17"
+ "node": "^18.19.0 || >=20.6.0"
},
- "funding": {
- "url": "https://github.com/sponsors/isaacs"
+ "peerDependencies": {
+ "@opentelemetry/api": "^1.3.0"
}
},
- "node_modules/@typescript-eslint/utils": {
- "version": "8.29.1",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.29.1.tgz",
- "integrity": "sha512-QAkFEbytSaB8wnmB+DflhUPz6CLbFWE2SnSCrRMEa+KnXIzDYbpsn++1HGvnfAsUY44doDXmvRkO5shlM/3UfA==",
- "dev": true,
- "license": "MIT",
+ "node_modules/@opentelemetry/instrumentation-graphql": {
+ "version": "0.51.0",
+ "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-graphql/-/instrumentation-graphql-0.51.0.tgz",
+ "integrity": "sha512-LchkOu9X5DrXAnPI1+Z06h/EH/zC7D6sA86hhPrk3evLlsJTz0grPrkL/yUJM9Ty0CL/y2HSvmWQCjbJEz/ADg==",
+ "license": "Apache-2.0",
"dependencies": {
- "@eslint-community/eslint-utils": "^4.4.0",
- "@typescript-eslint/scope-manager": "8.29.1",
- "@typescript-eslint/types": "8.29.1",
- "@typescript-eslint/typescript-estree": "8.29.1"
+ "@opentelemetry/instrumentation": "^0.203.0"
},
"engines": {
- "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/typescript-eslint"
+ "node": "^18.19.0 || >=20.6.0"
},
"peerDependencies": {
- "eslint": "^8.57.0 || ^9.0.0",
- "typescript": ">=4.8.4 <5.9.0"
+ "@opentelemetry/api": "^1.3.0"
}
},
- "node_modules/@typescript-eslint/visitor-keys": {
- "version": "8.29.1",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.29.1.tgz",
- "integrity": "sha512-RGLh5CRaUEf02viP5c1Vh1cMGffQscyHe7HPAzGpfmfflFg1wUz2rYxd+OZqwpeypYvZ8UxSxuIpF++fmOzEcg==",
- "dev": true,
- "license": "MIT",
+ "node_modules/@opentelemetry/instrumentation-hapi": {
+ "version": "0.50.0",
+ "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-hapi/-/instrumentation-hapi-0.50.0.tgz",
+ "integrity": "sha512-5xGusXOFQXKacrZmDbpHQzqYD1gIkrMWuwvlrEPkYOsjUqGUjl1HbxCsn5Y9bUXOCgP1Lj6A4PcKt1UiJ2MujA==",
+ "license": "Apache-2.0",
"dependencies": {
- "@typescript-eslint/types": "8.29.1",
- "eslint-visitor-keys": "^4.2.0"
+ "@opentelemetry/core": "^2.0.0",
+ "@opentelemetry/instrumentation": "^0.203.0",
+ "@opentelemetry/semantic-conventions": "^1.27.0"
},
"engines": {
- "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ "node": "^18.19.0 || >=20.6.0"
},
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/typescript-eslint"
+ "peerDependencies": {
+ "@opentelemetry/api": "^1.3.0"
}
},
- "node_modules/@typescript-eslint/visitor-keys/node_modules/eslint-visitor-keys": {
- "version": "4.2.0",
- "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.0.tgz",
- "integrity": "sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==",
- "dev": true,
+ "node_modules/@opentelemetry/instrumentation-http": {
+ "version": "0.203.0",
+ "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-http/-/instrumentation-http-0.203.0.tgz",
+ "integrity": "sha512-y3uQAcCOAwnO6vEuNVocmpVzG3PER6/YZqbPbbffDdJ9te5NkHEkfSMNzlC3+v7KlE+WinPGc3N7MR30G1HY2g==",
"license": "Apache-2.0",
+ "dependencies": {
+ "@opentelemetry/core": "2.0.1",
+ "@opentelemetry/instrumentation": "0.203.0",
+ "@opentelemetry/semantic-conventions": "^1.29.0",
+ "forwarded-parse": "2.1.2"
+ },
"engines": {
- "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ "node": "^18.19.0 || >=20.6.0"
},
- "funding": {
- "url": "https://opencollective.com/eslint"
+ "peerDependencies": {
+ "@opentelemetry/api": "^1.3.0"
}
},
- "node_modules/accepts": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/accepts/-/accepts-2.0.0.tgz",
- "integrity": "sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng==",
- "license": "MIT",
+ "node_modules/@opentelemetry/instrumentation-ioredis": {
+ "version": "0.51.0",
+ "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-ioredis/-/instrumentation-ioredis-0.51.0.tgz",
+ "integrity": "sha512-9IUws0XWCb80NovS+17eONXsw1ZJbHwYYMXiwsfR9TSurkLV5UNbRSKb9URHO+K+pIJILy9wCxvyiOneMr91Ig==",
+ "license": "Apache-2.0",
"dependencies": {
- "mime-types": "^3.0.0",
- "negotiator": "^1.0.0"
+ "@opentelemetry/instrumentation": "^0.203.0",
+ "@opentelemetry/redis-common": "^0.38.0",
+ "@opentelemetry/semantic-conventions": "^1.27.0"
},
"engines": {
- "node": ">= 0.6"
+ "node": "^18.19.0 || >=20.6.0"
+ },
+ "peerDependencies": {
+ "@opentelemetry/api": "^1.3.0"
}
},
- "node_modules/acorn": {
- "version": "8.14.1",
- "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.1.tgz",
- "integrity": "sha512-OvQ/2pUDKmgfCg++xsTX1wGxfTaszcHVcTctW4UJB4hibJx2HXxxO5UmVgyjMa+ZDsiaf5wWLXYpRWMmBI0QHg==",
- "dev": true,
- "license": "MIT",
- "bin": {
- "acorn": "bin/acorn"
+ "node_modules/@opentelemetry/instrumentation-kafkajs": {
+ "version": "0.12.0",
+ "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-kafkajs/-/instrumentation-kafkajs-0.12.0.tgz",
+ "integrity": "sha512-bIe4aSAAxytp88nzBstgr6M7ZiEpW6/D1/SuKXdxxuprf18taVvFL2H5BDNGZ7A14K27haHqzYqtCTqFXHZOYg==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@opentelemetry/instrumentation": "^0.203.0",
+ "@opentelemetry/semantic-conventions": "^1.30.0"
},
"engines": {
- "node": ">=0.4.0"
+ "node": "^18.19.0 || >=20.6.0"
+ },
+ "peerDependencies": {
+ "@opentelemetry/api": "^1.3.0"
}
},
- "node_modules/acorn-jsx": {
- "version": "5.3.2",
- "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz",
- "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==",
- "dev": true,
- "license": "MIT",
+ "node_modules/@opentelemetry/instrumentation-knex": {
+ "version": "0.48.0",
+ "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-knex/-/instrumentation-knex-0.48.0.tgz",
+ "integrity": "sha512-V5wuaBPv/lwGxuHjC6Na2JFRjtPgstw19jTFl1B1b6zvaX8zVDYUDaR5hL7glnQtUSCMktPttQsgK4dhXpddcA==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@opentelemetry/instrumentation": "^0.203.0",
+ "@opentelemetry/semantic-conventions": "^1.33.1"
+ },
+ "engines": {
+ "node": "^18.19.0 || >=20.6.0"
+ },
"peerDependencies": {
- "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0"
+ "@opentelemetry/api": "^1.3.0"
}
},
- "node_modules/ajv": {
- "version": "6.12.6",
- "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
- "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
- "dev": true,
- "license": "MIT",
+ "node_modules/@opentelemetry/instrumentation-koa": {
+ "version": "0.51.0",
+ "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-koa/-/instrumentation-koa-0.51.0.tgz",
+ "integrity": "sha512-XNLWeMTMG1/EkQBbgPYzCeBD0cwOrfnn8ao4hWgLv0fNCFQu1kCsJYygz2cvKuCs340RlnG4i321hX7R8gj3Rg==",
+ "license": "Apache-2.0",
"dependencies": {
- "fast-deep-equal": "^3.1.1",
- "fast-json-stable-stringify": "^2.0.0",
- "json-schema-traverse": "^0.4.1",
- "uri-js": "^4.2.2"
+ "@opentelemetry/core": "^2.0.0",
+ "@opentelemetry/instrumentation": "^0.203.0",
+ "@opentelemetry/semantic-conventions": "^1.27.0"
},
- "funding": {
- "type": "github",
- "url": "https://github.com/sponsors/epoberezkin"
+ "engines": {
+ "node": "^18.19.0 || >=20.6.0"
+ },
+ "peerDependencies": {
+ "@opentelemetry/api": "^1.3.0"
}
},
- "node_modules/ansi-styles": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
- "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
- "license": "MIT",
+ "node_modules/@opentelemetry/instrumentation-lru-memoizer": {
+ "version": "0.48.0",
+ "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-lru-memoizer/-/instrumentation-lru-memoizer-0.48.0.tgz",
+ "integrity": "sha512-KUW29wfMlTPX1wFz+NNrmE7IzN7NWZDrmFWHM/VJcmFEuQGnnBuTIdsP55CnBDxKgQ/qqYFp4udQFNtjeFosPw==",
+ "license": "Apache-2.0",
"dependencies": {
- "color-convert": "^2.0.1"
+ "@opentelemetry/instrumentation": "^0.203.0"
},
"engines": {
- "node": ">=8"
+ "node": "^18.19.0 || >=20.6.0"
},
- "funding": {
- "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ "peerDependencies": {
+ "@opentelemetry/api": "^1.3.0"
}
},
- "node_modules/argparse": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
- "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
- "license": "Python-2.0"
+ "node_modules/@opentelemetry/instrumentation-mongodb": {
+ "version": "0.56.0",
+ "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-mongodb/-/instrumentation-mongodb-0.56.0.tgz",
+ "integrity": "sha512-YG5IXUUmxX3Md2buVMvxm9NWlKADrnavI36hbJsihqqvBGsWnIfguf0rUP5Srr0pfPqhQjUP+agLMsvu0GmUpA==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@opentelemetry/instrumentation": "^0.203.0",
+ "@opentelemetry/semantic-conventions": "^1.27.0"
+ },
+ "engines": {
+ "node": "^18.19.0 || >=20.6.0"
+ },
+ "peerDependencies": {
+ "@opentelemetry/api": "^1.3.0"
+ }
},
- "node_modules/balanced-match": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
- "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
- "dev": true,
- "license": "MIT"
+ "node_modules/@opentelemetry/instrumentation-mongoose": {
+ "version": "0.50.0",
+ "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-mongoose/-/instrumentation-mongoose-0.50.0.tgz",
+ "integrity": "sha512-Am8pk1Ct951r4qCiqkBcGmPIgGhoDiFcRtqPSLbJrUZqEPUsigjtMjoWDRLG1Ki1NHgOF7D0H7d+suWz1AAizw==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@opentelemetry/core": "^2.0.0",
+ "@opentelemetry/instrumentation": "^0.203.0",
+ "@opentelemetry/semantic-conventions": "^1.27.0"
+ },
+ "engines": {
+ "node": "^18.19.0 || >=20.6.0"
+ },
+ "peerDependencies": {
+ "@opentelemetry/api": "^1.3.0"
+ }
},
- "node_modules/body-parser": {
- "version": "2.2.0",
- "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-2.2.0.tgz",
- "integrity": "sha512-02qvAaxv8tp7fBa/mw1ga98OGm+eCbqzJOKoRt70sLmfEEi+jyBYVTDGfCL/k06/4EMk/z01gCe7HoCH/f2LTg==",
- "license": "MIT",
+ "node_modules/@opentelemetry/instrumentation-mysql": {
+ "version": "0.49.0",
+ "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-mysql/-/instrumentation-mysql-0.49.0.tgz",
+ "integrity": "sha512-QU9IUNqNsrlfE3dJkZnFHqLjlndiU39ll/YAAEvWE40sGOCi9AtOF6rmEGzJ1IswoZ3oyePV7q2MP8SrhJfVAA==",
+ "license": "Apache-2.0",
"dependencies": {
- "bytes": "^3.1.2",
- "content-type": "^1.0.5",
- "debug": "^4.4.0",
- "http-errors": "^2.0.0",
- "iconv-lite": "^0.6.3",
- "on-finished": "^2.4.1",
- "qs": "^6.14.0",
- "raw-body": "^3.0.0",
- "type-is": "^2.0.0"
+ "@opentelemetry/instrumentation": "^0.203.0",
+ "@opentelemetry/semantic-conventions": "^1.27.0",
+ "@types/mysql": "2.15.27"
},
"engines": {
- "node": ">=18"
+ "node": "^18.19.0 || >=20.6.0"
+ },
+ "peerDependencies": {
+ "@opentelemetry/api": "^1.3.0"
}
},
- "node_modules/brace-expansion": {
- "version": "1.1.11",
- "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
- "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
- "dev": true,
- "license": "MIT",
+ "node_modules/@opentelemetry/instrumentation-mysql2": {
+ "version": "0.49.0",
+ "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-mysql2/-/instrumentation-mysql2-0.49.0.tgz",
+ "integrity": "sha512-dCub9wc02mkJWNyHdVEZ7dvRzy295SmNJa+LrAJY2a/+tIiVBQqEAajFzKwp9zegVVnel9L+WORu34rGLQDzxA==",
+ "license": "Apache-2.0",
"dependencies": {
- "balanced-match": "^1.0.0",
- "concat-map": "0.0.1"
+ "@opentelemetry/instrumentation": "^0.203.0",
+ "@opentelemetry/semantic-conventions": "^1.27.0",
+ "@opentelemetry/sql-common": "^0.41.0"
+ },
+ "engines": {
+ "node": "^18.19.0 || >=20.6.0"
+ },
+ "peerDependencies": {
+ "@opentelemetry/api": "^1.3.0"
}
},
- "node_modules/braces": {
- "version": "3.0.3",
- "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz",
- "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==",
- "dev": true,
- "license": "MIT",
+ "node_modules/@opentelemetry/instrumentation-pg": {
+ "version": "0.55.0",
+ "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-pg/-/instrumentation-pg-0.55.0.tgz",
+ "integrity": "sha512-yfJ5bYE7CnkW/uNsnrwouG/FR7nmg09zdk2MSs7k0ZOMkDDAE3WBGpVFFApGgNu2U+gtzLgEzOQG4I/X+60hXw==",
+ "license": "Apache-2.0",
"dependencies": {
- "fill-range": "^7.1.1"
+ "@opentelemetry/core": "^2.0.0",
+ "@opentelemetry/instrumentation": "^0.203.0",
+ "@opentelemetry/semantic-conventions": "^1.27.0",
+ "@opentelemetry/sql-common": "^0.41.0",
+ "@types/pg": "8.15.4",
+ "@types/pg-pool": "2.0.6"
},
"engines": {
- "node": ">=8"
+ "node": "^18.19.0 || >=20.6.0"
+ },
+ "peerDependencies": {
+ "@opentelemetry/api": "^1.3.0"
}
},
- "node_modules/bytes": {
- "version": "3.1.2",
- "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz",
- "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==",
- "license": "MIT",
+ "node_modules/@opentelemetry/instrumentation-redis": {
+ "version": "0.51.0",
+ "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-redis/-/instrumentation-redis-0.51.0.tgz",
+ "integrity": "sha512-uL/GtBA0u72YPPehwOvthAe+Wf8k3T+XQPBssJmTYl6fzuZjNq8zTfxVFhl9nRFjFVEe+CtiYNT0Q3AyqW1Z0A==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@opentelemetry/instrumentation": "^0.203.0",
+ "@opentelemetry/redis-common": "^0.38.0",
+ "@opentelemetry/semantic-conventions": "^1.27.0"
+ },
"engines": {
- "node": ">= 0.8"
+ "node": "^18.19.0 || >=20.6.0"
+ },
+ "peerDependencies": {
+ "@opentelemetry/api": "^1.3.0"
}
},
- "node_modules/call-bind-apply-helpers": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz",
- "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==",
- "license": "MIT",
+ "node_modules/@opentelemetry/instrumentation-tedious": {
+ "version": "0.22.0",
+ "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-tedious/-/instrumentation-tedious-0.22.0.tgz",
+ "integrity": "sha512-XrrNSUCyEjH1ax9t+Uo6lv0S2FCCykcF7hSxBMxKf7Xn0bPRxD3KyFUZy25aQXzbbbUHhtdxj3r2h88SfEM3aA==",
+ "license": "Apache-2.0",
"dependencies": {
- "es-errors": "^1.3.0",
- "function-bind": "^1.1.2"
+ "@opentelemetry/instrumentation": "^0.203.0",
+ "@opentelemetry/semantic-conventions": "^1.27.0",
+ "@types/tedious": "^4.0.14"
},
"engines": {
- "node": ">= 0.4"
+ "node": "^18.19.0 || >=20.6.0"
+ },
+ "peerDependencies": {
+ "@opentelemetry/api": "^1.3.0"
}
},
- "node_modules/call-bound": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz",
- "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==",
- "license": "MIT",
+ "node_modules/@opentelemetry/instrumentation-undici": {
+ "version": "0.14.0",
+ "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-undici/-/instrumentation-undici-0.14.0.tgz",
+ "integrity": "sha512-2HN+7ztxAReXuxzrtA3WboAKlfP5OsPA57KQn2AdYZbJ3zeRPcLXyW4uO/jpLE6PLm0QRtmeGCmfYpqRlwgSwg==",
+ "license": "Apache-2.0",
"dependencies": {
- "call-bind-apply-helpers": "^1.0.2",
- "get-intrinsic": "^1.3.0"
+ "@opentelemetry/core": "^2.0.0",
+ "@opentelemetry/instrumentation": "^0.203.0"
},
"engines": {
- "node": ">= 0.4"
+ "node": "^18.19.0 || >=20.6.0"
},
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
+ "peerDependencies": {
+ "@opentelemetry/api": "^1.7.0"
}
},
- "node_modules/callsites": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
- "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==",
- "dev": true,
- "license": "MIT",
+ "node_modules/@opentelemetry/redis-common": {
+ "version": "0.38.0",
+ "resolved": "https://registry.npmjs.org/@opentelemetry/redis-common/-/redis-common-0.38.0.tgz",
+ "integrity": "sha512-4Wc0AWURII2cfXVVoZ6vDqK+s5n4K5IssdrlVrvGsx6OEOKdghKtJZqXAHWFiZv4nTDLH2/2fldjIHY8clMOjQ==",
+ "license": "Apache-2.0",
"engines": {
- "node": ">=6"
+ "node": "^18.19.0 || >=20.6.0"
}
},
- "node_modules/chalk": {
- "version": "4.1.2",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
- "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
- "license": "MIT",
+ "node_modules/@opentelemetry/resources": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/@opentelemetry/resources/-/resources-2.0.1.tgz",
+ "integrity": "sha512-dZOB3R6zvBwDKnHDTB4X1xtMArB/d324VsbiPkX/Yu0Q8T2xceRthoIVFhJdvgVM2QhGVUyX9tzwiNxGtoBJUw==",
+ "license": "Apache-2.0",
"dependencies": {
- "ansi-styles": "^4.1.0",
- "supports-color": "^7.1.0"
+ "@opentelemetry/core": "2.0.1",
+ "@opentelemetry/semantic-conventions": "^1.29.0"
},
"engines": {
- "node": ">=10"
+ "node": "^18.19.0 || >=20.6.0"
},
- "funding": {
- "url": "https://github.com/chalk/chalk?sponsor=1"
+ "peerDependencies": {
+ "@opentelemetry/api": ">=1.3.0 <1.10.0"
}
},
- "node_modules/color-convert": {
+ "node_modules/@opentelemetry/sdk-trace-base": {
"version": "2.0.1",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
- "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
- "license": "MIT",
+ "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-trace-base/-/sdk-trace-base-2.0.1.tgz",
+ "integrity": "sha512-xYLlvk/xdScGx1aEqvxLwf6sXQLXCjk3/1SQT9X9AoN5rXRhkdvIFShuNNmtTEPRBqcsMbS4p/gJLNI2wXaDuQ==",
+ "license": "Apache-2.0",
"dependencies": {
- "color-name": "~1.1.4"
+ "@opentelemetry/core": "2.0.1",
+ "@opentelemetry/resources": "2.0.1",
+ "@opentelemetry/semantic-conventions": "^1.29.0"
},
"engines": {
- "node": ">=7.0.0"
+ "node": "^18.19.0 || >=20.6.0"
+ },
+ "peerDependencies": {
+ "@opentelemetry/api": ">=1.3.0 <1.10.0"
}
},
- "node_modules/color-name": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
- "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
- "license": "MIT"
- },
- "node_modules/concat-map": {
- "version": "0.0.1",
- "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
- "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==",
- "dev": true,
- "license": "MIT"
+ "node_modules/@opentelemetry/semantic-conventions": {
+ "version": "1.36.0",
+ "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.36.0.tgz",
+ "integrity": "sha512-TtxJSRD8Ohxp6bKkhrm27JRHAxPczQA7idtcTOMYI+wQRRrfgqxHv1cFbCApcSnNjtXkmzFozn6jQtFrOmbjPQ==",
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">=14"
+ }
},
- "node_modules/content-disposition": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-1.0.0.tgz",
- "integrity": "sha512-Au9nRL8VNUut/XSzbQA38+M78dzP4D+eqg3gfJHMIHHYa3bg067xj1KxMUWj+VULbiZMowKngFFbKczUrNJ1mg==",
- "license": "MIT",
+ "node_modules/@opentelemetry/sql-common": {
+ "version": "0.41.0",
+ "resolved": "https://registry.npmjs.org/@opentelemetry/sql-common/-/sql-common-0.41.0.tgz",
+ "integrity": "sha512-pmzXctVbEERbqSfiAgdes9Y63xjoOyXcD7B6IXBkVb+vbM7M9U98mn33nGXxPf4dfYR0M+vhcKRZmbSJ7HfqFA==",
+ "license": "Apache-2.0",
"dependencies": {
- "safe-buffer": "5.2.1"
+ "@opentelemetry/core": "^2.0.0"
},
"engines": {
- "node": ">= 0.6"
+ "node": "^18.19.0 || >=20.6.0"
+ },
+ "peerDependencies": {
+ "@opentelemetry/api": "^1.1.0"
}
},
- "node_modules/content-type": {
- "version": "1.0.5",
- "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz",
- "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==",
+ "node_modules/@pkgjs/parseargs": {
+ "version": "0.11.0",
+ "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz",
+ "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==",
+ "dev": true,
"license": "MIT",
+ "optional": true,
"engines": {
- "node": ">= 0.6"
+ "node": ">=14"
}
},
- "node_modules/cookie": {
- "version": "0.7.2",
- "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz",
- "integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==",
+ "node_modules/@pkgr/core": {
+ "version": "0.2.9",
+ "resolved": "https://registry.npmjs.org/@pkgr/core/-/core-0.2.9.tgz",
+ "integrity": "sha512-QNqXyfVS2wm9hweSYD2O7F0G06uurj9kZ96TRQE5Y9hU7+tgdZwIkbAKc5Ocy1HxEY2kuDQa6cQ1WRs/O5LFKA==",
+ "dev": true,
"license": "MIT",
"engines": {
- "node": ">= 0.6"
+ "node": "^12.20.0 || ^14.18.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/pkgr"
}
},
- "node_modules/cookie-signature": {
- "version": "1.2.2",
- "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.2.2.tgz",
- "integrity": "sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg==",
- "license": "MIT",
- "engines": {
- "node": ">=6.6.0"
- }
+ "node_modules/@polka/url": {
+ "version": "1.0.0-next.29",
+ "resolved": "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.29.tgz",
+ "integrity": "sha512-wwQAWhWSuHaag8c4q/KN/vCoeOJYshAIvMQwD4GpSb3OiZklFfvAgmj0VCBBImRpuF/aFgIRzllXlVX93Jevww==",
+ "dev": true,
+ "license": "MIT"
},
- "node_modules/cors": {
- "version": "2.8.5",
- "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz",
- "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==",
- "license": "MIT",
+ "node_modules/@prisma/instrumentation": {
+ "version": "6.13.0",
+ "resolved": "https://registry.npmjs.org/@prisma/instrumentation/-/instrumentation-6.13.0.tgz",
+ "integrity": "sha512-b97b0sBycGh89RQcqobSgjGl3jwPaC5cQIOFod6EX1v0zIxlXPmL3ckSXxoHpy+Js0QV/tgCzFvqicMJCtezBA==",
+ "license": "Apache-2.0",
"dependencies": {
- "object-assign": "^4",
- "vary": "^1"
+ "@opentelemetry/instrumentation": "^0.52.0 || ^0.53.0 || ^0.54.0 || ^0.55.0 || ^0.56.0 || ^0.57.0"
},
- "engines": {
- "node": ">= 0.10"
+ "peerDependencies": {
+ "@opentelemetry/api": "^1.8"
}
},
- "node_modules/cross-spawn": {
- "version": "7.0.6",
- "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
- "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==",
- "license": "MIT",
+ "node_modules/@prisma/instrumentation/node_modules/@opentelemetry/api-logs": {
+ "version": "0.57.2",
+ "resolved": "https://registry.npmjs.org/@opentelemetry/api-logs/-/api-logs-0.57.2.tgz",
+ "integrity": "sha512-uIX52NnTM0iBh84MShlpouI7UKqkZ7MrUszTmaypHBu4r7NofznSnQRfJ+uUeDtQDj6w8eFGg5KBLDAwAPz1+A==",
+ "license": "Apache-2.0",
"dependencies": {
- "path-key": "^3.1.0",
- "shebang-command": "^2.0.0",
- "which": "^2.0.1"
+ "@opentelemetry/api": "^1.3.0"
},
"engines": {
- "node": ">= 8"
+ "node": ">=14"
}
},
- "node_modules/debug": {
- "version": "4.4.0",
- "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz",
- "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==",
- "license": "MIT",
+ "node_modules/@prisma/instrumentation/node_modules/@opentelemetry/instrumentation": {
+ "version": "0.57.2",
+ "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation/-/instrumentation-0.57.2.tgz",
+ "integrity": "sha512-BdBGhQBh8IjZ2oIIX6F2/Q3LKm/FDDKi6ccYKcBTeilh6SNdNKveDOLk73BkSJjQLJk6qe4Yh+hHw1UPhCDdrg==",
+ "license": "Apache-2.0",
"dependencies": {
- "ms": "^2.1.3"
+ "@opentelemetry/api-logs": "0.57.2",
+ "@types/shimmer": "^1.2.0",
+ "import-in-the-middle": "^1.8.1",
+ "require-in-the-middle": "^7.1.1",
+ "semver": "^7.5.2",
+ "shimmer": "^1.2.1"
},
"engines": {
- "node": ">=6.0"
+ "node": ">=14"
},
- "peerDependenciesMeta": {
- "supports-color": {
- "optional": true
- }
+ "peerDependencies": {
+ "@opentelemetry/api": "^1.3.0"
}
},
- "node_modules/deep-is": {
- "version": "0.1.4",
- "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz",
- "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==",
+ "node_modules/@rollup/rollup-android-arm-eabi": {
+ "version": "4.46.2",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.46.2.tgz",
+ "integrity": "sha512-Zj3Hl6sN34xJtMv7Anwb5Gu01yujyE/cLBDB2gnHTAHaWS1Z38L7kuSG+oAh0giZMqG060f/YBStXtMH6FvPMA==",
+ "cpu": [
+ "arm"
+ ],
"dev": true,
- "license": "MIT"
- },
- "node_modules/depd": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz",
- "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==",
"license": "MIT",
- "engines": {
- "node": ">= 0.8"
- }
- },
- "node_modules/dunder-proto": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz",
- "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==",
+ "optional": true,
+ "os": [
+ "android"
+ ]
+ },
+ "node_modules/@rollup/rollup-android-arm64": {
+ "version": "4.46.2",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.46.2.tgz",
+ "integrity": "sha512-nTeCWY83kN64oQ5MGz3CgtPx8NSOhC5lWtsjTs+8JAJNLcP3QbLCtDDgUKQc/Ro/frpMq4SHUaHN6AMltcEoLQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
"license": "MIT",
- "dependencies": {
- "call-bind-apply-helpers": "^1.0.1",
- "es-errors": "^1.3.0",
- "gopd": "^1.2.0"
- },
- "engines": {
+ "optional": true,
+ "os": [
+ "android"
+ ]
+ },
+ "node_modules/@rollup/rollup-darwin-arm64": {
+ "version": "4.46.2",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.46.2.tgz",
+ "integrity": "sha512-HV7bW2Fb/F5KPdM/9bApunQh68YVDU8sO8BvcW9OngQVN3HHHkw99wFupuUJfGR9pYLLAjcAOA6iO+evsbBaPQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ]
+ },
+ "node_modules/@rollup/rollup-darwin-x64": {
+ "version": "4.46.2",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.46.2.tgz",
+ "integrity": "sha512-SSj8TlYV5nJixSsm/y3QXfhspSiLYP11zpfwp6G/YDXctf3Xkdnk4woJIF5VQe0of2OjzTt8EsxnJDCdHd2xMA==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ]
+ },
+ "node_modules/@rollup/rollup-freebsd-arm64": {
+ "version": "4.46.2",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.46.2.tgz",
+ "integrity": "sha512-ZyrsG4TIT9xnOlLsSSi9w/X29tCbK1yegE49RYm3tu3wF1L/B6LVMqnEWyDB26d9Ecx9zrmXCiPmIabVuLmNSg==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ]
+ },
+ "node_modules/@rollup/rollup-freebsd-x64": {
+ "version": "4.46.2",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.46.2.tgz",
+ "integrity": "sha512-pCgHFoOECwVCJ5GFq8+gR8SBKnMO+xe5UEqbemxBpCKYQddRQMgomv1104RnLSg7nNvgKy05sLsY51+OVRyiVw==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-arm-gnueabihf": {
+ "version": "4.46.2",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.46.2.tgz",
+ "integrity": "sha512-EtP8aquZ0xQg0ETFcxUbU71MZlHaw9MChwrQzatiE8U/bvi5uv/oChExXC4mWhjiqK7azGJBqU0tt5H123SzVA==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-arm-musleabihf": {
+ "version": "4.46.2",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.46.2.tgz",
+ "integrity": "sha512-qO7F7U3u1nfxYRPM8HqFtLd+raev2K137dsV08q/LRKRLEc7RsiDWihUnrINdsWQxPR9jqZ8DIIZ1zJJAm5PjQ==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-arm64-gnu": {
+ "version": "4.46.2",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.46.2.tgz",
+ "integrity": "sha512-3dRaqLfcOXYsfvw5xMrxAk9Lb1f395gkoBYzSFcc/scgRFptRXL9DOaDpMiehf9CO8ZDRJW2z45b6fpU5nwjng==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-arm64-musl": {
+ "version": "4.46.2",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.46.2.tgz",
+ "integrity": "sha512-fhHFTutA7SM+IrR6lIfiHskxmpmPTJUXpWIsBXpeEwNgZzZZSg/q4i6FU4J8qOGyJ0TR+wXBwx/L7Ho9z0+uDg==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-loongarch64-gnu": {
+ "version": "4.46.2",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.46.2.tgz",
+ "integrity": "sha512-i7wfGFXu8x4+FRqPymzjD+Hyav8l95UIZ773j7J7zRYc3Xsxy2wIn4x+llpunexXe6laaO72iEjeeGyUFmjKeA==",
+ "cpu": [
+ "loong64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-ppc64-gnu": {
+ "version": "4.46.2",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.46.2.tgz",
+ "integrity": "sha512-B/l0dFcHVUnqcGZWKcWBSV2PF01YUt0Rvlurci5P+neqY/yMKchGU8ullZvIv5e8Y1C6wOn+U03mrDylP5q9Yw==",
+ "cpu": [
+ "ppc64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-riscv64-gnu": {
+ "version": "4.46.2",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.46.2.tgz",
+ "integrity": "sha512-32k4ENb5ygtkMwPMucAb8MtV8olkPT03oiTxJbgkJa7lJ7dZMr0GCFJlyvy+K8iq7F/iuOr41ZdUHaOiqyR3iQ==",
+ "cpu": [
+ "riscv64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-riscv64-musl": {
+ "version": "4.46.2",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.46.2.tgz",
+ "integrity": "sha512-t5B2loThlFEauloaQkZg9gxV05BYeITLvLkWOkRXogP4qHXLkWSbSHKM9S6H1schf/0YGP/qNKtiISlxvfmmZw==",
+ "cpu": [
+ "riscv64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-s390x-gnu": {
+ "version": "4.46.2",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.46.2.tgz",
+ "integrity": "sha512-YKjekwTEKgbB7n17gmODSmJVUIvj8CX7q5442/CK80L8nqOUbMtf8b01QkG3jOqyr1rotrAnW6B/qiHwfcuWQA==",
+ "cpu": [
+ "s390x"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-x64-gnu": {
+ "version": "4.46.2",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.46.2.tgz",
+ "integrity": "sha512-Jj5a9RUoe5ra+MEyERkDKLwTXVu6s3aACP51nkfnK9wJTraCC8IMe3snOfALkrjTYd2G1ViE1hICj0fZ7ALBPA==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-x64-musl": {
+ "version": "4.46.2",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.46.2.tgz",
+ "integrity": "sha512-7kX69DIrBeD7yNp4A5b81izs8BqoZkCIaxQaOpumcJ1S/kmqNFjPhDu1LHeVXv0SexfHQv5cqHsxLOjETuqDuA==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-win32-arm64-msvc": {
+ "version": "4.46.2",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.46.2.tgz",
+ "integrity": "sha512-wiJWMIpeaak/jsbaq2HMh/rzZxHVW1rU6coyeNNpMwk5isiPjSTx0a4YLSlYDwBH/WBvLz+EtsNqQScZTLJy3g==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ]
+ },
+ "node_modules/@rollup/rollup-win32-ia32-msvc": {
+ "version": "4.46.2",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.46.2.tgz",
+ "integrity": "sha512-gBgaUDESVzMgWZhcyjfs9QFK16D8K6QZpwAaVNJxYDLHWayOta4ZMjGm/vsAEy3hvlS2GosVFlBlP9/Wb85DqQ==",
+ "cpu": [
+ "ia32"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ]
+ },
+ "node_modules/@rollup/rollup-win32-x64-msvc": {
+ "version": "4.46.2",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.46.2.tgz",
+ "integrity": "sha512-CvUo2ixeIQGtF6WvuB87XWqPQkoFAFqW+HUo/WzHwuHDvIwZCtjdWXoYCcr06iKGydiqTclC4jU/TNObC/xKZg==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ]
+ },
+ "node_modules/@sentry/cli": {
+ "version": "2.51.1",
+ "resolved": "https://registry.npmjs.org/@sentry/cli/-/cli-2.51.1.tgz",
+ "integrity": "sha512-FU+54kNcKJABU0+ekvtnoXHM9zVrDe1zXVFbQT7mS0On0m1P0zFRGdzbnWe2XzpzuEAJXtK6aog/W+esRU9AIA==",
+ "hasInstallScript": true,
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "https-proxy-agent": "^5.0.0",
+ "node-fetch": "^2.6.7",
+ "progress": "^2.0.3",
+ "proxy-from-env": "^1.1.0",
+ "which": "^2.0.2"
+ },
+ "bin": {
+ "sentry-cli": "bin/sentry-cli"
+ },
+ "engines": {
+ "node": ">= 10"
+ },
+ "optionalDependencies": {
+ "@sentry/cli-darwin": "2.51.1",
+ "@sentry/cli-linux-arm": "2.51.1",
+ "@sentry/cli-linux-arm64": "2.51.1",
+ "@sentry/cli-linux-i686": "2.51.1",
+ "@sentry/cli-linux-x64": "2.51.1",
+ "@sentry/cli-win32-arm64": "2.51.1",
+ "@sentry/cli-win32-i686": "2.51.1",
+ "@sentry/cli-win32-x64": "2.51.1"
+ }
+ },
+ "node_modules/@sentry/cli-darwin": {
+ "version": "2.51.1",
+ "resolved": "https://registry.npmjs.org/@sentry/cli-darwin/-/cli-darwin-2.51.1.tgz",
+ "integrity": "sha512-R1u8IQdn/7Rr8sf6bVVr0vJT4OqwCFdYsS44Y3OoWGVJW2aAQTWRJOTlV4ueclVLAyUQzmgBjfR8AtiUhd/M5w==",
+ "license": "BSD-3-Clause",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/@sentry/cli-linux-arm": {
+ "version": "2.51.1",
+ "resolved": "https://registry.npmjs.org/@sentry/cli-linux-arm/-/cli-linux-arm-2.51.1.tgz",
+ "integrity": "sha512-Klro17OmSSKOOSaxVKBBNPXet2+HrIDZUTSp8NRl4LQsIubdc1S/aQ79cH/g52Muwzpl3aFwPxyXw+46isfEgA==",
+ "cpu": [
+ "arm"
+ ],
+ "license": "BSD-3-Clause",
+ "optional": true,
+ "os": [
+ "linux",
+ "freebsd",
+ "android"
+ ],
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/@sentry/cli-linux-arm64": {
+ "version": "2.51.1",
+ "resolved": "https://registry.npmjs.org/@sentry/cli-linux-arm64/-/cli-linux-arm64-2.51.1.tgz",
+ "integrity": "sha512-nvA/hdhsw4bKLhslgbBqqvETjXwN1FVmwHLOrRvRcejDO6zeIKUElDiL5UOjGG0NC+62AxyNw5ri8Wzp/7rg9Q==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "BSD-3-Clause",
+ "optional": true,
+ "os": [
+ "linux",
+ "freebsd",
+ "android"
+ ],
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/@sentry/cli-linux-i686": {
+ "version": "2.51.1",
+ "resolved": "https://registry.npmjs.org/@sentry/cli-linux-i686/-/cli-linux-i686-2.51.1.tgz",
+ "integrity": "sha512-jp4TmR8VXBdT9dLo6mHniQHN0xKnmJoPGVz9h9VDvO2Vp/8o96rBc555D4Am5wJOXmfuPlyjGcmwHlB3+kQRWw==",
+ "cpu": [
+ "x86",
+ "ia32"
+ ],
+ "license": "BSD-3-Clause",
+ "optional": true,
+ "os": [
+ "linux",
+ "freebsd",
+ "android"
+ ],
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/@sentry/cli-linux-x64": {
+ "version": "2.51.1",
+ "resolved": "https://registry.npmjs.org/@sentry/cli-linux-x64/-/cli-linux-x64-2.51.1.tgz",
+ "integrity": "sha512-JuLt0MXM2KHNFmjqXjv23sly56mJmUQzGBWktkpY3r+jE08f5NLKPd5wQ6W/SoLXGIOKnwLz0WoUg7aBVyQdeQ==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "BSD-3-Clause",
+ "optional": true,
+ "os": [
+ "linux",
+ "freebsd",
+ "android"
+ ],
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/@sentry/cli-win32-arm64": {
+ "version": "2.51.1",
+ "resolved": "https://registry.npmjs.org/@sentry/cli-win32-arm64/-/cli-win32-arm64-2.51.1.tgz",
+ "integrity": "sha512-PiwjTdIFDazTQCTyDCutiSkt4omggYSKnO3HE1+LDjElsFrWY9pJs4fU3D40WAyE2oKu0MarjNH/WxYGdqEAlg==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "BSD-3-Clause",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/@sentry/cli-win32-i686": {
+ "version": "2.51.1",
+ "resolved": "https://registry.npmjs.org/@sentry/cli-win32-i686/-/cli-win32-i686-2.51.1.tgz",
+ "integrity": "sha512-TMvZZpeiI2HmrDFNVQ0uOiTuYKvjEGOZdmUxe3WlhZW82A/2Oka7sQ24ljcOovbmBOj5+fjCHRUMYvLMCWiysA==",
+ "cpu": [
+ "x86",
+ "ia32"
+ ],
+ "license": "BSD-3-Clause",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/@sentry/cli-win32-x64": {
+ "version": "2.51.1",
+ "resolved": "https://registry.npmjs.org/@sentry/cli-win32-x64/-/cli-win32-x64-2.51.1.tgz",
+ "integrity": "sha512-v2hreYUPPTNK1/N7+DeX7XBN/zb7p539k+2Osf0HFyVBaoUC3Y3+KBwSf4ASsnmgTAK7HCGR+X0NH1vP+icw4w==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "BSD-3-Clause",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/@sentry/core": {
+ "version": "10.5.0",
+ "resolved": "https://registry.npmjs.org/@sentry/core/-/core-10.5.0.tgz",
+ "integrity": "sha512-jTJ8NhZSKB2yj3QTVRXfCCngQzAOLThQUxCl9A7Mv+XF10tP7xbH/88MVQ5WiOr2IzcmrB9r2nmUe36BnMlLjA==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@sentry/node": {
+ "version": "10.5.0",
+ "resolved": "https://registry.npmjs.org/@sentry/node/-/node-10.5.0.tgz",
+ "integrity": "sha512-GqTkOc7tkWqRTKNjipysElh/bzIkhfLsvNGwH6+zel5kU15IdOCFtAqIri85ZLo9vbaIVtjQELXOzfo/5MMAFQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@opentelemetry/api": "^1.9.0",
+ "@opentelemetry/context-async-hooks": "^2.0.0",
+ "@opentelemetry/core": "^2.0.0",
+ "@opentelemetry/instrumentation": "^0.203.0",
+ "@opentelemetry/instrumentation-amqplib": "0.50.0",
+ "@opentelemetry/instrumentation-connect": "0.47.0",
+ "@opentelemetry/instrumentation-dataloader": "0.21.0",
+ "@opentelemetry/instrumentation-express": "0.52.0",
+ "@opentelemetry/instrumentation-fs": "0.23.0",
+ "@opentelemetry/instrumentation-generic-pool": "0.47.0",
+ "@opentelemetry/instrumentation-graphql": "0.51.0",
+ "@opentelemetry/instrumentation-hapi": "0.50.0",
+ "@opentelemetry/instrumentation-http": "0.203.0",
+ "@opentelemetry/instrumentation-ioredis": "0.51.0",
+ "@opentelemetry/instrumentation-kafkajs": "0.12.0",
+ "@opentelemetry/instrumentation-knex": "0.48.0",
+ "@opentelemetry/instrumentation-koa": "0.51.0",
+ "@opentelemetry/instrumentation-lru-memoizer": "0.48.0",
+ "@opentelemetry/instrumentation-mongodb": "0.56.0",
+ "@opentelemetry/instrumentation-mongoose": "0.50.0",
+ "@opentelemetry/instrumentation-mysql": "0.49.0",
+ "@opentelemetry/instrumentation-mysql2": "0.49.0",
+ "@opentelemetry/instrumentation-pg": "0.55.0",
+ "@opentelemetry/instrumentation-redis": "0.51.0",
+ "@opentelemetry/instrumentation-tedious": "0.22.0",
+ "@opentelemetry/instrumentation-undici": "0.14.0",
+ "@opentelemetry/resources": "^2.0.0",
+ "@opentelemetry/sdk-trace-base": "^2.0.0",
+ "@opentelemetry/semantic-conventions": "^1.34.0",
+ "@prisma/instrumentation": "6.13.0",
+ "@sentry/core": "10.5.0",
+ "@sentry/node-core": "10.5.0",
+ "@sentry/opentelemetry": "10.5.0",
+ "import-in-the-middle": "^1.14.2",
+ "minimatch": "^9.0.0"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@sentry/node-core": {
+ "version": "10.5.0",
+ "resolved": "https://registry.npmjs.org/@sentry/node-core/-/node-core-10.5.0.tgz",
+ "integrity": "sha512-VC4FCKMvvbUT32apTE0exfI/WigqKskzQA+VdFz61Y+T7mTCADngNrOjG3ilVYPBU7R9KEEziEd/oKgencqkmQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@sentry/core": "10.5.0",
+ "@sentry/opentelemetry": "10.5.0",
+ "import-in-the-middle": "^1.14.2"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "peerDependencies": {
+ "@opentelemetry/api": "^1.9.0",
+ "@opentelemetry/context-async-hooks": "^1.30.1 || ^2.0.0",
+ "@opentelemetry/core": "^1.30.1 || ^2.0.0",
+ "@opentelemetry/instrumentation": ">=0.57.1 <1",
+ "@opentelemetry/resources": "^1.30.1 || ^2.0.0",
+ "@opentelemetry/sdk-trace-base": "^1.30.1 || ^2.0.0",
+ "@opentelemetry/semantic-conventions": "^1.34.0"
+ }
+ },
+ "node_modules/@sentry/node/node_modules/brace-expansion": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz",
+ "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==",
+ "license": "MIT",
+ "dependencies": {
+ "balanced-match": "^1.0.0"
+ }
+ },
+ "node_modules/@sentry/node/node_modules/minimatch": {
+ "version": "9.0.5",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz",
+ "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==",
+ "license": "ISC",
+ "dependencies": {
+ "brace-expansion": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=16 || 14 >=14.17"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/@sentry/opentelemetry": {
+ "version": "10.5.0",
+ "resolved": "https://registry.npmjs.org/@sentry/opentelemetry/-/opentelemetry-10.5.0.tgz",
+ "integrity": "sha512-/Qva5vngtuh79YUUBA8kbbrD6w/A+u1vy1jnLoPMKDxWTfNPqT4tCiOOmWYotnITaE3QO0UtXK/j7LMX8FhtUA==",
+ "license": "MIT",
+ "dependencies": {
+ "@sentry/core": "10.5.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "peerDependencies": {
+ "@opentelemetry/api": "^1.9.0",
+ "@opentelemetry/context-async-hooks": "^1.30.1 || ^2.0.0",
+ "@opentelemetry/core": "^1.30.1 || ^2.0.0",
+ "@opentelemetry/sdk-trace-base": "^1.30.1 || ^2.0.0",
+ "@opentelemetry/semantic-conventions": "^1.34.0"
+ }
+ },
+ "node_modules/@tsconfig/node10": {
+ "version": "1.0.11",
+ "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.11.tgz",
+ "integrity": "sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@tsconfig/node12": {
+ "version": "1.0.11",
+ "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz",
+ "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@tsconfig/node14": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz",
+ "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@tsconfig/node16": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz",
+ "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/chai": {
+ "version": "5.2.2",
+ "resolved": "https://registry.npmjs.org/@types/chai/-/chai-5.2.2.tgz",
+ "integrity": "sha512-8kB30R7Hwqf40JPiKhVzodJs2Qc1ZJ5zuT3uzw5Hq/dhNCl3G3l83jfpdI1e20BP348+fV7VIL/+FxaXkqBmWg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/deep-eql": "*"
+ }
+ },
+ "node_modules/@types/connect": {
+ "version": "3.4.38",
+ "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz",
+ "integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/node": "*"
+ }
+ },
+ "node_modules/@types/deep-eql": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/@types/deep-eql/-/deep-eql-4.0.2.tgz",
+ "integrity": "sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/estree": {
+ "version": "1.0.8",
+ "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz",
+ "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/json-schema": {
+ "version": "7.0.15",
+ "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz",
+ "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/mysql": {
+ "version": "2.15.27",
+ "resolved": "https://registry.npmjs.org/@types/mysql/-/mysql-2.15.27.tgz",
+ "integrity": "sha512-YfWiV16IY0OeBfBCk8+hXKmdTKrKlwKN1MNKAPBu5JYxLwBEZl7QzeEpGnlZb3VMGJrrGmB84gXiH+ofs/TezA==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/node": "*"
+ }
+ },
+ "node_modules/@types/node": {
+ "version": "22.17.1",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-22.17.1.tgz",
+ "integrity": "sha512-y3tBaz+rjspDTylNjAX37jEC3TETEFGNJL6uQDxwF9/8GLLIjW1rvVHlynyuUKMnMr1Roq8jOv3vkopBjC4/VA==",
+ "license": "MIT",
+ "dependencies": {
+ "undici-types": "~6.21.0"
+ }
+ },
+ "node_modules/@types/pg": {
+ "version": "8.15.4",
+ "resolved": "https://registry.npmjs.org/@types/pg/-/pg-8.15.4.tgz",
+ "integrity": "sha512-I6UNVBAoYbvuWkkU3oosC8yxqH21f4/Jc4DK71JLG3dT2mdlGe1z+ep/LQGXaKaOgcvUrsQoPRqfgtMcvZiJhg==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/node": "*",
+ "pg-protocol": "*",
+ "pg-types": "^2.2.0"
+ }
+ },
+ "node_modules/@types/pg-pool": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/@types/pg-pool/-/pg-pool-2.0.6.tgz",
+ "integrity": "sha512-TaAUE5rq2VQYxab5Ts7WZhKNmuN78Q6PiFonTDdpbx8a1H0M1vhy3rhiMjl+e2iHmogyMw7jZF4FrE6eJUy5HQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/pg": "*"
+ }
+ },
+ "node_modules/@types/shimmer": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/@types/shimmer/-/shimmer-1.2.0.tgz",
+ "integrity": "sha512-UE7oxhQLLd9gub6JKIAhDq06T0F6FnztwMNRvYgjeQSBeMc1ZG/tA47EwfduvkuQS8apbkM/lpLpWsaCeYsXVg==",
+ "license": "MIT"
+ },
+ "node_modules/@types/tedious": {
+ "version": "4.0.14",
+ "resolved": "https://registry.npmjs.org/@types/tedious/-/tedious-4.0.14.tgz",
+ "integrity": "sha512-KHPsfX/FoVbUGbyYvk1q9MMQHLPeRZhRJZdO45Q4YjvFkv4hMNghCWTvy7rdKessBsmtz4euWCWAB6/tVpI1Iw==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/node": "*"
+ }
+ },
+ "node_modules/@typescript-eslint/eslint-plugin": {
+ "version": "8.39.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.39.0.tgz",
+ "integrity": "sha512-bhEz6OZeUR+O/6yx9Jk6ohX6H9JSFTaiY0v9/PuKT3oGK0rn0jNplLmyFUGV+a9gfYnVNwGDwS/UkLIuXNb2Rw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@eslint-community/regexpp": "^4.10.0",
+ "@typescript-eslint/scope-manager": "8.39.0",
+ "@typescript-eslint/type-utils": "8.39.0",
+ "@typescript-eslint/utils": "8.39.0",
+ "@typescript-eslint/visitor-keys": "8.39.0",
+ "graphemer": "^1.4.0",
+ "ignore": "^7.0.0",
+ "natural-compare": "^1.4.0",
+ "ts-api-utils": "^2.1.0"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependencies": {
+ "@typescript-eslint/parser": "^8.39.0",
+ "eslint": "^8.57.0 || ^9.0.0",
+ "typescript": ">=4.8.4 <6.0.0"
+ }
+ },
+ "node_modules/@typescript-eslint/eslint-plugin/node_modules/ignore": {
+ "version": "7.0.5",
+ "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.5.tgz",
+ "integrity": "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 4"
+ }
+ },
+ "node_modules/@typescript-eslint/parser": {
+ "version": "8.39.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.39.0.tgz",
+ "integrity": "sha512-g3WpVQHngx0aLXn6kfIYCZxM6rRJlWzEkVpqEFLT3SgEDsp9cpCbxxgwnE504q4H+ruSDh/VGS6nqZIDynP+vg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@typescript-eslint/scope-manager": "8.39.0",
+ "@typescript-eslint/types": "8.39.0",
+ "@typescript-eslint/typescript-estree": "8.39.0",
+ "@typescript-eslint/visitor-keys": "8.39.0",
+ "debug": "^4.3.4"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependencies": {
+ "eslint": "^8.57.0 || ^9.0.0",
+ "typescript": ">=4.8.4 <6.0.0"
+ }
+ },
+ "node_modules/@typescript-eslint/project-service": {
+ "version": "8.39.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.39.0.tgz",
+ "integrity": "sha512-CTzJqaSq30V/Z2Og9jogzZt8lJRR5TKlAdXmWgdu4hgcC9Kww5flQ+xFvMxIBWVNdxJO7OifgdOK4PokMIWPew==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@typescript-eslint/tsconfig-utils": "^8.39.0",
+ "@typescript-eslint/types": "^8.39.0",
+ "debug": "^4.3.4"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependencies": {
+ "typescript": ">=4.8.4 <6.0.0"
+ }
+ },
+ "node_modules/@typescript-eslint/scope-manager": {
+ "version": "8.39.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.39.0.tgz",
+ "integrity": "sha512-8QOzff9UKxOh6npZQ/4FQu4mjdOCGSdO3p44ww0hk8Vu+IGbg0tB/H1LcTARRDzGCC8pDGbh2rissBuuoPgH8A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@typescript-eslint/types": "8.39.0",
+ "@typescript-eslint/visitor-keys": "8.39.0"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ }
+ },
+ "node_modules/@typescript-eslint/tsconfig-utils": {
+ "version": "8.39.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.39.0.tgz",
+ "integrity": "sha512-Fd3/QjmFV2sKmvv3Mrj8r6N8CryYiCS8Wdb/6/rgOXAWGcFuc+VkQuG28uk/4kVNVZBQuuDHEDUpo/pQ32zsIQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependencies": {
+ "typescript": ">=4.8.4 <6.0.0"
+ }
+ },
+ "node_modules/@typescript-eslint/type-utils": {
+ "version": "8.39.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.39.0.tgz",
+ "integrity": "sha512-6B3z0c1DXVT2vYA9+z9axjtc09rqKUPRmijD5m9iv8iQpHBRYRMBcgxSiKTZKm6FwWw1/cI4v6em35OsKCiN5Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@typescript-eslint/types": "8.39.0",
+ "@typescript-eslint/typescript-estree": "8.39.0",
+ "@typescript-eslint/utils": "8.39.0",
+ "debug": "^4.3.4",
+ "ts-api-utils": "^2.1.0"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependencies": {
+ "eslint": "^8.57.0 || ^9.0.0",
+ "typescript": ">=4.8.4 <6.0.0"
+ }
+ },
+ "node_modules/@typescript-eslint/types": {
+ "version": "8.39.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.39.0.tgz",
+ "integrity": "sha512-ArDdaOllnCj3yn/lzKn9s0pBQYmmyme/v1HbGIGB0GB/knFI3fWMHloC+oYTJW46tVbYnGKTMDK4ah1sC2v0Kg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ }
+ },
+ "node_modules/@typescript-eslint/typescript-estree": {
+ "version": "8.39.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.39.0.tgz",
+ "integrity": "sha512-ndWdiflRMvfIgQRpckQQLiB5qAKQ7w++V4LlCHwp62eym1HLB/kw7D9f2e8ytONls/jt89TEasgvb+VwnRprsw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@typescript-eslint/project-service": "8.39.0",
+ "@typescript-eslint/tsconfig-utils": "8.39.0",
+ "@typescript-eslint/types": "8.39.0",
+ "@typescript-eslint/visitor-keys": "8.39.0",
+ "debug": "^4.3.4",
+ "fast-glob": "^3.3.2",
+ "is-glob": "^4.0.3",
+ "minimatch": "^9.0.4",
+ "semver": "^7.6.0",
+ "ts-api-utils": "^2.1.0"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependencies": {
+ "typescript": ">=4.8.4 <6.0.0"
+ }
+ },
+ "node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz",
+ "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "balanced-match": "^1.0.0"
+ }
+ },
+ "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": {
+ "version": "9.0.5",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz",
+ "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "brace-expansion": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=16 || 14 >=14.17"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/@typescript-eslint/utils": {
+ "version": "8.39.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.39.0.tgz",
+ "integrity": "sha512-4GVSvNA0Vx1Ktwvf4sFE+exxJ3QGUorQG1/A5mRfRNZtkBT2xrA/BCO2H0eALx/PnvCS6/vmYwRdDA41EoffkQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@eslint-community/eslint-utils": "^4.7.0",
+ "@typescript-eslint/scope-manager": "8.39.0",
+ "@typescript-eslint/types": "8.39.0",
+ "@typescript-eslint/typescript-estree": "8.39.0"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependencies": {
+ "eslint": "^8.57.0 || ^9.0.0",
+ "typescript": ">=4.8.4 <6.0.0"
+ }
+ },
+ "node_modules/@typescript-eslint/visitor-keys": {
+ "version": "8.39.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.39.0.tgz",
+ "integrity": "sha512-ldgiJ+VAhQCfIjeOgu8Kj5nSxds0ktPOSO9p4+0VDH2R2pLvQraaM5Oen2d7NxzMCm+Sn/vJT+mv2H5u6b/3fA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@typescript-eslint/types": "8.39.0",
+ "eslint-visitor-keys": "^4.2.1"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ }
+ },
+ "node_modules/@typescript-eslint/visitor-keys/node_modules/eslint-visitor-keys": {
+ "version": "4.2.1",
+ "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz",
+ "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/@vitest/coverage-v8": {
+ "version": "3.2.4",
+ "resolved": "https://registry.npmjs.org/@vitest/coverage-v8/-/coverage-v8-3.2.4.tgz",
+ "integrity": "sha512-EyF9SXU6kS5Ku/U82E259WSnvg6c8KTjppUncuNdm5QHpe17mwREHnjDzozC8x9MZ0xfBUFSaLkRv4TMA75ALQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@ampproject/remapping": "^2.3.0",
+ "@bcoe/v8-coverage": "^1.0.2",
+ "ast-v8-to-istanbul": "^0.3.3",
+ "debug": "^4.4.1",
+ "istanbul-lib-coverage": "^3.2.2",
+ "istanbul-lib-report": "^3.0.1",
+ "istanbul-lib-source-maps": "^5.0.6",
+ "istanbul-reports": "^3.1.7",
+ "magic-string": "^0.30.17",
+ "magicast": "^0.3.5",
+ "std-env": "^3.9.0",
+ "test-exclude": "^7.0.1",
+ "tinyrainbow": "^2.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/vitest"
+ },
+ "peerDependencies": {
+ "@vitest/browser": "3.2.4",
+ "vitest": "3.2.4"
+ },
+ "peerDependenciesMeta": {
+ "@vitest/browser": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@vitest/expect": {
+ "version": "3.2.4",
+ "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-3.2.4.tgz",
+ "integrity": "sha512-Io0yyORnB6sikFlt8QW5K7slY4OjqNX9jmJQ02QDda8lyM6B5oNgVWoSoKPac8/kgnCUzuHQKrSLtu/uOqqrig==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/chai": "^5.2.2",
+ "@vitest/spy": "3.2.4",
+ "@vitest/utils": "3.2.4",
+ "chai": "^5.2.0",
+ "tinyrainbow": "^2.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/vitest"
+ }
+ },
+ "node_modules/@vitest/mocker": {
+ "version": "3.2.4",
+ "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-3.2.4.tgz",
+ "integrity": "sha512-46ryTE9RZO/rfDd7pEqFl7etuyzekzEhUbTW3BvmeO/BcCMEgq59BKhek3dXDWgAj4oMK6OZi+vRr1wPW6qjEQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@vitest/spy": "3.2.4",
+ "estree-walker": "^3.0.3",
+ "magic-string": "^0.30.17"
+ },
+ "funding": {
+ "url": "https://opencollective.com/vitest"
+ },
+ "peerDependencies": {
+ "msw": "^2.4.9",
+ "vite": "^5.0.0 || ^6.0.0 || ^7.0.0-0"
+ },
+ "peerDependenciesMeta": {
+ "msw": {
+ "optional": true
+ },
+ "vite": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@vitest/pretty-format": {
+ "version": "3.2.4",
+ "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-3.2.4.tgz",
+ "integrity": "sha512-IVNZik8IVRJRTr9fxlitMKeJeXFFFN0JaB9PHPGQ8NKQbGpfjlTx9zO4RefN8gp7eqjNy8nyK3NZmBzOPeIxtA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "tinyrainbow": "^2.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/vitest"
+ }
+ },
+ "node_modules/@vitest/runner": {
+ "version": "3.2.4",
+ "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-3.2.4.tgz",
+ "integrity": "sha512-oukfKT9Mk41LreEW09vt45f8wx7DordoWUZMYdY/cyAk7w5TWkTRCNZYF7sX7n2wB7jyGAl74OxgwhPgKaqDMQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@vitest/utils": "3.2.4",
+ "pathe": "^2.0.3",
+ "strip-literal": "^3.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/vitest"
+ }
+ },
+ "node_modules/@vitest/snapshot": {
+ "version": "3.2.4",
+ "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-3.2.4.tgz",
+ "integrity": "sha512-dEYtS7qQP2CjU27QBC5oUOxLE/v5eLkGqPE0ZKEIDGMs4vKWe7IjgLOeauHsR0D5YuuycGRO5oSRXnwnmA78fQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@vitest/pretty-format": "3.2.4",
+ "magic-string": "^0.30.17",
+ "pathe": "^2.0.3"
+ },
+ "funding": {
+ "url": "https://opencollective.com/vitest"
+ }
+ },
+ "node_modules/@vitest/spy": {
+ "version": "3.2.4",
+ "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-3.2.4.tgz",
+ "integrity": "sha512-vAfasCOe6AIK70iP5UD11Ac4siNUNJ9i/9PZ3NKx07sG6sUxeag1LWdNrMWeKKYBLlzuK+Gn65Yd5nyL6ds+nw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "tinyspy": "^4.0.3"
+ },
+ "funding": {
+ "url": "https://opencollective.com/vitest"
+ }
+ },
+ "node_modules/@vitest/ui": {
+ "version": "3.2.4",
+ "resolved": "https://registry.npmjs.org/@vitest/ui/-/ui-3.2.4.tgz",
+ "integrity": "sha512-hGISOaP18plkzbWEcP/QvtRW1xDXF2+96HbEX6byqQhAUbiS5oH6/9JwW+QsQCIYON2bI6QZBF+2PvOmrRZ9wA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@vitest/utils": "3.2.4",
+ "fflate": "^0.8.2",
+ "flatted": "^3.3.3",
+ "pathe": "^2.0.3",
+ "sirv": "^3.0.1",
+ "tinyglobby": "^0.2.14",
+ "tinyrainbow": "^2.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/vitest"
+ },
+ "peerDependencies": {
+ "vitest": "3.2.4"
+ }
+ },
+ "node_modules/@vitest/utils": {
+ "version": "3.2.4",
+ "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-3.2.4.tgz",
+ "integrity": "sha512-fB2V0JFrQSMsCo9HiSq3Ezpdv4iYaXRG1Sx8edX3MwxfyNn83mKiGzOcH+Fkxt4MHxr3y42fQi1oeAInqgX2QA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@vitest/pretty-format": "3.2.4",
+ "loupe": "^3.1.4",
+ "tinyrainbow": "^2.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/vitest"
+ }
+ },
+ "node_modules/@xmldom/xmldom": {
+ "version": "0.7.13",
+ "resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.7.13.tgz",
+ "integrity": "sha512-lm2GW5PkosIzccsaZIz7tp8cPADSIlIHWDFTR1N0SzfinhhYgeIQjFMz4rYzanCScr3DqQLeomUDArp6MWKm+g==",
+ "deprecated": "this version is no longer supported, please update to at least 0.8.*",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=10.0.0"
+ }
+ },
+ "node_modules/accepts": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/accepts/-/accepts-2.0.0.tgz",
+ "integrity": "sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng==",
+ "license": "MIT",
+ "dependencies": {
+ "mime-types": "^3.0.0",
+ "negotiator": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/acorn": {
+ "version": "8.15.0",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz",
+ "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==",
+ "license": "MIT",
+ "bin": {
+ "acorn": "bin/acorn"
+ },
+ "engines": {
+ "node": ">=0.4.0"
+ }
+ },
+ "node_modules/acorn-import-attributes": {
+ "version": "1.9.5",
+ "resolved": "https://registry.npmjs.org/acorn-import-attributes/-/acorn-import-attributes-1.9.5.tgz",
+ "integrity": "sha512-n02Vykv5uA3eHGM/Z2dQrcD56kL8TyDb2p1+0P83PClMnC/nc+anbQRhIOWnSq4Ke/KvDPrY3C9hDtC/A3eHnQ==",
+ "license": "MIT",
+ "peerDependencies": {
+ "acorn": "^8"
+ }
+ },
+ "node_modules/acorn-jsx": {
+ "version": "5.3.2",
+ "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz",
+ "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==",
+ "dev": true,
+ "license": "MIT",
+ "peerDependencies": {
+ "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0"
+ }
+ },
+ "node_modules/acorn-walk": {
+ "version": "8.3.4",
+ "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.4.tgz",
+ "integrity": "sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "acorn": "^8.11.0"
+ },
+ "engines": {
+ "node": ">=0.4.0"
+ }
+ },
+ "node_modules/agent-base": {
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz",
+ "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==",
+ "license": "MIT",
+ "dependencies": {
+ "debug": "4"
+ },
+ "engines": {
+ "node": ">= 6.0.0"
+ }
+ },
+ "node_modules/ajv": {
+ "version": "6.12.6",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
+ "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "fast-deep-equal": "^3.1.1",
+ "fast-json-stable-stringify": "^2.0.0",
+ "json-schema-traverse": "^0.4.1",
+ "uri-js": "^4.2.2"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/epoberezkin"
+ }
+ },
+ "node_modules/ajv-formats": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-3.0.1.tgz",
+ "integrity": "sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==",
+ "license": "MIT",
+ "dependencies": {
+ "ajv": "^8.0.0"
+ },
+ "peerDependencies": {
+ "ajv": "^8.0.0"
+ },
+ "peerDependenciesMeta": {
+ "ajv": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/ajv-formats/node_modules/ajv": {
+ "version": "8.17.1",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz",
+ "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==",
+ "license": "MIT",
+ "dependencies": {
+ "fast-deep-equal": "^3.1.3",
+ "fast-uri": "^3.0.1",
+ "json-schema-traverse": "^1.0.0",
+ "require-from-string": "^2.0.2"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/epoberezkin"
+ }
+ },
+ "node_modules/ajv-formats/node_modules/json-schema-traverse": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz",
+ "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==",
+ "license": "MIT"
+ },
+ "node_modules/ansi-regex": {
+ "version": "6.1.0",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz",
+ "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-regex?sponsor=1"
+ }
+ },
+ "node_modules/ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "color-convert": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/any-promise": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz",
+ "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/arg": {
+ "version": "4.1.3",
+ "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz",
+ "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/argparse": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
+ "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
+ "dev": true,
+ "license": "Python-2.0"
+ },
+ "node_modules/assertion-error": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz",
+ "integrity": "sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/ast-v8-to-istanbul": {
+ "version": "0.3.4",
+ "resolved": "https://registry.npmjs.org/ast-v8-to-istanbul/-/ast-v8-to-istanbul-0.3.4.tgz",
+ "integrity": "sha512-cxrAnZNLBnQwBPByK4CeDaw5sWZtMilJE/Q3iDA0aamgaIVNDF9T6K2/8DfYDZEejZ2jNnDrG9m8MY72HFd0KA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jridgewell/trace-mapping": "^0.3.29",
+ "estree-walker": "^3.0.3",
+ "js-tokens": "^9.0.1"
+ }
+ },
+ "node_modules/balanced-match": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
+ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
+ "license": "MIT"
+ },
+ "node_modules/base64-js": {
+ "version": "1.5.1",
+ "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
+ "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "license": "MIT"
+ },
+ "node_modules/big-integer": {
+ "version": "1.6.52",
+ "resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.52.tgz",
+ "integrity": "sha512-QxD8cf2eVqJOOz63z6JIN9BzvVs/dlySa5HGSBH5xtR8dPteIRQnBxxKqkNTiT6jbDTF6jAfrd4oMcND9RGbQg==",
+ "dev": true,
+ "license": "Unlicense",
+ "engines": {
+ "node": ">=0.6"
+ }
+ },
+ "node_modules/body-parser": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-2.2.1.tgz",
+ "integrity": "sha512-nfDwkulwiZYQIGwxdy0RUmowMhKcFVcYXUU7m4QlKYim1rUtg83xm2yjZ40QjDuc291AJjjeSc9b++AWHSgSHw==",
+ "license": "MIT",
+ "dependencies": {
+ "bytes": "^3.1.2",
+ "content-type": "^1.0.5",
+ "debug": "^4.4.3",
+ "http-errors": "^2.0.0",
+ "iconv-lite": "^0.7.0",
+ "on-finished": "^2.4.1",
+ "qs": "^6.14.0",
+ "raw-body": "^3.0.1",
+ "type-is": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/express"
+ }
+ },
+ "node_modules/bplist-creator": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/bplist-creator/-/bplist-creator-0.1.0.tgz",
+ "integrity": "sha512-sXaHZicyEEmY86WyueLTQesbeoH/mquvarJaQNbjuOQO+7gbFcDEWqKmcWA4cOTLzFlfgvkiVxolk1k5bBIpmg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "stream-buffers": "2.2.x"
+ }
+ },
+ "node_modules/bplist-parser": {
+ "version": "0.3.1",
+ "resolved": "https://registry.npmjs.org/bplist-parser/-/bplist-parser-0.3.1.tgz",
+ "integrity": "sha512-PyJxiNtA5T2PlLIeBot4lbp7rj4OadzjnMZD/G5zuBNt8ei/yCU7+wW0h2bag9vr8c+/WuRWmSxbqAl9hL1rBA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "big-integer": "1.6.x"
+ },
+ "engines": {
+ "node": ">= 5.10.0"
+ }
+ },
+ "node_modules/brace-expansion": {
+ "version": "1.1.12",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz",
+ "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "balanced-match": "^1.0.0",
+ "concat-map": "0.0.1"
+ }
+ },
+ "node_modules/braces": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz",
+ "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "fill-range": "^7.1.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/bundle-require": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/bundle-require/-/bundle-require-5.1.0.tgz",
+ "integrity": "sha512-3WrrOuZiyaaZPWiEt4G3+IffISVC9HYlWueJEBWED4ZH4aIAC2PnkdnuRrR94M+w6yGWn4AglWtJtBI8YqvgoA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "load-tsconfig": "^0.2.3"
+ },
+ "engines": {
+ "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
+ },
+ "peerDependencies": {
+ "esbuild": ">=0.18"
+ }
+ },
+ "node_modules/bytes": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz",
+ "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/cac": {
+ "version": "6.7.14",
+ "resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz",
+ "integrity": "sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/call-bind-apply-helpers": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz",
+ "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==",
+ "license": "MIT",
+ "dependencies": {
+ "es-errors": "^1.3.0",
+ "function-bind": "^1.1.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/call-bound": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz",
+ "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==",
+ "license": "MIT",
+ "dependencies": {
+ "call-bind-apply-helpers": "^1.0.2",
+ "get-intrinsic": "^1.3.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/callsites": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
+ "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/chai": {
+ "version": "5.2.1",
+ "resolved": "https://registry.npmjs.org/chai/-/chai-5.2.1.tgz",
+ "integrity": "sha512-5nFxhUrX0PqtyogoYOA8IPswy5sZFTOsBFl/9bNsmDLgsxYTzSZQJDPppDnZPTQbzSEm0hqGjWPzRemQCYbD6A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "assertion-error": "^2.0.1",
+ "check-error": "^2.1.1",
+ "deep-eql": "^5.0.1",
+ "loupe": "^3.1.0",
+ "pathval": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/chalk": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/chalk?sponsor=1"
+ }
+ },
+ "node_modules/check-error": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/check-error/-/check-error-2.1.1.tgz",
+ "integrity": "sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 16"
+ }
+ },
+ "node_modules/chokidar": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz",
+ "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "readdirp": "^4.0.1"
+ },
+ "engines": {
+ "node": ">= 14.16.0"
+ },
+ "funding": {
+ "url": "https://paulmillr.com/funding/"
+ }
+ },
+ "node_modules/cjs-module-lexer": {
+ "version": "1.4.3",
+ "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.4.3.tgz",
+ "integrity": "sha512-9z8TZaGM1pfswYeXrUpzPrkx8UnWYdhJclsiYMm6x/w5+nN+8Tf/LnAgfLGQCm59qAOxU8WwHEq2vNwF6i4j+Q==",
+ "license": "MIT"
+ },
+ "node_modules/color-convert": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "color-name": "~1.1.4"
+ },
+ "engines": {
+ "node": ">=7.0.0"
+ }
+ },
+ "node_modules/color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/commander": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz",
+ "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/concat-map": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
+ "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/confbox": {
+ "version": "0.1.8",
+ "resolved": "https://registry.npmjs.org/confbox/-/confbox-0.1.8.tgz",
+ "integrity": "sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/consola": {
+ "version": "3.4.2",
+ "resolved": "https://registry.npmjs.org/consola/-/consola-3.4.2.tgz",
+ "integrity": "sha512-5IKcdX0nnYavi6G7TtOhwkYzyjfJlatbjMjuLSfE2kYT5pMDOilZ4OvMhi637CcDICTmz3wARPoyhqyX1Y+XvA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^14.18.0 || >=16.10.0"
+ }
+ },
+ "node_modules/content-disposition": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-1.0.0.tgz",
+ "integrity": "sha512-Au9nRL8VNUut/XSzbQA38+M78dzP4D+eqg3gfJHMIHHYa3bg067xj1KxMUWj+VULbiZMowKngFFbKczUrNJ1mg==",
+ "license": "MIT",
+ "dependencies": {
+ "safe-buffer": "5.2.1"
+ },
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/content-type": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz",
+ "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/cookie": {
+ "version": "0.7.2",
+ "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz",
+ "integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/cookie-signature": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.2.2.tgz",
+ "integrity": "sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.6.0"
+ }
+ },
+ "node_modules/cors": {
+ "version": "2.8.5",
+ "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz",
+ "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==",
+ "license": "MIT",
+ "dependencies": {
+ "object-assign": "^4",
+ "vary": "^1"
+ },
+ "engines": {
+ "node": ">= 0.10"
+ }
+ },
+ "node_modules/create-require": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz",
+ "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/cross-spawn": {
+ "version": "7.0.6",
+ "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
+ "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==",
+ "license": "MIT",
+ "dependencies": {
+ "path-key": "^3.1.0",
+ "shebang-command": "^2.0.0",
+ "which": "^2.0.1"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/debug": {
+ "version": "4.4.3",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz",
+ "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==",
+ "license": "MIT",
+ "dependencies": {
+ "ms": "^2.1.3"
+ },
+ "engines": {
+ "node": ">=6.0"
+ },
+ "peerDependenciesMeta": {
+ "supports-color": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/deep-eql": {
+ "version": "5.0.2",
+ "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-5.0.2.tgz",
+ "integrity": "sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/deep-is": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz",
+ "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/depd": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz",
+ "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/diff": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz",
+ "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "engines": {
+ "node": ">=0.3.1"
+ }
+ },
+ "node_modules/dunder-proto": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz",
+ "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==",
+ "license": "MIT",
+ "dependencies": {
+ "call-bind-apply-helpers": "^1.0.1",
+ "es-errors": "^1.3.0",
+ "gopd": "^1.2.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/eastasianwidth": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz",
+ "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/ee-first": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
+ "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==",
+ "license": "MIT"
+ },
+ "node_modules/emoji-regex": {
+ "version": "9.2.2",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz",
+ "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/encodeurl": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz",
+ "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/es-define-property": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz",
+ "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/es-errors": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz",
+ "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/es-module-lexer": {
+ "version": "1.7.0",
+ "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.7.0.tgz",
+ "integrity": "sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/es-object-atoms": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz",
+ "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==",
+ "license": "MIT",
+ "dependencies": {
+ "es-errors": "^1.3.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/esbuild": {
+ "version": "0.25.8",
+ "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.8.tgz",
+ "integrity": "sha512-vVC0USHGtMi8+R4Kz8rt6JhEWLxsv9Rnu/lGYbPR8u47B+DCBksq9JarW0zOO7bs37hyOK1l2/oqtbciutL5+Q==",
+ "dev": true,
+ "hasInstallScript": true,
+ "license": "MIT",
+ "bin": {
+ "esbuild": "bin/esbuild"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "optionalDependencies": {
+ "@esbuild/aix-ppc64": "0.25.8",
+ "@esbuild/android-arm": "0.25.8",
+ "@esbuild/android-arm64": "0.25.8",
+ "@esbuild/android-x64": "0.25.8",
+ "@esbuild/darwin-arm64": "0.25.8",
+ "@esbuild/darwin-x64": "0.25.8",
+ "@esbuild/freebsd-arm64": "0.25.8",
+ "@esbuild/freebsd-x64": "0.25.8",
+ "@esbuild/linux-arm": "0.25.8",
+ "@esbuild/linux-arm64": "0.25.8",
+ "@esbuild/linux-ia32": "0.25.8",
+ "@esbuild/linux-loong64": "0.25.8",
+ "@esbuild/linux-mips64el": "0.25.8",
+ "@esbuild/linux-ppc64": "0.25.8",
+ "@esbuild/linux-riscv64": "0.25.8",
+ "@esbuild/linux-s390x": "0.25.8",
+ "@esbuild/linux-x64": "0.25.8",
+ "@esbuild/netbsd-arm64": "0.25.8",
+ "@esbuild/netbsd-x64": "0.25.8",
+ "@esbuild/openbsd-arm64": "0.25.8",
+ "@esbuild/openbsd-x64": "0.25.8",
+ "@esbuild/openharmony-arm64": "0.25.8",
+ "@esbuild/sunos-x64": "0.25.8",
+ "@esbuild/win32-arm64": "0.25.8",
+ "@esbuild/win32-ia32": "0.25.8",
+ "@esbuild/win32-x64": "0.25.8"
+ }
+ },
+ "node_modules/escape-html": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
+ "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==",
+ "license": "MIT"
+ },
+ "node_modules/escape-string-regexp": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
+ "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/eslint": {
+ "version": "9.33.0",
+ "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.33.0.tgz",
+ "integrity": "sha512-TS9bTNIryDzStCpJN93aC5VRSW3uTx9sClUn4B87pwiCaJh220otoI0X8mJKr+VcPtniMdN8GKjlwgWGUv5ZKA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@eslint-community/eslint-utils": "^4.2.0",
+ "@eslint-community/regexpp": "^4.12.1",
+ "@eslint/config-array": "^0.21.0",
+ "@eslint/config-helpers": "^0.3.1",
+ "@eslint/core": "^0.15.2",
+ "@eslint/eslintrc": "^3.3.1",
+ "@eslint/js": "9.33.0",
+ "@eslint/plugin-kit": "^0.3.5",
+ "@humanfs/node": "^0.16.6",
+ "@humanwhocodes/module-importer": "^1.0.1",
+ "@humanwhocodes/retry": "^0.4.2",
+ "@types/estree": "^1.0.6",
+ "@types/json-schema": "^7.0.15",
+ "ajv": "^6.12.4",
+ "chalk": "^4.0.0",
+ "cross-spawn": "^7.0.6",
+ "debug": "^4.3.2",
+ "escape-string-regexp": "^4.0.0",
+ "eslint-scope": "^8.4.0",
+ "eslint-visitor-keys": "^4.2.1",
+ "espree": "^10.4.0",
+ "esquery": "^1.5.0",
+ "esutils": "^2.0.2",
+ "fast-deep-equal": "^3.1.3",
+ "file-entry-cache": "^8.0.0",
+ "find-up": "^5.0.0",
+ "glob-parent": "^6.0.2",
+ "ignore": "^5.2.0",
+ "imurmurhash": "^0.1.4",
+ "is-glob": "^4.0.0",
+ "json-stable-stringify-without-jsonify": "^1.0.1",
+ "lodash.merge": "^4.6.2",
+ "minimatch": "^3.1.2",
+ "natural-compare": "^1.4.0",
+ "optionator": "^0.9.3"
+ },
+ "bin": {
+ "eslint": "bin/eslint.js"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "url": "https://eslint.org/donate"
+ },
+ "peerDependencies": {
+ "jiti": "*"
+ },
+ "peerDependenciesMeta": {
+ "jiti": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/eslint-config-prettier": {
+ "version": "10.1.8",
+ "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-10.1.8.tgz",
+ "integrity": "sha512-82GZUjRS0p/jganf6q1rEO25VSoHH0hKPCTrgillPjdI/3bgBhAE1QzHrHTizjpRvy6pGAvKjDJtk2pF9NDq8w==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "eslint-config-prettier": "bin/cli.js"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint-config-prettier"
+ },
+ "peerDependencies": {
+ "eslint": ">=7.0.0"
+ }
+ },
+ "node_modules/eslint-plugin-prettier": {
+ "version": "5.5.4",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-5.5.4.tgz",
+ "integrity": "sha512-swNtI95SToIz05YINMA6Ox5R057IMAmWZ26GqPxusAp1TZzj+IdY9tXNWWD3vkF/wEqydCONcwjTFpxybBqZsg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "prettier-linter-helpers": "^1.0.0",
+ "synckit": "^0.11.7"
+ },
+ "engines": {
+ "node": "^14.18.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint-plugin-prettier"
+ },
+ "peerDependencies": {
+ "@types/eslint": ">=8.0.0",
+ "eslint": ">=8.0.0",
+ "eslint-config-prettier": ">= 7.0.0 <10.0.0 || >=10.1.0",
+ "prettier": ">=3.0.0"
+ },
+ "peerDependenciesMeta": {
+ "@types/eslint": {
+ "optional": true
+ },
+ "eslint-config-prettier": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/eslint-scope": {
+ "version": "8.4.0",
+ "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.4.0.tgz",
+ "integrity": "sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "esrecurse": "^4.3.0",
+ "estraverse": "^5.2.0"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/eslint-visitor-keys": {
+ "version": "3.4.3",
+ "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz",
+ "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/eslint/node_modules/eslint-visitor-keys": {
+ "version": "4.2.1",
+ "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz",
+ "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/espree": {
+ "version": "10.4.0",
+ "resolved": "https://registry.npmjs.org/espree/-/espree-10.4.0.tgz",
+ "integrity": "sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "acorn": "^8.15.0",
+ "acorn-jsx": "^5.3.2",
+ "eslint-visitor-keys": "^4.2.1"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/espree/node_modules/eslint-visitor-keys": {
+ "version": "4.2.1",
+ "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz",
+ "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/esquery": {
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz",
+ "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "estraverse": "^5.1.0"
+ },
+ "engines": {
+ "node": ">=0.10"
+ }
+ },
+ "node_modules/esrecurse": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz",
+ "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "estraverse": "^5.2.0"
+ },
+ "engines": {
+ "node": ">=4.0"
+ }
+ },
+ "node_modules/estraverse": {
+ "version": "5.3.0",
+ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz",
+ "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "engines": {
+ "node": ">=4.0"
+ }
+ },
+ "node_modules/estree-walker": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz",
+ "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/estree": "^1.0.0"
+ }
+ },
+ "node_modules/esutils": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz",
+ "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/etag": {
+ "version": "1.8.1",
+ "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
+ "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/eventsource": {
+ "version": "3.0.7",
+ "resolved": "https://registry.npmjs.org/eventsource/-/eventsource-3.0.7.tgz",
+ "integrity": "sha512-CRT1WTyuQoD771GW56XEZFQ/ZoSfWid1alKGDYMmkt2yl8UXrVR4pspqWNEcqKvVIzg6PAltWjxcSSPrboA4iA==",
+ "license": "MIT",
+ "dependencies": {
+ "eventsource-parser": "^3.0.1"
+ },
+ "engines": {
+ "node": ">=18.0.0"
+ }
+ },
+ "node_modules/eventsource-parser": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/eventsource-parser/-/eventsource-parser-3.0.3.tgz",
+ "integrity": "sha512-nVpZkTMM9rF6AQ9gPJpFsNAMt48wIzB5TQgiTLdHiuO8XEDhUgZEhqKlZWXbIzo9VmJ/HvysHqEaVeD5v9TPvA==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=20.0.0"
+ }
+ },
+ "node_modules/expect-type": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/expect-type/-/expect-type-1.2.2.tgz",
+ "integrity": "sha512-JhFGDVJ7tmDJItKhYgJCGLOWjuK9vPxiXoUFLwLDc99NlmklilbiQJwoctZtt13+xMw91MCk/REan6MWHqDjyA==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">=12.0.0"
+ }
+ },
+ "node_modules/express": {
+ "version": "5.2.1",
+ "resolved": "https://registry.npmjs.org/express/-/express-5.2.1.tgz",
+ "integrity": "sha512-hIS4idWWai69NezIdRt2xFVofaF4j+6INOpJlVOLDO8zXGpUVEVzIYk12UUi2JzjEzWL3IOAxcTubgz9Po0yXw==",
+ "license": "MIT",
+ "dependencies": {
+ "accepts": "^2.0.0",
+ "body-parser": "^2.2.1",
+ "content-disposition": "^1.0.0",
+ "content-type": "^1.0.5",
+ "cookie": "^0.7.1",
+ "cookie-signature": "^1.2.1",
+ "debug": "^4.4.0",
+ "depd": "^2.0.0",
+ "encodeurl": "^2.0.0",
+ "escape-html": "^1.0.3",
+ "etag": "^1.8.1",
+ "finalhandler": "^2.1.0",
+ "fresh": "^2.0.0",
+ "http-errors": "^2.0.0",
+ "merge-descriptors": "^2.0.0",
+ "mime-types": "^3.0.0",
+ "on-finished": "^2.4.1",
+ "once": "^1.4.0",
+ "parseurl": "^1.3.3",
+ "proxy-addr": "^2.0.7",
+ "qs": "^6.14.0",
+ "range-parser": "^1.2.1",
+ "router": "^2.2.0",
+ "send": "^1.1.0",
+ "serve-static": "^2.2.0",
+ "statuses": "^2.0.1",
+ "type-is": "^2.0.1",
+ "vary": "^1.1.2"
+ },
+ "engines": {
+ "node": ">= 18"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/express"
+ }
+ },
+ "node_modules/express-rate-limit": {
+ "version": "7.5.1",
+ "resolved": "https://registry.npmjs.org/express-rate-limit/-/express-rate-limit-7.5.1.tgz",
+ "integrity": "sha512-7iN8iPMDzOMHPUYllBEsQdWVB6fPDMPqwjBaFrgr4Jgr/+okjvzAy+UHlYYL/Vs0OsOrMkwS6PJDkFlJwoxUnw==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 16"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/express-rate-limit"
+ },
+ "peerDependencies": {
+ "express": ">= 4.11"
+ }
+ },
+ "node_modules/fast-deep-equal": {
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
+ "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
+ "license": "MIT"
+ },
+ "node_modules/fast-diff": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.3.0.tgz",
+ "integrity": "sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==",
+ "dev": true,
+ "license": "Apache-2.0"
+ },
+ "node_modules/fast-glob": {
+ "version": "3.3.3",
+ "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz",
+ "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@nodelib/fs.stat": "^2.0.2",
+ "@nodelib/fs.walk": "^1.2.3",
+ "glob-parent": "^5.1.2",
+ "merge2": "^1.3.0",
+ "micromatch": "^4.0.8"
+ },
+ "engines": {
+ "node": ">=8.6.0"
+ }
+ },
+ "node_modules/fast-glob/node_modules/glob-parent": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
+ "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "is-glob": "^4.0.1"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/fast-json-stable-stringify": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
+ "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/fast-levenshtein": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz",
+ "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/fast-uri": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.0.tgz",
+ "integrity": "sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/fastify"
+ },
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/fastify"
+ }
+ ],
+ "license": "BSD-3-Clause"
+ },
+ "node_modules/fastq": {
+ "version": "1.19.1",
+ "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.19.1.tgz",
+ "integrity": "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "reusify": "^1.0.4"
+ }
+ },
+ "node_modules/fflate": {
+ "version": "0.8.2",
+ "resolved": "https://registry.npmjs.org/fflate/-/fflate-0.8.2.tgz",
+ "integrity": "sha512-cPJU47OaAoCbg0pBvzsgpTPhmhqI5eJjh/JIu8tPj5q+T7iLvW/JAYUqmE7KOB4R1ZyEhzBaIQpQpardBF5z8A==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/file-entry-cache": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz",
+ "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "flat-cache": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=16.0.0"
+ }
+ },
+ "node_modules/fill-range": {
+ "version": "7.1.1",
+ "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
+ "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "to-regex-range": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/finalhandler": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-2.1.0.tgz",
+ "integrity": "sha512-/t88Ty3d5JWQbWYgaOGCCYfXRwV1+be02WqYYlL6h0lEiUAMPM8o8qKGO01YIkOHzka2up08wvgYD0mDiI+q3Q==",
+ "license": "MIT",
+ "dependencies": {
+ "debug": "^4.4.0",
+ "encodeurl": "^2.0.0",
+ "escape-html": "^1.0.3",
+ "on-finished": "^2.4.1",
+ "parseurl": "^1.3.3",
+ "statuses": "^2.0.1"
+ },
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/find-up": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz",
+ "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "locate-path": "^6.0.0",
+ "path-exists": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/fix-dts-default-cjs-exports": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/fix-dts-default-cjs-exports/-/fix-dts-default-cjs-exports-1.0.1.tgz",
+ "integrity": "sha512-pVIECanWFC61Hzl2+oOCtoJ3F17kglZC/6N94eRWycFgBH35hHx0Li604ZIzhseh97mf2p0cv7vVrOZGoqhlEg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "magic-string": "^0.30.17",
+ "mlly": "^1.7.4",
+ "rollup": "^4.34.8"
+ }
+ },
+ "node_modules/flat-cache": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz",
+ "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "flatted": "^3.2.9",
+ "keyv": "^4.5.4"
+ },
+ "engines": {
+ "node": ">=16"
+ }
+ },
+ "node_modules/flatted": {
+ "version": "3.3.3",
+ "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.3.tgz",
+ "integrity": "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/foreground-child": {
+ "version": "3.3.1",
+ "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.1.tgz",
+ "integrity": "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "cross-spawn": "^7.0.6",
+ "signal-exit": "^4.0.1"
+ },
+ "engines": {
+ "node": ">=14"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/forwarded": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz",
+ "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/forwarded-parse": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/forwarded-parse/-/forwarded-parse-2.1.2.tgz",
+ "integrity": "sha512-alTFZZQDKMporBH77856pXgzhEzaUVmLCDk+egLgIgHst3Tpndzz8MnKe+GzRJRfvVdn69HhpW7cmXzvtLvJAw==",
+ "license": "MIT"
+ },
+ "node_modules/fresh": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/fresh/-/fresh-2.0.0.tgz",
+ "integrity": "sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/fsevents": {
+ "version": "2.3.2",
+ "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz",
+ "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==",
+ "dev": true,
+ "hasInstallScript": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
+ }
+ },
+ "node_modules/function-bind": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
+ "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
+ "license": "MIT",
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/get-intrinsic": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz",
+ "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==",
+ "license": "MIT",
+ "dependencies": {
+ "call-bind-apply-helpers": "^1.0.2",
+ "es-define-property": "^1.0.1",
+ "es-errors": "^1.3.0",
+ "es-object-atoms": "^1.1.1",
+ "function-bind": "^1.1.2",
+ "get-proto": "^1.0.1",
+ "gopd": "^1.2.0",
+ "has-symbols": "^1.1.0",
+ "hasown": "^2.0.2",
+ "math-intrinsics": "^1.1.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/get-proto": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz",
+ "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==",
+ "license": "MIT",
+ "dependencies": {
+ "dunder-proto": "^1.0.1",
+ "es-object-atoms": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/get-tsconfig": {
+ "version": "4.10.1",
+ "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.10.1.tgz",
+ "integrity": "sha512-auHyJ4AgMz7vgS8Hp3N6HXSmlMdUyhSUrfBF16w153rxtLIEOE+HGqaBppczZvnHLqQJfiHotCYpNhl0lUROFQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "resolve-pkg-maps": "^1.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1"
+ }
+ },
+ "node_modules/glob": {
+ "version": "10.5.0",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-10.5.0.tgz",
+ "integrity": "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "foreground-child": "^3.1.0",
+ "jackspeak": "^3.1.2",
+ "minimatch": "^9.0.4",
+ "minipass": "^7.1.2",
+ "package-json-from-dist": "^1.0.0",
+ "path-scurry": "^1.11.1"
+ },
+ "bin": {
+ "glob": "dist/esm/bin.mjs"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/glob-parent": {
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz",
+ "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "is-glob": "^4.0.3"
+ },
+ "engines": {
+ "node": ">=10.13.0"
+ }
+ },
+ "node_modules/glob/node_modules/brace-expansion": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz",
+ "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "balanced-match": "^1.0.0"
+ }
+ },
+ "node_modules/glob/node_modules/minimatch": {
+ "version": "9.0.5",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz",
+ "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "brace-expansion": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=16 || 14 >=14.17"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/globals": {
+ "version": "14.0.0",
+ "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz",
+ "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/gopd": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz",
+ "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/graphemer": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz",
+ "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/has-symbols": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz",
+ "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/hasown": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz",
+ "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==",
+ "license": "MIT",
+ "dependencies": {
+ "function-bind": "^1.1.2"
+ },
+ "engines": {
"node": ">= 0.4"
}
},
- "node_modules/ee-first": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
- "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==",
+ "node_modules/hono": {
+ "version": "4.11.3",
+ "resolved": "https://registry.npmjs.org/hono/-/hono-4.11.3.tgz",
+ "integrity": "sha512-PmQi306+M/ct/m5s66Hrg+adPnkD5jiO6IjA7WhWw0gSBSo1EcRegwuI1deZ+wd5pzCGynCcn2DprnE4/yEV4w==",
+ "license": "MIT",
+ "peer": true,
+ "engines": {
+ "node": ">=16.9.0"
+ }
+ },
+ "node_modules/html-escaper": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz",
+ "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==",
+ "dev": true,
"license": "MIT"
},
- "node_modules/encodeurl": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz",
- "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==",
+ "node_modules/http-errors": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.1.tgz",
+ "integrity": "sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==",
"license": "MIT",
+ "dependencies": {
+ "depd": "~2.0.0",
+ "inherits": "~2.0.4",
+ "setprototypeof": "~1.2.0",
+ "statuses": "~2.0.2",
+ "toidentifier": "~1.0.1"
+ },
"engines": {
"node": ">= 0.8"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/express"
+ }
+ },
+ "node_modules/https-proxy-agent": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz",
+ "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==",
+ "license": "MIT",
+ "dependencies": {
+ "agent-base": "6",
+ "debug": "4"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/iconv-lite": {
+ "version": "0.7.0",
+ "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.0.tgz",
+ "integrity": "sha512-cf6L2Ds3h57VVmkZe+Pn+5APsT7FpqJtEhhieDCvrE2MK5Qk9MyffgQyuxQTm6BChfeZNtcOLHp9IcWRVcIcBQ==",
+ "license": "MIT",
+ "dependencies": {
+ "safer-buffer": ">= 2.1.2 < 3.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/express"
+ }
+ },
+ "node_modules/ignore": {
+ "version": "5.3.2",
+ "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz",
+ "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 4"
+ }
+ },
+ "node_modules/import-fresh": {
+ "version": "3.3.1",
+ "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz",
+ "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "parent-module": "^1.0.0",
+ "resolve-from": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/import-in-the-middle": {
+ "version": "1.14.2",
+ "resolved": "https://registry.npmjs.org/import-in-the-middle/-/import-in-the-middle-1.14.2.tgz",
+ "integrity": "sha512-5tCuY9BV8ujfOpwtAGgsTx9CGUapcFMEEyByLv1B+v2+6DhAcw+Zr0nhQT7uwaZ7DiourxFEscghOR8e1aPLQw==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "acorn": "^8.14.0",
+ "acorn-import-attributes": "^1.9.5",
+ "cjs-module-lexer": "^1.2.2",
+ "module-details-from-path": "^1.0.3"
+ }
+ },
+ "node_modules/imurmurhash": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
+ "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.8.19"
+ }
+ },
+ "node_modules/inherits": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
+ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
+ "license": "ISC"
+ },
+ "node_modules/ipaddr.js": {
+ "version": "1.9.1",
+ "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz",
+ "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.10"
+ }
+ },
+ "node_modules/is-core-module": {
+ "version": "2.16.1",
+ "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz",
+ "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==",
+ "license": "MIT",
+ "dependencies": {
+ "hasown": "^2.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-extglob": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
+ "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-fullwidth-code-point": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
+ "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/is-glob": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
+ "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-extglob": "^2.1.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-number": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
+ "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.12.0"
+ }
+ },
+ "node_modules/is-promise": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-4.0.0.tgz",
+ "integrity": "sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==",
+ "license": "MIT"
+ },
+ "node_modules/isexe": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
+ "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
+ "license": "ISC"
+ },
+ "node_modules/istanbul-lib-coverage": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz",
+ "integrity": "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/istanbul-lib-report": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz",
+ "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "istanbul-lib-coverage": "^3.0.0",
+ "make-dir": "^4.0.0",
+ "supports-color": "^7.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/istanbul-lib-source-maps": {
+ "version": "5.0.6",
+ "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-5.0.6.tgz",
+ "integrity": "sha512-yg2d+Em4KizZC5niWhQaIomgf5WlL4vOOjZ5xGCmF8SnPE/mDWWXgvRExdcpCgh9lLRRa1/fSYp2ymmbJ1pI+A==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "@jridgewell/trace-mapping": "^0.3.23",
+ "debug": "^4.1.1",
+ "istanbul-lib-coverage": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=10"
}
},
- "node_modules/es-define-property": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz",
- "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==",
+ "node_modules/istanbul-reports": {
+ "version": "3.1.7",
+ "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.7.tgz",
+ "integrity": "sha512-BewmUXImeuRk2YY0PVbxgKAysvhRPUQE0h5QRM++nVWyubKGV0l8qQ5op8+B2DOmwSe63Jivj0BjkPQVf8fP5g==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "html-escaper": "^2.0.0",
+ "istanbul-lib-report": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/jackspeak": {
+ "version": "3.4.3",
+ "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz",
+ "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==",
+ "dev": true,
+ "license": "BlueOak-1.0.0",
+ "dependencies": {
+ "@isaacs/cliui": "^8.0.2"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ },
+ "optionalDependencies": {
+ "@pkgjs/parseargs": "^0.11.0"
+ }
+ },
+ "node_modules/jose": {
+ "version": "6.1.3",
+ "resolved": "https://registry.npmjs.org/jose/-/jose-6.1.3.tgz",
+ "integrity": "sha512-0TpaTfihd4QMNwrz/ob2Bp7X04yuxJkjRGi4aKmOqwhov54i6u79oCv7T+C7lo70MKH6BesI3vscD1yb/yzKXQ==",
+ "license": "MIT",
+ "funding": {
+ "url": "https://github.com/sponsors/panva"
+ }
+ },
+ "node_modules/joycon": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/joycon/-/joycon-3.1.1.tgz",
+ "integrity": "sha512-34wB/Y7MW7bzjKRjUKTa46I2Z7eV62Rkhva+KkopW7Qvv/OSWBqvkSY7vusOPrNuZcUG3tApvdVgNB8POj3SPw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/js-tokens": {
+ "version": "9.0.1",
+ "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-9.0.1.tgz",
+ "integrity": "sha512-mxa9E9ITFOt0ban3j6L5MpjwegGz6lBQmM1IJkWeBZGcMxto50+eWdjC/52xDbS2vy0k7vIMK0Fe2wfL9OQSpQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/js-yaml": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz",
+ "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "argparse": "^2.0.1"
+ },
+ "bin": {
+ "js-yaml": "bin/js-yaml.js"
+ }
+ },
+ "node_modules/json-buffer": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz",
+ "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/json-schema-traverse": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
+ "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/json-schema-typed": {
+ "version": "8.0.2",
+ "resolved": "https://registry.npmjs.org/json-schema-typed/-/json-schema-typed-8.0.2.tgz",
+ "integrity": "sha512-fQhoXdcvc3V28x7C7BMs4P5+kNlgUURe2jmUT1T//oBRMDrqy1QPelJimwZGo7Hg9VPV3EQV5Bnq4hbFy2vetA==",
+ "license": "BSD-2-Clause"
+ },
+ "node_modules/json-stable-stringify-without-jsonify": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz",
+ "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/keyv": {
+ "version": "4.5.4",
+ "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz",
+ "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==",
+ "dev": true,
"license": "MIT",
- "engines": {
- "node": ">= 0.4"
+ "dependencies": {
+ "json-buffer": "3.0.1"
}
},
- "node_modules/es-errors": {
- "version": "1.3.0",
- "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz",
- "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==",
+ "node_modules/levn": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz",
+ "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==",
+ "dev": true,
"license": "MIT",
+ "dependencies": {
+ "prelude-ls": "^1.2.1",
+ "type-check": "~0.4.0"
+ },
"engines": {
- "node": ">= 0.4"
+ "node": ">= 0.8.0"
}
},
- "node_modules/es-object-atoms": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz",
- "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==",
+ "node_modules/lilconfig": {
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.3.tgz",
+ "integrity": "sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==",
+ "dev": true,
"license": "MIT",
- "dependencies": {
- "es-errors": "^1.3.0"
- },
"engines": {
- "node": ">= 0.4"
+ "node": ">=14"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/antonk52"
}
},
- "node_modules/escape-html": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
- "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==",
+ "node_modules/lines-and-columns": {
+ "version": "1.2.4",
+ "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz",
+ "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==",
+ "dev": true,
"license": "MIT"
},
- "node_modules/escape-string-regexp": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
- "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
+ "node_modules/load-tsconfig": {
+ "version": "0.2.5",
+ "resolved": "https://registry.npmjs.org/load-tsconfig/-/load-tsconfig-0.2.5.tgz",
+ "integrity": "sha512-IXO6OCs9yg8tMKzfPZ1YmheJbZCiEsnBdcB03l0OcfK9prKnJb96siuHCr5Fl37/yo9DnKU+TLpxzTUspw9shg==",
"dev": true,
"license": "MIT",
"engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
+ "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
}
},
- "node_modules/eslint": {
- "version": "9.24.0",
- "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.24.0.tgz",
- "integrity": "sha512-eh/jxIEJyZrvbWRe4XuVclLPDYSYYYgLy5zXGGxD6j8zjSAxFEzI2fL/8xNq6O2yKqVt+eF2YhV+hxjV6UKXwQ==",
+ "node_modules/locate-path": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz",
+ "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@eslint-community/eslint-utils": "^4.2.0",
- "@eslint-community/regexpp": "^4.12.1",
- "@eslint/config-array": "^0.20.0",
- "@eslint/config-helpers": "^0.2.0",
- "@eslint/core": "^0.12.0",
- "@eslint/eslintrc": "^3.3.1",
- "@eslint/js": "9.24.0",
- "@eslint/plugin-kit": "^0.2.7",
- "@humanfs/node": "^0.16.6",
- "@humanwhocodes/module-importer": "^1.0.1",
- "@humanwhocodes/retry": "^0.4.2",
- "@types/estree": "^1.0.6",
- "@types/json-schema": "^7.0.15",
- "ajv": "^6.12.4",
- "chalk": "^4.0.0",
- "cross-spawn": "^7.0.6",
- "debug": "^4.3.2",
- "escape-string-regexp": "^4.0.0",
- "eslint-scope": "^8.3.0",
- "eslint-visitor-keys": "^4.2.0",
- "espree": "^10.3.0",
- "esquery": "^1.5.0",
- "esutils": "^2.0.2",
- "fast-deep-equal": "^3.1.3",
- "file-entry-cache": "^8.0.0",
- "find-up": "^5.0.0",
- "glob-parent": "^6.0.2",
- "ignore": "^5.2.0",
- "imurmurhash": "^0.1.4",
- "is-glob": "^4.0.0",
- "json-stable-stringify-without-jsonify": "^1.0.1",
- "lodash.merge": "^4.6.2",
- "minimatch": "^3.1.2",
- "natural-compare": "^1.4.0",
- "optionator": "^0.9.3"
- },
- "bin": {
- "eslint": "bin/eslint.js"
+ "p-locate": "^5.0.0"
},
"engines": {
- "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ "node": ">=10"
},
"funding": {
- "url": "https://eslint.org/donate"
- },
- "peerDependencies": {
- "jiti": "*"
- },
- "peerDependenciesMeta": {
- "jiti": {
- "optional": true
- }
+ "url": "https://github.com/sponsors/sindresorhus"
}
},
- "node_modules/eslint-config-prettier": {
- "version": "10.1.1",
- "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-10.1.1.tgz",
- "integrity": "sha512-4EQQr6wXwS+ZJSzaR5ZCrYgLxqvUjdXctaEtBqHcbkW944B1NQyO4qpdHQbXBONfwxXdkAY81HH4+LUfrg+zPw==",
+ "node_modules/lodash.merge": {
+ "version": "4.6.2",
+ "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz",
+ "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/lodash.sortby": {
+ "version": "4.7.0",
+ "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz",
+ "integrity": "sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/loupe": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/loupe/-/loupe-3.2.0.tgz",
+ "integrity": "sha512-2NCfZcT5VGVNX9mSZIxLRkEAegDGBpuQZBy13desuHeVORmBDyAET4TkJr4SjqQy3A8JDofMN6LpkK8Xcm/dlw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/lru-cache": {
+ "version": "10.4.3",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz",
+ "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/magic-string": {
+ "version": "0.30.17",
+ "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.17.tgz",
+ "integrity": "sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==",
"dev": true,
"license": "MIT",
- "bin": {
- "eslint-config-prettier": "bin/cli.js"
- },
- "peerDependencies": {
- "eslint": ">=7.0.0"
+ "dependencies": {
+ "@jridgewell/sourcemap-codec": "^1.5.0"
}
},
- "node_modules/eslint-plugin-prettier": {
- "version": "5.2.6",
- "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-5.2.6.tgz",
- "integrity": "sha512-mUcf7QG2Tjk7H055Jk0lGBjbgDnfrvqjhXh9t2xLMSCjZVcw9Rb1V6sVNXO0th3jgeO7zllWPTNRil3JW94TnQ==",
+ "node_modules/magicast": {
+ "version": "0.3.5",
+ "resolved": "https://registry.npmjs.org/magicast/-/magicast-0.3.5.tgz",
+ "integrity": "sha512-L0WhttDl+2BOsybvEOLK7fW3UA0OQ0IQ2d6Zl2x/a6vVRs3bAY0ECOSHHeL5jD+SbOpOCUEi0y1DgHEn9Qn1AQ==",
"dev": true,
"license": "MIT",
"dependencies": {
- "prettier-linter-helpers": "^1.0.0",
- "synckit": "^0.11.0"
- },
- "engines": {
- "node": "^14.18.0 || >=16.0.0"
- },
- "funding": {
- "url": "https://opencollective.com/eslint-plugin-prettier"
- },
- "peerDependencies": {
- "@types/eslint": ">=8.0.0",
- "eslint": ">=8.0.0",
- "eslint-config-prettier": ">= 7.0.0 <10.0.0 || >=10.1.0",
- "prettier": ">=3.0.0"
- },
- "peerDependenciesMeta": {
- "@types/eslint": {
- "optional": true
- },
- "eslint-config-prettier": {
- "optional": true
- }
+ "@babel/parser": "^7.25.4",
+ "@babel/types": "^7.25.4",
+ "source-map-js": "^1.2.0"
}
},
- "node_modules/eslint-scope": {
- "version": "8.3.0",
- "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.3.0.tgz",
- "integrity": "sha512-pUNxi75F8MJ/GdeKtVLSbYg4ZI34J6C0C7sbL4YOp2exGwen7ZsuBqKzUhXd0qMQ362yET3z+uPwKeg/0C2XCQ==",
+ "node_modules/make-dir": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz",
+ "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==",
"dev": true,
- "license": "BSD-2-Clause",
+ "license": "MIT",
"dependencies": {
- "esrecurse": "^4.3.0",
- "estraverse": "^5.2.0"
+ "semver": "^7.5.3"
},
"engines": {
- "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ "node": ">=10"
},
"funding": {
- "url": "https://opencollective.com/eslint"
+ "url": "https://github.com/sponsors/sindresorhus"
}
},
- "node_modules/eslint-visitor-keys": {
- "version": "3.4.3",
- "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz",
- "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==",
+ "node_modules/make-error": {
+ "version": "1.3.6",
+ "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz",
+ "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==",
"dev": true,
- "license": "Apache-2.0",
+ "license": "ISC"
+ },
+ "node_modules/math-intrinsics": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
+ "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==",
+ "license": "MIT",
"engines": {
- "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/media-typer": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-1.1.0.tgz",
+ "integrity": "sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/merge-descriptors": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-2.0.0.tgz",
+ "integrity": "sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
},
"funding": {
- "url": "https://opencollective.com/eslint"
+ "url": "https://github.com/sponsors/sindresorhus"
}
},
- "node_modules/eslint/node_modules/eslint-visitor-keys": {
- "version": "4.2.0",
- "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.0.tgz",
- "integrity": "sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==",
+ "node_modules/merge2": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
+ "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==",
"dev": true,
- "license": "Apache-2.0",
+ "license": "MIT",
"engines": {
- "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
- },
- "funding": {
- "url": "https://opencollective.com/eslint"
+ "node": ">= 8"
}
},
- "node_modules/espree": {
- "version": "10.3.0",
- "resolved": "https://registry.npmjs.org/espree/-/espree-10.3.0.tgz",
- "integrity": "sha512-0QYC8b24HWY8zjRnDTL6RiHfDbAWn63qb4LMj1Z4b076A4une81+z03Kg7l7mn/48PUTqoLptSXez8oknU8Clg==",
+ "node_modules/micromatch": {
+ "version": "4.0.8",
+ "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz",
+ "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==",
"dev": true,
- "license": "BSD-2-Clause",
+ "license": "MIT",
"dependencies": {
- "acorn": "^8.14.0",
- "acorn-jsx": "^5.3.2",
- "eslint-visitor-keys": "^4.2.0"
+ "braces": "^3.0.3",
+ "picomatch": "^2.3.1"
},
"engines": {
- "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
- },
- "funding": {
- "url": "https://opencollective.com/eslint"
+ "node": ">=8.6"
}
},
- "node_modules/espree/node_modules/eslint-visitor-keys": {
- "version": "4.2.0",
- "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.0.tgz",
- "integrity": "sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==",
- "dev": true,
- "license": "Apache-2.0",
+ "node_modules/mime-db": {
+ "version": "1.54.0",
+ "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz",
+ "integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==",
+ "license": "MIT",
"engines": {
- "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
- },
- "funding": {
- "url": "https://opencollective.com/eslint"
+ "node": ">= 0.6"
}
},
- "node_modules/esquery": {
- "version": "1.6.0",
- "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz",
- "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==",
- "dev": true,
- "license": "BSD-3-Clause",
+ "node_modules/mime-types": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.1.tgz",
+ "integrity": "sha512-xRc4oEhT6eaBpU1XF7AjpOFD+xQmXNB5OVKwp4tqCuBpHLS/ZbBDrc07mYTDqVMg6PfxUjjNp85O6Cd2Z/5HWA==",
+ "license": "MIT",
"dependencies": {
- "estraverse": "^5.1.0"
+ "mime-db": "^1.54.0"
},
"engines": {
- "node": ">=0.10"
+ "node": ">= 0.6"
}
},
- "node_modules/esrecurse": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz",
- "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==",
+ "node_modules/minimatch": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
+ "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
"dev": true,
- "license": "BSD-2-Clause",
+ "license": "ISC",
"dependencies": {
- "estraverse": "^5.2.0"
+ "brace-expansion": "^1.1.7"
},
"engines": {
- "node": ">=4.0"
+ "node": "*"
}
},
- "node_modules/estraverse": {
- "version": "5.3.0",
- "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz",
- "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==",
+ "node_modules/minipass": {
+ "version": "7.1.2",
+ "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz",
+ "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==",
"dev": true,
- "license": "BSD-2-Clause",
+ "license": "ISC",
"engines": {
- "node": ">=4.0"
+ "node": ">=16 || 14 >=14.17"
}
},
- "node_modules/esutils": {
- "version": "2.0.3",
- "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz",
- "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==",
+ "node_modules/mlly": {
+ "version": "1.7.4",
+ "resolved": "https://registry.npmjs.org/mlly/-/mlly-1.7.4.tgz",
+ "integrity": "sha512-qmdSIPC4bDJXgZTCR7XosJiNKySV7O215tsPtDN9iEO/7q/76b/ijtgRu/+epFXSJhijtTCCGp3DWS549P3xKw==",
"dev": true,
- "license": "BSD-2-Clause",
- "engines": {
- "node": ">=0.10.0"
+ "license": "MIT",
+ "dependencies": {
+ "acorn": "^8.14.0",
+ "pathe": "^2.0.1",
+ "pkg-types": "^1.3.0",
+ "ufo": "^1.5.4"
}
},
- "node_modules/etag": {
- "version": "1.8.1",
- "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
- "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==",
+ "node_modules/module-details-from-path": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/module-details-from-path/-/module-details-from-path-1.0.4.tgz",
+ "integrity": "sha512-EGWKgxALGMgzvxYF1UyGTy0HXX/2vHLkw6+NvDKW2jypWbHpjQuj4UMcqQWXHERJhVGKikolT06G3bcKe4fi7w==",
+ "license": "MIT"
+ },
+ "node_modules/mrmime": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/mrmime/-/mrmime-2.0.1.tgz",
+ "integrity": "sha512-Y3wQdFg2Va6etvQ5I82yUhGdsKrcYox6p7FfL1LbK2J4V01F9TGlepTIhnK24t7koZibmg82KGglhA1XK5IsLQ==",
+ "dev": true,
"license": "MIT",
"engines": {
- "node": ">= 0.6"
+ "node": ">=10"
}
},
- "node_modules/eventsource": {
- "version": "3.0.6",
- "resolved": "https://registry.npmjs.org/eventsource/-/eventsource-3.0.6.tgz",
- "integrity": "sha512-l19WpE2m9hSuyP06+FbuUUf1G+R0SFLrtQfbRb9PRr+oimOfxQhgGCbVaXg5IvZyyTThJsxh6L/srkMiCeBPDA==",
+ "node_modules/ms": {
+ "version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
+ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
+ "license": "MIT"
+ },
+ "node_modules/mz": {
+ "version": "2.7.0",
+ "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz",
+ "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==",
+ "dev": true,
"license": "MIT",
"dependencies": {
- "eventsource-parser": "^3.0.1"
+ "any-promise": "^1.0.0",
+ "object-assign": "^4.0.1",
+ "thenify-all": "^1.0.0"
+ }
+ },
+ "node_modules/nanoid": {
+ "version": "3.3.11",
+ "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz",
+ "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "license": "MIT",
+ "bin": {
+ "nanoid": "bin/nanoid.cjs"
},
"engines": {
- "node": ">=18.0.0"
+ "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
}
},
- "node_modules/eventsource-parser": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/eventsource-parser/-/eventsource-parser-3.0.1.tgz",
- "integrity": "sha512-VARTJ9CYeuQYb0pZEPbzi740OWFgpHe7AYJ2WFZVnUDUQp5Dk2yJUgF36YsZ81cOyxT0QxmXD2EQpapAouzWVA==",
+ "node_modules/natural-compare": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz",
+ "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/negotiator": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-1.0.0.tgz",
+ "integrity": "sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==",
"license": "MIT",
"engines": {
- "node": ">=18.0.0"
+ "node": ">= 0.6"
}
},
- "node_modules/express": {
- "version": "5.1.0",
- "resolved": "https://registry.npmjs.org/express/-/express-5.1.0.tgz",
- "integrity": "sha512-DT9ck5YIRU+8GYzzU5kT3eHGA5iL+1Zd0EutOmTE9Dtk+Tvuzd23VBU+ec7HPNSTxXYO55gPV/hq4pSBJDjFpA==",
+ "node_modules/node-fetch": {
+ "version": "2.7.0",
+ "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz",
+ "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==",
"license": "MIT",
"dependencies": {
- "accepts": "^2.0.0",
- "body-parser": "^2.2.0",
- "content-disposition": "^1.0.0",
- "content-type": "^1.0.5",
- "cookie": "^0.7.1",
- "cookie-signature": "^1.2.1",
- "debug": "^4.4.0",
- "encodeurl": "^2.0.0",
- "escape-html": "^1.0.3",
- "etag": "^1.8.1",
- "finalhandler": "^2.1.0",
- "fresh": "^2.0.0",
- "http-errors": "^2.0.0",
- "merge-descriptors": "^2.0.0",
- "mime-types": "^3.0.0",
- "on-finished": "^2.4.1",
- "once": "^1.4.0",
- "parseurl": "^1.3.3",
- "proxy-addr": "^2.0.7",
- "qs": "^6.14.0",
- "range-parser": "^1.2.1",
- "router": "^2.2.0",
- "send": "^1.1.0",
- "serve-static": "^2.2.0",
- "statuses": "^2.0.1",
- "type-is": "^2.0.1",
- "vary": "^1.1.2"
+ "whatwg-url": "^5.0.0"
},
"engines": {
- "node": ">= 18"
+ "node": "4.x || >=6.0.0"
},
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/express"
+ "peerDependencies": {
+ "encoding": "^0.1.0"
+ },
+ "peerDependenciesMeta": {
+ "encoding": {
+ "optional": true
+ }
}
},
- "node_modules/express-rate-limit": {
- "version": "7.5.0",
- "resolved": "https://registry.npmjs.org/express-rate-limit/-/express-rate-limit-7.5.0.tgz",
- "integrity": "sha512-eB5zbQh5h+VenMPM3fh+nw1YExi5nMr6HUCR62ELSP11huvxm/Uir1H1QEyTkk5QX6A58pX6NmaTMceKZ0Eodg==",
+ "node_modules/object-assign": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
+ "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==",
"license": "MIT",
"engines": {
- "node": ">= 16"
- },
- "funding": {
- "url": "https://github.com/sponsors/express-rate-limit"
- },
- "peerDependencies": {
- "express": "^4.11 || 5 || ^5.0.0-beta.1"
+ "node": ">=0.10.0"
}
},
- "node_modules/fast-deep-equal": {
- "version": "3.1.3",
- "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
- "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/fast-diff": {
- "version": "1.3.0",
- "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.3.0.tgz",
- "integrity": "sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==",
- "dev": true,
- "license": "Apache-2.0"
- },
- "node_modules/fast-glob": {
- "version": "3.3.3",
- "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz",
- "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==",
- "dev": true,
+ "node_modules/object-inspect": {
+ "version": "1.13.4",
+ "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz",
+ "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==",
"license": "MIT",
- "dependencies": {
- "@nodelib/fs.stat": "^2.0.2",
- "@nodelib/fs.walk": "^1.2.3",
- "glob-parent": "^5.1.2",
- "merge2": "^1.3.0",
- "micromatch": "^4.0.8"
- },
"engines": {
- "node": ">=8.6.0"
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/fast-glob/node_modules/glob-parent": {
- "version": "5.1.2",
- "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
- "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
- "dev": true,
- "license": "ISC",
+ "node_modules/on-finished": {
+ "version": "2.4.1",
+ "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz",
+ "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==",
+ "license": "MIT",
"dependencies": {
- "is-glob": "^4.0.1"
+ "ee-first": "1.1.1"
},
"engines": {
- "node": ">= 6"
+ "node": ">= 0.8"
}
},
- "node_modules/fast-json-stable-stringify": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
- "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/fast-levenshtein": {
- "version": "2.0.6",
- "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz",
- "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/fastq": {
- "version": "1.19.1",
- "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.19.1.tgz",
- "integrity": "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==",
- "dev": true,
+ "node_modules/once": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
+ "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
"license": "ISC",
"dependencies": {
- "reusify": "^1.0.4"
+ "wrappy": "1"
}
},
- "node_modules/file-entry-cache": {
- "version": "8.0.0",
- "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz",
- "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==",
+ "node_modules/optionator": {
+ "version": "0.9.4",
+ "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz",
+ "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==",
"dev": true,
"license": "MIT",
"dependencies": {
- "flat-cache": "^4.0.0"
+ "deep-is": "^0.1.3",
+ "fast-levenshtein": "^2.0.6",
+ "levn": "^0.4.1",
+ "prelude-ls": "^1.2.1",
+ "type-check": "^0.4.0",
+ "word-wrap": "^1.2.5"
},
"engines": {
- "node": ">=16.0.0"
+ "node": ">= 0.8.0"
}
},
- "node_modules/fill-range": {
- "version": "7.1.1",
- "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
- "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==",
+ "node_modules/p-limit": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz",
+ "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==",
"dev": true,
"license": "MIT",
"dependencies": {
- "to-regex-range": "^5.0.1"
+ "yocto-queue": "^0.1.0"
},
"engines": {
- "node": ">=8"
- }
- },
- "node_modules/finalhandler": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-2.1.0.tgz",
- "integrity": "sha512-/t88Ty3d5JWQbWYgaOGCCYfXRwV1+be02WqYYlL6h0lEiUAMPM8o8qKGO01YIkOHzka2up08wvgYD0mDiI+q3Q==",
- "license": "MIT",
- "dependencies": {
- "debug": "^4.4.0",
- "encodeurl": "^2.0.0",
- "escape-html": "^1.0.3",
- "on-finished": "^2.4.1",
- "parseurl": "^1.3.3",
- "statuses": "^2.0.1"
+ "node": ">=10"
},
- "engines": {
- "node": ">= 0.8"
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
}
},
- "node_modules/find-up": {
+ "node_modules/p-locate": {
"version": "5.0.0",
- "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz",
- "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==",
+ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz",
+ "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==",
+ "dev": true,
"license": "MIT",
"dependencies": {
- "locate-path": "^6.0.0",
- "path-exists": "^4.0.0"
+ "p-limit": "^3.0.2"
},
"engines": {
"node": ">=10"
@@ -1506,1063 +4997,1329 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
- "node_modules/flat-cache": {
- "version": "4.0.1",
- "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz",
- "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==",
+ "node_modules/package-json-from-dist": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz",
+ "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==",
+ "dev": true,
+ "license": "BlueOak-1.0.0"
+ },
+ "node_modules/parent-module": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
+ "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==",
"dev": true,
"license": "MIT",
"dependencies": {
- "flatted": "^3.2.9",
- "keyv": "^4.5.4"
+ "callsites": "^3.0.0"
},
"engines": {
- "node": ">=16"
+ "node": ">=6"
}
},
- "node_modules/flatted": {
- "version": "3.3.3",
- "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.3.tgz",
- "integrity": "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==",
- "dev": true,
- "license": "ISC"
- },
- "node_modules/forwarded": {
- "version": "0.2.0",
- "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz",
- "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==",
+ "node_modules/parseurl": {
+ "version": "1.3.3",
+ "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
+ "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==",
"license": "MIT",
"engines": {
- "node": ">= 0.6"
+ "node": ">= 0.8"
}
},
- "node_modules/fresh": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/fresh/-/fresh-2.0.0.tgz",
- "integrity": "sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==",
+ "node_modules/path-exists": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
+ "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
+ "dev": true,
"license": "MIT",
"engines": {
- "node": ">= 0.8"
+ "node": ">=8"
}
},
- "node_modules/function-bind": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
- "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
+ "node_modules/path-key": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
+ "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
"license": "MIT",
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
+ "engines": {
+ "node": ">=8"
}
},
- "node_modules/get-intrinsic": {
- "version": "1.3.0",
- "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz",
- "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==",
- "license": "MIT",
+ "node_modules/path-parse": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
+ "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==",
+ "license": "MIT"
+ },
+ "node_modules/path-scurry": {
+ "version": "1.11.1",
+ "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz",
+ "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==",
+ "dev": true,
+ "license": "BlueOak-1.0.0",
"dependencies": {
- "call-bind-apply-helpers": "^1.0.2",
- "es-define-property": "^1.0.1",
- "es-errors": "^1.3.0",
- "es-object-atoms": "^1.1.1",
- "function-bind": "^1.1.2",
- "get-proto": "^1.0.1",
- "gopd": "^1.2.0",
- "has-symbols": "^1.1.0",
- "hasown": "^2.0.2",
- "math-intrinsics": "^1.1.0"
+ "lru-cache": "^10.2.0",
+ "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0"
},
"engines": {
- "node": ">= 0.4"
+ "node": ">=16 || 14 >=14.18"
},
"funding": {
- "url": "https://github.com/sponsors/ljharb"
+ "url": "https://github.com/sponsors/isaacs"
}
},
- "node_modules/get-proto": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz",
- "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==",
+ "node_modules/path-to-regexp": {
+ "version": "8.2.0",
+ "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.2.0.tgz",
+ "integrity": "sha512-TdrF7fW9Rphjq4RjrW0Kp2AW0Ahwu9sRGTkS6bvDi0SCwZlEZYmcfDbEsTz8RVk0EHIS/Vd1bv3JhG+1xZuAyQ==",
"license": "MIT",
- "dependencies": {
- "dunder-proto": "^1.0.1",
- "es-object-atoms": "^1.0.0"
- },
"engines": {
- "node": ">= 0.4"
+ "node": ">=16"
}
},
- "node_modules/glob-parent": {
- "version": "6.0.2",
- "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz",
- "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==",
+ "node_modules/pathe": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz",
+ "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/pathval": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/pathval/-/pathval-2.0.1.tgz",
+ "integrity": "sha512-//nshmD55c46FuFw26xV/xFAaB5HF9Xdap7HJBBnrKdAd6/GxDBaNA1870O79+9ueg61cZLSVc+OaFlfmObYVQ==",
"dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 14.16"
+ }
+ },
+ "node_modules/pg-int8": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/pg-int8/-/pg-int8-1.0.1.tgz",
+ "integrity": "sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==",
"license": "ISC",
+ "engines": {
+ "node": ">=4.0.0"
+ }
+ },
+ "node_modules/pg-protocol": {
+ "version": "1.10.3",
+ "resolved": "https://registry.npmjs.org/pg-protocol/-/pg-protocol-1.10.3.tgz",
+ "integrity": "sha512-6DIBgBQaTKDJyxnXaLiLR8wBpQQcGWuAESkRBX/t6OwA8YsqP+iVSiond2EDy6Y/dsGk8rh/jtax3js5NeV7JQ==",
+ "license": "MIT"
+ },
+ "node_modules/pg-types": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/pg-types/-/pg-types-2.2.0.tgz",
+ "integrity": "sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA==",
+ "license": "MIT",
"dependencies": {
- "is-glob": "^4.0.3"
+ "pg-int8": "1.0.1",
+ "postgres-array": "~2.0.0",
+ "postgres-bytea": "~1.0.0",
+ "postgres-date": "~1.0.4",
+ "postgres-interval": "^1.1.0"
},
"engines": {
- "node": ">=10.13.0"
+ "node": ">=4"
}
},
- "node_modules/globals": {
- "version": "14.0.0",
- "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz",
- "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==",
+ "node_modules/picocolors": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
+ "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/picomatch": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
+ "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
"dev": true,
"license": "MIT",
"engines": {
- "node": ">=18"
+ "node": ">=8.6"
},
"funding": {
- "url": "https://github.com/sponsors/sindresorhus"
+ "url": "https://github.com/sponsors/jonschlinkert"
}
},
- "node_modules/gopd": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz",
- "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==",
+ "node_modules/pirates": {
+ "version": "4.0.7",
+ "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.7.tgz",
+ "integrity": "sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA==",
+ "dev": true,
"license": "MIT",
"engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
+ "node": ">= 6"
}
},
- "node_modules/graphemer": {
- "version": "1.4.0",
- "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz",
- "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/has-flag": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
- "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "node_modules/pkce-challenge": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/pkce-challenge/-/pkce-challenge-5.0.0.tgz",
+ "integrity": "sha512-ueGLflrrnvwB3xuo/uGob5pd5FN7l0MsLf0Z87o/UQmRtwjvfylfc9MurIxRAWywCYTgrvpXBcqjV4OfCYGCIQ==",
"license": "MIT",
"engines": {
- "node": ">=8"
+ "node": ">=16.20.0"
}
},
- "node_modules/has-symbols": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz",
- "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==",
+ "node_modules/pkg-types": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-1.3.1.tgz",
+ "integrity": "sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ==",
+ "dev": true,
"license": "MIT",
+ "dependencies": {
+ "confbox": "^0.1.8",
+ "mlly": "^1.7.4",
+ "pathe": "^2.0.1"
+ }
+ },
+ "node_modules/playwright": {
+ "version": "1.55.1",
+ "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.55.1.tgz",
+ "integrity": "sha512-cJW4Xd/G3v5ovXtJJ52MAOclqeac9S/aGGgRzLabuF8TnIb6xHvMzKIa6JmrRzUkeXJgfL1MhukP0NK6l39h3A==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "playwright-core": "1.55.1"
+ },
+ "bin": {
+ "playwright": "cli.js"
+ },
"engines": {
- "node": ">= 0.4"
+ "node": ">=18"
},
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
+ "optionalDependencies": {
+ "fsevents": "2.3.2"
}
},
- "node_modules/hasown": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz",
- "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==",
- "license": "MIT",
- "dependencies": {
- "function-bind": "^1.1.2"
+ "node_modules/playwright-core": {
+ "version": "1.55.1",
+ "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.55.1.tgz",
+ "integrity": "sha512-Z6Mh9mkwX+zxSlHqdr5AOcJnfp+xUWLCt9uKV18fhzA8eyxUd8NUWzAjxUh55RZKSYwDGX0cfaySdhZJGMoJ+w==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "bin": {
+ "playwright-core": "cli.js"
},
"engines": {
- "node": ">= 0.4"
+ "node": ">=18"
}
},
- "node_modules/http-errors": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz",
- "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==",
+ "node_modules/plist": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/plist/-/plist-3.1.0.tgz",
+ "integrity": "sha512-uysumyrvkUX0rX/dEVqt8gC3sTBzd4zoWfLeS29nb53imdaXVvLINYXTI2GNqzaMuvacNx4uJQ8+b3zXR0pkgQ==",
+ "dev": true,
"license": "MIT",
"dependencies": {
- "depd": "2.0.0",
- "inherits": "2.0.4",
- "setprototypeof": "1.2.0",
- "statuses": "2.0.1",
- "toidentifier": "1.0.1"
+ "@xmldom/xmldom": "^0.8.8",
+ "base64-js": "^1.5.1",
+ "xmlbuilder": "^15.1.1"
},
"engines": {
- "node": ">= 0.8"
+ "node": ">=10.4.0"
}
},
- "node_modules/iconv-lite": {
- "version": "0.6.3",
- "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz",
- "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==",
+ "node_modules/plist/node_modules/@xmldom/xmldom": {
+ "version": "0.8.10",
+ "resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.8.10.tgz",
+ "integrity": "sha512-2WALfTl4xo2SkGCYRt6rDTFfk9R1czmBvUQy12gK2KuRKIpWEhcbbzy8EZXtz/jkRqHX8bFEc6FC1HjX4TUWYw==",
+ "dev": true,
"license": "MIT",
- "dependencies": {
- "safer-buffer": ">= 2.1.2 < 3.0.0"
- },
"engines": {
- "node": ">=0.10.0"
+ "node": ">=10.0.0"
}
},
- "node_modules/ignore": {
- "version": "5.3.2",
- "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz",
- "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==",
+ "node_modules/plist/node_modules/xmlbuilder": {
+ "version": "15.1.1",
+ "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-15.1.1.tgz",
+ "integrity": "sha512-yMqGBqtXyeN1e3TGYvgNgDVZ3j84W4cwkOXQswghol6APgZWaff9lnbvN7MHYJOiXsvGPXtjTYJEiC9J2wv9Eg==",
"dev": true,
"license": "MIT",
"engines": {
- "node": ">= 4"
+ "node": ">=8.0"
}
},
- "node_modules/import-fresh": {
- "version": "3.3.1",
- "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz",
- "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==",
+ "node_modules/postcss": {
+ "version": "8.5.6",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz",
+ "integrity": "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==",
"dev": true,
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/postcss/"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/postcss"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
"license": "MIT",
"dependencies": {
- "parent-module": "^1.0.0",
- "resolve-from": "^4.0.0"
+ "nanoid": "^3.3.11",
+ "picocolors": "^1.1.1",
+ "source-map-js": "^1.2.1"
},
"engines": {
- "node": ">=6"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
+ "node": "^10 || ^12 || >=14"
}
},
- "node_modules/imurmurhash": {
- "version": "0.1.4",
- "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
- "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==",
+ "node_modules/postcss-load-config": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-6.0.1.tgz",
+ "integrity": "sha512-oPtTM4oerL+UXmx+93ytZVN82RrlY/wPUV8IeDxFrzIjXOLF1pN+EmKPLbubvKHT2HC20xXsCAH2Z+CKV6Oz/g==",
"dev": true,
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/postcss/"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
"license": "MIT",
+ "dependencies": {
+ "lilconfig": "^3.1.1"
+ },
"engines": {
- "node": ">=0.8.19"
+ "node": ">= 18"
+ },
+ "peerDependencies": {
+ "jiti": ">=1.21.0",
+ "postcss": ">=8.0.9",
+ "tsx": "^4.8.1",
+ "yaml": "^2.4.2"
+ },
+ "peerDependenciesMeta": {
+ "jiti": {
+ "optional": true
+ },
+ "postcss": {
+ "optional": true
+ },
+ "tsx": {
+ "optional": true
+ },
+ "yaml": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/postgres-array": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/postgres-array/-/postgres-array-2.0.0.tgz",
+ "integrity": "sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=4"
}
},
- "node_modules/inherits": {
- "version": "2.0.4",
- "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
- "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
- "license": "ISC"
- },
- "node_modules/ipaddr.js": {
- "version": "1.9.1",
- "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz",
- "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==",
+ "node_modules/postgres-bytea": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/postgres-bytea/-/postgres-bytea-1.0.0.tgz",
+ "integrity": "sha512-xy3pmLuQqRBZBXDULy7KbaitYqLcmxigw14Q5sj8QBVLqEwXfeybIKVWiqAXTlcvdvb0+xkOtDbfQMOf4lST1w==",
"license": "MIT",
"engines": {
- "node": ">= 0.10"
+ "node": ">=0.10.0"
}
},
- "node_modules/is-extglob": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
- "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
- "dev": true,
+ "node_modules/postgres-date": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/postgres-date/-/postgres-date-1.0.7.tgz",
+ "integrity": "sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q==",
"license": "MIT",
"engines": {
"node": ">=0.10.0"
}
},
- "node_modules/is-glob": {
- "version": "4.0.3",
- "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
- "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
- "dev": true,
+ "node_modules/postgres-interval": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/postgres-interval/-/postgres-interval-1.2.0.tgz",
+ "integrity": "sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==",
"license": "MIT",
"dependencies": {
- "is-extglob": "^2.1.1"
+ "xtend": "^4.0.0"
},
"engines": {
"node": ">=0.10.0"
}
},
- "node_modules/is-number": {
- "version": "7.0.0",
- "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
- "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
+ "node_modules/prelude-ls": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz",
+ "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==",
"dev": true,
"license": "MIT",
"engines": {
- "node": ">=0.12.0"
+ "node": ">= 0.8.0"
}
},
- "node_modules/is-promise": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-4.0.0.tgz",
- "integrity": "sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==",
- "license": "MIT"
- },
- "node_modules/isexe": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
- "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
- "license": "ISC"
- },
- "node_modules/js-tokens": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
- "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
- "license": "MIT"
- },
- "node_modules/js-yaml": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
- "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==",
+ "node_modules/prettier": {
+ "version": "3.6.2",
+ "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.6.2.tgz",
+ "integrity": "sha512-I7AIg5boAr5R0FFtJ6rCfD+LFsWHp81dolrFD8S79U9tb8Az2nGrJncnMSnys+bpQJfRUzqs9hnA81OAA3hCuQ==",
+ "dev": true,
"license": "MIT",
- "dependencies": {
- "argparse": "^2.0.1"
- },
"bin": {
- "js-yaml": "bin/js-yaml.js"
+ "prettier": "bin/prettier.cjs"
+ },
+ "engines": {
+ "node": ">=14"
+ },
+ "funding": {
+ "url": "https://github.com/prettier/prettier?sponsor=1"
}
},
- "node_modules/json-buffer": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz",
- "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/json-schema-traverse": {
- "version": "0.4.1",
- "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
- "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/json-stable-stringify-without-jsonify": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz",
- "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/keyv": {
- "version": "4.5.4",
- "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz",
- "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==",
+ "node_modules/prettier-linter-helpers": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz",
+ "integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==",
"dev": true,
"license": "MIT",
"dependencies": {
- "json-buffer": "3.0.1"
+ "fast-diff": "^1.1.2"
+ },
+ "engines": {
+ "node": ">=6.0.0"
}
},
- "node_modules/levn": {
- "version": "0.4.1",
- "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz",
- "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==",
- "dev": true,
+ "node_modules/progress": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz",
+ "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.4.0"
+ }
+ },
+ "node_modules/proxy-addr": {
+ "version": "2.0.7",
+ "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz",
+ "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==",
"license": "MIT",
"dependencies": {
- "prelude-ls": "^1.2.1",
- "type-check": "~0.4.0"
+ "forwarded": "0.2.0",
+ "ipaddr.js": "1.9.1"
},
"engines": {
- "node": ">= 0.8.0"
+ "node": ">= 0.10"
}
},
- "node_modules/locate-path": {
- "version": "6.0.0",
- "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz",
- "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==",
+ "node_modules/proxy-from-env": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
+ "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==",
+ "license": "MIT"
+ },
+ "node_modules/punycode": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz",
+ "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==",
+ "dev": true,
"license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/qs": {
+ "version": "6.14.1",
+ "resolved": "https://registry.npmjs.org/qs/-/qs-6.14.1.tgz",
+ "integrity": "sha512-4EK3+xJl8Ts67nLYNwqw/dsFVnCf+qR7RgXSK9jEEm9unao3njwMDdmsdvoKBKHzxd7tCYz5e5M+SnMjdtXGQQ==",
+ "license": "BSD-3-Clause",
"dependencies": {
- "p-locate": "^5.0.0"
+ "side-channel": "^1.1.0"
},
"engines": {
- "node": ">=10"
+ "node": ">=0.6"
},
"funding": {
- "url": "https://github.com/sponsors/sindresorhus"
+ "url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/lodash.merge": {
- "version": "4.6.2",
- "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz",
- "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==",
+ "node_modules/queue-microtask": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
+ "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==",
"dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
"license": "MIT"
},
- "node_modules/math-intrinsics": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
- "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==",
+ "node_modules/range-parser": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz",
+ "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==",
"license": "MIT",
"engines": {
- "node": ">= 0.4"
+ "node": ">= 0.6"
}
},
- "node_modules/media-typer": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-1.1.0.tgz",
- "integrity": "sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw==",
+ "node_modules/raw-body": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-3.0.2.tgz",
+ "integrity": "sha512-K5zQjDllxWkf7Z5xJdV0/B0WTNqx6vxG70zJE4N0kBs4LovmEYWJzQGxC9bS9RAKu3bgM40lrd5zoLJ12MQ5BA==",
"license": "MIT",
+ "dependencies": {
+ "bytes": "~3.1.2",
+ "http-errors": "~2.0.1",
+ "iconv-lite": "~0.7.0",
+ "unpipe": "~1.0.0"
+ },
"engines": {
- "node": ">= 0.8"
+ "node": ">= 0.10"
}
},
- "node_modules/merge-descriptors": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-2.0.0.tgz",
- "integrity": "sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g==",
+ "node_modules/readdirp": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz",
+ "integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==",
+ "dev": true,
"license": "MIT",
"engines": {
- "node": ">=18"
+ "node": ">= 14.18.0"
},
"funding": {
- "url": "https://github.com/sponsors/sindresorhus"
+ "type": "individual",
+ "url": "https://paulmillr.com/funding/"
}
},
- "node_modules/merge2": {
- "version": "1.4.1",
- "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
- "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==",
- "dev": true,
+ "node_modules/require-from-string": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz",
+ "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==",
"license": "MIT",
"engines": {
- "node": ">= 8"
+ "node": ">=0.10.0"
}
},
- "node_modules/micromatch": {
- "version": "4.0.8",
- "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz",
- "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==",
- "dev": true,
+ "node_modules/require-in-the-middle": {
+ "version": "7.5.2",
+ "resolved": "https://registry.npmjs.org/require-in-the-middle/-/require-in-the-middle-7.5.2.tgz",
+ "integrity": "sha512-gAZ+kLqBdHarXB64XpAe2VCjB7rIRv+mU8tfRWziHRJ5umKsIHN2tLLv6EtMw7WCdP19S0ERVMldNvxYCHnhSQ==",
"license": "MIT",
"dependencies": {
- "braces": "^3.0.3",
- "picomatch": "^2.3.1"
+ "debug": "^4.3.5",
+ "module-details-from-path": "^1.0.3",
+ "resolve": "^1.22.8"
},
"engines": {
- "node": ">=8.6"
- }
- },
- "node_modules/mime-db": {
- "version": "1.54.0",
- "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz",
- "integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.6"
+ "node": ">=8.6.0"
}
},
- "node_modules/mime-types": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.1.tgz",
- "integrity": "sha512-xRc4oEhT6eaBpU1XF7AjpOFD+xQmXNB5OVKwp4tqCuBpHLS/ZbBDrc07mYTDqVMg6PfxUjjNp85O6Cd2Z/5HWA==",
+ "node_modules/resolve": {
+ "version": "1.22.10",
+ "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.10.tgz",
+ "integrity": "sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==",
"license": "MIT",
"dependencies": {
- "mime-db": "^1.54.0"
+ "is-core-module": "^2.16.0",
+ "path-parse": "^1.0.7",
+ "supports-preserve-symlinks-flag": "^1.0.0"
},
- "engines": {
- "node": ">= 0.6"
- }
- },
- "node_modules/minimatch": {
- "version": "3.1.2",
- "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
- "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
- "dev": true,
- "license": "ISC",
- "dependencies": {
- "brace-expansion": "^1.1.7"
+ "bin": {
+ "resolve": "bin/resolve"
},
"engines": {
- "node": "*"
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/ms": {
- "version": "2.1.3",
- "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
- "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
- "license": "MIT"
- },
- "node_modules/natural-compare": {
- "version": "1.4.0",
- "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz",
- "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==",
+ "node_modules/resolve-from": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz",
+ "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==",
"dev": true,
- "license": "MIT"
+ "license": "MIT",
+ "engines": {
+ "node": ">=4"
+ }
},
- "node_modules/negotiator": {
+ "node_modules/resolve-pkg-maps": {
"version": "1.0.0",
- "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-1.0.0.tgz",
- "integrity": "sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==",
+ "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz",
+ "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==",
+ "dev": true,
"license": "MIT",
- "engines": {
- "node": ">= 0.6"
+ "funding": {
+ "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1"
}
},
- "node_modules/object-assign": {
- "version": "4.1.1",
- "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
- "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==",
+ "node_modules/reusify": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz",
+ "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==",
+ "dev": true,
"license": "MIT",
"engines": {
+ "iojs": ">=1.0.0",
"node": ">=0.10.0"
}
},
- "node_modules/object-inspect": {
- "version": "1.13.4",
- "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz",
- "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==",
+ "node_modules/rollup": {
+ "version": "4.46.2",
+ "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.46.2.tgz",
+ "integrity": "sha512-WMmLFI+Boh6xbop+OAGo9cQ3OgX9MIg7xOQjn+pTCwOkk+FNDAeAemXkJ3HzDJrVXleLOFVa1ipuc1AmEx1Dwg==",
+ "dev": true,
"license": "MIT",
- "engines": {
- "node": ">= 0.4"
+ "dependencies": {
+ "@types/estree": "1.0.8"
},
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
+ "bin": {
+ "rollup": "dist/bin/rollup"
+ },
+ "engines": {
+ "node": ">=18.0.0",
+ "npm": ">=8.0.0"
+ },
+ "optionalDependencies": {
+ "@rollup/rollup-android-arm-eabi": "4.46.2",
+ "@rollup/rollup-android-arm64": "4.46.2",
+ "@rollup/rollup-darwin-arm64": "4.46.2",
+ "@rollup/rollup-darwin-x64": "4.46.2",
+ "@rollup/rollup-freebsd-arm64": "4.46.2",
+ "@rollup/rollup-freebsd-x64": "4.46.2",
+ "@rollup/rollup-linux-arm-gnueabihf": "4.46.2",
+ "@rollup/rollup-linux-arm-musleabihf": "4.46.2",
+ "@rollup/rollup-linux-arm64-gnu": "4.46.2",
+ "@rollup/rollup-linux-arm64-musl": "4.46.2",
+ "@rollup/rollup-linux-loongarch64-gnu": "4.46.2",
+ "@rollup/rollup-linux-ppc64-gnu": "4.46.2",
+ "@rollup/rollup-linux-riscv64-gnu": "4.46.2",
+ "@rollup/rollup-linux-riscv64-musl": "4.46.2",
+ "@rollup/rollup-linux-s390x-gnu": "4.46.2",
+ "@rollup/rollup-linux-x64-gnu": "4.46.2",
+ "@rollup/rollup-linux-x64-musl": "4.46.2",
+ "@rollup/rollup-win32-arm64-msvc": "4.46.2",
+ "@rollup/rollup-win32-ia32-msvc": "4.46.2",
+ "@rollup/rollup-win32-x64-msvc": "4.46.2",
+ "fsevents": "~2.3.2"
}
},
- "node_modules/on-finished": {
- "version": "2.4.1",
- "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz",
- "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==",
+ "node_modules/router": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/router/-/router-2.2.0.tgz",
+ "integrity": "sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ==",
"license": "MIT",
"dependencies": {
- "ee-first": "1.1.1"
+ "debug": "^4.4.0",
+ "depd": "^2.0.0",
+ "is-promise": "^4.0.0",
+ "parseurl": "^1.3.3",
+ "path-to-regexp": "^8.0.0"
},
"engines": {
- "node": ">= 0.8"
- }
- },
- "node_modules/once": {
- "version": "1.4.0",
- "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
- "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
- "license": "ISC",
- "dependencies": {
- "wrappy": "1"
+ "node": ">= 18"
}
},
- "node_modules/optionator": {
- "version": "0.9.4",
- "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz",
- "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==",
+ "node_modules/run-parallel": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz",
+ "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==",
"dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
"license": "MIT",
"dependencies": {
- "deep-is": "^0.1.3",
- "fast-levenshtein": "^2.0.6",
- "levn": "^0.4.1",
- "prelude-ls": "^1.2.1",
- "type-check": "^0.4.0",
- "word-wrap": "^1.2.5"
+ "queue-microtask": "^1.2.2"
+ }
+ },
+ "node_modules/safe-buffer": {
+ "version": "5.2.1",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
+ "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "license": "MIT"
+ },
+ "node_modules/safer-buffer": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
+ "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
+ "license": "MIT"
+ },
+ "node_modules/semver": {
+ "version": "7.7.2",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz",
+ "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==",
+ "license": "ISC",
+ "bin": {
+ "semver": "bin/semver.js"
},
"engines": {
- "node": ">= 0.8.0"
+ "node": ">=10"
}
},
- "node_modules/p-limit": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz",
- "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==",
+ "node_modules/send": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/send/-/send-1.2.0.tgz",
+ "integrity": "sha512-uaW0WwXKpL9blXE2o0bRhoL2EGXIrZxQ2ZQ4mgcfoBxdFmQold+qWsD2jLrfZ0trjKL6vOw0j//eAwcALFjKSw==",
"license": "MIT",
"dependencies": {
- "yocto-queue": "^0.1.0"
+ "debug": "^4.3.5",
+ "encodeurl": "^2.0.0",
+ "escape-html": "^1.0.3",
+ "etag": "^1.8.1",
+ "fresh": "^2.0.0",
+ "http-errors": "^2.0.0",
+ "mime-types": "^3.0.1",
+ "ms": "^2.1.3",
+ "on-finished": "^2.4.1",
+ "range-parser": "^1.2.1",
+ "statuses": "^2.0.1"
},
"engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
+ "node": ">= 18"
}
},
- "node_modules/p-locate": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz",
- "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==",
+ "node_modules/serve-static": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-2.2.0.tgz",
+ "integrity": "sha512-61g9pCh0Vnh7IutZjtLGGpTA355+OPn2TyDv/6ivP2h/AdAVX9azsoxmg2/M6nZeQZNYBEwIcsne1mJd9oQItQ==",
"license": "MIT",
"dependencies": {
- "p-limit": "^3.0.2"
+ "encodeurl": "^2.0.0",
+ "escape-html": "^1.0.3",
+ "parseurl": "^1.3.3",
+ "send": "^1.2.0"
},
"engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
+ "node": ">= 18"
}
},
- "node_modules/parent-module": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
- "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==",
- "dev": true,
+ "node_modules/setprototypeof": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz",
+ "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==",
+ "license": "ISC"
+ },
+ "node_modules/shebang-command": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
+ "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
"license": "MIT",
"dependencies": {
- "callsites": "^3.0.0"
+ "shebang-regex": "^3.0.0"
},
"engines": {
- "node": ">=6"
+ "node": ">=8"
}
},
- "node_modules/parseurl": {
- "version": "1.3.3",
- "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
- "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==",
+ "node_modules/shebang-regex": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
+ "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
"license": "MIT",
"engines": {
- "node": ">= 0.8"
+ "node": ">=8"
}
},
- "node_modules/path-exists": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
- "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
+ "node_modules/shimmer": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/shimmer/-/shimmer-1.2.1.tgz",
+ "integrity": "sha512-sQTKC1Re/rM6XyFM6fIAGHRPVGvyXfgzIDvzoq608vM+jeyVD0Tu1E6Np0Kc2zAIFWIj963V2800iF/9LPieQw==",
+ "license": "BSD-2-Clause"
+ },
+ "node_modules/side-channel": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz",
+ "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==",
"license": "MIT",
+ "dependencies": {
+ "es-errors": "^1.3.0",
+ "object-inspect": "^1.13.3",
+ "side-channel-list": "^1.0.0",
+ "side-channel-map": "^1.0.1",
+ "side-channel-weakmap": "^1.0.2"
+ },
"engines": {
- "node": ">=8"
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/path-key": {
- "version": "3.1.1",
- "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
- "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
+ "node_modules/side-channel-list": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz",
+ "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==",
"license": "MIT",
+ "dependencies": {
+ "es-errors": "^1.3.0",
+ "object-inspect": "^1.13.3"
+ },
"engines": {
- "node": ">=8"
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/path-to-regexp": {
- "version": "8.2.0",
- "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.2.0.tgz",
- "integrity": "sha512-TdrF7fW9Rphjq4RjrW0Kp2AW0Ahwu9sRGTkS6bvDi0SCwZlEZYmcfDbEsTz8RVk0EHIS/Vd1bv3JhG+1xZuAyQ==",
+ "node_modules/side-channel-map": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz",
+ "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==",
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.2",
+ "es-errors": "^1.3.0",
+ "get-intrinsic": "^1.2.5",
+ "object-inspect": "^1.13.3"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/side-channel-weakmap": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz",
+ "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==",
"license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.2",
+ "es-errors": "^1.3.0",
+ "get-intrinsic": "^1.2.5",
+ "object-inspect": "^1.13.3",
+ "side-channel-map": "^1.0.1"
+ },
"engines": {
- "node": ">=16"
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/picocolors": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
- "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==",
+ "node_modules/siginfo": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/siginfo/-/siginfo-2.0.0.tgz",
+ "integrity": "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==",
+ "dev": true,
"license": "ISC"
},
- "node_modules/picomatch": {
- "version": "2.3.1",
- "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
- "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
+ "node_modules/signal-exit": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz",
+ "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==",
"dev": true,
- "license": "MIT",
+ "license": "ISC",
"engines": {
- "node": ">=8.6"
+ "node": ">=14"
},
"funding": {
- "url": "https://github.com/sponsors/jonschlinkert"
+ "url": "https://github.com/sponsors/isaacs"
}
},
- "node_modules/pkce-challenge": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/pkce-challenge/-/pkce-challenge-5.0.0.tgz",
- "integrity": "sha512-ueGLflrrnvwB3xuo/uGob5pd5FN7l0MsLf0Z87o/UQmRtwjvfylfc9MurIxRAWywCYTgrvpXBcqjV4OfCYGCIQ==",
+ "node_modules/simple-plist": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/simple-plist/-/simple-plist-1.3.1.tgz",
+ "integrity": "sha512-iMSw5i0XseMnrhtIzRb7XpQEXepa9xhWxGUojHBL43SIpQuDQkh3Wpy67ZbDzZVr6EKxvwVChnVpdl8hEVLDiw==",
+ "dev": true,
"license": "MIT",
- "engines": {
- "node": ">=16.20.0"
+ "dependencies": {
+ "bplist-creator": "0.1.0",
+ "bplist-parser": "0.3.1",
+ "plist": "^3.0.5"
}
},
- "node_modules/prelude-ls": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz",
- "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==",
+ "node_modules/sirv": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/sirv/-/sirv-3.0.1.tgz",
+ "integrity": "sha512-FoqMu0NCGBLCcAkS1qA+XJIQTR6/JHfQXl+uGteNCQ76T91DMUjPa9xfmeqMY3z80nLSg9yQmNjK0Px6RWsH/A==",
"dev": true,
"license": "MIT",
+ "dependencies": {
+ "@polka/url": "^1.0.0-next.24",
+ "mrmime": "^2.0.0",
+ "totalist": "^3.0.0"
+ },
"engines": {
- "node": ">= 0.8.0"
+ "node": ">=18"
}
},
- "node_modules/prettier": {
- "version": "3.5.3",
- "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.5.3.tgz",
- "integrity": "sha512-QQtaxnoDJeAkDvDKWCLiwIXkTgRhwYDEQCghU9Z6q03iyek/rxRh/2lC3HB7P8sWT2xC/y5JDctPLBIGzHKbhw==",
+ "node_modules/source-map": {
+ "version": "0.8.0-beta.0",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.8.0-beta.0.tgz",
+ "integrity": "sha512-2ymg6oRBpebeZi9UUNsgQ89bhx01TcTkmNTGnNO88imTmbSgy4nfujrgVEFKWpMTEGA11EDkTt7mqObTPdigIA==",
+ "deprecated": "The work that was done in this beta branch won't be included in future versions",
"dev": true,
- "license": "MIT",
- "bin": {
- "prettier": "bin/prettier.cjs"
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "whatwg-url": "^7.0.0"
},
"engines": {
- "node": ">=14"
- },
- "funding": {
- "url": "https://github.com/prettier/prettier?sponsor=1"
+ "node": ">= 8"
}
},
- "node_modules/prettier-linter-helpers": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz",
- "integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==",
+ "node_modules/source-map-js": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz",
+ "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==",
"dev": true,
- "license": "MIT",
- "dependencies": {
- "fast-diff": "^1.1.2"
- },
+ "license": "BSD-3-Clause",
"engines": {
- "node": ">=6.0.0"
+ "node": ">=0.10.0"
}
},
- "node_modules/proxy-addr": {
- "version": "2.0.7",
- "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz",
- "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==",
+ "node_modules/source-map/node_modules/tr46": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/tr46/-/tr46-1.0.1.tgz",
+ "integrity": "sha512-dTpowEjclQ7Kgx5SdBkqRzVhERQXov8/l9Ft9dVM9fmg0W0KQSVaXX9T4i6twCPNtYiZM53lpSSUAwJbFPOHxA==",
+ "dev": true,
"license": "MIT",
"dependencies": {
- "forwarded": "0.2.0",
- "ipaddr.js": "1.9.1"
- },
- "engines": {
- "node": ">= 0.10"
+ "punycode": "^2.1.0"
}
},
- "node_modules/punycode": {
- "version": "2.3.1",
- "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz",
- "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==",
+ "node_modules/source-map/node_modules/webidl-conversions": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-4.0.2.tgz",
+ "integrity": "sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==",
+ "dev": true,
+ "license": "BSD-2-Clause"
+ },
+ "node_modules/source-map/node_modules/whatwg-url": {
+ "version": "7.1.0",
+ "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-7.1.0.tgz",
+ "integrity": "sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg==",
"dev": true,
"license": "MIT",
- "engines": {
- "node": ">=6"
+ "dependencies": {
+ "lodash.sortby": "^4.7.0",
+ "tr46": "^1.0.1",
+ "webidl-conversions": "^4.0.2"
}
},
- "node_modules/qs": {
- "version": "6.14.0",
- "resolved": "https://registry.npmjs.org/qs/-/qs-6.14.0.tgz",
- "integrity": "sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w==",
- "license": "BSD-3-Clause",
- "dependencies": {
- "side-channel": "^1.1.0"
- },
+ "node_modules/stackback": {
+ "version": "0.0.2",
+ "resolved": "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz",
+ "integrity": "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/statuses": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.2.tgz",
+ "integrity": "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==",
+ "license": "MIT",
"engines": {
- "node": ">=0.6"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
+ "node": ">= 0.8"
}
},
- "node_modules/queue-microtask": {
- "version": "1.2.3",
- "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
- "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==",
+ "node_modules/std-env": {
+ "version": "3.9.0",
+ "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.9.0.tgz",
+ "integrity": "sha512-UGvjygr6F6tpH7o2qyqR6QYpwraIjKSdtzyBdyytFOHmPZY917kwdwLG0RbOjWOnKmnm3PeHjaoLLMie7kPLQw==",
"dev": true,
- "funding": [
- {
- "type": "github",
- "url": "https://github.com/sponsors/feross"
- },
- {
- "type": "patreon",
- "url": "https://www.patreon.com/feross"
- },
- {
- "type": "consulting",
- "url": "https://feross.org/support"
- }
- ],
"license": "MIT"
},
- "node_modules/range-parser": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz",
- "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==",
- "license": "MIT",
+ "node_modules/stream-buffers": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/stream-buffers/-/stream-buffers-2.2.0.tgz",
+ "integrity": "sha512-uyQK/mx5QjHun80FLJTfaWE7JtwfRMKBLkMne6udYOmvH0CawotVa7TfgYHzAnpphn4+TweIx1QKMnRIbipmUg==",
+ "dev": true,
+ "license": "Unlicense",
"engines": {
- "node": ">= 0.6"
+ "node": ">= 0.10.0"
}
},
- "node_modules/raw-body": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-3.0.0.tgz",
- "integrity": "sha512-RmkhL8CAyCRPXCE28MMH0z2PNWQBNk2Q09ZdxM9IOOXwxwZbN+qbWaatPkdkWIKL2ZVDImrN/pK5HTRz2PcS4g==",
+ "node_modules/string-width": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz",
+ "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==",
+ "dev": true,
"license": "MIT",
"dependencies": {
- "bytes": "3.1.2",
- "http-errors": "2.0.0",
- "iconv-lite": "0.6.3",
- "unpipe": "1.0.0"
+ "eastasianwidth": "^0.2.0",
+ "emoji-regex": "^9.2.2",
+ "strip-ansi": "^7.0.1"
},
"engines": {
- "node": ">= 0.8"
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
}
},
- "node_modules/resolve-from": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz",
- "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==",
+ "node_modules/string-width-cjs": {
+ "name": "string-width",
+ "version": "4.2.3",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
+ "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
"dev": true,
"license": "MIT",
+ "dependencies": {
+ "emoji-regex": "^8.0.0",
+ "is-fullwidth-code-point": "^3.0.0",
+ "strip-ansi": "^6.0.1"
+ },
"engines": {
- "node": ">=4"
+ "node": ">=8"
}
},
- "node_modules/reusify": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz",
- "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==",
+ "node_modules/string-width-cjs/node_modules/ansi-regex": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
+ "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
"dev": true,
"license": "MIT",
"engines": {
- "iojs": ">=1.0.0",
- "node": ">=0.10.0"
+ "node": ">=8"
}
},
- "node_modules/router": {
- "version": "2.2.0",
- "resolved": "https://registry.npmjs.org/router/-/router-2.2.0.tgz",
- "integrity": "sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ==",
+ "node_modules/string-width-cjs/node_modules/emoji-regex": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
+ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/string-width-cjs/node_modules/strip-ansi": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
+ "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
+ "dev": true,
"license": "MIT",
"dependencies": {
- "debug": "^4.4.0",
- "depd": "^2.0.0",
- "is-promise": "^4.0.0",
- "parseurl": "^1.3.3",
- "path-to-regexp": "^8.0.0"
+ "ansi-regex": "^5.0.1"
},
"engines": {
- "node": ">= 18"
+ "node": ">=8"
}
},
- "node_modules/run-parallel": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz",
- "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==",
+ "node_modules/strip-ansi": {
+ "version": "7.1.0",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz",
+ "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==",
"dev": true,
- "funding": [
- {
- "type": "github",
- "url": "https://github.com/sponsors/feross"
- },
- {
- "type": "patreon",
- "url": "https://www.patreon.com/feross"
- },
- {
- "type": "consulting",
- "url": "https://feross.org/support"
- }
- ],
"license": "MIT",
"dependencies": {
- "queue-microtask": "^1.2.2"
+ "ansi-regex": "^6.0.1"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/strip-ansi?sponsor=1"
}
},
- "node_modules/safe-buffer": {
- "version": "5.2.1",
- "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
- "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
- "funding": [
- {
- "type": "github",
- "url": "https://github.com/sponsors/feross"
- },
- {
- "type": "patreon",
- "url": "https://www.patreon.com/feross"
- },
- {
- "type": "consulting",
- "url": "https://feross.org/support"
- }
- ],
- "license": "MIT"
- },
- "node_modules/safer-buffer": {
- "version": "2.1.2",
- "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
- "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
- "license": "MIT"
- },
- "node_modules/semver": {
- "version": "7.7.1",
- "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.1.tgz",
- "integrity": "sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==",
+ "node_modules/strip-ansi-cjs": {
+ "name": "strip-ansi",
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
+ "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
"dev": true,
- "license": "ISC",
- "bin": {
- "semver": "bin/semver.js"
+ "license": "MIT",
+ "dependencies": {
+ "ansi-regex": "^5.0.1"
},
"engines": {
- "node": ">=10"
+ "node": ">=8"
}
},
- "node_modules/send": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/send/-/send-1.2.0.tgz",
- "integrity": "sha512-uaW0WwXKpL9blXE2o0bRhoL2EGXIrZxQ2ZQ4mgcfoBxdFmQold+qWsD2jLrfZ0trjKL6vOw0j//eAwcALFjKSw==",
+ "node_modules/strip-ansi-cjs/node_modules/ansi-regex": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
+ "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/strip-json-comments": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz",
+ "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/strip-literal": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/strip-literal/-/strip-literal-3.0.0.tgz",
+ "integrity": "sha512-TcccoMhJOM3OebGhSBEmp3UZ2SfDMZUEBdRA/9ynfLi8yYajyWX3JiXArcJt4Umh4vISpspkQIY8ZZoCqjbviA==",
+ "dev": true,
"license": "MIT",
"dependencies": {
- "debug": "^4.3.5",
- "encodeurl": "^2.0.0",
- "escape-html": "^1.0.3",
- "etag": "^1.8.1",
- "fresh": "^2.0.0",
- "http-errors": "^2.0.0",
- "mime-types": "^3.0.1",
- "ms": "^2.1.3",
- "on-finished": "^2.4.1",
- "range-parser": "^1.2.1",
- "statuses": "^2.0.1"
+ "js-tokens": "^9.0.1"
},
- "engines": {
- "node": ">= 18"
+ "funding": {
+ "url": "https://github.com/sponsors/antfu"
}
},
- "node_modules/serve-static": {
- "version": "2.2.0",
- "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-2.2.0.tgz",
- "integrity": "sha512-61g9pCh0Vnh7IutZjtLGGpTA355+OPn2TyDv/6ivP2h/AdAVX9azsoxmg2/M6nZeQZNYBEwIcsne1mJd9oQItQ==",
+ "node_modules/sucrase": {
+ "version": "3.35.0",
+ "resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.35.0.tgz",
+ "integrity": "sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA==",
+ "dev": true,
"license": "MIT",
"dependencies": {
- "encodeurl": "^2.0.0",
- "escape-html": "^1.0.3",
- "parseurl": "^1.3.3",
- "send": "^1.2.0"
+ "@jridgewell/gen-mapping": "^0.3.2",
+ "commander": "^4.0.0",
+ "glob": "^10.3.10",
+ "lines-and-columns": "^1.1.6",
+ "mz": "^2.7.0",
+ "pirates": "^4.0.1",
+ "ts-interface-checker": "^0.1.9"
+ },
+ "bin": {
+ "sucrase": "bin/sucrase",
+ "sucrase-node": "bin/sucrase-node"
},
"engines": {
- "node": ">= 18"
+ "node": ">=16 || 14 >=14.17"
}
},
- "node_modules/setprototypeof": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz",
- "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==",
- "license": "ISC"
- },
- "node_modules/shebang-command": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
- "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
+ "node_modules/supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "dev": true,
"license": "MIT",
"dependencies": {
- "shebang-regex": "^3.0.0"
+ "has-flag": "^4.0.0"
},
"engines": {
"node": ">=8"
}
},
- "node_modules/shebang-regex": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
- "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
+ "node_modules/supports-preserve-symlinks-flag": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz",
+ "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==",
"license": "MIT",
"engines": {
- "node": ">=8"
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/side-channel": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz",
- "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==",
+ "node_modules/synckit": {
+ "version": "0.11.11",
+ "resolved": "https://registry.npmjs.org/synckit/-/synckit-0.11.11.tgz",
+ "integrity": "sha512-MeQTA1r0litLUf0Rp/iisCaL8761lKAZHaimlbGK4j0HysC4PLfqygQj9srcs0m2RdtDYnF8UuYyKpbjHYp7Jw==",
+ "dev": true,
"license": "MIT",
"dependencies": {
- "es-errors": "^1.3.0",
- "object-inspect": "^1.13.3",
- "side-channel-list": "^1.0.0",
- "side-channel-map": "^1.0.1",
- "side-channel-weakmap": "^1.0.2"
+ "@pkgr/core": "^0.2.9"
},
"engines": {
- "node": ">= 0.4"
+ "node": "^14.18.0 || >=16.0.0"
},
"funding": {
- "url": "https://github.com/sponsors/ljharb"
+ "url": "https://opencollective.com/synckit"
}
},
- "node_modules/side-channel-list": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz",
- "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==",
+ "node_modules/test-exclude": {
+ "version": "7.0.1",
+ "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-7.0.1.tgz",
+ "integrity": "sha512-pFYqmTw68LXVjeWJMST4+borgQP2AyMNbg1BpZh9LbyhUeNkeaPF9gzfPGUAnSMV3qPYdWUwDIjjCLiSDOl7vg==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "@istanbuljs/schema": "^0.1.2",
+ "glob": "^10.4.1",
+ "minimatch": "^9.0.4"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/test-exclude/node_modules/brace-expansion": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz",
+ "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==",
+ "dev": true,
"license": "MIT",
"dependencies": {
- "es-errors": "^1.3.0",
- "object-inspect": "^1.13.3"
+ "balanced-match": "^1.0.0"
+ }
+ },
+ "node_modules/test-exclude/node_modules/minimatch": {
+ "version": "9.0.5",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz",
+ "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "brace-expansion": "^2.0.1"
},
"engines": {
- "node": ">= 0.4"
+ "node": ">=16 || 14 >=14.17"
},
"funding": {
- "url": "https://github.com/sponsors/ljharb"
+ "url": "https://github.com/sponsors/isaacs"
}
},
- "node_modules/side-channel-map": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz",
- "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==",
+ "node_modules/thenify": {
+ "version": "3.3.1",
+ "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz",
+ "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==",
+ "dev": true,
"license": "MIT",
"dependencies": {
- "call-bound": "^1.0.2",
- "es-errors": "^1.3.0",
- "get-intrinsic": "^1.2.5",
- "object-inspect": "^1.13.3"
+ "any-promise": "^1.0.0"
+ }
+ },
+ "node_modules/thenify-all": {
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz",
+ "integrity": "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "thenify": ">= 3.1.0 < 4"
},
"engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
+ "node": ">=0.8"
}
},
- "node_modules/side-channel-weakmap": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz",
- "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==",
+ "node_modules/tinybench": {
+ "version": "2.9.0",
+ "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.9.0.tgz",
+ "integrity": "sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/tinyexec": {
+ "version": "0.3.2",
+ "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-0.3.2.tgz",
+ "integrity": "sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/tinyglobby": {
+ "version": "0.2.15",
+ "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz",
+ "integrity": "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==",
+ "dev": true,
"license": "MIT",
"dependencies": {
- "call-bound": "^1.0.2",
- "es-errors": "^1.3.0",
- "get-intrinsic": "^1.2.5",
- "object-inspect": "^1.13.3",
- "side-channel-map": "^1.0.1"
+ "fdir": "^6.5.0",
+ "picomatch": "^4.0.3"
},
"engines": {
- "node": ">= 0.4"
+ "node": ">=12.0.0"
},
"funding": {
- "url": "https://github.com/sponsors/ljharb"
+ "url": "https://github.com/sponsors/SuperchupuDev"
}
},
- "node_modules/statuses": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz",
- "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==",
+ "node_modules/tinyglobby/node_modules/fdir": {
+ "version": "6.5.0",
+ "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz",
+ "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==",
+ "dev": true,
"license": "MIT",
"engines": {
- "node": ">= 0.8"
+ "node": ">=12.0.0"
+ },
+ "peerDependencies": {
+ "picomatch": "^3 || ^4"
+ },
+ "peerDependenciesMeta": {
+ "picomatch": {
+ "optional": true
+ }
}
},
- "node_modules/strip-json-comments": {
- "version": "3.1.1",
- "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz",
- "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==",
+ "node_modules/tinyglobby/node_modules/picomatch": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz",
+ "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==",
"dev": true,
"license": "MIT",
"engines": {
- "node": ">=8"
+ "node": ">=12"
},
"funding": {
- "url": "https://github.com/sponsors/sindresorhus"
+ "url": "https://github.com/sponsors/jonschlinkert"
}
},
- "node_modules/supports-color": {
- "version": "7.2.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
- "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "node_modules/tinypool": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-1.1.1.tgz",
+ "integrity": "sha512-Zba82s87IFq9A9XmjiX5uZA/ARWDrB03OHlq+Vw1fSdt0I+4/Kutwy8BP4Y/y/aORMo61FQ0vIb5j44vSo5Pkg==",
+ "dev": true,
"license": "MIT",
- "dependencies": {
- "has-flag": "^4.0.0"
- },
"engines": {
- "node": ">=8"
+ "node": "^18.0.0 || >=20.0.0"
}
},
- "node_modules/synckit": {
- "version": "0.11.3",
- "resolved": "https://registry.npmjs.org/synckit/-/synckit-0.11.3.tgz",
- "integrity": "sha512-szhWDqNNI9etJUvbZ1/cx1StnZx8yMmFxme48SwR4dty4ioSY50KEZlpv0qAfgc1fpRzuh9hBXEzoCpJ779dLg==",
+ "node_modules/tinyrainbow": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/tinyrainbow/-/tinyrainbow-2.0.0.tgz",
+ "integrity": "sha512-op4nsTR47R6p0vMUUoYl/a+ljLFVtlfaXkLQmqfLR1qHma1h/ysYk4hEXZ880bf2CYgTskvTa/e196Vd5dDQXw==",
"dev": true,
"license": "MIT",
- "dependencies": {
- "@pkgr/core": "^0.2.1",
- "tslib": "^2.8.1"
- },
"engines": {
- "node": "^14.18.0 || >=16.0.0"
- },
- "funding": {
- "url": "https://opencollective.com/synckit"
+ "node": ">=14.0.0"
+ }
+ },
+ "node_modules/tinyspy": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-4.0.3.tgz",
+ "integrity": "sha512-t2T/WLB2WRgZ9EpE4jgPJ9w+i66UZfDc8wHh0xrwiRNN+UwH98GIJkTeZqX9rg0i0ptwzqW+uYeIF0T4F8LR7A==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=14.0.0"
}
},
"node_modules/to-regex-range": {
@@ -2578,34 +6335,202 @@
"node": ">=8.0"
}
},
- "node_modules/toidentifier": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz",
- "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==",
+ "node_modules/toidentifier": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz",
+ "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.6"
+ }
+ },
+ "node_modules/totalist": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/totalist/-/totalist-3.0.1.tgz",
+ "integrity": "sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/tr46": {
+ "version": "0.0.3",
+ "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
+ "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==",
+ "license": "MIT"
+ },
+ "node_modules/tree-kill": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz",
+ "integrity": "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "tree-kill": "cli.js"
+ }
+ },
+ "node_modules/ts-api-utils": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.1.0.tgz",
+ "integrity": "sha512-CUgTZL1irw8u29bzrOD/nH85jqyc74D6SshFgujOIA7osm2Rz7dYH77agkx7H4FBNxDq7Cjf+IjaX/8zwFW+ZQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=18.12"
+ },
+ "peerDependencies": {
+ "typescript": ">=4.8.4"
+ }
+ },
+ "node_modules/ts-interface-checker": {
+ "version": "0.1.13",
+ "resolved": "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz",
+ "integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==",
+ "dev": true,
+ "license": "Apache-2.0"
+ },
+ "node_modules/ts-node": {
+ "version": "10.9.2",
+ "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz",
+ "integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@cspotcode/source-map-support": "^0.8.0",
+ "@tsconfig/node10": "^1.0.7",
+ "@tsconfig/node12": "^1.0.7",
+ "@tsconfig/node14": "^1.0.0",
+ "@tsconfig/node16": "^1.0.2",
+ "acorn": "^8.4.1",
+ "acorn-walk": "^8.1.1",
+ "arg": "^4.1.0",
+ "create-require": "^1.1.0",
+ "diff": "^4.0.1",
+ "make-error": "^1.1.1",
+ "v8-compile-cache-lib": "^3.0.1",
+ "yn": "3.1.1"
+ },
+ "bin": {
+ "ts-node": "dist/bin.js",
+ "ts-node-cwd": "dist/bin-cwd.js",
+ "ts-node-esm": "dist/bin-esm.js",
+ "ts-node-script": "dist/bin-script.js",
+ "ts-node-transpile-only": "dist/bin-transpile.js",
+ "ts-script": "dist/bin-script-deprecated.js"
+ },
+ "peerDependencies": {
+ "@swc/core": ">=1.2.50",
+ "@swc/wasm": ">=1.2.50",
+ "@types/node": "*",
+ "typescript": ">=2.7"
+ },
+ "peerDependenciesMeta": {
+ "@swc/core": {
+ "optional": true
+ },
+ "@swc/wasm": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/tsup": {
+ "version": "8.5.0",
+ "resolved": "https://registry.npmjs.org/tsup/-/tsup-8.5.0.tgz",
+ "integrity": "sha512-VmBp77lWNQq6PfuMqCHD3xWl22vEoWsKajkF8t+yMBawlUS8JzEI+vOVMeuNZIuMML8qXRizFKi9oD5glKQVcQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "bundle-require": "^5.1.0",
+ "cac": "^6.7.14",
+ "chokidar": "^4.0.3",
+ "consola": "^3.4.0",
+ "debug": "^4.4.0",
+ "esbuild": "^0.25.0",
+ "fix-dts-default-cjs-exports": "^1.0.0",
+ "joycon": "^3.1.1",
+ "picocolors": "^1.1.1",
+ "postcss-load-config": "^6.0.1",
+ "resolve-from": "^5.0.0",
+ "rollup": "^4.34.8",
+ "source-map": "0.8.0-beta.0",
+ "sucrase": "^3.35.0",
+ "tinyexec": "^0.3.2",
+ "tinyglobby": "^0.2.11",
+ "tree-kill": "^1.2.2"
+ },
+ "bin": {
+ "tsup": "dist/cli-default.js",
+ "tsup-node": "dist/cli-node.js"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "peerDependencies": {
+ "@microsoft/api-extractor": "^7.36.0",
+ "@swc/core": "^1",
+ "postcss": "^8.4.12",
+ "typescript": ">=4.5.0"
+ },
+ "peerDependenciesMeta": {
+ "@microsoft/api-extractor": {
+ "optional": true
+ },
+ "@swc/core": {
+ "optional": true
+ },
+ "postcss": {
+ "optional": true
+ },
+ "typescript": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/tsup/node_modules/resolve-from": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz",
+ "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==",
+ "dev": true,
"license": "MIT",
"engines": {
- "node": ">=0.6"
+ "node": ">=8"
}
},
- "node_modules/ts-api-utils": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.1.0.tgz",
- "integrity": "sha512-CUgTZL1irw8u29bzrOD/nH85jqyc74D6SshFgujOIA7osm2Rz7dYH77agkx7H4FBNxDq7Cjf+IjaX/8zwFW+ZQ==",
+ "node_modules/tsx": {
+ "version": "4.20.4",
+ "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.20.4.tgz",
+ "integrity": "sha512-yyxBKfORQ7LuRt/BQKBXrpcq59ZvSW0XxwfjAt3w2/8PmdxaFzijtMhTawprSHhpzeM5BgU2hXHG3lklIERZXg==",
"dev": true,
"license": "MIT",
+ "dependencies": {
+ "esbuild": "~0.25.0",
+ "get-tsconfig": "^4.7.5"
+ },
+ "bin": {
+ "tsx": "dist/cli.mjs"
+ },
"engines": {
- "node": ">=18.12"
+ "node": ">=18.0.0"
},
- "peerDependencies": {
- "typescript": ">=4.8.4"
+ "optionalDependencies": {
+ "fsevents": "~2.3.3"
}
},
- "node_modules/tslib": {
- "version": "2.8.1",
- "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
- "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==",
+ "node_modules/tsx/node_modules/fsevents": {
+ "version": "2.3.3",
+ "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
+ "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
"dev": true,
- "license": "0BSD"
+ "hasInstallScript": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
+ }
},
"node_modules/type-check": {
"version": "0.4.0",
@@ -2635,9 +6560,9 @@
}
},
"node_modules/typescript": {
- "version": "5.8.3",
- "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.3.tgz",
- "integrity": "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==",
+ "version": "5.9.2",
+ "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.2.tgz",
+ "integrity": "sha512-CWBzXQrc/qOkhidw1OzBTQuYRbfyxDXJMVJ1XNwUHGROVmuaeiEm3OslpZ1RV96d7SKKjZKrSJu3+t/xlw3R9A==",
"dev": true,
"license": "Apache-2.0",
"bin": {
@@ -2649,15 +6574,16 @@
}
},
"node_modules/typescript-eslint": {
- "version": "8.29.1",
- "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.29.1.tgz",
- "integrity": "sha512-f8cDkvndhbQMPcysk6CUSGBWV+g1utqdn71P5YKwMumVMOG/5k7cHq0KyG4O52nB0oKS4aN2Tp5+wB4APJGC+w==",
+ "version": "8.39.0",
+ "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.39.0.tgz",
+ "integrity": "sha512-lH8FvtdtzcHJCkMOKnN73LIn6SLTpoojgJqDAxPm1jCR14eWSGPX8ul/gggBdPMk/d5+u9V854vTYQ8T5jF/1Q==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@typescript-eslint/eslint-plugin": "8.29.1",
- "@typescript-eslint/parser": "8.29.1",
- "@typescript-eslint/utils": "8.29.1"
+ "@typescript-eslint/eslint-plugin": "8.39.0",
+ "@typescript-eslint/parser": "8.39.0",
+ "@typescript-eslint/typescript-estree": "8.39.0",
+ "@typescript-eslint/utils": "8.39.0"
},
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
@@ -2668,14 +6594,20 @@
},
"peerDependencies": {
"eslint": "^8.57.0 || ^9.0.0",
- "typescript": ">=4.8.4 <5.9.0"
+ "typescript": ">=4.8.4 <6.0.0"
}
},
+ "node_modules/ufo": {
+ "version": "1.6.1",
+ "resolved": "https://registry.npmjs.org/ufo/-/ufo-1.6.1.tgz",
+ "integrity": "sha512-9a4/uxlTWJ4+a5i0ooc1rU7C7YOw3wT+UGqdeNNHWnOF9qcMBgLRS+4IYUqbczewFx4mLEig6gawh7X6mFlEkA==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/undici-types": {
"version": "6.21.0",
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz",
"integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==",
- "dev": true,
"license": "MIT"
},
"node_modules/unpipe": {
@@ -2710,6 +6642,13 @@
"uuid": "dist/esm/bin/uuid"
}
},
+ "node_modules/v8-compile-cache-lib": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz",
+ "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/vary": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
@@ -2719,6 +6658,252 @@
"node": ">= 0.8"
}
},
+ "node_modules/vite": {
+ "version": "7.1.11",
+ "resolved": "https://registry.npmjs.org/vite/-/vite-7.1.11.tgz",
+ "integrity": "sha512-uzcxnSDVjAopEUjljkWh8EIrg6tlzrjFUfMcR1EVsRDGwf/ccef0qQPRyOrROwhrTDaApueq+ja+KLPlzR/zdg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "esbuild": "^0.25.0",
+ "fdir": "^6.5.0",
+ "picomatch": "^4.0.3",
+ "postcss": "^8.5.6",
+ "rollup": "^4.43.0",
+ "tinyglobby": "^0.2.15"
+ },
+ "bin": {
+ "vite": "bin/vite.js"
+ },
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ },
+ "funding": {
+ "url": "https://github.com/vitejs/vite?sponsor=1"
+ },
+ "optionalDependencies": {
+ "fsevents": "~2.3.3"
+ },
+ "peerDependencies": {
+ "@types/node": "^20.19.0 || >=22.12.0",
+ "jiti": ">=1.21.0",
+ "less": "^4.0.0",
+ "lightningcss": "^1.21.0",
+ "sass": "^1.70.0",
+ "sass-embedded": "^1.70.0",
+ "stylus": ">=0.54.8",
+ "sugarss": "^5.0.0",
+ "terser": "^5.16.0",
+ "tsx": "^4.8.1",
+ "yaml": "^2.4.2"
+ },
+ "peerDependenciesMeta": {
+ "@types/node": {
+ "optional": true
+ },
+ "jiti": {
+ "optional": true
+ },
+ "less": {
+ "optional": true
+ },
+ "lightningcss": {
+ "optional": true
+ },
+ "sass": {
+ "optional": true
+ },
+ "sass-embedded": {
+ "optional": true
+ },
+ "stylus": {
+ "optional": true
+ },
+ "sugarss": {
+ "optional": true
+ },
+ "terser": {
+ "optional": true
+ },
+ "tsx": {
+ "optional": true
+ },
+ "yaml": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/vite-node": {
+ "version": "3.2.4",
+ "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-3.2.4.tgz",
+ "integrity": "sha512-EbKSKh+bh1E1IFxeO0pg1n4dvoOTt0UDiXMd/qn++r98+jPO1xtJilvXldeuQ8giIB5IkpjCgMleHMNEsGH6pg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "cac": "^6.7.14",
+ "debug": "^4.4.1",
+ "es-module-lexer": "^1.7.0",
+ "pathe": "^2.0.3",
+ "vite": "^5.0.0 || ^6.0.0 || ^7.0.0-0"
+ },
+ "bin": {
+ "vite-node": "vite-node.mjs"
+ },
+ "engines": {
+ "node": "^18.0.0 || ^20.0.0 || >=22.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/vitest"
+ }
+ },
+ "node_modules/vite/node_modules/fdir": {
+ "version": "6.5.0",
+ "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz",
+ "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12.0.0"
+ },
+ "peerDependencies": {
+ "picomatch": "^3 || ^4"
+ },
+ "peerDependenciesMeta": {
+ "picomatch": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/vite/node_modules/fsevents": {
+ "version": "2.3.3",
+ "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
+ "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
+ "dev": true,
+ "hasInstallScript": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
+ }
+ },
+ "node_modules/vite/node_modules/picomatch": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz",
+ "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/jonschlinkert"
+ }
+ },
+ "node_modules/vitest": {
+ "version": "3.2.4",
+ "resolved": "https://registry.npmjs.org/vitest/-/vitest-3.2.4.tgz",
+ "integrity": "sha512-LUCP5ev3GURDysTWiP47wRRUpLKMOfPh+yKTx3kVIEiu5KOMeqzpnYNsKyOoVrULivR8tLcks4+lga33Whn90A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/chai": "^5.2.2",
+ "@vitest/expect": "3.2.4",
+ "@vitest/mocker": "3.2.4",
+ "@vitest/pretty-format": "^3.2.4",
+ "@vitest/runner": "3.2.4",
+ "@vitest/snapshot": "3.2.4",
+ "@vitest/spy": "3.2.4",
+ "@vitest/utils": "3.2.4",
+ "chai": "^5.2.0",
+ "debug": "^4.4.1",
+ "expect-type": "^1.2.1",
+ "magic-string": "^0.30.17",
+ "pathe": "^2.0.3",
+ "picomatch": "^4.0.2",
+ "std-env": "^3.9.0",
+ "tinybench": "^2.9.0",
+ "tinyexec": "^0.3.2",
+ "tinyglobby": "^0.2.14",
+ "tinypool": "^1.1.1",
+ "tinyrainbow": "^2.0.0",
+ "vite": "^5.0.0 || ^6.0.0 || ^7.0.0-0",
+ "vite-node": "3.2.4",
+ "why-is-node-running": "^2.3.0"
+ },
+ "bin": {
+ "vitest": "vitest.mjs"
+ },
+ "engines": {
+ "node": "^18.0.0 || ^20.0.0 || >=22.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/vitest"
+ },
+ "peerDependencies": {
+ "@edge-runtime/vm": "*",
+ "@types/debug": "^4.1.12",
+ "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0",
+ "@vitest/browser": "3.2.4",
+ "@vitest/ui": "3.2.4",
+ "happy-dom": "*",
+ "jsdom": "*"
+ },
+ "peerDependenciesMeta": {
+ "@edge-runtime/vm": {
+ "optional": true
+ },
+ "@types/debug": {
+ "optional": true
+ },
+ "@types/node": {
+ "optional": true
+ },
+ "@vitest/browser": {
+ "optional": true
+ },
+ "@vitest/ui": {
+ "optional": true
+ },
+ "happy-dom": {
+ "optional": true
+ },
+ "jsdom": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/vitest/node_modules/picomatch": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz",
+ "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/jonschlinkert"
+ }
+ },
+ "node_modules/webidl-conversions": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
+ "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==",
+ "license": "BSD-2-Clause"
+ },
+ "node_modules/whatwg-url": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
+ "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==",
+ "license": "MIT",
+ "dependencies": {
+ "tr46": "~0.0.3",
+ "webidl-conversions": "^3.0.0"
+ }
+ },
"node_modules/which": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
@@ -2734,6 +6919,23 @@
"node": ">= 8"
}
},
+ "node_modules/why-is-node-running": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/why-is-node-running/-/why-is-node-running-2.3.0.tgz",
+ "integrity": "sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "siginfo": "^2.0.0",
+ "stackback": "0.0.2"
+ },
+ "bin": {
+ "why-is-node-running": "cli.js"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
"node_modules/word-wrap": {
"version": "1.2.5",
"resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz",
@@ -2744,16 +6946,165 @@
"node": ">=0.10.0"
}
},
+ "node_modules/wrap-ansi": {
+ "version": "8.1.0",
+ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz",
+ "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-styles": "^6.1.0",
+ "string-width": "^5.0.1",
+ "strip-ansi": "^7.0.1"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
+ }
+ },
+ "node_modules/wrap-ansi-cjs": {
+ "name": "wrap-ansi",
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
+ "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-styles": "^4.0.0",
+ "string-width": "^4.1.0",
+ "strip-ansi": "^6.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
+ }
+ },
+ "node_modules/wrap-ansi-cjs/node_modules/ansi-regex": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
+ "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/wrap-ansi-cjs/node_modules/emoji-regex": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
+ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/wrap-ansi-cjs/node_modules/string-width": {
+ "version": "4.2.3",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
+ "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "emoji-regex": "^8.0.0",
+ "is-fullwidth-code-point": "^3.0.0",
+ "strip-ansi": "^6.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/wrap-ansi-cjs/node_modules/strip-ansi": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
+ "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-regex": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/wrap-ansi/node_modules/ansi-styles": {
+ "version": "6.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz",
+ "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
"node_modules/wrappy": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
"integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==",
"license": "ISC"
},
+ "node_modules/xcode": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/xcode/-/xcode-3.0.1.tgz",
+ "integrity": "sha512-kCz5k7J7XbJtjABOvkc5lJmkiDh8VhjVCGNiqdKCscmVpdVUpEAyXv1xmCLkQJ5dsHqx3IPO4XW+NTDhU/fatA==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "simple-plist": "^1.1.0",
+ "uuid": "^7.0.3"
+ },
+ "engines": {
+ "node": ">=10.0.0"
+ }
+ },
+ "node_modules/xcode/node_modules/uuid": {
+ "version": "7.0.3",
+ "resolved": "https://registry.npmjs.org/uuid/-/uuid-7.0.3.tgz",
+ "integrity": "sha512-DPSke0pXhTZgoF/d+WSt2QaKMCFSfx7QegxEWT+JOuHF5aWrKEn0G+ztjuJg/gG8/ItK+rbPCD/yNv8yyih6Cg==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "uuid": "dist/bin/uuid"
+ }
+ },
+ "node_modules/xmlbuilder": {
+ "version": "14.0.0",
+ "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-14.0.0.tgz",
+ "integrity": "sha512-ts+B2rSe4fIckR6iquDjsKbQFK2NlUk6iG5nf14mDEyldgoc2nEKZ3jZWMPTxGQwVgToSjt6VGIho1H8/fNFTg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8.0"
+ }
+ },
+ "node_modules/xtend": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",
+ "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.4"
+ }
+ },
+ "node_modules/yn": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz",
+ "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
"node_modules/yocto-queue": {
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",
"integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==",
+ "dev": true,
"license": "MIT",
"engines": {
"node": ">=10"
@@ -2763,21 +7114,21 @@
}
},
"node_modules/zod": {
- "version": "3.24.2",
- "resolved": "https://registry.npmjs.org/zod/-/zod-3.24.2.tgz",
- "integrity": "sha512-lY7CDW43ECgW9u1TcT3IoXHflywfVqDYze4waEz812jR/bZ8FHDsl7pFQoSZTz5N+2NqRXs8GBwnAwo3ZNxqhQ==",
+ "version": "3.25.76",
+ "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz",
+ "integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==",
"license": "MIT",
"funding": {
"url": "https://github.com/sponsors/colinhacks"
}
},
"node_modules/zod-to-json-schema": {
- "version": "3.24.5",
- "resolved": "https://registry.npmjs.org/zod-to-json-schema/-/zod-to-json-schema-3.24.5.tgz",
- "integrity": "sha512-/AuWwMP+YqiPbsJx5D6TfgRTc4kTLjsh5SOcd4bLsfUg2RcEXrFMJl1DGgdHy2aCfsIA/cr/1JM0xcB2GZji8g==",
+ "version": "3.25.1",
+ "resolved": "https://registry.npmjs.org/zod-to-json-schema/-/zod-to-json-schema-3.25.1.tgz",
+ "integrity": "sha512-pM/SU9d3YAggzi6MtR4h7ruuQlqKtad8e9S0fmxcMi+ueAK5Korys/aWcV9LIIHTVbj01NdzxcnXSN+O74ZIVA==",
"license": "ISC",
"peerDependencies": {
- "zod": "^3.24.1"
+ "zod": "^3.25 || ^4"
}
}
}
diff --git a/package.json b/package.json
index 2b929b6b..6194e003 100644
--- a/package.json
+++ b/package.json
@@ -1,21 +1,42 @@
{
"name": "xcodebuildmcp",
- "version": "1.2.0",
+ "version": "1.15.1",
+ "mcpName": "com.xcodebuildmcp/XcodeBuildMCP",
+ "iOSTemplateVersion": "v1.0.8",
+ "macOSTemplateVersion": "v1.0.5",
"main": "build/index.js",
"type": "module",
"bin": {
- "xcodebuildmcp": "./build/index.js"
+ "xcodebuildmcp": "build/index.js",
+ "xcodebuildmcp-doctor": "build/doctor-cli.js"
},
"scripts": {
- "prebuild": "node -p \"'export const version = ' + JSON.stringify(require('./package.json').version) + ';'\" > src/version.ts",
- "build": "tsc && node -e \"require('fs').chmodSync('build/index.js', '755')\"",
+ "build": "node -e \"const fs = require('fs'); const pkg = require('./package.json'); fs.writeFileSync('src/version.ts', \\`export const version = '\\${pkg.version}';\\nexport const iOSTemplateVersion = '\\${pkg.iOSTemplateVersion}';\\nexport const macOSTemplateVersion = '\\${pkg.macOSTemplateVersion}';\\n\\`)\" && tsup",
+ "dev": "npm run build && tsup --watch",
+ "bundle:axe": "scripts/bundle-axe.sh",
"lint": "eslint 'src/**/*.{js,ts}'",
"lint:fix": "eslint 'src/**/*.{js,ts}' --fix",
"format": "prettier --write 'src/**/*.{js,ts}'",
- "format:check": "prettier --check 'src/**/*.{js,ts}'"
+ "format:check": "prettier --check 'src/**/*.{js,ts}'",
+ "typecheck": "npx tsc --noEmit",
+ "inspect": "npx @modelcontextprotocol/inspector node build/index.js",
+ "doctor": "node build/doctor-cli.js",
+ "tools": "npx tsx scripts/tools-cli.ts",
+ "tools:list": "npx tsx scripts/tools-cli.ts list",
+ "tools:static": "npx tsx scripts/tools-cli.ts static",
+ "tools:count": "npx tsx scripts/tools-cli.ts count --static",
+ "tools:analysis": "npx tsx scripts/analysis/tools-analysis.ts",
+ "docs:update": "npx tsx scripts/update-tools-docs.ts",
+ "docs:update:dry-run": "npx tsx scripts/update-tools-docs.ts --dry-run --verbose",
+ "test": "vitest run",
+ "test:watch": "vitest",
+ "test:ui": "vitest --ui",
+ "test:coverage": "vitest run --coverage"
},
"files": [
- "build"
+ "build",
+ "bundled",
+ "plugins"
],
"keywords": [
"xcodebuild",
@@ -38,23 +59,32 @@
"url": "https://github.com/cameroncooke/XcodeBuildMCP/issues"
},
"dependencies": {
- "@expo/xcpretty": "^4.3.2",
- "@modelcontextprotocol/sdk": "^1.6.1",
- "@types/uuid": "^10.0.0",
+ "@modelcontextprotocol/sdk": "^1.25.1",
+ "@sentry/cli": "^2.43.1",
+ "@sentry/node": "^10.5.0",
"uuid": "^11.1.0",
"zod": "^3.24.2"
},
"devDependencies": {
+ "@bacons/xcode": "^1.0.0-alpha.24",
"@eslint/eslintrc": "^3.3.1",
"@eslint/js": "^9.23.0",
"@types/node": "^22.13.6",
"@typescript-eslint/eslint-plugin": "^8.28.0",
"@typescript-eslint/parser": "^8.28.0",
+ "@vitest/coverage-v8": "^3.2.4",
+ "@vitest/ui": "^3.2.4",
"eslint": "^9.23.0",
"eslint-config-prettier": "^10.1.1",
"eslint-plugin-prettier": "^5.2.5",
- "prettier": "^3.5.3",
+ "playwright": "^1.53.0",
+ "prettier": "3.6.2",
+ "ts-node": "^10.9.2",
+ "tsup": "^8.5.0",
+ "tsx": "^4.20.4",
"typescript": "^5.8.2",
- "typescript-eslint": "^8.28.0"
+ "typescript-eslint": "^8.28.0",
+ "vitest": "^3.2.4",
+ "xcode": "^3.0.1"
}
}
diff --git a/scripts/analysis/tools-analysis.ts b/scripts/analysis/tools-analysis.ts
new file mode 100644
index 00000000..7e6d5988
--- /dev/null
+++ b/scripts/analysis/tools-analysis.ts
@@ -0,0 +1,457 @@
+#!/usr/bin/env node
+
+/**
+ * XcodeBuildMCP Tools Analysis
+ *
+ * Core TypeScript module for analyzing XcodeBuildMCP tools using AST parsing.
+ * Provides reliable extraction of tool information without fallback strategies.
+ */
+
+import {
+ createSourceFile,
+ forEachChild,
+ isExportAssignment,
+ isIdentifier,
+ isNoSubstitutionTemplateLiteral,
+ isObjectLiteralExpression,
+ isPropertyAssignment,
+ isStringLiteral,
+ isTemplateExpression,
+ isVariableDeclaration,
+ isVariableStatement,
+ type Node,
+ type ObjectLiteralExpression,
+ ScriptTarget,
+ type SourceFile,
+ SyntaxKind,
+} from 'typescript';
+import * as fs from 'fs';
+import * as path from 'path';
+import { glob } from 'glob';
+import { fileURLToPath } from 'url';
+
+// Get project root
+const __filename = fileURLToPath(import.meta.url);
+const __dirname = path.dirname(__filename);
+const projectRoot = path.resolve(__dirname, '..', '..');
+const toolsDir = path.join(projectRoot, 'src', 'mcp', 'tools');
+
+export interface ToolInfo {
+ name: string;
+ workflow: string;
+ path: string;
+ relativePath: string;
+ description: string;
+ isCanonical: boolean;
+}
+
+export interface WorkflowInfo {
+ name: string;
+ displayName: string;
+ description: string;
+ tools: ToolInfo[];
+ toolCount: number;
+ canonicalCount: number;
+ reExportCount: number;
+}
+
+export interface AnalysisStats {
+ totalTools: number;
+ canonicalTools: number;
+ reExportTools: number;
+ workflowCount: number;
+}
+
+export interface StaticAnalysisResult {
+ workflows: WorkflowInfo[];
+ tools: ToolInfo[];
+ stats: AnalysisStats;
+}
+
+/**
+ * Extract the description from a tool's default export using TypeScript AST
+ */
+function extractToolDescription(sourceFile: SourceFile): string {
+ let description: string | null = null;
+
+ function visit(node: Node): void {
+ let objectExpression: ObjectLiteralExpression | null = null;
+
+ // Look for export default { ... } - the standard TypeScript pattern
+ // isExportEquals is undefined for `export default` and true for `export = `
+ if (isExportAssignment(node) && !node.isExportEquals) {
+ if (isObjectLiteralExpression(node.expression)) {
+ objectExpression = node.expression;
+ }
+ }
+
+ if (objectExpression) {
+ // Found export default { ... }, now look for description property
+ for (const property of objectExpression.properties) {
+ if (
+ isPropertyAssignment(property) &&
+ isIdentifier(property.name) &&
+ property.name.text === 'description'
+ ) {
+ // Extract the description value
+ if (isStringLiteral(property.initializer)) {
+ // This is the most common case - simple string literal
+ description = property.initializer.text;
+ } else if (
+ isTemplateExpression(property.initializer) ||
+ isNoSubstitutionTemplateLiteral(property.initializer)
+ ) {
+ // Handle template literals - get the raw text and clean it
+ description = property.initializer.getFullText(sourceFile).trim();
+ // Remove surrounding backticks
+ if (description.startsWith('`') && description.endsWith('`')) {
+ description = description.slice(1, -1);
+ }
+ } else {
+ // Handle any other expression (multiline strings, computed values)
+ const fullText = property.initializer.getFullText(sourceFile).trim();
+ // This covers cases where the description spans multiple lines
+ // Remove surrounding quotes and normalize whitespace
+ let cleaned = fullText;
+ if (
+ (cleaned.startsWith('"') && cleaned.endsWith('"')) ||
+ (cleaned.startsWith("'") && cleaned.endsWith("'"))
+ ) {
+ cleaned = cleaned.slice(1, -1);
+ }
+ // Collapse multiple whitespaces and newlines into single spaces
+ description = cleaned.replace(/\s+/g, ' ').trim();
+ }
+ return; // Found description, stop looking
+ }
+ }
+ }
+
+ forEachChild(node, visit);
+ }
+
+ visit(sourceFile);
+
+ if (description === null) {
+ throw new Error('Could not extract description from tool export default object');
+ }
+
+ return description;
+}
+
+/**
+ * Check if a file is a re-export by examining its content
+ */
+function isReExportFile(filePath: string): boolean {
+ const content = fs.readFileSync(filePath, 'utf-8');
+
+ // Remove comments and empty lines, then check for re-export pattern
+ // First remove multi-line comments
+ const contentWithoutBlockComments = content.replace(/\/\*[\s\S]*?\*\//g, '');
+
+ const cleanedLines = contentWithoutBlockComments
+ .split('\n')
+ .map((line) => {
+ // Remove inline comments but preserve the code before them
+ const codeBeforeComment = line.split('//')[0].trim();
+ return codeBeforeComment;
+ })
+ .filter((line) => line.length > 0);
+
+ // Should have exactly one line: export { default } from '...';
+ if (cleanedLines.length !== 1) {
+ return false;
+ }
+
+ const exportLine = cleanedLines[0];
+ return /^export\s*{\s*default\s*}\s*from\s*['"][^'"]+['"];?\s*$/.test(exportLine);
+}
+
+/**
+ * Get workflow metadata from index.ts file if it exists
+ */
+async function getWorkflowMetadata(
+ workflowDir: string,
+): Promise<{ displayName: string; description: string } | null> {
+ const indexPath = path.join(toolsDir, workflowDir, 'index.ts');
+
+ if (!fs.existsSync(indexPath)) {
+ return null;
+ }
+
+ try {
+ const content = fs.readFileSync(indexPath, 'utf-8');
+ const sourceFile = createSourceFile(indexPath, content, ScriptTarget.Latest, true);
+
+ const workflowExport: { name?: string; description?: string } = {};
+
+ function visit(node: Node): void {
+ // Look for: export const workflow = { ... }
+ if (
+ isVariableStatement(node) &&
+ node.modifiers?.some((mod) => mod.kind === SyntaxKind.ExportKeyword)
+ ) {
+ for (const declaration of node.declarationList.declarations) {
+ if (
+ isVariableDeclaration(declaration) &&
+ isIdentifier(declaration.name) &&
+ declaration.name.text === 'workflow' &&
+ declaration.initializer &&
+ isObjectLiteralExpression(declaration.initializer)
+ ) {
+ // Extract name and description properties
+ for (const property of declaration.initializer.properties) {
+ if (isPropertyAssignment(property) && isIdentifier(property.name)) {
+ const propertyName = property.name.text;
+
+ if (propertyName === 'name' && isStringLiteral(property.initializer)) {
+ workflowExport.name = property.initializer.text;
+ } else if (
+ propertyName === 'description' &&
+ isStringLiteral(property.initializer)
+ ) {
+ workflowExport.description = property.initializer.text;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ forEachChild(node, visit);
+ }
+
+ visit(sourceFile);
+
+ if (workflowExport.name && workflowExport.description) {
+ return {
+ displayName: workflowExport.name,
+ description: workflowExport.description,
+ };
+ }
+ } catch (error) {
+ console.error(`Warning: Could not parse workflow metadata from ${indexPath}: ${error}`);
+ }
+
+ return null;
+}
+
+/**
+ * Get a human-readable workflow name from directory name
+ */
+function getWorkflowDisplayName(workflowDir: string): string {
+ const displayNames: Record = {
+ device: 'iOS Device Development',
+ doctor: 'System Doctor',
+ logging: 'Logging & Monitoring',
+ macos: 'macOS Development',
+ 'project-discovery': 'Project Discovery',
+ 'project-scaffolding': 'Project Scaffolding',
+ simulator: 'iOS Simulator Development',
+ 'simulator-management': 'Simulator Management',
+ 'swift-package': 'Swift Package Manager',
+ 'ui-testing': 'UI Testing & Automation',
+ utilities: 'Utilities',
+ };
+
+ return displayNames[workflowDir] || workflowDir;
+}
+
+/**
+ * Get workflow description
+ */
+function getWorkflowDescription(workflowDir: string): string {
+ const descriptions: Record = {
+ device: 'Physical device development, testing, and deployment',
+ doctor: 'System health checks and environment validation',
+ logging: 'Log capture and monitoring across platforms',
+ macos: 'Native macOS application development and testing',
+ 'project-discovery': 'Project analysis and information gathering',
+ 'project-scaffolding': 'Create new projects from templates',
+ simulator: 'Simulator-based development, testing, and deployment',
+ 'simulator-management': 'Simulator environment and configuration management',
+ 'swift-package': 'Swift Package development and testing',
+ 'ui-testing': 'Automated UI interaction and testing',
+ utilities: 'General utility operations',
+ };
+
+ return descriptions[workflowDir] || `${workflowDir} related tools`;
+}
+
+/**
+ * Perform static analysis of all tools in the project
+ */
+export async function getStaticToolAnalysis(): Promise {
+ // Find all workflow directories
+ const workflowDirs = fs
+ .readdirSync(toolsDir, { withFileTypes: true })
+ .filter((dirent) => dirent.isDirectory())
+ .map((dirent) => dirent.name)
+ .sort();
+
+ // Find all tool files
+ const files = await glob('**/*.ts', {
+ cwd: toolsDir,
+ ignore: [
+ '**/__tests__/**',
+ '**/index.ts',
+ '**/*.test.ts',
+ '**/lib/**',
+ '**/*-processes.ts', // Process management utilities
+ '**/*.deps.ts', // Dependency files
+ '**/*-utils.ts', // Utility files
+ '**/*-common.ts', // Common/shared code
+ '**/*-types.ts', // Type definition files
+ ],
+ absolute: true,
+ });
+
+ const allTools: ToolInfo[] = [];
+ const workflowMap = new Map();
+
+ let canonicalCount = 0;
+ let reExportCount = 0;
+
+ // Initialize workflow map
+ for (const workflowDir of workflowDirs) {
+ workflowMap.set(workflowDir, []);
+ }
+
+ // Process each tool file
+ for (const filePath of files) {
+ const toolName = path.basename(filePath, '.ts');
+ const workflowDir = path.basename(path.dirname(filePath));
+ const relativePath = path.relative(projectRoot, filePath);
+
+ const isReExport = isReExportFile(filePath);
+
+ let description = '';
+
+ if (!isReExport) {
+ // Extract description from canonical tool using AST
+ try {
+ const content = fs.readFileSync(filePath, 'utf-8');
+ const sourceFile = createSourceFile(filePath, content, ScriptTarget.Latest, true);
+
+ description = extractToolDescription(sourceFile);
+ canonicalCount++;
+ } catch (error) {
+ throw new Error(`Failed to extract description from ${relativePath}: ${error}`);
+ }
+ } else {
+ description = '(Re-exported from shared workflow)';
+ reExportCount++;
+ }
+
+ const toolInfo: ToolInfo = {
+ name: toolName,
+ workflow: workflowDir,
+ path: filePath,
+ relativePath,
+ description,
+ isCanonical: !isReExport,
+ };
+
+ allTools.push(toolInfo);
+
+ const workflowTools = workflowMap.get(workflowDir);
+ if (workflowTools) {
+ workflowTools.push(toolInfo);
+ }
+ }
+
+ // Build workflow information
+ const workflows: WorkflowInfo[] = [];
+
+ for (const workflowDir of workflowDirs) {
+ const workflowTools = workflowMap.get(workflowDir) ?? [];
+ const canonicalTools = workflowTools.filter((t) => t.isCanonical);
+ const reExportTools = workflowTools.filter((t) => !t.isCanonical);
+
+ // Try to get metadata from index.ts, fall back to hardcoded names/descriptions
+ const metadata = await getWorkflowMetadata(workflowDir);
+
+ const workflowInfo: WorkflowInfo = {
+ name: workflowDir,
+ displayName: metadata?.displayName ?? getWorkflowDisplayName(workflowDir),
+ description: metadata?.description ?? getWorkflowDescription(workflowDir),
+ tools: workflowTools.sort((a, b) => a.name.localeCompare(b.name)),
+ toolCount: workflowTools.length,
+ canonicalCount: canonicalTools.length,
+ reExportCount: reExportTools.length,
+ };
+
+ workflows.push(workflowInfo);
+ }
+
+ const stats: AnalysisStats = {
+ totalTools: allTools.length,
+ canonicalTools: canonicalCount,
+ reExportTools: reExportCount,
+ workflowCount: workflows.length,
+ };
+
+ return {
+ workflows: workflows.sort((a, b) => a.displayName.localeCompare(b.displayName)),
+ tools: allTools.sort((a, b) => a.name.localeCompare(b.name)),
+ stats,
+ };
+}
+
+/**
+ * Get only canonical tools (excluding re-exports) for documentation generation
+ */
+export async function getCanonicalTools(): Promise {
+ const analysis = await getStaticToolAnalysis();
+ return analysis.tools.filter((tool) => tool.isCanonical);
+}
+
+/**
+ * Get tools grouped by workflow for documentation generation
+ */
+export async function getToolsByWorkflow(): Promise