From 83499550e3b42c4e53e601d944614a52420c04dd Mon Sep 17 00:00:00 2001 From: Morgan Dean Date: Wed, 25 Jun 2025 16:10:08 -0700 Subject: [PATCH] Move non-python libs to respective directories. Update workflows to use updated directories --- .github/workflows/ci-lume.yml | 4 +- .github/workflows/publish-agent.yml | 218 ++++---- .github/workflows/publish-computer-server.yml | 66 +-- .github/workflows/publish-computer.yml | 182 +++---- .github/workflows/publish-core.yml | 52 +- .github/workflows/publish-lume.yml | 82 +-- .github/workflows/publish-mcp-server.yml | 204 ++++---- .github/workflows/publish-pylume.yml | 72 +-- .github/workflows/publish-som.yml | 52 +- .github/workflows/reusable-publish.yml | 476 +++++++++--------- libs/{python => bash}/lumier/.dockerignore | 0 libs/{python => bash}/lumier/Dockerfile | 0 libs/{python => bash}/lumier/README.md | 0 libs/{python => bash}/lumier/src/bin/entry.sh | 0 .../lumier/src/config/constants.sh | 0 .../lumier/src/hooks/on-logon.sh | 0 libs/{python => bash}/lumier/src/lib/utils.sh | 0 libs/{python => bash}/lumier/src/lib/vm.sh | 0 libs/{python => swift}/lume/.cursorignore | 0 libs/{python => swift}/lume/CONTRIBUTING.md | 0 libs/{python => swift}/lume/Package.resolved | 0 libs/{python => swift}/lume/Package.swift | 0 libs/{python => swift}/lume/README.md | 0 .../lume/docs/API-Reference.md | 0 .../lume/docs/Development.md | 0 libs/{python => swift}/lume/docs/FAQ.md | 0 libs/{python => swift}/lume/img/cli.png | Bin .../{python => swift}/lume/img/logo_black.png | Bin .../{python => swift}/lume/img/logo_white.png | Bin .../lume/resources/lume.entitlements | 0 .../{python => swift}/lume/scripts/install.sh | 0 .../lume/src/Commands/Clone.swift | 0 .../lume/src/Commands/Config.swift | 0 .../lume/src/Commands/Create.swift | 0 .../lume/src/Commands/Delete.swift | 0 .../lume/src/Commands/Get.swift | 0 .../lume/src/Commands/IPSW.swift | 0 .../lume/src/Commands/Images.swift | 0 .../lume/src/Commands/List.swift | 0 .../lume/src/Commands/Logs.swift | 0 .../src/Commands/Options/FormatOption.swift | 0 .../lume/src/Commands/Prune.swift | 0 .../lume/src/Commands/Pull.swift | 0 .../lume/src/Commands/Push.swift | 0 .../lume/src/Commands/Run.swift | 0 .../lume/src/Commands/Serve.swift | 0 .../lume/src/Commands/Set.swift | 0 .../lume/src/Commands/Stop.swift | 0 .../ImageContainerRegistry.swift | 0 .../src/ContainerRegistry/ImageList.swift | 0 .../src/ContainerRegistry/ImagesPrinter.swift | 0 .../lume/src/Errors/Errors.swift | 0 .../lume/src/FileSystem/Home.swift | 0 .../lume/src/FileSystem/Settings.swift | 0 .../lume/src/FileSystem/VMConfig.swift | 0 .../lume/src/FileSystem/VMDirectory.swift | 0 .../lume/src/FileSystem/VMLocation.swift | 0 .../lume/src/LumeController.swift | 0 libs/{python => swift}/lume/src/Main.swift | 0 .../lume/src/Server/HTTP.swift | 0 .../lume/src/Server/Handlers.swift | 0 .../lume/src/Server/Requests.swift | 0 .../lume/src/Server/Responses.swift | 0 .../lume/src/Server/Server.swift | 0 .../lume/src/Utils/CommandRegistry.swift | 0 .../lume/src/Utils/CommandUtils.swift | 0 .../lume/src/Utils/Logger.swift | 0 .../lume/src/Utils/NetworkUtils.swift | 0 .../lume/src/Utils/Path.swift | 0 .../lume/src/Utils/ProcessRunner.swift | 0 .../lume/src/Utils/ProgressLogger.swift | 0 .../lume/src/Utils/String.swift | 0 .../lume/src/Utils/Utils.swift | 0 .../lume/src/VM/DarwinVM.swift | 0 .../lume/src/VM/LinuxVM.swift | 0 libs/{python => swift}/lume/src/VM/VM.swift | 0 .../lume/src/VM/VMDetails.swift | 0 .../lume/src/VM/VMDetailsPrinter.swift | 0 .../lume/src/VM/VMDisplayResolution.swift | 0 .../lume/src/VM/VMFactory.swift | 0 .../lume/src/VNC/PassphraseGenerator.swift | 0 .../lume/src/VNC/VNCService.swift | 0 .../src/Virtualization/DHCPLeaseParser.swift | 0 .../Virtualization/DarwinImageLoader.swift | 0 .../Virtualization/ImageLoaderFactory.swift | 0 .../VMVirtualizationService.swift | 0 .../lume/tests/Mocks/MockVM.swift | 0 .../Mocks/MockVMVirtualizationService.swift | 0 .../lume/tests/Mocks/MockVNCService.swift | 0 .../lume/tests/VM/VMDetailsPrinterTests.swift | 0 .../lume/tests/VMTests.swift | 0 .../tests/VMVirtualizationServiceTests.swift | 0 .../lume/tests/VNCServiceTests.swift | 0 93 files changed, 704 insertions(+), 704 deletions(-) rename libs/{python => bash}/lumier/.dockerignore (100%) rename libs/{python => bash}/lumier/Dockerfile (100%) rename libs/{python => bash}/lumier/README.md (100%) rename libs/{python => bash}/lumier/src/bin/entry.sh (100%) rename libs/{python => bash}/lumier/src/config/constants.sh (100%) rename libs/{python => bash}/lumier/src/hooks/on-logon.sh (100%) rename libs/{python => bash}/lumier/src/lib/utils.sh (100%) rename libs/{python => bash}/lumier/src/lib/vm.sh (100%) rename libs/{python => swift}/lume/.cursorignore (100%) rename libs/{python => swift}/lume/CONTRIBUTING.md (100%) rename libs/{python => swift}/lume/Package.resolved (100%) rename libs/{python => swift}/lume/Package.swift (100%) rename libs/{python => swift}/lume/README.md (100%) rename libs/{python => swift}/lume/docs/API-Reference.md (100%) rename libs/{python => swift}/lume/docs/Development.md (100%) rename libs/{python => swift}/lume/docs/FAQ.md (100%) rename libs/{python => swift}/lume/img/cli.png (100%) rename libs/{python => swift}/lume/img/logo_black.png (100%) rename libs/{python => swift}/lume/img/logo_white.png (100%) rename libs/{python => swift}/lume/resources/lume.entitlements (100%) rename libs/{python => swift}/lume/scripts/install.sh (100%) rename libs/{python => swift}/lume/src/Commands/Clone.swift (100%) rename libs/{python => swift}/lume/src/Commands/Config.swift (100%) rename libs/{python => swift}/lume/src/Commands/Create.swift (100%) rename libs/{python => swift}/lume/src/Commands/Delete.swift (100%) rename libs/{python => swift}/lume/src/Commands/Get.swift (100%) rename libs/{python => swift}/lume/src/Commands/IPSW.swift (100%) rename libs/{python => swift}/lume/src/Commands/Images.swift (100%) rename libs/{python => swift}/lume/src/Commands/List.swift (100%) rename libs/{python => swift}/lume/src/Commands/Logs.swift (100%) rename libs/{python => swift}/lume/src/Commands/Options/FormatOption.swift (100%) rename libs/{python => swift}/lume/src/Commands/Prune.swift (100%) rename libs/{python => swift}/lume/src/Commands/Pull.swift (100%) rename libs/{python => swift}/lume/src/Commands/Push.swift (100%) rename libs/{python => swift}/lume/src/Commands/Run.swift (100%) rename libs/{python => swift}/lume/src/Commands/Serve.swift (100%) rename libs/{python => swift}/lume/src/Commands/Set.swift (100%) rename libs/{python => swift}/lume/src/Commands/Stop.swift (100%) rename libs/{python => swift}/lume/src/ContainerRegistry/ImageContainerRegistry.swift (100%) rename libs/{python => swift}/lume/src/ContainerRegistry/ImageList.swift (100%) rename libs/{python => swift}/lume/src/ContainerRegistry/ImagesPrinter.swift (100%) rename libs/{python => swift}/lume/src/Errors/Errors.swift (100%) rename libs/{python => swift}/lume/src/FileSystem/Home.swift (100%) rename libs/{python => swift}/lume/src/FileSystem/Settings.swift (100%) rename libs/{python => swift}/lume/src/FileSystem/VMConfig.swift (100%) rename libs/{python => swift}/lume/src/FileSystem/VMDirectory.swift (100%) rename libs/{python => swift}/lume/src/FileSystem/VMLocation.swift (100%) rename libs/{python => swift}/lume/src/LumeController.swift (100%) rename libs/{python => swift}/lume/src/Main.swift (100%) rename libs/{python => swift}/lume/src/Server/HTTP.swift (100%) rename libs/{python => swift}/lume/src/Server/Handlers.swift (100%) rename libs/{python => swift}/lume/src/Server/Requests.swift (100%) rename libs/{python => swift}/lume/src/Server/Responses.swift (100%) rename libs/{python => swift}/lume/src/Server/Server.swift (100%) rename libs/{python => swift}/lume/src/Utils/CommandRegistry.swift (100%) rename libs/{python => swift}/lume/src/Utils/CommandUtils.swift (100%) rename libs/{python => swift}/lume/src/Utils/Logger.swift (100%) rename libs/{python => swift}/lume/src/Utils/NetworkUtils.swift (100%) rename libs/{python => swift}/lume/src/Utils/Path.swift (100%) rename libs/{python => swift}/lume/src/Utils/ProcessRunner.swift (100%) rename libs/{python => swift}/lume/src/Utils/ProgressLogger.swift (100%) rename libs/{python => swift}/lume/src/Utils/String.swift (100%) rename libs/{python => swift}/lume/src/Utils/Utils.swift (100%) rename libs/{python => swift}/lume/src/VM/DarwinVM.swift (100%) rename libs/{python => swift}/lume/src/VM/LinuxVM.swift (100%) rename libs/{python => swift}/lume/src/VM/VM.swift (100%) rename libs/{python => swift}/lume/src/VM/VMDetails.swift (100%) rename libs/{python => swift}/lume/src/VM/VMDetailsPrinter.swift (100%) rename libs/{python => swift}/lume/src/VM/VMDisplayResolution.swift (100%) rename libs/{python => swift}/lume/src/VM/VMFactory.swift (100%) rename libs/{python => swift}/lume/src/VNC/PassphraseGenerator.swift (100%) rename libs/{python => swift}/lume/src/VNC/VNCService.swift (100%) rename libs/{python => swift}/lume/src/Virtualization/DHCPLeaseParser.swift (100%) rename libs/{python => swift}/lume/src/Virtualization/DarwinImageLoader.swift (100%) rename libs/{python => swift}/lume/src/Virtualization/ImageLoaderFactory.swift (100%) rename libs/{python => swift}/lume/src/Virtualization/VMVirtualizationService.swift (100%) rename libs/{python => swift}/lume/tests/Mocks/MockVM.swift (100%) rename libs/{python => swift}/lume/tests/Mocks/MockVMVirtualizationService.swift (100%) rename libs/{python => swift}/lume/tests/Mocks/MockVNCService.swift (100%) rename libs/{python => swift}/lume/tests/VM/VMDetailsPrinterTests.swift (100%) rename libs/{python => swift}/lume/tests/VMTests.swift (100%) rename libs/{python => swift}/lume/tests/VMVirtualizationServiceTests.swift (100%) rename libs/{python => swift}/lume/tests/VNCServiceTests.swift (100%) diff --git a/.github/workflows/ci-lume.yml b/.github/workflows/ci-lume.yml index d33191cc..dc31bd5a 100644 --- a/.github/workflows/ci-lume.yml +++ b/.github/workflows/ci-lume.yml @@ -20,7 +20,7 @@ jobs: - run: uname -a - run: sudo xcode-select -s /Applications/Xcode_16.app # Swift 6.0 - run: swift test - working-directory: ./libs/lume + working-directory: ./libs/swift/lume build: name: Release build runs-on: macos-15 @@ -29,4 +29,4 @@ jobs: - run: uname -a - run: sudo xcode-select -s /Applications/Xcode_16.app # Swift 6.0 - run: swift build --configuration release - working-directory: ./libs/lume + working-directory: ./libs/swift/lume diff --git a/.github/workflows/publish-agent.yml b/.github/workflows/publish-agent.yml index ea03edd6..5869bcd1 100644 --- a/.github/workflows/publish-agent.yml +++ b/.github/workflows/publish-agent.yml @@ -3,17 +3,17 @@ name: Publish Agent Package on: push: tags: - - 'agent-v*' + - "agent-v*" workflow_dispatch: inputs: version: - description: 'Version to publish (without v prefix)' + description: "Version to publish (without v prefix)" required: true - default: '0.1.0' + default: "0.1.0" workflow_call: inputs: version: - description: 'Version to publish' + description: "Version to publish" required: true type: string @@ -30,127 +30,127 @@ jobs: som_version: ${{ steps.update-deps.outputs.som_version }} core_version: ${{ steps.update-deps.outputs.core_version }} steps: - - uses: actions/checkout@v4 - - - name: Determine version - id: get-version - run: | - if [ "${{ github.event_name }}" == "push" ]; then - # Extract version from tag (for package-specific tags) - if [[ "${{ github.ref }}" =~ ^refs/tags/agent-v([0-9]+\.[0-9]+\.[0-9]+) ]]; then - VERSION=${BASH_REMATCH[1]} + - uses: actions/checkout@v4 + + - name: Determine version + id: get-version + run: | + if [ "${{ github.event_name }}" == "push" ]; then + # Extract version from tag (for package-specific tags) + if [[ "${{ github.ref }}" =~ ^refs/tags/agent-v([0-9]+\.[0-9]+\.[0-9]+) ]]; then + VERSION=${BASH_REMATCH[1]} + else + echo "Invalid tag format for agent" + exit 1 + fi + elif [ "${{ github.event_name }}" == "workflow_dispatch" ]; then + # Use version from workflow dispatch + VERSION=${{ github.event.inputs.version }} else - echo "Invalid tag format for agent" - exit 1 + # Use version from workflow_call + VERSION=${{ inputs.version }} fi - elif [ "${{ github.event_name }}" == "workflow_dispatch" ]; then - # Use version from workflow dispatch - VERSION=${{ github.event.inputs.version }} - else - # Use version from workflow_call - VERSION=${{ inputs.version }} - fi - echo "VERSION=$VERSION" - echo "version=$VERSION" >> $GITHUB_OUTPUT + echo "VERSION=$VERSION" + echo "version=$VERSION" >> $GITHUB_OUTPUT - - name: Set up Python - uses: actions/setup-python@v4 - with: - python-version: '3.11' + - name: Set up Python + uses: actions/setup-python@v4 + with: + python-version: "3.11" - - name: Update dependencies to latest versions - id: update-deps - run: | - cd libs/agent - - # Install required package for PyPI API access - pip install requests - - # Create a more robust Python script for PyPI version checking - cat > get_latest_versions.py << 'EOF' - import requests - import json - import sys + - name: Update dependencies to latest versions + id: update-deps + run: | + cd libs/python/agent - def get_package_version(package_name, fallback="0.1.0"): - try: - response = requests.get(f'https://pypi.org/pypi/{package_name}/json') - print(f"API Response Status for {package_name}: {response.status_code}", file=sys.stderr) - - if response.status_code != 200: - print(f"API request failed for {package_name}, using fallback version", file=sys.stderr) - return fallback - - data = json.loads(response.text) - - if 'info' not in data: - print(f"Missing 'info' key in API response for {package_name}, using fallback version", file=sys.stderr) - return fallback - - return data['info']['version'] - except Exception as e: - print(f"Error fetching version for {package_name}: {str(e)}", file=sys.stderr) - return fallback + # Install required package for PyPI API access + pip install requests - # Get latest versions - print(get_package_version('cua-computer')) - print(get_package_version('cua-som')) - print(get_package_version('cua-core')) - EOF - - # Execute the script to get the versions - VERSIONS=($(python get_latest_versions.py)) - LATEST_COMPUTER=${VERSIONS[0]} - LATEST_SOM=${VERSIONS[1]} - LATEST_CORE=${VERSIONS[2]} - - echo "Latest cua-computer version: $LATEST_COMPUTER" - echo "Latest cua-som version: $LATEST_SOM" - echo "Latest cua-core version: $LATEST_CORE" - - # Output the versions for the next job - echo "computer_version=$LATEST_COMPUTER" >> $GITHUB_OUTPUT - echo "som_version=$LATEST_SOM" >> $GITHUB_OUTPUT - echo "core_version=$LATEST_CORE" >> $GITHUB_OUTPUT - - # Determine major version for version constraint - COMPUTER_MAJOR=$(echo $LATEST_COMPUTER | cut -d. -f1) - SOM_MAJOR=$(echo $LATEST_SOM | cut -d. -f1) - CORE_MAJOR=$(echo $LATEST_CORE | cut -d. -f1) - - NEXT_COMPUTER_MAJOR=$((COMPUTER_MAJOR + 1)) - NEXT_SOM_MAJOR=$((SOM_MAJOR + 1)) - NEXT_CORE_MAJOR=$((CORE_MAJOR + 1)) - - # Update dependencies in pyproject.toml - if [[ "$OSTYPE" == "darwin"* ]]; then - # macOS version of sed needs an empty string for -i - sed -i '' "s/\"cua-computer>=.*,<.*\"/\"cua-computer>=$LATEST_COMPUTER,<$NEXT_COMPUTER_MAJOR.0.0\"/" pyproject.toml - sed -i '' "s/\"cua-som>=.*,<.*\"/\"cua-som>=$LATEST_SOM,<$NEXT_SOM_MAJOR.0.0\"/" pyproject.toml - sed -i '' "s/\"cua-core>=.*,<.*\"/\"cua-core>=$LATEST_CORE,<$NEXT_CORE_MAJOR.0.0\"/" pyproject.toml - else - # Linux version - sed -i "s/\"cua-computer>=.*,<.*\"/\"cua-computer>=$LATEST_COMPUTER,<$NEXT_COMPUTER_MAJOR.0.0\"/" pyproject.toml - sed -i "s/\"cua-som>=.*,<.*\"/\"cua-som>=$LATEST_SOM,<$NEXT_SOM_MAJOR.0.0\"/" pyproject.toml - sed -i "s/\"cua-core>=.*,<.*\"/\"cua-core>=$LATEST_CORE,<$NEXT_CORE_MAJOR.0.0\"/" pyproject.toml - fi - - # Display the updated dependencies - echo "Updated dependencies in pyproject.toml:" - grep -E "cua-computer|cua-som|cua-core" pyproject.toml + # Create a more robust Python script for PyPI version checking + cat > get_latest_versions.py << 'EOF' + import requests + import json + import sys + + def get_package_version(package_name, fallback="0.1.0"): + try: + response = requests.get(f'https://pypi.org/pypi/{package_name}/json') + print(f"API Response Status for {package_name}: {response.status_code}", file=sys.stderr) + + if response.status_code != 200: + print(f"API request failed for {package_name}, using fallback version", file=sys.stderr) + return fallback + + data = json.loads(response.text) + + if 'info' not in data: + print(f"Missing 'info' key in API response for {package_name}, using fallback version", file=sys.stderr) + return fallback + + return data['info']['version'] + except Exception as e: + print(f"Error fetching version for {package_name}: {str(e)}", file=sys.stderr) + return fallback + + # Get latest versions + print(get_package_version('cua-computer')) + print(get_package_version('cua-som')) + print(get_package_version('cua-core')) + EOF + + # Execute the script to get the versions + VERSIONS=($(python get_latest_versions.py)) + LATEST_COMPUTER=${VERSIONS[0]} + LATEST_SOM=${VERSIONS[1]} + LATEST_CORE=${VERSIONS[2]} + + echo "Latest cua-computer version: $LATEST_COMPUTER" + echo "Latest cua-som version: $LATEST_SOM" + echo "Latest cua-core version: $LATEST_CORE" + + # Output the versions for the next job + echo "computer_version=$LATEST_COMPUTER" >> $GITHUB_OUTPUT + echo "som_version=$LATEST_SOM" >> $GITHUB_OUTPUT + echo "core_version=$LATEST_CORE" >> $GITHUB_OUTPUT + + # Determine major version for version constraint + COMPUTER_MAJOR=$(echo $LATEST_COMPUTER | cut -d. -f1) + SOM_MAJOR=$(echo $LATEST_SOM | cut -d. -f1) + CORE_MAJOR=$(echo $LATEST_CORE | cut -d. -f1) + + NEXT_COMPUTER_MAJOR=$((COMPUTER_MAJOR + 1)) + NEXT_SOM_MAJOR=$((SOM_MAJOR + 1)) + NEXT_CORE_MAJOR=$((CORE_MAJOR + 1)) + + # Update dependencies in pyproject.toml + if [[ "$OSTYPE" == "darwin"* ]]; then + # macOS version of sed needs an empty string for -i + sed -i '' "s/\"cua-computer>=.*,<.*\"/\"cua-computer>=$LATEST_COMPUTER,<$NEXT_COMPUTER_MAJOR.0.0\"/" pyproject.toml + sed -i '' "s/\"cua-som>=.*,<.*\"/\"cua-som>=$LATEST_SOM,<$NEXT_SOM_MAJOR.0.0\"/" pyproject.toml + sed -i '' "s/\"cua-core>=.*,<.*\"/\"cua-core>=$LATEST_CORE,<$NEXT_CORE_MAJOR.0.0\"/" pyproject.toml + else + # Linux version + sed -i "s/\"cua-computer>=.*,<.*\"/\"cua-computer>=$LATEST_COMPUTER,<$NEXT_COMPUTER_MAJOR.0.0\"/" pyproject.toml + sed -i "s/\"cua-som>=.*,<.*\"/\"cua-som>=$LATEST_SOM,<$NEXT_SOM_MAJOR.0.0\"/" pyproject.toml + sed -i "s/\"cua-core>=.*,<.*\"/\"cua-core>=$LATEST_CORE,<$NEXT_CORE_MAJOR.0.0\"/" pyproject.toml + fi + + # Display the updated dependencies + echo "Updated dependencies in pyproject.toml:" + grep -E "cua-computer|cua-som|cua-core" pyproject.toml publish: needs: prepare uses: ./.github/workflows/reusable-publish.yml with: package_name: "agent" - package_dir: "libs/agent" + package_dir: "libs/python/agent" version: ${{ needs.prepare.outputs.version }} is_lume_package: false base_package_name: "cua-agent" secrets: PYPI_TOKEN: ${{ secrets.PYPI_TOKEN }} - + set-env-variables: needs: [prepare, publish] runs-on: macos-latest @@ -159,4 +159,4 @@ jobs: run: | echo "COMPUTER_VERSION=${{ needs.prepare.outputs.computer_version }}" >> $GITHUB_ENV echo "SOM_VERSION=${{ needs.prepare.outputs.som_version }}" >> $GITHUB_ENV - echo "CORE_VERSION=${{ needs.prepare.outputs.core_version }}" >> $GITHUB_ENV \ No newline at end of file + echo "CORE_VERSION=${{ needs.prepare.outputs.core_version }}" >> $GITHUB_ENV diff --git a/.github/workflows/publish-computer-server.yml b/.github/workflows/publish-computer-server.yml index 15eca348..01f61530 100644 --- a/.github/workflows/publish-computer-server.yml +++ b/.github/workflows/publish-computer-server.yml @@ -3,17 +3,17 @@ name: Publish Computer Server Package on: push: tags: - - 'computer-server-v*' + - "computer-server-v*" workflow_dispatch: inputs: version: - description: 'Version to publish (without v prefix)' + description: "Version to publish (without v prefix)" required: true - default: '0.1.0' + default: "0.1.0" workflow_call: inputs: version: - description: 'Version to publish' + description: "Version to publish" required: true type: string outputs: @@ -31,50 +31,50 @@ jobs: outputs: version: ${{ steps.get-version.outputs.version }} steps: - - uses: actions/checkout@v4 - - - name: Determine version - id: get-version - run: | - if [ "${{ github.event_name }}" == "push" ]; then - # Extract version from tag (for package-specific tags) - if [[ "${{ github.ref }}" =~ ^refs/tags/computer-server-v([0-9]+\.[0-9]+\.[0-9]+) ]]; then - VERSION=${BASH_REMATCH[1]} - else - echo "Invalid tag format for computer-server" - exit 1 - fi - elif [ "${{ github.event_name }}" == "workflow_dispatch" ]; then - # Use version from workflow dispatch - VERSION=${{ github.event.inputs.version }} - else - # Use version from workflow_call - VERSION=${{ inputs.version }} - fi - echo "VERSION=$VERSION" - echo "version=$VERSION" >> $GITHUB_OUTPUT + - uses: actions/checkout@v4 - - name: Set up Python - uses: actions/setup-python@v4 - with: - python-version: '3.10' + - name: Determine version + id: get-version + run: | + if [ "${{ github.event_name }}" == "push" ]; then + # Extract version from tag (for package-specific tags) + if [[ "${{ github.ref }}" =~ ^refs/tags/computer-server-v([0-9]+\.[0-9]+\.[0-9]+) ]]; then + VERSION=${BASH_REMATCH[1]} + else + echo "Invalid tag format for computer-server" + exit 1 + fi + elif [ "${{ github.event_name }}" == "workflow_dispatch" ]; then + # Use version from workflow dispatch + VERSION=${{ github.event.inputs.version }} + else + # Use version from workflow_call + VERSION=${{ inputs.version }} + fi + echo "VERSION=$VERSION" + echo "version=$VERSION" >> $GITHUB_OUTPUT + + - name: Set up Python + uses: actions/setup-python@v4 + with: + python-version: "3.10" publish: needs: prepare uses: ./.github/workflows/reusable-publish.yml with: package_name: "computer-server" - package_dir: "libs/computer-server" + package_dir: "libs/python/computer-server" version: ${{ needs.prepare.outputs.version }} is_lume_package: false base_package_name: "cua-computer-server" secrets: PYPI_TOKEN: ${{ secrets.PYPI_TOKEN }} - + set-env-variables: needs: [prepare, publish] runs-on: macos-latest steps: - name: Set environment variables for use in other jobs run: | - echo "COMPUTER_VERSION=${{ needs.prepare.outputs.version }}" >> $GITHUB_ENV \ No newline at end of file + echo "COMPUTER_VERSION=${{ needs.prepare.outputs.version }}" >> $GITHUB_ENV diff --git a/.github/workflows/publish-computer.yml b/.github/workflows/publish-computer.yml index 52e5c6ab..df13669d 100644 --- a/.github/workflows/publish-computer.yml +++ b/.github/workflows/publish-computer.yml @@ -3,17 +3,17 @@ name: Publish Computer Package on: push: tags: - - 'computer-v*' + - "computer-v*" workflow_dispatch: inputs: version: - description: 'Version to publish (without v prefix)' + description: "Version to publish (without v prefix)" required: true - default: '0.1.0' + default: "0.1.0" workflow_call: inputs: version: - description: 'Version to publish' + description: "Version to publish" required: true type: string @@ -28,113 +28,113 @@ jobs: version: ${{ steps.get-version.outputs.version }} core_version: ${{ steps.update-deps.outputs.core_version }} steps: - - uses: actions/checkout@v4 - - - name: Determine version - id: get-version - run: | - if [ "${{ github.event_name }}" == "push" ]; then - # Extract version from tag (for package-specific tags) - if [[ "${{ github.ref }}" =~ ^refs/tags/computer-v([0-9]+\.[0-9]+\.[0-9]+) ]]; then - VERSION=${BASH_REMATCH[1]} + - uses: actions/checkout@v4 + + - name: Determine version + id: get-version + run: | + if [ "${{ github.event_name }}" == "push" ]; then + # Extract version from tag (for package-specific tags) + if [[ "${{ github.ref }}" =~ ^refs/tags/computer-v([0-9]+\.[0-9]+\.[0-9]+) ]]; then + VERSION=${BASH_REMATCH[1]} + else + echo "Invalid tag format for computer" + exit 1 + fi + elif [ "${{ github.event_name }}" == "workflow_dispatch" ]; then + # Use version from workflow dispatch + VERSION=${{ github.event.inputs.version }} else - echo "Invalid tag format for computer" - exit 1 + # Use version from workflow_call + VERSION=${{ inputs.version }} fi - elif [ "${{ github.event_name }}" == "workflow_dispatch" ]; then - # Use version from workflow dispatch - VERSION=${{ github.event.inputs.version }} - else - # Use version from workflow_call - VERSION=${{ inputs.version }} - fi - echo "VERSION=$VERSION" - echo "version=$VERSION" >> $GITHUB_OUTPUT + echo "VERSION=$VERSION" + echo "version=$VERSION" >> $GITHUB_OUTPUT - - name: Set up Python - uses: actions/setup-python@v4 - with: - python-version: '3.11' + - name: Set up Python + uses: actions/setup-python@v4 + with: + python-version: "3.11" - - name: Update dependencies to latest versions - id: update-deps - run: | - cd libs/computer/python - # Install required package for PyPI API access - pip install requests - - # Create a more robust Python script for PyPI version checking - cat > get_latest_versions.py << 'EOF' - import requests - import json - import sys + - name: Update dependencies to latest versions + id: update-deps + run: | + cd libs/python/computer + # Install required package for PyPI API access + pip install requests - def get_package_version(package_name, fallback="0.1.0"): - try: - response = requests.get(f'https://pypi.org/pypi/{package_name}/json') - print(f"API Response Status for {package_name}: {response.status_code}", file=sys.stderr) - - if response.status_code != 200: - print(f"API request failed for {package_name}, using fallback version", file=sys.stderr) - return fallback - - data = json.loads(response.text) - - if 'info' not in data: - print(f"Missing 'info' key in API response for {package_name}, using fallback version", file=sys.stderr) - return fallback - - return data['info']['version'] - except Exception as e: - print(f"Error fetching version for {package_name}: {str(e)}", file=sys.stderr) - return fallback + # Create a more robust Python script for PyPI version checking + cat > get_latest_versions.py << 'EOF' + import requests + import json + import sys - # Get latest versions - print(get_package_version('cua-core')) - EOF - - # Execute the script to get the versions - VERSIONS=($(python get_latest_versions.py)) - LATEST_CORE=${VERSIONS[0]} - - echo "Latest cua-core version: $LATEST_CORE" - - # Output the versions for the next job - echo "core_version=$LATEST_CORE" >> $GITHUB_OUTPUT - - # Determine major version for version constraint - CORE_MAJOR=$(echo $LATEST_CORE | cut -d. -f1) - NEXT_CORE_MAJOR=$((CORE_MAJOR + 1)) - - # Update dependencies in pyproject.toml - if [[ "$OSTYPE" == "darwin"* ]]; then - # macOS version of sed needs an empty string for -i - sed -i '' "s/\"cua-core>=.*,<.*\"/\"cua-core>=$LATEST_CORE,<$NEXT_CORE_MAJOR.0.0\"/" pyproject.toml - else - # Linux version - sed -i "s/\"cua-core>=.*,<.*\"/\"cua-core>=$LATEST_CORE,<$NEXT_CORE_MAJOR.0.0\"/" pyproject.toml - fi - - # Display the updated dependencies - echo "Updated dependencies in pyproject.toml:" - grep -E "cua-core" pyproject.toml + def get_package_version(package_name, fallback="0.1.0"): + try: + response = requests.get(f'https://pypi.org/pypi/{package_name}/json') + print(f"API Response Status for {package_name}: {response.status_code}", file=sys.stderr) + + if response.status_code != 200: + print(f"API request failed for {package_name}, using fallback version", file=sys.stderr) + return fallback + + data = json.loads(response.text) + + if 'info' not in data: + print(f"Missing 'info' key in API response for {package_name}, using fallback version", file=sys.stderr) + return fallback + + return data['info']['version'] + except Exception as e: + print(f"Error fetching version for {package_name}: {str(e)}", file=sys.stderr) + return fallback + + # Get latest versions + print(get_package_version('cua-core')) + EOF + + # Execute the script to get the versions + VERSIONS=($(python get_latest_versions.py)) + LATEST_CORE=${VERSIONS[0]} + + echo "Latest cua-core version: $LATEST_CORE" + + # Output the versions for the next job + echo "core_version=$LATEST_CORE" >> $GITHUB_OUTPUT + + # Determine major version for version constraint + CORE_MAJOR=$(echo $LATEST_CORE | cut -d. -f1) + NEXT_CORE_MAJOR=$((CORE_MAJOR + 1)) + + # Update dependencies in pyproject.toml + if [[ "$OSTYPE" == "darwin"* ]]; then + # macOS version of sed needs an empty string for -i + sed -i '' "s/\"cua-core>=.*,<.*\"/\"cua-core>=$LATEST_CORE,<$NEXT_CORE_MAJOR.0.0\"/" pyproject.toml + else + # Linux version + sed -i "s/\"cua-core>=.*,<.*\"/\"cua-core>=$LATEST_CORE,<$NEXT_CORE_MAJOR.0.0\"/" pyproject.toml + fi + + # Display the updated dependencies + echo "Updated dependencies in pyproject.toml:" + grep -E "cua-core" pyproject.toml publish: needs: prepare uses: ./.github/workflows/reusable-publish.yml with: package_name: "computer" - package_dir: "libs/computer/python" + package_dir: "libs/python/computer" version: ${{ needs.prepare.outputs.version }} is_lume_package: false base_package_name: "cua-computer" secrets: PYPI_TOKEN: ${{ secrets.PYPI_TOKEN }} - + set-env-variables: needs: [prepare, publish] runs-on: macos-latest steps: - name: Set environment variables for use in other jobs run: | - echo "CORE_VERSION=${{ needs.prepare.outputs.core_version }}" >> $GITHUB_ENV \ No newline at end of file + echo "CORE_VERSION=${{ needs.prepare.outputs.core_version }}" >> $GITHUB_ENV diff --git a/.github/workflows/publish-core.yml b/.github/workflows/publish-core.yml index 4f868f26..760c055d 100644 --- a/.github/workflows/publish-core.yml +++ b/.github/workflows/publish-core.yml @@ -3,17 +3,17 @@ name: Publish Core Package on: push: tags: - - 'core-v*' + - "core-v*" workflow_dispatch: inputs: version: - description: 'Version to publish (without v prefix)' + description: "Version to publish (without v prefix)" required: true - default: '0.1.0' + default: "0.1.0" workflow_call: inputs: version: - description: 'Version to publish' + description: "Version to publish" required: true type: string @@ -27,37 +27,37 @@ jobs: outputs: version: ${{ steps.get-version.outputs.version }} steps: - - uses: actions/checkout@v4 - - - name: Determine version - id: get-version - run: | - if [ "${{ github.event_name }}" == "push" ]; then - # Extract version from tag (for package-specific tags) - if [[ "${{ github.ref }}" =~ ^refs/tags/core-v([0-9]+\.[0-9]+\.[0-9]+) ]]; then - VERSION=${BASH_REMATCH[1]} + - uses: actions/checkout@v4 + + - name: Determine version + id: get-version + run: | + if [ "${{ github.event_name }}" == "push" ]; then + # Extract version from tag (for package-specific tags) + if [[ "${{ github.ref }}" =~ ^refs/tags/core-v([0-9]+\.[0-9]+\.[0-9]+) ]]; then + VERSION=${BASH_REMATCH[1]} + else + echo "Invalid tag format for core" + exit 1 + fi + elif [ "${{ github.event_name }}" == "workflow_dispatch" ]; then + # Use version from workflow dispatch + VERSION=${{ github.event.inputs.version }} else - echo "Invalid tag format for core" - exit 1 + # Use version from workflow_call + VERSION=${{ inputs.version }} fi - elif [ "${{ github.event_name }}" == "workflow_dispatch" ]; then - # Use version from workflow dispatch - VERSION=${{ github.event.inputs.version }} - else - # Use version from workflow_call - VERSION=${{ inputs.version }} - fi - echo "VERSION=$VERSION" - echo "version=$VERSION" >> $GITHUB_OUTPUT + echo "VERSION=$VERSION" + echo "version=$VERSION" >> $GITHUB_OUTPUT publish: needs: prepare uses: ./.github/workflows/reusable-publish.yml with: package_name: "core" - package_dir: "libs/core" + package_dir: "libs/python/core" version: ${{ needs.prepare.outputs.version }} is_lume_package: false base_package_name: "cua-core" secrets: - PYPI_TOKEN: ${{ secrets.PYPI_TOKEN }} \ No newline at end of file + PYPI_TOKEN: ${{ secrets.PYPI_TOKEN }} diff --git a/.github/workflows/publish-lume.yml b/.github/workflows/publish-lume.yml index ec5e7550..8557d516 100644 --- a/.github/workflows/publish-lume.yml +++ b/.github/workflows/publish-lume.yml @@ -3,17 +3,17 @@ name: Publish Notarized Lume on: push: tags: - - 'lume-v*' + - "lume-v*" workflow_dispatch: inputs: version: - description: 'Version to notarize (without v prefix)' + description: "Version to notarize (without v prefix)" required: true - default: '0.1.0' + default: "0.1.0" workflow_call: inputs: version: - description: 'Version to notarize' + description: "Version to notarize" required: true type: string secrets: @@ -64,7 +64,7 @@ jobs: - name: Create .release directory run: mkdir -p .release - + - name: Set version id: set_version run: | @@ -82,11 +82,11 @@ jobs: echo "Error: No version found in tag or input" exit 1 fi - + # Update version in Main.swift echo "Updating version in Main.swift to $VERSION" - sed -i '' "s/static let current: String = \".*\"/static let current: String = \"$VERSION\"/" libs/lume/src/Main.swift - + sed -i '' "s/static let current: String = \".*\"/static let current: String = \"$VERSION\"/" libs/swift/lume/src/Main.swift + # Set output for later steps echo "version=$VERSION" >> $GITHUB_OUTPUT @@ -106,34 +106,34 @@ jobs: # Import certificates echo $APPLICATION_CERT_BASE64 | base64 --decode > application.p12 echo $INSTALLER_CERT_BASE64 | base64 --decode > installer.p12 - + # Import certificates silently (minimize output) security import application.p12 -k build.keychain -P "$CERT_PASSWORD" -T /usr/bin/codesign -T /usr/bin/pkgbuild > /dev/null 2>&1 security import installer.p12 -k build.keychain -P "$CERT_PASSWORD" -T /usr/bin/codesign -T /usr/bin/pkgbuild > /dev/null 2>&1 - + # Allow codesign to access the certificates (minimal output) security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k "$KEYCHAIN_PASSWORD" build.keychain > /dev/null 2>&1 - + # Verify certificates were imported echo "Verifying signing identities..." CERT_COUNT=$(security find-identity -v -p codesigning build.keychain | grep -c "Developer ID Application" || echo "0") INSTALLER_COUNT=$(security find-identity -v build.keychain | grep -c "Developer ID Installer" || echo "0") - + if [ "$CERT_COUNT" -eq 0 ]; then echo "Error: No Developer ID Application certificate found" security find-identity -v -p codesigning build.keychain exit 1 fi - + if [ "$INSTALLER_COUNT" -eq 0 ]; then echo "Error: No Developer ID Installer certificate found" security find-identity -v build.keychain exit 1 fi - + echo "Found $CERT_COUNT Developer ID Application certificate(s) and $INSTALLER_COUNT Developer ID Installer certificate(s)" echo "All required certificates verified successfully" - + # Clean up certificate files rm application.p12 installer.p12 @@ -147,45 +147,45 @@ jobs: CERT_APPLICATION_NAME: "Developer ID Application: ${{ secrets.DEVELOPER_NAME }} (${{ secrets.TEAM_ID }})" CERT_INSTALLER_NAME: "Developer ID Installer: ${{ secrets.DEVELOPER_NAME }} (${{ secrets.TEAM_ID }})" VERSION: ${{ steps.set_version.outputs.version }} - working-directory: ./libs/lume + working-directory: ./libs/swift/lume run: | # Minimal debug information echo "Starting build process..." echo "Swift version: $(swift --version | head -n 1)" echo "Building version: $VERSION" - + # Ensure .release directory exists mkdir -p .release chmod 755 .release - + # Build the project first (redirect verbose output) echo "Building project..." swift build --configuration release > build.log 2>&1 echo "Build completed." - + # Run the notarization script with LOG_LEVEL env var chmod +x scripts/build/build-release-notarized.sh cd scripts/build LOG_LEVEL=minimal ./build-release-notarized.sh - + # Return to the lume directory cd ../.. - + # Debug: List what files were actually created echo "Files in .release directory:" find .release -type f -name "*.tar.gz" -o -name "*.pkg.tar.gz" - + # Get architecture for output filename ARCH=$(uname -m) OS_IDENTIFIER="darwin-${ARCH}" - + # Output paths for later use echo "tarball_path=.release/lume-${VERSION}-${OS_IDENTIFIER}.tar.gz" >> $GITHUB_OUTPUT echo "pkg_path=.release/lume-${VERSION}-${OS_IDENTIFIER}.pkg.tar.gz" >> $GITHUB_OUTPUT - name: Generate SHA256 Checksums id: generate_checksums - working-directory: ./libs/lume/.release + working-directory: ./libs/swift/lume/.release run: | # Use existing checksums file if it exists, otherwise generate one if [ -f "checksums.txt" ]; then @@ -197,31 +197,31 @@ jobs: shasum -a 256 lume-*.tar.gz >> checksums.txt echo '```' >> checksums.txt fi - + checksums=$(cat checksums.txt) echo "checksums<> $GITHUB_OUTPUT echo "$checksums" >> $GITHUB_OUTPUT echo "EOF" >> $GITHUB_OUTPUT - + # Debug: Show all files in the release directory echo "All files in release directory:" ls -la - name: Create Standard Version Releases - working-directory: ./libs/lume/.release + working-directory: ./libs/swift/lume/.release run: | VERSION=${{ steps.set_version.outputs.version }} ARCH=$(uname -m) OS_IDENTIFIER="darwin-${ARCH}" - + # Create OS-tagged symlinks ln -sf "lume-${VERSION}-${OS_IDENTIFIER}.tar.gz" "lume-darwin.tar.gz" ln -sf "lume-${VERSION}-${OS_IDENTIFIER}.pkg.tar.gz" "lume-darwin.pkg.tar.gz" - + # Create simple symlinks ln -sf "lume-${VERSION}-${OS_IDENTIFIER}.tar.gz" "lume.tar.gz" ln -sf "lume-${VERSION}-${OS_IDENTIFIER}.pkg.tar.gz" "lume.pkg.tar.gz" - + # List all files (including symlinks) echo "Files with symlinks in release directory:" ls -la @@ -230,14 +230,14 @@ jobs: uses: actions/upload-artifact@v4 with: name: lume-notarized-tarball - path: ./libs/lume/${{ steps.build_notarize.outputs.tarball_path }} + path: ./libs/swift/lume/${{ steps.build_notarize.outputs.tarball_path }} if-no-files-found: error - name: Upload Notarized Package (Installer) uses: actions/upload-artifact@v4 with: name: lume-notarized-installer - path: ./libs/lume/${{ steps.build_notarize.outputs.pkg_path }} + path: ./libs/swift/lume/${{ steps.build_notarize.outputs.pkg_path }} if-no-files-found: error - name: Create Release @@ -245,18 +245,18 @@ jobs: uses: softprops/action-gh-release@v1 with: files: | - ./libs/lume/${{ steps.build_notarize.outputs.tarball_path }} - ./libs/lume/${{ steps.build_notarize.outputs.pkg_path }} - ./libs/lume/.release/lume-darwin.tar.gz - ./libs/lume/.release/lume-darwin.pkg.tar.gz - ./libs/lume/.release/lume.tar.gz - ./libs/lume/.release/lume.pkg.tar.gz + ./libs/swift/lume/${{ steps.build_notarize.outputs.tarball_path }} + ./libs/swift/lume/${{ steps.build_notarize.outputs.pkg_path }} + ./libs/swift/lume/.release/lume-darwin.tar.gz + ./libs/swift/lume/.release/lume-darwin.pkg.tar.gz + ./libs/swift/lume/.release/lume.tar.gz + ./libs/swift/lume/.release/lume.pkg.tar.gz body: | ${{ steps.generate_checksums.outputs.checksums }} - + ### Installation with script - /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/trycua/cua/main/libs/lume/scripts/install.sh)" + /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/trycua/cua/main/libs/swift/lume/scripts/install.sh)" ``` generate_release_notes: true - make_latest: true \ No newline at end of file + make_latest: true diff --git a/.github/workflows/publish-mcp-server.yml b/.github/workflows/publish-mcp-server.yml index e6eccd5a..0e84a5a6 100644 --- a/.github/workflows/publish-mcp-server.yml +++ b/.github/workflows/publish-mcp-server.yml @@ -3,17 +3,17 @@ name: Publish MCP Server Package on: push: tags: - - 'mcp-server-v*' + - "mcp-server-v*" workflow_dispatch: inputs: version: - description: 'Version to publish (without v prefix)' + description: "Version to publish (without v prefix)" required: true - default: '0.1.0' + default: "0.1.0" workflow_call: inputs: version: - description: 'Version to publish' + description: "Version to publish" required: true type: string outputs: @@ -33,120 +33,120 @@ jobs: agent_version: ${{ steps.update-deps.outputs.agent_version }} computer_version: ${{ steps.update-deps.outputs.computer_version }} steps: - - uses: actions/checkout@v4 - - - name: Determine version - id: get-version - run: | - if [ "${{ github.event_name }}" == "push" ]; then - # Extract version from tag (for package-specific tags) - if [[ "${{ github.ref }}" =~ ^refs/tags/mcp-server-v([0-9]+\.[0-9]+\.[0-9]+) ]]; then - VERSION=${BASH_REMATCH[1]} + - uses: actions/checkout@v4 + + - name: Determine version + id: get-version + run: | + if [ "${{ github.event_name }}" == "push" ]; then + # Extract version from tag (for package-specific tags) + if [[ "${{ github.ref }}" =~ ^refs/tags/mcp-server-v([0-9]+\.[0-9]+\.[0-9]+) ]]; then + VERSION=${BASH_REMATCH[1]} + else + echo "Invalid tag format for mcp-server" + exit 1 + fi + elif [ "${{ github.event_name }}" == "workflow_dispatch" ]; then + # Use version from workflow dispatch + VERSION=${{ github.event.inputs.version }} else - echo "Invalid tag format for mcp-server" - exit 1 + # Use version from workflow_call + VERSION=${{ inputs.version }} fi - elif [ "${{ github.event_name }}" == "workflow_dispatch" ]; then - # Use version from workflow dispatch - VERSION=${{ github.event.inputs.version }} - else - # Use version from workflow_call - VERSION=${{ inputs.version }} - fi - echo "VERSION=$VERSION" - echo "version=$VERSION" >> $GITHUB_OUTPUT + echo "VERSION=$VERSION" + echo "version=$VERSION" >> $GITHUB_OUTPUT - - name: Set up Python - uses: actions/setup-python@v4 - with: - python-version: '3.11' + - name: Set up Python + uses: actions/setup-python@v4 + with: + python-version: "3.11" - - name: Update dependencies to latest versions - id: update-deps - run: | - cd libs/mcp-server - - # Install required package for PyPI API access - pip install requests - - # Create a Python script for PyPI version checking - cat > get_latest_versions.py << 'EOF' - import requests - import json - import sys + - name: Update dependencies to latest versions + id: update-deps + run: | + cd libs/python/mcp-server - def get_package_version(package_name, fallback="0.1.0"): - try: - response = requests.get(f'https://pypi.org/pypi/{package_name}/json') - print(f"API Response Status for {package_name}: {response.status_code}", file=sys.stderr) - - if response.status_code != 200: - print(f"API request failed for {package_name}, using fallback version", file=sys.stderr) - return fallback - - data = json.loads(response.text) - - if 'info' not in data: - print(f"Missing 'info' key in API response for {package_name}, using fallback version", file=sys.stderr) - return fallback - - return data['info']['version'] - except Exception as e: - print(f"Error fetching version for {package_name}: {str(e)}", file=sys.stderr) - return fallback + # Install required package for PyPI API access + pip install requests - # Get latest versions - print(get_package_version('cua-agent')) - print(get_package_version('cua-computer')) - EOF - - # Execute the script to get the versions - VERSIONS=($(python get_latest_versions.py)) - LATEST_AGENT=${VERSIONS[0]} - LATEST_COMPUTER=${VERSIONS[1]} - - echo "Latest cua-agent version: $LATEST_AGENT" - echo "Latest cua-computer version: $LATEST_COMPUTER" - - # Output the versions for the next job - echo "agent_version=$LATEST_AGENT" >> $GITHUB_OUTPUT - echo "computer_version=$LATEST_COMPUTER" >> $GITHUB_OUTPUT - - # Determine major version for version constraint - AGENT_MAJOR=$(echo $LATEST_AGENT | cut -d. -f1) - COMPUTER_MAJOR=$(echo $LATEST_COMPUTER | cut -d. -f1) - - NEXT_AGENT_MAJOR=$((AGENT_MAJOR + 1)) - NEXT_COMPUTER_MAJOR=$((COMPUTER_MAJOR + 1)) - - # Update dependencies in pyproject.toml - if [[ "$OSTYPE" == "darwin"* ]]; then - # macOS version of sed needs an empty string for -i - # Update cua-agent with all extras - sed -i '' "s/\"cua-agent\[all\]>=.*,<.*\"/\"cua-agent[all]>=$LATEST_AGENT,<$NEXT_AGENT_MAJOR.0.0\"/" pyproject.toml - sed -i '' "s/\"cua-computer>=.*,<.*\"/\"cua-computer>=$LATEST_COMPUTER,<$NEXT_COMPUTER_MAJOR.0.0\"/" pyproject.toml - else - # Linux version - sed -i "s/\"cua-agent\[all\]>=.*,<.*\"/\"cua-agent[all]>=$LATEST_AGENT,<$NEXT_AGENT_MAJOR.0.0\"/" pyproject.toml - sed -i "s/\"cua-computer>=.*,<.*\"/\"cua-computer>=$LATEST_COMPUTER,<$NEXT_COMPUTER_MAJOR.0.0\"/" pyproject.toml - fi - - # Display the updated dependencies - echo "Updated dependencies in pyproject.toml:" - grep -E "cua-agent|cua-computer" pyproject.toml + # Create a Python script for PyPI version checking + cat > get_latest_versions.py << 'EOF' + import requests + import json + import sys + + def get_package_version(package_name, fallback="0.1.0"): + try: + response = requests.get(f'https://pypi.org/pypi/{package_name}/json') + print(f"API Response Status for {package_name}: {response.status_code}", file=sys.stderr) + + if response.status_code != 200: + print(f"API request failed for {package_name}, using fallback version", file=sys.stderr) + return fallback + + data = json.loads(response.text) + + if 'info' not in data: + print(f"Missing 'info' key in API response for {package_name}, using fallback version", file=sys.stderr) + return fallback + + return data['info']['version'] + except Exception as e: + print(f"Error fetching version for {package_name}: {str(e)}", file=sys.stderr) + return fallback + + # Get latest versions + print(get_package_version('cua-agent')) + print(get_package_version('cua-computer')) + EOF + + # Execute the script to get the versions + VERSIONS=($(python get_latest_versions.py)) + LATEST_AGENT=${VERSIONS[0]} + LATEST_COMPUTER=${VERSIONS[1]} + + echo "Latest cua-agent version: $LATEST_AGENT" + echo "Latest cua-computer version: $LATEST_COMPUTER" + + # Output the versions for the next job + echo "agent_version=$LATEST_AGENT" >> $GITHUB_OUTPUT + echo "computer_version=$LATEST_COMPUTER" >> $GITHUB_OUTPUT + + # Determine major version for version constraint + AGENT_MAJOR=$(echo $LATEST_AGENT | cut -d. -f1) + COMPUTER_MAJOR=$(echo $LATEST_COMPUTER | cut -d. -f1) + + NEXT_AGENT_MAJOR=$((AGENT_MAJOR + 1)) + NEXT_COMPUTER_MAJOR=$((COMPUTER_MAJOR + 1)) + + # Update dependencies in pyproject.toml + if [[ "$OSTYPE" == "darwin"* ]]; then + # macOS version of sed needs an empty string for -i + # Update cua-agent with all extras + sed -i '' "s/\"cua-agent\[all\]>=.*,<.*\"/\"cua-agent[all]>=$LATEST_AGENT,<$NEXT_AGENT_MAJOR.0.0\"/" pyproject.toml + sed -i '' "s/\"cua-computer>=.*,<.*\"/\"cua-computer>=$LATEST_COMPUTER,<$NEXT_COMPUTER_MAJOR.0.0\"/" pyproject.toml + else + # Linux version + sed -i "s/\"cua-agent\[all\]>=.*,<.*\"/\"cua-agent[all]>=$LATEST_AGENT,<$NEXT_AGENT_MAJOR.0.0\"/" pyproject.toml + sed -i "s/\"cua-computer>=.*,<.*\"/\"cua-computer>=$LATEST_COMPUTER,<$NEXT_COMPUTER_MAJOR.0.0\"/" pyproject.toml + fi + + # Display the updated dependencies + echo "Updated dependencies in pyproject.toml:" + grep -E "cua-agent|cua-computer" pyproject.toml publish: needs: prepare uses: ./.github/workflows/reusable-publish.yml with: package_name: "mcp-server" - package_dir: "libs/mcp-server" + package_dir: "libs/python/mcp-server" version: ${{ needs.prepare.outputs.version }} is_lume_package: false base_package_name: "cua-mcp-server" secrets: PYPI_TOKEN: ${{ secrets.PYPI_TOKEN }} - + set-env-variables: needs: [prepare, publish] runs-on: macos-latest @@ -154,4 +154,4 @@ jobs: - name: Set environment variables for use in other jobs run: | echo "AGENT_VERSION=${{ needs.prepare.outputs.agent_version }}" >> $GITHUB_ENV - echo "COMPUTER_VERSION=${{ needs.prepare.outputs.computer_version }}" >> $GITHUB_ENV \ No newline at end of file + echo "COMPUTER_VERSION=${{ needs.prepare.outputs.computer_version }}" >> $GITHUB_ENV diff --git a/.github/workflows/publish-pylume.yml b/.github/workflows/publish-pylume.yml index c5bd4f6f..e9e52539 100644 --- a/.github/workflows/publish-pylume.yml +++ b/.github/workflows/publish-pylume.yml @@ -3,17 +3,17 @@ name: Publish Pylume Package on: push: tags: - - 'pylume-v*' + - "pylume-v*" workflow_dispatch: inputs: version: - description: 'Version to publish (without v prefix)' + description: "Version to publish (without v prefix)" required: true - default: '0.1.0' + default: "0.1.0" workflow_call: inputs: version: - description: 'Version to publish' + description: "Version to publish" required: true type: string outputs: @@ -31,52 +31,52 @@ jobs: outputs: version: ${{ steps.get-version.outputs.version }} steps: - - uses: actions/checkout@v4 - - - name: Determine version - id: get-version - run: | - if [ "${{ github.event_name }}" == "push" ]; then - # Extract version from tag (for package-specific tags) - if [[ "${{ github.ref }}" =~ ^refs/tags/pylume-v([0-9]+\.[0-9]+\.[0-9]+) ]]; then - VERSION=${BASH_REMATCH[1]} + - uses: actions/checkout@v4 + + - name: Determine version + id: get-version + run: | + if [ "${{ github.event_name }}" == "push" ]; then + # Extract version from tag (for package-specific tags) + if [[ "${{ github.ref }}" =~ ^refs/tags/pylume-v([0-9]+\.[0-9]+\.[0-9]+) ]]; then + VERSION=${BASH_REMATCH[1]} + else + echo "Invalid tag format for pylume" + exit 1 + fi + elif [ "${{ github.event_name }}" == "workflow_dispatch" ]; then + # Use version from workflow dispatch + VERSION=${{ github.event.inputs.version }} else - echo "Invalid tag format for pylume" - exit 1 + # Use version from workflow_call + VERSION=${{ inputs.version }} fi - elif [ "${{ github.event_name }}" == "workflow_dispatch" ]; then - # Use version from workflow dispatch - VERSION=${{ github.event.inputs.version }} - else - # Use version from workflow_call - VERSION=${{ inputs.version }} - fi - echo "VERSION=$VERSION" - echo "version=$VERSION" >> $GITHUB_OUTPUT + echo "VERSION=$VERSION" + echo "version=$VERSION" >> $GITHUB_OUTPUT validate-version: runs-on: macos-latest needs: determine-version steps: - - uses: actions/checkout@v4 - - name: Validate version - id: validate-version - run: | - CODE_VERSION=$(grep '__version__' libs/pylume/pylume/__init__.py | cut -d'"' -f2) - if [ "${{ needs.determine-version.outputs.version }}" != "$CODE_VERSION" ]; then - echo "Version mismatch: expected $CODE_VERSION, got ${{ needs.determine-version.outputs.version }}" - exit 1 - fi - echo "Version validated: $CODE_VERSION" + - uses: actions/checkout@v4 + - name: Validate version + id: validate-version + run: | + CODE_VERSION=$(grep '__version__' libs/python/pylume/pylume/__init__.py | cut -d'"' -f2) + if [ "${{ needs.determine-version.outputs.version }}" != "$CODE_VERSION" ]; then + echo "Version mismatch: expected $CODE_VERSION, got ${{ needs.determine-version.outputs.version }}" + exit 1 + fi + echo "Version validated: $CODE_VERSION" publish: needs: determine-version uses: ./.github/workflows/reusable-publish.yml with: package_name: "pylume" - package_dir: "libs/pylume" + package_dir: "libs/python/pylume" version: ${{ needs.determine-version.outputs.version }} is_lume_package: true base_package_name: "pylume" secrets: - PYPI_TOKEN: ${{ secrets.PYPI_TOKEN }} \ No newline at end of file + PYPI_TOKEN: ${{ secrets.PYPI_TOKEN }} diff --git a/.github/workflows/publish-som.yml b/.github/workflows/publish-som.yml index b1d53ac8..a5ac30e9 100644 --- a/.github/workflows/publish-som.yml +++ b/.github/workflows/publish-som.yml @@ -3,17 +3,17 @@ name: Publish SOM Package on: push: tags: - - 'som-v*' + - "som-v*" workflow_dispatch: inputs: version: - description: 'Version to publish (without v prefix)' + description: "Version to publish (without v prefix)" required: true - default: '0.1.0' + default: "0.1.0" workflow_call: inputs: version: - description: 'Version to publish' + description: "Version to publish" required: true type: string outputs: @@ -31,37 +31,37 @@ jobs: outputs: version: ${{ steps.get-version.outputs.version }} steps: - - uses: actions/checkout@v4 - - - name: Determine version - id: get-version - run: | - if [ "${{ github.event_name }}" == "push" ]; then - # Extract version from tag (for package-specific tags) - if [[ "${{ github.ref }}" =~ ^refs/tags/som-v([0-9]+\.[0-9]+\.[0-9]+) ]]; then - VERSION=${BASH_REMATCH[1]} + - uses: actions/checkout@v4 + + - name: Determine version + id: get-version + run: | + if [ "${{ github.event_name }}" == "push" ]; then + # Extract version from tag (for package-specific tags) + if [[ "${{ github.ref }}" =~ ^refs/tags/som-v([0-9]+\.[0-9]+\.[0-9]+) ]]; then + VERSION=${BASH_REMATCH[1]} + else + echo "Invalid tag format for som" + exit 1 + fi + elif [ "${{ github.event_name }}" == "workflow_dispatch" ]; then + # Use version from workflow dispatch + VERSION=${{ github.event.inputs.version }} else - echo "Invalid tag format for som" - exit 1 + # Use version from workflow_call + VERSION=${{ inputs.version }} fi - elif [ "${{ github.event_name }}" == "workflow_dispatch" ]; then - # Use version from workflow dispatch - VERSION=${{ github.event.inputs.version }} - else - # Use version from workflow_call - VERSION=${{ inputs.version }} - fi - echo "VERSION=$VERSION" - echo "version=$VERSION" >> $GITHUB_OUTPUT + echo "VERSION=$VERSION" + echo "version=$VERSION" >> $GITHUB_OUTPUT publish: needs: determine-version uses: ./.github/workflows/reusable-publish.yml with: package_name: "som" - package_dir: "libs/som" + package_dir: "libs/python/som" version: ${{ needs.determine-version.outputs.version }} is_lume_package: false base_package_name: "cua-som" secrets: - PYPI_TOKEN: ${{ secrets.PYPI_TOKEN }} \ No newline at end of file + PYPI_TOKEN: ${{ secrets.PYPI_TOKEN }} diff --git a/.github/workflows/reusable-publish.yml b/.github/workflows/reusable-publish.yml index 8856b60d..f1eb045e 100644 --- a/.github/workflows/reusable-publish.yml +++ b/.github/workflows/reusable-publish.yml @@ -4,28 +4,28 @@ on: workflow_call: inputs: package_name: - description: 'Name of the package (e.g. pylume, computer, agent)' + description: "Name of the package (e.g. pylume, computer, agent)" required: true type: string package_dir: - description: 'Directory containing the package relative to workspace root (e.g. libs/pylume)' + description: "Directory containing the package relative to workspace root (e.g. libs/python/pylume)" required: true type: string version: - description: 'Version to publish' + description: "Version to publish" required: true type: string is_lume_package: - description: 'Whether this package includes the lume binary' + description: "Whether this package includes the lume binary" required: false type: boolean default: false base_package_name: - description: 'PyPI package name (e.g. pylume, cua-agent)' + description: "PyPI package name (e.g. pylume, cua-agent)" required: true type: string make_latest: - description: 'Whether to mark this release as latest (should only be true for lume)' + description: "Whether to mark this release as latest (should only be true for lume)" required: false type: boolean default: false @@ -41,240 +41,240 @@ jobs: build-and-publish: runs-on: macos-latest permissions: - contents: write # This permission is needed for creating releases + contents: write # This permission is needed for creating releases outputs: version: ${{ steps.set-version.outputs.version }} steps: - - uses: actions/checkout@v4 - with: - fetch-depth: 0 # Full history for release creation - - - name: Set up Python - uses: actions/setup-python@v4 - with: - python-version: '3.11' - - - name: Create root pdm.lock file - run: | - # Create an empty pdm.lock file in the root - touch pdm.lock - - - name: Install PDM - uses: pdm-project/setup-pdm@v3 - with: - python-version: '3.11' - cache: true - - - name: Set version - id: set-version - run: | - echo "VERSION=${{ inputs.version }}" >> $GITHUB_ENV - echo "version=${{ inputs.version }}" >> $GITHUB_OUTPUT + - uses: actions/checkout@v4 + with: + fetch-depth: 0 # Full history for release creation - - name: Initialize PDM in package directory - run: | - # Make sure we're working with a properly initialized PDM project - cd ${{ inputs.package_dir }} - - # Create pdm.lock if it doesn't exist - if [ ! -f "pdm.lock" ]; then - echo "No pdm.lock found, initializing PDM project..." - pdm lock - fi - - - name: Set version in package - run: | - cd ${{ inputs.package_dir }} - # Replace pdm bump with direct edit of pyproject.toml - if [[ "$OSTYPE" == "darwin"* ]]; then - # macOS version of sed needs an empty string for -i - sed -i '' "s/version = \".*\"/version = \"$VERSION\"/" pyproject.toml - else - # Linux version - sed -i "s/version = \".*\"/version = \"$VERSION\"/" pyproject.toml - fi - # Verify version was updated - echo "Updated version in pyproject.toml:" - grep "version =" pyproject.toml - - # Conditional step for lume binary download (only for pylume package) - - name: Download and setup lume binary - if: inputs.is_lume_package - run: | - # Create a temporary directory for extraction - mkdir -p temp_lume - - # Download the latest lume release directly - echo "Downloading latest lume version..." - curl -sL "https://github.com/trycua/lume/releases/latest/download/lume.tar.gz" -o temp_lume/lume.tar.gz - - # Extract the tar file (ignore ownership and suppress warnings) - cd temp_lume && tar --no-same-owner -xzf lume.tar.gz - - # Make the binary executable - chmod +x lume - - # Copy the lume binary to the correct location in the pylume package - mkdir -p "${GITHUB_WORKSPACE}/${{ inputs.package_dir }}/pylume" - cp lume "${GITHUB_WORKSPACE}/${{ inputs.package_dir }}/pylume/lume" - - # Verify the binary exists and is executable - test -x "${GITHUB_WORKSPACE}/${{ inputs.package_dir }}/pylume/lume" || { echo "lume binary not found or not executable"; exit 1; } - - # Get the version from the downloaded binary for reference - LUME_VERSION=$(./lume --version | grep -oE '[0-9]+\.[0-9]+\.[0-9]+' || echo "unknown") - echo "Using lume version: $LUME_VERSION" - - # Cleanup - cd "${GITHUB_WORKSPACE}" && rm -rf temp_lume - - # Save the lume version for reference - echo "LUME_VERSION=${LUME_VERSION}" >> $GITHUB_ENV - - - name: Build and publish - env: - PYPI_TOKEN: ${{ secrets.PYPI_TOKEN }} - run: | - cd ${{ inputs.package_dir }} - # Build with PDM - pdm build - - # For pylume package, verify the binary is in the wheel - if [ "${{ inputs.is_lume_package }}" = "true" ]; then - python -m pip install wheel - wheel unpack dist/*.whl --dest temp_wheel - echo "Listing contents of wheel directory:" - find temp_wheel -type f - test -f temp_wheel/pylume-*/pylume/lume || { echo "lume binary not found in wheel"; exit 1; } - rm -rf temp_wheel - echo "Publishing ${{ inputs.base_package_name }} ${VERSION} with lume ${LUME_VERSION}" - else - echo "Publishing ${{ inputs.base_package_name }} ${VERSION}" - fi - - # Install and use twine directly instead of PDM publish - echo "Installing twine for direct publishing..." - pip install twine - - echo "Publishing to PyPI using twine..." - TWINE_USERNAME="__token__" TWINE_PASSWORD="$PYPI_TOKEN" python -m twine upload dist/* - - # Save the wheel file path for the release - WHEEL_FILE=$(ls dist/*.whl | head -1) - echo "WHEEL_FILE=${WHEEL_FILE}" >> $GITHUB_ENV - - - name: Prepare Simple Release Notes - if: startsWith(github.ref, 'refs/tags/') - run: | - # Create release notes based on package type - echo "# ${{ inputs.base_package_name }} v${VERSION}" > release_notes.md - echo "" >> release_notes.md - - if [ "${{ inputs.package_name }}" = "pylume" ]; then - echo "## Python SDK for lume - run macOS and Linux VMs on Apple Silicon" >> release_notes.md + - name: Set up Python + uses: actions/setup-python@v4 + with: + python-version: "3.11" + + - name: Create root pdm.lock file + run: | + # Create an empty pdm.lock file in the root + touch pdm.lock + + - name: Install PDM + uses: pdm-project/setup-pdm@v3 + with: + python-version: "3.11" + cache: true + + - name: Set version + id: set-version + run: | + echo "VERSION=${{ inputs.version }}" >> $GITHUB_ENV + echo "version=${{ inputs.version }}" >> $GITHUB_OUTPUT + + - name: Initialize PDM in package directory + run: | + # Make sure we're working with a properly initialized PDM project + cd ${{ inputs.package_dir }} + + # Create pdm.lock if it doesn't exist + if [ ! -f "pdm.lock" ]; then + echo "No pdm.lock found, initializing PDM project..." + pdm lock + fi + + - name: Set version in package + run: | + cd ${{ inputs.package_dir }} + # Replace pdm bump with direct edit of pyproject.toml + if [[ "$OSTYPE" == "darwin"* ]]; then + # macOS version of sed needs an empty string for -i + sed -i '' "s/version = \".*\"/version = \"$VERSION\"/" pyproject.toml + else + # Linux version + sed -i "s/version = \".*\"/version = \"$VERSION\"/" pyproject.toml + fi + # Verify version was updated + echo "Updated version in pyproject.toml:" + grep "version =" pyproject.toml + + # Conditional step for lume binary download (only for pylume package) + - name: Download and setup lume binary + if: inputs.is_lume_package + run: | + # Create a temporary directory for extraction + mkdir -p temp_lume + + # Download the latest lume release directly + echo "Downloading latest lume version..." + curl -sL "https://github.com/trycua/lume/releases/latest/download/lume.tar.gz" -o temp_lume/lume.tar.gz + + # Extract the tar file (ignore ownership and suppress warnings) + cd temp_lume && tar --no-same-owner -xzf lume.tar.gz + + # Make the binary executable + chmod +x lume + + # Copy the lume binary to the correct location in the pylume package + mkdir -p "${GITHUB_WORKSPACE}/${{ inputs.package_dir }}/pylume" + cp lume "${GITHUB_WORKSPACE}/${{ inputs.package_dir }}/pylume/lume" + + # Verify the binary exists and is executable + test -x "${GITHUB_WORKSPACE}/${{ inputs.package_dir }}/pylume/lume" || { echo "lume binary not found or not executable"; exit 1; } + + # Get the version from the downloaded binary for reference + LUME_VERSION=$(./lume --version | grep -oE '[0-9]+\.[0-9]+\.[0-9]+' || echo "unknown") + echo "Using lume version: $LUME_VERSION" + + # Cleanup + cd "${GITHUB_WORKSPACE}" && rm -rf temp_lume + + # Save the lume version for reference + echo "LUME_VERSION=${LUME_VERSION}" >> $GITHUB_ENV + + - name: Build and publish + env: + PYPI_TOKEN: ${{ secrets.PYPI_TOKEN }} + run: | + cd ${{ inputs.package_dir }} + # Build with PDM + pdm build + + # For pylume package, verify the binary is in the wheel + if [ "${{ inputs.is_lume_package }}" = "true" ]; then + python -m pip install wheel + wheel unpack dist/*.whl --dest temp_wheel + echo "Listing contents of wheel directory:" + find temp_wheel -type f + test -f temp_wheel/pylume-*/pylume/lume || { echo "lume binary not found in wheel"; exit 1; } + rm -rf temp_wheel + echo "Publishing ${{ inputs.base_package_name }} ${VERSION} with lume ${LUME_VERSION}" + else + echo "Publishing ${{ inputs.base_package_name }} ${VERSION}" + fi + + # Install and use twine directly instead of PDM publish + echo "Installing twine for direct publishing..." + pip install twine + + echo "Publishing to PyPI using twine..." + TWINE_USERNAME="__token__" TWINE_PASSWORD="$PYPI_TOKEN" python -m twine upload dist/* + + # Save the wheel file path for the release + WHEEL_FILE=$(ls dist/*.whl | head -1) + echo "WHEEL_FILE=${WHEEL_FILE}" >> $GITHUB_ENV + + - name: Prepare Simple Release Notes + if: startsWith(github.ref, 'refs/tags/') + run: | + # Create release notes based on package type + echo "# ${{ inputs.base_package_name }} v${VERSION}" > release_notes.md echo "" >> release_notes.md - echo "This package provides Python bindings for the lume virtualization tool." >> release_notes.md - echo "" >> release_notes.md - echo "## Dependencies" >> release_notes.md - echo "* lume binary: v${LUME_VERSION}" >> release_notes.md - elif [ "${{ inputs.package_name }}" = "computer" ]; then - echo "## Computer control library for the Computer Universal Automation (CUA) project" >> release_notes.md - echo "" >> release_notes.md - echo "## Dependencies" >> release_notes.md - echo "* pylume: ${PYLUME_VERSION:-latest}" >> release_notes.md - elif [ "${{ inputs.package_name }}" = "agent" ]; then - echo "## Dependencies" >> release_notes.md - echo "* cua-computer: ${COMPUTER_VERSION:-latest}" >> release_notes.md - echo "* cua-som: ${SOM_VERSION:-latest}" >> release_notes.md - echo "" >> release_notes.md - echo "## Installation Options" >> release_notes.md - echo "" >> release_notes.md - echo "### Basic installation with Anthropic" >> release_notes.md - echo '```bash' >> release_notes.md - echo "pip install cua-agent[anthropic]==${VERSION}" >> release_notes.md - echo '```' >> release_notes.md - echo "" >> release_notes.md - echo "### With SOM (recommended)" >> release_notes.md - echo '```bash' >> release_notes.md - echo "pip install cua-agent[som]==${VERSION}" >> release_notes.md - echo '```' >> release_notes.md - echo "" >> release_notes.md - echo "### All features" >> release_notes.md - echo '```bash' >> release_notes.md - echo "pip install cua-agent[all]==${VERSION}" >> release_notes.md - echo '```' >> release_notes.md - elif [ "${{ inputs.package_name }}" = "som" ]; then - echo "## Computer Vision and OCR library for detecting and analyzing UI elements" >> release_notes.md - echo "" >> release_notes.md - echo "This package provides enhanced UI understanding capabilities through computer vision and OCR." >> release_notes.md - elif [ "${{ inputs.package_name }}" = "computer-server" ]; then - echo "## Computer Server for the Computer Universal Automation (CUA) project" >> release_notes.md - echo "" >> release_notes.md - echo "A FastAPI-based server implementation for computer control." >> release_notes.md - echo "" >> release_notes.md - echo "## Dependencies" >> release_notes.md - echo "* cua-computer: ${COMPUTER_VERSION:-latest}" >> release_notes.md - echo "" >> release_notes.md - echo "## Usage" >> release_notes.md - echo '```bash' >> release_notes.md - echo "# Run the server" >> release_notes.md - echo "cua-computer-server" >> release_notes.md - echo '```' >> release_notes.md - elif [ "${{ inputs.package_name }}" = "mcp-server" ]; then - echo "## MCP Server for the Computer-Use Agent (CUA)" >> release_notes.md - echo "" >> release_notes.md - echo "This package provides MCP (Model Context Protocol) integration for CUA agents, allowing them to be used with Claude Desktop, Cursor, and other MCP clients." >> release_notes.md - echo "" >> release_notes.md - echo "## Dependencies" >> release_notes.md - echo "* cua-computer: ${COMPUTER_VERSION:-latest}" >> release_notes.md - echo "* cua-agent: ${AGENT_VERSION:-latest}" >> release_notes.md - echo "" >> release_notes.md - echo "## Usage" >> release_notes.md - echo '```bash' >> release_notes.md - echo "# Run the MCP server directly" >> release_notes.md - echo "cua-mcp-server" >> release_notes.md - echo '```' >> release_notes.md - echo "" >> release_notes.md - echo "## Claude Desktop Integration" >> release_notes.md - echo "Add to your Claude Desktop configuration (~/.config/claude-desktop/claude_desktop_config.json or OS-specific location):" >> release_notes.md - echo '```json' >> release_notes.md - echo '"mcpServers": {' >> release_notes.md - echo ' "cua-agent": {' >> release_notes.md - echo ' "command": "cua-mcp-server",' >> release_notes.md - echo ' "args": [],' >> release_notes.md - echo ' "env": {' >> release_notes.md - echo ' "CUA_AGENT_LOOP": "OMNI",' >> release_notes.md - echo ' "CUA_MODEL_PROVIDER": "ANTHROPIC",' >> release_notes.md - echo ' "CUA_MODEL_NAME": "claude-3-opus-20240229",' >> release_notes.md - echo ' "ANTHROPIC_API_KEY": "your-api-key",' >> release_notes.md - echo ' "PYTHONIOENCODING": "utf-8"' >> release_notes.md - echo ' }' >> release_notes.md - echo ' }' >> release_notes.md - echo '}' >> release_notes.md - echo '```' >> release_notes.md - fi - - # Add installation section if not agent (which has its own installation section) - if [ "${{ inputs.package_name }}" != "agent" ]; then - echo "" >> release_notes.md - echo "## Installation" >> release_notes.md - echo '```bash' >> release_notes.md - echo "pip install ${{ inputs.base_package_name }}==${VERSION}" >> release_notes.md - echo '```' >> release_notes.md - fi - - echo "Release notes created:" - cat release_notes.md - - - name: Create GitHub Release - uses: softprops/action-gh-release@v2 - if: startsWith(github.ref, 'refs/tags/') - with: - name: "${{ inputs.base_package_name }} v${{ env.VERSION }}" - body_path: release_notes.md - files: ${{ inputs.package_dir }}/${{ env.WHEEL_FILE }} - draft: false - prerelease: false - make_latest: ${{ inputs.package_name == 'lume' }} - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} \ No newline at end of file + + if [ "${{ inputs.package_name }}" = "pylume" ]; then + echo "## Python SDK for lume - run macOS and Linux VMs on Apple Silicon" >> release_notes.md + echo "" >> release_notes.md + echo "This package provides Python bindings for the lume virtualization tool." >> release_notes.md + echo "" >> release_notes.md + echo "## Dependencies" >> release_notes.md + echo "* lume binary: v${LUME_VERSION}" >> release_notes.md + elif [ "${{ inputs.package_name }}" = "computer" ]; then + echo "## Computer control library for the Computer Universal Automation (CUA) project" >> release_notes.md + echo "" >> release_notes.md + echo "## Dependencies" >> release_notes.md + echo "* pylume: ${PYLUME_VERSION:-latest}" >> release_notes.md + elif [ "${{ inputs.package_name }}" = "agent" ]; then + echo "## Dependencies" >> release_notes.md + echo "* cua-computer: ${COMPUTER_VERSION:-latest}" >> release_notes.md + echo "* cua-som: ${SOM_VERSION:-latest}" >> release_notes.md + echo "" >> release_notes.md + echo "## Installation Options" >> release_notes.md + echo "" >> release_notes.md + echo "### Basic installation with Anthropic" >> release_notes.md + echo '```bash' >> release_notes.md + echo "pip install cua-agent[anthropic]==${VERSION}" >> release_notes.md + echo '```' >> release_notes.md + echo "" >> release_notes.md + echo "### With SOM (recommended)" >> release_notes.md + echo '```bash' >> release_notes.md + echo "pip install cua-agent[som]==${VERSION}" >> release_notes.md + echo '```' >> release_notes.md + echo "" >> release_notes.md + echo "### All features" >> release_notes.md + echo '```bash' >> release_notes.md + echo "pip install cua-agent[all]==${VERSION}" >> release_notes.md + echo '```' >> release_notes.md + elif [ "${{ inputs.package_name }}" = "som" ]; then + echo "## Computer Vision and OCR library for detecting and analyzing UI elements" >> release_notes.md + echo "" >> release_notes.md + echo "This package provides enhanced UI understanding capabilities through computer vision and OCR." >> release_notes.md + elif [ "${{ inputs.package_name }}" = "computer-server" ]; then + echo "## Computer Server for the Computer Universal Automation (CUA) project" >> release_notes.md + echo "" >> release_notes.md + echo "A FastAPI-based server implementation for computer control." >> release_notes.md + echo "" >> release_notes.md + echo "## Dependencies" >> release_notes.md + echo "* cua-computer: ${COMPUTER_VERSION:-latest}" >> release_notes.md + echo "" >> release_notes.md + echo "## Usage" >> release_notes.md + echo '```bash' >> release_notes.md + echo "# Run the server" >> release_notes.md + echo "cua-computer-server" >> release_notes.md + echo '```' >> release_notes.md + elif [ "${{ inputs.package_name }}" = "mcp-server" ]; then + echo "## MCP Server for the Computer-Use Agent (CUA)" >> release_notes.md + echo "" >> release_notes.md + echo "This package provides MCP (Model Context Protocol) integration for CUA agents, allowing them to be used with Claude Desktop, Cursor, and other MCP clients." >> release_notes.md + echo "" >> release_notes.md + echo "## Dependencies" >> release_notes.md + echo "* cua-computer: ${COMPUTER_VERSION:-latest}" >> release_notes.md + echo "* cua-agent: ${AGENT_VERSION:-latest}" >> release_notes.md + echo "" >> release_notes.md + echo "## Usage" >> release_notes.md + echo '```bash' >> release_notes.md + echo "# Run the MCP server directly" >> release_notes.md + echo "cua-mcp-server" >> release_notes.md + echo '```' >> release_notes.md + echo "" >> release_notes.md + echo "## Claude Desktop Integration" >> release_notes.md + echo "Add to your Claude Desktop configuration (~/.config/claude-desktop/claude_desktop_config.json or OS-specific location):" >> release_notes.md + echo '```json' >> release_notes.md + echo '"mcpServers": {' >> release_notes.md + echo ' "cua-agent": {' >> release_notes.md + echo ' "command": "cua-mcp-server",' >> release_notes.md + echo ' "args": [],' >> release_notes.md + echo ' "env": {' >> release_notes.md + echo ' "CUA_AGENT_LOOP": "OMNI",' >> release_notes.md + echo ' "CUA_MODEL_PROVIDER": "ANTHROPIC",' >> release_notes.md + echo ' "CUA_MODEL_NAME": "claude-3-opus-20240229",' >> release_notes.md + echo ' "ANTHROPIC_API_KEY": "your-api-key",' >> release_notes.md + echo ' "PYTHONIOENCODING": "utf-8"' >> release_notes.md + echo ' }' >> release_notes.md + echo ' }' >> release_notes.md + echo '}' >> release_notes.md + echo '```' >> release_notes.md + fi + + # Add installation section if not agent (which has its own installation section) + if [ "${{ inputs.package_name }}" != "agent" ]; then + echo "" >> release_notes.md + echo "## Installation" >> release_notes.md + echo '```bash' >> release_notes.md + echo "pip install ${{ inputs.base_package_name }}==${VERSION}" >> release_notes.md + echo '```' >> release_notes.md + fi + + echo "Release notes created:" + cat release_notes.md + + - name: Create GitHub Release + uses: softprops/action-gh-release@v2 + if: startsWith(github.ref, 'refs/tags/') + with: + name: "${{ inputs.base_package_name }} v${{ env.VERSION }}" + body_path: release_notes.md + files: ${{ inputs.package_dir }}/${{ env.WHEEL_FILE }} + draft: false + prerelease: false + make_latest: ${{ inputs.package_name == 'lume' }} + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/libs/python/lumier/.dockerignore b/libs/bash/lumier/.dockerignore similarity index 100% rename from libs/python/lumier/.dockerignore rename to libs/bash/lumier/.dockerignore diff --git a/libs/python/lumier/Dockerfile b/libs/bash/lumier/Dockerfile similarity index 100% rename from libs/python/lumier/Dockerfile rename to libs/bash/lumier/Dockerfile diff --git a/libs/python/lumier/README.md b/libs/bash/lumier/README.md similarity index 100% rename from libs/python/lumier/README.md rename to libs/bash/lumier/README.md diff --git a/libs/python/lumier/src/bin/entry.sh b/libs/bash/lumier/src/bin/entry.sh similarity index 100% rename from libs/python/lumier/src/bin/entry.sh rename to libs/bash/lumier/src/bin/entry.sh diff --git a/libs/python/lumier/src/config/constants.sh b/libs/bash/lumier/src/config/constants.sh similarity index 100% rename from libs/python/lumier/src/config/constants.sh rename to libs/bash/lumier/src/config/constants.sh diff --git a/libs/python/lumier/src/hooks/on-logon.sh b/libs/bash/lumier/src/hooks/on-logon.sh similarity index 100% rename from libs/python/lumier/src/hooks/on-logon.sh rename to libs/bash/lumier/src/hooks/on-logon.sh diff --git a/libs/python/lumier/src/lib/utils.sh b/libs/bash/lumier/src/lib/utils.sh similarity index 100% rename from libs/python/lumier/src/lib/utils.sh rename to libs/bash/lumier/src/lib/utils.sh diff --git a/libs/python/lumier/src/lib/vm.sh b/libs/bash/lumier/src/lib/vm.sh similarity index 100% rename from libs/python/lumier/src/lib/vm.sh rename to libs/bash/lumier/src/lib/vm.sh diff --git a/libs/python/lume/.cursorignore b/libs/swift/lume/.cursorignore similarity index 100% rename from libs/python/lume/.cursorignore rename to libs/swift/lume/.cursorignore diff --git a/libs/python/lume/CONTRIBUTING.md b/libs/swift/lume/CONTRIBUTING.md similarity index 100% rename from libs/python/lume/CONTRIBUTING.md rename to libs/swift/lume/CONTRIBUTING.md diff --git a/libs/python/lume/Package.resolved b/libs/swift/lume/Package.resolved similarity index 100% rename from libs/python/lume/Package.resolved rename to libs/swift/lume/Package.resolved diff --git a/libs/python/lume/Package.swift b/libs/swift/lume/Package.swift similarity index 100% rename from libs/python/lume/Package.swift rename to libs/swift/lume/Package.swift diff --git a/libs/python/lume/README.md b/libs/swift/lume/README.md similarity index 100% rename from libs/python/lume/README.md rename to libs/swift/lume/README.md diff --git a/libs/python/lume/docs/API-Reference.md b/libs/swift/lume/docs/API-Reference.md similarity index 100% rename from libs/python/lume/docs/API-Reference.md rename to libs/swift/lume/docs/API-Reference.md diff --git a/libs/python/lume/docs/Development.md b/libs/swift/lume/docs/Development.md similarity index 100% rename from libs/python/lume/docs/Development.md rename to libs/swift/lume/docs/Development.md diff --git a/libs/python/lume/docs/FAQ.md b/libs/swift/lume/docs/FAQ.md similarity index 100% rename from libs/python/lume/docs/FAQ.md rename to libs/swift/lume/docs/FAQ.md diff --git a/libs/python/lume/img/cli.png b/libs/swift/lume/img/cli.png similarity index 100% rename from libs/python/lume/img/cli.png rename to libs/swift/lume/img/cli.png diff --git a/libs/python/lume/img/logo_black.png b/libs/swift/lume/img/logo_black.png similarity index 100% rename from libs/python/lume/img/logo_black.png rename to libs/swift/lume/img/logo_black.png diff --git a/libs/python/lume/img/logo_white.png b/libs/swift/lume/img/logo_white.png similarity index 100% rename from libs/python/lume/img/logo_white.png rename to libs/swift/lume/img/logo_white.png diff --git a/libs/python/lume/resources/lume.entitlements b/libs/swift/lume/resources/lume.entitlements similarity index 100% rename from libs/python/lume/resources/lume.entitlements rename to libs/swift/lume/resources/lume.entitlements diff --git a/libs/python/lume/scripts/install.sh b/libs/swift/lume/scripts/install.sh similarity index 100% rename from libs/python/lume/scripts/install.sh rename to libs/swift/lume/scripts/install.sh diff --git a/libs/python/lume/src/Commands/Clone.swift b/libs/swift/lume/src/Commands/Clone.swift similarity index 100% rename from libs/python/lume/src/Commands/Clone.swift rename to libs/swift/lume/src/Commands/Clone.swift diff --git a/libs/python/lume/src/Commands/Config.swift b/libs/swift/lume/src/Commands/Config.swift similarity index 100% rename from libs/python/lume/src/Commands/Config.swift rename to libs/swift/lume/src/Commands/Config.swift diff --git a/libs/python/lume/src/Commands/Create.swift b/libs/swift/lume/src/Commands/Create.swift similarity index 100% rename from libs/python/lume/src/Commands/Create.swift rename to libs/swift/lume/src/Commands/Create.swift diff --git a/libs/python/lume/src/Commands/Delete.swift b/libs/swift/lume/src/Commands/Delete.swift similarity index 100% rename from libs/python/lume/src/Commands/Delete.swift rename to libs/swift/lume/src/Commands/Delete.swift diff --git a/libs/python/lume/src/Commands/Get.swift b/libs/swift/lume/src/Commands/Get.swift similarity index 100% rename from libs/python/lume/src/Commands/Get.swift rename to libs/swift/lume/src/Commands/Get.swift diff --git a/libs/python/lume/src/Commands/IPSW.swift b/libs/swift/lume/src/Commands/IPSW.swift similarity index 100% rename from libs/python/lume/src/Commands/IPSW.swift rename to libs/swift/lume/src/Commands/IPSW.swift diff --git a/libs/python/lume/src/Commands/Images.swift b/libs/swift/lume/src/Commands/Images.swift similarity index 100% rename from libs/python/lume/src/Commands/Images.swift rename to libs/swift/lume/src/Commands/Images.swift diff --git a/libs/python/lume/src/Commands/List.swift b/libs/swift/lume/src/Commands/List.swift similarity index 100% rename from libs/python/lume/src/Commands/List.swift rename to libs/swift/lume/src/Commands/List.swift diff --git a/libs/python/lume/src/Commands/Logs.swift b/libs/swift/lume/src/Commands/Logs.swift similarity index 100% rename from libs/python/lume/src/Commands/Logs.swift rename to libs/swift/lume/src/Commands/Logs.swift diff --git a/libs/python/lume/src/Commands/Options/FormatOption.swift b/libs/swift/lume/src/Commands/Options/FormatOption.swift similarity index 100% rename from libs/python/lume/src/Commands/Options/FormatOption.swift rename to libs/swift/lume/src/Commands/Options/FormatOption.swift diff --git a/libs/python/lume/src/Commands/Prune.swift b/libs/swift/lume/src/Commands/Prune.swift similarity index 100% rename from libs/python/lume/src/Commands/Prune.swift rename to libs/swift/lume/src/Commands/Prune.swift diff --git a/libs/python/lume/src/Commands/Pull.swift b/libs/swift/lume/src/Commands/Pull.swift similarity index 100% rename from libs/python/lume/src/Commands/Pull.swift rename to libs/swift/lume/src/Commands/Pull.swift diff --git a/libs/python/lume/src/Commands/Push.swift b/libs/swift/lume/src/Commands/Push.swift similarity index 100% rename from libs/python/lume/src/Commands/Push.swift rename to libs/swift/lume/src/Commands/Push.swift diff --git a/libs/python/lume/src/Commands/Run.swift b/libs/swift/lume/src/Commands/Run.swift similarity index 100% rename from libs/python/lume/src/Commands/Run.swift rename to libs/swift/lume/src/Commands/Run.swift diff --git a/libs/python/lume/src/Commands/Serve.swift b/libs/swift/lume/src/Commands/Serve.swift similarity index 100% rename from libs/python/lume/src/Commands/Serve.swift rename to libs/swift/lume/src/Commands/Serve.swift diff --git a/libs/python/lume/src/Commands/Set.swift b/libs/swift/lume/src/Commands/Set.swift similarity index 100% rename from libs/python/lume/src/Commands/Set.swift rename to libs/swift/lume/src/Commands/Set.swift diff --git a/libs/python/lume/src/Commands/Stop.swift b/libs/swift/lume/src/Commands/Stop.swift similarity index 100% rename from libs/python/lume/src/Commands/Stop.swift rename to libs/swift/lume/src/Commands/Stop.swift diff --git a/libs/python/lume/src/ContainerRegistry/ImageContainerRegistry.swift b/libs/swift/lume/src/ContainerRegistry/ImageContainerRegistry.swift similarity index 100% rename from libs/python/lume/src/ContainerRegistry/ImageContainerRegistry.swift rename to libs/swift/lume/src/ContainerRegistry/ImageContainerRegistry.swift diff --git a/libs/python/lume/src/ContainerRegistry/ImageList.swift b/libs/swift/lume/src/ContainerRegistry/ImageList.swift similarity index 100% rename from libs/python/lume/src/ContainerRegistry/ImageList.swift rename to libs/swift/lume/src/ContainerRegistry/ImageList.swift diff --git a/libs/python/lume/src/ContainerRegistry/ImagesPrinter.swift b/libs/swift/lume/src/ContainerRegistry/ImagesPrinter.swift similarity index 100% rename from libs/python/lume/src/ContainerRegistry/ImagesPrinter.swift rename to libs/swift/lume/src/ContainerRegistry/ImagesPrinter.swift diff --git a/libs/python/lume/src/Errors/Errors.swift b/libs/swift/lume/src/Errors/Errors.swift similarity index 100% rename from libs/python/lume/src/Errors/Errors.swift rename to libs/swift/lume/src/Errors/Errors.swift diff --git a/libs/python/lume/src/FileSystem/Home.swift b/libs/swift/lume/src/FileSystem/Home.swift similarity index 100% rename from libs/python/lume/src/FileSystem/Home.swift rename to libs/swift/lume/src/FileSystem/Home.swift diff --git a/libs/python/lume/src/FileSystem/Settings.swift b/libs/swift/lume/src/FileSystem/Settings.swift similarity index 100% rename from libs/python/lume/src/FileSystem/Settings.swift rename to libs/swift/lume/src/FileSystem/Settings.swift diff --git a/libs/python/lume/src/FileSystem/VMConfig.swift b/libs/swift/lume/src/FileSystem/VMConfig.swift similarity index 100% rename from libs/python/lume/src/FileSystem/VMConfig.swift rename to libs/swift/lume/src/FileSystem/VMConfig.swift diff --git a/libs/python/lume/src/FileSystem/VMDirectory.swift b/libs/swift/lume/src/FileSystem/VMDirectory.swift similarity index 100% rename from libs/python/lume/src/FileSystem/VMDirectory.swift rename to libs/swift/lume/src/FileSystem/VMDirectory.swift diff --git a/libs/python/lume/src/FileSystem/VMLocation.swift b/libs/swift/lume/src/FileSystem/VMLocation.swift similarity index 100% rename from libs/python/lume/src/FileSystem/VMLocation.swift rename to libs/swift/lume/src/FileSystem/VMLocation.swift diff --git a/libs/python/lume/src/LumeController.swift b/libs/swift/lume/src/LumeController.swift similarity index 100% rename from libs/python/lume/src/LumeController.swift rename to libs/swift/lume/src/LumeController.swift diff --git a/libs/python/lume/src/Main.swift b/libs/swift/lume/src/Main.swift similarity index 100% rename from libs/python/lume/src/Main.swift rename to libs/swift/lume/src/Main.swift diff --git a/libs/python/lume/src/Server/HTTP.swift b/libs/swift/lume/src/Server/HTTP.swift similarity index 100% rename from libs/python/lume/src/Server/HTTP.swift rename to libs/swift/lume/src/Server/HTTP.swift diff --git a/libs/python/lume/src/Server/Handlers.swift b/libs/swift/lume/src/Server/Handlers.swift similarity index 100% rename from libs/python/lume/src/Server/Handlers.swift rename to libs/swift/lume/src/Server/Handlers.swift diff --git a/libs/python/lume/src/Server/Requests.swift b/libs/swift/lume/src/Server/Requests.swift similarity index 100% rename from libs/python/lume/src/Server/Requests.swift rename to libs/swift/lume/src/Server/Requests.swift diff --git a/libs/python/lume/src/Server/Responses.swift b/libs/swift/lume/src/Server/Responses.swift similarity index 100% rename from libs/python/lume/src/Server/Responses.swift rename to libs/swift/lume/src/Server/Responses.swift diff --git a/libs/python/lume/src/Server/Server.swift b/libs/swift/lume/src/Server/Server.swift similarity index 100% rename from libs/python/lume/src/Server/Server.swift rename to libs/swift/lume/src/Server/Server.swift diff --git a/libs/python/lume/src/Utils/CommandRegistry.swift b/libs/swift/lume/src/Utils/CommandRegistry.swift similarity index 100% rename from libs/python/lume/src/Utils/CommandRegistry.swift rename to libs/swift/lume/src/Utils/CommandRegistry.swift diff --git a/libs/python/lume/src/Utils/CommandUtils.swift b/libs/swift/lume/src/Utils/CommandUtils.swift similarity index 100% rename from libs/python/lume/src/Utils/CommandUtils.swift rename to libs/swift/lume/src/Utils/CommandUtils.swift diff --git a/libs/python/lume/src/Utils/Logger.swift b/libs/swift/lume/src/Utils/Logger.swift similarity index 100% rename from libs/python/lume/src/Utils/Logger.swift rename to libs/swift/lume/src/Utils/Logger.swift diff --git a/libs/python/lume/src/Utils/NetworkUtils.swift b/libs/swift/lume/src/Utils/NetworkUtils.swift similarity index 100% rename from libs/python/lume/src/Utils/NetworkUtils.swift rename to libs/swift/lume/src/Utils/NetworkUtils.swift diff --git a/libs/python/lume/src/Utils/Path.swift b/libs/swift/lume/src/Utils/Path.swift similarity index 100% rename from libs/python/lume/src/Utils/Path.swift rename to libs/swift/lume/src/Utils/Path.swift diff --git a/libs/python/lume/src/Utils/ProcessRunner.swift b/libs/swift/lume/src/Utils/ProcessRunner.swift similarity index 100% rename from libs/python/lume/src/Utils/ProcessRunner.swift rename to libs/swift/lume/src/Utils/ProcessRunner.swift diff --git a/libs/python/lume/src/Utils/ProgressLogger.swift b/libs/swift/lume/src/Utils/ProgressLogger.swift similarity index 100% rename from libs/python/lume/src/Utils/ProgressLogger.swift rename to libs/swift/lume/src/Utils/ProgressLogger.swift diff --git a/libs/python/lume/src/Utils/String.swift b/libs/swift/lume/src/Utils/String.swift similarity index 100% rename from libs/python/lume/src/Utils/String.swift rename to libs/swift/lume/src/Utils/String.swift diff --git a/libs/python/lume/src/Utils/Utils.swift b/libs/swift/lume/src/Utils/Utils.swift similarity index 100% rename from libs/python/lume/src/Utils/Utils.swift rename to libs/swift/lume/src/Utils/Utils.swift diff --git a/libs/python/lume/src/VM/DarwinVM.swift b/libs/swift/lume/src/VM/DarwinVM.swift similarity index 100% rename from libs/python/lume/src/VM/DarwinVM.swift rename to libs/swift/lume/src/VM/DarwinVM.swift diff --git a/libs/python/lume/src/VM/LinuxVM.swift b/libs/swift/lume/src/VM/LinuxVM.swift similarity index 100% rename from libs/python/lume/src/VM/LinuxVM.swift rename to libs/swift/lume/src/VM/LinuxVM.swift diff --git a/libs/python/lume/src/VM/VM.swift b/libs/swift/lume/src/VM/VM.swift similarity index 100% rename from libs/python/lume/src/VM/VM.swift rename to libs/swift/lume/src/VM/VM.swift diff --git a/libs/python/lume/src/VM/VMDetails.swift b/libs/swift/lume/src/VM/VMDetails.swift similarity index 100% rename from libs/python/lume/src/VM/VMDetails.swift rename to libs/swift/lume/src/VM/VMDetails.swift diff --git a/libs/python/lume/src/VM/VMDetailsPrinter.swift b/libs/swift/lume/src/VM/VMDetailsPrinter.swift similarity index 100% rename from libs/python/lume/src/VM/VMDetailsPrinter.swift rename to libs/swift/lume/src/VM/VMDetailsPrinter.swift diff --git a/libs/python/lume/src/VM/VMDisplayResolution.swift b/libs/swift/lume/src/VM/VMDisplayResolution.swift similarity index 100% rename from libs/python/lume/src/VM/VMDisplayResolution.swift rename to libs/swift/lume/src/VM/VMDisplayResolution.swift diff --git a/libs/python/lume/src/VM/VMFactory.swift b/libs/swift/lume/src/VM/VMFactory.swift similarity index 100% rename from libs/python/lume/src/VM/VMFactory.swift rename to libs/swift/lume/src/VM/VMFactory.swift diff --git a/libs/python/lume/src/VNC/PassphraseGenerator.swift b/libs/swift/lume/src/VNC/PassphraseGenerator.swift similarity index 100% rename from libs/python/lume/src/VNC/PassphraseGenerator.swift rename to libs/swift/lume/src/VNC/PassphraseGenerator.swift diff --git a/libs/python/lume/src/VNC/VNCService.swift b/libs/swift/lume/src/VNC/VNCService.swift similarity index 100% rename from libs/python/lume/src/VNC/VNCService.swift rename to libs/swift/lume/src/VNC/VNCService.swift diff --git a/libs/python/lume/src/Virtualization/DHCPLeaseParser.swift b/libs/swift/lume/src/Virtualization/DHCPLeaseParser.swift similarity index 100% rename from libs/python/lume/src/Virtualization/DHCPLeaseParser.swift rename to libs/swift/lume/src/Virtualization/DHCPLeaseParser.swift diff --git a/libs/python/lume/src/Virtualization/DarwinImageLoader.swift b/libs/swift/lume/src/Virtualization/DarwinImageLoader.swift similarity index 100% rename from libs/python/lume/src/Virtualization/DarwinImageLoader.swift rename to libs/swift/lume/src/Virtualization/DarwinImageLoader.swift diff --git a/libs/python/lume/src/Virtualization/ImageLoaderFactory.swift b/libs/swift/lume/src/Virtualization/ImageLoaderFactory.swift similarity index 100% rename from libs/python/lume/src/Virtualization/ImageLoaderFactory.swift rename to libs/swift/lume/src/Virtualization/ImageLoaderFactory.swift diff --git a/libs/python/lume/src/Virtualization/VMVirtualizationService.swift b/libs/swift/lume/src/Virtualization/VMVirtualizationService.swift similarity index 100% rename from libs/python/lume/src/Virtualization/VMVirtualizationService.swift rename to libs/swift/lume/src/Virtualization/VMVirtualizationService.swift diff --git a/libs/python/lume/tests/Mocks/MockVM.swift b/libs/swift/lume/tests/Mocks/MockVM.swift similarity index 100% rename from libs/python/lume/tests/Mocks/MockVM.swift rename to libs/swift/lume/tests/Mocks/MockVM.swift diff --git a/libs/python/lume/tests/Mocks/MockVMVirtualizationService.swift b/libs/swift/lume/tests/Mocks/MockVMVirtualizationService.swift similarity index 100% rename from libs/python/lume/tests/Mocks/MockVMVirtualizationService.swift rename to libs/swift/lume/tests/Mocks/MockVMVirtualizationService.swift diff --git a/libs/python/lume/tests/Mocks/MockVNCService.swift b/libs/swift/lume/tests/Mocks/MockVNCService.swift similarity index 100% rename from libs/python/lume/tests/Mocks/MockVNCService.swift rename to libs/swift/lume/tests/Mocks/MockVNCService.swift diff --git a/libs/python/lume/tests/VM/VMDetailsPrinterTests.swift b/libs/swift/lume/tests/VM/VMDetailsPrinterTests.swift similarity index 100% rename from libs/python/lume/tests/VM/VMDetailsPrinterTests.swift rename to libs/swift/lume/tests/VM/VMDetailsPrinterTests.swift diff --git a/libs/python/lume/tests/VMTests.swift b/libs/swift/lume/tests/VMTests.swift similarity index 100% rename from libs/python/lume/tests/VMTests.swift rename to libs/swift/lume/tests/VMTests.swift diff --git a/libs/python/lume/tests/VMVirtualizationServiceTests.swift b/libs/swift/lume/tests/VMVirtualizationServiceTests.swift similarity index 100% rename from libs/python/lume/tests/VMVirtualizationServiceTests.swift rename to libs/swift/lume/tests/VMVirtualizationServiceTests.swift diff --git a/libs/python/lume/tests/VNCServiceTests.swift b/libs/swift/lume/tests/VNCServiceTests.swift similarity index 100% rename from libs/python/lume/tests/VNCServiceTests.swift rename to libs/swift/lume/tests/VNCServiceTests.swift