diff --git a/.github/workflows/create-release-pr.yml b/.github/workflows/create-release-pr.yml new file mode 100644 index 000000000..ad7a3bab9 --- /dev/null +++ b/.github/workflows/create-release-pr.yml @@ -0,0 +1,46 @@ +name: Create Release PR + +on: + workflow_dispatch: + +permissions: + contents: read + pull-requests: write + +jobs: + create-release-pr: + name: Create Release PR + runs-on: ubuntu-latest + steps: + - uses: actions/create-github-app-token@v3 + id: app-token + with: + app-id: ${{ secrets.DEVSY_GITHUB_APP_ID }} + private-key: ${{ secrets.DEVSY_GITHUB_APP_PRIVATE_KEY }} + + - uses: actions/checkout@v6 + with: + fetch-depth: 0 + token: ${{ steps.app-token.outputs.token }} + + - name: Get commit log + id: commits + run: | + COMMITS=$(git log origin/release..origin/main --oneline) + { + echo "log<> "$GITHUB_OUTPUT" + + - name: Create PR + env: + GH_TOKEN: ${{ steps.app-token.outputs.token }} + run: | + gh pr create \ + --base release \ + --head main \ + --title "release: promote main to stable" \ + --body "## Commits being promoted + + ${{ steps.commits.outputs.log }}" diff --git a/.github/workflows/desktop-ci.yml b/.github/workflows/desktop-ci.yml index 898a4705f..adca54a4d 100644 --- a/.github/workflows/desktop-ci.yml +++ b/.github/workflows/desktop-ci.yml @@ -74,7 +74,6 @@ jobs: cache: npm cache-dependency-path: desktop/package-lock.json - # ── Build Go CLI binary ── - name: Build CLI (unix) if: runner.os != 'Windows' run: | @@ -97,13 +96,11 @@ jobs: $env:GOARCH = "amd64" go build -o desktop/resources/bin/devsy.exe . - # ── Windows native build tools ── - name: Configure Windows build tools if: runner.os == 'Windows' shell: pwsh run: echo "GYP_MSVS_VERSION=2022" >> $env:GITHUB_ENV - # ── Setup Python for native module builds ── - name: Setup Python uses: actions/setup-python@v6 with: @@ -112,17 +109,14 @@ jobs: - name: Install setuptools run: pip install setuptools - # ── Install Electron dependencies ── - name: Install dependencies working-directory: desktop run: npm ci - # ── Install xvfb on Linux for e2e tests ── - name: Install xvfb if: runner.os == 'Linux' run: sudo apt-get update && sudo apt-get install -y xvfb - # ── E2E tests ── - name: Run e2e tests (Linux) if: runner.os == 'Linux' working-directory: desktop @@ -137,7 +131,6 @@ jobs: npm run electron:build npx playwright test - # ── Package ── - name: Package with electron-builder working-directory: desktop run: npx electron-builder ${{ matrix.builder-args }} --config electron-builder.yml @@ -150,7 +143,6 @@ jobs: # APPLE_APP_SPECIFIC_PASSWORD: ${{ secrets.APPLE_APP_SPECIFIC_PASSWORD }} # APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }} - # ── Upload artifacts ── - name: Upload artifacts uses: actions/upload-artifact@v5 with: diff --git a/.github/workflows/promote-release.yml b/.github/workflows/promote-release.yml deleted file mode 100644 index b7ad31f50..000000000 --- a/.github/workflows/promote-release.yml +++ /dev/null @@ -1,97 +0,0 @@ -name: Promote RC to Stable - -on: - workflow_dispatch: - inputs: - rc_tag: - description: "RC tag to promote (e.g., v1.3.0-rc.1)" - required: true - type: string - -permissions: - contents: write - actions: write - -jobs: - promote: - name: Promote RC to Stable Release - runs-on: ubuntu-latest - steps: - - uses: actions/create-github-app-token@v3 - id: app-token - with: - app-id: ${{ secrets.DEVSY_GITHUB_APP_ID }} - private-key: ${{ secrets.DEVSY_GITHUB_APP_PRIVATE_KEY }} - - - uses: actions/checkout@v6 - with: - fetch-tags: true - - - name: validate RC tag - env: - GH_TOKEN: ${{ steps.app-token.outputs.token }} - RC_TAG: ${{ inputs.rc_tag }} - run: | - if ! echo "$RC_TAG" | grep -qE '^v[0-9]+\.[0-9]+\.[0-9]+-rc\.[0-9]+$'; then - echo "::error::Invalid RC tag format: $RC_TAG (expected v*.*.*-rc*)" - exit 1 - fi - - RELEASE=$(gh release view "$RC_TAG" --json tagName,isPrerelease 2>/dev/null || true) - if [ -z "$RELEASE" ]; then - echo "::error::Release $RC_TAG not found" - exit 1 - fi - - IS_PRERELEASE=$(echo "$RELEASE" | jq -r '.isPrerelease') - if [ "$IS_PRERELEASE" != "true" ]; then - echo "::error::Release $RC_TAG is not a prerelease" - exit 1 - fi - - echo "RC release $RC_TAG validated" - - - name: derive stable version - id: version - env: - RC_TAG: ${{ inputs.rc_tag }} - run: | - STABLE_TAG="${RC_TAG%%-rc*}" - echo "stable_tag=$STABLE_TAG" >> "$GITHUB_OUTPUT" - - COMMIT_SHA=$(git rev-list -n 1 "$RC_TAG") - echo "commit_sha=$COMMIT_SHA" >> "$GITHUB_OUTPUT" - - echo "Stable tag: $STABLE_TAG at commit: $COMMIT_SHA" - - - name: fetch RC release notes - id: rc_notes - env: - GH_TOKEN: ${{ steps.app-token.outputs.token }} - RC_TAG: ${{ inputs.rc_tag }} - run: | - BODY=$(gh release view "$RC_TAG" --json body -q .body) - BODY=$(echo "$BODY" | sed "1s/-rc\.[0-9]*//" ) - { echo "body<> "$GITHUB_OUTPUT" - - - name: create stable release - uses: softprops/action-gh-release@v3 - with: - token: ${{ steps.app-token.outputs.token }} - tag_name: ${{ steps.version.outputs.stable_tag }} - target_commitish: ${{ steps.version.outputs.commit_sha }} - name: ${{ steps.version.outputs.stable_tag }} - body: ${{ steps.rc_notes.outputs.body }} - draft: false - prerelease: false - make_latest: true - - - name: trigger full rebuild - env: - GH_TOKEN: ${{ github.token }} - STABLE_TAG: ${{ steps.version.outputs.stable_tag }} - run: | - gh workflow run release.yml \ - --field tag="$STABLE_TAG" - - echo "Triggered release.yml rebuild for $STABLE_TAG" diff --git a/.github/workflows/release-please.yml b/.github/workflows/release-please.yml deleted file mode 100644 index 1f464a603..000000000 --- a/.github/workflows/release-please.yml +++ /dev/null @@ -1,63 +0,0 @@ -name: Release Please - -on: - push: - branches: [main] - -permissions: - contents: write - pull-requests: write - -jobs: - release-please: - name: Release Please - runs-on: ubuntu-latest - outputs: - release_created: ${{ steps.release.outputs.release_created }} - tag_name: ${{ steps.release.outputs.tag_name }} - steps: - - uses: actions/create-github-app-token@v3 - id: app-token - with: - app-id: ${{ secrets.DEVSY_GITHUB_APP_ID }} - private-key: ${{ secrets.DEVSY_GITHUB_APP_PRIVATE_KEY }} - - - uses: googleapis/release-please-action@v4 - id: release - with: - token: ${{ steps.app-token.outputs.token }} - config-file: release-please-config.json - manifest-file: .release-please-manifest.json - - auto-merge-rc: - name: Auto-merge RC Release PR - runs-on: ubuntu-latest - needs: release-please - if: ${{ !needs.release-please.outputs.release_created }} - steps: - - uses: actions/create-github-app-token@v3 - id: app-token - with: - app-id: ${{ secrets.DEVSY_GITHUB_APP_ID }} - private-key: ${{ secrets.DEVSY_GITHUB_APP_PRIVATE_KEY }} - - - name: auto-merge RC release PR - env: - GH_TOKEN: ${{ steps.app-token.outputs.token }} - GH_REPO: ${{ github.repository }} - run: | - PR=$(gh pr list --label "autorelease: pending" --json number,title --jq '.[0]') - if [ -z "$PR" ] || [ "$PR" = "null" ]; then - echo "No pending release PR found" - exit 0 - fi - - PR_NUMBER=$(echo "$PR" | jq -r '.number') - PR_TITLE=$(echo "$PR" | jq -r '.title') - - if echo "$PR_TITLE" | grep -qiE '\-rc[0-9]*'; then - echo "Enabling auto-merge for RC release PR #$PR_NUMBER: $PR_TITLE" - gh pr merge "$PR_NUMBER" --auto --squash - else - echo "Skipping auto-merge for non-RC release PR #$PR_NUMBER: $PR_TITLE" - fi diff --git a/.github/workflows/semantic-release.yml b/.github/workflows/semantic-release.yml new file mode 100644 index 000000000..cf4ce9584 --- /dev/null +++ b/.github/workflows/semantic-release.yml @@ -0,0 +1,45 @@ +name: Semantic Release + +on: + push: + branches: [main, release] + workflow_dispatch: + inputs: + dry-run: + description: Run in dry-run mode (no release created) + type: boolean + default: false + +permissions: + contents: write + issues: write + pull-requests: write + +jobs: + release: + name: Release + runs-on: ubuntu-latest + steps: + - uses: actions/create-github-app-token@v3 + id: app-token + with: + app-id: ${{ secrets.DEVSY_GITHUB_APP_ID }} + private-key: ${{ secrets.DEVSY_GITHUB_APP_PRIVATE_KEY }} + + - uses: actions/checkout@v6 + with: + fetch-depth: 0 + token: ${{ steps.app-token.outputs.token }} + + - uses: actions/setup-node@v6 + with: + node-version: 22 + cache: npm + + - run: npm ci + + - name: Run semantic-release + run: npx semantic-release ${{ inputs.dry-run && '--dry-run' || '' }} + env: + GITHUB_TOKEN: ${{ steps.app-token.outputs.token }} + GH_TOKEN: ${{ steps.app-token.outputs.token }} diff --git a/.gitignore b/.gitignore index 9c9f3d725..88bfab2a8 100644 --- a/.gitignore +++ b/.gitignore @@ -10,7 +10,6 @@ # Unit test targets /main /profile.out -/package-lock.json /tagsvendor/ node_modules/ desktop/dist/ diff --git a/.release-please-manifest.json b/.release-please-manifest.json deleted file mode 100644 index 35918cca9..000000000 --- a/.release-please-manifest.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - ".": "1.3.0-rc.18" -} diff --git a/.releaserc.json b/.releaserc.json new file mode 100644 index 000000000..a29af5bbe --- /dev/null +++ b/.releaserc.json @@ -0,0 +1,15 @@ +{ + "tagFormat": "v${version}", + "branches": [ + { "name": "main", "prerelease": "rc" }, + { "name": "release", "prerelease": false } + ], + "plugins": [ + "@semantic-release/commit-analyzer", + "@semantic-release/release-notes-generator", + [ + "@semantic-release/github", + { "successComment": false, "failTitle": false } + ] + ] +} diff --git a/CHANGELOG.md b/CHANGELOG.md deleted file mode 100644 index c280646a5..000000000 --- a/CHANGELOG.md +++ /dev/null @@ -1,461 +0,0 @@ -# Changelog - -## [1.3.0-rc.18](https://github.com/devsy-org/devsy/compare/v1.3.0-rc.17...v1.3.0-rc.18) (2026-05-18) - - -### Bug Fixes - -* **ci:** remove permission-contents scope restriction from app token step ([#359](https://github.com/devsy-org/devsy/issues/359)) ([28b8a1b](https://github.com/devsy-org/devsy/commit/28b8a1be2831509ead2dd25f552ef05e3f698d62)) - -## [1.3.0-rc.17](https://github.com/devsy-org/devsy/compare/v1.3.0-rc.16...v1.3.0-rc.17) (2026-05-18) - - -### Bug Fixes - -* **ci:** pass app token via GITHUB_TOKEN env for softprops release step ([#357](https://github.com/devsy-org/devsy/issues/357)) ([69b8cb3](https://github.com/devsy-org/devsy/commit/69b8cb302776cf6bacf54e4dc0a7f6412a3cdd5f)) - -## [1.3.0-rc.16](https://github.com/devsy-org/devsy/compare/v1.3.0-rc.15...v1.3.0-rc.16) (2026-05-18) - - -### Bug Fixes - -* **ci:** explicitly request contents:write permission for app token ([#355](https://github.com/devsy-org/devsy/issues/355)) ([ed11e14](https://github.com/devsy-org/devsy/commit/ed11e145b81d11a1df595180a938492330a81a95)) - -## [1.3.0-rc.15](https://github.com/devsy-org/devsy/compare/v1.3.0-rc.14...v1.3.0-rc.15) (2026-05-18) - - -### Bug Fixes - -* **ci:** use make_latest legacy to avoid admin permission requirement ([#353](https://github.com/devsy-org/devsy/issues/353)) ([540e67a](https://github.com/devsy-org/devsy/commit/540e67ac6581f7386de511e877a6b9bdc73a4525)) - -## [1.3.0-rc.14](https://github.com/devsy-org/devsy/compare/v1.3.0-rc.13...v1.3.0-rc.14) (2026-05-18) - - -### Bug Fixes - -* **ci:** restore softprops release step and wire rc_notes output id ([#351](https://github.com/devsy-org/devsy/issues/351)) ([a31522b](https://github.com/devsy-org/devsy/commit/a31522bd5c947f85f5177a0f709097cae8d37d9c)) - -## [1.3.0-rc.13](https://github.com/devsy-org/devsy/compare/v1.3.0-rc.12...v1.3.0-rc.13) (2026-05-18) - - -### Bug Fixes - -* **ci:** use github.token for stable release creation in promote workflow ([#349](https://github.com/devsy-org/devsy/issues/349)) ([abde042](https://github.com/devsy-org/devsy/commit/abde04251bc5bcebf8c6e06dfe778a57d764e97c)) - -## [1.3.0-rc.12](https://github.com/devsy-org/devsy/compare/v1.3.0-rc.11...v1.3.0-rc.12) (2026-05-18) - - -### Bug Fixes - -* **ci:** fix RC header rewrite and use gh CLI for stable release creation ([#347](https://github.com/devsy-org/devsy/issues/347)) ([9b80897](https://github.com/devsy-org/devsy/commit/9b80897dbfba3d4aafc3b751befb2e1e64d5e5de)) - -## [1.3.0-rc.11](https://github.com/devsy-org/devsy/compare/v1.3.0-rc.10...v1.3.0-rc.11) (2026-05-18) - - -### Bug Fixes - -* **ci:** rewrite RC version header to stable in promote workflow ([#345](https://github.com/devsy-org/devsy/issues/345)) ([fdfed92](https://github.com/devsy-org/devsy/commit/fdfed92b27d251d43a97d00b2c17f934ff86e8dc)) - -## [1.3.0-rc.10](https://github.com/devsy-org/devsy/compare/v1.3.0-rc.9...v1.3.0-rc.10) (2026-05-18) - - -### Bug Fixes - -* **ci:** publish stable release as latest instead of draft in promote workflow ([#344](https://github.com/devsy-org/devsy/issues/344)) ([4455eea](https://github.com/devsy-org/devsy/commit/4455eeae321a568421e26d6946260142d8504e63)) -* **ci:** use GITHUB_TOKEN for release.yml dispatch in promote workflow ([#342](https://github.com/devsy-org/devsy/issues/342)) ([5b9492f](https://github.com/devsy-org/devsy/commit/5b9492f9ca888194710589b9802f8a4d6ed6e64e)) - -## [1.3.0-rc.9](https://github.com/devsy-org/devsy/compare/v1.3.0-rc.8...v1.3.0-rc.9) (2026-05-18) - - -### Bug Fixes - -* **ci:** add fetch-tags to promote-release checkout step ([#340](https://github.com/devsy-org/devsy/issues/340)) ([8d457be](https://github.com/devsy-org/devsy/commit/8d457be20695e89568c644c522cb20448f229d32)) - -## [1.3.0-rc.8](https://github.com/devsy-org/devsy/compare/v1.3.0-rc.7...v1.3.0-rc.8) (2026-05-18) - - -### Bug Fixes - -* **ci:** exclude CLI deploys from Netlify restore search ([#337](https://github.com/devsy-org/devsy/issues/337)) ([db5ecf3](https://github.com/devsy-org/devsy/commit/db5ecf392f7d91dda6d39711c1d22e47356e678c)) - -## [1.3.0-rc.7](https://github.com/devsy-org/devsy/compare/v1.3.0-rc.6...v1.3.0-rc.7) (2026-05-18) - - -### Bug Fixes - -* **ci:** deploy electron update metadata to dl.devsy.sh via Netlify ([#334](https://github.com/devsy-org/devsy/issues/334)) ([094c375](https://github.com/devsy-org/devsy/commit/094c3759fad5ad121fac2a969793aae14bb2a986)) - -## [1.3.0-rc.6](https://github.com/devsy-org/devsy/compare/v1.3.0-rc.5...v1.3.0-rc.6) (2026-05-18) - - -### Features - -* **ci:** add path-based filtering to skip e2e on non-Go changes ([#332](https://github.com/devsy-org/devsy/issues/332)) ([af92dfc](https://github.com/devsy-org/devsy/commit/af92dfc8eaf2376bf5365adf09bafafffb770f40)) - -## [1.3.0-rc.5](https://github.com/devsy-org/devsy/compare/v1.3.0-rc.4...v1.3.0-rc.5) (2026-05-18) - - -### Bug Fixes - -* **ci:** correct RC tag regex to match dot-separated format ([#328](https://github.com/devsy-org/devsy/issues/328)) ([6bdacbe](https://github.com/devsy-org/devsy/commit/6bdacbeaec13ae1c620ad3e817c38bc89f4be1c9)) -* **ci:** remove Netlify prod deploy that overwrites devsy.sh ([#330](https://github.com/devsy-org/devsy/issues/330)) ([791c0e7](https://github.com/devsy-org/devsy/commit/791c0e7f55b04d835a177f3d1f7c3c9dfe9323dd)) - -## [1.3.0-rc.4](https://github.com/devsy-org/devsy/compare/v1.3.0-rc.3...v1.3.0-rc.4) (2026-05-18) - - -### Bug Fixes - -* **ci:** upload desktop artifacts via softprops/action-gh-release ([#326](https://github.com/devsy-org/devsy/issues/326)) ([6a67c26](https://github.com/devsy-org/devsy/commit/6a67c2629dca504bc2dcf9ee88b3c4b53b445aa3)) - -## [1.3.0-rc.3](https://github.com/devsy-org/devsy/compare/v1.3.0-rc.2...v1.3.0-rc.3) (2026-05-18) - - -### Bug Fixes - -* **ci:** add permissions to publish-prerelease job ([#324](https://github.com/devsy-org/devsy/issues/324)) ([2f3cdbd](https://github.com/devsy-org/devsy/commit/2f3cdbda66e68459cb26770ebcf62bff6648448c)) - -## [1.3.0-rc.2](https://github.com/devsy-org/devsy/compare/v1.3.0-rc.1...v1.3.0-rc.2) (2026-05-18) - - -### Bug Fixes - -* **ci:** add --no-build flag to netlify deploy in release workflow ([#323](https://github.com/devsy-org/devsy/issues/323)) ([3c186eb](https://github.com/devsy-org/devsy/commit/3c186ebf66a693989bdef14f9ab708bb59439eda)) -* **ci:** fix Netlify deploy and Flatpak upload in release workflow ([#321](https://github.com/devsy-org/devsy/issues/321)) ([642dc1c](https://github.com/devsy-org/devsy/commit/642dc1c63aba7e6ba7e61412e19cf3cc57b3a9b2)) - -## [1.3.0-rc.1](https://github.com/devsy-org/devsy/compare/v1.3.0-rc...v1.3.0-rc.1) (2026-05-18) - - -### Bug Fixes - -* **ci:** pin Windows desktop builds to windows-2022 for node-gyp compat ([#319](https://github.com/devsy-org/devsy/issues/319)) ([fb38c95](https://github.com/devsy-org/devsy/commit/fb38c9505b48d9bb746340e45ae3ba22577b3b19)) -* **ci:** resolve 3 desktop build failures in release workflow ([#314](https://github.com/devsy-org/devsy/issues/314)) ([4c5cea8](https://github.com/devsy-org/devsy/commit/4c5cea8fff9ebde992821710583dd54122855ce3)) -* **ci:** revert CI skip condition on release-please PRs ([#320](https://github.com/devsy-org/devsy/issues/320)) ([a7110d7](https://github.com/devsy-org/devsy/commit/a7110d727f04e95e589450f432ed0a007a6cd5a2)) - -## [1.3.0-rc](https://github.com/devsy-org/devsy/compare/v1.2.1-rc...v1.3.0-rc) (2026-05-17) - - -### Features - -* add workspace rename command with auto-stop and e2e tests ([#308](https://github.com/devsy-org/devsy/issues/308)) ([ff2afac](https://github.com/devsy-org/devsy/commit/ff2afac1170f863629a95850db304cb32caeb6e9)) -* **desktop:** add workspace rename UI with inline editing ([#311](https://github.com/devsy-org/devsy/issues/311)) ([0038071](https://github.com/devsy-org/devsy/commit/0038071020b48fae8ba2774e1a5f6baa01db5af2)) - - -### Bug Fixes - -* **ci:** flatten downloaded CLI artifacts before desktop build ([#312](https://github.com/devsy-org/devsy/issues/312)) ([8a3b397](https://github.com/devsy-org/devsy/commit/8a3b397d6055c2f886740ffe5908a5e87b0a8a40)) -* **ci:** skip network-dependent OCI tests in goreleaser pre-hook ([#309](https://github.com/devsy-org/devsy/issues/309)) ([87d893e](https://github.com/devsy-org/devsy/commit/87d893eec5765d67966a0c826a2fa8220bfb99f3)) - -## [1.2.1-rc](https://github.com/devsy-org/devsy/compare/v1.2.0...v1.2.1-rc) (2026-05-17) - - -### Bug Fixes - -* **ci:** add prerelease versioning to release-please config ([#305](https://github.com/devsy-org/devsy/issues/305)) ([f65bb85](https://github.com/devsy-org/devsy/commit/f65bb8540c9a03c4bcafa95bdb247e00cdac6d81)) - -## [1.2.0](https://github.com/devsy-org/devsy/compare/v1.1.0...v1.2.0) (2026-05-17) - - -### Features - -* **telemetry:** replace Loft analytics with PostHog and add Netlify update hosting ([#303](https://github.com/devsy-org/devsy/issues/303)) ([07824bd](https://github.com/devsy-org/devsy/commit/07824bdf875abefc5d51c1a1d1fe68c34bbde08f)) - -## [1.1.0](https://github.com/devsy-org/devsy/compare/v1.0.0...v1.1.0) (2026-05-16) - - -### Features - -* add community provider for podman ([#453](https://github.com/devsy-org/devsy/issues/453)) ([a0efad6](https://github.com/devsy-org/devsy/commit/a0efad62c7c68b6f1385fcc803a84b9a4c6586d9)) -* add support for IBM Bob IDE ([#657](https://github.com/devsy-org/devsy/issues/657)) ([5c5255d](https://github.com/devsy-org/devsy/commit/5c5255d94e9f47e2492e9dbfc12a0d48e435dda0)) -* add zap-based pkg/log and CLI verbosity flags ([#13](https://github.com/devsy-org/devsy/issues/13)) ([5f05055](https://github.com/devsy-org/devsy/commit/5f05055ce3ed917c8fcc0d1cc1635c535a3e2310)) -* **agent:** implement AgentDelivery interface ([#265](https://github.com/devsy-org/devsy/issues/265)) ([9d5a5b8](https://github.com/devsy-org/devsy/commit/9d5a5b8acf4969ab10a9f0b44c203b43f8ebbd15)) -* **build:** add CLI --cache-from flags with priority over devcontainer.json ([#167](https://github.com/devsy-org/devsy/issues/167)) ([ecd9945](https://github.com/devsy-org/devsy/commit/ecd99451c78dc6c8e319907ef2d369ef9cab9c58)) -* **cli:** add --default-user-env-probe flag to override config ([#175](https://github.com/devsy-org/devsy/issues/175)) ([77d40f5](https://github.com/devsy-org/devsy/commit/77d40f57216b030319b90fb02543aca03f5b8dc9)) -* **cli:** add --docker-path flag to read-configuration command ([#245](https://github.com/devsy-org/devsy/issues/245)) ([7e53991](https://github.com/devsy-org/devsy/commit/7e53991a55dc802cb79566f79a57cc0324f7ca64)) -* **cli:** add --id-label flag for custom container identification ([#183](https://github.com/devsy-org/devsy/issues/183)) ([7e61e8c](https://github.com/devsy-org/devsy/commit/7e61e8cfdebeace29b90016dcad8eb7d4d6cb6cc)) -* **cli:** add --id-label flag to read-configuration command ([#244](https://github.com/devsy-org/devsy/issues/244)) ([271f84e](https://github.com/devsy-org/devsy/commit/271f84e3c860dc44a033ad31559935cea3044a7e)) -* **cli:** add --result-format flag for JSON envelope control (DEVSY-022) ([#243](https://github.com/devsy-org/devsy/issues/243)) ([955dd58](https://github.com/devsy-org/devsy/commit/955dd58d6384b7d000169ac44071f9dfd4ffe220)) -* **cli:** add --secrets-file flag for lifecycle command env injection ([#179](https://github.com/devsy-org/devsy/issues/179)) ([8a996c3](https://github.com/devsy-org/devsy/commit/8a996c307aacd44d7cc6ed5b5a169c9fe3904d62)) -* **cli:** add exec command for container command execution ([#157](https://github.com/devsy-org/devsy/issues/157)) ([029684c](https://github.com/devsy-org/devsy/commit/029684ca8ad15c36b18cfb166171a847cc44cccb)) -* **cli:** add features publish command ([#263](https://github.com/devsy-org/devsy/issues/263)) ([3bc64ed](https://github.com/devsy-org/devsy/commit/3bc64ed62cd4fedd977f7a9b01089fb5e7e1d752)) -* **cli:** add features test command for isolated feature testing ([#258](https://github.com/devsy-org/devsy/issues/258)) ([a54d9ff](https://github.com/devsy-org/devsy/commit/a54d9ff1bd1faab87863072aa84def8665dcf0c9)) -* **cli:** add flag aliases for devcontainer CLI compatibility ([#174](https://github.com/devsy-org/devsy/issues/174)) ([3c1fed4](https://github.com/devsy-org/devsy/commit/3c1fed43de7355eb160cdfad42592815c9f0110d)) -* **cli:** add read-configuration command ([#152](https://github.com/devsy-org/devsy/issues/152)) ([bb029d0](https://github.com/devsy-org/devsy/commit/bb029d0289bdb4a0fc212051ca2021afd11a830e)) -* **cli:** add repeatable --mount flag to up command ([#295](https://github.com/devsy-org/devsy/issues/295)) ([7db7af3](https://github.com/devsy-org/devsy/commit/7db7af390422693874c540ebc10ae4235aa5c300)) -* **cli:** add spec-required flags to run-user-commands (DEVSY-027) ([#246](https://github.com/devsy-org/devsy/issues/246)) ([c9bca5d](https://github.com/devsy-org/devsy/commit/c9bca5d701bff20582ea5eacfe8f47df5ef5a268)) -* **cli:** add upgrade command for feature versions ([#290](https://github.com/devsy-org/devsy/issues/290)) ([4e1f879](https://github.com/devsy-org/devsy/commit/4e1f879fbd537f0b516166a7eada4d3e230231b2)) -* **cli:** implement features package command ([#260](https://github.com/devsy-org/devsy/issues/260)) ([d074633](https://github.com/devsy-org/devsy/commit/d074633ef4ccfff1a2cca8ee49b7dc671f551bc3)) -* **cli:** rewrite set-up command to full devcontainer spec compliance ([#251](https://github.com/devsy-org/devsy/issues/251)) ([9563e32](https://github.com/devsy-org/devsy/commit/9563e3256aaa51b5f47dce1cef84cdc66918553b)) -* **cmd:** add --container-id flag to read-configuration ([#205](https://github.com/devsy-org/devsy/issues/205)) ([198dee1](https://github.com/devsy-org/devsy/commit/198dee1f6b07892dd3f9225ab6a1d459e5d69477)) -* **cmd:** add --remove-volumes flag to down command ([#207](https://github.com/devsy-org/devsy/issues/207)) ([ba9fbb9](https://github.com/devsy-org/devsy/commit/ba9fbb92534b8f4e56bf54d297bbbfa48d035288)) -* **cmd:** add --update-remote-user-uid-default flag to up command ([#208](https://github.com/devsy-org/devsy/issues/208)) ([14e6944](https://github.com/devsy-org/devsy/commit/14e6944dc1215d83a641f17887bd971e53ccb3b9)) -* **cmd:** add --workspace-mount-consistency flag to up command ([#198](https://github.com/devsy-org/devsy/issues/198)) ([e2992f8](https://github.com/devsy-org/devsy/commit/e2992f8a2b7a031ea4156acbd3cc2a65ec1998de)) -* **cmd:** add `--additional-features` flag for feature injection ([#626](https://github.com/devsy-org/devsy/issues/626)) ([265b290](https://github.com/devsy-org/devsy/commit/265b290b3653b7021cfd8649ab2d61952d4c376d)) -* **cmd:** add `outdated` command to check for newer feature versions ([#191](https://github.com/devsy-org/devsy/issues/191)) ([43fba26](https://github.com/devsy-org/devsy/commit/43fba2676a3fc071edc3d417e4b16e58775bc637)) -* **cmd:** add `set-up` command for BYOC container configuration ([#196](https://github.com/devsy-org/devsy/issues/196)) ([3eb488e](https://github.com/devsy-org/devsy/commit/3eb488e36b736b66e306a166e646815567ac913b)) -* **cmd:** add features info/resolve-deps/generate-docs commands ([#219](https://github.com/devsy-org/devsy/issues/219)) ([be8aeac](https://github.com/devsy-org/devsy/commit/be8aeac00425cf3a260785084bb8f0403e8f3836)) -* **cmd:** add generic TERM compatibility modes ([#490](https://github.com/devsy-org/devsy/issues/490)) ([42e54c2](https://github.com/devsy-org/devsy/commit/42e54c234a8b88ed0b0b5095ab5f0efbef1fda5e)) -* **cmd:** add hidden flag aliases for devcontainer CLI compat ([#200](https://github.com/devsy-org/devsy/issues/200)) ([7af1be2](https://github.com/devsy-org/devsy/commit/7af1be222ccd5aad462ce4064abfc98463275509)) -* **cmd:** add JSON result envelope on stdout for up/build/exec ([#199](https://github.com/devsy-org/devsy/issues/199)) ([75cec78](https://github.com/devsy-org/devsy/commit/75cec78cc88962fa8db193c25261ff42aaffa0c1)) -* **cmd:** add minor CLI flags ([#217](https://github.com/devsy-org/devsy/issues/217)) ([7d056fb](https://github.com/devsy-org/devsy/commit/7d056fbb7cf986d62029b7fc91027c4d96d4d115)) -* **cmd:** add newline separator to version output ([#425](https://github.com/devsy-org/devsy/issues/425)) ([d24f93c](https://github.com/devsy-org/devsy/commit/d24f93cfbdef1298071521d9ba40ef2cba3b1548)) -* **cmd:** add remaining minor flags ([#215](https://github.com/devsy-org/devsy/issues/215)) ([ec85a11](https://github.com/devsy-org/devsy/commit/ec85a119fd35f5e5f273157ecadf043be937cc20)) -* **cmd:** add run-user-commands lifecycle command ([#203](https://github.com/devsy-org/devsy/issues/203)) ([d2ca833](https://github.com/devsy-org/devsy/commit/d2ca8330b622b4f9c501027d86e7c2fdeefb639b)) -* **cmd:** add templates apply/publish/metadata/generate-docs commands ([#220](https://github.com/devsy-org/devsy/issues/220)) ([84d21c6](https://github.com/devsy-org/devsy/commit/84d21c6993ce6748024d13669456d246549c3439)) -* **cmd:** rename `upgrade` command to `self-update` ([#192](https://github.com/devsy-org/devsy/issues/192)) ([bb0c72f](https://github.com/devsy-org/devsy/commit/bb0c72f1689942f457582429a4ae48f2e74dedd7)) -* **cmd:** retrieve virtual machine instance description ([#602](https://github.com/devsy-org/devsy/issues/602)) ([1451fa1](https://github.com/devsy-org/devsy/commit/1451fa12b1b350bc1c3d1e19355d5b21ddfad9ba)) -* **compose:** add podman compose detection path ([#274](https://github.com/devsy-org/devsy/issues/274)) ([774ab5d](https://github.com/devsy-org/devsy/commit/774ab5d5941805fee431bb651d3cd46f75cdc48d)) -* **compose:** validate hostRequirements in Docker Compose path ([#247](https://github.com/devsy-org/devsy/issues/247)) ([7cd689f](https://github.com/devsy-org/devsy/commit/7cd689f30fc08f350b3a2d3284c08913912822a8)) -* **compose:** validate runServices against compose file services ([#211](https://github.com/devsy-org/devsy/issues/211)) ([db7f18a](https://github.com/devsy-org/devsy/commit/db7f18a0795ced9f631ade8e6e5714b673bde365)) -* **config:** add hostRequirements pre-flight validation ([#173](https://github.com/devsy-org/devsy/issues/173)) ([82cf6b0](https://github.com/devsy-org/devsy/commit/82cf6b0ba88d3849379f54e39c77b9da4ed3dc36)) -* **config:** add local-path extends support for devcontainer.json ([#184](https://github.com/devsy-org/devsy/issues/184)) ([b51dbf6](https://github.com/devsy-org/devsy/commit/b51dbf60143ad3b11a704fac332fbc8295cc69ec)) -* **config:** add oci:// prefix, multi-cloud auth, and digest caching to OCI extends ([#253](https://github.com/devsy-org/devsy/issues/253)) ([80f6170](https://github.com/devsy-org/devsy/commit/80f61702d9aea4375a98e46ce961223a3cd2545c)) -* **config:** add PathManager for XDG-compliant path computation ([#74](https://github.com/devsy-org/devsy/issues/74)) ([e477cf8](https://github.com/devsy-org/devsy/commit/e477cf83291451cc815ae0b9106158927f4976af)) -* **config:** add securityOpt passthrough to container create ([#169](https://github.com/devsy-org/devsy/issues/169)) ([3ef60f9](https://github.com/devsy-org/devsy/commit/3ef60f92456505e834fbfc6e7a7d5d5418fa4eb9)) -* **config:** derive devcontainerId from workspace folder per spec ([#195](https://github.com/devsy-org/devsy/issues/195)) ([d1895c5](https://github.com/devsy-org/devsy/commit/d1895c5368ae09ca9dabd093d04f2acbcedc2f84)) -* **config:** enforce phase-aware variable substitution scoping ([#249](https://github.com/devsy-org/devsy/issues/249)) ([8f74302](https://github.com/devsy-org/devsy/commit/8f743022838e20555a263710505aec2ecb668249)) -* **config:** implement spec-compliant devcontainerId derivation ([#252](https://github.com/devsy-org/devsy/issues/252)) ([d2ee4ab](https://github.com/devsy-org/devsy/commit/d2ee4ab6ca2b9b7bd668434f29b2ccbf8f4282a4)) -* **config:** parse and resolve devcontainer secrets property ([#83](https://github.com/devsy-org/devsy/issues/83)) ([64a6d4f](https://github.com/devsy-org/devsy/commit/64a6d4f52775a76ba480efb95e401fd2814ece23)) -* **config:** resolve variable substitution in extends paths ([#256](https://github.com/devsy-org/devsy/issues/256)) ([e73498e](https://github.com/devsy-org/devsy/commit/e73498e77a2d4c638e042b7a12d94c7abcdc3895)) -* **config:** support array form for extends property ([#188](https://github.com/devsy-org/devsy/issues/188)) ([da42f37](https://github.com/devsy-org/devsy/commit/da42f37fedad1ddf9ede0f20835290480c869272)) -* **config:** support custom workspaceMount from devcontainer.json ([#170](https://github.com/devsy-org/devsy/issues/170)) ([a7794f0](https://github.com/devsy-org/devsy/commit/a7794f01eff445528eddfc9f5695521f7b8d0ccf)) -* **config:** support forwardPorts range syntax expansion ([#168](https://github.com/devsy-org/devsy/issues/168)) ([1c618f1](https://github.com/devsy-org/devsy/commit/1c618f1b9b40a985783723b9b3659e05f5d471d6)) -* **config:** support OCI remote extends for devcontainer.json ([#190](https://github.com/devsy-org/devsy/issues/190)) ([8e1e7dd](https://github.com/devsy-org/devsy/commit/8e1e7ddc0d396d6d1f70578ff5ec20d5e4e581e3)) -* **delivery:** add KubernetesDelivery strategy for K8s agent binary injection ([#267](https://github.com/devsy-org/devsy/issues/267)) ([918ed99](https://github.com/devsy-org/devsy/commit/918ed99ea1331bfa1f0c9a8886d2ea91ead931a6)) -* **desktop:** add Electron desktop app ([#298](https://github.com/devsy-org/devsy/issues/298)) ([b01eae3](https://github.com/devsy-org/devsy/commit/b01eae3a2cd79a00e3aab21b19b5892a79caf303)) -* **devcontainer/setup:** open IDE before postAttachCommand runs ([#728](https://github.com/devsy-org/devsy/issues/728)) ([0ba9c1a](https://github.com/devsy-org/devsy/commit/0ba9c1aa1c47cc1fd80edaa75b2b410648ce76cd)) -* **devcontainer:** add stopCompose shutdownAction for compose containers ([#186](https://github.com/devsy-org/devsy/issues/186)) ([9ab288f](https://github.com/devsy-org/devsy/commit/9ab288f9ebf0d57241e0a5717e73a2f8374dd367)) -* **dockercredentials:** add Docker credential helper for agent ([#428](https://github.com/devsy-org/devsy/issues/428)) ([90dbaad](https://github.com/devsy-org/devsy/commit/90dbaad38d717f493c9fff82287f1e4089e5f423)) -* **driver/docker:** execute docker run in the workspace directory ([#498](https://github.com/devsy-org/devsy/issues/498)) ([19dbf79](https://github.com/devsy-org/devsy/commit/19dbf79a71ec2229e1bdaf1c6ac29c7d374ca7b7)) -* **driver:** guard BuildKit strategy against Podman runtime ([#270](https://github.com/devsy-org/devsy/issues/270)) ([01ef390](https://github.com/devsy-org/devsy/commit/01ef3909f1bf13a6a1496da63a5fe4bf6ab0da7c)) -* enable renaming providers ([#358](https://github.com/devsy-org/devsy/issues/358)) ([1c2b543](https://github.com/devsy-org/devsy/commit/1c2b54389f55bc429a94b8397cfc637a797fe738)) -* enforce hostRequirements validation with GPU support ([#292](https://github.com/devsy-org/devsy/issues/292)) ([9f49d77](https://github.com/devsy-org/devsy/commit/9f49d77515c99d3b29a022aca5bd43e749146151)) -* **envelope:** surface hostRequirements warnings in CLI result JSON ([#204](https://github.com/devsy-org/devsy/issues/204)) ([c62b068](https://github.com/devsy-org/devsy/commit/c62b068c30147784793194538f1eef4dde52af3d)) -* **exec:** add devcontainer spec compliance (workdir, user, remoteEnv, userEnvProbe) ([#162](https://github.com/devsy-org/devsy/issues/162)) ([94b3b9e](https://github.com/devsy-org/devsy/commit/94b3b9e0681c36ede40d568906e05e3c19114b68)) -* expand user home directory references in workspace source ([#499](https://github.com/devsy-org/devsy/issues/499)) ([15c75cc](https://github.com/devsy-org/devsy/commit/15c75cc93adfa030d64304e19dbc5c4488083c86)) -* expose compose project name as env var in containers ([#711](https://github.com/devsy-org/devsy/issues/711)) ([36c10c9](https://github.com/devsy-org/devsy/commit/36c10c9b8438d052339c24734f48554bd1c975ab)), closes [#456](https://github.com/devsy-org/devsy/issues/456) -* **feature:** add interactive prompting for secret options ([#291](https://github.com/devsy-org/devsy/issues/291)) ([6035a26](https://github.com/devsy-org/devsy/commit/6035a26517d3346ea11d466ba892e102c9f4654c)) -* **feature:** add OCI pull retry with URL sanitization ([#176](https://github.com/devsy-org/devsy/issues/176)) ([bce287e](https://github.com/devsy-org/devsy/commit/bce287ea912b5da71b0113fb2607ca8b820c9e6e)) -* **feature:** consume collection.json from OCI feature registries ([#214](https://github.com/devsy-org/devsy/issues/214)) ([80e7b08](https://github.com/devsy-org/devsy/commit/80e7b08331020bbf3e15a394df9d53d39f230e25)) -* **feature:** implement secret option handling ([#213](https://github.com/devsy-org/devsy/issues/213)) ([77431d7](https://github.com/devsy-org/devsy/commit/77431d7d7be644dd42ca5e48235c745ea5729cd1)) -* **feature:** parse OCI annotations from feature manifests ([#218](https://github.com/devsy-org/devsy/issues/218)) ([4208400](https://github.com/devsy-org/devsy/commit/42084009b4ff6ac825a215020378c735493afcfe)) -* **feature:** resolve legacy IDs during dependency resolution ([#206](https://github.com/devsy-org/devsy/issues/206)) ([f9dc6e3](https://github.com/devsy-org/devsy/commit/f9dc6e3d9899bc71ca247db575a75a93fbebb403)) -* **features:** add info manifest and info tags subcommands ([#289](https://github.com/devsy-org/devsy/issues/289)) ([2d4b112](https://github.com/devsy-org/devsy/commit/2d4b112b5fd90f84e9e5ad43e31494ad90352a0c)) -* **feature:** validate option type and enum constraints at install time ([#187](https://github.com/devsy-org/devsy/issues/187)) ([836062d](https://github.com/devsy-org/devsy/commit/836062dc024000acb15fe9ff98a145631c424664)) -* **feature:** version-aware feature equality ([#210](https://github.com/devsy-org/devsy/issues/210)) ([9f01c25](https://github.com/devsy-org/devsy/commit/9f01c25a0b89423cdd1e92a7c52eea02920d9797)) -* **git:** support includeIf conditional config via workspace directory context ([#296](https://github.com/devsy-org/devsy/issues/296)) ([6ef0418](https://github.com/devsy-org/devsy/commit/6ef0418fe100087a38d04ccf8cf9d7c948dfd6f1)) -* **graph:** implement round-based topological sort ([#201](https://github.com/devsy-org/devsy/issues/201)) ([7ddcfca](https://github.com/devsy-org/devsy/commit/7ddcfcac2a1e486292d2dc35ed95aebe749e93eb)) -* **ide/vscode:** improve VS Code server discovery ([#673](https://github.com/devsy-org/devsy/issues/673)) ([9f49d94](https://github.com/devsy-org/devsy/commit/9f49d9417f7af4d0d5f7aed0da03528ba56ca071)), closes [#639](https://github.com/devsy-org/devsy/issues/639) -* **metadata:** include containerEnv in label and warn on size limit ([#178](https://github.com/devsy-org/devsy/issues/178)) ([a148fb3](https://github.com/devsy-org/devsy/commit/a148fb3a1a90e46c85afee92f0dc9590da08de68)) -* **netstat:** wire portsAttributes into port forwarding watcher ([#202](https://github.com/devsy-org/devsy/issues/202)) ([2e93da4](https://github.com/devsy-org/devsy/commit/2e93da4487d472661d645906de23e3686888d8fd)) -* **obs:** add injection pipeline timing logs ([#147](https://github.com/devsy-org/devsy/issues/147)) ([6773838](https://github.com/devsy-org/devsy/commit/677383868ecc474d7cc0e6809a4cd70980ed8a22)) -* **port:** accept hostnames in SSH port forwarding ([#294](https://github.com/devsy-org/devsy/issues/294)) ([6832043](https://github.com/devsy-org/devsy/commit/6832043454f23ca70c0b9c05e1d22cf5fa2e0144)) -* **ports:** wire portsAttributes into forwarding decisions ([#248](https://github.com/devsy-org/devsy/issues/248)) ([90dee39](https://github.com/devsy-org/devsy/commit/90dee393b062cbe4e1e70592a0b6a6cd1f586f33)) -* **provider:** add built-in Podman provider ([#277](https://github.com/devsy-org/devsy/issues/277)) ([afbfd81](https://github.com/devsy-org/devsy/commit/afbfd81e13e1612fc647ea681cce02f834958aeb)) -* rebrand devpod/loft to devsy ([#1](https://github.com/devsy-org/devsy/issues/1)) ([f809604](https://github.com/devsy-org/devsy/commit/f8096040b681b00f2c6f2d42f76cec7eb970fc95)) -* replace PrintTable with lipgloss table renderer ([#716](https://github.com/devsy-org/devsy/issues/716)) ([6d6af55](https://github.com/devsy-org/devsy/commit/6d6af5546264b17a65d73e0ce6998c6a9eaaf2e6)) -* rewrite module deps from loft-sh to skevetter forks ([#726](https://github.com/devsy-org/devsy/issues/726)) ([28b39c2](https://github.com/devsy-org/devsy/commit/28b39c2df6318c51a5bf77131e94a46d0defdfee)) -* **runtime:** add ContainerRuntime abstraction interface ([#281](https://github.com/devsy-org/devsy/issues/281)) ([d74b492](https://github.com/devsy-org/devsy/commit/d74b492d20e72d23cd5bead58c042a55be9e15b5)) -* **tunnel:** add PipeBridge and ConnError primitives ([#137](https://github.com/devsy-org/devsy/issues/137)) ([395b50c](https://github.com/devsy-org/devsy/commit/395b50c77fb18aeaa58fa7d95234844874df600d)) -* **tunnel:** apply otherPortsAttributes defaults to unlisted ports ([#171](https://github.com/devsy-org/devsy/issues/171)) ([7828ec3](https://github.com/devsy-org/devsy/commit/7828ec3f263262c0ea2d2b2ffb3a69e735b9299e)) -* **tunnel:** extract PipeBridge and ConnError primitives, fix direct.go race ([#91](https://github.com/devsy-org/devsy/issues/91)) ([d639e53](https://github.com/devsy-org/devsy/commit/d639e537743f03a38fdf63f3f5849fd5bede1cfb)) -* **tunnel:** wire portsAttributes per-port settings into forwarding ([#172](https://github.com/devsy-org/devsy/issues/172)) ([11158bb](https://github.com/devsy-org/devsy/commit/11158bb67fb47232100f688af4386e4aa6c40afd)) -* **ui:** remove try devpod pro button and setting ([#463](https://github.com/devsy-org/devsy/issues/463)) ([62895c9](https://github.com/devsy-org/devsy/commit/62895c927f1609963ab327390bb6d27bdcd1ea92)) -* **up:** add --gpu-availability flag to override GPU detection ([#185](https://github.com/devsy-org/devsy/issues/185)) ([92b3cd7](https://github.com/devsy-org/devsy/commit/92b3cd7b5dec9da0a46a00cb067c4bc8ce1b7d27)) -* **up:** add --prebuild flag for devcontainer prebuild lifecycle ([#80](https://github.com/devsy-org/devsy/issues/80)) ([e6974ff](https://github.com/devsy-org/devsy/commit/e6974ff773f7ea5d78977ba8314c5cbb4814086e)) - - -### Bug Fixes - -* **agent/git_ssh_signature:** remove agent-forwarding and start-services flags ([#662](https://github.com/devsy-org/devsy/issues/662)) ([2738ef0](https://github.com/devsy-org/devsy/commit/2738ef005e5eb802fc2fdaf21456a02fa659e0d7)) -* **agent/git_ssh_signature:** ssh signature forwarding fails when signing ([#648](https://github.com/devsy-org/devsy/issues/648)) ([c52702b](https://github.com/devsy-org/devsy/commit/c52702b53d8f9de5caa874dab0ea2b8124c1fea5)) -* **build:** pass environment variables to flatpak-spawn wrapper ([#640](https://github.com/devsy-org/devsy/issues/640)) ([f370b5d](https://github.com/devsy-org/devsy/commit/f370b5d926a071735f78696b8c891eee2e5e25ce)) -* **build:** pass metadata labels to docker buildx build command ([#82](https://github.com/devsy-org/devsy/issues/82)) ([8d6d7c8](https://github.com/devsy-org/devsy/commit/8d6d7c8e5f140e0ac533e89d536c9fef1f493c8c)) -* **build:** wire devcontainer.json cacheFrom into docker build args ([#163](https://github.com/devsy-org/devsy/issues/163)) ([61b144a](https://github.com/devsy-org/devsy/commit/61b144a729bc7dcbcc311592cc50d7e00f449750)) -* capitalization of type bug in report ([#667](https://github.com/devsy-org/devsy/issues/667)) ([cfdbee4](https://github.com/devsy-org/devsy/commit/cfdbee411e05de8802bd5217b00712b6ed230c9b)) -* **ci:** disable rust-cache bin caching to fix macOS cargo resolution ([#288](https://github.com/devsy-org/devsy/issues/288)) ([bf7762d](https://github.com/devsy-org/devsy/commit/bf7762de0c3655f7bb084b440dffcb424d6cacae)) -* **ci:** install kind directly on Windows to avoid docker-desktop dep ([#261](https://github.com/devsy-org/devsy/issues/261)) ([e06bcf5](https://github.com/devsy-org/devsy/commit/e06bcf56e861d8853498afd0836a0fb0c7be0f3b)) -* **ci:** use goreleaser-action in act workflow to avoid Go version mismatch ([#122](https://github.com/devsy-org/devsy/issues/122)) ([c1ffa70](https://github.com/devsy-org/devsy/commit/c1ffa70b4b9ce851f9e0ca76915c8b8447e6ad79)) -* **cli:** make down command stop and delete containers per spec ([#153](https://github.com/devsy-org/devsy/issues/153)) ([1b24641](https://github.com/devsy-org/devsy/commit/1b24641886d2b91679b1aae358eb10323c7cc30d)) -* **cmd/machine:** linting errors ([#505](https://github.com/devsy-org/devsy/issues/505)) ([33e565f](https://github.com/devsy-org/devsy/commit/33e565f7701080c55d0d6ccf83934777dad1cfdc)) -* **cmd/ssh:** default ssh workdir to merged workspaceFolder ([#517](https://github.com/devsy-org/devsy/issues/517)) ([288c56d](https://github.com/devsy-org/devsy/commit/288c56d879dbf6fb0fc0fbd6d0cd79e503c3cffd)) -* **cmd:** GPG agent forwarding fails with SSH signing keys ([#732](https://github.com/devsy-org/devsy/issues/732)) ([fdd4906](https://github.com/devsy-org/devsy/commit/fdd4906d53191efbbbe226b853efea7c8d3abc81)) -* **compose:** podman with docker-compose stderr handling ([#618](https://github.com/devsy-org/devsy/issues/618)) ([aa90f6d](https://github.com/devsy-org/devsy/commit/aa90f6d82bd62c722e3e62df2c6d667ef7fccd26)) -* **compose:** surface helper error messages ([#462](https://github.com/devsy-org/devsy/issues/462)) ([b12f407](https://github.com/devsy-org/devsy/commit/b12f407aafa41e13f8a13b0b204a568612d71f42)) -* **config:** correct lifecycle hook merge ordering ([#236](https://github.com/devsy-org/devsy/issues/236)) ([a640dba](https://github.com/devsy-org/devsy/commit/a640dba777ec2098b0803f3f6166d6235be7c8b0)) -* **config:** correct portsAttributes JSON struct tag typo ([#81](https://github.com/devsy-org/devsy/issues/81)) ([93e0da3](https://github.com/devsy-org/devsy/commit/93e0da3f53ed403694c188479eda518f46c81ba9)) -* **config:** handle remoteEnv null values to unset variables ([#93](https://github.com/devsy-org/devsy/issues/93)) ([893db05](https://github.com/devsy-org/devsy/commit/893db0581dc9e36bbc91bf3bcb6412b092aa9811)) -* **config:** make shutdownAction defaults explicit in config resolution ([#259](https://github.com/devsy-org/devsy/issues/259)) ([01b5b82](https://github.com/devsy-org/devsy/commit/01b5b824969a6f37257a008323fe4114f017be85)) -* **config:** order feature hooks before image hooks per spec ([#197](https://github.com/devsy-org/devsy/issues/197)) ([d396b6b](https://github.com/devsy-org/devsy/commit/d396b6b30abfc7c6a7cc4cbbacc99ed4ec6ff7c4)) -* **config:** preserve colons in variable substitution default values ([#9](https://github.com/devsy-org/devsy/issues/9)) ([#94](https://github.com/devsy-org/devsy/issues/94)) ([97f2d96](https://github.com/devsy-org/devsy/commit/97f2d96aa4ac606a5c61029b822e0f717368a370)) -* **config:** remove unsupported ${env:VAR} variable substitution ([#194](https://github.com/devsy-org/devsy/issues/194)) ([b79d806](https://github.com/devsy-org/devsy/commit/b79d806f6ebdb469ef0971e908e0e2b30d0e7ab6)) -* **config:** resolve undefined variables to empty string ([#96](https://github.com/devsy-org/devsy/issues/96)) ([3701855](https://github.com/devsy-org/devsy/commit/37018553b144fd706ae4a943de793769f2b78d14)) -* **config:** support hostRequirements.gpu object format ([#117](https://github.com/devsy-org/devsy/issues/117)) ([377bac9](https://github.com/devsy-org/devsy/commit/377bac981152f26b3d441df44fe55d2f55c097da)) -* **config:** suppress workspace mount when workspaceMount is empty string ([#283](https://github.com/devsy-org/devsy/issues/283)) ([#287](https://github.com/devsy-org/devsy/issues/287)) ([2992939](https://github.com/devsy-org/devsy/commit/2992939fbfe4b75545cf84cb458ce2386a770024)) -* **config:** union hostRequirements across merge sources ([#121](https://github.com/devsy-org/devsy/issues/121)) ([b66c2a1](https://github.com/devsy-org/devsy/commit/b66c2a1029816bf748ac71fe26b19fea8baa75bd)) -* **conn:** plug goroutine leaks and WaitGroup race in ssh/agent packages ([#126](https://github.com/devsy-org/devsy/issues/126)) ([93c54e3](https://github.com/devsy-org/devsy/commit/93c54e31f72da1939f9797c7c26dc64302e28708)) -* **conn:** plug goroutine leaks and WaitGroup race in ssh/agent packages ([#90](https://github.com/devsy-org/devsy/issues/90)) ([b05020d](https://github.com/devsy-org/devsy/commit/b05020d6592e70d1d0223019fab027422e877876)) -* **credentials:** surface error responses from credential server endpoint ([#694](https://github.com/devsy-org/devsy/issues/694)) ([f2b481f](https://github.com/devsy-org/devsy/commit/f2b481fa73c1562aa58677e031b7197b32c8b23e)), closes [#645](https://github.com/devsy-org/devsy/issues/645) -* **daemon:** enforce shutdownAction property at runtime ([#88](https://github.com/devsy-org/devsy/issues/88)) ([ea9f774](https://github.com/devsy-org/devsy/commit/ea9f774c66d6f46d1335abe345e26772fd48fdac)) -* **daemon:** trust merge layer for ShutdownAction instead of re-defaulting ([#286](https://github.com/devsy-org/devsy/issues/286)) ([32e062a](https://github.com/devsy-org/devsy/commit/32e062a778aa4dbed5072566d3d7a1fb018ed82d)) -* **delivery:** clean up agent delivery volumes on workspace deletion ([#266](https://github.com/devsy-org/devsy/issues/266)) ([c75008c](https://github.com/devsy-org/devsy/commit/c75008cce548e32c4667504e3a4f7a70925ca6c9)) -* **delivery:** ensure target dir exists before docker cp ([#269](https://github.com/devsy-org/devsy/issues/269)) ([b39c2b4](https://github.com/devsy-org/devsy/commit/b39c2b4800cf81ca1d251e4a5110f37fb7487325)) -* **delivery:** support rootless Podman in volume direct copy ([#275](https://github.com/devsy-org/devsy/issues/275)) ([f489ccb](https://github.com/devsy-org/devsy/commit/f489ccb469174421a7d90ceebfda28822a600919)) -* **deps:** remove programming-language-detection dependency ([#695](https://github.com/devsy-org/devsy/issues/695)) ([bdc7124](https://github.com/devsy-org/devsy/commit/bdc7124b1d61de445581adc06d00d75433185a7e)) -* **deps:** update dependency @loft-enterprise/client to v4 ([#506](https://github.com/devsy-org/devsy/issues/506)) ([987ffad](https://github.com/devsy-org/devsy/commit/987ffad621734b3f6c4208d659241eff461c017e)) -* **deps:** update dependency @loft-enterprise/client to v4 ([#600](https://github.com/devsy-org/devsy/issues/600)) ([475efca](https://github.com/devsy-org/devsy/commit/475efca753945e6021e597147c20156ce44cee4c)) -* **deps:** update dependency @tauri-apps/plugin-shell to v2.3.5 ([#438](https://github.com/devsy-org/devsy/issues/438)) ([d7226e6](https://github.com/devsy-org/devsy/commit/d7226e680c47a99350b1f9e644514c8cdb734aa9)) -* **deps:** update dependency @tauri-apps/plugin-updater to v2.10.0 ([#441](https://github.com/devsy-org/devsy/issues/441)) ([19087c1](https://github.com/devsy-org/devsy/commit/19087c187b559c2ca7705573dc664c30c52a24fa)) -* **deps:** update dependency react-hook-form to v7.71.2 ([#562](https://github.com/devsy-org/devsy/issues/562)) ([6a6158a](https://github.com/devsy-org/devsy/commit/6a6158a375877c3f3652cbe9a5fed085a2b15a64)) -* **deps:** update github.com/google/go-containerregistry/pkg/authn/kubernetes digest to 0794660 ([#651](https://github.com/devsy-org/devsy/issues/651)) ([bcb9091](https://github.com/devsy-org/devsy/commit/bcb9091790e78c09ae2c8d2667a54d7f4b966481)) -* **deps:** update github.com/google/go-containerregistry/pkg/authn/kubernetes digest to 3888fb8 ([#621](https://github.com/devsy-org/devsy/issues/621)) ([870e6e3](https://github.com/devsy-org/devsy/commit/870e6e31e338fcff01a35d7663de78a11cfc8cd5)) -* **deps:** update github.com/google/go-containerregistry/pkg/authn/kubernetes digest to 400c263 ([#620](https://github.com/devsy-org/devsy/issues/620)) ([ebbc373](https://github.com/devsy-org/devsy/commit/ebbc373ca484810a884809b32f35979cff68fb1e)) -* **deps:** update github.com/google/go-containerregistry/pkg/authn/kubernetes digest to 47eedc9 ([#619](https://github.com/devsy-org/devsy/issues/619)) ([a27dae5](https://github.com/devsy-org/devsy/commit/a27dae5cc55599c919b4e91911515891055de2a3)) -* **deps:** update github.com/google/go-containerregistry/pkg/authn/kubernetes digest to 5b80281 ([#715](https://github.com/devsy-org/devsy/issues/715)) ([7873b67](https://github.com/devsy-org/devsy/commit/7873b67e7f5448fc0d72ca9dd51e224f4cd29310)) -* **deps:** update github.com/google/go-containerregistry/pkg/authn/kubernetes digest to 7a66278 ([#737](https://github.com/devsy-org/devsy/issues/737)) ([e78e2b7](https://github.com/devsy-org/devsy/commit/e78e2b740820aea175c11815ea0385dc4b0464b7)) -* **deps:** update github.com/google/go-containerregistry/pkg/authn/kubernetes digest to 85f2bf5 ([#538](https://github.com/devsy-org/devsy/issues/538)) ([91a3cf5](https://github.com/devsy-org/devsy/commit/91a3cf57784de0e9e45a38ae0e4bfa609b9755d3)) -* **deps:** update github.com/google/go-containerregistry/pkg/authn/kubernetes digest to 93aa273 ([#439](https://github.com/devsy-org/devsy/issues/439)) ([2866ef7](https://github.com/devsy-org/devsy/commit/2866ef7d75acf53bb508e093cc076c36227644c7)) -* **deps:** update github.com/google/go-containerregistry/pkg/authn/kubernetes digest to 9e0ccb0 ([#541](https://github.com/devsy-org/devsy/issues/541)) ([b685929](https://github.com/devsy-org/devsy/commit/b685929d1a63f6de1243af1dcda6389a7a494188)) -* **deps:** update github.com/google/go-containerregistry/pkg/authn/kubernetes digest to b6eadd8 ([#474](https://github.com/devsy-org/devsy/issues/474)) ([4745c03](https://github.com/devsy-org/devsy/commit/4745c03610eca98c4551f604185f400633145afc)) -* **deps:** update github.com/google/go-containerregistry/pkg/authn/kubernetes digest to bf0f710 ([#641](https://github.com/devsy-org/devsy/issues/641)) ([219fe9d](https://github.com/devsy-org/devsy/commit/219fe9d9f0ea724d2e47dd219455f76400d18395)) -* **deps:** update github.com/google/go-containerregistry/pkg/authn/kubernetes digest to e90447d ([#668](https://github.com/devsy-org/devsy/issues/668)) ([0d60f4b](https://github.com/devsy-org/devsy/commit/0d60f4b1384999d1d73a25fb73390d128a79d4ff)) -* **deps:** update k8s.io/utils digest to 28399d8 ([#631](https://github.com/devsy-org/devsy/issues/631)) ([f4fd4e9](https://github.com/devsy-org/devsy/commit/f4fd4e91a07bea418a25fb2b3e080dca35420700)) -* **deps:** update k8s.io/utils digest to b8788ab ([#467](https://github.com/devsy-org/devsy/issues/467)) ([eac3511](https://github.com/devsy-org/devsy/commit/eac351116e1827a3e1c391ded32e988c12dcb595)) -* **deps:** update kubernetes monorepo to v0.35.3 ([#632](https://github.com/devsy-org/devsy/issues/632)) ([d40d249](https://github.com/devsy-org/devsy/commit/d40d249587c4ba4469422a64011b9dcf1409b58d)) -* **deps:** update kubernetes packages to v0.35.1 ([#468](https://github.com/devsy-org/devsy/issues/468)) ([38b3cfd](https://github.com/devsy-org/devsy/commit/38b3cfd01a4ea2d6b5c77fe39b4eb9707564d1a5)) -* **deps:** update kubernetes packages to v0.35.2 ([#539](https://github.com/devsy-org/devsy/issues/539)) ([212b625](https://github.com/devsy-org/devsy/commit/212b6254140b4b3cd20195d49d657ab285cc83b1)) -* **deps:** update module charm.land/lipgloss/v2 to v2.0.2 ([#727](https://github.com/devsy-org/devsy/issues/727)) ([2613a0f](https://github.com/devsy-org/devsy/commit/2613a0f3220e0895ab22238edb71b49e9859b5b0)) -* **deps:** update module charm.land/lipgloss/v2 to v2.0.3 ([#735](https://github.com/devsy-org/devsy/issues/735)) ([f28dcb1](https://github.com/devsy-org/devsy/commit/f28dcb1b33701e02e45f403de11f32abedd8f0db)) -* **deps:** update module github.com/awslabs/amazon-ecr-credential-helper/ecr-login to v0.12.0 ([#540](https://github.com/devsy-org/devsy/issues/540)) ([5f473e2](https://github.com/devsy-org/devsy/commit/5f473e2b7aa4f63cd0c07a735069d5113876c84f)) -* **deps:** update module github.com/azure/azure-sdk-for-go/sdk/azcore to v1.21.0 ([#718](https://github.com/devsy-org/devsy/issues/718)) ([7e38d0a](https://github.com/devsy-org/devsy/commit/7e38d0aaf68949525c8317cf14504bc47d0d1087)) -* **deps:** update module github.com/charmbracelet/huh to v2 ([#723](https://github.com/devsy-org/devsy/issues/723)) ([3b87242](https://github.com/devsy-org/devsy/commit/3b872424436d2c628663973eb2e1c251a292fc0d)) -* **deps:** update module github.com/compose-spec/compose-go/v2 to v2.10.2 ([#672](https://github.com/devsy-org/devsy/issues/672)) ([9c397fe](https://github.com/devsy-org/devsy/commit/9c397fe38b69683a547f4000c4487a922d6d7d7b)) -* **deps:** update module github.com/docker/cli to v29.3.0+incompatible ([#580](https://github.com/devsy-org/devsy/issues/580)) ([991462d](https://github.com/devsy-org/devsy/commit/991462d7a7bfcb0a2d4b7158c77a4a9698e35d0d)) -* **deps:** update module github.com/google/go-containerregistry to v0.21.2 ([#543](https://github.com/devsy-org/devsy/issues/543)) ([12c6b63](https://github.com/devsy-org/devsy/commit/12c6b63f7c886e3608e06ed74f2a0ad56a6f8a9a)) -* **deps:** update module github.com/google/go-containerregistry to v0.21.3 ([#622](https://github.com/devsy-org/devsy/issues/622)) ([fc4b602](https://github.com/devsy-org/devsy/commit/fc4b602287e578ee467c2c4bc89881c020ec69e3)) -* **deps:** update module github.com/google/go-containerregistry to v0.21.5 ([#717](https://github.com/devsy-org/devsy/issues/717)) ([ed04623](https://github.com/devsy-org/devsy/commit/ed046239f2b12a2cc7c7409c7c933e93c7225bdb)) -* **deps:** update module github.com/loft-sh/agentapi/v4 to v4.7.0 ([#547](https://github.com/devsy-org/devsy/issues/547)) ([6fe7c4c](https://github.com/devsy-org/devsy/commit/6fe7c4c68c492718e25dcb733e2ee6e1eb97044f)) -* **deps:** update module github.com/loft-sh/agentapi/v4 to v4.7.1 ([#561](https://github.com/devsy-org/devsy/issues/561)) ([7413389](https://github.com/devsy-org/devsy/commit/7413389c9bed9cbb567225c4db055d9102914989)) -* **deps:** update module github.com/loft-sh/agentapi/v4 to v4.8.1 ([#669](https://github.com/devsy-org/devsy/issues/669)) ([4a7835c](https://github.com/devsy-org/devsy/commit/4a7835c64bcf8396ad98f34fa80d17d051c4d934)) -* **deps:** update module github.com/moby/buildkit to v0.28.0 ([#553](https://github.com/devsy-org/devsy/issues/553)) ([9a95f7f](https://github.com/devsy-org/devsy/commit/9a95f7fd6058b10009cca96a5f5155bdb66a72ec)) -* **deps:** update module github.com/moby/buildkit to v0.28.1 ([#642](https://github.com/devsy-org/devsy/issues/642)) ([139d061](https://github.com/devsy-org/devsy/commit/139d0614c57bcbce7302bb8ec2a4a303142462e0)) -* **deps:** update module github.com/moby/buildkit to v0.29.0 ([#689](https://github.com/devsy-org/devsy/issues/689)) ([c26fb2d](https://github.com/devsy-org/devsy/commit/c26fb2dc233173008f44610d4dd32c614b6aa2a7)) -* **deps:** update module github.com/skevetter/ssh to v0.1.0 ([#596](https://github.com/devsy-org/devsy/issues/596)) ([9873496](https://github.com/devsy-org/devsy/commit/9873496256bcfe7edc84ae758332c48473604ac3)) -* **deps:** update module github.com/tidwall/jsonc to v0.3.3 ([#634](https://github.com/devsy-org/devsy/issues/634)) ([09ef2e7](https://github.com/devsy-org/devsy/commit/09ef2e7df6ccbf945f9ce0c75f95fc127378f2e8)) -* **deps:** update module golang.org/x/crypto to v0.48.0 ([#470](https://github.com/devsy-org/devsy/issues/470)) ([a496fa2](https://github.com/devsy-org/devsy/commit/a496fa29cce9c20e13b5b1863fcf4343b8b78aca)) -* **deps:** update module golang.org/x/mod to v0.33.0 ([#472](https://github.com/devsy-org/devsy/issues/472)) ([62d77b8](https://github.com/devsy-org/devsy/commit/62d77b8bdd002de5871bcb597fc296f8418e33c9)) -* **deps:** update module golang.org/x/sys to v0.42.0 ([#594](https://github.com/devsy-org/devsy/issues/594)) ([7dcbae7](https://github.com/devsy-org/devsy/commit/7dcbae7131ddf4396f679e9641672108cf546396)) -* **deps:** update module google.golang.org/grpc to v1.79.0 ([#481](https://github.com/devsy-org/devsy/issues/481)) ([928cd45](https://github.com/devsy-org/devsy/commit/928cd4542f330ef0be44dcc19560cfee78d1a261)) -* **deps:** update module google.golang.org/grpc to v1.79.1 ([#486](https://github.com/devsy-org/devsy/issues/486)) ([35199d2](https://github.com/devsy-org/devsy/commit/35199d2f279427394748cece0d8c9557b67887ab)) -* **deps:** update module google.golang.org/grpc to v1.79.2 ([#579](https://github.com/devsy-org/devsy/issues/579)) ([b9d05dc](https://github.com/devsy-org/devsy/commit/b9d05dcedac61a0336e56297e2b8e9a7d4d634f3)) -* **deps:** update module google.golang.org/grpc to v1.79.3 ([#635](https://github.com/devsy-org/devsy/issues/635)) ([951527a](https://github.com/devsy-org/devsy/commit/951527a4685c6fbb65e1df7f8885f5c540a02aa1)) -* **deps:** update module google.golang.org/grpc to v1.80.0 ([#691](https://github.com/devsy-org/devsy/issues/691)) ([96a4ae9](https://github.com/devsy-org/devsy/commit/96a4ae9964172102b3982fd0db4d78045974dce0)) -* **deps:** update module k8s.io/klog/v2 to v2.140.0 ([#581](https://github.com/devsy-org/devsy/issues/581)) ([e2c1d6c](https://github.com/devsy-org/devsy/commit/e2c1d6c32ed23ea8f54f0e9cf0e757fdf79e4cfa)) -* **deps:** update module sigs.k8s.io/controller-runtime to v0.23.2 ([#567](https://github.com/devsy-org/devsy/issues/567)) ([ef70a92](https://github.com/devsy-org/devsy/commit/ef70a92dfd9976b6a4d3f25cebc91c9f0c79258e)) -* **deps:** update module sigs.k8s.io/controller-runtime to v0.23.3 ([#568](https://github.com/devsy-org/devsy/issues/568)) ([3aeed65](https://github.com/devsy-org/devsy/commit/3aeed655ce7514fb8058cc101c4a9be10e59a883)) -* **deps:** update module tailscale.com to v1.94.2 ([#502](https://github.com/devsy-org/devsy/issues/502)) ([273dc28](https://github.com/devsy-org/devsy/commit/273dc28cc1ee77a2a41b7a0c57dfefbef159a77f)) -* **deps:** update module tailscale.com to v1.96.0 ([#582](https://github.com/devsy-org/devsy/issues/582)) ([ba577ae](https://github.com/devsy-org/devsy/commit/ba577aed2f8440d32349fb8d841e1bbbe2240f85)) -* **deps:** update module tailscale.com to v1.96.5 ([#652](https://github.com/devsy-org/devsy/issues/652)) ([8ec0e80](https://github.com/devsy-org/devsy/commit/8ec0e804262f585ccbb418a81425d4508d660183)) -* **deps:** update tanstack-query monorepo to v4.43.0 ([#484](https://github.com/devsy-org/devsy/issues/484)) ([2fd88b1](https://github.com/devsy-org/devsy/commit/2fd88b1380e5ef0fbe03b6b1fc131acc380195f8)) -* **desktop:** strip newlines from environment variable ([#492](https://github.com/devsy-org/devsy/issues/492)) ([22ef145](https://github.com/devsy-org/devsy/commit/22ef145a9219b18f892374e5df217c2523dac5be)) -* **desktop:** tray icon for flatpaks ([#659](https://github.com/devsy-org/devsy/issues/659)) ([20d4ddb](https://github.com/devsy-org/devsy/commit/20d4ddbd4b7bfeb30191b4437d176f8599c9ea16)) -* **devcontainer/config:** parsing container environment variables during userenvprobe ([#497](https://github.com/devsy-org/devsy/issues/497)) ([4d79fa2](https://github.com/devsy-org/devsy/commit/4d79fa26092917f46ea453761a306c9712eed15e)) -* **devcontainer/feature:** resolve _REMOTE_USER from merged metadata during feature install ([#496](https://github.com/devsy-org/devsy/issues/496)) ([2a5ff5c](https://github.com/devsy-org/devsy/commit/2a5ff5c4825e25aa8d6104d91ab6b3c197e6a707)) -* **devcontainer/setup:** shell quoting for lifecycle commands ([#494](https://github.com/devsy-org/devsy/issues/494)) ([1ff0c8b](https://github.com/devsy-org/devsy/commit/1ff0c8b7c854586c74fde5b2b6254153c76f9936)) -* **devcontainer/single:** postStartCommand skipped after container restart ([#660](https://github.com/devsy-org/devsy/issues/660)) ([0d0206c](https://github.com/devsy-org/devsy/commit/0d0206c1a2d16397c4ad9c6d74f519562c9a39b9)) -* **devcontainer/sshtunnel:** eof handling in SSH execution and context cancellation ([#585](https://github.com/devsy-org/devsy/issues/585)) ([5938cea](https://github.com/devsy-org/devsy/commit/5938cea85aa45d43aa2e406bbabebad9c6a5004b)) -* **devcontainer:** compose builds when context differs from devcontainer path ([#493](https://github.com/devsy-org/devsy/issues/493)) ([2a590dc](https://github.com/devsy-org/devsy/commit/2a590dc0c0c0a49a6e444791e07e96d3d0b447d2)) -* **devcontainer:** compose mutation of shared local image tag ([#655](https://github.com/devsy-org/devsy/issues/655)) ([ba33e78](https://github.com/devsy-org/devsy/commit/ba33e78eef9f6f895bd99159154567b85c5e0767)) -* **devcontainer:** include feature containerEnv in metadata label and warn on parse failure ([#231](https://github.com/devsy-org/devsy/issues/231)) ([ad731d4](https://github.com/devsy-org/devsy/commit/ad731d4a36e115564b39e8565dd0f0c282434b27)) -* **devcontainer:** merge init environment variables to env ([#526](https://github.com/devsy-org/devsy/issues/526)) ([9230696](https://github.com/devsy-org/devsy/commit/9230696254525635a32b3ef60ec8a956007bd86d)) -* **devcontainer:** strip digest from compose feature build image refs ([#459](https://github.com/devsy-org/devsy/issues/459)) ([d916613](https://github.com/devsy-org/devsy/commit/d916613795d72a480bdef499e26ce37a4588b76a)) -* **docker:** detect GPU support via CDI for Podman runtimes ([#273](https://github.com/devsy-org/devsy/issues/273)) ([61d741d](https://github.com/devsy-org/devsy/commit/61d741df0e4117c6b2e644140f54198e431de3c4)) -* **docker:** restart and wait for container readiness before exec ([#688](https://github.com/devsy-org/devsy/issues/688)) ([b3b2fe6](https://github.com/devsy-org/devsy/commit/b3b2fe69e5c4b102396e1982a95582be3e8ae04a)) -* **docs:** rename devpod media files to devsy to fix broken images ([#4](https://github.com/devsy-org/devsy/issues/4)) ([a403e65](https://github.com/devsy-org/devsy/commit/a403e65a2e7b4cde53aa4eed2fc7dcecdbcdd225)) -* **docs:** rename missed devpod doc files and fix broken anchor links ([#3](https://github.com/devsy-org/devsy/issues/3)) ([2a6026e](https://github.com/devsy-org/devsy/commit/2a6026e9464227fcdaa0e555546cbb5ada3fcde3)) -* **driver/docker:** restore docker buildx build with fallback to buildkit ([#471](https://github.com/devsy-org/devsy/issues/471)) ([c24aa5d](https://github.com/devsy-org/devsy/commit/c24aa5d119a439c225a809588fbea9d567c5d7b1)) -* **driver/kubernetes:** unable to pull credentials for registry ([#430](https://github.com/devsy-org/devsy/issues/430)) ([32a3c93](https://github.com/devsy-org/devsy/commit/32a3c93d03e247dbf2e7a022c7e5c2873e18f0a3)) -* **e2e:** add comment noting devcontainer.json requirement for test repo ([#143](https://github.com/devsy-org/devsy/issues/143)) ([0f23b76](https://github.com/devsy-org/devsy/commit/0f23b761b807243d7dd3c3ebedee371a1d1d905e)) -* **e2e:** add retry logic for transient workspace lookup in port-forward test ([#123](https://github.com/devsy-org/devsy/issues/123)) ([d30b09e](https://github.com/devsy-org/devsy/commit/d30b09ec947dd081f6d22b52551118a032d2cf4c)) -* **e2e:** add SSH retry logic for flaky Windows WSL tests ([#115](https://github.com/devsy-org/devsy/issues/115)) ([d7c2ee4](https://github.com/devsy-org/devsy/commit/d7c2ee40d7705d4c6a8eff3517b82109e1f156a9)) -* **e2e:** add SSH retry logic for flaky Windows WSL tests ([#99](https://github.com/devsy-org/devsy/issues/99)) ([c5389c5](https://github.com/devsy-org/devsy/commit/c5389c5f7040d46ee7693d049d4933a6a467905e)) -* **e2e:** correct runServices error assertion ([#224](https://github.com/devsy-org/devsy/issues/224)) ([4465aa9](https://github.com/devsy-org/devsy/commit/4465aa99abda57bb63e20b5ca50384a290ab57f6)) -* **e2e:** increase machineprovider2 inactivity timeout from 5s to 30s ([#140](https://github.com/devsy-org/devsy/issues/140)) ([1a02cde](https://github.com/devsy-org/devsy/commit/1a02cde879f566e1d54c1d5a1167b08eef51dacb)) -* **e2e:** increase timeout for container-pull-heavy E2E tests ([#222](https://github.com/devsy-org/devsy/issues/222)) ([c9e438d](https://github.com/devsy-org/devsy/commit/c9e438d1a60b5e49211953add39a572176b2750b)) -* **e2e:** increase TimeoutShort from 2min to 3min ([#212](https://github.com/devsy-org/devsy/issues/212)) ([212e381](https://github.com/devsy-org/devsy/commit/212e3818d2d616d3819da132acbaa72a7e6ab33f)) -* **e2e:** migrate all test images to ghcr.io/devsy-org registry ([#146](https://github.com/devsy-org/devsy/issues/146)) ([9fce990](https://github.com/devsy-org/devsy/commit/9fce990dd44e7d2dc47fdb58ecffdaa1e75dcafd)) -* **e2e:** replace external devcontainer image with own registry test container ([#223](https://github.com/devsy-org/devsy/issues/223)) ([b4b1afa](https://github.com/devsy-org/devsy/commit/b4b1afac8e1441aa12ed6e705b2318cf2befe8a3)) -* **e2e:** replace MCR image reference with GHCR test image ([#125](https://github.com/devsy-org/devsy/issues/125)) ([ea4f1ed](https://github.com/devsy-org/devsy/commit/ea4f1edcf69ad6708939fa11231c23318a6ac219)) -* **e2e:** replace mcr.microsoft.com references with ghcr.io/devsy-org test images ([#241](https://github.com/devsy-org/devsy/issues/241)) ([143b86e](https://github.com/devsy-org/devsy/commit/143b86eba082786b4ee5bfd714716a9411e76927)) -* **exec:** use workspace UID for container lookup ([#160](https://github.com/devsy-org/devsy/issues/160)) ([b2af297](https://github.com/devsy-org/devsy/commit/b2af29745fc19322379d0a8b29794da2091a7ce8)) -* extend timeout when getting Docker credentials from host ([#575](https://github.com/devsy-org/devsy/issues/575)) ([50c203f](https://github.com/devsy-org/devsy/commit/50c203f9f827c552d29f02aa6c605b176316928e)) -* **extract:** add path traversal guard for tar extraction ([#92](https://github.com/devsy-org/devsy/issues/92)) ([ac70e7b](https://github.com/devsy-org/devsy/commit/ac70e7bd030ca62d3d8df62f2dda456c1ad74004)) -* **feature:** add SHA-256 integrity verification for direct tar downloads ([#89](https://github.com/devsy-org/devsy/issues/89)) ([ae95ec8](https://github.com/devsy-org/devsy/commit/ae95ec8e029504ef4b6fefcdce92c0600df4af9d)) -* **feature:** prevent false positive circular dependency detection for installsAfter ([#240](https://github.com/devsy-org/devsy/issues/240)) ([03e5cb1](https://github.com/devsy-org/devsy/commit/03e5cb149298c84c70d021a365f45e3d37b9bc0c)) -* **feature:** resolve lint failures in OCI annotations code ([#221](https://github.com/devsy-org/devsy/issues/221)) ([c368e1e](https://github.com/devsy-org/devsy/commit/c368e1eefa16d3351760ef3884f5b8b125786083)) -* **features:** enforce dependsOn constraints in overrideFeatureInstallOrder ([#151](https://github.com/devsy-org/devsy/issues/151)) ([7da82b8](https://github.com/devsy-org/devsy/commit/7da82b838ad75e6b1b44e5a566303ac1203041a0)) -* **flatpak:** grant xdg-run permissions to podman ([#450](https://github.com/devsy-org/devsy/issues/450)) ([40b723d](https://github.com/devsy-org/devsy/commit/40b723dcdc8d7ae07e2d108537c9cfb1d29396c0)) -* **graph:** use round-based topological sort in sortNodeIDsWithPriority ([#235](https://github.com/devsy-org/devsy/issues/235)) ([b3d0008](https://github.com/devsy-org/devsy/commit/b3d00083e78b58995c6758ed57dce5589ee7b3a2)) -* **ide/vscode:** extension installation in VS Code flavors ([#636](https://github.com/devsy-org/devsy/issues/636)) ([dca065b](https://github.com/devsy-org/devsy/commit/dca065b814048ead5c3788f6b0bd12dea2ec14b3)) -* **image:** sanitize HTML error pages in container registry responses ([#127](https://github.com/devsy-org/devsy/issues/127)) ([021184c](https://github.com/devsy-org/devsy/commit/021184cc8d08cac5366f5747be6afd8ec0d8b859)) -* **images:** resize cursor icon ([#650](https://github.com/devsy-org/devsy/issues/650)) ([5e92a90](https://github.com/devsy-org/devsy/commit/5e92a901a8b62b04099be657d76251892d0008e7)) -* **inject:** chmod binary before mv to prevent entrypoint race on Alpine ([#264](https://github.com/devsy-org/devsy/issues/264)) ([594f71c](https://github.com/devsy-org/devsy/commit/594f71ca4d571e6442958099b27bad61ceeb7f02)) -* **inject:** resolve goroutine race in pipe() bidirectional copy ([#139](https://github.com/devsy-org/devsy/issues/139)) ([51a9405](https://github.com/devsy-org/devsy/commit/51a9405d7a4a542ba567a7b0989e7d853b501dd1)) -* **lifecycle:** accept initializeCommand as a valid waitFor value ([#114](https://github.com/devsy-org/devsy/issues/114)) ([908300a](https://github.com/devsy-org/devsy/commit/908300a68ff15d9e14b278fee9d8db88bc33cb37)) -* **lifecycle:** accept initializeCommand as a valid waitFor value ([#98](https://github.com/devsy-org/devsy/issues/98)) ([4953b11](https://github.com/devsy-org/devsy/commit/4953b1132b163cb28094a9288b5628112ad62c53)) -* **lifecycle:** enforce waitFor property in lifecycle hook execution ([#87](https://github.com/devsy-org/devsy/issues/87)) ([f366335](https://github.com/devsy-org/devsy/commit/f366335818c36b684b1df1695bedb9715c6e39f2)) -* **lifecycle:** install dotfiles between postCreate and postStart ([#97](https://github.com/devsy-org/devsy/issues/97)) ([7b67e90](https://github.com/devsy-org/devsy/commit/7b67e9099f0eeaabae108062fe13f017e63efed7)) -* **lifecycle:** install dotfiles between postCreate and postStart ([#97](https://github.com/devsy-org/devsy/issues/97)) ([#112](https://github.com/devsy-org/devsy/issues/112)) ([fe8884b](https://github.com/devsy-org/devsy/commit/fe8884b16d0f37c70a37898c5924a7dd06ce0533)) -* **lifecycle:** resolve dotfiles race condition in deferred hooks ([#113](https://github.com/devsy-org/devsy/issues/113)) ([f72417d](https://github.com/devsy-org/devsy/commit/f72417dc957a9c9b75196b7ff7f397afe9bd714b)) -* **lifecycle:** run initializeCommand named sub-commands in parallel ([#100](https://github.com/devsy-org/devsy/issues/100)) ([a5e7e27](https://github.com/devsy-org/devsy/commit/a5e7e27b5c0927ab9cfb02fb5c2e8d2cd21e0976)) -* **lifecycle:** run initializeCommand named sub-commands in parallel ([#116](https://github.com/devsy-org/devsy/issues/116)) ([93f8171](https://github.com/devsy-org/devsy/commit/93f81715a181f3da24d8a1bd234d3cde63b8a7fa)) -* **lifecycle:** run named sub-commands in parallel within lifecycle hooks ([#95](https://github.com/devsy-org/devsy/issues/95)) ([bc4be89](https://github.com/devsy-org/devsy/commit/bc4be89178cff178066fd7ef34fa60fb3bbd9c41)) -* **lifecycle:** run postAttachCommand on every attach per spec ([#177](https://github.com/devsy-org/devsy/issues/177)) ([83d024c](https://github.com/devsy-org/devsy/commit/83d024cb6656463297225106dd64fb9c9187eac1)) -* **lifecycle:** surface deferred hook errors instead of swallowing them ([#189](https://github.com/devsy-org/devsy/issues/189)) ([b7fbfc9](https://github.com/devsy-org/devsy/commit/b7fbfc9a06e45adf34ada3d2df3b90538d58f09f)) -* **lifecycle:** warn when waitFor references phase with no commands ([#120](https://github.com/devsy-org/devsy/issues/120)) ([60f5b1a](https://github.com/devsy-org/devsy/commit/60f5b1a8dcc78b9a35171741ff97ad8822531ab9)) -* **lint:** remove nolint:gosec directives from templates and e2e tests ([#225](https://github.com/devsy-org/devsy/issues/225)) ([58d2ba8](https://github.com/devsy-org/devsy/commit/58d2ba8012099102a00720b1686a61c675c1a9b2)) -* **log:** bridge klog to zap backend via LogrSink ([#299](https://github.com/devsy-org/devsy/issues/299)) ([9b0073b](https://github.com/devsy-org/devsy/commit/9b0073b4a6bc6aca165e192ab4e162b7fce12fd7)) -* **log:** make global logger thread-safe with atomic.Pointer ([#155](https://github.com/devsy-org/devsy/issues/155)) ([7fdb0f4](https://github.com/devsy-org/devsy/commit/7fdb0f4480591584542f2f28a6279f361dd9f81f)) -* **netstat:** handle missing /proc/net/tcp6 on IPv6-disabled hosts ([#706](https://github.com/devsy-org/devsy/issues/706)) ([cb27dd4](https://github.com/devsy-org/devsy/commit/cb27dd469607f3252bac2b47a16e3cf6f413c641)) -* prevent stdout corruption in kubernetes e2e tests ([#24](https://github.com/devsy-org/devsy/issues/24)) ([ed3e252](https://github.com/devsy-org/devsy/commit/ed3e252aac936a1f8c5620d664858df0b6608c0a)) -* propagate GitSSHSigningKey in daemon path and thread context through backhaul ([#722](https://github.com/devsy-org/devsy/issues/722)) ([d543be9](https://github.com/devsy-org/devsy/commit/d543be92b35f2304a2d8efd4ca425a437b8f17c3)) -* rename flatpak files from DevPod/loft to Devsy ([#9](https://github.com/devsy-org/devsy/issues/9)) ([a884e7f](https://github.com/devsy-org/devsy/commit/a884e7f9bcc9ea10b59ff06fd8678124ddcbd834)) -* rename logo images and fix broken badge URL in README ([#10](https://github.com/devsy-org/devsy/issues/10)) ([58a85f8](https://github.com/devsy-org/devsy/commit/58a85f8a0ccdcf13301428e3ddca24903060325b)) -* resolve Git SSH signature forwarding failures ([#704](https://github.com/devsy-org/devsy/issues/704)) ([3cc1d02](https://github.com/devsy-org/devsy/commit/3cc1d02a1e4634d354f155ab5c3e8163257fd0b6)) -* resolve SSH signature key path for container-to-host forwarding ([#714](https://github.com/devsy-org/devsy/issues/714)) ([696b944](https://github.com/devsy-org/devsy/commit/696b94402909d9ecab305801dcb45069e05c0a75)) -* resolve unused rust warnings and spelling issues ([#700](https://github.com/devsy-org/devsy/issues/700)) ([45249fc](https://github.com/devsy-org/devsy/commit/45249fc8b3da3e57af0f36d8697818cf8ce84dbf)) -* **run:** respect user-specified consistency in workspaceMount ([#182](https://github.com/devsy-org/devsy/issues/182)) ([d7bb5ed](https://github.com/devsy-org/devsy/commit/d7bb5edd8a30dea117fcccd317713a5117ba4483)) -* sanitize AppImage environment before opening URLs ([#710](https://github.com/devsy-org/devsy/issues/710)) ([702c227](https://github.com/devsy-org/devsy/commit/702c227848d219735db7cf9ae136ca17488e6880)) -* **shell:** update module mvdan.cc/sh/v3 to v3.13.1 ([#692](https://github.com/devsy-org/devsy/issues/692)) ([8f8e5cd](https://github.com/devsy-org/devsy/commit/8f8e5cd7653850cb4169e749f3358eb6f22f687b)) -* **ssh/agent:** expand tilde in SSH_AUTH_SOCK path ([#674](https://github.com/devsy-org/devsy/issues/674)) ([4fb2d7b](https://github.com/devsy-org/devsy/commit/4fb2d7b962a6ab5f3a9d7505df034cd53dcd3fc4)), closes [#671](https://github.com/devsy-org/devsy/issues/671) -* **ssh/server:** disable PTY emulation to prevent terminal rendering issues in TUI programs ([#595](https://github.com/devsy-org/devsy/issues/595)) ([a26eb64](https://github.com/devsy-org/devsy/commit/a26eb646002223dc7ee040d5e58b5bae8d644ebe)) -* **ssh/server:** pseudo-tty signal handling ([#601](https://github.com/devsy-org/devsy/issues/601)) ([273ed5b](https://github.com/devsy-org/devsy/commit/273ed5b64e0e5db629ea0cdae563d323963ec3bb)) -* **ssh/server:** start PTY with the client terminal dimensions ([#583](https://github.com/devsy-org/devsy/issues/583)) ([f833edb](https://github.com/devsy-org/devsy/commit/f833edb85ada0a66e94c20b4398270fb6af8fba1)) -* **ssh:** skip file path signing keys in GPG agent forwarding ([#734](https://github.com/devsy-org/devsy/issues/734)) ([8f408e4](https://github.com/devsy-org/devsy/commit/8f408e42dbc492f0a0b64db24842ddf63132d0af)) -* **ssh:** use platform raw terminal handling for PTY sessions ([#698](https://github.com/devsy-org/devsy/issues/698)) ([ad7254f](https://github.com/devsy-org/devsy/commit/ad7254fd08eb2321956123cb811743294fbb69a4)) -* **test:** isolate GPG signing key unit tests from host git config ([#233](https://github.com/devsy-org/devsy/issues/233)) ([c6034f3](https://github.com/devsy-org/devsy/commit/c6034f32180a5dac8bc3b1d3a1126f96dcc593cc)) -* **tunnel:** do not error when user exits ssh connection ([#586](https://github.com/devsy-org/devsy/issues/586)) ([371e52e](https://github.com/devsy-org/devsy/commit/371e52e2bdbfc97eb1dc2fffb2d04085b7bbeab0)) -* **tunnel:** extract JSON log lines instead of double-wrapping them ([#141](https://github.com/devsy-org/devsy/issues/141)) ([43ceb3f](https://github.com/devsy-org/devsy/commit/43ceb3ffe3b84ffa15b01948bcc8411b51096767)) -* **tunnel:** PipeBridge shutdown and goroutine leak fixes ([#158](https://github.com/devsy-org/devsy/issues/158)) ([b91e15a](https://github.com/devsy-org/devsy/commit/b91e15aedc81fee0da18e94a0ce5cf1060512c51)) -* **tunnel:** resolve SSH handshake EOF race in container tunnel ([#86](https://github.com/devsy-org/devsy/issues/86)) ([81d5811](https://github.com/devsy-org/devsy/commit/81d5811eaa77c6b6ae09f6f57e681362ccf71cc4)) -* **ui:** add error handling to provider options form ([#625](https://github.com/devsy-org/devsy/issues/625)) ([167febf](https://github.com/devsy-org/devsy/commit/167febff3474c5d9de3bf20b6bddf1011aca8248)) -* **ui:** migrate to Tauri opener plugin for file downloads from app ([#627](https://github.com/devsy-org/devsy/issues/627)) ([ab54f8a](https://github.com/devsy-org/devsy/commit/ab54f8afb4f6d97e170ce2d10cb74e47a097293b)) -* **ui:** provider modal view issues when adding new providers ([#646](https://github.com/devsy-org/devsy/issues/646)) ([c005899](https://github.com/devsy-org/devsy/commit/c00589940a5063f34f25e6de1e17c8cb42a343e3)) -* **upgrade:** check if already up-to-date ([#559](https://github.com/devsy-org/devsy/issues/559)) ([ae7d61e](https://github.com/devsy-org/devsy/commit/ae7d61e7a83ada613e0b90176f33b8b6d7fb0b84)) -* **upgrade:** install correct binary release for operating system during selfupdate ([#535](https://github.com/devsy-org/devsy/issues/535)) ([62e38b8](https://github.com/devsy-org/devsy/commit/62e38b81cef998fcdecb0a8848cc53a8113064ac)) -* **upgrade:** trim 'v' prefix from current version check in Upgrade function ([#574](https://github.com/devsy-org/devsy/issues/574)) ([f18b6e2](https://github.com/devsy-org/devsy/commit/f18b6e27c72f84d5a54b4090f5254c241c047e23)) -* use docker-credentials endpoint for helper auth flow ([#478](https://github.com/devsy-org/devsy/issues/478)) ([6f54ce2](https://github.com/devsy-org/devsy/commit/6f54ce226faa1e7489bae17de4a84661e1fa94b5)) -* **ux:** add operation context to error messages at command boundary ([#133](https://github.com/devsy-org/devsy/issues/133)) ([8c6740f](https://github.com/devsy-org/devsy/commit/8c6740f42ed6a7c48aa7b512af9c52ee2155d8bb)) -* **ux:** include lifecycle phase name in hook error messages ([#132](https://github.com/devsy-org/devsy/issues/132)) ([bcdb2e0](https://github.com/devsy-org/devsy/commit/bcdb2e00947f3c1d7a7182ce046e3f37e879b7e8)) -* **ux:** prevent remote agent fatal log from killing local CLI ([#130](https://github.com/devsy-org/devsy/issues/130)) ([37a153e](https://github.com/devsy-org/devsy/commit/37a153e6ade10637b81be302c2a63995d33ed775)) -* **ux:** print error message on SSH/exec exit failures ([#128](https://github.com/devsy-org/devsy/issues/128)) ([61c84c9](https://github.com/devsy-org/devsy/commit/61c84c9e98da12e28bfe5aaa778e4992bc1797e2)) -* **ux:** propagate swallowed errors in workspace resolution ([#131](https://github.com/devsy-org/devsy/issues/131)) ([41d7d38](https://github.com/devsy-org/devsy/commit/41d7d385e08275861536374ba9c07744b215f655)) -* **ux:** remove duplicate error logging in feature downloads ([#135](https://github.com/devsy-org/devsy/issues/135)) ([bf5a96f](https://github.com/devsy-org/devsy/commit/bf5a96f446accb072ba8be31203a6eacfb74f40b)) -* **ux:** replace %w with %v in log format strings ([#129](https://github.com/devsy-org/devsy/issues/129)) ([7697411](https://github.com/devsy-org/devsy/commit/7697411984d68c60bb4c28ca6dc141bef60a3ced)) -* **ux:** use %w for proper error chain wrapping ([#134](https://github.com/devsy-org/devsy/issues/134)) ([1360313](https://github.com/devsy-org/devsy/commit/1360313f4136917c1dacd11941fb8a0237d0d9b9)) -* **workspace:** force-remove workspace folder with restrictive permissions ([#297](https://github.com/devsy-org/devsy/issues/297)) ([f8f41f6](https://github.com/devsy-org/devsy/commit/f8f41f6baf2e82e819b3acdf0390eb7d17ed0c99)) -* **workspace:** propagate findWorkspace errors and fix list append bug ([#124](https://github.com/devsy-org/devsy/issues/124)) ([81ab5f1](https://github.com/devsy-org/devsy/commit/81ab5f1d0170b4425723c0828d62859208a681a2)) - - -### Reverts - -* undo commits after 37018553b (PRs [#90](https://github.com/devsy-org/devsy/issues/90), [#91](https://github.com/devsy-org/devsy/issues/91), [#97](https://github.com/devsy-org/devsy/issues/97)-101) ([#111](https://github.com/devsy-org/devsy/issues/111)) ([ec11fbd](https://github.com/devsy-org/devsy/commit/ec11fbdf04137657eda22e8fc25bed39b0131ec2)) diff --git a/LICENSE b/LICENSE index a612ad981..df69d9dd9 100644 --- a/LICENSE +++ b/LICENSE @@ -1,373 +1,57 @@ -Mozilla Public License Version 2.0 -================================== +License text copyright (c) 2020 MariaDB Corporation Ab, All Rights Reserved. +"Business Source License" is a trademark of MariaDB Corporation Ab. -1. Definitions --------------- +Parameters -1.1. "Contributor" - means each individual or legal entity that creates, contributes to - the creation of, or owns Covered Software. +Licensor: Devsy +Licensed Work: Devsy. The Licensed Work is (c) 2026 Devsy. +Additional Use Grant: You may make non-commercial, personal use of the + Licensed Work. +Change Date: May 19, 2046 +Change License: Apache License, Version 2.0 -1.2. "Contributor Version" - means the combination of the Contributions of others (if any) used - by a Contributor and that particular Contributor's Contribution. +For information about alternative licensing arrangements for the Licensed Work, +please contact licensing@devsy.org. -1.3. "Contribution" - means Covered Software of a particular Contributor. +Notice -1.4. "Covered Software" - means Source Code Form to which the initial Contributor has attached - the notice in Exhibit A, the Executable Form of such Source Code - Form, and Modifications of such Source Code Form, in each case - including portions thereof. +Business Source License 1.1 -1.5. "Incompatible With Secondary Licenses" - means +Terms - (a) that the initial Contributor has attached the notice described - in Exhibit B to the Covered Software; or +The Licensor hereby grants you the right to copy, modify, create derivative +works, redistribute, and make non-production use of the Licensed Work. The +Licensor may make an Additional Use Grant, above, permitting limited production use. - (b) that the Covered Software was made available under the terms of - version 1.1 or earlier of the License, but not also under the - terms of a Secondary License. +Effective on the Change Date, the Licensor hereby grants you rights under +the terms of the Change License, and the rights granted in the paragraph +above terminate. -1.6. "Executable Form" - means any form of the work other than Source Code Form. +If your use of the Licensed Work does not comply with the requirements +currently in effect as described in this License, you must purchase a +commercial license from the Licensor, its affiliated entities, or authorized +resellers, or you must refrain from using the Licensed Work. -1.7. "Larger Work" - means a work that combines Covered Software with other material, in - a separate file or files, that is not Covered Software. +All copies of the original and modified Licensed Work, and derivative works +of the Licensed Work, are subject to this License. This License applies +separately for each version of the Licensed Work and the Change Date may vary +for each version of the Licensed Work released by Licensor. -1.8. "License" - means this document. +You must conspicuously display this License on each original or modified copy +of the Licensed Work. If you receive the Licensed Work in original or +modified form from a third party, the terms and conditions set forth in this +License apply to your use of that work. -1.9. "Licensable" - means having the right to grant, to the maximum extent possible, - whether at the time of the initial grant or subsequently, any and - all of the rights conveyed by this License. +Any use of the Licensed Work in violation of this License will automatically +terminate your rights under this License for the current and all other +versions of the Licensed Work. -1.10. "Modifications" - means any of the following: +This License does not grant you any right in any trademark or logo of +Licensor or its affiliates (provided that you may use a trademark or logo of +Licensor as expressly required by this License). - (a) any file in Source Code Form that results from an addition to, - deletion from, or modification of the contents of Covered - Software; or - - (b) any new file in Source Code Form that contains any Covered - Software. - -1.11. "Patent Claims" of a Contributor - means any patent claim(s), including without limitation, method, - process, and apparatus claims, in any patent Licensable by such - Contributor that would be infringed, but for the grant of the - License, by the making, using, selling, offering for sale, having - made, import, or transfer of either its Contributions or its - Contributor Version. - -1.12. "Secondary License" - means either the GNU General Public License, Version 2.0, the GNU - Lesser General Public License, Version 2.1, the GNU Affero General - Public License, Version 3.0, or any later versions of those - licenses. - -1.13. "Source Code Form" - means the form of the work preferred for making modifications. - -1.14. "You" (or "Your") - means an individual or a legal entity exercising rights under this - License. For legal entities, "You" includes any entity that - controls, is controlled by, or is under common control with You. For - purposes of this definition, "control" means (a) the power, direct - or indirect, to cause the direction or management of such entity, - whether by contract or otherwise, or (b) ownership of more than - fifty percent (50%) of the outstanding shares or beneficial - ownership of such entity. - -2. License Grants and Conditions --------------------------------- - -2.1. Grants - -Each Contributor hereby grants You a world-wide, royalty-free, -non-exclusive license: - -(a) under intellectual property rights (other than patent or trademark) - Licensable by such Contributor to use, reproduce, make available, - modify, display, perform, distribute, and otherwise exploit its - Contributions, either on an unmodified basis, with Modifications, or - as part of a Larger Work; and - -(b) under Patent Claims of such Contributor to make, use, sell, offer - for sale, have made, import, and otherwise transfer either its - Contributions or its Contributor Version. - -2.2. Effective Date - -The licenses granted in Section 2.1 with respect to any Contribution -become effective for each Contribution on the date the Contributor first -distributes such Contribution. - -2.3. Limitations on Grant Scope - -The licenses granted in this Section 2 are the only rights granted under -this License. No additional rights or licenses will be implied from the -distribution or licensing of Covered Software under this License. -Notwithstanding Section 2.1(b) above, no patent license is granted by a -Contributor: - -(a) for any code that a Contributor has removed from Covered Software; - or - -(b) for infringements caused by: (i) Your and any other third party's - modifications of Covered Software, or (ii) the combination of its - Contributions with other software (except as part of its Contributor - Version); or - -(c) under Patent Claims infringed by Covered Software in the absence of - its Contributions. - -This License does not grant any rights in the trademarks, service marks, -or logos of any Contributor (except as may be necessary to comply with -the notice requirements in Section 3.4). - -2.4. Subsequent Licenses - -No Contributor makes additional grants as a result of Your choice to -distribute the Covered Software under a subsequent version of this -License (see Section 10.2) or under the terms of a Secondary License (if -permitted under the terms of Section 3.3). - -2.5. Representation - -Each Contributor represents that the Contributor believes its -Contributions are its original creation(s) or it has sufficient rights -to grant the rights to its Contributions conveyed by this License. - -2.6. Fair Use - -This License is not intended to limit any rights You have under -applicable copyright doctrines of fair use, fair dealing, or other -equivalents. - -2.7. Conditions - -Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted -in Section 2.1. - -3. Responsibilities -------------------- - -3.1. Distribution of Source Form - -All distribution of Covered Software in Source Code Form, including any -Modifications that You create or to which You contribute, must be under -the terms of this License. You must inform recipients that the Source -Code Form of the Covered Software is governed by the terms of this -License, and how they can obtain a copy of this License. You may not -attempt to alter or restrict the recipients' rights in the Source Code -Form. - -3.2. Distribution of Executable Form - -If You distribute Covered Software in Executable Form then: - -(a) such Covered Software must also be made available in Source Code - Form, as described in Section 3.1, and You must inform recipients of - the Executable Form how they can obtain a copy of such Source Code - Form by reasonable means in a timely manner, at a charge no more - than the cost of distribution to the recipient; and - -(b) You may distribute such Executable Form under the terms of this - License, or sublicense it under different terms, provided that the - license for the Executable Form does not attempt to limit or alter - the recipients' rights in the Source Code Form under this License. - -3.3. Distribution of a Larger Work - -You may create and distribute a Larger Work under terms of Your choice, -provided that You also comply with the requirements of this License for -the Covered Software. If the Larger Work is a combination of Covered -Software with a work governed by one or more Secondary Licenses, and the -Covered Software is not Incompatible With Secondary Licenses, this -License permits You to additionally distribute such Covered Software -under the terms of such Secondary License(s), so that the recipient of -the Larger Work may, at their option, further distribute the Covered -Software under the terms of either this License or such Secondary -License(s). - -3.4. Notices - -You may not remove or alter the substance of any license notices -(including copyright notices, patent notices, disclaimers of warranty, -or limitations of liability) contained within the Source Code Form of -the Covered Software, except that You may alter any license notices to -the extent required to remedy known factual inaccuracies. - -3.5. Application of Additional Terms - -You may choose to offer, and to charge a fee for, warranty, support, -indemnity or liability obligations to one or more recipients of Covered -Software. However, You may do so only on Your own behalf, and not on -behalf of any Contributor. You must make it absolutely clear that any -such warranty, support, indemnity, or liability obligation is offered by -You alone, and You hereby agree to indemnify every Contributor for any -liability incurred by such Contributor as a result of warranty, support, -indemnity or liability terms You offer. You may include additional -disclaimers of warranty and limitations of liability specific to any -jurisdiction. - -4. Inability to Comply Due to Statute or Regulation ---------------------------------------------------- - -If it is impossible for You to comply with any of the terms of this -License with respect to some or all of the Covered Software due to -statute, judicial order, or regulation then You must: (a) comply with -the terms of this License to the maximum extent possible; and (b) -describe the limitations and the code they affect. Such description must -be placed in a text file included with all distributions of the Covered -Software under this License. Except to the extent prohibited by statute -or regulation, such description must be sufficiently detailed for a -recipient of ordinary skill to be able to understand it. - -5. Termination --------------- - -5.1. The rights granted under this License will terminate automatically -if You fail to comply with any of its terms. However, if You become -compliant, then the rights granted under this License from a particular -Contributor are reinstated (a) provisionally, unless and until such -Contributor explicitly and finally terminates Your grants, and (b) on an -ongoing basis, if such Contributor fails to notify You of the -non-compliance by some reasonable means prior to 60 days after You have -come back into compliance. Moreover, Your grants from a particular -Contributor are reinstated on an ongoing basis if such Contributor -notifies You of the non-compliance by some reasonable means, this is the -first time You have received notice of non-compliance with this License -from such Contributor, and You become compliant prior to 30 days after -Your receipt of the notice. - -5.2. If You initiate litigation against any entity by asserting a patent -infringement claim (excluding declaratory judgment actions, -counter-claims, and cross-claims) alleging that a Contributor Version -directly or indirectly infringes any patent, then the rights granted to -You by any and all Contributors for the Covered Software under Section -2.1 of this License shall terminate. - -5.3. In the event of termination under Sections 5.1 or 5.2 above, all -end user license agreements (excluding distributors and resellers) which -have been validly granted by You or Your distributors under this License -prior to termination shall survive termination. - -************************************************************************ -* * -* 6. Disclaimer of Warranty * -* ------------------------- * -* * -* Covered Software is provided under this License on an "as is" * -* basis, without warranty of any kind, either expressed, implied, or * -* statutory, including, without limitation, warranties that the * -* Covered Software is free of defects, merchantable, fit for a * -* particular purpose or non-infringing. The entire risk as to the * -* quality and performance of the Covered Software is with You. * -* Should any Covered Software prove defective in any respect, You * -* (not any Contributor) assume the cost of any necessary servicing, * -* repair, or correction. This disclaimer of warranty constitutes an * -* essential part of this License. No use of any Covered Software is * -* authorized under this License except under this disclaimer. * -* * -************************************************************************ - -************************************************************************ -* * -* 7. Limitation of Liability * -* -------------------------- * -* * -* Under no circumstances and under no legal theory, whether tort * -* (including negligence), contract, or otherwise, shall any * -* Contributor, or anyone who distributes Covered Software as * -* permitted above, be liable to You for any direct, indirect, * -* special, incidental, or consequential damages of any character * -* including, without limitation, damages for lost profits, loss of * -* goodwill, work stoppage, computer failure or malfunction, or any * -* and all other commercial damages or losses, even if such party * -* shall have been informed of the possibility of such damages. This * -* limitation of liability shall not apply to liability for death or * -* personal injury resulting from such party's negligence to the * -* extent applicable law prohibits such limitation. Some * -* jurisdictions do not allow the exclusion or limitation of * -* incidental or consequential damages, so this exclusion and * -* limitation may not apply to You. * -* * -************************************************************************ - -8. Litigation -------------- - -Any litigation relating to this License may be brought only in the -courts of a jurisdiction where the defendant maintains its principal -place of business and such litigation shall be governed by laws of that -jurisdiction, without reference to its conflict-of-law provisions. -Nothing in this Section shall prevent a party's ability to bring -cross-claims or counter-claims. - -9. Miscellaneous ----------------- - -This License represents the complete agreement concerning the subject -matter hereof. If any provision of this License is held to be -unenforceable, such provision shall be reformed only to the extent -necessary to make it enforceable. Any law or regulation which provides -that the language of a contract shall be construed against the drafter -shall not be used to construe this License against a Contributor. - -10. Versions of the License ---------------------------- - -10.1. New Versions - -Mozilla Foundation is the license steward. Except as provided in Section -10.3, no one other than the license steward has the right to modify or -publish new versions of this License. Each version will be given a -distinguishing version number. - -10.2. Effect of New Versions - -You may distribute the Covered Software under the terms of the version -of the License under which You originally received the Covered Software, -or under the terms of any subsequent version published by the license -steward. - -10.3. Modified Versions - -If you create software not governed by this License, and you want to -create a new license for such software, you may create and use a -modified version of this License if you rename the license and remove -any references to the name of the license steward (except to note that -such modified license differs from this License). - -10.4. Distributing Source Code Form that is Incompatible With Secondary -Licenses - -If You choose to distribute Source Code Form that is Incompatible With -Secondary Licenses under the terms of this version of the License, the -notice described in Exhibit B of this License must be attached. - -Exhibit A - Source Code Form License Notice -------------------------------------------- - - This Source Code Form is subject to the terms of the Mozilla Public - License, v. 2.0. If a copy of the MPL was not distributed with this - file, You can obtain one at http://mozilla.org/MPL/2.0/. - -If it is not possible or desirable to put the notice in a particular -file, then You may include the notice in a location (such as a LICENSE -file in a relevant directory) where a recipient would be likely to look -for such a notice. - -You may add additional accurate notices of copyright ownership. - -Exhibit B - "Incompatible With Secondary Licenses" Notice ---------------------------------------------------------- - - This Source Code Form is "Incompatible With Secondary Licenses", as - defined by the Mozilla Public License, v. 2.0. +TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON +AN "AS IS" BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, +EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND +TITLE. diff --git a/README.md b/README.md index c174bee86..afe1a170f 100644 --- a/README.md +++ b/README.md @@ -149,8 +149,8 @@ VS Code in its various flavors and the full JetBrains suite are supported, all o No need to install a server backend, Devsy runs only on your computer. -Open-Source
-Devsy is 100% open-source and extensible. A provider doesn't exist? Just create your own. +Extensible
+Devsy is source-available and extensible. A provider doesn't exist? Just create your own. diff --git a/cmd/agent/workspace/clean.go b/cmd/agent/workspace/clean.go new file mode 100644 index 000000000..10e2e9ada --- /dev/null +++ b/cmd/agent/workspace/clean.go @@ -0,0 +1,119 @@ +package workspace + +import ( + "context" + "fmt" + "os/exec" + "strings" + + "github.com/devsy-org/devsy/cmd/flags" + "github.com/devsy-org/devsy/pkg/log" + "github.com/spf13/cobra" +) + +const ( + cleanVolumePrefix = "devsy-agent-" + cleanVolumeMountPath = "/opt/devsy" + cleanBinaryName = "devsy" + cleanHelperImage = "busybox:latest" + cleanDefaultDockerCmd = "docker" +) + +// CleanCmd holds the cmd flags. +type CleanCmd struct { + *flags.GlobalFlags + + DockerCommand string + HelperImage string +} + +// NewCleanCmd creates a new command. +func NewCleanCmd(globalFlags *flags.GlobalFlags) *cobra.Command { + cmd := &CleanCmd{ + GlobalFlags: globalFlags, + } + cleanCmd := &cobra.Command{ + Use: "clean [workspace-id]", + Short: "Removes the agent binary from the Docker volume for a workspace", + Long: `Removes the agent binary from the Docker named volume for the specified workspace. +This forces a fresh binary injection on the next workspace start.`, + Args: cobra.ExactArgs(1), + RunE: func(cobraCmd *cobra.Command, args []string) error { + return cmd.Run(cobraCmd.Context(), args[0]) + }, + } + cleanCmd.Flags(). + StringVar(&cmd.DockerCommand, "docker-command", cleanDefaultDockerCmd, "Docker command to use") + cleanCmd.Flags(). + StringVar(&cmd.HelperImage, "helper-image", cleanHelperImage, "Helper image for volume operations") + return cleanCmd +} + +func (cmd *CleanCmd) Run(ctx context.Context, workspaceID string) error { + if workspaceID == "" { + return fmt.Errorf("workspace ID must not be empty") + } + + volumeName := cleanVolumePrefix + workspaceID + log.Infof("Removing agent binary from volume %s", volumeName) + + if err := cmd.removeBinaryFromVolume(ctx, volumeName); err != nil { + return fmt.Errorf("remove agent binary from volume %s: %w", volumeName, err) + } + + log.Infof("Successfully removed agent binary from volume %s", volumeName) + return nil +} + +func (cmd *CleanCmd) removeBinaryFromVolume(ctx context.Context, volumeName string) error { + if err := cmd.checkVolumeExists(ctx, volumeName); err != nil { + return err + } + + binaryPath := cleanVolumeMountPath + "/" + cleanBinaryName + script := fmt.Sprintf(`rm -f "%s"`, binaryPath) + args := []string{ + "run", "--rm", + "-v", volumeName + ":" + cleanVolumeMountPath, + cmd.helperImage(), + "sh", "-c", script, + } + + out, err := cmd.dockerCmd(ctx, args...).CombinedOutput() + if err != nil { + return fmt.Errorf("docker run failed: %s: %w", strings.TrimSpace(string(out)), err) + } + return nil +} + +func (cmd *CleanCmd) checkVolumeExists(ctx context.Context, volumeName string) error { + out, err := cmd.dockerCmd(ctx, "volume", "inspect", volumeName).CombinedOutput() + if err != nil { + return fmt.Errorf( + "volume %s not found (is Docker running?): %s: %w", + volumeName, + strings.TrimSpace(string(out)), + err, + ) + } + return nil +} + +func (cmd *CleanCmd) dockerCmd(ctx context.Context, args ...string) *exec.Cmd { + // #nosec G204 -- args are constructed internally, not from user input + return exec.CommandContext(ctx, cmd.dockerCommand(), args...) +} + +func (cmd *CleanCmd) dockerCommand() string { + if cmd.DockerCommand != "" { + return cmd.DockerCommand + } + return cleanDefaultDockerCmd +} + +func (cmd *CleanCmd) helperImage() string { + if cmd.HelperImage != "" { + return cmd.HelperImage + } + return cleanHelperImage +} diff --git a/cmd/agent/workspace/clean_test.go b/cmd/agent/workspace/clean_test.go new file mode 100644 index 000000000..70877bdb9 --- /dev/null +++ b/cmd/agent/workspace/clean_test.go @@ -0,0 +1,124 @@ +package workspace + +import ( + "context" + "os" + "path/filepath" + "testing" + + "github.com/devsy-org/devsy/cmd/flags" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestCleanCmd_EmptyWorkspaceID(t *testing.T) { + cmd := &CleanCmd{GlobalFlags: &flags.GlobalFlags{}} + err := cmd.Run(context.Background(), "") + require.Error(t, err) + assert.Contains(t, err.Error(), "must not be empty") +} + +func TestCleanCmd_VolumeNotFound(t *testing.T) { + tmpDir := t.TempDir() + + scriptPath := filepath.Join(tmpDir, "fake-docker.sh") + script := "#!/bin/sh\necho 'no such volume' >&2; exit 1\n" + require.NoError(t, os.WriteFile(scriptPath, []byte(script), 0o600)) + // #nosec G302 -- test script must be executable + require.NoError(t, os.Chmod(scriptPath, 0o755)) + + cmd := &CleanCmd{ + GlobalFlags: &flags.GlobalFlags{}, + DockerCommand: scriptPath, + } + err := cmd.Run(context.Background(), "nonexistent-ws") + require.Error(t, err) + assert.Contains(t, err.Error(), "not found") +} + +func TestCleanCmd_RemoveBinarySuccess(t *testing.T) { + tmpDir := t.TempDir() + + scriptPath := filepath.Join(tmpDir, "fake-docker.sh") + markerPath := filepath.Join(tmpDir, "rm-called") + script := "#!/bin/sh\n" + + "case \"$1\" in\n" + + " volume) echo '{}' ;;\n" + + " run) touch \"" + markerPath + "\" ;;\n" + + " *) exit 1 ;;\n" + + "esac\n" + require.NoError(t, os.WriteFile(scriptPath, []byte(script), 0o600)) + // #nosec G302 -- test script must be executable + require.NoError(t, os.Chmod(scriptPath, 0o755)) + + cmd := &CleanCmd{ + GlobalFlags: &flags.GlobalFlags{}, + DockerCommand: scriptPath, + } + err := cmd.Run(context.Background(), "test-workspace-123") + require.NoError(t, err) + + _, statErr := os.Stat(markerPath) + assert.NoError(t, statErr, "docker run should have been called to remove the binary") +} + +func TestCleanCmd_DockerRunFails(t *testing.T) { + tmpDir := t.TempDir() + + scriptPath := filepath.Join(tmpDir, "fake-docker.sh") + script := "#!/bin/sh\n" + + "case \"$1\" in\n" + + " volume) echo '{}' ;;\n" + + " run) echo 'container error' >&2; exit 1 ;;\n" + + " *) exit 1 ;;\n" + + "esac\n" + require.NoError(t, os.WriteFile(scriptPath, []byte(script), 0o600)) + // #nosec G302 -- test script must be executable + require.NoError(t, os.Chmod(scriptPath, 0o755)) + + cmd := &CleanCmd{ + GlobalFlags: &flags.GlobalFlags{}, + DockerCommand: scriptPath, + } + err := cmd.Run(context.Background(), "test-workspace") + require.Error(t, err) + assert.Contains(t, err.Error(), "docker run failed") +} + +func TestCleanCmd_VolumeName(t *testing.T) { + assert.Equal(t, "devsy-agent-", cleanVolumePrefix) + assert.Equal(t, "devsy-agent-my-ws", cleanVolumePrefix+"my-ws") +} + +func TestCleanCmd_HelperImage_Default(t *testing.T) { + cmd := &CleanCmd{GlobalFlags: &flags.GlobalFlags{}} + assert.Equal(t, "busybox:latest", cmd.helperImage()) +} + +func TestCleanCmd_HelperImage_Custom(t *testing.T) { + cmd := &CleanCmd{ + GlobalFlags: &flags.GlobalFlags{}, + HelperImage: "alpine:latest", + } + assert.Equal(t, "alpine:latest", cmd.helperImage()) +} + +func TestCleanCmd_DockerCommand_Default(t *testing.T) { + cmd := &CleanCmd{GlobalFlags: &flags.GlobalFlags{}} + assert.Equal(t, "docker", cmd.dockerCommand()) +} + +func TestCleanCmd_DockerCommand_Custom(t *testing.T) { + cmd := &CleanCmd{ + GlobalFlags: &flags.GlobalFlags{}, + DockerCommand: "podman", + } + assert.Equal(t, "podman", cmd.dockerCommand()) +} + +func TestNewCleanCmd_CobraSetup(t *testing.T) { + cobraCmd := NewCleanCmd(&flags.GlobalFlags{}) + assert.Equal(t, "clean [workspace-id]", cobraCmd.Use) + assert.NotEmpty(t, cobraCmd.Short) + assert.NotEmpty(t, cobraCmd.Long) +} diff --git a/cmd/agent/workspace/workspace.go b/cmd/agent/workspace/workspace.go index 15378e4d9..dfdfe9261 100644 --- a/cmd/agent/workspace/workspace.go +++ b/cmd/agent/workspace/workspace.go @@ -22,5 +22,6 @@ func NewWorkspaceCmd(flags *flags.GlobalFlags) *cobra.Command { workspaceCmd.AddCommand(NewInstallDotfilesCmd(flags)) workspaceCmd.AddCommand(NewSetupGPGCmd(flags)) workspaceCmd.AddCommand(NewLogsCmd(flags)) + workspaceCmd.AddCommand(NewCleanCmd(flags)) return workspaceCmd } diff --git a/docs/pages/what-is-devsy.mdx b/docs/pages/what-is-devsy.mdx index 452462d9a..6328c0887 100644 --- a/docs/pages/what-is-devsy.mdx +++ b/docs/pages/what-is-devsy.mdx @@ -32,6 +32,6 @@ Compared to hosted services such as GitHub Codespaces, JetBrains Spaces or Googl * **Local development**: You get the same developer experience also locally, so you don't need to rely on a cloud provider at all. * **Cross-IDE support**: VS Code in its various flavors and the full JetBrains suite are supported, all others can be connected through SSH. * **Client-only**: No need to install a server backend, Devsy runs solely on your computer. -* **Open-Source**: Devsy is 100% open-source and extensible. A provider doesn't exist? Just create your own. +* **Extensible**: Devsy is source-available and extensible. A provider doesn't exist? Just create your own. * **Rich feature set**: Devsy already supports prebuilds, auto inactivity shutdown, git & docker credentials sync and many more features to come. * **Desktop App**: Devsy comes with an easy-to-use desktop application that abstracts all the complexity away. If you want to build your own integration, Devsy offers a feature-rich CLI as well. diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 000000000..43575e818 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,5873 @@ +{ + "name": "devsy", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "devsy", + "dependencies": { + "@semantic-release/changelog": "^6.0.3", + "@semantic-release/git": "^10.0.1" + }, + "devDependencies": { + "@biomejs/biome": "2.4.12", + "semantic-release": "^24.2.3" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.0.tgz", + "integrity": "sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw==", + "license": "MIT", + "dependencies": { + "@babel/helper-validator-identifier": "^7.28.5", + "js-tokens": "^4.0.0", + "picocolors": "^1.1.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz", + "integrity": "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@biomejs/biome": { + "version": "2.4.12", + "resolved": "https://registry.npmjs.org/@biomejs/biome/-/biome-2.4.12.tgz", + "integrity": "sha512-Rro7adQl3NLq/zJCIL98eElXKI8eEiBtoeu5TbXF/U3qbjuSc7Jb5rjUbeHHcquDWeSf3HnGP7XI5qGrlRk/pA==", + "dev": true, + "license": "MIT OR Apache-2.0", + "bin": { + "biome": "bin/biome" + }, + "engines": { + "node": ">=14.21.3" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/biome" + }, + "optionalDependencies": { + "@biomejs/cli-darwin-arm64": "2.4.12", + "@biomejs/cli-darwin-x64": "2.4.12", + "@biomejs/cli-linux-arm64": "2.4.12", + "@biomejs/cli-linux-arm64-musl": "2.4.12", + "@biomejs/cli-linux-x64": "2.4.12", + "@biomejs/cli-linux-x64-musl": "2.4.12", + "@biomejs/cli-win32-arm64": "2.4.12", + "@biomejs/cli-win32-x64": "2.4.12" + } + }, + "node_modules/@biomejs/cli-darwin-arm64": { + "version": "2.4.12", + "resolved": "https://registry.npmjs.org/@biomejs/cli-darwin-arm64/-/cli-darwin-arm64-2.4.12.tgz", + "integrity": "sha512-BnMU4Pc3ciEVteVpZ0BK33MLr7X57F5w1dwDLDn+/iy/yTrA4Q/N2yftidFtsA4vrDh0FMXDpacNV/Tl3fbmng==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT OR Apache-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=14.21.3" + } + }, + "node_modules/@biomejs/cli-darwin-x64": { + "version": "2.4.12", + "resolved": "https://registry.npmjs.org/@biomejs/cli-darwin-x64/-/cli-darwin-x64-2.4.12.tgz", + "integrity": "sha512-x9uJ0bI1rJsWICp3VH8w/5PnAVD3A7SqzDpbrfoUQX1QyWrK5jSU4fRLo/wSgGeplCivbxBRKmt5Xq4/nWvq8A==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT OR Apache-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=14.21.3" + } + }, + "node_modules/@biomejs/cli-linux-arm64": { + "version": "2.4.12", + "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-arm64/-/cli-linux-arm64-2.4.12.tgz", + "integrity": "sha512-tOwuCuZZtKi1jVzbk/5nXmIsziOB6yqN8c9r9QM0EJYPU6DpQWf11uBOSCfFKKM4H3d9ZoarvlgMfbcuD051Pw==", + "cpu": [ + "arm64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT OR Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=14.21.3" + } + }, + "node_modules/@biomejs/cli-linux-arm64-musl": { + "version": "2.4.12", + "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-arm64-musl/-/cli-linux-arm64-musl-2.4.12.tgz", + "integrity": "sha512-FhfpkAAlKL6kwvcVap0Hgp4AhZmtd3YImg0kK1jd7C/aSoh4SfsB2f++yG1rU0lr8Y5MCFJrcSkmssiL9Xnnig==", + "cpu": [ + "arm64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT OR Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=14.21.3" + } + }, + "node_modules/@biomejs/cli-linux-x64": { + "version": "2.4.12", + "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-x64/-/cli-linux-x64-2.4.12.tgz", + "integrity": "sha512-8pFeAnLU9QdW9jCIslB/v82bI0lhBmz2ZAKc8pVMFPO0t0wAHsoEkrUQUbMkIorTRIjbqyNZHA3lEXavsPWYSw==", + "cpu": [ + "x64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT OR Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=14.21.3" + } + }, + "node_modules/@biomejs/cli-linux-x64-musl": { + "version": "2.4.12", + "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-x64-musl/-/cli-linux-x64-musl-2.4.12.tgz", + "integrity": "sha512-dwTIgZrGutzhkQCuvHynCkyW6hJxUuyZqKKO0YNfaS2GUoRO+tOvxXZqZB6SkWAOdfZTzwaw8IEdUnIkHKHoew==", + "cpu": [ + "x64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT OR Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=14.21.3" + } + }, + "node_modules/@biomejs/cli-win32-arm64": { + "version": "2.4.12", + "resolved": "https://registry.npmjs.org/@biomejs/cli-win32-arm64/-/cli-win32-arm64-2.4.12.tgz", + "integrity": "sha512-B0DLnx0vA9ya/3v7XyCaP+/lCpnbWbMOfUFFve+xb5OxyYvdHaS55YsSddr228Y+JAFk58agCuZTsqNiw2a6ig==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT OR Apache-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=14.21.3" + } + }, + "node_modules/@biomejs/cli-win32-x64": { + "version": "2.4.12", + "resolved": "https://registry.npmjs.org/@biomejs/cli-win32-x64/-/cli-win32-x64-2.4.12.tgz", + "integrity": "sha512-yMckRzTyZ83hkk8iDFWswqSdU8tvZxspJKnYNh7JZr/zhZNOlzH13k4ecboU6MurKExCe2HUkH75pGI/O2JwGA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT OR Apache-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=14.21.3" + } + }, + "node_modules/@colors/colors": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz", + "integrity": "sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">=0.1.90" + } + }, + "node_modules/@octokit/auth-token": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-6.0.0.tgz", + "integrity": "sha512-P4YJBPdPSpWTQ1NU4XYdvHvXJJDxM6YwpS0FZHRgP7YFkdVxsWcpWGy/NVqlAA7PcPCnMacXlRm1y2PFZRWL/w==", + "license": "MIT", + "engines": { + "node": ">= 20" + } + }, + "node_modules/@octokit/core": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/@octokit/core/-/core-7.0.6.tgz", + "integrity": "sha512-DhGl4xMVFGVIyMwswXeyzdL4uXD5OGILGX5N8Y+f6W7LhC1Ze2poSNrkF/fedpVDHEEZ+PHFW0vL14I+mm8K3Q==", + "license": "MIT", + "dependencies": { + "@octokit/auth-token": "^6.0.0", + "@octokit/graphql": "^9.0.3", + "@octokit/request": "^10.0.6", + "@octokit/request-error": "^7.0.2", + "@octokit/types": "^16.0.0", + "before-after-hook": "^4.0.0", + "universal-user-agent": "^7.0.0" + }, + "engines": { + "node": ">= 20" + } + }, + "node_modules/@octokit/endpoint": { + "version": "11.0.3", + "resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-11.0.3.tgz", + "integrity": "sha512-FWFlNxghg4HrXkD3ifYbS/IdL/mDHjh9QcsNyhQjN8dplUoZbejsdpmuqdA76nxj2xoWPs7p8uX2SNr9rYu0Ag==", + "license": "MIT", + "dependencies": { + "@octokit/types": "^16.0.0", + "universal-user-agent": "^7.0.2" + }, + "engines": { + "node": ">= 20" + } + }, + "node_modules/@octokit/graphql": { + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-9.0.3.tgz", + "integrity": "sha512-grAEuupr/C1rALFnXTv6ZQhFuL1D8G5y8CN04RgrO4FIPMrtm+mcZzFG7dcBm+nq+1ppNixu+Jd78aeJOYxlGA==", + "license": "MIT", + "dependencies": { + "@octokit/request": "^10.0.6", + "@octokit/types": "^16.0.0", + "universal-user-agent": "^7.0.0" + }, + "engines": { + "node": ">= 20" + } + }, + "node_modules/@octokit/openapi-types": { + "version": "27.0.0", + "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-27.0.0.tgz", + "integrity": "sha512-whrdktVs1h6gtR+09+QsNk2+FO+49j6ga1c55YZudfEG+oKJVvJLQi3zkOm5JjiUXAagWK2tI2kTGKJ2Ys7MGA==", + "license": "MIT" + }, + "node_modules/@octokit/plugin-paginate-rest": { + "version": "13.2.1", + "resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-13.2.1.tgz", + "integrity": "sha512-Tj4PkZyIL6eBMYcG/76QGsedF0+dWVeLhYprTmuFVVxzDW7PQh23tM0TP0z+1MvSkxB29YFZwnUX+cXfTiSdyw==", + "license": "MIT", + "dependencies": { + "@octokit/types": "^15.0.1" + }, + "engines": { + "node": ">= 20" + }, + "peerDependencies": { + "@octokit/core": ">=6" + } + }, + "node_modules/@octokit/plugin-paginate-rest/node_modules/@octokit/openapi-types": { + "version": "26.0.0", + "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-26.0.0.tgz", + "integrity": "sha512-7AtcfKtpo77j7Ts73b4OWhOZHTKo/gGY8bB3bNBQz4H+GRSWqx2yvj8TXRsbdTE0eRmYmXOEY66jM7mJ7LzfsA==", + "license": "MIT" + }, + "node_modules/@octokit/plugin-paginate-rest/node_modules/@octokit/types": { + "version": "15.0.2", + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-15.0.2.tgz", + "integrity": "sha512-rR+5VRjhYSer7sC51krfCctQhVTmjyUMAaShfPB8mscVa8tSoLyon3coxQmXu0ahJoLVWl8dSGD/3OGZlFV44Q==", + "license": "MIT", + "dependencies": { + "@octokit/openapi-types": "^26.0.0" + } + }, + "node_modules/@octokit/plugin-retry": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@octokit/plugin-retry/-/plugin-retry-8.1.0.tgz", + "integrity": "sha512-O1FZgXeiGb2sowEr/hYTr6YunGdSAFWnr2fyW39Ah85H8O33ELASQxcvOFF5LE6Tjekcyu2ms4qAzJVhSaJxTw==", + "license": "MIT", + "dependencies": { + "@octokit/request-error": "^7.0.2", + "@octokit/types": "^16.0.0", + "bottleneck": "^2.15.3" + }, + "engines": { + "node": ">= 20" + }, + "peerDependencies": { + "@octokit/core": ">=7" + } + }, + "node_modules/@octokit/plugin-throttling": { + "version": "11.0.3", + "resolved": "https://registry.npmjs.org/@octokit/plugin-throttling/-/plugin-throttling-11.0.3.tgz", + "integrity": "sha512-34eE0RkFCKycLl2D2kq7W+LovheM/ex3AwZCYN8udpi6bxsyjZidb2McXs69hZhLmJlDqTSP8cH+jSRpiaijBg==", + "license": "MIT", + "dependencies": { + "@octokit/types": "^16.0.0", + "bottleneck": "^2.15.3" + }, + "engines": { + "node": ">= 20" + }, + "peerDependencies": { + "@octokit/core": "^7.0.0" + } + }, + "node_modules/@octokit/request": { + "version": "10.0.9", + "resolved": "https://registry.npmjs.org/@octokit/request/-/request-10.0.9.tgz", + "integrity": "sha512-o8Bi3f608eyM+7BmBiUWxFsdjLb3/ym1cQek5LZOv9KkZcxRrHCPhhRzm6xjO6HVZ85ItD6+sTsjxo821SVa/A==", + "license": "MIT", + "dependencies": { + "@octokit/endpoint": "^11.0.3", + "@octokit/request-error": "^7.0.2", + "@octokit/types": "^16.0.0", + "content-type": "^2.0.0", + "fast-content-type-parse": "^3.0.0", + "json-with-bigint": "^3.5.3", + "universal-user-agent": "^7.0.2" + }, + "engines": { + "node": ">= 20" + } + }, + "node_modules/@octokit/request-error": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-7.1.0.tgz", + "integrity": "sha512-KMQIfq5sOPpkQYajXHwnhjCC0slzCNScLHs9JafXc4RAJI+9f+jNDlBNaIMTvazOPLgb4BnlhGJOTbnN0wIjPw==", + "license": "MIT", + "dependencies": { + "@octokit/types": "^16.0.0" + }, + "engines": { + "node": ">= 20" + } + }, + "node_modules/@octokit/types": { + "version": "16.0.0", + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-16.0.0.tgz", + "integrity": "sha512-sKq+9r1Mm4efXW1FCk7hFSeJo4QKreL/tTbR0rz/qx/r1Oa2VV83LTA/H/MuCOX7uCIJmQVRKBcbmWoySjAnSg==", + "license": "MIT", + "dependencies": { + "@octokit/openapi-types": "^27.0.0" + } + }, + "node_modules/@pnpm/config.env-replace": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@pnpm/config.env-replace/-/config.env-replace-1.1.0.tgz", + "integrity": "sha512-htyl8TWnKL7K/ESFa1oW2UB5lVDxuF5DpM7tBi6Hu2LNL3mWkIzNLG6N4zoCUP1lCKNxWy/3iu8mS8MvToGd6w==", + "license": "MIT", + "engines": { + "node": ">=12.22.0" + } + }, + "node_modules/@pnpm/network.ca-file": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@pnpm/network.ca-file/-/network.ca-file-1.0.2.tgz", + "integrity": "sha512-YcPQ8a0jwYU9bTdJDpXjMi7Brhkr1mXsXrUJvjqM2mQDgkRiz8jFaQGOdaLxgjtUfQgZhKy/O3cG/YwmgKaxLA==", + "license": "MIT", + "dependencies": { + "graceful-fs": "4.2.10" + }, + "engines": { + "node": ">=12.22.0" + } + }, + "node_modules/@pnpm/network.ca-file/node_modules/graceful-fs": { + "version": "4.2.10", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", + "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==", + "license": "ISC" + }, + "node_modules/@pnpm/npm-conf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@pnpm/npm-conf/-/npm-conf-3.0.2.tgz", + "integrity": "sha512-h104Kh26rR8tm+a3Qkc5S4VLYint3FE48as7+/5oCEcKR2idC/pF1G6AhIXKI+eHPJa/3J9i5z0Al47IeGHPkA==", + "license": "MIT", + "dependencies": { + "@pnpm/config.env-replace": "^1.1.0", + "@pnpm/network.ca-file": "^1.0.1", + "config-chain": "^1.1.11" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@sec-ant/readable-stream": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@sec-ant/readable-stream/-/readable-stream-0.4.1.tgz", + "integrity": "sha512-831qok9r2t8AlxLko40y2ebgSDhenenCatLVeW/uBtnHPyhHOvG0C7TvfgecV+wHzIm5KUICgzmVpWS+IMEAeg==", + "license": "MIT" + }, + "node_modules/@semantic-release/changelog": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/@semantic-release/changelog/-/changelog-6.0.3.tgz", + "integrity": "sha512-dZuR5qByyfe3Y03TpmCvAxCyTnp7r5XwtHRf/8vD9EAn4ZWbavUX8adMtXYzE86EVh0gyLA7lm5yW4IV30XUag==", + "license": "MIT", + "dependencies": { + "@semantic-release/error": "^3.0.0", + "aggregate-error": "^3.0.0", + "fs-extra": "^11.0.0", + "lodash": "^4.17.4" + }, + "engines": { + "node": ">=14.17" + }, + "peerDependencies": { + "semantic-release": ">=18.0.0" + } + }, + "node_modules/@semantic-release/changelog/node_modules/@semantic-release/error": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@semantic-release/error/-/error-3.0.0.tgz", + "integrity": "sha512-5hiM4Un+tpl4cKw3lV4UgzJj+SmfNIDCLLw0TepzQxz9ZGV5ixnqkzIVF+3tp0ZHgcMKE+VNGHJjEeyFG2dcSw==", + "license": "MIT", + "engines": { + "node": ">=14.17" + } + }, + "node_modules/@semantic-release/changelog/node_modules/aggregate-error": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", + "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", + "license": "MIT", + "dependencies": { + "clean-stack": "^2.0.0", + "indent-string": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@semantic-release/changelog/node_modules/clean-stack": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", + "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/@semantic-release/changelog/node_modules/indent-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/@semantic-release/commit-analyzer": { + "version": "13.0.1", + "resolved": "https://registry.npmjs.org/@semantic-release/commit-analyzer/-/commit-analyzer-13.0.1.tgz", + "integrity": "sha512-wdnBPHKkr9HhNhXOhZD5a2LNl91+hs8CC2vsAVYxtZH3y0dV3wKn+uZSN61rdJQZ8EGxzWB3inWocBHV9+u/CQ==", + "license": "MIT", + "dependencies": { + "conventional-changelog-angular": "^8.0.0", + "conventional-changelog-writer": "^8.0.0", + "conventional-commits-filter": "^5.0.0", + "conventional-commits-parser": "^6.0.0", + "debug": "^4.0.0", + "import-from-esm": "^2.0.0", + "lodash-es": "^4.17.21", + "micromatch": "^4.0.2" + }, + "engines": { + "node": ">=20.8.1" + }, + "peerDependencies": { + "semantic-release": ">=20.1.0" + } + }, + "node_modules/@semantic-release/error": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@semantic-release/error/-/error-4.0.0.tgz", + "integrity": "sha512-mgdxrHTLOjOddRVYIYDo0fR3/v61GNN1YGkfbrjuIKg/uMgCd+Qzo3UAXJ+woLQQpos4pl5Esuw5A7AoNlzjUQ==", + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/@semantic-release/git": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/@semantic-release/git/-/git-10.0.1.tgz", + "integrity": "sha512-eWrx5KguUcU2wUPaO6sfvZI0wPafUKAMNC18aXY4EnNcrZL86dEmpNVnC9uMpGZkmZJ9EfCVJBQx4pV4EMGT1w==", + "license": "MIT", + "dependencies": { + "@semantic-release/error": "^3.0.0", + "aggregate-error": "^3.0.0", + "debug": "^4.0.0", + "dir-glob": "^3.0.0", + "execa": "^5.0.0", + "lodash": "^4.17.4", + "micromatch": "^4.0.0", + "p-reduce": "^2.0.0" + }, + "engines": { + "node": ">=14.17" + }, + "peerDependencies": { + "semantic-release": ">=18.0.0" + } + }, + "node_modules/@semantic-release/git/node_modules/@semantic-release/error": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@semantic-release/error/-/error-3.0.0.tgz", + "integrity": "sha512-5hiM4Un+tpl4cKw3lV4UgzJj+SmfNIDCLLw0TepzQxz9ZGV5ixnqkzIVF+3tp0ZHgcMKE+VNGHJjEeyFG2dcSw==", + "license": "MIT", + "engines": { + "node": ">=14.17" + } + }, + "node_modules/@semantic-release/git/node_modules/aggregate-error": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", + "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", + "license": "MIT", + "dependencies": { + "clean-stack": "^2.0.0", + "indent-string": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@semantic-release/git/node_modules/clean-stack": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", + "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/@semantic-release/git/node_modules/execa": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", + "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", + "license": "MIT", + "dependencies": { + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.0", + "human-signals": "^2.1.0", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.1", + "onetime": "^5.1.2", + "signal-exit": "^3.0.3", + "strip-final-newline": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "node_modules/@semantic-release/git/node_modules/human-signals": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", + "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", + "license": "Apache-2.0", + "engines": { + "node": ">=10.17.0" + } + }, + "node_modules/@semantic-release/git/node_modules/indent-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/@semantic-release/git/node_modules/is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@semantic-release/git/node_modules/mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/@semantic-release/git/node_modules/npm-run-path": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", + "license": "MIT", + "dependencies": { + "path-key": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@semantic-release/git/node_modules/onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "license": "MIT", + "dependencies": { + "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@semantic-release/git/node_modules/p-reduce": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/p-reduce/-/p-reduce-2.1.0.tgz", + "integrity": "sha512-2USApvnsutq8uoxZBGbbWM0JIYLiEMJ9RlaN7fAzVNb9OZN0SHjjTTfIcb667XynS5Y1VhwDJVDa72TnPzAYWw==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/@semantic-release/git/node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "license": "ISC" + }, + "node_modules/@semantic-release/git/node_modules/strip-final-newline": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", + "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/@semantic-release/github": { + "version": "11.0.6", + "resolved": "https://registry.npmjs.org/@semantic-release/github/-/github-11.0.6.tgz", + "integrity": "sha512-ctDzdSMrT3H+pwKBPdyCPty6Y47X8dSrjd3aPZ5KKIKKWTwZBE9De8GtsH3TyAlw3Uyo2stegMx6rJMXKpJwJA==", + "license": "MIT", + "dependencies": { + "@octokit/core": "^7.0.0", + "@octokit/plugin-paginate-rest": "^13.0.0", + "@octokit/plugin-retry": "^8.0.0", + "@octokit/plugin-throttling": "^11.0.0", + "@semantic-release/error": "^4.0.0", + "aggregate-error": "^5.0.0", + "debug": "^4.3.4", + "dir-glob": "^3.0.1", + "http-proxy-agent": "^7.0.0", + "https-proxy-agent": "^7.0.0", + "issue-parser": "^7.0.0", + "lodash-es": "^4.17.21", + "mime": "^4.0.0", + "p-filter": "^4.0.0", + "tinyglobby": "^0.2.14", + "url-join": "^5.0.0" + }, + "engines": { + "node": ">=20.8.1" + }, + "peerDependencies": { + "semantic-release": ">=24.1.0" + } + }, + "node_modules/@semantic-release/npm": { + "version": "12.0.2", + "resolved": "https://registry.npmjs.org/@semantic-release/npm/-/npm-12.0.2.tgz", + "integrity": "sha512-+M9/Lb35IgnlUO6OSJ40Ie+hUsZLuph2fqXC/qrKn0fMvUU/jiCjpoL6zEm69vzcmaZJ8yNKtMBEKHWN49WBbQ==", + "license": "MIT", + "dependencies": { + "@semantic-release/error": "^4.0.0", + "aggregate-error": "^5.0.0", + "execa": "^9.0.0", + "fs-extra": "^11.0.0", + "lodash-es": "^4.17.21", + "nerf-dart": "^1.0.0", + "normalize-url": "^8.0.0", + "npm": "^10.9.3", + "rc": "^1.2.8", + "read-pkg": "^9.0.0", + "registry-auth-token": "^5.0.0", + "semver": "^7.1.2", + "tempy": "^3.0.0" + }, + "engines": { + "node": ">=20.8.1" + }, + "peerDependencies": { + "semantic-release": ">=20.1.0" + } + }, + "node_modules/@semantic-release/release-notes-generator": { + "version": "14.1.1", + "resolved": "https://registry.npmjs.org/@semantic-release/release-notes-generator/-/release-notes-generator-14.1.1.tgz", + "integrity": "sha512-Pbd2e2XRMUD0OxehHpgd5/YghsE76cddkRHSoDvKLK+OCy4Ewxn49rWR631MEUU01lgwF/uyVXvbnVuu6+Z6VA==", + "license": "MIT", + "dependencies": { + "conventional-changelog-angular": "^8.0.0", + "conventional-changelog-writer": "^8.0.0", + "conventional-commits-filter": "^5.0.0", + "conventional-commits-parser": "^6.0.0", + "debug": "^4.0.0", + "import-from-esm": "^2.0.0", + "lodash-es": "^4.17.21", + "read-package-up": "^11.0.0" + }, + "engines": { + "node": ">=20.8.1" + }, + "peerDependencies": { + "semantic-release": ">=20.1.0" + } + }, + "node_modules/@simple-libs/stream-utils": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@simple-libs/stream-utils/-/stream-utils-1.2.0.tgz", + "integrity": "sha512-KxXvfapcixpz6rVEB6HPjOUZT22yN6v0vI0urQSk1L8MlEWPDFCZkhw2xmkyoTGYeFw7tWTZd7e3lVzRZRN/EA==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://ko-fi.com/dangreen" + } + }, + "node_modules/@sindresorhus/is": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.6.0.tgz", + "integrity": "sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/is?sponsor=1" + } + }, + "node_modules/@sindresorhus/merge-streams": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/merge-streams/-/merge-streams-4.0.0.tgz", + "integrity": "sha512-tlqY9xq5ukxTUZBmoOp+m61cqwQD5pHJtFY3Mn8CA8ps6yghLH/Hw8UPdqg4OLmFW3IFlcXnQNmo/dh8HzXYIQ==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@types/normalize-package-data": { + "version": "2.4.4", + "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.4.tgz", + "integrity": "sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==", + "license": "MIT" + }, + "node_modules/agent-base": { + "version": "7.1.4", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.4.tgz", + "integrity": "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==", + "license": "MIT", + "engines": { + "node": ">= 14" + } + }, + "node_modules/aggregate-error": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-5.0.0.tgz", + "integrity": "sha512-gOsf2YwSlleG6IjRYG2A7k0HmBMEo6qVNk9Bp/EaLgAJT5ngH6PXbqa4ItvnEwCm/velL5jAnQgsHsWnjhGmvw==", + "license": "MIT", + "dependencies": { + "clean-stack": "^5.2.0", + "indent-string": "^5.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ansi-escapes": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-7.3.0.tgz", + "integrity": "sha512-BvU8nYgGQBxcmMuEeUEmNTvrMVjJNSH7RgW24vXexN4Ven6qCvy4TntnvlnwnMLTVlcRQQdbRY8NKnaIoeWDNg==", + "license": "MIT", + "dependencies": { + "environment": "^1.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ansi-regex": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", + "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/any-promise": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", + "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==", + "license": "MIT" + }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "license": "Python-2.0" + }, + "node_modules/argv-formatter": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/argv-formatter/-/argv-formatter-1.0.0.tgz", + "integrity": "sha512-F2+Hkm9xFaRg+GkaNnbwXNDV5O6pnCFEmqyhvfC/Ic5LbgOWjJh3L+mN/s91rxVL3znE7DYVpW0GJFT+4YBgWw==", + "license": "MIT" + }, + "node_modules/array-ify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/array-ify/-/array-ify-1.0.0.tgz", + "integrity": "sha512-c5AMf34bKdvPhQ7tBGhqkgKNUzMr4WUs+WDtC2ZUGOUncbxKMTvqxYctiseW3+L4bA8ec+GcZ6/A/FW4m8ukng==", + "license": "MIT" + }, + "node_modules/before-after-hook": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-4.0.0.tgz", + "integrity": "sha512-q6tR3RPqIB1pMiTRMFcZwuG5T8vwp+vUvEG0vuI6B+Rikh5BfPp2fQ82c925FOs+b0lcFQ8CFrL+KbilfZFhOQ==", + "license": "Apache-2.0" + }, + "node_modules/bottleneck": { + "version": "2.19.5", + "resolved": "https://registry.npmjs.org/bottleneck/-/bottleneck-2.19.5.tgz", + "integrity": "sha512-VHiNCbI1lKdl44tGrhNfU3lup0Tj/ZBMJB5/2ZbNXRCPuRCO7ed2mgcK4r17y+KB2EfuYuRaVlwNbAeaWGSpbw==", + "license": "MIT" + }, + "node_modules/braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "license": "MIT", + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/chalk": { + "version": "5.6.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.6.2.tgz", + "integrity": "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==", + "license": "MIT", + "engines": { + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/char-regex": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz", + "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "node_modules/clean-stack": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-5.3.0.tgz", + "integrity": "sha512-9ngPTOhYGQqNVSfeJkYXHmF7AGWp4/nN5D/QqNQs3Dvxd1Kk/WpjHfNujKHYUQ/5CoGyOyFNoWSPk5afzP0QVg==", + "license": "MIT", + "dependencies": { + "escape-string-regexp": "5.0.0" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cli-highlight": { + "version": "2.1.11", + "resolved": "https://registry.npmjs.org/cli-highlight/-/cli-highlight-2.1.11.tgz", + "integrity": "sha512-9KDcoEVwyUXrjcJNvHD0NFc/hiwe/WPVYIleQh2O1N2Zro5gWJZ/K+3DGn8w8P/F6FxOgzyC5bxDyHIgCSPhGg==", + "license": "ISC", + "dependencies": { + "chalk": "^4.0.0", + "highlight.js": "^10.7.1", + "mz": "^2.4.0", + "parse5": "^5.1.1", + "parse5-htmlparser2-tree-adapter": "^6.0.0", + "yargs": "^16.0.0" + }, + "bin": { + "highlight": "bin/highlight" + }, + "engines": { + "node": ">=8.0.0", + "npm": ">=5.0.0" + } + }, + "node_modules/cli-highlight/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/cli-highlight/node_modules/cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "license": "ISC", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "node_modules/cli-highlight/node_modules/yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "license": "MIT", + "dependencies": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/cli-highlight/node_modules/yargs-parser": { + "version": "20.2.9", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", + "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "node_modules/cli-table3": { + "version": "0.6.5", + "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.6.5.tgz", + "integrity": "sha512-+W/5efTR7y5HRD7gACw9yQjqMVvEMLBHmboM/kPWam+H+Hmyrgjh6YncVKK122YZkXrLudzTuAukUw9FnMf7IQ==", + "license": "MIT", + "dependencies": { + "string-width": "^4.2.0" + }, + "engines": { + "node": "10.* || >= 12.*" + }, + "optionalDependencies": { + "@colors/colors": "1.5.0" + } + }, + "node_modules/cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "license": "ISC", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "license": "MIT" + }, + "node_modules/compare-func": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/compare-func/-/compare-func-2.0.0.tgz", + "integrity": "sha512-zHig5N+tPWARooBnb0Zx1MFcdfpyJrfTJ3Y5L+IFvUm8rM74hHz66z0gw0x4tijh5CorKkKUCnW82R2vmpeCRA==", + "license": "MIT", + "dependencies": { + "array-ify": "^1.0.0", + "dot-prop": "^5.1.0" + } + }, + "node_modules/config-chain": { + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/config-chain/-/config-chain-1.1.13.tgz", + "integrity": "sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ==", + "license": "MIT", + "dependencies": { + "ini": "^1.3.4", + "proto-list": "~1.2.1" + } + }, + "node_modules/content-type": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-2.0.0.tgz", + "integrity": "sha512-j/O/d7GcZCyNl7/hwZAb606rzqkyvaDctLmckbxLzHvFBzTJHuGEdodATcP3yIRoDrLHkIATJuvzbFlp/ki2cQ==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/conventional-changelog-angular": { + "version": "8.3.1", + "resolved": "https://registry.npmjs.org/conventional-changelog-angular/-/conventional-changelog-angular-8.3.1.tgz", + "integrity": "sha512-6gfI3otXK5Ph5DfCOI1dblr+kN3FAm5a97hYoQkqNZxOaYa5WKfXH+AnpsmS+iUH2mgVC2Cg2Qw9m5OKcmNrIg==", + "license": "ISC", + "dependencies": { + "compare-func": "^2.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/conventional-changelog-writer": { + "version": "8.4.0", + "resolved": "https://registry.npmjs.org/conventional-changelog-writer/-/conventional-changelog-writer-8.4.0.tgz", + "integrity": "sha512-HHBFkk1EECxxmCi4CTu091iuDpQv5/OavuCUAuZmrkWpmYfyD816nom1CvtfXJ/uYfAAjavgHvXHX291tSLK8g==", + "license": "MIT", + "dependencies": { + "@simple-libs/stream-utils": "^1.2.0", + "conventional-commits-filter": "^5.0.0", + "handlebars": "^4.7.7", + "meow": "^13.0.0", + "semver": "^7.5.2" + }, + "bin": { + "conventional-changelog-writer": "dist/cli/index.js" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/conventional-commits-filter": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/conventional-commits-filter/-/conventional-commits-filter-5.0.0.tgz", + "integrity": "sha512-tQMagCOC59EVgNZcC5zl7XqO30Wki9i9J3acbUvkaosCT6JX3EeFwJD7Qqp4MCikRnzS18WXV3BLIQ66ytu6+Q==", + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/conventional-commits-parser": { + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/conventional-commits-parser/-/conventional-commits-parser-6.4.0.tgz", + "integrity": "sha512-tvRg7FIBNlyPzjdG8wWRlPHQJJHI7DylhtRGeU9Lq+JuoPh5BKpPRX83ZdLrvXuOSu5Eo/e7SzOQhU4Hd2Miuw==", + "license": "MIT", + "dependencies": { + "@simple-libs/stream-utils": "^1.2.0", + "meow": "^13.0.0" + }, + "bin": { + "conventional-commits-parser": "dist/cli/index.js" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/convert-hrtime": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/convert-hrtime/-/convert-hrtime-5.0.0.tgz", + "integrity": "sha512-lOETlkIeYSJWcbbcvjRKGxVMXJR+8+OQb/mTPbA4ObPMytYIsUbuOE0Jzy60hjARYszq1id0j8KgVhC+WGZVTg==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/core-util-is": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", + "license": "MIT" + }, + "node_modules/cosmiconfig": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-9.0.1.tgz", + "integrity": "sha512-hr4ihw+DBqcvrsEDioRO31Z17x71pUYoNe/4h6Z0wB72p7MU7/9gH8Q3s12NFhHPfYBBOV3qyfUxmr/Yn3shnQ==", + "license": "MIT", + "dependencies": { + "env-paths": "^2.2.1", + "import-fresh": "^3.3.0", + "js-yaml": "^4.1.0", + "parse-json": "^5.2.0" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/d-fischer" + }, + "peerDependencies": { + "typescript": ">=4.9.5" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/cross-spawn": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/crypto-random-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-4.0.0.tgz", + "integrity": "sha512-x8dy3RnvYdlUcPOjkEHqozhiwzKNSq7GcPuXFbnyMOCHxX8V3OgIg/pYuabl2sbUPfIJaeAQB7PMOK8DFIdoRA==", + "license": "MIT", + "dependencies": { + "type-fest": "^1.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/crypto-random-string/node_modules/type-fest": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-1.4.0.tgz", + "integrity": "sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA==", + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/deep-extend": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", + "license": "MIT", + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "license": "MIT", + "dependencies": { + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/dot-prop": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz", + "integrity": "sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==", + "license": "MIT", + "dependencies": { + "is-obj": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/duplexer2": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.1.4.tgz", + "integrity": "sha512-asLFVfWWtJ90ZyOUHMqk7/S2w2guQKxUI2itj3d92ADHhxUSbCMGi1f1cBcJ7xM1To+pE/Khbwo1yuNbMEPKeA==", + "license": "BSD-3-Clause", + "dependencies": { + "readable-stream": "^2.0.2" + } + }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "license": "MIT" + }, + "node_modules/emojilib": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/emojilib/-/emojilib-2.4.0.tgz", + "integrity": "sha512-5U0rVMU5Y2n2+ykNLQqMoqklN9ICBT/KsvC1Gz6vqHbz2AXXGkG+Pm5rMWk/8Vjrr/mY9985Hi8DYzn1F09Nyw==", + "license": "MIT" + }, + "node_modules/env-ci": { + "version": "11.2.0", + "resolved": "https://registry.npmjs.org/env-ci/-/env-ci-11.2.0.tgz", + "integrity": "sha512-D5kWfzkmaOQDioPmiviWAVtKmpPT4/iJmMVQxWxMPJTFyTkdc5JQUfc5iXEeWxcOdsYTKSAiA/Age4NUOqKsRA==", + "license": "MIT", + "dependencies": { + "execa": "^8.0.0", + "java-properties": "^1.0.2" + }, + "engines": { + "node": "^18.17 || >=20.6.1" + } + }, + "node_modules/env-ci/node_modules/execa": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-8.0.1.tgz", + "integrity": "sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==", + "license": "MIT", + "dependencies": { + "cross-spawn": "^7.0.3", + "get-stream": "^8.0.1", + "human-signals": "^5.0.0", + "is-stream": "^3.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^5.1.0", + "onetime": "^6.0.0", + "signal-exit": "^4.1.0", + "strip-final-newline": "^3.0.0" + }, + "engines": { + "node": ">=16.17" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "node_modules/env-ci/node_modules/get-stream": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-8.0.1.tgz", + "integrity": "sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==", + "license": "MIT", + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/env-ci/node_modules/human-signals": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-5.0.0.tgz", + "integrity": "sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==", + "license": "Apache-2.0", + "engines": { + "node": ">=16.17.0" + } + }, + "node_modules/env-ci/node_modules/is-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz", + "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==", + "license": "MIT", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/env-ci/node_modules/npm-run-path": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.3.0.tgz", + "integrity": "sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==", + "license": "MIT", + "dependencies": { + "path-key": "^4.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/env-ci/node_modules/path-key": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz", + "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/env-ci/node_modules/strip-final-newline": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz", + "integrity": "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/env-paths": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", + "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/environment": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/environment/-/environment-1.1.0.tgz", + "integrity": "sha512-xUtoPkMggbz0MPyPiIWr1Kp4aeWJjDZ6SMvURhimjdZgsRuDplF5/s9hcgGhyXMhs+6vpnuoiZ2kFiu3FMnS8Q==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/error-ex": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.4.tgz", + "integrity": "sha512-sqQamAnR14VgCr1A618A3sGrygcpK+HEbenA/HiEAkkUwcZIIB/tgWqHFxWgOyDh4nB4JCRimh79dR5Ywc9MDQ==", + "license": "MIT", + "dependencies": { + "is-arrayish": "^0.2.1" + } + }, + "node_modules/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-string-regexp": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", + "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/execa": { + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-9.6.1.tgz", + "integrity": "sha512-9Be3ZoN4LmYR90tUoVu2te2BsbzHfhJyfEiAVfz7N5/zv+jduIfLrV2xdQXOHbaD6KgpGdO9PRPM1Y4Q9QkPkA==", + "license": "MIT", + "dependencies": { + "@sindresorhus/merge-streams": "^4.0.0", + "cross-spawn": "^7.0.6", + "figures": "^6.1.0", + "get-stream": "^9.0.0", + "human-signals": "^8.0.1", + "is-plain-obj": "^4.1.0", + "is-stream": "^4.0.1", + "npm-run-path": "^6.0.0", + "pretty-ms": "^9.2.0", + "signal-exit": "^4.1.0", + "strip-final-newline": "^4.0.0", + "yoctocolors": "^2.1.1" + }, + "engines": { + "node": "^18.19.0 || >=20.5.0" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "node_modules/execa/node_modules/get-stream": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-9.0.1.tgz", + "integrity": "sha512-kVCxPF3vQM/N0B1PmoqVUqgHP+EeVjmZSQn+1oCRPxd2P21P2F19lIgbR3HBosbB1PUhOAoctJnfEn2GbN2eZA==", + "license": "MIT", + "dependencies": { + "@sec-ant/readable-stream": "^0.4.1", + "is-stream": "^4.0.1" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/fast-content-type-parse": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/fast-content-type-parse/-/fast-content-type-parse-3.0.0.tgz", + "integrity": "sha512-ZvLdcY8P+N8mGQJahJV5G4U88CSvT1rP8ApL6uETe88MBXrBHAkZlSEySdUlyztF7ccb+Znos3TFqaepHxdhBg==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "MIT" + }, + "node_modules/figures": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-6.1.0.tgz", + "integrity": "sha512-d+l3qxjSesT4V7v2fh+QnmFnUWv9lSpjarhShNTgBOfA0ttejbQUAlHLitbjkoRiDulW0OPoQPYIGhIC8ohejg==", + "license": "MIT", + "dependencies": { + "is-unicode-supported": "^2.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "license": "MIT", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha512-NWzkk0jSJtTt08+FBFMvXoeZnOJD+jTtsRmBYbAIzJdX6l7dLgR7CTubCM5/eDdPUBvLCeVasP1brfVR/9/EZQ==", + "license": "MIT", + "dependencies": { + "locate-path": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/find-up-simple": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/find-up-simple/-/find-up-simple-1.0.1.tgz", + "integrity": "sha512-afd4O7zpqHeRyg4PfDQsXmlDe2PfdHtJt6Akt8jOWaApLOZk5JXs6VMR29lz03pRe9mpykrRCYIYxaJYcfpncQ==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/find-versions": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/find-versions/-/find-versions-6.0.0.tgz", + "integrity": "sha512-2kCCtc+JvcZ86IGAz3Z2Y0A1baIz9fL31pH/0S1IqZr9Iwnjq8izfPtrCyQKO6TLMPELLsQMre7VDqeIKCsHkA==", + "license": "MIT", + "dependencies": { + "semver-regex": "^4.0.5", + "super-regex": "^1.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/fs-extra": { + "version": "11.3.5", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.3.5.tgz", + "integrity": "sha512-eKpRKAovdpZtR1WopLHxlBWvAgPny3c4gX1G5Jhwmmw4XJj0ifSD5qB5TOo8hmA0wlRKDAOAhEE1yVPgs6Fgcg==", + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=14.14" + } + }, + "node_modules/function-timeout": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/function-timeout/-/function-timeout-1.0.2.tgz", + "integrity": "sha512-939eZS4gJ3htTHAldmyyuzlrD58P03fHG49v2JfFXbV6OhvZKRC9j2yAtdHw/zrp2zXHuv05zMIy40F0ge7spA==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "license": "ISC", + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/get-stream": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/git-log-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/git-log-parser/-/git-log-parser-1.2.1.tgz", + "integrity": "sha512-PI+sPDvHXNPl5WNOErAK05s3j0lgwUzMN6o8cyQrDaKfT3qd7TmNJKeXX+SknI5I0QhG5fVPAEwSY4tRGDtYoQ==", + "license": "MIT", + "dependencies": { + "argv-formatter": "~1.0.0", + "spawn-error-forwarder": "~1.0.0", + "split2": "~1.0.0", + "stream-combiner2": "~1.1.1", + "through2": "~2.0.0", + "traverse": "0.6.8" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "license": "ISC" + }, + "node_modules/handlebars": { + "version": "4.7.9", + "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.9.tgz", + "integrity": "sha512-4E71E0rpOaQuJR2A3xDZ+GM1HyWYv1clR58tC8emQNeQe3RH7MAzSbat+V0wG78LQBo6m6bzSG/L4pBuCsgnUQ==", + "license": "MIT", + "dependencies": { + "minimist": "^1.2.5", + "neo-async": "^2.6.2", + "source-map": "^0.6.1", + "wordwrap": "^1.0.0" + }, + "bin": { + "handlebars": "bin/handlebars" + }, + "engines": { + "node": ">=0.4.7" + }, + "optionalDependencies": { + "uglify-js": "^3.1.4" + } + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/highlight.js": { + "version": "10.7.3", + "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-10.7.3.tgz", + "integrity": "sha512-tzcUFauisWKNHaRkN4Wjl/ZA07gENAjFl3J/c480dprkGTg5EQstgaNFqBfUqCq54kZRIEcreTsAgF/m2quD7A==", + "license": "BSD-3-Clause", + "engines": { + "node": "*" + } + }, + "node_modules/hook-std": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/hook-std/-/hook-std-4.0.0.tgz", + "integrity": "sha512-IHI4bEVOt3vRUDJ+bFA9VUJlo7SzvFARPNLw75pqSmAOP2HmTWfFJtPvLBrDrlgjEYXY9zs7SFdHPQaJShkSCQ==", + "license": "MIT", + "engines": { + "node": ">=20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/hosted-git-info": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-8.1.0.tgz", + "integrity": "sha512-Rw/B2DNQaPBICNXEm8balFz9a6WpZrkCGpcWFpy7nCj+NyhSdqXipmfvtmWt9xGfp0wZnBxB+iVpLmQMYt47Tw==", + "license": "ISC", + "dependencies": { + "lru-cache": "^10.0.1" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/http-proxy-agent": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz", + "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==", + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.0", + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/https-proxy-agent": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz", + "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==", + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.2", + "debug": "4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/human-signals": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-8.0.1.tgz", + "integrity": "sha512-eKCa6bwnJhvxj14kZk5NCPc6Hb6BdsU9DZcOnmQKSnO1VKrfV0zCvtttPZUsBvjmNDn8rpcJfpwSYnHBjc95MQ==", + "license": "Apache-2.0", + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/import-fresh": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz", + "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==", + "license": "MIT", + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/import-fresh/node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/import-from-esm": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/import-from-esm/-/import-from-esm-2.0.0.tgz", + "integrity": "sha512-YVt14UZCgsX1vZQ3gKjkWVdBdHQ6eu3MPU1TBgL1H5orXe2+jWD006WCPPtOuwlQm10NuzOW5WawiF1Q9veW8g==", + "license": "MIT", + "dependencies": { + "debug": "^4.3.4", + "import-meta-resolve": "^4.0.0" + }, + "engines": { + "node": ">=18.20" + } + }, + "node_modules/import-meta-resolve": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/import-meta-resolve/-/import-meta-resolve-4.2.0.tgz", + "integrity": "sha512-Iqv2fzaTQN28s/FwZAoFq0ZSs/7hMAHJVX+w8PZl3cY19Pxk6jFFalxQoIfW2826i/fDLXv8IiEZRIT0lDuWcg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/indent-string": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-5.0.0.tgz", + "integrity": "sha512-m6FAo/spmsW2Ab2fU35JTYwtOKa2yAwXSwgjSv1TJzh4Mh7mC3lzAOVLBprb72XsTrgkEIsl7YrFNAiDiRhIGg==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/index-to-position": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/index-to-position/-/index-to-position-1.2.0.tgz", + "integrity": "sha512-Yg7+ztRkqslMAS2iFaU+Oa4KTSidr63OsFGlOrJoW981kIYO3CGCS3wA95P1mUi/IVSJkn0D479KTJpVpvFNuw==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "license": "ISC" + }, + "node_modules/ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", + "license": "ISC" + }, + "node_modules/is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", + "license": "MIT" + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-obj": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", + "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-plain-obj": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.1.0.tgz", + "integrity": "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-stream": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-4.0.1.tgz", + "integrity": "sha512-Dnz92NInDqYckGEUJv689RbRiTSEHCQ7wOVeALbkOz999YpqT46yMRIGtSNl2iCL1waAZSx40+h59NV/EwzV/A==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-unicode-supported": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-2.1.0.tgz", + "integrity": "sha512-mE00Gnza5EEB3Ds0HfMyllZzbBrmLOX3vfWoj9A9PEnTfratQ/BcaJOuMhnkhjXvb2+FkY3VuHqtAGpTPmglFQ==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "license": "MIT" + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "license": "ISC" + }, + "node_modules/issue-parser": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/issue-parser/-/issue-parser-7.0.2.tgz", + "integrity": "sha512-7atWPjhGEIX3JEtMrOYd8TKzboYlq+5sNbdl9POiLYOI14G5HZiQbZP0Xj5EZdrufQVXfJlpTV0hys0CuxwxZw==", + "license": "MIT", + "dependencies": { + "lodash.capitalize": "^4.2.1", + "lodash.escaperegexp": "^4.1.2", + "lodash.isplainobject": "^4.0.6", + "lodash.isstring": "^4.0.1", + "lodash.uniqby": "^4.7.0" + }, + "engines": { + "node": "^18.17 || >=20.6.1" + } + }, + "node_modules/java-properties": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/java-properties/-/java-properties-1.0.2.tgz", + "integrity": "sha512-qjdpeo2yKlYTH7nFdK0vbZWuTCesk4o63v5iVOlhMQPfuIZQfW/HI35SjfhA+4qpg36rnFSvUK5b1m+ckIblQQ==", + "license": "MIT", + "engines": { + "node": ">= 0.6.0" + } + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "license": "MIT" + }, + "node_modules/js-yaml": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz", + "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==", + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/json-parse-better-errors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", + "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", + "license": "MIT" + }, + "node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "license": "MIT" + }, + "node_modules/json-with-bigint": { + "version": "3.5.8", + "resolved": "https://registry.npmjs.org/json-with-bigint/-/json-with-bigint-3.5.8.tgz", + "integrity": "sha512-eq/4KP6K34kwa7TcFdtvnftvHCD9KvHOGGICWwMFc4dOOKF5t4iYqnfLK8otCRCRv06FXOzGGyqE8h8ElMvvdw==", + "license": "MIT" + }, + "node_modules/jsonfile": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.2.1.tgz", + "integrity": "sha512-zwOTdL3rFQ/lRdBnntKVOX6k5cKJwEc1HdilT71BWEu7J41gXIB2MRp+vxduPSwZJPWBxEzv4yH1wYLJGUHX4Q==", + "license": "MIT", + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", + "license": "MIT" + }, + "node_modules/load-json-file": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", + "integrity": "sha512-Kx8hMakjX03tiGTLAIdJ+lL0htKnXjEZN6hk/tozf/WOuYGdZBJrZ+rCJRbVCugsjB3jMLn9746NsQIf5VjBMw==", + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.1.2", + "parse-json": "^4.0.0", + "pify": "^3.0.0", + "strip-bom": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/load-json-file/node_modules/parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw==", + "license": "MIT", + "dependencies": { + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha512-NCI2kiDkyR7VeEKm27Kda/iQHyKJe1Bu0FlTbYp3CqJu+9IFe9bLyAjMxf5ZDDbEg+iMPzB5zYyUTSm8wVTKmA==", + "license": "MIT", + "dependencies": { + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/lodash": { + "version": "4.18.1", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.18.1.tgz", + "integrity": "sha512-dMInicTPVE8d1e5otfwmmjlxkZoUpiVLwyeTdUsi/Caj/gfzzblBcCE5sRHV/AsjuCmxWrte2TNGSYuCeCq+0Q==", + "license": "MIT" + }, + "node_modules/lodash-es": { + "version": "4.18.1", + "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.18.1.tgz", + "integrity": "sha512-J8xewKD/Gk22OZbhpOVSwcs60zhd95ESDwezOFuA3/099925PdHJ7OFHNTGtajL3AlZkykD32HykiMo+BIBI8A==", + "license": "MIT" + }, + "node_modules/lodash.capitalize": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/lodash.capitalize/-/lodash.capitalize-4.2.1.tgz", + "integrity": "sha512-kZzYOKspf8XVX5AvmQF94gQW0lejFVgb80G85bU4ZWzoJ6C03PQg3coYAUpSTpQWelrZELd3XWgHzw4Ck5kaIw==", + "license": "MIT" + }, + "node_modules/lodash.escaperegexp": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/lodash.escaperegexp/-/lodash.escaperegexp-4.1.2.tgz", + "integrity": "sha512-TM9YBvyC84ZxE3rgfefxUWiQKLilstD6k7PTGt6wfbtXF8ixIJLOL3VYyV/z+ZiPLsVxAsKAFVwWlWeb2Y8Yyw==", + "license": "MIT" + }, + "node_modules/lodash.isplainobject": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", + "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==", + "license": "MIT" + }, + "node_modules/lodash.isstring": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz", + "integrity": "sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==", + "license": "MIT" + }, + "node_modules/lodash.uniqby": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/lodash.uniqby/-/lodash.uniqby-4.7.0.tgz", + "integrity": "sha512-e/zcLx6CSbmaEgFHCA7BnoQKyCtKMxnuWrJygbwPs/AIn+IMKl66L8/s+wBUn5LRw2pZx3bUHibiV1b6aTWIww==", + "license": "MIT" + }, + "node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "license": "ISC" + }, + "node_modules/make-asynchronous": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/make-asynchronous/-/make-asynchronous-1.1.0.tgz", + "integrity": "sha512-ayF7iT+44LXdxJLTrTd3TLQpFDDvPCBxXxbv+pMUSuHA5Q8zyAfwkRP6aHHwNVFBUFWtxAHqwNJxF8vMZLAbVg==", + "license": "MIT", + "dependencies": { + "p-event": "^6.0.0", + "type-fest": "^4.6.0", + "web-worker": "^1.5.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/marked": { + "version": "15.0.12", + "resolved": "https://registry.npmjs.org/marked/-/marked-15.0.12.tgz", + "integrity": "sha512-8dD6FusOQSrpv9Z1rdNMdlSgQOIP880DHqnohobOmYLElGEqAL/JvxvuxZO16r4HtjTlfPRDC1hbvxC9dPN2nA==", + "license": "MIT", + "bin": { + "marked": "bin/marked.js" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/marked-terminal": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/marked-terminal/-/marked-terminal-7.3.0.tgz", + "integrity": "sha512-t4rBvPsHc57uE/2nJOLmMbZCQ4tgAccAED3ngXQqW6g+TxA488JzJ+FK3lQkzBQOI1mRV/r/Kq+1ZlJ4D0owQw==", + "license": "MIT", + "dependencies": { + "ansi-escapes": "^7.0.0", + "ansi-regex": "^6.1.0", + "chalk": "^5.4.1", + "cli-highlight": "^2.1.11", + "cli-table3": "^0.6.5", + "node-emoji": "^2.2.0", + "supports-hyperlinks": "^3.1.0" + }, + "engines": { + "node": ">=16.0.0" + }, + "peerDependencies": { + "marked": ">=1 <16" + } + }, + "node_modules/meow": { + "version": "13.2.0", + "resolved": "https://registry.npmjs.org/meow/-/meow-13.2.0.tgz", + "integrity": "sha512-pxQJQzB6djGPXh08dacEloMFopsOqGVRKFPYvPOt9XDZ1HasbgDZA74CJGreSU4G3Ak7EFJGoiH2auq+yXISgA==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "license": "MIT" + }, + "node_modules/micromatch": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", + "license": "MIT", + "dependencies": { + "braces": "^3.0.3", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/mime": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-4.1.0.tgz", + "integrity": "sha512-X5ju04+cAzsojXKes0B/S4tcYtFAJ6tTMuSPBEn9CPGlrWr8Fiw7qYeLT0XyH80HSoAoqWCaz+MWKh22P7G1cw==", + "funding": [ + "https://github.com/sponsors/broofa" + ], + "license": "MIT", + "bin": { + "mime": "bin/cli.js" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/mimic-fn": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz", + "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "license": "MIT" + }, + "node_modules/mz": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz", + "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==", + "license": "MIT", + "dependencies": { + "any-promise": "^1.0.0", + "object-assign": "^4.0.1", + "thenify-all": "^1.0.0" + } + }, + "node_modules/neo-async": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", + "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", + "license": "MIT" + }, + "node_modules/nerf-dart": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/nerf-dart/-/nerf-dart-1.0.0.tgz", + "integrity": "sha512-EZSPZB70jiVsivaBLYDCyntd5eH8NTSMOn3rB+HxwdmKThGELLdYv8qVIMWvZEFy9w8ZZpW9h9OB32l1rGtj7g==", + "license": "MIT" + }, + "node_modules/node-emoji": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/node-emoji/-/node-emoji-2.2.0.tgz", + "integrity": "sha512-Z3lTE9pLaJF47NyMhd4ww1yFTAP8YhYI8SleJiHzM46Fgpm5cnNzSl9XfzFNqbaz+VlJrIj3fXQ4DeN1Rjm6cw==", + "license": "MIT", + "dependencies": { + "@sindresorhus/is": "^4.6.0", + "char-regex": "^1.0.2", + "emojilib": "^2.4.0", + "skin-tone": "^2.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/normalize-package-data": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-6.0.2.tgz", + "integrity": "sha512-V6gygoYb/5EmNI+MEGrWkC+e6+Rr7mTmfHrxDbLzxQogBkgzo76rkok0Am6thgSF7Mv2nLOajAJj5vDJZEFn7g==", + "license": "BSD-2-Clause", + "dependencies": { + "hosted-git-info": "^7.0.0", + "semver": "^7.3.5", + "validate-npm-package-license": "^3.0.4" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/normalize-package-data/node_modules/hosted-git-info": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-7.0.2.tgz", + "integrity": "sha512-puUZAUKT5m8Zzvs72XWy3HtvVbTWljRE66cP60bxJzAqf2DgICo7lYTY2IHUmLnNpjYvw5bvmoHvPc0QO2a62w==", + "license": "ISC", + "dependencies": { + "lru-cache": "^10.0.1" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/normalize-url": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-8.1.1.tgz", + "integrity": "sha512-JYc0DPlpGWB40kH5g07gGTrYuMqV653k3uBKY6uITPWds3M0ov3GaWGp9lbE3Bzngx8+XkfzgvASb9vk9JDFXQ==", + "license": "MIT", + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/npm": { + "version": "10.9.8", + "resolved": "https://registry.npmjs.org/npm/-/npm-10.9.8.tgz", + "integrity": "sha512-fYwb6ODSmHkqrJQQaCxY3M2lPf/mpgC7ik0HSzzIwG5CGtabRp4bNqikatvCoT42b5INQSqudVH0R7yVmC9hVg==", + "bundleDependencies": [ + "@isaacs/string-locale-compare", + "@npmcli/arborist", + "@npmcli/config", + "@npmcli/fs", + "@npmcli/map-workspaces", + "@npmcli/package-json", + "@npmcli/promise-spawn", + "@npmcli/redact", + "@npmcli/run-script", + "@sigstore/tuf", + "abbrev", + "archy", + "cacache", + "chalk", + "ci-info", + "cli-columns", + "fastest-levenshtein", + "fs-minipass", + "glob", + "graceful-fs", + "hosted-git-info", + "ini", + "init-package-json", + "is-cidr", + "json-parse-even-better-errors", + "libnpmaccess", + "libnpmdiff", + "libnpmexec", + "libnpmfund", + "libnpmhook", + "libnpmorg", + "libnpmpack", + "libnpmpublish", + "libnpmsearch", + "libnpmteam", + "libnpmversion", + "make-fetch-happen", + "minimatch", + "minipass", + "minipass-pipeline", + "ms", + "node-gyp", + "nopt", + "normalize-package-data", + "npm-audit-report", + "npm-install-checks", + "npm-package-arg", + "npm-pick-manifest", + "npm-profile", + "npm-registry-fetch", + "npm-user-validate", + "p-map", + "pacote", + "parse-conflict-json", + "proc-log", + "qrcode-terminal", + "read", + "semver", + "spdx-expression-parse", + "ssri", + "supports-color", + "tar", + "text-table", + "tiny-relative-date", + "treeverse", + "validate-npm-package-name", + "which", + "write-file-atomic" + ], + "license": "Artistic-2.0", + "workspaces": [ + "docs", + "smoke-tests", + "mock-globals", + "mock-registry", + "workspaces/*" + ], + "dependencies": { + "@isaacs/string-locale-compare": "^1.1.0", + "@npmcli/arborist": "^8.0.5", + "@npmcli/config": "^9.0.0", + "@npmcli/fs": "^4.0.0", + "@npmcli/map-workspaces": "^4.0.2", + "@npmcli/package-json": "^6.2.0", + "@npmcli/promise-spawn": "^8.0.3", + "@npmcli/redact": "^3.2.2", + "@npmcli/run-script": "^9.1.0", + "@sigstore/tuf": "^3.1.1", + "abbrev": "^3.0.1", + "archy": "~1.0.0", + "cacache": "^19.0.1", + "chalk": "^5.6.2", + "ci-info": "^4.4.0", + "cli-columns": "^4.0.0", + "fastest-levenshtein": "^1.0.16", + "fs-minipass": "^3.0.3", + "glob": "^10.5.0", + "graceful-fs": "^4.2.11", + "hosted-git-info": "^8.1.0", + "ini": "^5.0.0", + "init-package-json": "^7.0.2", + "is-cidr": "^5.1.1", + "json-parse-even-better-errors": "^4.0.0", + "libnpmaccess": "^9.0.0", + "libnpmdiff": "^7.0.5", + "libnpmexec": "^9.0.5", + "libnpmfund": "^6.0.5", + "libnpmhook": "^11.0.0", + "libnpmorg": "^7.0.0", + "libnpmpack": "^8.0.5", + "libnpmpublish": "^10.0.2", + "libnpmsearch": "^8.0.0", + "libnpmteam": "^7.0.0", + "libnpmversion": "^7.0.0", + "make-fetch-happen": "^14.0.3", + "minimatch": "^9.0.9", + "minipass": "^7.1.3", + "minipass-pipeline": "^1.2.4", + "ms": "^2.1.2", + "node-gyp": "^11.5.0", + "nopt": "^8.1.0", + "normalize-package-data": "^7.0.1", + "npm-audit-report": "^6.0.0", + "npm-install-checks": "^7.1.2", + "npm-package-arg": "^12.0.2", + "npm-pick-manifest": "^10.0.0", + "npm-profile": "^11.0.1", + "npm-registry-fetch": "^18.0.2", + "npm-user-validate": "^3.0.0", + "p-map": "^7.0.4", + "pacote": "^19.0.1", + "parse-conflict-json": "^4.0.0", + "proc-log": "^5.0.0", + "qrcode-terminal": "^0.12.0", + "read": "^4.1.0", + "semver": "^7.7.4", + "spdx-expression-parse": "^4.0.0", + "ssri": "^12.0.0", + "supports-color": "^9.4.0", + "tar": "^7.5.11", + "text-table": "~0.2.0", + "tiny-relative-date": "^1.3.0", + "treeverse": "^3.0.0", + "validate-npm-package-name": "^6.0.2", + "which": "^5.0.0", + "write-file-atomic": "^6.0.0" + }, + "bin": { + "npm": "bin/npm-cli.js", + "npx": "bin/npx-cli.js" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm-run-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-6.0.0.tgz", + "integrity": "sha512-9qny7Z9DsQU8Ou39ERsPU4OZQlSTP47ShQzuKZ6PRXpYLtIFgl/DEBYEXKlvcEa+9tHVcK8CF81Y2V72qaZhWA==", + "license": "MIT", + "dependencies": { + "path-key": "^4.0.0", + "unicorn-magic": "^0.3.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/npm-run-path/node_modules/path-key": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz", + "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/npm/node_modules/@isaacs/cliui": { + "version": "8.0.2", + "inBundle": true, + "license": "ISC", + "dependencies": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/npm/node_modules/@isaacs/cliui/node_modules/ansi-regex": { + "version": "6.2.2", + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/npm/node_modules/@isaacs/cliui/node_modules/emoji-regex": { + "version": "9.2.2", + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/@isaacs/cliui/node_modules/string-width": { + "version": "5.1.2", + "inBundle": true, + "license": "MIT", + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/npm/node_modules/@isaacs/cliui/node_modules/strip-ansi": { + "version": "7.2.0", + "inBundle": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.2.2" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/npm/node_modules/@isaacs/fs-minipass": { + "version": "4.0.1", + "inBundle": true, + "license": "ISC", + "dependencies": { + "minipass": "^7.0.4" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/npm/node_modules/@isaacs/string-locale-compare": { + "version": "1.1.0", + "inBundle": true, + "license": "ISC" + }, + "node_modules/npm/node_modules/@npmcli/agent": { + "version": "3.0.0", + "inBundle": true, + "license": "ISC", + "dependencies": { + "agent-base": "^7.1.0", + "http-proxy-agent": "^7.0.0", + "https-proxy-agent": "^7.0.1", + "lru-cache": "^10.0.1", + "socks-proxy-agent": "^8.0.3" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/@npmcli/arborist": { + "version": "8.0.5", + "inBundle": true, + "license": "ISC", + "dependencies": { + "@isaacs/string-locale-compare": "^1.1.0", + "@npmcli/fs": "^4.0.0", + "@npmcli/installed-package-contents": "^3.0.0", + "@npmcli/map-workspaces": "^4.0.1", + "@npmcli/metavuln-calculator": "^8.0.0", + "@npmcli/name-from-folder": "^3.0.0", + "@npmcli/node-gyp": "^4.0.0", + "@npmcli/package-json": "^6.0.1", + "@npmcli/query": "^4.0.0", + "@npmcli/redact": "^3.0.0", + "@npmcli/run-script": "^9.0.1", + "bin-links": "^5.0.0", + "cacache": "^19.0.1", + "common-ancestor-path": "^1.0.1", + "hosted-git-info": "^8.0.0", + "json-parse-even-better-errors": "^4.0.0", + "json-stringify-nice": "^1.1.4", + "lru-cache": "^10.2.2", + "minimatch": "^9.0.4", + "nopt": "^8.0.0", + "npm-install-checks": "^7.1.0", + "npm-package-arg": "^12.0.0", + "npm-pick-manifest": "^10.0.0", + "npm-registry-fetch": "^18.0.1", + "pacote": "^19.0.0", + "parse-conflict-json": "^4.0.0", + "proc-log": "^5.0.0", + "proggy": "^3.0.0", + "promise-all-reject-late": "^1.0.0", + "promise-call-limit": "^3.0.1", + "promise-retry": "^2.0.1", + "read-package-json-fast": "^4.0.0", + "semver": "^7.3.7", + "ssri": "^12.0.0", + "treeverse": "^3.0.0", + "walk-up-path": "^3.0.1" + }, + "bin": { + "arborist": "bin/index.js" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/@npmcli/config": { + "version": "9.0.0", + "inBundle": true, + "license": "ISC", + "dependencies": { + "@npmcli/map-workspaces": "^4.0.1", + "@npmcli/package-json": "^6.0.1", + "ci-info": "^4.0.0", + "ini": "^5.0.0", + "nopt": "^8.0.0", + "proc-log": "^5.0.0", + "semver": "^7.3.5", + "walk-up-path": "^3.0.1" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/@npmcli/fs": { + "version": "4.0.0", + "inBundle": true, + "license": "ISC", + "dependencies": { + "semver": "^7.3.5" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/@npmcli/git": { + "version": "6.0.3", + "inBundle": true, + "license": "ISC", + "dependencies": { + "@npmcli/promise-spawn": "^8.0.0", + "ini": "^5.0.0", + "lru-cache": "^10.0.1", + "npm-pick-manifest": "^10.0.0", + "proc-log": "^5.0.0", + "promise-retry": "^2.0.1", + "semver": "^7.3.5", + "which": "^5.0.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/@npmcli/installed-package-contents": { + "version": "3.0.0", + "inBundle": true, + "license": "ISC", + "dependencies": { + "npm-bundled": "^4.0.0", + "npm-normalize-package-bin": "^4.0.0" + }, + "bin": { + "installed-package-contents": "bin/index.js" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/@npmcli/map-workspaces": { + "version": "4.0.2", + "inBundle": true, + "license": "ISC", + "dependencies": { + "@npmcli/name-from-folder": "^3.0.0", + "@npmcli/package-json": "^6.0.0", + "glob": "^10.2.2", + "minimatch": "^9.0.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/@npmcli/metavuln-calculator": { + "version": "8.0.1", + "inBundle": true, + "license": "ISC", + "dependencies": { + "cacache": "^19.0.0", + "json-parse-even-better-errors": "^4.0.0", + "pacote": "^20.0.0", + "proc-log": "^5.0.0", + "semver": "^7.3.5" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/@npmcli/metavuln-calculator/node_modules/pacote": { + "version": "20.0.1", + "inBundle": true, + "license": "ISC", + "dependencies": { + "@npmcli/git": "^6.0.0", + "@npmcli/installed-package-contents": "^3.0.0", + "@npmcli/package-json": "^6.0.0", + "@npmcli/promise-spawn": "^8.0.0", + "@npmcli/run-script": "^9.0.0", + "cacache": "^19.0.0", + "fs-minipass": "^3.0.0", + "minipass": "^7.0.2", + "npm-package-arg": "^12.0.0", + "npm-packlist": "^9.0.0", + "npm-pick-manifest": "^10.0.0", + "npm-registry-fetch": "^18.0.0", + "proc-log": "^5.0.0", + "promise-retry": "^2.0.1", + "sigstore": "^3.0.0", + "ssri": "^12.0.0", + "tar": "^7.5.10" + }, + "bin": { + "pacote": "bin/index.js" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/@npmcli/name-from-folder": { + "version": "3.0.0", + "inBundle": true, + "license": "ISC", + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/@npmcli/node-gyp": { + "version": "4.0.0", + "inBundle": true, + "license": "ISC", + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/@npmcli/package-json": { + "version": "6.2.0", + "inBundle": true, + "license": "ISC", + "dependencies": { + "@npmcli/git": "^6.0.0", + "glob": "^10.2.2", + "hosted-git-info": "^8.0.0", + "json-parse-even-better-errors": "^4.0.0", + "proc-log": "^5.0.0", + "semver": "^7.5.3", + "validate-npm-package-license": "^3.0.4" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/@npmcli/promise-spawn": { + "version": "8.0.3", + "inBundle": true, + "license": "ISC", + "dependencies": { + "which": "^5.0.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/@npmcli/query": { + "version": "4.0.1", + "inBundle": true, + "license": "ISC", + "dependencies": { + "postcss-selector-parser": "^7.0.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/@npmcli/redact": { + "version": "3.2.2", + "inBundle": true, + "license": "ISC", + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/@npmcli/run-script": { + "version": "9.1.0", + "inBundle": true, + "license": "ISC", + "dependencies": { + "@npmcli/node-gyp": "^4.0.0", + "@npmcli/package-json": "^6.0.0", + "@npmcli/promise-spawn": "^8.0.0", + "node-gyp": "^11.0.0", + "proc-log": "^5.0.0", + "which": "^5.0.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/@pkgjs/parseargs": { + "version": "0.11.0", + "inBundle": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=14" + } + }, + "node_modules/npm/node_modules/@sigstore/bundle": { + "version": "3.1.0", + "inBundle": true, + "license": "Apache-2.0", + "dependencies": { + "@sigstore/protobuf-specs": "^0.4.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/@sigstore/core": { + "version": "2.0.0", + "inBundle": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/@sigstore/protobuf-specs": { + "version": "0.4.3", + "inBundle": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/@sigstore/sign": { + "version": "3.1.0", + "inBundle": true, + "license": "Apache-2.0", + "dependencies": { + "@sigstore/bundle": "^3.1.0", + "@sigstore/core": "^2.0.0", + "@sigstore/protobuf-specs": "^0.4.0", + "make-fetch-happen": "^14.0.2", + "proc-log": "^5.0.0", + "promise-retry": "^2.0.1" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/@sigstore/tuf": { + "version": "3.1.1", + "inBundle": true, + "license": "Apache-2.0", + "dependencies": { + "@sigstore/protobuf-specs": "^0.4.1", + "tuf-js": "^3.0.1" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/@sigstore/verify": { + "version": "2.1.1", + "inBundle": true, + "license": "Apache-2.0", + "dependencies": { + "@sigstore/bundle": "^3.1.0", + "@sigstore/core": "^2.0.0", + "@sigstore/protobuf-specs": "^0.4.1" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/@tufjs/canonical-json": { + "version": "2.0.0", + "inBundle": true, + "license": "MIT", + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/abbrev": { + "version": "3.0.1", + "inBundle": true, + "license": "ISC", + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/agent-base": { + "version": "7.1.4", + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">= 14" + } + }, + "node_modules/npm/node_modules/ansi-regex": { + "version": "5.0.1", + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/npm/node_modules/ansi-styles": { + "version": "6.2.3", + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/npm/node_modules/aproba": { + "version": "2.1.0", + "inBundle": true, + "license": "ISC" + }, + "node_modules/npm/node_modules/archy": { + "version": "1.0.0", + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/balanced-match": { + "version": "1.0.2", + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/bin-links": { + "version": "5.0.0", + "inBundle": true, + "license": "ISC", + "dependencies": { + "cmd-shim": "^7.0.0", + "npm-normalize-package-bin": "^4.0.0", + "proc-log": "^5.0.0", + "read-cmd-shim": "^5.0.0", + "write-file-atomic": "^6.0.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/binary-extensions": { + "version": "2.3.0", + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/npm/node_modules/brace-expansion": { + "version": "2.0.2", + "inBundle": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/npm/node_modules/cacache": { + "version": "19.0.1", + "inBundle": true, + "license": "ISC", + "dependencies": { + "@npmcli/fs": "^4.0.0", + "fs-minipass": "^3.0.0", + "glob": "^10.2.2", + "lru-cache": "^10.0.1", + "minipass": "^7.0.3", + "minipass-collect": "^2.0.1", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.4", + "p-map": "^7.0.2", + "ssri": "^12.0.0", + "tar": "^7.4.3", + "unique-filename": "^4.0.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/chalk": { + "version": "5.6.2", + "inBundle": true, + "license": "MIT", + "engines": { + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/npm/node_modules/chownr": { + "version": "3.0.0", + "inBundle": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=18" + } + }, + "node_modules/npm/node_modules/ci-info": { + "version": "4.4.0", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/sibiraj-s" + } + ], + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/npm/node_modules/cidr-regex": { + "version": "4.1.3", + "inBundle": true, + "license": "BSD-2-Clause", + "dependencies": { + "ip-regex": "^5.0.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/npm/node_modules/cli-columns": { + "version": "4.0.0", + "inBundle": true, + "license": "MIT", + "dependencies": { + "string-width": "^4.2.3", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/npm/node_modules/cmd-shim": { + "version": "7.0.0", + "inBundle": true, + "license": "ISC", + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/color-convert": { + "version": "2.0.1", + "inBundle": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/npm/node_modules/color-name": { + "version": "1.1.4", + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/common-ancestor-path": { + "version": "1.0.1", + "inBundle": true, + "license": "ISC" + }, + "node_modules/npm/node_modules/cross-spawn": { + "version": "7.0.6", + "inBundle": true, + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/npm/node_modules/cross-spawn/node_modules/which": { + "version": "2.0.2", + "inBundle": true, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/npm/node_modules/cssesc": { + "version": "3.0.0", + "inBundle": true, + "license": "MIT", + "bin": { + "cssesc": "bin/cssesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/npm/node_modules/debug": { + "version": "4.4.3", + "inBundle": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/npm/node_modules/diff": { + "version": "5.2.2", + "inBundle": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/npm/node_modules/eastasianwidth": { + "version": "0.2.0", + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/emoji-regex": { + "version": "8.0.0", + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/encoding": { + "version": "0.1.13", + "inBundle": true, + "license": "MIT", + "optional": true, + "dependencies": { + "iconv-lite": "^0.6.2" + } + }, + "node_modules/npm/node_modules/env-paths": { + "version": "2.2.1", + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/npm/node_modules/err-code": { + "version": "2.0.3", + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/exponential-backoff": { + "version": "3.1.3", + "inBundle": true, + "license": "Apache-2.0" + }, + "node_modules/npm/node_modules/fastest-levenshtein": { + "version": "1.0.16", + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">= 4.9.1" + } + }, + "node_modules/npm/node_modules/fdir": { + "version": "6.5.0", + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/npm/node_modules/foreground-child": { + "version": "3.3.1", + "inBundle": true, + "license": "ISC", + "dependencies": { + "cross-spawn": "^7.0.6", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/npm/node_modules/fs-minipass": { + "version": "3.0.3", + "inBundle": true, + "license": "ISC", + "dependencies": { + "minipass": "^7.0.3" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/glob": { + "version": "10.5.0", + "inBundle": true, + "license": "ISC", + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/npm/node_modules/graceful-fs": { + "version": "4.2.11", + "inBundle": true, + "license": "ISC" + }, + "node_modules/npm/node_modules/hosted-git-info": { + "version": "8.1.0", + "inBundle": true, + "license": "ISC", + "dependencies": { + "lru-cache": "^10.0.1" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/http-cache-semantics": { + "version": "4.2.0", + "inBundle": true, + "license": "BSD-2-Clause" + }, + "node_modules/npm/node_modules/http-proxy-agent": { + "version": "7.0.2", + "inBundle": true, + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.0", + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/npm/node_modules/https-proxy-agent": { + "version": "7.0.6", + "inBundle": true, + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.2", + "debug": "4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/npm/node_modules/iconv-lite": { + "version": "0.6.3", + "inBundle": true, + "license": "MIT", + "optional": true, + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/npm/node_modules/ignore-walk": { + "version": "7.0.0", + "inBundle": true, + "license": "ISC", + "dependencies": { + "minimatch": "^9.0.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/imurmurhash": { + "version": "0.1.4", + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/npm/node_modules/ini": { + "version": "5.0.0", + "inBundle": true, + "license": "ISC", + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/init-package-json": { + "version": "7.0.2", + "inBundle": true, + "license": "ISC", + "dependencies": { + "@npmcli/package-json": "^6.0.0", + "npm-package-arg": "^12.0.0", + "promzard": "^2.0.0", + "read": "^4.0.0", + "semver": "^7.3.5", + "validate-npm-package-license": "^3.0.4", + "validate-npm-package-name": "^6.0.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/ip-address": { + "version": "10.1.0", + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">= 12" + } + }, + "node_modules/npm/node_modules/ip-regex": { + "version": "5.0.0", + "inBundle": true, + "license": "MIT", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/npm/node_modules/is-cidr": { + "version": "5.1.1", + "inBundle": true, + "license": "BSD-2-Clause", + "dependencies": { + "cidr-regex": "^4.1.1" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/npm/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/npm/node_modules/isexe": { + "version": "2.0.0", + "inBundle": true, + "license": "ISC" + }, + "node_modules/npm/node_modules/jackspeak": { + "version": "3.4.3", + "inBundle": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" + } + }, + "node_modules/npm/node_modules/json-parse-even-better-errors": { + "version": "4.0.0", + "inBundle": true, + "license": "MIT", + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/json-stringify-nice": { + "version": "1.1.4", + "inBundle": true, + "license": "ISC", + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/npm/node_modules/jsonparse": { + "version": "1.3.1", + "engines": [ + "node >= 0.2.0" + ], + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/just-diff": { + "version": "6.0.2", + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/just-diff-apply": { + "version": "5.5.0", + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/libnpmaccess": { + "version": "9.0.0", + "inBundle": true, + "license": "ISC", + "dependencies": { + "npm-package-arg": "^12.0.0", + "npm-registry-fetch": "^18.0.1" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/libnpmdiff": { + "version": "7.0.5", + "inBundle": true, + "license": "ISC", + "dependencies": { + "@npmcli/arborist": "^8.0.5", + "@npmcli/installed-package-contents": "^3.0.0", + "binary-extensions": "^2.3.0", + "diff": "^5.1.0", + "minimatch": "^9.0.4", + "npm-package-arg": "^12.0.0", + "pacote": "^19.0.0", + "tar": "^7.5.11" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/libnpmexec": { + "version": "9.0.5", + "inBundle": true, + "license": "ISC", + "dependencies": { + "@npmcli/arborist": "^8.0.5", + "@npmcli/run-script": "^9.0.1", + "ci-info": "^4.0.0", + "npm-package-arg": "^12.0.0", + "pacote": "^19.0.0", + "proc-log": "^5.0.0", + "read": "^4.0.0", + "read-package-json-fast": "^4.0.0", + "semver": "^7.3.7", + "walk-up-path": "^3.0.1" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/libnpmfund": { + "version": "6.0.5", + "inBundle": true, + "license": "ISC", + "dependencies": { + "@npmcli/arborist": "^8.0.5" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/libnpmhook": { + "version": "11.0.0", + "inBundle": true, + "license": "ISC", + "dependencies": { + "aproba": "^2.0.0", + "npm-registry-fetch": "^18.0.1" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/libnpmorg": { + "version": "7.0.0", + "inBundle": true, + "license": "ISC", + "dependencies": { + "aproba": "^2.0.0", + "npm-registry-fetch": "^18.0.1" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/libnpmpack": { + "version": "8.0.5", + "inBundle": true, + "license": "ISC", + "dependencies": { + "@npmcli/arborist": "^8.0.5", + "@npmcli/run-script": "^9.0.1", + "npm-package-arg": "^12.0.0", + "pacote": "^19.0.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/libnpmpublish": { + "version": "10.0.2", + "inBundle": true, + "license": "ISC", + "dependencies": { + "ci-info": "^4.0.0", + "normalize-package-data": "^7.0.0", + "npm-package-arg": "^12.0.0", + "npm-registry-fetch": "^18.0.1", + "proc-log": "^5.0.0", + "semver": "^7.3.7", + "sigstore": "^3.0.0", + "ssri": "^12.0.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/libnpmsearch": { + "version": "8.0.0", + "inBundle": true, + "license": "ISC", + "dependencies": { + "npm-registry-fetch": "^18.0.1" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/libnpmteam": { + "version": "7.0.0", + "inBundle": true, + "license": "ISC", + "dependencies": { + "aproba": "^2.0.0", + "npm-registry-fetch": "^18.0.1" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/libnpmversion": { + "version": "7.0.0", + "inBundle": true, + "license": "ISC", + "dependencies": { + "@npmcli/git": "^6.0.1", + "@npmcli/run-script": "^9.0.1", + "json-parse-even-better-errors": "^4.0.0", + "proc-log": "^5.0.0", + "semver": "^7.3.7" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/lru-cache": { + "version": "10.4.3", + "inBundle": true, + "license": "ISC" + }, + "node_modules/npm/node_modules/make-fetch-happen": { + "version": "14.0.3", + "inBundle": true, + "license": "ISC", + "dependencies": { + "@npmcli/agent": "^3.0.0", + "cacache": "^19.0.1", + "http-cache-semantics": "^4.1.1", + "minipass": "^7.0.2", + "minipass-fetch": "^4.0.0", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.4", + "negotiator": "^1.0.0", + "proc-log": "^5.0.0", + "promise-retry": "^2.0.1", + "ssri": "^12.0.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/minimatch": { + "version": "9.0.9", + "inBundle": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.2" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/npm/node_modules/minipass": { + "version": "7.1.3", + "inBundle": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/npm/node_modules/minipass-collect": { + "version": "2.0.1", + "inBundle": true, + "license": "ISC", + "dependencies": { + "minipass": "^7.0.3" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/npm/node_modules/minipass-fetch": { + "version": "4.0.1", + "inBundle": true, + "license": "MIT", + "dependencies": { + "minipass": "^7.0.3", + "minipass-sized": "^1.0.3", + "minizlib": "^3.0.1" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + }, + "optionalDependencies": { + "encoding": "^0.1.13" + } + }, + "node_modules/npm/node_modules/minipass-flush": { + "version": "1.0.5", + "inBundle": true, + "license": "ISC", + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/npm/node_modules/minipass-flush/node_modules/minipass": { + "version": "3.3.6", + "inBundle": true, + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/npm/node_modules/minipass-flush/node_modules/yallist": { + "version": "4.0.0", + "inBundle": true, + "license": "ISC" + }, + "node_modules/npm/node_modules/minipass-pipeline": { + "version": "1.2.4", + "inBundle": true, + "license": "ISC", + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/npm/node_modules/minipass-pipeline/node_modules/minipass": { + "version": "3.3.6", + "inBundle": true, + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/npm/node_modules/minipass-pipeline/node_modules/yallist": { + "version": "4.0.0", + "inBundle": true, + "license": "ISC" + }, + "node_modules/npm/node_modules/minipass-sized": { + "version": "1.0.3", + "inBundle": true, + "license": "ISC", + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/npm/node_modules/minipass-sized/node_modules/minipass": { + "version": "3.3.6", + "inBundle": true, + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/npm/node_modules/minipass-sized/node_modules/yallist": { + "version": "4.0.0", + "inBundle": true, + "license": "ISC" + }, + "node_modules/npm/node_modules/minizlib": { + "version": "3.1.0", + "inBundle": true, + "license": "MIT", + "dependencies": { + "minipass": "^7.1.2" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/npm/node_modules/ms": { + "version": "2.1.3", + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/mute-stream": { + "version": "2.0.0", + "inBundle": true, + "license": "ISC", + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/negotiator": { + "version": "1.0.0", + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/npm/node_modules/node-gyp": { + "version": "11.5.0", + "inBundle": true, + "license": "MIT", + "dependencies": { + "env-paths": "^2.2.0", + "exponential-backoff": "^3.1.1", + "graceful-fs": "^4.2.6", + "make-fetch-happen": "^14.0.3", + "nopt": "^8.0.0", + "proc-log": "^5.0.0", + "semver": "^7.3.5", + "tar": "^7.4.3", + "tinyglobby": "^0.2.12", + "which": "^5.0.0" + }, + "bin": { + "node-gyp": "bin/node-gyp.js" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/nopt": { + "version": "8.1.0", + "inBundle": true, + "license": "ISC", + "dependencies": { + "abbrev": "^3.0.0" + }, + "bin": { + "nopt": "bin/nopt.js" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/normalize-package-data": { + "version": "7.0.1", + "inBundle": true, + "license": "BSD-2-Clause", + "dependencies": { + "hosted-git-info": "^8.0.0", + "semver": "^7.3.5", + "validate-npm-package-license": "^3.0.4" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/npm-audit-report": { + "version": "6.0.0", + "inBundle": true, + "license": "ISC", + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/npm-bundled": { + "version": "4.0.0", + "inBundle": true, + "license": "ISC", + "dependencies": { + "npm-normalize-package-bin": "^4.0.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/npm-install-checks": { + "version": "7.1.2", + "inBundle": true, + "license": "BSD-2-Clause", + "dependencies": { + "semver": "^7.1.1" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/npm-normalize-package-bin": { + "version": "4.0.0", + "inBundle": true, + "license": "ISC", + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/npm-package-arg": { + "version": "12.0.2", + "inBundle": true, + "license": "ISC", + "dependencies": { + "hosted-git-info": "^8.0.0", + "proc-log": "^5.0.0", + "semver": "^7.3.5", + "validate-npm-package-name": "^6.0.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/npm-packlist": { + "version": "9.0.0", + "inBundle": true, + "license": "ISC", + "dependencies": { + "ignore-walk": "^7.0.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/npm-pick-manifest": { + "version": "10.0.0", + "inBundle": true, + "license": "ISC", + "dependencies": { + "npm-install-checks": "^7.1.0", + "npm-normalize-package-bin": "^4.0.0", + "npm-package-arg": "^12.0.0", + "semver": "^7.3.5" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/npm-profile": { + "version": "11.0.1", + "inBundle": true, + "license": "ISC", + "dependencies": { + "npm-registry-fetch": "^18.0.0", + "proc-log": "^5.0.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/npm-registry-fetch": { + "version": "18.0.2", + "inBundle": true, + "license": "ISC", + "dependencies": { + "@npmcli/redact": "^3.0.0", + "jsonparse": "^1.3.1", + "make-fetch-happen": "^14.0.0", + "minipass": "^7.0.2", + "minipass-fetch": "^4.0.0", + "minizlib": "^3.0.1", + "npm-package-arg": "^12.0.0", + "proc-log": "^5.0.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/npm-user-validate": { + "version": "3.0.0", + "inBundle": true, + "license": "BSD-2-Clause", + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/p-map": { + "version": "7.0.4", + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/npm/node_modules/package-json-from-dist": { + "version": "1.0.1", + "inBundle": true, + "license": "BlueOak-1.0.0" + }, + "node_modules/npm/node_modules/pacote": { + "version": "19.0.2", + "inBundle": true, + "license": "ISC", + "dependencies": { + "@npmcli/git": "^6.0.0", + "@npmcli/installed-package-contents": "^3.0.0", + "@npmcli/package-json": "^6.0.0", + "@npmcli/promise-spawn": "^8.0.0", + "@npmcli/run-script": "^9.0.0", + "cacache": "^19.0.0", + "fs-minipass": "^3.0.0", + "minipass": "^7.0.2", + "npm-package-arg": "^12.0.0", + "npm-packlist": "^9.0.0", + "npm-pick-manifest": "^10.0.0", + "npm-registry-fetch": "^18.0.0", + "proc-log": "^5.0.0", + "promise-retry": "^2.0.1", + "sigstore": "^3.0.0", + "ssri": "^12.0.0", + "tar": "^7.5.10" + }, + "bin": { + "pacote": "bin/index.js" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/parse-conflict-json": { + "version": "4.0.0", + "inBundle": true, + "license": "ISC", + "dependencies": { + "json-parse-even-better-errors": "^4.0.0", + "just-diff": "^6.0.0", + "just-diff-apply": "^5.2.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/path-key": { + "version": "3.1.1", + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/npm/node_modules/path-scurry": { + "version": "1.11.1", + "inBundle": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "lru-cache": "^10.2.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "engines": { + "node": ">=16 || 14 >=14.18" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/npm/node_modules/picomatch": { + "version": "4.0.3", + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/npm/node_modules/postcss-selector-parser": { + "version": "7.1.1", + "inBundle": true, + "license": "MIT", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/npm/node_modules/proc-log": { + "version": "5.0.0", + "inBundle": true, + "license": "ISC", + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/proggy": { + "version": "3.0.0", + "inBundle": true, + "license": "ISC", + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/promise-all-reject-late": { + "version": "1.0.1", + "inBundle": true, + "license": "ISC", + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/npm/node_modules/promise-call-limit": { + "version": "3.0.2", + "inBundle": true, + "license": "ISC", + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/npm/node_modules/promise-retry": { + "version": "2.0.1", + "inBundle": true, + "license": "MIT", + "dependencies": { + "err-code": "^2.0.2", + "retry": "^0.12.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/npm/node_modules/promzard": { + "version": "2.0.0", + "inBundle": true, + "license": "ISC", + "dependencies": { + "read": "^4.0.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/qrcode-terminal": { + "version": "0.12.0", + "inBundle": true, + "bin": { + "qrcode-terminal": "bin/qrcode-terminal.js" + } + }, + "node_modules/npm/node_modules/read": { + "version": "4.1.0", + "inBundle": true, + "license": "ISC", + "dependencies": { + "mute-stream": "^2.0.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/read-cmd-shim": { + "version": "5.0.0", + "inBundle": true, + "license": "ISC", + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/read-package-json-fast": { + "version": "4.0.0", + "inBundle": true, + "license": "ISC", + "dependencies": { + "json-parse-even-better-errors": "^4.0.0", + "npm-normalize-package-bin": "^4.0.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/retry": { + "version": "0.12.0", + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/npm/node_modules/safer-buffer": { + "version": "2.1.2", + "inBundle": true, + "license": "MIT", + "optional": true + }, + "node_modules/npm/node_modules/semver": { + "version": "7.7.4", + "inBundle": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/npm/node_modules/shebang-command": { + "version": "2.0.0", + "inBundle": true, + "license": "MIT", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/npm/node_modules/shebang-regex": { + "version": "3.0.0", + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/npm/node_modules/signal-exit": { + "version": "4.1.0", + "inBundle": true, + "license": "ISC", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/npm/node_modules/sigstore": { + "version": "3.1.0", + "inBundle": true, + "license": "Apache-2.0", + "dependencies": { + "@sigstore/bundle": "^3.1.0", + "@sigstore/core": "^2.0.0", + "@sigstore/protobuf-specs": "^0.4.0", + "@sigstore/sign": "^3.1.0", + "@sigstore/tuf": "^3.1.0", + "@sigstore/verify": "^2.1.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/smart-buffer": { + "version": "4.2.0", + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">= 6.0.0", + "npm": ">= 3.0.0" + } + }, + "node_modules/npm/node_modules/socks": { + "version": "2.8.7", + "inBundle": true, + "license": "MIT", + "dependencies": { + "ip-address": "^10.0.1", + "smart-buffer": "^4.2.0" + }, + "engines": { + "node": ">= 10.0.0", + "npm": ">= 3.0.0" + } + }, + "node_modules/npm/node_modules/socks-proxy-agent": { + "version": "8.0.5", + "inBundle": true, + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.2", + "debug": "^4.3.4", + "socks": "^2.8.3" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/npm/node_modules/spdx-correct": { + "version": "3.2.0", + "inBundle": true, + "license": "Apache-2.0", + "dependencies": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/npm/node_modules/spdx-correct/node_modules/spdx-expression-parse": { + "version": "3.0.1", + "inBundle": true, + "license": "MIT", + "dependencies": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/npm/node_modules/spdx-exceptions": { + "version": "2.5.0", + "inBundle": true, + "license": "CC-BY-3.0" + }, + "node_modules/npm/node_modules/spdx-expression-parse": { + "version": "4.0.0", + "inBundle": true, + "license": "MIT", + "dependencies": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/npm/node_modules/spdx-license-ids": { + "version": "3.0.23", + "inBundle": true, + "license": "CC0-1.0" + }, + "node_modules/npm/node_modules/ssri": { + "version": "12.0.0", + "inBundle": true, + "license": "ISC", + "dependencies": { + "minipass": "^7.0.3" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/string-width": { + "version": "4.2.3", + "inBundle": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/npm/node_modules/string-width-cjs": { + "name": "string-width", + "version": "4.2.3", + "inBundle": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/npm/node_modules/strip-ansi": { + "version": "6.0.1", + "inBundle": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/npm/node_modules/strip-ansi-cjs": { + "name": "strip-ansi", + "version": "6.0.1", + "inBundle": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/npm/node_modules/supports-color": { + "version": "9.4.0", + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/npm/node_modules/tar": { + "version": "7.5.11", + "inBundle": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "@isaacs/fs-minipass": "^4.0.0", + "chownr": "^3.0.0", + "minipass": "^7.1.2", + "minizlib": "^3.1.0", + "yallist": "^5.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/npm/node_modules/text-table": { + "version": "0.2.0", + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/tiny-relative-date": { + "version": "1.3.0", + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/tinyglobby": { + "version": "0.2.15", + "inBundle": true, + "license": "MIT", + "dependencies": { + "fdir": "^6.5.0", + "picomatch": "^4.0.3" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, + "node_modules/npm/node_modules/treeverse": { + "version": "3.0.0", + "inBundle": true, + "license": "ISC", + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/tuf-js": { + "version": "3.1.0", + "inBundle": true, + "license": "MIT", + "dependencies": { + "@tufjs/models": "3.0.1", + "debug": "^4.4.1", + "make-fetch-happen": "^14.0.3" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/tuf-js/node_modules/@tufjs/models": { + "version": "3.0.1", + "inBundle": true, + "license": "MIT", + "dependencies": { + "@tufjs/canonical-json": "2.0.0", + "minimatch": "^9.0.5" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/unique-filename": { + "version": "4.0.0", + "inBundle": true, + "license": "ISC", + "dependencies": { + "unique-slug": "^5.0.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/unique-slug": { + "version": "5.0.0", + "inBundle": true, + "license": "ISC", + "dependencies": { + "imurmurhash": "^0.1.4" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/util-deprecate": { + "version": "1.0.2", + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/validate-npm-package-license": { + "version": "3.0.4", + "inBundle": true, + "license": "Apache-2.0", + "dependencies": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, + "node_modules/npm/node_modules/validate-npm-package-license/node_modules/spdx-expression-parse": { + "version": "3.0.1", + "inBundle": true, + "license": "MIT", + "dependencies": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/npm/node_modules/validate-npm-package-name": { + "version": "6.0.2", + "inBundle": true, + "license": "ISC", + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/walk-up-path": { + "version": "3.0.1", + "inBundle": true, + "license": "ISC" + }, + "node_modules/npm/node_modules/which": { + "version": "5.0.0", + "inBundle": true, + "license": "ISC", + "dependencies": { + "isexe": "^3.1.1" + }, + "bin": { + "node-which": "bin/which.js" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/which/node_modules/isexe": { + "version": "3.1.5", + "inBundle": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=18" + } + }, + "node_modules/npm/node_modules/wrap-ansi": { + "version": "8.1.0", + "inBundle": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/npm/node_modules/wrap-ansi-cjs": { + "name": "wrap-ansi", + "version": "7.0.0", + "inBundle": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/npm/node_modules/wrap-ansi-cjs/node_modules/ansi-styles": { + "version": "4.3.0", + "inBundle": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/npm/node_modules/wrap-ansi/node_modules/ansi-regex": { + "version": "6.2.2", + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/npm/node_modules/wrap-ansi/node_modules/emoji-regex": { + "version": "9.2.2", + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/wrap-ansi/node_modules/string-width": { + "version": "5.1.2", + "inBundle": true, + "license": "MIT", + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/npm/node_modules/wrap-ansi/node_modules/strip-ansi": { + "version": "7.2.0", + "inBundle": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.2.2" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/npm/node_modules/write-file-atomic": { + "version": "6.0.0", + "inBundle": true, + "license": "ISC", + "dependencies": { + "imurmurhash": "^0.1.4", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/yallist": { + "version": "5.0.0", + "inBundle": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=18" + } + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/onetime": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz", + "integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==", + "license": "MIT", + "dependencies": { + "mimic-fn": "^4.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-each-series": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-each-series/-/p-each-series-3.0.0.tgz", + "integrity": "sha512-lastgtAdoH9YaLyDa5i5z64q+kzOcQHsQ5SsZJD3q0VEyI8mq872S3geuNbRUQLVAE9siMfgKrpj7MloKFHruw==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-event": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/p-event/-/p-event-6.0.1.tgz", + "integrity": "sha512-Q6Bekk5wpzW5qIyUP4gdMEujObYstZl6DMMOSenwBvV0BlE5LkDwkjs5yHbZmdCEq2o4RJx4tE1vwxFVf2FG1w==", + "license": "MIT", + "dependencies": { + "p-timeout": "^6.1.2" + }, + "engines": { + "node": ">=16.17" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-filter": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-filter/-/p-filter-4.1.0.tgz", + "integrity": "sha512-37/tPdZ3oJwHaS3gNJdenCDB3Tz26i9sjhnguBtvN0vYlRIiDNnvTWkuh+0hETV9rLPdJ3rlL3yVOYPIAnM8rw==", + "license": "MIT", + "dependencies": { + "p-map": "^7.0.1" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-limit": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", + "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "license": "MIT", + "dependencies": { + "p-try": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha512-nQja7m7gSKuewoVRen45CtVfODR3crN3goVQ0DDZ9N3yHxgpkuBhZqsaiotSQRrADUrne346peY7kT3TSACykg==", + "license": "MIT", + "dependencies": { + "p-limit": "^1.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/p-map": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-7.0.4.tgz", + "integrity": "sha512-tkAQEw8ysMzmkhgw8k+1U/iPhWNhykKnSk4Rd5zLoPJCuJaGRPo6YposrZgaxHKzDHdDWWZvE/Sk7hsL2X/CpQ==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-reduce": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-reduce/-/p-reduce-3.0.0.tgz", + "integrity": "sha512-xsrIUgI0Kn6iyDYm9StOpOeK29XM1aboGji26+QEortiFST1hGZaUQOLhtEbqHErPpGW/aSz6allwK2qcptp0Q==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-timeout": { + "version": "6.1.4", + "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-6.1.4.tgz", + "integrity": "sha512-MyIV3ZA/PmyBN/ud8vV9XzwTrNtR4jFrObymZYnZqMmW0zA8Z17vnT0rBgFE/TlohB+YCHqXMgZzb3Csp49vqg==", + "license": "MIT", + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-try": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha512-U1etNYuMJoIz3ZXSrrySFjsXQTWOx2/jdi86L+2pRvph/qMKL6sbcCYdH23fqsbm8TH2Gn0OybpT4eSFlCVHww==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "license": "MIT", + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/parse-ms": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse-ms/-/parse-ms-4.0.0.tgz", + "integrity": "sha512-TXfryirbmq34y8QBwgqCVLi+8oA3oWx2eAnSn62ITyEhEYaWRlVZ2DvMM9eZbMs/RfxPu/PK/aBLyGj4IrqMHw==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/parse5": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-5.1.1.tgz", + "integrity": "sha512-ugq4DFI0Ptb+WWjAdOK16+u/nHfiIrcE+sh8kZMaM0WllQKLI9rOUq6c2b7cwPkXdzfQESqvoqK6ug7U/Yyzug==", + "license": "MIT" + }, + "node_modules/parse5-htmlparser2-tree-adapter": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-6.0.1.tgz", + "integrity": "sha512-qPuWvbLgvDGilKc5BoicRovlT4MtYT6JfJyBOMDsKoiT+GiuP5qyrPCnR9HcPECIJJmZh5jRndyNThnhhb/vlA==", + "license": "MIT", + "dependencies": { + "parse5": "^6.0.1" + } + }, + "node_modules/parse5-htmlparser2-tree-adapter/node_modules/parse5": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", + "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==", + "license": "MIT" + }, + "node_modules/path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "license": "ISC" + }, + "node_modules/picomatch": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.2.tgz", + "integrity": "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==", + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/pkg-conf": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/pkg-conf/-/pkg-conf-2.1.0.tgz", + "integrity": "sha512-C+VUP+8jis7EsQZIhDYmS5qlNtjv2yP4SNtjXK9AP1ZcTRlnSfuumaTnRfYZnYgUUYVIKqL0fRvmUGDV2fmp6g==", + "license": "MIT", + "dependencies": { + "find-up": "^2.0.0", + "load-json-file": "^4.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/pretty-ms": { + "version": "9.3.0", + "resolved": "https://registry.npmjs.org/pretty-ms/-/pretty-ms-9.3.0.tgz", + "integrity": "sha512-gjVS5hOP+M3wMm5nmNOucbIrqudzs9v/57bWRHQWLYklXqoXKrVfYW2W9+glfGsqtPgpiz5WwyEEB+ksXIx3gQ==", + "license": "MIT", + "dependencies": { + "parse-ms": "^4.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", + "license": "MIT" + }, + "node_modules/proto-list": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/proto-list/-/proto-list-1.2.4.tgz", + "integrity": "sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA==", + "license": "ISC" + }, + "node_modules/rc": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", + "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", + "license": "(BSD-2-Clause OR MIT OR Apache-2.0)", + "dependencies": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + }, + "bin": { + "rc": "cli.js" + } + }, + "node_modules/read-package-up": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/read-package-up/-/read-package-up-11.0.0.tgz", + "integrity": "sha512-MbgfoNPANMdb4oRBNg5eqLbB2t2r+o5Ua1pNt8BqGp4I0FJZhuVSOj3PaBPni4azWuSzEdNn2evevzVmEk1ohQ==", + "license": "MIT", + "dependencies": { + "find-up-simple": "^1.0.0", + "read-pkg": "^9.0.0", + "type-fest": "^4.6.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/read-pkg": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-9.0.1.tgz", + "integrity": "sha512-9viLL4/n1BJUCT1NXVTdS1jtm80yDEgR5T4yCelII49Mbj0v1rZdKqj7zCiYdbB0CuCgdrvHcNogAKTFPBocFA==", + "license": "MIT", + "dependencies": { + "@types/normalize-package-data": "^2.4.3", + "normalize-package-data": "^6.0.0", + "parse-json": "^8.0.0", + "type-fest": "^4.6.0", + "unicorn-magic": "^0.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/read-pkg/node_modules/parse-json": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-8.3.0.tgz", + "integrity": "sha512-ybiGyvspI+fAoRQbIPRddCcSTV9/LsJbf0e/S85VLowVGzRmokfneg2kwVW/KU5rOXrPSbF1qAKPMgNTqqROQQ==", + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.26.2", + "index-to-position": "^1.1.0", + "type-fest": "^4.39.1" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/read-pkg/node_modules/unicorn-magic": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/unicorn-magic/-/unicorn-magic-0.1.0.tgz", + "integrity": "sha512-lRfVq8fE8gz6QMBuDM6a+LO3IAzTi05H6gCVaUpir2E1Rwpo4ZUog45KpNXKC/Mn3Yb9UDuHumeFTo9iV/D9FQ==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "license": "MIT", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/registry-auth-token": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-5.1.1.tgz", + "integrity": "sha512-P7B4+jq8DeD2nMsAcdfaqHbssgHtZ7Z5+++a5ask90fvmJ8p5je4mOa+wzu+DB4vQ5tdJV/xywY+UnVFeQLV5Q==", + "license": "MIT", + "dependencies": { + "@pnpm/npm-conf": "^3.0.2" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "license": "MIT" + }, + "node_modules/semantic-release": { + "version": "24.2.9", + "resolved": "https://registry.npmjs.org/semantic-release/-/semantic-release-24.2.9.tgz", + "integrity": "sha512-phCkJ6pjDi9ANdhuF5ElS10GGdAKY6R1Pvt9lT3SFhOwM4T7QZE7MLpBDbNruUx/Q3gFD92/UOFringGipRqZA==", + "license": "MIT", + "dependencies": { + "@semantic-release/commit-analyzer": "^13.0.0-beta.1", + "@semantic-release/error": "^4.0.0", + "@semantic-release/github": "^11.0.0", + "@semantic-release/npm": "^12.0.2", + "@semantic-release/release-notes-generator": "^14.0.0-beta.1", + "aggregate-error": "^5.0.0", + "cosmiconfig": "^9.0.0", + "debug": "^4.0.0", + "env-ci": "^11.0.0", + "execa": "^9.0.0", + "figures": "^6.0.0", + "find-versions": "^6.0.0", + "get-stream": "^6.0.0", + "git-log-parser": "^1.2.0", + "hook-std": "^4.0.0", + "hosted-git-info": "^8.0.0", + "import-from-esm": "^2.0.0", + "lodash-es": "^4.17.21", + "marked": "^15.0.0", + "marked-terminal": "^7.3.0", + "micromatch": "^4.0.2", + "p-each-series": "^3.0.0", + "p-reduce": "^3.0.0", + "read-package-up": "^11.0.0", + "resolve-from": "^5.0.0", + "semver": "^7.3.2", + "semver-diff": "^5.0.0", + "signale": "^1.2.1", + "yargs": "^17.5.1" + }, + "bin": { + "semantic-release": "bin/semantic-release.js" + }, + "engines": { + "node": ">=20.8.1" + } + }, + "node_modules/semver": { + "version": "7.8.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.0.tgz", + "integrity": "sha512-AcM7dV/5ul4EekoQ29Agm5vri8JNqRyj39o0qpX6vDF2GZrtutZl5RwgD1XnZjiTAfncsJhMI48QQH3sN87YNA==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/semver-diff": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/semver-diff/-/semver-diff-5.0.0.tgz", + "integrity": "sha512-0HbGtOm+S7T6NGQ/pxJSJipJvc4DK3FcRVMRkhsIwJDJ4Jcz5DQC1cPPzB5GhzyHjwttW878HaWQq46CkL3cqg==", + "deprecated": "Deprecated as the semver package now supports this built-in.", + "license": "MIT", + "dependencies": { + "semver": "^7.3.5" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/semver-regex": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/semver-regex/-/semver-regex-4.0.5.tgz", + "integrity": "sha512-hunMQrEy1T6Jr2uEVjrAIqjwWcQTgOAcIM52C8MY1EZSD3DDNft04XzvYKPqjED65bNVVko0YI38nYeEHCX3yw==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "license": "MIT", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "license": "ISC", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/signale": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/signale/-/signale-1.4.0.tgz", + "integrity": "sha512-iuh+gPf28RkltuJC7W5MRi6XAjTDCAPC/prJUpQoG4vIP3MJZ+GTydVnodXA7pwvTKb2cA0m9OFZW/cdWy/I/w==", + "license": "MIT", + "dependencies": { + "chalk": "^2.3.2", + "figures": "^2.0.0", + "pkg-conf": "^2.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/signale/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "license": "MIT", + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/signale/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/signale/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "license": "MIT", + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/signale/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "license": "MIT" + }, + "node_modules/signale/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "license": "MIT", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/signale/node_modules/figures": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", + "integrity": "sha512-Oa2M9atig69ZkfwiApY8F2Yy+tzMbazyvqv21R0NsSC8floSOC09BbT1ITWAdoMGQvJ/aZnR1KMwdx9tvHnTNA==", + "license": "MIT", + "dependencies": { + "escape-string-regexp": "^1.0.5" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/signale/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/signale/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "license": "MIT", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/skin-tone": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/skin-tone/-/skin-tone-2.0.0.tgz", + "integrity": "sha512-kUMbT1oBJCpgrnKoSr0o6wPtvRWT9W9UKvGLwfJYO2WuahZRHOpEyL1ckyMGgMWh0UdpmaoFqKKD29WTomNEGA==", + "license": "MIT", + "dependencies": { + "unicode-emoji-modifier-base": "^1.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/spawn-error-forwarder": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/spawn-error-forwarder/-/spawn-error-forwarder-1.0.0.tgz", + "integrity": "sha512-gRjMgK5uFjbCvdibeGJuy3I5OYz6VLoVdsOJdA6wV0WlfQVLFueoqMxwwYD9RODdgb6oUIvlRlsyFSiQkMKu0g==", + "license": "MIT" + }, + "node_modules/spdx-correct": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz", + "integrity": "sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==", + "license": "Apache-2.0", + "dependencies": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-exceptions": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.5.0.tgz", + "integrity": "sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==", + "license": "CC-BY-3.0" + }, + "node_modules/spdx-expression-parse": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", + "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", + "license": "MIT", + "dependencies": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-license-ids": { + "version": "3.0.23", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.23.tgz", + "integrity": "sha512-CWLcCCH7VLu13TgOH+r8p1O/Znwhqv/dbb6lqWy67G+pT1kHmeD/+V36AVb/vq8QMIQwVShJ6Ssl5FPh0fuSdw==", + "license": "CC0-1.0" + }, + "node_modules/split2": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/split2/-/split2-1.0.0.tgz", + "integrity": "sha512-NKywug4u4pX/AZBB1FCPzZ6/7O+Xhz1qMVbzTvvKvikjO99oPN87SkK08mEY9P63/5lWjK+wgOOgApnTg5r6qg==", + "license": "ISC", + "dependencies": { + "through2": "~2.0.0" + } + }, + "node_modules/stream-combiner2": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/stream-combiner2/-/stream-combiner2-1.1.1.tgz", + "integrity": "sha512-3PnJbYgS56AeWgtKF5jtJRT6uFJe56Z0Hc5Ngg/6sI6rIt8iiMBTa9cvdyFfpMQjaVHr8dusbNeFGIIonxOvKw==", + "license": "MIT", + "dependencies": { + "duplexer2": "~0.1.0", + "readable-stream": "^2.0.2" + } + }, + "node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/strip-final-newline": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-4.0.0.tgz", + "integrity": "sha512-aulFJcD6YK8V1G7iRB5tigAP4TsHBZZrOV8pjV++zdUwmeV8uzbY7yn6h9MswN62adStNZFuCIx4haBnRuMDaw==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/super-regex": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/super-regex/-/super-regex-1.1.0.tgz", + "integrity": "sha512-WHkws2ZflZe41zj6AolvvmaTrWds/VuyeYr9iPVv/oQeaIoVxMKaushfFWpOGDT+GuBrM/sVqF8KUCYQlSSTdQ==", + "license": "MIT", + "dependencies": { + "function-timeout": "^1.0.1", + "make-asynchronous": "^1.0.1", + "time-span": "^5.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-hyperlinks": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-3.2.0.tgz", + "integrity": "sha512-zFObLMyZeEwzAoKCyu1B91U79K2t7ApXuQfo8OuxwXLDgcKxuwM+YvcbIhm6QWqz7mHUH1TVytR1PwVVjEuMig==", + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0", + "supports-color": "^7.0.0" + }, + "engines": { + "node": ">=14.18" + }, + "funding": { + "url": "https://github.com/chalk/supports-hyperlinks?sponsor=1" + } + }, + "node_modules/temp-dir": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/temp-dir/-/temp-dir-3.0.0.tgz", + "integrity": "sha512-nHc6S/bwIilKHNRgK/3jlhDoIHcp45YgyiwcAk46Tr0LfEqGBVpmiAyuiuxeVE44m3mXnEeVhaipLOEWmH+Njw==", + "license": "MIT", + "engines": { + "node": ">=14.16" + } + }, + "node_modules/tempy": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/tempy/-/tempy-3.2.0.tgz", + "integrity": "sha512-d79HhZya5Djd7am0q+W4RTsSU+D/aJzM+4Y4AGJGuGlgM2L6sx5ZvOYTmZjqPhrDrV6xJTtRSm1JCLj6V6LHLQ==", + "license": "MIT", + "dependencies": { + "is-stream": "^3.0.0", + "temp-dir": "^3.0.0", + "type-fest": "^2.12.2", + "unique-string": "^3.0.0" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/tempy/node_modules/is-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz", + "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==", + "license": "MIT", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/tempy/node_modules/type-fest": { + "version": "2.19.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-2.19.0.tgz", + "integrity": "sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==", + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=12.20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/thenify": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz", + "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==", + "license": "MIT", + "dependencies": { + "any-promise": "^1.0.0" + } + }, + "node_modules/thenify-all": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz", + "integrity": "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==", + "license": "MIT", + "dependencies": { + "thenify": ">= 3.1.0 < 4" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/through2": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", + "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", + "license": "MIT", + "dependencies": { + "readable-stream": "~2.3.6", + "xtend": "~4.0.1" + } + }, + "node_modules/time-span": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/time-span/-/time-span-5.1.0.tgz", + "integrity": "sha512-75voc/9G4rDIJleOo4jPvN4/YC4GRZrY8yy1uU4lwrB3XEQbWve8zXoO5No4eFrGcTAMYyoY67p8jRQdtA1HbA==", + "license": "MIT", + "dependencies": { + "convert-hrtime": "^5.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/tinyglobby": { + "version": "0.2.16", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.16.tgz", + "integrity": "sha512-pn99VhoACYR8nFHhxqix+uvsbXineAasWm5ojXoN8xEwK5Kd3/TrhNn1wByuD52UxWRLy8pu+kRMniEi6Eq9Zg==", + "license": "MIT", + "dependencies": { + "fdir": "^6.5.0", + "picomatch": "^4.0.4" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, + "node_modules/tinyglobby/node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", + "license": "MIT", + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/tinyglobby/node_modules/picomatch": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", + "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "license": "MIT", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/traverse": { + "version": "0.6.8", + "resolved": "https://registry.npmjs.org/traverse/-/traverse-0.6.8.tgz", + "integrity": "sha512-aXJDbk6SnumuaZSANd21XAo15ucCDE38H4fkqiGsc3MhCK+wOlZvLP9cB/TvpHT0mOyWgC4Z8EwRlzqYSUzdsA==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/type-fest": { + "version": "4.41.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.41.0.tgz", + "integrity": "sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==", + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/uglify-js": { + "version": "3.19.3", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.19.3.tgz", + "integrity": "sha512-v3Xu+yuwBXisp6QYTcH4UbH+xYJXqnq2m/LtQVWKWzYc1iehYnLixoQDN9FH6/j9/oybfd6W9Ghwkl8+UMKTKQ==", + "license": "BSD-2-Clause", + "optional": true, + "bin": { + "uglifyjs": "bin/uglifyjs" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/unicode-emoji-modifier-base": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unicode-emoji-modifier-base/-/unicode-emoji-modifier-base-1.0.0.tgz", + "integrity": "sha512-yLSH4py7oFH3oG/9K+XWrz1pSi3dfUrWEnInbxMfArOfc1+33BlGPQtLsOYwvdMy11AwUBetYuaRxSPqgkq+8g==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/unicorn-magic": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/unicorn-magic/-/unicorn-magic-0.3.0.tgz", + "integrity": "sha512-+QBBXBCvifc56fsbuxZQ6Sic3wqqc3WWaqxs58gvJrcOuN83HGTCwz3oS5phzU9LthRNE9VrJCFCLUgHeeFnfA==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/unique-string": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-3.0.0.tgz", + "integrity": "sha512-VGXBUVwxKMBUznyffQweQABPRRW1vHZAbadFZud4pLFAqRGvv/96vafgjWFqzourzr8YonlQiPgH0YCJfawoGQ==", + "license": "MIT", + "dependencies": { + "crypto-random-string": "^4.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/universal-user-agent": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-7.0.3.tgz", + "integrity": "sha512-TmnEAEAsBJVZM/AADELsK76llnwcf9vMKuPz8JflO1frO8Lchitr0fNaN9d+Ap0BjKtqWqd/J17qeDnXh8CL2A==", + "license": "ISC" + }, + "node_modules/universalify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", + "license": "MIT", + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/url-join": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/url-join/-/url-join-5.0.0.tgz", + "integrity": "sha512-n2huDr9h9yzd6exQVnH/jU5mr+Pfx08LRXXZhkLLetAMESRj+anQsTAh940iMrIetKAmry9coFuZQ2jY8/p3WA==", + "license": "MIT", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "license": "MIT" + }, + "node_modules/validate-npm-package-license": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", + "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", + "license": "Apache-2.0", + "dependencies": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, + "node_modules/web-worker": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/web-worker/-/web-worker-1.5.0.tgz", + "integrity": "sha512-RiMReJrTAiA+mBjGONMnjVDP2u3p9R1vkcGz6gDIrOMT3oGuYwX2WRMYI9ipkphSuE5XKEhydbhNEJh4NY9mlw==", + "license": "Apache-2.0" + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/wordwrap": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", + "integrity": "sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==", + "license": "MIT" + }, + "node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "license": "MIT", + "engines": { + "node": ">=0.4" + } + }, + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs": { + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "license": "MIT", + "dependencies": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/yoctocolors": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yoctocolors/-/yoctocolors-2.1.2.tgz", + "integrity": "sha512-CzhO+pFNo8ajLM2d2IW/R93ipy99LWjtwblvC1RsoSUMZgyLbYFr221TnSNT7GjGdYui6P459mw9JH/g/zW2ug==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + } + } +} diff --git a/package.json b/package.json index c0a173ca7..62cb76ca8 100644 --- a/package.json +++ b/package.json @@ -2,6 +2,7 @@ "name": "devsy", "private": true, "devDependencies": { - "@biomejs/biome": "2.4.12" + "@biomejs/biome": "2.4.12", + "semantic-release": "^24.2.3" } } diff --git a/pkg/agent/delivery/local_docker.go b/pkg/agent/delivery/local_docker.go index 3149b3a24..74a7a7cc7 100644 --- a/pkg/agent/delivery/local_docker.go +++ b/pkg/agent/delivery/local_docker.go @@ -13,6 +13,7 @@ import ( "github.com/devsy-org/devsy/pkg/agent" "github.com/devsy-org/devsy/pkg/devcontainer/config" "github.com/devsy-org/devsy/pkg/log" + "github.com/devsy-org/devsy/pkg/version" ) var _ AgentDelivery = (*LocalDockerDelivery)(nil) @@ -26,9 +27,10 @@ const ( ) type LocalDockerDelivery struct { - DockerCommand string - Environment []string - HelperImage string + DockerCommand string + Environment []string + HelperImage string + ExpectedVersion string } func (d *LocalDockerDelivery) Phase() DeliveryPhase { @@ -46,11 +48,8 @@ func (d *LocalDockerDelivery) DeliverPreStart(ctx context.Context, opts PreStart return fmt.Errorf("create agent volume: %w", err) } - if err := d.populateVolume(ctx, volumeName, opts.BinarySource, opts.Arch); err != nil { - if removeErr := d.removeVolume(ctx, volumeName); removeErr != nil { - log.Debugf("failed to clean up volume after populate failure: %v", removeErr) - } - return fmt.Errorf("populate agent volume: %w", err) + if err := d.ensureCurrentBinary(ctx, volumeName, opts.BinarySource, opts.Arch); err != nil { + return err } opts.RunOptions.Mounts = append(opts.RunOptions.Mounts, &config.Mount{ @@ -75,6 +74,36 @@ func (d *LocalDockerDelivery) Cleanup(ctx context.Context, workspaceID string) e return d.removeVolume(ctx, workspaceID) } +func (d *LocalDockerDelivery) ensureCurrentBinary( + ctx context.Context, + volumeName string, + binarySource BinarySourceFunc, + arch string, +) error { + expected := d.expectedVersion() + actual := d.detectVolumeVersion(ctx, volumeName) + + if actual != "" && actual == expected { + log.Debugf( + "remote agent version matches expected version %s, skipping delivery", + expected, + ) + return nil + } + + if actual != "" { + log.Infof("upgraded remote agent from %s → %s", actual, expected) + } + + if err := d.populateVolume(ctx, volumeName, binarySource, arch); err != nil { + if removeErr := d.removeVolume(ctx, volumeName); removeErr != nil { + log.Debugf("failed to clean up volume after populate failure: %v", removeErr) + } + return fmt.Errorf("populate agent volume: %w", err) + } + return nil +} + func (d *LocalDockerDelivery) createVolume(ctx context.Context, name string) error { out, err := d.cmd(ctx, "volume", "create", name).CombinedOutput() if err != nil { @@ -90,6 +119,34 @@ func (d *LocalDockerDelivery) helperImageName() string { return defaultHelperImage } +func (d *LocalDockerDelivery) expectedVersion() string { + if d.ExpectedVersion != "" { + return d.ExpectedVersion + } + return version.GetVersion() +} + +func (d *LocalDockerDelivery) detectVolumeVersion(ctx context.Context, volumeName string) string { + binaryPath := volumeMountPath + "/" + binaryName() + script := fmt.Sprintf( + `[ -x "%s" ] && "%s" version 2>/dev/null || true`, + binaryPath, binaryPath, + ) + args := []string{ + "run", "--rm", + "-v", volumeName + ":" + volumeMountPath, + d.helperImageName(), + "sh", "-c", script, + } + + out, err := d.cmd(ctx, args...).CombinedOutput() + if err != nil { + log.Debugf("failed to detect agent version in volume: %v", err) + return "" + } + return strings.TrimSpace(string(out)) +} + func (d *LocalDockerDelivery) populateVolume( ctx context.Context, volumeName string, diff --git a/pkg/agent/delivery/local_docker_test.go b/pkg/agent/delivery/local_docker_test.go index 744fcb46c..8bf425200 100644 --- a/pkg/agent/delivery/local_docker_test.go +++ b/pkg/agent/delivery/local_docker_test.go @@ -8,11 +8,14 @@ import ( "path/filepath" "testing" + "github.com/devsy-org/devsy/pkg/driver" "github.com/devsy-org/devsy/pkg/provider" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) +const testArch = "amd64" + func TestLocalDockerDelivery_Phase(t *testing.T) { d := &LocalDockerDelivery{} assert.Equal(t, PhasePreStart, d.Phase()) @@ -112,7 +115,7 @@ func TestPopulateVolume_FallbackToDirectCopy(t *testing.T) { DockerCommand: scriptPath, } - err := d.populateVolume(context.Background(), "test-vol", binarySource, "amd64") + err := d.populateVolume(context.Background(), "test-vol", binarySource, testArch) require.NoError(t, err) destPath := filepath.Join(mountDir, binaryName()) @@ -222,3 +225,164 @@ func TestPopulateVolumeViaUnshare_FailureReturnsError(t *testing.T) { require.Error(t, err) assert.Contains(t, err.Error(), "podman unshare write failed") } + +func TestDetectVolumeVersion_ReturnsVersionFromHelper(t *testing.T) { + tmpDir := t.TempDir() + + scriptPath := filepath.Join(tmpDir, "fake-docker.sh") + script := "#!/bin/sh\n" + + "case \"$1\" in\n" + + " run) echo \"v1.2.3\" ;;\n" + + " *) exit 1 ;;\n" + + "esac\n" + require.NoError(t, os.WriteFile(scriptPath, []byte(script), 0o600)) + // #nosec G302 -- test script must be executable + require.NoError(t, os.Chmod(scriptPath, 0o755)) + + d := &LocalDockerDelivery{DockerCommand: scriptPath} + ver := d.detectVolumeVersion(context.Background(), "test-vol") + assert.Equal(t, "v1.2.3", ver) +} + +func TestDetectVolumeVersion_ReturnsEmptyOnFailure(t *testing.T) { + tmpDir := t.TempDir() + + scriptPath := filepath.Join(tmpDir, "fake-docker.sh") + script := "#!/bin/sh\nexit 1\n" + require.NoError(t, os.WriteFile(scriptPath, []byte(script), 0o600)) + // #nosec G302 -- test script must be executable + require.NoError(t, os.Chmod(scriptPath, 0o755)) + + d := &LocalDockerDelivery{DockerCommand: scriptPath} + ver := d.detectVolumeVersion(context.Background(), "test-vol") + assert.Empty(t, ver) +} + +func TestDetectVolumeVersion_ReturnsEmptyWhenNoBinary(t *testing.T) { + tmpDir := t.TempDir() + + scriptPath := filepath.Join(tmpDir, "fake-docker.sh") + script := "#!/bin/sh\n" + + "case \"$1\" in\n" + + " run) echo \"\" ;;\n" + + " *) exit 1 ;;\n" + + "esac\n" + require.NoError(t, os.WriteFile(scriptPath, []byte(script), 0o600)) + // #nosec G302 -- test script must be executable + require.NoError(t, os.Chmod(scriptPath, 0o755)) + + d := &LocalDockerDelivery{DockerCommand: scriptPath} + ver := d.detectVolumeVersion(context.Background(), "test-vol") + assert.Empty(t, ver) +} + +func TestDeliverPreStart_VersionMatch_SkipsPopulate(t *testing.T) { + tmpDir := t.TempDir() + + populateCalled := false + scriptPath := filepath.Join(tmpDir, "fake-docker.sh") + markerPath := filepath.Join(tmpDir, "populate-called") + script := "#!/bin/sh\n" + + "case \"$1\" in\n" + + " volume) echo \"ok\" ;;\n" + + " run)\n" + + " if echo \"$@\" | grep -q \"\\-i\"; then\n" + + " touch \"" + markerPath + "\"\n" + + " cat > /dev/null\n" + + " else\n" + + " echo \"v2.0.0\"\n" + + " fi\n" + + " ;;\n" + + " *) exit 1 ;;\n" + + "esac\n" + require.NoError(t, os.WriteFile(scriptPath, []byte(script), 0o600)) + // #nosec G302 -- test script must be executable + require.NoError(t, os.Chmod(scriptPath, 0o755)) + + binarySource := func(_ context.Context, _ string) (io.ReadCloser, error) { + return io.NopCloser(bytes.NewReader([]byte("binary"))), nil + } + + d := &LocalDockerDelivery{ + DockerCommand: scriptPath, + ExpectedVersion: "v2.0.0", + } + + opts := PreStartOptions{ + WorkspaceID: "test-ws", + RunOptions: &driver.RunOptions{}, + BinarySource: binarySource, + Arch: testArch, + } + + err := d.DeliverPreStart(context.Background(), opts) + require.NoError(t, err) + + _, statErr := os.Stat(markerPath) + populateCalled = statErr == nil + assert.False(t, populateCalled, "populateVolume should not be called when versions match") +} + +func TestDeliverPreStart_VersionMismatch_Overwrites(t *testing.T) { + tmpDir := t.TempDir() + mountDir := filepath.Join(tmpDir, "mount") + require.NoError(t, os.MkdirAll(mountDir, 0o750)) + + scriptPath := filepath.Join(tmpDir, "fake-docker.sh") + script := "#!/bin/sh\n" + + "case \"$1\" in\n" + + " volume)\n" + + " case \"$2\" in\n" + + " create) echo \"ok\" ;;\n" + + " inspect) echo \"" + mountDir + "\" ;;\n" + + " *) exit 1 ;;\n" + + " esac\n" + + " ;;\n" + + " run)\n" + + " if echo \"$@\" | grep -q \"\\-i\"; then\n" + + " echo \"image not found\" >&2; exit 1\n" + + " else\n" + + " echo \"v1.0.0\"\n" + + " fi\n" + + " ;;\n" + + " *) exit 1 ;;\n" + + "esac\n" + require.NoError(t, os.WriteFile(scriptPath, []byte(script), 0o600)) + // #nosec G302 -- test script must be executable + require.NoError(t, os.Chmod(scriptPath, 0o755)) + + binaryContent := []byte("new-agent-binary") + binarySource := func(_ context.Context, _ string) (io.ReadCloser, error) { + return io.NopCloser(bytes.NewReader(binaryContent)), nil + } + + d := &LocalDockerDelivery{ + DockerCommand: scriptPath, + ExpectedVersion: "v2.0.0", + } + + opts := PreStartOptions{ + WorkspaceID: "test-ws", + RunOptions: &driver.RunOptions{}, + BinarySource: binarySource, + Arch: testArch, + } + + err := d.DeliverPreStart(context.Background(), opts) + require.NoError(t, err) + + destPath := filepath.Join(mountDir, binaryName()) + data, err := os.ReadFile(destPath) //nolint:gosec // test reads from a temp directory we control + require.NoError(t, err) + assert.Equal(t, binaryContent, data) +} + +func TestExpectedVersion_UsesFieldWhenSet(t *testing.T) { + d := &LocalDockerDelivery{ExpectedVersion: "v3.0.0"} + assert.Equal(t, "v3.0.0", d.expectedVersion()) +} + +func TestExpectedVersion_FallsBackToGetVersion(t *testing.T) { + d := &LocalDockerDelivery{} + assert.NotEmpty(t, d.expectedVersion()) +} diff --git a/pkg/workspace/rename.go b/pkg/workspace/rename.go index 9dd9b6749..ac42b5b64 100644 --- a/pkg/workspace/rename.go +++ b/pkg/workspace/rename.go @@ -5,9 +5,12 @@ import ( "errors" "fmt" "os" + "path/filepath" + "strings" client2 "github.com/devsy-org/devsy/pkg/client" "github.com/devsy-org/devsy/pkg/config" + devcontainerconfig "github.com/devsy-org/devsy/pkg/devcontainer/config" "github.com/devsy-org/devsy/pkg/log" "github.com/devsy-org/devsy/pkg/platform" "github.com/devsy-org/devsy/pkg/provider" @@ -77,6 +80,96 @@ func stopWorkspaceIfRunning( return nil } +type pathReplacer struct { + pairs [][2]string + changed bool +} + +func newPathReplacer( + containerWorkspaceFolder, localWorkspaceFolder, oldName, newName string, +) *pathReplacer { + r := &pathReplacer{} + + if containerWorkspaceFolder != "" { + containerParent := strings.TrimSuffix( + containerWorkspaceFolder, filepath.Base(containerWorkspaceFolder), + ) + r.pairs = append(r.pairs, [2]string{ + containerParent + oldName, + containerParent + newName, + }) + } + + if localWorkspaceFolder != "" { + localParent := strings.TrimSuffix( + localWorkspaceFolder, filepath.Base(localWorkspaceFolder), + ) + r.pairs = append(r.pairs, [2]string{ + localParent + oldName, + localParent + newName, + }) + } + + return r +} + +func (r *pathReplacer) replace(s string) string { + for _, pair := range r.pairs { + if strings.Contains(s, pair[0]) { + s = strings.ReplaceAll(s, pair[0], pair[1]) + r.changed = true + } + } + return s +} + +func (r *pathReplacer) applyToMergedConfig(mc *devcontainerconfig.MergedDevContainerConfig) { + if mc == nil { + return + } + mc.WorkspaceFolder = r.replace(mc.WorkspaceFolder) + if mc.WorkspaceMount != nil { + updated := r.replace(*mc.WorkspaceMount) + mc.WorkspaceMount = &updated + } +} + +// updateWorkspaceResult rewrites workspace_result.json to replace references +// to the old workspace name with the new one. This ensures that cached paths +// like ContainerWorkspaceFolder, LocalWorkspaceFolder, and WorkspaceMount +// stay valid after rename. +func updateWorkspaceResult(devsyConfig *config.Config, oldName, newName string) { + context := devsyConfig.DefaultContext + result, err := provider.LoadWorkspaceResult(context, newName) + if err != nil || result == nil { + return + } + + var containerWSFolder, localWSFolder string + if sc := result.SubstitutionContext; sc != nil { + containerWSFolder = sc.ContainerWorkspaceFolder + localWSFolder = sc.LocalWorkspaceFolder + } + + r := newPathReplacer(containerWSFolder, localWSFolder, oldName, newName) + + if sc := result.SubstitutionContext; sc != nil { + sc.ContainerWorkspaceFolder = r.replace(sc.ContainerWorkspaceFolder) + sc.LocalWorkspaceFolder = r.replace(sc.LocalWorkspaceFolder) + sc.WorkspaceMount = r.replace(sc.WorkspaceMount) + } + r.applyToMergedConfig(result.MergedConfig) + + if !r.changed { + return + } + + ws := &provider.Workspace{ID: newName, Context: context} + if err := provider.SaveWorkspaceResult(ws, result); err != nil { + log.Warnf("failed to update workspace result after rename: %v", err) + } +} + // Rename performs the workspace rename: auto-stops if running, moves the // workspace directory, updates the config ID, and removes the old SSH config // entry. If any step after the directory move fails, the entire operation is @@ -109,6 +202,8 @@ func Rename(ctx context.Context, opts RenameOptions) error { return errors.Join(err, rollbackErr) } + updateWorkspaceResult(opts.DevsyConfig, opts.OldName, opts.NewName) + _ = devssh.RemoveFromConfig( opts.OldName, wsConfig.SSHConfigPath, diff --git a/pkg/workspace/rename_integration_test.go b/pkg/workspace/rename_integration_test.go new file mode 100644 index 000000000..5663af618 --- /dev/null +++ b/pkg/workspace/rename_integration_test.go @@ -0,0 +1,393 @@ +package workspace + +import ( + "encoding/json" + "os" + "path/filepath" + "testing" + + "github.com/devsy-org/devsy/pkg/config" + devcontainerconfig "github.com/devsy-org/devsy/pkg/devcontainer/config" + "github.com/devsy-org/devsy/pkg/provider" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +const ( + testDefaultContext = "default" + testContainerWSMount = "/workspaces/ws-old" +) + +func setupTestPathManager(t *testing.T) { + t.Helper() + + t.Setenv("XDG_DATA_HOME", t.TempDir()) + t.Setenv("XDG_CONFIG_HOME", t.TempDir()) + t.Setenv("XDG_CACHE_HOME", t.TempDir()) + t.Setenv("XDG_STATE_HOME", t.TempDir()) + t.Setenv("XDG_RUNTIME_DIR", t.TempDir()) + + config.ResetPathManager() + t.Cleanup(config.ResetPathManager) +} + +func writeWorkspaceResult( + t *testing.T, workspaceID string, result *devcontainerconfig.Result, +) { + t.Helper() + + ws := &provider.Workspace{ID: workspaceID, Context: testDefaultContext} + require.NoError(t, provider.SaveWorkspaceResult(ws, result)) +} + +func loadWorkspaceResult( + t *testing.T, workspaceID string, +) *devcontainerconfig.Result { + t.Helper() + + result, err := provider.LoadWorkspaceResult(testDefaultContext, workspaceID) + require.NoError(t, err) + require.NotNil(t, result) + + return result +} + +func ptrStr(s string) *string { return &s } + +func TestUpdateWorkspaceResult_BasicRename(t *testing.T) { + setupTestPathManager(t) + + oldName := "my-project" + newName := "my-project-renamed" + + result := &devcontainerconfig.Result{ + SubstitutionContext: &devcontainerconfig.SubstitutionContext{ + ContainerWorkspaceFolder: "/workspaces/my-project", + LocalWorkspaceFolder: "/home/user/my-project", + WorkspaceMount: "type=bind,source=/home/user/my-project,target=/workspaces/my-project", + }, + MergedConfig: &devcontainerconfig.MergedDevContainerConfig{}, + } + result.MergedConfig.WorkspaceFolder = "/workspaces/my-project" + result.MergedConfig.WorkspaceMount = ptrStr( + "type=bind,source=/home/user/my-project,target=/workspaces/my-project", + ) + + writeWorkspaceResult(t, newName, result) + + devsyConfig := &config.Config{DefaultContext: testDefaultContext} + updateWorkspaceResult(devsyConfig, oldName, newName) + + got := loadWorkspaceResult(t, newName) + + assert.Equal( + t, + "/workspaces/my-project-renamed", + got.SubstitutionContext.ContainerWorkspaceFolder, + ) + assert.Equal(t, "/home/user/my-project-renamed", got.SubstitutionContext.LocalWorkspaceFolder) + assert.Contains(t, got.SubstitutionContext.WorkspaceMount, "/workspaces/my-project-renamed") + assert.Contains(t, got.SubstitutionContext.WorkspaceMount, "/home/user/my-project-renamed") + assert.Equal(t, "/workspaces/my-project-renamed", got.MergedConfig.WorkspaceFolder) + require.NotNil(t, got.MergedConfig.WorkspaceMount) + assert.Contains(t, *got.MergedConfig.WorkspaceMount, "/workspaces/my-project-renamed") + assert.Contains(t, *got.MergedConfig.WorkspaceMount, "/home/user/my-project-renamed") +} + +func TestUpdateWorkspaceResult_MergedConfigUpdated(t *testing.T) { + setupTestPathManager(t) + + oldName := "app" + newName := "app-v2" + + result := &devcontainerconfig.Result{ + SubstitutionContext: &devcontainerconfig.SubstitutionContext{ + ContainerWorkspaceFolder: "/workspaces/app", + LocalWorkspaceFolder: "/home/dev/app", + WorkspaceMount: "type=bind,source=/home/dev/app,target=/workspaces/app", + }, + MergedConfig: &devcontainerconfig.MergedDevContainerConfig{}, + } + result.MergedConfig.WorkspaceFolder = "/workspaces/app" + result.MergedConfig.WorkspaceMount = ptrStr( + "type=bind,source=/home/dev/app,target=/workspaces/app", + ) + + writeWorkspaceResult(t, newName, result) + + devsyConfig := &config.Config{DefaultContext: testDefaultContext} + updateWorkspaceResult(devsyConfig, oldName, newName) + + got := loadWorkspaceResult(t, newName) + + assert.Equal(t, "/workspaces/app-v2", got.MergedConfig.WorkspaceFolder) + require.NotNil(t, got.MergedConfig.WorkspaceMount) + assert.Equal( + t, + "type=bind,source=/home/dev/app-v2,target=/workspaces/app-v2", + *got.MergedConfig.WorkspaceMount, + ) +} + +func TestUpdateWorkspaceResult_NonDefaultWorkspaceDir(t *testing.T) { + setupTestPathManager(t) + + oldName := "project" + newName := "project-new" + + result := &devcontainerconfig.Result{ + SubstitutionContext: &devcontainerconfig.SubstitutionContext{ + ContainerWorkspaceFolder: "/home/coder/project", + LocalWorkspaceFolder: "/mnt/data/project", + WorkspaceMount: "type=bind,source=/mnt/data/project,target=/home/coder/project", + }, + MergedConfig: &devcontainerconfig.MergedDevContainerConfig{}, + } + result.MergedConfig.WorkspaceFolder = "/home/coder/project" + result.MergedConfig.WorkspaceMount = ptrStr( + "type=bind,source=/mnt/data/project,target=/home/coder/project", + ) + + writeWorkspaceResult(t, newName, result) + + devsyConfig := &config.Config{DefaultContext: testDefaultContext} + updateWorkspaceResult(devsyConfig, oldName, newName) + + got := loadWorkspaceResult(t, newName) + + assert.Equal(t, "/home/coder/project-new", got.SubstitutionContext.ContainerWorkspaceFolder) + assert.Equal(t, "/mnt/data/project-new", got.SubstitutionContext.LocalWorkspaceFolder) + assert.Equal( + t, + "type=bind,source=/mnt/data/project-new,target=/home/coder/project-new", + got.SubstitutionContext.WorkspaceMount, + ) + assert.Equal(t, "/home/coder/project-new", got.MergedConfig.WorkspaceFolder) + require.NotNil(t, got.MergedConfig.WorkspaceMount) + assert.Equal( + t, + "type=bind,source=/mnt/data/project-new,target=/home/coder/project-new", + *got.MergedConfig.WorkspaceMount, + ) +} + +func TestUpdateWorkspaceResult_NestedPath(t *testing.T) { + setupTestPathManager(t) + + oldName := "repo" + newName := "repo-renamed" + + result := &devcontainerconfig.Result{ + SubstitutionContext: &devcontainerconfig.SubstitutionContext{ + ContainerWorkspaceFolder: "/workspaces/org/repo", + LocalWorkspaceFolder: "/home/user/dev/org/repo", + WorkspaceMount: "type=bind,source=/home/user/dev/org/repo,target=/workspaces/org/repo", + }, + MergedConfig: &devcontainerconfig.MergedDevContainerConfig{}, + } + result.MergedConfig.WorkspaceFolder = "/workspaces/org/repo" + result.MergedConfig.WorkspaceMount = ptrStr( + "type=bind,source=/home/user/dev/org/repo,target=/workspaces/org/repo", + ) + + writeWorkspaceResult(t, newName, result) + + devsyConfig := &config.Config{DefaultContext: testDefaultContext} + updateWorkspaceResult(devsyConfig, oldName, newName) + + got := loadWorkspaceResult(t, newName) + + assert.Equal( + t, + "/workspaces/org/repo-renamed", + got.SubstitutionContext.ContainerWorkspaceFolder, + ) + assert.Equal(t, "/home/user/dev/org/repo-renamed", got.SubstitutionContext.LocalWorkspaceFolder) + assert.Contains(t, got.SubstitutionContext.WorkspaceMount, "/workspaces/org/repo-renamed") + assert.Contains(t, got.SubstitutionContext.WorkspaceMount, "/home/user/dev/org/repo-renamed") + assert.Equal(t, "/workspaces/org/repo-renamed", got.MergedConfig.WorkspaceFolder) +} + +func TestUpdateWorkspaceResult_SameNameIdempotent(t *testing.T) { + setupTestPathManager(t) + + name := "my-ws" + + result := &devcontainerconfig.Result{ + SubstitutionContext: &devcontainerconfig.SubstitutionContext{ + ContainerWorkspaceFolder: "/workspaces/my-ws", + LocalWorkspaceFolder: "/home/user/my-ws", + WorkspaceMount: "type=bind,source=/home/user/my-ws,target=/workspaces/my-ws", + }, + MergedConfig: &devcontainerconfig.MergedDevContainerConfig{}, + } + result.MergedConfig.WorkspaceFolder = "/workspaces/my-ws" + result.MergedConfig.WorkspaceMount = ptrStr( + "type=bind,source=/home/user/my-ws,target=/workspaces/my-ws", + ) + + writeWorkspaceResult(t, name, result) + + devsyConfig := &config.Config{DefaultContext: testDefaultContext} + updateWorkspaceResult(devsyConfig, name, name) + + got := loadWorkspaceResult(t, name) + assert.Equal(t, "/workspaces/my-ws", got.SubstitutionContext.ContainerWorkspaceFolder) + assert.Equal(t, "/home/user/my-ws", got.SubstitutionContext.LocalWorkspaceFolder) + assert.Equal(t, + "type=bind,source=/home/user/my-ws,target=/workspaces/my-ws", + got.SubstitutionContext.WorkspaceMount, + ) + assert.Equal(t, "/workspaces/my-ws", got.MergedConfig.WorkspaceFolder) +} + +func TestUpdateWorkspaceResult_NilMergedConfig(t *testing.T) { + setupTestPathManager(t) + + oldName := "ws-old" + newName := "ws-new" + + result := &devcontainerconfig.Result{ + SubstitutionContext: &devcontainerconfig.SubstitutionContext{ + ContainerWorkspaceFolder: testContainerWSMount, + LocalWorkspaceFolder: "/home/user/ws-old", + WorkspaceMount: "type=bind,source=/home/user/ws-old,target=" + testContainerWSMount, + }, + MergedConfig: nil, + } + + writeWorkspaceResult(t, newName, result) + + devsyConfig := &config.Config{DefaultContext: testDefaultContext} + updateWorkspaceResult(devsyConfig, oldName, newName) + + got := loadWorkspaceResult(t, newName) + + assert.Equal(t, "/workspaces/ws-new", got.SubstitutionContext.ContainerWorkspaceFolder) + assert.Equal(t, "/home/user/ws-new", got.SubstitutionContext.LocalWorkspaceFolder) + assert.Contains(t, got.SubstitutionContext.WorkspaceMount, "/workspaces/ws-new") +} + +func TestUpdateWorkspaceResult_NilWorkspaceMount(t *testing.T) { + setupTestPathManager(t) + + oldName := "ws-old" + newName := "ws-new" + + result := &devcontainerconfig.Result{ + SubstitutionContext: &devcontainerconfig.SubstitutionContext{ + ContainerWorkspaceFolder: testContainerWSMount, + LocalWorkspaceFolder: "/home/user/ws-old", + WorkspaceMount: "type=bind,source=/home/user/ws-old,target=" + testContainerWSMount, + }, + MergedConfig: &devcontainerconfig.MergedDevContainerConfig{}, + } + result.MergedConfig.WorkspaceFolder = testContainerWSMount + result.MergedConfig.WorkspaceMount = nil + + writeWorkspaceResult(t, newName, result) + + devsyConfig := &config.Config{DefaultContext: testDefaultContext} + updateWorkspaceResult(devsyConfig, oldName, newName) + + got := loadWorkspaceResult(t, newName) + + assert.Equal(t, "/workspaces/ws-new", got.MergedConfig.WorkspaceFolder) + assert.Nil(t, got.MergedConfig.WorkspaceMount) +} + +func TestUpdateWorkspaceResult_NoResultFile(t *testing.T) { + setupTestPathManager(t) + + oldName := "nonexistent-old" + newName := "nonexistent-new" + + wsDir, err := provider.GetWorkspaceDir(testDefaultContext, newName) + require.NoError(t, err) + require.NoError(t, os.MkdirAll(wsDir, 0o750)) + + devsyConfig := &config.Config{DefaultContext: testDefaultContext} + updateWorkspaceResult(devsyConfig, oldName, newName) + + _, err = os.Stat(filepath.Join(wsDir, "workspace_result.json")) + assert.True(t, os.IsNotExist(err), "should not create file when none exists") +} + +func TestUpdateWorkspaceResult_PreservesOtherFields(t *testing.T) { + setupTestPathManager(t) + + oldName := "myapp" + newName := "myapp-v2" + + result := &devcontainerconfig.Result{ + SubstitutionContext: &devcontainerconfig.SubstitutionContext{ + DevContainerID: "abc123", + ContainerWorkspaceFolder: "/workspaces/myapp", + LocalWorkspaceFolder: "/home/user/myapp", + WorkspaceMount: "type=bind,source=/home/user/myapp,target=/workspaces/myapp", + Env: map[string]string{"FOO": "bar"}, + }, + MergedConfig: &devcontainerconfig.MergedDevContainerConfig{}, + HostWarnings: []string{"some warning"}, + } + result.MergedConfig.WorkspaceFolder = "/workspaces/myapp" + + writeWorkspaceResult(t, newName, result) + + devsyConfig := &config.Config{DefaultContext: testDefaultContext} + updateWorkspaceResult(devsyConfig, oldName, newName) + + got := loadWorkspaceResult(t, newName) + + assert.Equal(t, "abc123", got.SubstitutionContext.DevContainerID) + assert.Equal(t, map[string]string{"FOO": "bar"}, got.SubstitutionContext.Env) + assert.Equal(t, []string{"some warning"}, got.HostWarnings) +} + +func TestUpdateWorkspaceResult_RawJSON(t *testing.T) { + setupTestPathManager(t) + + oldName := "old-ws" + newName := "new-ws" + + wsDir, err := provider.GetWorkspaceDir(testDefaultContext, newName) + require.NoError(t, err) + require.NoError(t, os.MkdirAll(wsDir, 0o750)) + + rawJSON := `{ + "SubstitutionContext": { + "ContainerWorkspaceFolder": "/workspaces/old-ws", + "LocalWorkspaceFolder": "/home/user/old-ws", + "WorkspaceMount": "type=bind,source=/home/user/old-ws,target=/workspaces/old-ws" + }, + "MergedConfig": { + "workspaceFolder": "/workspaces/old-ws", + "workspaceMount": "type=bind,source=/home/user/old-ws,target=/workspaces/old-ws" + } +}` + + resultFile := filepath.Join(wsDir, "workspace_result.json") + require.NoError(t, os.WriteFile(resultFile, []byte(rawJSON), 0o600)) + + devsyConfig := &config.Config{DefaultContext: testDefaultContext} + updateWorkspaceResult(devsyConfig, oldName, newName) + + updatedBytes, err := os.ReadFile(resultFile) //nolint:gosec + require.NoError(t, err) + + var got devcontainerconfig.Result + require.NoError(t, json.Unmarshal(updatedBytes, &got)) + + assert.Equal(t, "/workspaces/new-ws", got.SubstitutionContext.ContainerWorkspaceFolder) + assert.Equal(t, "/home/user/new-ws", got.SubstitutionContext.LocalWorkspaceFolder) + assert.Equal(t, + "type=bind,source=/home/user/new-ws,target=/workspaces/new-ws", + got.SubstitutionContext.WorkspaceMount, + ) + assert.Equal(t, "/workspaces/new-ws", got.MergedConfig.WorkspaceFolder) + require.NotNil(t, got.MergedConfig.WorkspaceMount) + assert.Equal(t, + "type=bind,source=/home/user/new-ws,target=/workspaces/new-ws", + *got.MergedConfig.WorkspaceMount, + ) +} diff --git a/pkg/workspace/rename_test.go b/pkg/workspace/rename_test.go new file mode 100644 index 000000000..f084e9b68 --- /dev/null +++ b/pkg/workspace/rename_test.go @@ -0,0 +1,296 @@ +package workspace + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +const ( + testContainerNewWS = "/workspaces/new-ws" + testLocalNewWS = "/home/user/new-ws" + testContainerNew = "/workspaces/new" + testContainerOldWS = "/workspaces/old-ws" + testLocalOldWS = "/home/user/old-ws" + testContainerApp = "/workspaces/app" + testContainerOld = "/workspaces/old" +) + +func TestNewPathReplacer_DefaultWorkspaceDir(t *testing.T) { + r := newPathReplacer(testContainerOldWS, testLocalOldWS, "old-ws", "new-ws") + + expected := [][2]string{ + {testContainerOldWS, testContainerNewWS}, + {testLocalOldWS, testLocalNewWS}, + } + + assert.NotNil(t, r) + assert.Equal(t, expected, r.pairs) + assert.False(t, r.changed) +} + +func TestNewPathReplacer_NonDefaultWorkspaceDir(t *testing.T) { + r := newPathReplacer("/home/user/project", "/mnt/data/project", "project", "renamed") + + expected := [][2]string{ + {"/home/user/project", "/home/user/renamed"}, + {"/mnt/data/project", "/mnt/data/renamed"}, + } + + assert.Equal(t, expected, r.pairs) + assert.False(t, r.changed) +} + +func TestNewPathReplacer_NestedWorkspacePath(t *testing.T) { + r := newPathReplacer( + "/workspace/dev/projects/my-app", + "/home/user/workspace/dev/projects/my-app", + "my-app", + "my-app-v2", + ) + + expected := [][2]string{ + {"/workspace/dev/projects/my-app", "/workspace/dev/projects/my-app-v2"}, + { + "/home/user/workspace/dev/projects/my-app", + "/home/user/workspace/dev/projects/my-app-v2", + }, + } + + assert.Equal(t, expected, r.pairs) +} + +func TestNewPathReplacer_EmptyContainerFolder(t *testing.T) { + r := newPathReplacer("", testLocalOldWS, "old-ws", "new-ws") + + expected := [][2]string{ + {testLocalOldWS, testLocalNewWS}, + } + + assert.Equal(t, expected, r.pairs) +} + +func TestNewPathReplacer_EmptyLocalFolder(t *testing.T) { + r := newPathReplacer(testContainerOldWS, "", "old-ws", "new-ws") + + expected := [][2]string{ + {testContainerOldWS, testContainerNewWS}, + } + + assert.Equal(t, expected, r.pairs) +} + +func TestNewPathReplacer_BothEmpty(t *testing.T) { + r := newPathReplacer("", "", "old-ws", "new-ws") + + assert.Nil(t, r.pairs) +} + +func TestNewPathReplacer_SpecialCharacters(t *testing.T) { + r := newPathReplacer( + "/workspaces/my-app_v1.0", + "/home/user/my-app_v1.0", + "my-app_v1.0", + "my-app_v2.0", + ) + + expected := [][2]string{ + {"/workspaces/my-app_v1.0", "/workspaces/my-app_v2.0"}, + {"/home/user/my-app_v1.0", "/home/user/my-app_v2.0"}, + } + + assert.Equal(t, expected, r.pairs) +} + +func TestPathReplacer_Replace_BasicReplacement(t *testing.T) { + r := &pathReplacer{ + pairs: [][2]string{ + {testContainerOldWS, testContainerNewWS}, + }, + } + + output := r.replace("/workspaces/old-ws/src/main.go") + + assert.Equal(t, "/workspaces/new-ws/src/main.go", output) + assert.True(t, r.changed) +} + +func TestPathReplacer_Replace_NoMatch(t *testing.T) { + r := &pathReplacer{ + pairs: [][2]string{ + {testContainerOldWS, testContainerNewWS}, + }, + } + + output := r.replace("/workspaces/other-ws/src/main.go") + + assert.Equal(t, "/workspaces/other-ws/src/main.go", output) + assert.False(t, r.changed) +} + +func TestPathReplacer_Replace_MultipleReplacements(t *testing.T) { + r := &pathReplacer{ + pairs: [][2]string{ + {testContainerOldWS, testContainerNewWS}, + {testLocalOldWS, testLocalNewWS}, + }, + } + + input := "source=/home/user/old-ws,target=/workspaces/old-ws,type=bind" + expected := "source=/home/user/new-ws,target=/workspaces/new-ws,type=bind" + + output := r.replace(input) + + assert.Equal(t, expected, output) + assert.True(t, r.changed) +} + +func TestPathReplacer_Replace_EmptyString(t *testing.T) { + r := &pathReplacer{ + pairs: [][2]string{ + {testContainerOldWS, testContainerNewWS}, + }, + } + + output := r.replace("") + + assert.Equal(t, "", output) + assert.False(t, r.changed) +} + +func TestPathReplacer_Replace_MultipleOccurrences(t *testing.T) { + r := &pathReplacer{ + pairs: [][2]string{ + {testContainerApp, "/workspaces/app-new"}, + }, + } + + input := testContainerApp + "/go.mod " + testContainerApp + "/go.sum" + expected := "/workspaces/app-new/go.mod /workspaces/app-new/go.sum" + + output := r.replace(input) + + assert.Equal(t, expected, output) + assert.True(t, r.changed) +} + +func TestPathReplacer_Replace_PartialMatch(t *testing.T) { + r := &pathReplacer{ + pairs: [][2]string{ + {testContainerApp, "/workspaces/app-new"}, + }, + } + + input := "/workspaces/application/src" + expected := "/workspaces/app-newlication/src" + + output := r.replace(input) + + assert.Equal(t, expected, output) + assert.True(t, r.changed) +} + +func TestPathReplacer_Replace_NoPairs(t *testing.T) { + r := &pathReplacer{ + pairs: nil, + } + + output := r.replace("/workspaces/old-ws/src/main.go") + + assert.Equal(t, "/workspaces/old-ws/src/main.go", output) + assert.False(t, r.changed) +} + +func TestPathReplacer_Replace_WorkspaceMount(t *testing.T) { + r := &pathReplacer{ + pairs: [][2]string{ + {testContainerOldWS, testContainerNewWS}, + {testLocalOldWS, testLocalNewWS}, + }, + } + + input := "type=bind,source=/home/user/old-ws,target=/workspaces/old-ws" + expected := "type=bind,source=/home/user/new-ws,target=/workspaces/new-ws" + + output := r.replace(input) + + assert.Equal(t, expected, output) + assert.True(t, r.changed) +} + +func TestPathReplacer_ReplaceMultipleCalls(t *testing.T) { + r := &pathReplacer{ + pairs: [][2]string{ + {testContainerOld, testContainerNew}, + }, + } + + r.replace("/workspaces/other") + assert.False(t, r.changed) + + r.replace(testContainerOld) + assert.True(t, r.changed) + + r.replace("/workspaces/other") + assert.True(t, r.changed, "changed flag should remain true once set") +} + +func TestPathReplacer_ReplacePairOrder(t *testing.T) { + r := &pathReplacer{ + pairs: [][2]string{ + {testContainerOld, testContainerNew}, + {"/home/old", "/home/new"}, + {"/mnt/old", "/mnt/new"}, + }, + } + + input := testContainerOld + " /home/old /mnt/old" + expected := testContainerNew + " /home/new /mnt/new" + + output := r.replace(input) + + assert.Equal(t, expected, output) + assert.True(t, r.changed) +} + +func TestPathReplacer_ReplaceWithTrailingSlash(t *testing.T) { + tests := []struct { + name string + pairs [][2]string + input string + expected string + }{ + { + name: "no trailing slash in pair or input", + pairs: [][2]string{ + {testContainerOld, testContainerNew}, + }, + input: testContainerOld, + expected: testContainerNew, + }, + { + name: "trailing slash in input only", + pairs: [][2]string{ + {testContainerOld, testContainerNew}, + }, + input: testContainerOld + "/", + expected: testContainerNew + "/", + }, + { + name: "subpath match", + pairs: [][2]string{ + {testContainerOld, testContainerNew}, + }, + input: testContainerOld + "/subdir/file.txt", + expected: testContainerNew + "/subdir/file.txt", + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + r := &pathReplacer{pairs: tt.pairs} + output := r.replace(tt.input) + assert.Equal(t, tt.expected, output) + }) + } +} diff --git a/release-please-config.json b/release-please-config.json deleted file mode 100644 index f6e6473f9..000000000 --- a/release-please-config.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "$schema": "https://raw.githubusercontent.com/googleapis/release-please/main/schemas/config.json", - "packages": { - ".": { - "release-type": "go", - "prerelease-type": "rc", - "prerelease": true, - "versioning": "prerelease", - "bump-minor-pre-major": true, - "component": "devsy", - "changelog-path": "CHANGELOG.md", - "include-component-in-tag": false, - "include-v-in-tag": true - } - } -}