From f8dc241c0ed163805eec44ccdf52a25504810b74 Mon Sep 17 00:00:00 2001 From: LittleCoinCoin Date: Mon, 18 Aug 2025 17:53:33 +0900 Subject: [PATCH 1/4] ci: migrate to semantic-release Major: Replace custom versioning system with semantic-release. This requires using Conventional Commits for all future changes. - Remove custom scripts and workflows (327+ lines eliminated) - Add semantic-release configuration with Node.js dependencies - Update project structure for automated releases - Replace VERSION/VERSION.meta files with pyproject.toml version - Add commitizen for guided commit messages - Update documentation for Conventional Commits workflow - Add CONTRIBUTING.md with development guidelines - Configure GitHub Actions for semantic-release automation Migration benefits: - Fully automated versioning without manual intervention - Industry-standard Conventional Commits workflow - Elimination of complex custom code and potential infinite loops - Better compliance with GitHub best practices - Improved developer experience with guided tooling --- .commitlintrc.json | 26 + .github/workflows/commit_version_tag.yml | 46 - .github/workflows/commitlint.yml | 25 + .github/workflows/release.yml | 86 - .github/workflows/semantic-release.yml | 62 + .github/workflows/tag-cleanup.yml | 50 - .github/workflows/tag-release.yml | 45 - .../workflows/validate-pr-branch-common.yml | 141 + .github/workflows/validate-pr-to-dev.yml | 40 +- .github/workflows/validate-pr-to-main.yml | 86 +- .gitignore | 7 + .releaserc.json | 61 + CONTRIBUTING.md | 241 + LLM_Reports/Architecture_Analysis_Report.md | 164 + .../GitHub_Specific_Solutions_Report.md | 503 + LLM_Reports/Industry_Best_Practices_Report.md | 324 + ...ntegrated_Automated_Versioning_Strategy.md | 842 ++ .../Semantic_Release_Migration_Plan.md | 689 ++ .../Semantic_Release_Migration_Plan_v2.md | 733 ++ LLM_Reports/Workflow_Optimization_Report.md | 555 ++ README.md | 28 +- VERSION | 1 - VERSION.meta | 10 - docs/articles/devs/versioning.md | 297 +- package-lock.json | 8790 +++++++++++++++++ package.json | 23 + pyproject.toml | 5 +- scripts/prepare_version.py | 37 - scripts/tag_cleanup.py | 94 - scripts/version_manager.py | 327 - 30 files changed, 13347 insertions(+), 991 deletions(-) create mode 100644 .commitlintrc.json delete mode 100644 .github/workflows/commit_version_tag.yml create mode 100644 .github/workflows/commitlint.yml delete mode 100644 .github/workflows/release.yml create mode 100644 .github/workflows/semantic-release.yml delete mode 100644 .github/workflows/tag-cleanup.yml delete mode 100644 .github/workflows/tag-release.yml create mode 100644 .github/workflows/validate-pr-branch-common.yml create mode 100644 .releaserc.json create mode 100644 CONTRIBUTING.md create mode 100644 LLM_Reports/Architecture_Analysis_Report.md create mode 100644 LLM_Reports/GitHub_Specific_Solutions_Report.md create mode 100644 LLM_Reports/Industry_Best_Practices_Report.md create mode 100644 LLM_Reports/Integrated_Automated_Versioning_Strategy.md create mode 100644 LLM_Reports/Semantic_Release_Migration_Plan.md create mode 100644 LLM_Reports/Semantic_Release_Migration_Plan_v2.md create mode 100644 LLM_Reports/Workflow_Optimization_Report.md delete mode 100644 VERSION delete mode 100644 VERSION.meta create mode 100644 package-lock.json create mode 100644 package.json delete mode 100755 scripts/prepare_version.py delete mode 100644 scripts/tag_cleanup.py delete mode 100755 scripts/version_manager.py diff --git a/.commitlintrc.json b/.commitlintrc.json new file mode 100644 index 0000000..23f1e7e --- /dev/null +++ b/.commitlintrc.json @@ -0,0 +1,26 @@ +{ + "extends": ["@commitlint/config-conventional"], + "rules": { + "type-enum": [ + 2, + "always", + [ + "build", + "chore", + "ci", + "docs", + "feat", + "fix", + "perf", + "refactor", + "revert", + "style", + "test" + ] + ], + "subject-case": [2, "never", ["start-case", "pascal-case", "upper-case"]], + "subject-empty": [2, "never"], + "subject-full-stop": [2, "never", "."], + "header-max-length": [2, "always", 72] + } +} diff --git a/.github/workflows/commit_version_tag.yml b/.github/workflows/commit_version_tag.yml deleted file mode 100644 index 7425b11..0000000 --- a/.github/workflows/commit_version_tag.yml +++ /dev/null @@ -1,46 +0,0 @@ -name: Commit Version Tag - -on: - push: - branches: - - dev - - main - - feat/* - - fix/* - -jobs: - test-build: - uses: ./.github/workflows/test_build.yml - with: - branch: ${{ github.ref_name }} - permissions: - contents: write - - commit-version-tag: - needs: test-build - runs-on: ubuntu-latest - permissions: - contents: write - - steps: - - uses: actions/checkout@v4 - with: - fetch-depth: 0 - - - name: Download VERSION files - uses: actions/download-artifact@v4 - with: - name: version-files - - - name: Commit updated VERSION files - run: | - git config --local user.email "action@github.com" - git config --local user.name "GitHub Action" - git add VERSION VERSION.meta - git diff --staged --quiet || git commit -m "Update VERSION files in \`${{ github.ref_name }}\` to ${{ needs.test-build.outputs.version }}" - git push - - - name: Create lightweight tag - run: | - git tag -a "${{ needs.test-build.outputs.version }}" -m "Release ${{ needs.test-build.outputs.version }}" - git push origin "${{ needs.test-build.outputs.version }}" \ No newline at end of file diff --git a/.github/workflows/commitlint.yml b/.github/workflows/commitlint.yml new file mode 100644 index 0000000..300aaa6 --- /dev/null +++ b/.github/workflows/commitlint.yml @@ -0,0 +1,25 @@ +name: Commit Lint + +on: + pull_request: + branches: [main, dev] + +jobs: + commitlint: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: "lts/*" + + - name: Install dependencies + run: npm ci + + - name: Validate PR commits with commitlint + run: npx commitlint --from ${{ github.event.pull_request.base.sha }} --to ${{ github.event.pull_request.head.sha }} --verbose diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml deleted file mode 100644 index 4391c67..0000000 --- a/.github/workflows/release.yml +++ /dev/null @@ -1,86 +0,0 @@ -name: Release - -on: - workflow_call: - # This workflow is deprecated since the introduction of the `commit_version_tag.yml` workflow. - # Keeping it for now until the new version has been tested. - # push: - # branches: [ main ] - # pull_request: - # branches: [ main ] - -env: - PYTHON_VERSION: '3.12' - -jobs: - test: - uses: ./.github/workflows/test_build.yml - - release: - if: github.event_name == 'push' && github.ref == 'refs/heads/main' - needs: test - runs-on: ubuntu-latest - permissions: - contents: write - packages: write - - steps: - - uses: actions/checkout@v4 - with: - fetch-depth: 0 - - - name: Set up Python - uses: actions/setup-python@v5 - with: - python-version: ${{ env.PYTHON_VERSION }} - - - name: Get version info - id: version - run: | - VERSION=$(python scripts/version_manager.py --get) - echo "version=$VERSION" >> $GITHUB_OUTPUT - echo "Version: $VERSION" - - - name: Update VERSION file for main branch - run: | - python scripts/version_manager.py --update-for-branch main - - - name: Prepare version for build - run: | - python scripts/prepare_version.py - - - name: Install build dependencies - run: | - python -m pip install --upgrade pip - pip install build twine - - - name: Build package - run: | - python -m build - - - name: Create Release - uses: softprops/action-gh-release@v2 - with: - tag_name: ${{ steps.version.outputs.version }} - name: Release ${{ steps.version.outputs.version }} - body: | - Release ${{ steps.version.outputs.version }} - - ## Changes - - See commit history for detailed changes - - ## Installation - ```bash - pip install hatchling==${{ steps.version.outputs.version }} - ``` - draft: false - prerelease: false - token: ${{ secrets.GITHUB_TOKEN }} - - - name: Commit updated VERSION file - run: | - git config --local user.email "action@github.com" - git config --local user.name "GitHub Action" - git add VERSION - git diff --staged --quiet || git commit -m "Update VERSION file for release ${{ steps.version.outputs.version }}" - git push \ No newline at end of file diff --git a/.github/workflows/semantic-release.yml b/.github/workflows/semantic-release.yml new file mode 100644 index 0000000..b71aed5 --- /dev/null +++ b/.github/workflows/semantic-release.yml @@ -0,0 +1,62 @@ +name: Semantic Release + +on: + push: + branches: + - main + - dev + +permissions: + contents: write + issues: write + pull-requests: write + id-token: write + +jobs: + test: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Setup Python + uses: actions/setup-python@v5 + with: + python-version: '3.12' + + - name: Install Python dependencies + run: | + python -m pip install --upgrade pip + pip install -e . + + - name: Run tests + run: python run_tests.py --regression --feature + + release: + needs: test + runs-on: ubuntu-latest + if: github.event_name == 'push' + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 0 + token: ${{ secrets.GITHUB_TOKEN }} + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: "lts/*" + + - name: Install Node dependencies + run: npm ci + + - name: Verify npm audit + run: npm audit signatures + + - name: Release + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: npx semantic-release diff --git a/.github/workflows/tag-cleanup.yml b/.github/workflows/tag-cleanup.yml deleted file mode 100644 index 50af89d..0000000 --- a/.github/workflows/tag-cleanup.yml +++ /dev/null @@ -1,50 +0,0 @@ -name: Tag Cleanup - -on: - # We will run this workflow only manually to check behaviors for a while. - # Later we will enable it to run on a schedule that is yet to be determined (below weekly is only an example). - #schedule: - # Run weekly on Sundays at 2:00 AM UTC - #- cron: '0 2 * * 0' - workflow_dispatch: - inputs: - dry_run: - description: 'Dry run (show what would be deleted without actually deleting)' - required: false - default: 'true' - type: choice - options: - - 'true' - - 'false' - -env: - PYTHON_VERSION: '3.12' - -jobs: - cleanup-tags: - runs-on: ubuntu-latest - permissions: - contents: write - - steps: - - uses: actions/checkout@v4 - with: - fetch-depth: 0 - - - name: Set up Python - uses: actions/setup-python@v5 - with: - python-version: ${{ env.PYTHON_VERSION }} - - - name: Run tag cleanup - run: | - DRY_RUN="${{ github.event.inputs.dry_run || 'true' }}" - python scripts/tag_cleanup.py "$DRY_RUN" - - - name: Summary - run: | - if [ "${{ github.event.inputs.dry_run || 'true' }}" = "true" ]; then - echo "Tag cleanup completed in dry-run mode. No tags were actually deleted." - else - echo "Tag cleanup completed. Old build and dev tags have been removed." - fi \ No newline at end of file diff --git a/.github/workflows/tag-release.yml b/.github/workflows/tag-release.yml deleted file mode 100644 index e792c35..0000000 --- a/.github/workflows/tag-release.yml +++ /dev/null @@ -1,45 +0,0 @@ -name: Tagged Release - -on: - push: - tags: - - 'v[0-9]+.[0-9]+.[0-9]+' - - 'v[0-9]+.[0-9]+.[0-9]+.dev[0-9]+' - -jobs: - releasing: - runs-on: ubuntu-latest - steps: - - name: Create Pre-Release - if: ${{ contains(github.ref_name, '.dev') }} - uses: softprops/action-gh-release@v2 - with: - tag_name: ${{ github.ref_name }} - name: Pre-Release ${{ github.ref_name }} - body: | - Pre-release ${{ github.ref_name }} - - ## Changes - - See commit history for detailed changes - - ⚠️ **This is a pre-release version** - - draft: false - prerelease: true - token: ${{ secrets.GITHUB_TOKEN }} - - - name: Create Release - if: ${{ !contains(github.ref_name, '.dev') }} - uses: softprops/action-gh-release@v2 - with: - tag_name: ${{ github.ref_name }} - name: Release ${{ github.ref_name }} - body: | - Release ${{ github.ref_name }} - - ## Changes - - See commit history for detailed changes - - draft: false - prerelease: false - token: ${{ secrets.GITHUB_TOKEN }} \ No newline at end of file diff --git a/.github/workflows/validate-pr-branch-common.yml b/.github/workflows/validate-pr-branch-common.yml new file mode 100644 index 0000000..86165bc --- /dev/null +++ b/.github/workflows/validate-pr-branch-common.yml @@ -0,0 +1,141 @@ +name: Reusable PR branch & author validator + +on: + workflow_call: + inputs: + allowed_prefixes: + required: true + type: string + allowed_exact: + required: false + type: string + default: '' + require_org_for: + required: false + type: string + default: '' + allowed_apps: + required: false + type: string + default: '' + org_name: + required: false + type: string + default: 'CrackingShells' + fail_message: + required: false + type: string + default: '' + +jobs: + validate: + runs-on: ubuntu-latest + outputs: + branch_valid: ${{ steps.check.outputs.branch_valid }} + steps: + - name: Generate GitHub App token + id: generate-token + uses: tibdex/github-app-token@v2 + with: + app_id: ${{ secrets.HATCH_WORKFLOW_APP_ID }} + private_key: ${{ secrets.HATCH_WORKFLOW_APP_PRIVATE_KEY }} + + - name: Run branch and author checks + id: check + uses: actions/github-script@v7 + with: + github-token: ${{ steps.generate-token.outputs.token }} + script: | + const branch = process.env.GITHUB_HEAD_REF || '${{ github.head_ref }}'; + const author = '${{ github.event.pull_request.user.login }}'; + const prNumber = ${{ github.event.pull_request.number }}; + const owner = context.repo.owner; + const repo = context.repo.repo; + + const allowedPrefixes = (`${{ inputs.allowed_prefixes }}` || '').split(',').map(s => s.trim()).filter(Boolean); + const allowedExact = (`${{ inputs.allowed_exact }}` || '').split(',').map(s => s.trim()).filter(Boolean); + const requireOrgFor = (`${{ inputs.require_org_for }}` || '').split(',').map(s => s.trim()).filter(Boolean); + const allowedApps = (`${{ inputs.allowed_apps }}` || '').split(',').map(s => s.trim()).filter(Boolean); + const failMessage = `${{ inputs.fail_message }}` || 'Branch not allowed to open PR to this target.'; + + function matchesAllowed() { + for (const p of allowedPrefixes) { + if (p.endsWith('/')) { + if (branch.startsWith(p)) return true; + } else { + if (branch === p) return true; + } + } + if (allowedExact.includes(branch)) return true; + return false; + } + + async function isOrgMember() { + const orgName = `${{ inputs.org_name }}` || 'CrackingShells'; + try { + const res = await github.rest.orgs.checkMembershipForUser({ org: orgName, username: author }); + return res.status === 204; + } catch (e) { + return false; + } + } + + // Allowed by prefix/exact test first + if (!matchesAllowed()) { + const message = `${failMessage}\nYour branch: ${branch}.`; + await github.rest.issues.createComment({ + issue_number: prNumber, + owner, + repo, + body: message + }); + core.setFailed('Invalid branch for PR.'); + core.setOutput('branch_valid', 'invalid'); + return; + } + + // If author is an allowed app, allow + if (allowedApps.includes(author)) { + console.log(`Author ${author} is in allowed apps list`); + core.setOutput('branch_valid', 'valid'); + return; + } + + // If this branch requires org membership, check + if (requireOrgFor.includes(branch) || requireOrgFor.some(b => b === branch)) { + if (!await isOrgMember()) { + const message = `⚠️ Only members of the ${`${{ inputs.org_name }}`} organization can open PRs from '${branch}' to this target.`; + await github.rest.issues.createComment({ + issue_number: prNumber, + owner, + repo, + body: message + }); + core.setFailed('PR author is not a member of the organization.'); + core.setOutput('branch_valid', 'invalid'); + return; + } + core.setOutput('branch_valid', 'valid'); + return; + } + + // Special case: version-bump behavior - allow if org member OR allowed app + if (branch === 'version-bump') { + if (await isOrgMember()) { core.setOutput('branch_valid', 'valid'); return; } + const isAllowedApp = allowedApps.includes(author); + if (isAllowedApp) { core.setOutput('branch_valid', 'valid'); return; } + const message = `❌ Only organization members or registered GitHub Apps (${allowedApps.join(', ')}) can open PRs from 'version-bump' to this target.\nYour author: ${author}`; + await github.rest.issues.createComment({ + issue_number: prNumber, + owner, + repo, + body: message + }); + core.setFailed('PR author is not allowed for version-bump branch.'); + core.setOutput('branch_valid', 'invalid'); + return; + } + + // Otherwise allowed + core.setOutput('branch_valid', 'valid'); + return; diff --git a/.github/workflows/validate-pr-to-dev.yml b/.github/workflows/validate-pr-to-dev.yml index 5ec7abc..1ee00e0 100644 --- a/.github/workflows/validate-pr-to-dev.yml +++ b/.github/workflows/validate-pr-to-dev.yml @@ -7,35 +7,11 @@ on: jobs: validate-branch: - runs-on: ubuntu-latest - steps: - - name: Check PR source branch name - id: check-branch - run: | - BRANCH_NAME="${{ github.head_ref }}" - echo "Checking PR branch: $BRANCH_NAME" - if [[ "$BRANCH_NAME" =~ ^(docs/|cicd/|feat/|fix/) ]]; then - echo "---" - echo "✅ Branch $BRANCH_NAME is allowed for PR to dev." - echo "branch_valid=true" >> $GITHUB_OUTPUT - else - echo "---" - echo "❌ Error: Only 'docs/', 'cicd/', 'feat/' and 'fix/' branches can open PRs to 'dev'." - echo "branch_valid=false" >> $GITHUB_OUTPUT - fi - - - name: Comment on PR if branch invalid - if: ${{ steps.check-branch.outputs.branch_valid == 'false' }} - uses: actions/github-script@v7 - with: - script: | - const pr_number = process.env.GITHUB_REF.split('/')[2]; - const branch_name = process.env.GITHUB_HEAD_REF; - const message = `❌ To automate versioning, only branches starting with 'docs/', 'cicd/', 'feat/' or 'fix/' are allowed to open PRs to 'dev'.\nYour branch: ${branch_name}. Please rename your branch.`; - await github.rest.issues.createComment({ - issue_number: pr_number, - owner: context.repo.owner, - repo: context.repo.repo, - body: message - }); - core.setFailed('Invalid branch for PR to dev.'); + uses: ./.github/workflows/validate-pr-branch-common.yml + with: + allowed_prefixes: 'docs/,cicd/,feat/,fix/' + allowed_exact: '' + require_org_for: '' + allowed_apps: '' + org_name: 'CrackingShells' + fail_message: "❌ To automate versioning, only branches starting with 'docs/', 'cicd/', 'feat/' or 'fix/' are allowed to open PRs to 'dev'." diff --git a/.github/workflows/validate-pr-to-main.yml b/.github/workflows/validate-pr-to-main.yml index 184528b..6800fc8 100644 --- a/.github/workflows/validate-pr-to-main.yml +++ b/.github/workflows/validate-pr-to-main.yml @@ -7,81 +7,11 @@ on: jobs: validate-branch: - runs-on: ubuntu-latest - steps: - - name: Validate PR source branch - id: check-branch - run: | - BRANCH_NAME="${{ github.head_ref }}" - AUTHOR="${{ github.event.pull_request.user.login }}" - echo "Checking PR branch: $BRANCH_NAME" - echo "PR author: $AUTHOR" - if [[ "$BRANCH_NAME" =~ ^fix/ ]]; then - echo "---" - echo "✅ Branch $BRANCH_NAME is allowed for PR to main (fix branch)." - echo "branch_valid=fix" >> $GITHUB_OUTPUT - elif [[ "$BRANCH_NAME" == "dev" ]]; then - echo "---" - echo "🔍 Branch $BRANCH_NAME is a dev branch." - echo "branch_valid=dev" >> $GITHUB_OUTPUT - else - echo "---" - echo "❌ Error: Only 'fix/' or 'dev' branches can open PRs to 'main'." - echo "branch_valid=invalid" >> $GITHUB_OUTPUT - fi - - - name: Comment and fail if branch invalid - if: ${{ steps.check-branch.outputs.branch_valid == 'invalid' }} - uses: actions/github-script@v7 - with: - script: | - const pr_number = ${{ github.event.pull_request.number }}; - const branch_name = '${{ github.head_ref }}'; - const message = `❌ To automate versioning, only branches starting with 'fix/' or 'dev' are allowed to open PRs to 'main'.\nYour branch: ${branch_name}. Please rename your branch.\nMoreover, if you intended to open a PR to 'main', please ensure **you are a member of the CrackingShells organization.**`; - await github.rest.issues.createComment({ - issue_number: pr_number, - owner: context.repo.owner, - repo: context.repo.repo, - body: message - }); - core.setFailed('Invalid branch for PR to main.'); - - - name: Generate GitHub App token for workflow - id: generate-workflow-token - uses: tibdex/github-app-token@v2 - with: - app_id: ${{ secrets.HATCH_WORKFLOW_APP_ID }} - private_key: ${{ secrets.HATCH_WORKFLOW_APP_PRIVATE_KEY }} - - - name: Check org membership for dev branch and fail if not member - if: ${{ steps.check-branch.outputs.branch_valid == 'dev' }} - uses: actions/github-script@v7 - with: - github-token: ${{ steps.generate-workflow-token.outputs.token }} - script: | - const org = 'CrackingShells'; - const author = process.env.AUTHOR || '${{ github.event.pull_request.user.login }}'; - const pr_number = ${{ github.event.pull_request.number }}; - const branch_name = '${{ github.head_ref }}'; - try { - const res = await github.rest.orgs.checkMembershipForUser({ org, username: author }); - if (res.status !== 204) { - const message = `⚠️ Only members of the CrackingShells organization can open PRs from 'dev' to 'main'.\nPlease, rebase your branch on \`dev\` and open a PR to \`dev\` instead.`; - await github.rest.issues.createComment({ - issue_number: pr_number, - owner: context.repo.owner, - repo: context.repo.repo, - body: message - }); - core.setFailed('PR author is not a member of the organization.'); - } - } catch (e) { - const message = `❌ Unexpected error happened while checking organization membership of ${author}: ${e.message}`; - await github.rest.issues.createComment({ - issue_number: pr_number, - owner: context.repo.owner, - repo: context.repo.repo, - body: message - }); - core.setFailed('PR author is not a member of the organization.'); - } + uses: ./.github/workflows/validate-pr-branch-common.yml + with: + allowed_prefixes: 'fix/,dev,version-bump' + allowed_exact: '' + require_org_for: 'dev' + allowed_apps: 'github-actions[bot],hatch-workflow-app[bot]' + org_name: 'CrackingShells' + fail_message: "❌ To automate versioning, only 'fix/*', 'dev' or 'version-bump' branches may open PRs to 'main'." diff --git a/.gitignore b/.gitignore index 2af5d96..a58d618 100644 --- a/.gitignore +++ b/.gitignore @@ -46,7 +46,14 @@ coverage.xml *.ipynb_checkpoints *.pyc +# Node.js dependencies for semantic-release +node_modules/ +npm-debug.log* +yarn-debug.log* +yarn-error.log* +# Semantic-release +.semantic-release/ # Docker *.dockerfile diff --git a/.releaserc.json b/.releaserc.json new file mode 100644 index 0000000..5749ab5 --- /dev/null +++ b/.releaserc.json @@ -0,0 +1,61 @@ +{ + "repositoryUrl": "https://github.com/CrackingShells/Hatchling", + "branches": [ + "main", + { + "name": "dev", + "prerelease": "dev" + } + ], + "plugins": [ + [ + "@semantic-release/commit-analyzer", + { + "preset": "conventionalcommits", + "releaseRules": [ + {"type": "docs", "scope": "README", "release": "patch"}, + {"type": "refactor", "release": "patch"}, + {"type": "style", "release": "patch"}, + {"type": "test", "release": false}, + {"type": "chore", "release": false} + ] + } + ], + [ + "@semantic-release/release-notes-generator", + { + "preset": "conventionalcommits", + "presetConfig": { + "types": [ + {"type": "feat", "section": "Features"}, + {"type": "fix", "section": "Bug Fixes"}, + {"type": "docs", "section": "Documentation"}, + {"type": "refactor", "section": "Code Refactoring"}, + {"type": "perf", "section": "Performance Improvements"} + ] + } + } + ], + [ + "@semantic-release/changelog", + { + "changelogFile": "CHANGELOG.md" + } + ], + [ + "@semantic-release/git", + { + "assets": ["CHANGELOG.md", "pyproject.toml"], + "message": "chore(release): ${nextRelease.version} [skip ci]\n\n${nextRelease.notes}" + } + ], + [ + "@semantic-release/github", + { + "successComment": false, + "failComment": false, + "releasedLabels": false + } + ] + ] +} diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..b72b0ce --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,241 @@ +# Contributing to Hatchling + +Thank you for your interest in contributing to Hatchling! This guide will help you get started with our development workflow and contribution standards. + +## Commit Message Format + +We use [Conventional Commits](https://www.conventionalcommits.org/) for automated versioning and changelog generation. + +### Format + +``` +[optional scope]: + +[optional body] + +[optional footer(s)] +``` + +### Types + +- **feat**: New features (triggers minor version bump) +- **fix**: Bug fixes (triggers patch version bump) +- **docs**: Documentation changes +- **refactor**: Code refactoring without functional changes +- **test**: Adding or updating tests +- **chore**: Maintenance tasks, dependency updates +- **ci**: Changes to CI/CD configuration +- **perf**: Performance improvements +- **style**: Code style changes (formatting, etc.) + +### Examples + +```bash +# Good commit messages +feat: add support for Claude 3.5 Sonnet model +fix: resolve memory leak in streaming responses +docs: update API documentation for new providers +refactor: simplify provider registry initialization +test: add integration tests for OpenAI provider +chore: update dependencies to latest versions + +# Breaking changes (use sparingly until v1.0.0) +feat!: change configuration file format +fix!: remove deprecated API methods + +# With scope +feat(providers): add Anthropic Claude support +fix(mcp): resolve tool execution timeout +docs(api): update provider configuration guide +``` + +### Using Commitizen + +For guided commit messages, use commitizen: + +```bash +# Install dependencies first +npm install + +# Use commitizen for guided commits +npm run commit +# or +npx cz +``` + +This will prompt you through creating a properly formatted commit message. + +## Development Workflow + +### 1. Fork and Clone + +```bash +git clone https://github.com/YOUR_USERNAME/Hatchling.git +cd Hatchling +``` + +### 2. Set Up Development Environment + +```bash +# Install Python dependencies +pip install -e . + +# Install Node.js dependencies for semantic-release +npm install +``` + +### 3. Create Feature Branch + +```bash +git checkout -b feat/your-feature-name +# or +git checkout -b fix/your-bug-fix +``` + +### 4. Make Changes + +- Write code following existing patterns +- Add tests for new functionality +- Update documentation as needed +- Follow PEP 8 style guidelines + +### 5. Test Your Changes + +```bash +# Run the test suite +python run_tests.py --regression --feature + +# Run specific test categories +python run_tests.py --integration # Requires API keys/services +python run_tests.py --file test_specific_file.py +``` + +### 6. Commit Changes + +```bash +# Use commitizen for guided commits +npm run commit + +# Or commit manually with conventional format +git commit -m "feat: add your feature description" +``` + +### 7. Push and Create Pull Request + +```bash +git push origin feat/your-feature-name +``` + +Then create a pull request on GitHub. + +## Pull Request Guidelines + +### Title Format + +Use conventional commit format for PR titles: + +- `feat: add new LLM provider support` +- `fix: resolve streaming timeout issue` +- `docs: update installation guide` + +### Description + +Include in your PR description: + +- **What**: Brief description of changes +- **Why**: Reason for the changes +- **How**: Implementation approach (if complex) +- **Testing**: How you tested the changes +- **Breaking Changes**: Any breaking changes (if applicable) + +### Checklist + +- [ ] Code follows existing style and patterns +- [ ] Tests added for new functionality +- [ ] Documentation updated (if needed) +- [ ] Commit messages follow conventional format +- [ ] All tests pass +- [ ] No breaking changes (unless intentional and documented) + +## Code Style + +### Python + +- Follow PEP 8 style guidelines +- Use type hints where appropriate +- Write docstrings for public functions and classes +- Keep functions focused and small +- Use meaningful variable and function names + +### Documentation + +- Update relevant documentation for changes +- Use clear, concise language +- Include code examples where helpful +- Keep README.md up to date + +## Testing + +### Test Categories + +- **Regression**: Ensure existing functionality works +- **Feature**: Test new functionality +- **Integration**: Test with external services (requires setup) + +### Running Tests + +```bash +# All tests +python run_tests.py --all + +# Specific categories +python run_tests.py --regression +python run_tests.py --feature +python run_tests.py --integration + +# Skip slow tests +python run_tests.py --skip slow + +# Only run specific tags +python run_tests.py --only feature,regression +``` + +### Writing Tests + +- Add tests for new features +- Test edge cases and error conditions +- Use descriptive test names +- Follow existing test patterns + +## Release Process + +Releases are fully automated using semantic-release: + +1. **Commits are analyzed** for conventional commit format +2. **Version is calculated** based on commit types +3. **Changelog is generated** from commit messages +4. **GitHub release is created** with release notes +5. **Version is updated** in pyproject.toml + +### Version Impact + +- `feat:` commits → Minor version (0.4.0 → 0.5.0) +- `fix:` commits → Patch version (0.4.0 → 0.4.1) +- `feat!:` or `BREAKING CHANGE:` → Major version (0.4.0 → 1.0.0) +- Other types → No release + +## Getting Help + +- **Issues**: Report bugs or request features via GitHub Issues +- **Discussions**: Ask questions in GitHub Discussions +- **Documentation**: Check docs/articles/ for detailed guides +- **Code**: Look at existing code for patterns and examples + +## Code of Conduct + +- Be respectful and inclusive +- Focus on constructive feedback +- Help others learn and grow +- Follow GitHub's community guidelines + +Thank you for contributing to Hatchling! 🚀 diff --git a/LLM_Reports/Architecture_Analysis_Report.md b/LLM_Reports/Architecture_Analysis_Report.md new file mode 100644 index 0000000..c071be8 --- /dev/null +++ b/LLM_Reports/Architecture_Analysis_Report.md @@ -0,0 +1,164 @@ +# Architecture Analysis Report: Hatchling Automated Versioning System + +## Executive Summary + +The Hatchling repository implements a sophisticated automated versioning system that combines Python helper scripts with GitHub Actions workflows to manage semantic versioning across multiple branches. The system uses a dual-file approach (VERSION and VERSION.meta) and attempts to work around branch protection rules through a complex PR-based workflow. + +**Current Status**: The system is experiencing critical issues with infinite workflow loops and branch protection conflicts, requiring immediate architectural review. + +## System Components Overview + +### 1. Helper Scripts (`/scripts/`) + +#### `version_manager.py` (327 lines) +**Purpose**: Core versioning logic with dual-file system management +**Key Features**: +- Manages VERSION (simple format) and VERSION.meta (structured format) +- Implements branch-specific versioning rules +- Supports semantic versioning with dev/build suffixes +- Handles version increments based on branch type + +**Versioning Rules**: +- `main`: Clean releases (no dev/build suffixes) +- `dev`: Development prereleases with dev numbers +- `feat/*`: Minor version increment + dev/build numbers +- `fix/*`: Patch version increment + dev/build numbers + +**Strengths**: +- Comprehensive versioning logic +- Dual-file system preserves metadata while maintaining setuptools compatibility +- Branch-aware version management +- Well-structured Python code + +**Weaknesses**: +- Complex branching logic that may be difficult to maintain +- No validation of version consistency across branches +- Limited error handling for edge cases + +#### `prepare_version.py` (37 lines) +**Purpose**: Build-time VERSION file preparation for setuptools +**Function**: Converts VERSION.meta to simple VERSION format +**Assessment**: Simple, focused utility with clear purpose + +#### `tag_cleanup.py` (94 lines) +**Purpose**: Automated cleanup of old development and build tags +**Features**: +- Removes build tags older than 7 days +- Removes dev tags older than 30 days +- Dry-run capability +**Assessment**: Well-designed maintenance utility + +### 2. GitHub Actions Workflows (`/.github/workflows/`) + +#### Core Versioning Workflows + +**`test_build.yml`** (Reusable workflow) +- Updates VERSION files based on branch +- Builds and tests package +- Uploads VERSION artifacts +- **Status**: Functional, well-designed + +**`commit_version_tag.yml`** (84 lines) +- **Triggers**: Push to dev, main, feat/*, fix/* +- **Function**: Creates version-bump PR to main +- **Critical Issues**: + - Uses GitHub App token but still creates PR workflow + - Potential for infinite loops with other workflows + - Complex dependency chain + +**`auto_merge_version_bump.yml`** (110 lines) +- **Triggers**: Completion of "Validate PR Branches to Main" workflow +- **Function**: Auto-merges version-bump PRs +- **Critical Issues**: + - Workflow chaining creates complex dependencies + - Risk of infinite loops + - Multiple points of failure + +**`validate-pr-to-main.yml`** (18 lines) +- **Function**: Validates PR branch names and authors +- **Issues**: Triggers validation workflow that feeds into auto-merge + +**`validate-pr-branch-common.yml`** (142 lines) +- **Function**: Reusable PR validation logic +- **Features**: Organization membership checks, app authentication +- **Assessment**: Well-designed but complex + +**`create_tag_on_main.yml`** (35 lines) +- **Triggers**: Push to main with version update commit message +- **Function**: Creates git tags for releases +- **Assessment**: Simple and focused + +## Current Architecture Flow + +``` +Push to dev/feat/fix → commit_version_tag.yml → test_build.yml → Create PR to main + ↓ + validate-pr-to-main.yml + ↓ + validate-pr-branch-common.yml + ↓ + auto_merge_version_bump.yml + ↓ + Merge to main → create_tag_on_main.yml +``` + +## Architectural Strengths + +1. **Comprehensive Versioning Logic**: The version_manager.py provides sophisticated branch-aware versioning +2. **Dual-File System**: Maintains both human-readable and setuptools-compatible formats +3. **Automated Testing**: Integration with build/test workflows +4. **Tag Management**: Automated cleanup of old tags +5. **Security Considerations**: Uses GitHub App tokens for authentication +6. **Branch Protection Awareness**: Attempts to work within GitHub's protection rules + +## Critical Architectural Weaknesses + +### 1. Infinite Loop Risk +- **Issue**: Workflows trigger each other in a chain that could become circular +- **Risk Level**: HIGH +- **Impact**: Repository becomes unusable, CI/CD system fails + +### 2. Complex Workflow Dependencies +- **Issue**: 4+ workflows must execute in sequence for a single version bump +- **Risk Level**: MEDIUM +- **Impact**: High failure rate, difficult debugging + +### 3. Branch Protection Workaround Complexity +- **Issue**: Creating PRs to bypass protection adds significant complexity +- **Risk Level**: MEDIUM +- **Impact**: Maintenance burden, potential security gaps + +### 4. Lack of Atomic Operations +- **Issue**: Version updates span multiple commits and PRs +- **Risk Level**: MEDIUM +- **Impact**: Inconsistent state during failures + +### 5. GitHub App Configuration Dependency +- **Issue**: System relies on external GitHub App configuration +- **Risk Level**: LOW +- **Impact**: Additional setup complexity, potential access issues + +## Recommendations + +### Immediate Actions (Critical) +1. **Disable auto_merge_version_bump.yml** to prevent infinite loops +2. **Review and simplify workflow triggers** to break circular dependencies +3. **Implement workflow run conditions** to prevent cascading executions + +### Short-term Improvements +1. **Consolidate workflows** into fewer, more focused actions +2. **Implement proper error handling** and rollback mechanisms +3. **Add workflow state validation** to prevent inconsistent executions + +### Long-term Architectural Changes +1. **Consider tag-based triggering** instead of branch-based workflows +2. **Evaluate GitHub Apps vs. service account approaches** +3. **Implement atomic version update operations** +4. **Design fail-safe mechanisms** for workflow failures + +## Conclusion + +The current architecture demonstrates sophisticated understanding of versioning requirements but suffers from over-engineering and circular dependency issues. The system requires immediate stabilization followed by systematic simplification to achieve reliable automated versioning while maintaining branch protection. + +**Overall Grade**: C- (Functional concept with critical implementation flaws) +**Priority**: URGENT - System stability at risk diff --git a/LLM_Reports/GitHub_Specific_Solutions_Report.md b/LLM_Reports/GitHub_Specific_Solutions_Report.md new file mode 100644 index 0000000..7558903 --- /dev/null +++ b/LLM_Reports/GitHub_Specific_Solutions_Report.md @@ -0,0 +1,503 @@ +# GitHub-Specific Solutions Report: Automated Workflows with Branch Protection + +## Executive Summary + +This report provides comprehensive guidance on implementing automated versioning workflows while maintaining GitHub branch protection rules. It covers GitHub Apps, service accounts, organization-level configurations, and specific GitHub features that enable secure automation. + +## GitHub Branch Protection Overview + +### Core Protection Features + +- **Pull Request Requirements**: Enforce code review before merging +- **Status Check Requirements**: Require CI/CD checks to pass +- **Conversation Resolution**: Ensure all comments are addressed +- **Signed Commits**: Require cryptographic verification +- **Linear History**: Prevent merge commits +- **Merge Queue**: Automated merge management +- **Deployment Requirements**: Require successful deployments +- **Branch Locking**: Make branches read-only +- **Push Restrictions**: Limit who can push directly + +### Bypass Mechanisms + +1. **Administrator Override**: Repository admins can bypass by default +2. **Custom Roles**: Organization-level roles with bypass permissions +3. **GitHub Apps**: Applications added to bypass list +4. **Service Accounts**: Dedicated automation accounts + +## GitHub Apps: The Preferred Solution + +### Why GitHub Apps Are Recommended + +**Security Benefits**: + +- Fine-grained permissions (repository-specific) +- No personal access token exposure +- Automatic token rotation +- Audit trail for all actions +- Organization-level management + +**Operational Benefits**: + +- Can be added to branch protection bypass lists +- Works across multiple repositories +- Centralized credential management +- No dependency on individual user accounts + +### GitHub App Setup Process + +#### Step 1: Create GitHub App + +1. **Navigate to GitHub Settings**: + - Organization: `Settings` → `Developer settings` → `GitHub Apps` + - Personal: `Settings` → `Developer settings` → `GitHub Apps` + +2. **Basic Information**: + + ``` + App Name: [Organization]-Versioning-Bot + Homepage URL: https://github.com/[org]/[repo] + Description: Automated versioning and release management + ``` + +3. **Webhook Configuration**: + + ``` + Webhook URL: [Optional - leave blank for simple automation] + Webhook Secret: [Optional] + SSL Verification: Enabled + ``` + +#### Step 2: Configure Permissions + +**Repository Permissions**: + +``` +Contents: Read & Write (required for commits/tags) +Metadata: Read (required for basic repository access) +Pull Requests: Write (if using PR-based workflow) +Actions: Read (if triggering workflows) +Checks: Write (if updating status checks) +``` + +**Organization Permissions**: + +``` +Members: Read (if checking organization membership) +``` + +**Account Permissions**: + +``` +Email addresses: Read (if needed for commit attribution) +``` + +#### Step 3: Generate Private Key + +1. Scroll to "Private keys" section +2. Click "Generate a private key" +3. Download and securely store the `.pem` file +4. Note the App ID from the app settings + +#### Step 4: Install App + +1. Go to "Install App" tab +2. Select target organization/repositories +3. Choose "All repositories" or "Selected repositories" +4. Complete installation + +### GitHub App Authentication in Workflows + +#### Using tibdex/github-app-token Action + +```yaml +name: Automated Versioning +on: + push: + branches: [main, dev] + +jobs: + version-and-release: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Generate GitHub App Token + id: generate-token + uses: tibdex/github-app-token@v2 + with: + app_id: ${{ secrets.APP_ID }} + private_key: ${{ secrets.APP_PRIVATE_KEY }} + + - name: Configure Git + run: | + git config --local user.email "action@github.com" + git config --local user.name "Versioning Bot" + + - name: Update Version and Commit + run: | + # Your versioning logic here + python scripts/version_manager.py --update-for-branch ${{ github.ref_name }} + git add VERSION VERSION.meta + git commit -m "chore: update version files [skip ci]" + git push + env: + GITHUB_TOKEN: ${{ steps.generate-token.outputs.token }} +``` + +#### Storing Secrets + +1. **Repository Secrets**: + - `Settings` → `Secrets and variables` → `Actions` + - Add `APP_ID` (GitHub App ID) + - Add `APP_PRIVATE_KEY` (contents of .pem file) + +2. **Organization Secrets** (for multiple repositories): + - Organization `Settings` → `Secrets and variables` → `Actions` + - Set repository access permissions + +### Adding GitHub App to Branch Protection Bypass + +#### Repository Level + +1. Navigate to repository `Settings` → `Branches` +2. Edit existing branch protection rule or create new one +3. Scroll to "Restrict pushes that create files" +4. In "Bypass restrictions" section: + - Check "Apps" checkbox + - Select your GitHub App from dropdown +5. Save changes + +#### Organization Level (Enterprise) + +For GitHub Enterprise Cloud organizations: + +1. Organization `Settings` → `Repository defaults` +2. Configure default branch protection rules +3. Add GitHub App to bypass list +4. Apply to new repositories automatically + +## Alternative Authentication Methods + +### 1. Fine-Grained Personal Access Tokens (Beta) + +**Setup**: + +``` +Token Name: Versioning Automation +Expiration: 1 year (maximum) +Resource Owner: [Organization] +Repository Access: Selected repositories +Permissions: + - Contents: Write + - Metadata: Read + - Pull Requests: Write (if needed) +``` + +**Usage**: + +```yaml +- uses: actions/checkout@v4 + with: + token: ${{ secrets.FINE_GRAINED_PAT }} +``` + +**Limitations**: + +- Still in beta +- Requires manual token rotation +- Tied to user account +- Limited organization support + +### 2. Deploy Keys (Read-Only Alternative) + +**Use Case**: For read-only operations or when combined with other auth methods + +**Setup**: + +1. Generate SSH key pair: `ssh-keygen -t ed25519 -C "deploy-key"` +2. Add public key to repository `Settings` → `Deploy keys` +3. Store private key as repository secret + +**Limitations**: + +- Read-only by default +- Repository-specific +- Cannot bypass branch protection + +### 3. Service Account with PAT (Legacy) + +**Setup**: + +1. Create dedicated GitHub user account +2. Add to organization with appropriate permissions +3. Generate classic PAT with required scopes +4. Add to branch protection bypass list + +**Disadvantages**: + +- Requires paid seat in organization +- Manual token rotation +- Security risk if token is compromised +- Tied to user account lifecycle + +## Branch Protection Configuration Best Practices + +### Recommended Settings for Automated Versioning + +```yaml +# Example branch protection configuration +Branch Protection Rule: main +Settings: + ✅ Require pull request reviews: false (for direct automation) + ✅ Require status checks: true + - Required checks: ["test", "build", "lint"] + - Require up-to-date branches: true + ❌ Require conversation resolution: false + ✅ Require signed commits: true (recommended) + ❌ Require linear history: false (allows merge commits) + ❌ Require merge queue: false (unless high-traffic) + ❌ Lock branch: false + ❌ Do not allow bypassing: false (allow bypass for automation) + ✅ Restrict pushes: true + - Bypass restrictions: [Your GitHub App] + ❌ Allow force pushes: false + ❌ Allow deletions: false +``` + +### Development Branch Configuration + +```yaml +Branch Protection Rule: dev +Settings: + ❌ Require pull request reviews: false + ✅ Require status checks: true + - Required checks: ["test", "build"] + - Require up-to-date branches: false + ❌ Require conversation resolution: false + ❌ Require signed commits: false + ❌ Require linear history: false + ❌ Lock branch: false + ❌ Do not allow bypassing: false + ✅ Restrict pushes: true + - Bypass restrictions: [Your GitHub App, Developers Team] + ❌ Allow force pushes: false + ❌ Allow deletions: false +``` + +## Advanced GitHub Features + +### 1. Repository Rulesets (New Alternative) + +**Benefits over Branch Protection**: + +- More flexible targeting +- Better inheritance model +- Improved API support +- Organization-level management + +**Configuration**: + +```yaml +# .github/rulesets/main-protection.yml +name: Main Branch Protection +target: branch +enforcement: active +conditions: + ref_name: + include: ["refs/heads/main"] +rules: + - type: required_status_checks + parameters: + required_status_checks: + - context: "test" + - context: "build" + - type: restrict_pushes + parameters: + restrict_pushes: true +bypass_actors: + - actor_id: [GitHub App ID] + actor_type: Integration + bypass_mode: always +``` + +### 2. Merge Queues + +**Use Case**: High-traffic repositories with frequent merges + +**Benefits**: + +- Automatic conflict resolution +- Parallel testing +- Reduced developer wait time +- Maintains branch protection + +**Configuration**: + +```yaml +# In branch protection settings +Require merge queue: true +Merge method: merge (or squash/rebase) +Build concurrency: 5 +Merge timeout: 60 minutes +``` + +### 3. Required Deployments + +**Use Case**: Ensure staging deployment before production merge + +**Configuration**: + +```yaml +Required deployments before merging: + - staging + - integration-tests +``` + +## Security Considerations + +### 1. Principle of Least Privilege + +**GitHub App Permissions**: + +- Only grant minimum required permissions +- Use repository-specific installations when possible +- Regular permission audits + +**Branch Protection**: + +- Limit bypass actors to essential automation only +- Use separate apps for different functions +- Monitor bypass usage + +### 2. Audit and Monitoring + +**GitHub Audit Log**: + +- Monitor app token usage +- Track bypass events +- Review permission changes + +**Workflow Monitoring**: + +```yaml +- name: Audit Workflow Run + run: | + echo "Workflow: ${{ github.workflow }}" + echo "Actor: ${{ github.actor }}" + echo "Event: ${{ github.event_name }}" + echo "Ref: ${{ github.ref }}" +``` + +### 3. Secret Management + +**Best Practices**: + +- Use GitHub App tokens over PATs +- Rotate secrets regularly +- Use organization-level secrets for shared resources +- Implement secret scanning + +**Secret Rotation**: + +```yaml +# Automated secret rotation workflow +name: Rotate GitHub App Key +on: + schedule: + - cron: '0 0 1 */3 *' # Quarterly +jobs: + rotate: + runs-on: ubuntu-latest + steps: + - name: Generate New Key + # Implementation depends on your key management system +``` + +## Troubleshooting Common Issues + +### 1. "GH006: Protected branch update failed" + +**Cause**: GitHub App not in bypass list or insufficient permissions + +**Solution**: + +1. Verify app is added to branch protection bypass +2. Check app has "Contents: Write" permission +3. Ensure app is installed on repository + +### 2. "Resource not accessible by integration" + +**Cause**: Missing permissions or incorrect token scope + +**Solution**: + +1. Review GitHub App permissions +2. Verify token generation in workflow +3. Check repository installation + +### 3. Workflow Infinite Loops + +**Cause**: Workflow triggering itself + +**Solution**: + +```yaml +# Use [skip ci] in commit messages +git commit -m "chore: update version [skip ci]" + +# Or use conditional triggers +on: + push: + branches: [main] + paths-ignore: + - 'VERSION' + - 'VERSION.meta' +``` + +## Recommendations for Hatchling + +### Immediate Implementation + +1. **Create GitHub App**: + - Name: "Hatchling-Versioning-Bot" + - Permissions: Contents (Write), Metadata (Read) + - Install on Hatchling repository + +2. **Update Branch Protection**: + - Add GitHub App to bypass list for main branch + - Maintain status check requirements + - Remove complex workflow chains + +3. **Simplify Workflows**: + - Use direct commits instead of PR-based flow + - Implement proper [skip ci] usage + - Add fail-safe mechanisms + +### Long-term Strategy + +1. **Organization-wide Deployment**: + - Install app across all repositories + - Standardize branch protection rules + - Implement centralized secret management + +2. **Advanced Features**: + - Evaluate repository rulesets + - Consider merge queues for high-traffic repos + - Implement comprehensive audit logging + +## Conclusion + +GitHub Apps provide the most secure and scalable solution for automated versioning in protected repositories. The combination of fine-grained permissions, bypass capabilities, and centralized management makes them superior to alternative authentication methods. + +**Key Success Factors**: + +1. Proper GitHub App configuration with minimal permissions +2. Correct branch protection bypass setup +3. Simplified workflow architecture +4. Comprehensive monitoring and auditing + +**Grade**: GitHub's native solutions are mature and well-supported (A) +**Recommendation**: Implement GitHub App-based authentication immediately diff --git a/LLM_Reports/Industry_Best_Practices_Report.md b/LLM_Reports/Industry_Best_Practices_Report.md new file mode 100644 index 0000000..c88bb70 --- /dev/null +++ b/LLM_Reports/Industry_Best_Practices_Report.md @@ -0,0 +1,324 @@ +# Industry Best Practices Report: Automated Versioning in Protected Repositories + +## Executive Summary + +This report analyzes mainstream CI/CD approaches for automated versioning in protected repositories, examining solutions from major projects and organizations. The research reveals several established patterns and emerging best practices that address the fundamental tension between automation and security in modern software development. + +## Key Findings + +1. **Semantic Release** is the industry standard for automated versioning +2. **GitHub Apps** are the preferred solution for bypassing branch protection +3. **Tag-based workflows** are increasingly favored over branch-based approaches +4. **Atomic operations** are critical for maintaining repository consistency +5. **Fail-safe mechanisms** are essential for production environments + +## Industry Standard Solutions + +### 1. Semantic Release Ecosystem + +**Overview**: The most widely adopted automated versioning solution in the JavaScript/Node.js ecosystem, with growing adoption in other languages. + +**Key Features**: + +- Conventional commit parsing +- Automatic version calculation +- Changelog generation +- Multi-platform publishing +- Plugin architecture + +**Branch Protection Strategy**: + +- Uses GitHub Apps for authentication +- Bypasses branch protection through app permissions +- Supports both direct commits and PR-based workflows + +**Major Adopters**: + +- Angular (Google) +- React (Meta) +- Vue.js +- Webpack +- Babel + +**Implementation Pattern**: + +```yaml +# Typical semantic-release workflow +name: Release +on: + push: + branches: [main] +jobs: + release: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + with: + token: ${{ secrets.GITHUB_APP_TOKEN }} + - run: npx semantic-release +``` + +### 2. GitHub Apps for Branch Protection Bypass + +**Industry Consensus**: GitHub Apps are the recommended approach for automated workflows that need to bypass branch protection rules. + +**Advantages**: + +- Fine-grained permissions +- Organization-level management +- Audit trail +- No personal access tokens required +- Can be added to branch protection bypass list + +**Configuration Requirements**: + +- Repository permissions: Contents (Read & Write) +- Metadata permissions: Read +- Pull requests permissions: Write (if using PR workflow) +- Add app to branch protection bypass list + +**Major Implementations**: + +- **Dependabot**: GitHub's own dependency update bot +- **Renovate**: Popular dependency management tool +- **Release Please**: Google's release automation tool +- **Semantic Release**: Via community GitHub Apps + +### 3. Tag-Based Release Workflows + +**Trend**: Moving away from branch-based triggers to tag-based workflows for better control and atomicity. + +**Pattern**: + +```yaml +# Tag-based release trigger +on: + push: + tags: + - 'v*' +``` + +**Benefits**: + +- Explicit release control +- Atomic version operations +- Cleaner git history +- Reduced workflow complexity +- Better rollback capabilities + +**Adopters**: + +- Kubernetes +- Docker +- Terraform +- Go standard library + +### 4. Release Please (Google's Approach) + +**Overview**: Google's open-source solution for automated releases, used across many Google projects. + +**Key Features**: + +- Language-agnostic +- Conventional commit support +- PR-based workflow +- Automatic changelog generation +- Multi-package repository support + +**Workflow Pattern**: + +1. Analyzes commits since last release +2. Creates a "release PR" with version bumps +3. When PR is merged, creates release and tags +4. Publishes packages + +**Benefits**: + +- Human oversight through PR review +- Atomic release operations +- Clear audit trail +- Supports complex repository structures + +## Enterprise Patterns + +### 1. Microsoft's Approach (Azure DevOps) + +**Strategy**: Service connections with managed identities + +- Uses Azure service principals +- Fine-grained RBAC permissions +- Centralized credential management +- Audit logging + +### 2. GitLab's Built-in Solutions + +**Features**: + +- Push rules for branch protection +- Deploy tokens for automation +- Project access tokens +- CI/CD variables for secrets + +**Pattern**: + +```yaml +# GitLab CI pattern +release: + stage: release + rules: + - if: $CI_COMMIT_BRANCH == "main" + script: + - semantic-release + variables: + GITLAB_TOKEN: $CI_JOB_TOKEN +``` + +### 3. Atlassian's Bitbucket Approach + +**Strategy**: App passwords and repository access keys + +- App-specific passwords +- Repository access keys for read-only access +- Webhook-based automation +- Branch permissions with service account bypass + +## Language-Specific Best Practices + +### JavaScript/Node.js + +- **Standard**: semantic-release +- **Alternative**: release-please +- **Package Management**: npm, yarn +- **Registry**: npmjs.com + +### Python + +- **Tools**: bump2version, semantic-release-python +- **Package Management**: pip, poetry +- **Registry**: PyPI +- **Pattern**: setuptools_scm for version from git tags + +### Go + +- **Approach**: Git tags as versions +- **Tools**: goreleaser +- **Pattern**: Module versioning through tags +- **Registry**: pkg.go.dev + +### Rust + +- **Tools**: cargo-release +- **Package Management**: cargo +- **Registry**: crates.io +- **Pattern**: Cargo.toml version management + +### Java + +- **Tools**: Maven Release Plugin, Gradle Release Plugin +- **Pattern**: POM/build.gradle version management +- **Registry**: Maven Central + +## Security Considerations + +### 1. Principle of Least Privilege + +- Use GitHub Apps instead of personal access tokens +- Limit permissions to minimum required +- Regular permission audits +- Rotate credentials regularly + +### 2. Audit and Monitoring + +- Log all automated actions +- Monitor for unusual activity +- Set up alerts for failed releases +- Regular security reviews + +### 3. Fail-Safe Mechanisms + +- Dry-run capabilities +- Rollback procedures +- Manual override options +- Circuit breakers for repeated failures + +## Emerging Trends + +### 1. GitOps Integration + +- ArgoCD and Flux integration +- Kubernetes-native versioning +- Infrastructure as Code versioning +- Multi-repository coordination + +### 2. Supply Chain Security + +- SLSA compliance +- Signed commits and tags +- Provenance tracking +- Vulnerability scanning integration + +### 3. Monorepo Support + +- Multi-package versioning +- Selective releases +- Dependency graph analysis +- Coordinated releases + +## Anti-Patterns to Avoid + +### 1. Personal Access Tokens for Automation + +- **Problem**: Security risk, tied to individual users +- **Solution**: Use GitHub Apps or service accounts + +### 2. Complex Workflow Chains + +- **Problem**: Difficult to debug, prone to infinite loops +- **Solution**: Simplify triggers, use atomic operations + +### 3. Manual Version Management + +- **Problem**: Human error, inconsistency +- **Solution**: Automate based on conventional commits + +### 4. Bypassing All Protection + +- **Problem**: Removes safety nets +- **Solution**: Selective bypass with proper permissions + +## Recommendations for Hatchling + +### Immediate Actions + +1. **Adopt semantic-release** or release-please pattern +2. **Implement GitHub App** for authentication +3. **Simplify workflow triggers** to prevent loops +4. **Add fail-safe mechanisms** for error recovery + +### Strategic Improvements + +1. **Move to tag-based releases** for better control +2. **Implement conventional commits** for automation +3. **Add comprehensive testing** before releases +4. **Create rollback procedures** for failed releases + +### Long-term Considerations + +1. **Evaluate monorepo patterns** if expanding +2. **Implement supply chain security** measures +3. **Consider GitOps integration** for deployment +4. **Plan for multi-language support** if needed + +## Conclusion + +The industry has converged on several key patterns for automated versioning in protected repositories: + +1. **GitHub Apps** are the standard for authentication and bypass +2. **Semantic versioning** with conventional commits is widely adopted +3. **Atomic operations** through tags or PRs are preferred +4. **Fail-safe mechanisms** are essential for production use + +The Hatchling project should align with these industry standards while maintaining its specific requirements for branch-based development workflows. + +**Grade**: Industry practices are mature and well-established (A) +**Recommendation**: Adopt proven patterns rather than custom solutions diff --git a/LLM_Reports/Integrated_Automated_Versioning_Strategy.md b/LLM_Reports/Integrated_Automated_Versioning_Strategy.md new file mode 100644 index 0000000..8b13350 --- /dev/null +++ b/LLM_Reports/Integrated_Automated_Versioning_Strategy.md @@ -0,0 +1,842 @@ +# Integrated Automated Versioning Strategy: Preserving Emergent Versioning While Fixing Architectural Issues + +## Executive Summary + +This report synthesizes insights from all previous analyses and extensive research into state-of-the-art automated versioning solutions to propose a comprehensive strategy that **preserves the automatic, emergent versioning behavior** of the current Hatchling system while eliminating the critical architectural flaws. + +The solution combines industry-standard tools (semantic-release/release-please) with custom branch-pattern automation to maintain the "hands-off" developer experience while achieving enterprise-grade reliability and compliance with GitHub branch protection. + +## Core Requirement Analysis + +### What Must Be Preserved + +The current system's **key value proposition** is automatic version bumping based on git workflow patterns: + +- **feat/* branches** → Minor version increment + dev/build numbers +- **fix/* branches** → Patch version increment + dev/build numbers +- **dev branch** → Development prereleases with dev numbers +- **main branch** → Clean releases (no dev/build suffixes) + +**Critical Success Factor**: Developers never need to think about versioning - it emerges naturally from their git workflow patterns. + +### What Must Be Fixed + +1. **Infinite loop risk** from workflow chains +2. **Complex dependency chains** with multiple failure points +3. **Branch protection conflicts** requiring PR-based workarounds +4. **Non-atomic operations** spanning multiple commits +5. **Poor error handling** and recovery mechanisms + +## Research Findings: State-of-the-Art Solutions + +### 1. Semantic Release with Branch Configuration + +**Key Discovery**: Semantic-release supports sophisticated branch-based workflows through its `branches` configuration: + +```javascript +// .releaserc.js +module.exports = { + branches: [ + 'main', + { name: 'dev', prerelease: 'dev' }, + { name: 'feat/*', prerelease: '${name.replace(/^feat\\//g, "")}-dev' }, + { name: 'fix/*', prerelease: '${name.replace(/^fix\\//g, "")}-fix' } + ], + plugins: [ + '@semantic-release/commit-analyzer', + '@semantic-release/release-notes-generator', + '@semantic-release/changelog', + '@semantic-release/npm', + '@semantic-release/github', + '@semantic-release/git' + ] +} +``` + +**Benefits**: + +- Automatic version calculation based on conventional commits +- Branch-specific prerelease patterns +- Built-in loop prevention +- GitHub App authentication support +- Atomic operations + +### 2. Release Please with Custom Configuration + +**Key Discovery**: Release-please can be configured for branch-based automation while maintaining PR-based oversight: + +```yaml +# release-please-config.json +{ + "packages": { + ".": { + "release-type": "python", + "include-component-in-tag": false, + "include-v-in-tag": true + } + }, + "branches": ["main", "dev"], + "changelog-sections": [ + {"type": "feat", "section": "Features"}, + {"type": "fix", "section": "Bug Fixes"}, + {"type": "chore", "section": "Miscellaneous", "hidden": true} + ] +} +``` + +### 3. Advanced GitHub Actions Patterns + +**Key Discovery**: Modern GitHub Actions patterns for automated versioning include: + +1. **Conditional Execution** to prevent loops +2. **GitHub App Authentication** for branch protection bypass +3. **Atomic Commit Strategies** for consistency +4. **Branch Pattern Triggers** for emergent behavior +5. **Fail-Safe Mechanisms** for error recovery + +## Proposed Integrated Solutions + +### Option 1: Enhanced Semantic Release (Recommended) + +**Architecture**: Direct commit with semantic-release + custom branch logic + +```yaml +name: Automated Versioning +on: + push: + branches: [main, dev, 'feat/*', 'fix/*'] + workflow_dispatch: + inputs: + force_release: + description: 'Force release creation' + required: false + default: false + +jobs: + version-and-release: + runs-on: ubuntu-latest + if: "!contains(github.event.head_commit.message, '[skip ci]') && github.actor != 'github-actions[bot]'" + + steps: + - name: Generate GitHub App Token + id: generate-token + uses: tibdex/github-app-token@v2 + with: + app_id: ${{ secrets.HATCHLING_APP_ID }} + private_key: ${{ secrets.HATCHLING_APP_PRIVATE_KEY }} + + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + token: ${{ steps.generate-token.outputs.token }} + + - name: Setup Python + uses: actions/setup-python@v5 + with: + python-version: '3.12' + + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install build twine semantic-release + + - name: Configure Git + run: | + git config --local user.email "hatchling-bot@users.noreply.github.com" + git config --local user.name "Hatchling Bot" + + - name: Determine Version Strategy + id: strategy + run: | + BRANCH="${{ github.ref_name }}" + if [[ "$BRANCH" == "main" ]]; then + echo "strategy=release" >> $GITHUB_OUTPUT + echo "prerelease=false" >> $GITHUB_OUTPUT + elif [[ "$BRANCH" == "dev" ]]; then + echo "strategy=prerelease" >> $GITHUB_OUTPUT + echo "prerelease=dev" >> $GITHUB_OUTPUT + elif [[ "$BRANCH" =~ ^feat/ ]]; then + FEATURE_NAME=$(echo "$BRANCH" | sed 's/^feat\///') + echo "strategy=prerelease" >> $GITHUB_OUTPUT + echo "prerelease=${FEATURE_NAME}-dev" >> $GITHUB_OUTPUT + elif [[ "$BRANCH" =~ ^fix/ ]]; then + FIX_NAME=$(echo "$BRANCH" | sed 's/^fix\///') + echo "strategy=prerelease" >> $GITHUB_OUTPUT + echo "prerelease=${FIX_NAME}-fix" >> $GITHUB_OUTPUT + else + echo "strategy=skip" >> $GITHUB_OUTPUT + fi + + - name: Run Tests + if: steps.strategy.outputs.strategy != 'skip' + run: python -m pytest tests/ || exit 1 + + - name: Semantic Release + if: steps.strategy.outputs.strategy != 'skip' + env: + GITHUB_TOKEN: ${{ steps.generate-token.outputs.token }} + GH_TOKEN: ${{ steps.generate-token.outputs.token }} + run: | + # Configure semantic-release for current branch + cat > .releaserc.js << EOF + module.exports = { + branches: [ + 'main', + { name: 'dev', prerelease: 'dev' }, + { name: 'feat/*', prerelease: '\${name.replace(/^feat\\\\//g, "")}-dev' }, + { name: 'fix/*', prerelease: '\${name.replace(/^fix\\\\//g, "")}-fix' } + ], + plugins: [ + '@semantic-release/commit-analyzer', + '@semantic-release/release-notes-generator', + '@semantic-release/changelog', + [ + '@semantic-release/exec', + { + prepareCmd: 'python scripts/version_manager.py --set-version \${nextRelease.version}', + publishCmd: 'python -m build && python -m twine check dist/*' + } + ], + [ + '@semantic-release/git', + { + assets: ['VERSION', 'VERSION.meta', 'CHANGELOG.md'], + message: 'chore(release): \${nextRelease.version} [skip ci]\\n\\n\${nextRelease.notes}' + } + ], + '@semantic-release/github' + ] + } + EOF + + npx semantic-release + + - name: Cleanup Old Tags (main branch only) + if: github.ref == 'refs/heads/main' + run: python scripts/tag_cleanup.py --execute +``` + +**Benefits**: + +- **Preserves emergent versioning**: Branch patterns automatically determine version strategy +- **Eliminates infinite loops**: Built-in semantic-release loop prevention + [skip ci] +- **Atomic operations**: Single workflow handles entire version lifecycle +- **GitHub App authentication**: Bypasses branch protection cleanly +- **Industry standard**: Uses proven semantic-release patterns +- **Fail-safe**: Comprehensive error handling and rollback + +### Option 2: Hybrid Release Please + Custom Logic + +**Architecture**: Release Please for main releases + custom logic for development branches + +```yaml +name: Development Branch Versioning +on: + push: + branches: [dev, 'feat/*', 'fix/*'] + +jobs: + dev-versioning: + runs-on: ubuntu-latest + if: "!contains(github.event.head_commit.message, '[skip ci]')" + + steps: + - name: Generate GitHub App Token + id: generate-token + uses: tibdex/github-app-token@v2 + with: + app_id: ${{ secrets.HATCHLING_APP_ID }} + private_key: ${{ secrets.HATCHLING_APP_PRIVATE_KEY }} + + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + token: ${{ steps.generate-token.outputs.token }} + + - name: Update Development Version + run: | + # Custom logic preserving current branch-based versioning + python scripts/version_manager.py --update-for-branch ${{ github.ref_name }} + + git config --local user.email "hatchling-bot@users.noreply.github.com" + git config --local user.name "Hatchling Bot" + git add VERSION VERSION.meta + git commit -m "chore: update version for ${{ github.ref_name }} [skip ci]" || exit 0 + git push +``` + +```yaml +name: Main Branch Release Please +on: + push: + branches: [main] + +jobs: + release-please: + runs-on: ubuntu-latest + steps: + - uses: googleapis/release-please-action@v4 + id: release + with: + token: ${{ secrets.GITHUB_APP_TOKEN }} + release-type: python + + - uses: actions/checkout@v4 + if: ${{ steps.release.outputs.release_created }} + + - name: Build and Publish + if: ${{ steps.release.outputs.release_created }} + run: | + python -m pip install --upgrade pip build twine + python -m build + python -m twine upload dist/* + env: + TWINE_USERNAME: __token__ + TWINE_PASSWORD: ${{ secrets.PYPI_TOKEN }} +``` + +### Option 3: Custom Conventional Commit Automation + +**Architecture**: Custom implementation using conventional commits with branch pattern enhancement + +```yaml +name: Branch-Aware Conventional Versioning +on: + push: + branches: [main, dev, 'feat/*', 'fix/*'] + +jobs: + version: + runs-on: ubuntu-latest + if: "!contains(github.event.head_commit.message, '[skip ci]') && github.actor != 'github-actions[bot]'" + + steps: + - name: Generate GitHub App Token + id: generate-token + uses: tibdex/github-app-token@v2 + with: + app_id: ${{ secrets.HATCHLING_APP_ID }} + private_key: ${{ secrets.HATCHLING_APP_PRIVATE_KEY }} + + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + token: ${{ steps.generate-token.outputs.token }} + + - name: Analyze Commits and Determine Version + id: version + run: | + # Enhanced version_manager.py with conventional commit parsing + python scripts/enhanced_version_manager.py \ + --branch ${{ github.ref_name }} \ + --analyze-commits \ + --output-github-actions + + - name: Update Version Files + if: steps.version.outputs.should_release == 'true' + run: | + python scripts/enhanced_version_manager.py \ + --branch ${{ github.ref_name }} \ + --set-version ${{ steps.version.outputs.next_version }} + + - name: Build and Test + if: steps.version.outputs.should_release == 'true' + run: | + python -m pip install --upgrade pip build + python -m build + python -m pytest tests/ + + - name: Commit and Tag + if: steps.version.outputs.should_release == 'true' + run: | + git config --local user.email "hatchling-bot@users.noreply.github.com" + git config --local user.name "Hatchling Bot" + + git add VERSION VERSION.meta + git commit -m "chore(release): ${{ steps.version.outputs.next_version }} [skip ci]" + + if [[ "${{ github.ref_name }}" == "main" ]]; then + git tag -a "v${{ steps.version.outputs.next_version }}" -m "Release v${{ steps.version.outputs.next_version }}" + git push origin "v${{ steps.version.outputs.next_version }}" + fi + + git push +``` + +## Implementation Roadmap + +### Phase 1: Immediate Stabilization (Week 1) + +1. **DISABLE** `auto_merge_version_bump.yml` to prevent infinite loops +2. **CREATE** GitHub App with proper permissions +3. **IMPLEMENT** Option 1 (Enhanced Semantic Release) in development environment +4. **TEST** thoroughly with all branch patterns + +### Phase 2: Migration (Week 2-3) + +1. **DEPLOY** new workflow to production +2. **MONITOR** for 1 week with existing workflows disabled +3. **VALIDATE** version generation matches expected patterns +4. **REMOVE** deprecated workflows once stable + +### Phase 3: Enhancement (Month 2) + +1. **ADD** advanced features (changelog generation, release notes) +2. **IMPLEMENT** comprehensive monitoring and alerting +3. **OPTIMIZE** performance and reliability +4. **DOCUMENT** new workflow for team + +## Loop Prevention Strategies + +### 1. Multi-Layer Protection + +```yaml +# Workflow level +if: "!contains(github.event.head_commit.message, '[skip ci]') && github.actor != 'github-actions[bot]'" + +# Commit level +git commit -m "chore(release): ${version} [skip ci]" + +# Path-based (if needed) +on: + push: + paths-ignore: + - 'VERSION' + - 'VERSION.meta' +``` + +### 2. Workflow State Validation + +```yaml +- name: Check for concurrent workflows + run: | + RUNNING=$(gh run list --workflow="${{ github.workflow }}" --status=in_progress --json databaseId --jq length) + if [ "$RUNNING" -gt 1 ]; then + echo "Another workflow is running, exiting gracefully" + exit 0 + fi +``` + +### 3. Branch-Specific Logic + +```yaml +- name: Validate branch for release + run: | + if [[ "${{ github.ref_name }}" =~ ^(main|dev|feat/|fix/).*$ ]]; then + echo "Valid branch for versioning" + else + echo "Skipping versioning for branch: ${{ github.ref_name }}" + exit 0 + fi +``` + +## Error Handling and Recovery + +### 1. Atomic Operations with Rollback + +```yaml +- name: Version update with rollback + run: | + # Create backup + cp VERSION VERSION.backup + cp VERSION.meta VERSION.meta.backup + + # Attempt update + if ! python scripts/version_manager.py --update; then + # Restore on failure + mv VERSION.backup VERSION + mv VERSION.meta.backup VERSION.meta + echo "Version update failed, restored backup" + exit 1 + fi + + # Clean up on success + rm -f *.backup +``` + +### 2. Comprehensive Monitoring + +```yaml +- name: Report status + if: always() + run: | + if [[ "${{ job.status }}" == "failure" ]]; then + gh issue create \ + --title "Automated versioning failed on ${{ github.ref_name }}" \ + --body "Workflow run: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}" + fi +``` + +## Migration Strategy + +### Step 1: GitHub App Setup + +1. Create GitHub App with permissions: + - Contents: Read & Write + - Metadata: Read + - Pull Requests: Write (if using Option 2) +2. Install app on repository +3. Add app to branch protection bypass list +4. Store app credentials as repository secrets + +### Step 2: Workflow Implementation + +1. Implement chosen option in `.github/workflows/` +2. Test in development environment +3. Gradually migrate branch by branch +4. Monitor and adjust as needed + +### Step 3: Legacy Cleanup + +1. Disable old workflows +2. Remove deprecated files +3. Update documentation +4. Train team on new process + +## Enhanced Version Manager Implementation + +To support the new workflows, the existing `version_manager.py` needs enhancement to work with conventional commits and semantic-release patterns: + +```python +# Enhanced version_manager.py additions +import re +from typing import Dict, List, Tuple + +class ConventionalCommitAnalyzer: + """Analyzes conventional commits to determine version bumps""" + + COMMIT_PATTERN = re.compile( + r'^(?P\w+)(?:\((?P[\w\-]+)\))?(?P!)?: (?P.+)$' + ) + + VERSION_BUMPS = { + 'feat': 'minor', + 'fix': 'patch', + 'perf': 'patch', + 'revert': 'patch', + 'docs': None, + 'style': None, + 'refactor': None, + 'test': None, + 'build': None, + 'ci': None, + 'chore': None + } + + def analyze_commits_since_last_release(self, branch: str) -> str: + """Determine version bump type based on commits since last release""" + commits = self._get_commits_since_last_release(branch) + + has_breaking = False + has_feature = False + has_fix = False + + for commit in commits: + match = self.COMMIT_PATTERN.match(commit.message.split('\n')[0]) + if not match: + continue + + commit_type = match.group('type') + is_breaking = match.group('breaking') == '!' or 'BREAKING CHANGE' in commit.message + + if is_breaking: + has_breaking = True + elif commit_type == 'feat': + has_feature = True + elif commit_type in ['fix', 'perf']: + has_fix = True + + if has_breaking: + return 'major' + elif has_feature: + return 'minor' + elif has_fix: + return 'patch' + else: + return None # No releasable changes + +def enhanced_version_manager_cli(): + """Enhanced CLI for integration with semantic-release""" + parser = argparse.ArgumentParser(description='Enhanced Version Manager') + parser.add_argument('--analyze-commits', action='store_true', + help='Analyze commits to determine version bump') + parser.add_argument('--set-version', type=str, + help='Set specific version (for semantic-release integration)') + parser.add_argument('--output-github-actions', action='store_true', + help='Output GitHub Actions compatible variables') + + args = parser.parse_args() + + if args.analyze_commits: + analyzer = ConventionalCommitAnalyzer() + bump_type = analyzer.analyze_commits_since_last_release(args.branch) + + if args.output_github_actions: + print(f"should_release={'true' if bump_type else 'false'}") + if bump_type: + current_version = get_current_version() + next_version = calculate_next_version(current_version, bump_type, args.branch) + print(f"next_version={next_version}") +``` + +## Real-World Implementation Examples + +### Example 1: Feature Branch Workflow + +**Developer Action**: + +```bash +git checkout -b feat/user-authentication +# ... make changes ... +git commit -m "feat: add user authentication system" +git push origin feat/user-authentication +``` + +**Automated Result**: + +- Workflow triggers on `feat/user-authentication` branch +- Semantic-release analyzes commit: `feat:` → minor version bump +- Version becomes: `1.2.0-user-authentication-dev.1` +- VERSION files updated automatically +- No manual intervention required + +### Example 2: Bug Fix Workflow + +**Developer Action**: + +```bash +git checkout -b fix/login-validation +git commit -m "fix: resolve login validation issue" +git push origin fix/login-validation +``` + +**Automated Result**: + +- Workflow triggers on `fix/login-validation` branch +- Semantic-release analyzes commit: `fix:` → patch version bump +- Version becomes: `1.1.1-login-validation-fix.1` +- Automatic testing and validation +- Clean integration with existing patterns + +### Example 3: Main Branch Release + +**Developer Action**: + +```bash +git checkout main +git merge feat/user-authentication +git push origin main +``` + +**Automated Result**: + +- Workflow triggers on main branch +- Analyzes all commits since last release +- Determines version: `1.2.0` (clean release) +- Creates git tag: `v1.2.0` +- Generates GitHub release with changelog +- Updates VERSION files with clean version + +## Advanced Configuration Options + +### Semantic Release Configuration + +```javascript +// .releaserc.js - Advanced configuration +module.exports = { + branches: [ + 'main', + { name: 'dev', prerelease: 'dev' }, + { name: 'feat/*', prerelease: '${name.replace(/^feat\\//g, "")}-dev' }, + { name: 'fix/*', prerelease: '${name.replace(/^fix\\//g, "")}-fix' } + ], + plugins: [ + [ + '@semantic-release/commit-analyzer', + { + preset: 'conventionalcommits', + releaseRules: [ + { type: 'feat', release: 'minor' }, + { type: 'fix', release: 'patch' }, + { type: 'perf', release: 'patch' }, + { type: 'revert', release: 'patch' }, + { type: 'docs', release: false }, + { type: 'style', release: false }, + { type: 'chore', release: false }, + { type: 'refactor', release: false }, + { type: 'test', release: false }, + { type: 'build', release: false }, + { type: 'ci', release: false } + ] + } + ], + [ + '@semantic-release/release-notes-generator', + { + preset: 'conventionalcommits', + presetConfig: { + types: [ + { type: 'feat', section: 'Features' }, + { type: 'fix', section: 'Bug Fixes' }, + { type: 'perf', section: 'Performance Improvements' }, + { type: 'revert', section: 'Reverts' }, + { type: 'docs', section: 'Documentation', hidden: true }, + { type: 'style', section: 'Styles', hidden: true }, + { type: 'chore', section: 'Miscellaneous Chores', hidden: true }, + { type: 'refactor', section: 'Code Refactoring', hidden: true }, + { type: 'test', section: 'Tests', hidden: true }, + { type: 'build', section: 'Build System', hidden: true }, + { type: 'ci', section: 'Continuous Integration', hidden: true } + ] + } + } + ], + '@semantic-release/changelog', + [ + '@semantic-release/exec', + { + prepareCmd: 'python scripts/enhanced_version_manager.py --set-version ${nextRelease.version}', + publishCmd: 'python -m build && python -m twine check dist/*' + } + ], + [ + '@semantic-release/git', + { + assets: ['VERSION', 'VERSION.meta', 'CHANGELOG.md'], + message: 'chore(release): ${nextRelease.version} [skip ci]\n\n${nextRelease.notes}' + } + ], + [ + '@semantic-release/github', + { + successComment: false, + failComment: false, + releasedLabels: ['released'] + } + ] + ] +} +``` + +### GitHub App Permissions Checklist + +**Required Permissions**: + +- ✅ Contents: Read & Write (for commits and tags) +- ✅ Metadata: Read (for repository access) +- ✅ Actions: Read (for workflow status) +- ✅ Pull Requests: Write (if using PR-based option) +- ✅ Issues: Write (for error reporting) + +**Branch Protection Configuration**: + +- ✅ Add GitHub App to bypass list +- ✅ Require status checks: `Automated Versioning` +- ✅ Require up-to-date branches: true +- ✅ Restrict pushes: true +- ✅ Allow bypass for: [Your GitHub App] + +## Monitoring and Observability + +### Workflow Monitoring + +```yaml +- name: Report Workflow Metrics + if: always() + run: | + echo "::notice title=Workflow Status::Status: ${{ job.status }}" + echo "::notice title=Branch::${{ github.ref_name }}" + echo "::notice title=Commit::${{ github.sha }}" + + if [[ "${{ job.status }}" == "success" ]]; then + echo "::notice title=Version::Successfully processed version update" + else + echo "::error title=Failure::Workflow failed - check logs" + fi +``` + +### Error Alerting + +```yaml +- name: Create Issue on Failure + if: failure() + uses: actions/github-script@v7 + with: + script: | + github.rest.issues.create({ + owner: context.repo.owner, + repo: context.repo.repo, + title: `Automated versioning failed on ${context.ref}`, + body: ` + ## Workflow Failure Report + + **Branch**: ${context.ref} + **Commit**: ${context.sha} + **Run**: ${context.serverUrl}/${context.repo.owner}/${context.repo.repo}/actions/runs/${context.runId} + **Actor**: ${context.actor} + + Please investigate and resolve the issue. + `, + labels: ['bug', 'automation', 'versioning'] + }) +``` + +## Performance Optimizations + +### Caching Strategy + +```yaml +- name: Cache Python dependencies + uses: actions/cache@v4 + with: + path: ~/.cache/pip + key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements.txt') }} + restore-keys: | + ${{ runner.os }}-pip- + +- name: Cache semantic-release + uses: actions/cache@v4 + with: + path: ~/.npm + key: ${{ runner.os }}-npm-${{ hashFiles('**/package-lock.json') }} + restore-keys: | + ${{ runner.os }}-npm- +``` + +### Conditional Execution + +```yaml +- name: Check if version update needed + id: check + run: | + if git log --oneline -1 | grep -q '\[skip ci\]'; then + echo "skip=true" >> $GITHUB_OUTPUT + else + echo "skip=false" >> $GITHUB_OUTPUT + fi + +- name: Run versioning + if: steps.check.outputs.skip == 'false' + # ... rest of workflow +``` + +## Conclusion + +The **Enhanced Semantic Release** approach (Option 1) provides the optimal balance of: + +- **Preserving emergent versioning behavior** through branch pattern automation +- **Eliminating architectural issues** with proven industry-standard tools +- **Maintaining developer experience** with zero manual intervention required +- **Ensuring enterprise reliability** with comprehensive error handling + +This solution transforms the current system from a custom, fragile implementation into a robust, industry-standard automated versioning system while preserving the core value proposition that makes it valuable to developers. + +**Recommendation**: Implement Option 1 immediately to resolve critical stability issues while maintaining the automatic, hands-off versioning behavior that developers rely on. + +**Next Steps**: + +1. Create GitHub App and configure permissions +2. Implement enhanced version manager with conventional commit support +3. Deploy new workflow with comprehensive testing +4. Monitor and iterate based on real-world usage +5. Remove legacy workflows once stable diff --git a/LLM_Reports/Semantic_Release_Migration_Plan.md b/LLM_Reports/Semantic_Release_Migration_Plan.md new file mode 100644 index 0000000..8b6e600 --- /dev/null +++ b/LLM_Reports/Semantic_Release_Migration_Plan.md @@ -0,0 +1,689 @@ +# Semantic Release Migration Plan: Complete Replacement of Custom Versioning System + +## Executive Summary + +This comprehensive migration plan details the complete replacement of Hatchling's custom automated versioning system with `semantic-release`, a battle-tested industry standard. The migration will eliminate all architectural flaws while maintaining fully automated versioning through Conventional Commits and branch-based workflows. + +**Key Benefits:** +- ✅ Eliminates infinite loop risks and complex dependency chains +- ✅ Full GitHub branch protection compliance +- ✅ Atomic operations with proper error handling +- ✅ Industry-standard Conventional Commits workflow +- ✅ Maintains fully automated versioning without manual intervention +- ✅ Supports pre-releases and multiple distribution channels + +## Current State Analysis + +### What Will Be Removed + +The following custom implementation components will be completely removed: + +**Scripts to Remove:** +- `scripts/version_manager.py` (327 lines of complex version logic) +- `scripts/prepare_version.py` (version preparation logic) +- `scripts/tag_cleanup.py` (cleanup utilities) + +**Workflows to Remove:** +- `.github/workflows/auto_merge_version_bump.yml` +- `.github/workflows/commit_version_tag.yml` +- `.github/workflows/create_tag_on_main.yml` +- `.github/workflows/tag-cleanup.yml` +- `.github/workflows/tag-release.yml` +- `.github/workflows/release.yml` (current release workflow) + +**Files to Remove:** +- `VERSION` (simple version file) +- `VERSION.meta` (structured version metadata) + +### Current System Issues + +1. **Infinite Loop Risk**: Workflows trigger other workflows creating potential loops +2. **Complex Dependencies**: Multi-step chains with numerous failure points +3. **Branch Protection Conflicts**: Requires PR-based workarounds for protected branches +4. **Non-Atomic Operations**: Version updates span multiple commits and workflows +5. **Poor Error Handling**: Limited recovery mechanisms for failed operations +6. **Maintenance Overhead**: 327+ lines of custom version management code + +## Semantic Release Overview + +### How Semantic Release Works + +Semantic Release automates the entire release workflow based on commit message analysis: + +1. **Commit Analysis**: Analyzes commit messages using Conventional Commits format +2. **Version Calculation**: Determines next version based on commit types: + - `fix:` → Patch release (1.0.0 → 1.0.1) + - `feat:` → Minor release (1.0.0 → 1.1.0) + - `BREAKING CHANGE:` → Major release (1.0.0 → 2.0.0) +3. **Release Generation**: Creates GitHub releases with auto-generated changelogs +4. **Asset Publishing**: Publishes to npm, PyPI, or other registries +5. **Notification**: Updates issues/PRs and sends notifications + +### Key Advantages + +- **Battle-Tested**: Used by thousands of projects including major open source libraries +- **Atomic Operations**: All release steps happen in a single workflow run +- **Branch Protection Compliant**: Works seamlessly with protected branches +- **Extensible**: Rich plugin ecosystem for customization +- **Zero Configuration**: Works out-of-the-box with sensible defaults + +## Conventional Commits Integration + +### Transition from Current Practices + +**Current Approach**: Branch naming patterns determine version increments +- `feat/*` branches → Minor version increment +- `fix/*` branches → Patch version increment + +**New Approach**: Commit message format determines version increments +- `feat: add new feature` → Minor version increment +- `fix: resolve bug` → Patch version increment +- `feat!: breaking change` → Major version increment + +### Conventional Commits Format + +``` +[optional scope]: + +[optional body] + +[optional footer(s)] +``` + +**Common Types:** +- `feat`: New feature (minor version) +- `fix`: Bug fix (patch version) +- `docs`: Documentation changes +- `style`: Code style changes (formatting, etc.) +- `refactor`: Code refactoring +- `test`: Adding or updating tests +- `chore`: Maintenance tasks + +**Breaking Changes:** +- Add `!` after type: `feat!: breaking change` +- Or add footer: `BREAKING CHANGE: description` + +### Migration Strategy for Commit Messages + +**Phase 1**: Education and tooling setup +- Install commitizen for guided commit messages +- Add commit message linting with commitlint +- Update documentation with examples + +**Phase 2**: Gradual adoption +- Encourage conventional commits in new PRs +- Provide commit message templates +- Add PR checks for commit format + +**Phase 3**: Enforcement +- Require conventional commits for all new changes +- Use squash merging to clean up commit history + +## Step-by-Step Migration Plan + +### Phase 1: Preparation and Setup (Week 1) + +#### 1.1 Install Dependencies + +Add to `pyproject.toml`: +```toml +[tool.semantic_release] +version_toml = ["pyproject.toml:project.version"] +build_command = "python -m build" +dist_path = "dist/" +upload_to_pypi = false +upload_to_release = true +remove_dist = false + +[tool.semantic_release.branches.main] +match = "main" +prerelease = false + +[tool.semantic_release.branches.dev] +match = "dev" +prerelease = "dev" + +[tool.semantic_release.changelog] +template_dir = "templates" +changelog_file = "CHANGELOG.md" + +[tool.semantic_release.commit_parser_options] +allowed_tags = ["build", "chore", "ci", "docs", "feat", "fix", "perf", "style", "refactor", "test"] +minor_tags = ["feat"] +patch_tags = ["fix", "perf"] +``` + +#### 1.2 Create Package.json for Node Dependencies + +Create `package.json`: +```json +{ + "name": "hatchling", + "private": true, + "devDependencies": { + "semantic-release": "^22.0.0", + "@semantic-release/changelog": "^6.0.0", + "@semantic-release/git": "^10.0.0", + "@semantic-release/github": "^9.0.0", + "commitizen": "^4.3.0", + "@commitlint/cli": "^18.0.0", + "@commitlint/config-conventional": "^18.0.0", + "cz-conventional-changelog": "^3.3.0" + }, + "config": { + "commitizen": { + "path": "./node_modules/cz-conventional-changelog" + } + } +} +``` + +#### 1.3 Create Semantic Release Configuration + +Create `.releaserc.json`: +```json +{ + "branches": [ + "main", + { + "name": "dev", + "prerelease": "dev" + } + ], + "plugins": [ + "@semantic-release/commit-analyzer", + "@semantic-release/release-notes-generator", + "@semantic-release/changelog", + [ + "@semantic-release/git", + { + "assets": ["CHANGELOG.md", "pyproject.toml"], + "message": "chore(release): ${nextRelease.version} [skip ci]\n\n${nextRelease.notes}" + } + ], + "@semantic-release/github" + ] +} +``` + +### Phase 2: GitHub Actions Setup (Week 1) + +#### 2.1 Create New Release Workflow + +Create `.github/workflows/semantic-release.yml`: +```yaml +name: Semantic Release + +on: + push: + branches: + - main + - dev + pull_request: + branches: + - main + +permissions: + contents: write + issues: write + pull-requests: write + id-token: write + +jobs: + test: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Setup Python + uses: actions/setup-python@v5 + with: + python-version: '3.12' + + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -e . + pip install pytest + + - name: Run tests + run: python run_tests.py + + release: + needs: test + runs-on: ubuntu-latest + if: github.event_name == 'push' + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 0 + token: ${{ secrets.GITHUB_TOKEN }} + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: "lts/*" + + - name: Setup Python + uses: actions/setup-python@v5 + with: + python-version: '3.12' + + - name: Install dependencies + run: | + npm ci + python -m pip install --upgrade pip + pip install build python-semantic-release + + - name: Verify the integrity of provenance attestations and registry signatures for installed dependencies + run: npm audit signatures + + - name: Release + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: npx semantic-release +``` + +#### 2.2 Create Commit Lint Workflow + +Create `.github/workflows/commitlint.yml`: +```yaml +name: Commit Lint + +on: + pull_request: + branches: [main, dev] + +jobs: + commitlint: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: "lts/*" + + - name: Install dependencies + run: npm ci + + - name: Validate current commit (last commit) with commitlint + if: github.event_name == 'push' + run: npx commitlint --last --verbose + + - name: Validate PR commits with commitlint + if: github.event_name == 'pull_request' + run: npx commitlint --from ${{ github.event.pull_request.head.sha }}~${{ github.event.pull_request.commits }} --to ${{ github.event.pull_request.head.sha }} --verbose +``` + +### Phase 3: Configuration Files (Week 1) + +#### 3.1 Create Commitlint Configuration + +Create `.commitlintrc.json`: +```json +{ + "extends": ["@commitlint/config-conventional"], + "rules": { + "type-enum": [ + 2, + "always", + [ + "build", + "chore", + "ci", + "docs", + "feat", + "fix", + "perf", + "refactor", + "revert", + "style", + "test" + ] + ] + } +} +``` + +#### 3.2 Update Pyproject.toml + +Update version configuration in `pyproject.toml`: +```toml +[project] +name = "hatchling" +version = "0.4.0" # Remove dynamic = ["version"] +# ... rest of configuration +``` + +### Phase 4: Migration Execution (Week 2) + +#### 4.1 Remove Custom System + +1. **Delete custom scripts:** + ```bash + rm -rf scripts/ + ``` + +2. **Delete custom workflows:** + ```bash + rm .github/workflows/auto_merge_version_bump.yml + rm .github/workflows/commit_version_tag.yml + rm .github/workflows/create_tag_on_main.yml + rm .github/workflows/tag-cleanup.yml + rm .github/workflows/tag-release.yml + rm .github/workflows/release.yml + ``` + +3. **Delete version files:** + ```bash + rm VERSION VERSION.meta + ``` + +#### 4.2 Initialize Semantic Release + +1. **Install Node dependencies:** + ```bash + npm install + ``` + +2. **Set up initial version:** + ```bash + # Update pyproject.toml with current version + # Commit with conventional format + git add . + git commit -m "feat!: migrate to semantic-release + + BREAKING CHANGE: Replace custom versioning system with semantic-release. + This requires using Conventional Commits for all future changes." + ``` + +3. **Test the new system:** + ```bash + # Dry run to verify configuration + npx semantic-release --dry-run + ``` + +### Phase 5: Validation and Testing (Week 2) + +#### 5.1 Test Release Process + +1. **Create test feature branch:** + ```bash + git checkout -b feat/test-semantic-release + echo "# Test" >> test.md + git add test.md + git commit -m "feat: add test file for semantic-release validation" + git push origin feat/test-semantic-release + ``` + +2. **Create PR and merge to trigger release** + +3. **Verify release creation:** + - Check GitHub releases page + - Verify changelog generation + - Confirm version bumping + +#### 5.2 Test Pre-release Process + +1. **Push to dev branch:** + ```bash + git checkout dev + git commit -m "feat: test dev pre-release" --allow-empty + git push origin dev + ``` + +2. **Verify pre-release creation:** + - Check for dev pre-release tags + - Verify pre-release marking in GitHub + +### Phase 6: Documentation and Training (Week 3) + +#### 6.1 Update Documentation + +Create `docs/CONTRIBUTING.md`: +```markdown +# Contributing to Hatchling + +## Commit Message Format + +We use [Conventional Commits](https://www.conventionalcommits.org/) for all commit messages. + +### Format +``` +[optional scope]: + +[optional body] + +[optional footer(s)] +``` + +### Examples +- `feat: add new LLM provider` +- `fix: resolve memory leak in streaming` +- `docs: update API documentation` +- `feat!: change configuration format` + +### Using Commitizen +For guided commit messages, use: +```bash +npm run commit +# or +npx cz +``` +``` + +#### 6.2 Update README + +Add to `README.md`: +```markdown +## Development + +### Commit Messages +This project uses [Conventional Commits](https://www.conventionalcommits.org/). +Please format your commit messages accordingly: + +- `feat:` for new features +- `fix:` for bug fixes +- `docs:` for documentation changes +- `test:` for test changes +- `chore:` for maintenance tasks + +### Releases +Releases are automatically created when changes are merged to `main` using +[semantic-release](https://semantic-release.gitbook.io/). +``` + +## Configuration Examples + +### Complete .releaserc.json +```json +{ + "branches": [ + "main", + { + "name": "dev", + "prerelease": "dev" + }, + { + "name": "beta", + "prerelease": "beta" + } + ], + "plugins": [ + [ + "@semantic-release/commit-analyzer", + { + "preset": "conventionalcommits", + "releaseRules": [ + {"type": "docs", "scope": "README", "release": "patch"}, + {"type": "refactor", "release": "patch"}, + {"type": "style", "release": "patch"} + ] + } + ], + [ + "@semantic-release/release-notes-generator", + { + "preset": "conventionalcommits", + "presetConfig": { + "types": [ + {"type": "feat", "section": "Features"}, + {"type": "fix", "section": "Bug Fixes"}, + {"type": "chore", "hidden": true}, + {"type": "docs", "section": "Documentation"}, + {"type": "style", "hidden": true}, + {"type": "refactor", "section": "Code Refactoring"}, + {"type": "perf", "section": "Performance Improvements"}, + {"type": "test", "hidden": true} + ] + } + } + ], + [ + "@semantic-release/changelog", + { + "changelogFile": "CHANGELOG.md" + } + ], + [ + "@semantic-release/git", + { + "assets": ["CHANGELOG.md", "pyproject.toml"], + "message": "chore(release): ${nextRelease.version} [skip ci]\n\n${nextRelease.notes}" + } + ], + [ + "@semantic-release/github", + { + "successComment": "🎉 This ${issue.pull_request ? 'PR is included' : 'issue has been resolved'} in version ${nextRelease.version} 🎉", + "labels": ["released"], + "releasedLabels": ["released<%= nextRelease.type === 'prerelease' ? ` on @${nextRelease.channel}` : '' %>"] + } + ] + ] +} +``` + +## Migration Timeline + +### Week 1: Setup and Configuration +- **Day 1-2**: Install dependencies and create configuration files +- **Day 3-4**: Set up GitHub Actions workflows +- **Day 5**: Create commit lint and validation workflows + +### Week 2: Migration Execution +- **Day 1-2**: Remove custom system components +- **Day 3-4**: Initialize semantic-release and test +- **Day 5**: Validation and troubleshooting + +### Week 3: Documentation and Training +- **Day 1-2**: Update all documentation +- **Day 3-4**: Team training on Conventional Commits +- **Day 5**: Final testing and go-live + +### Week 4: Monitoring and Optimization +- **Day 1-3**: Monitor release process +- **Day 4-5**: Optimize configuration based on usage + +## Validation and Testing + +### Pre-Migration Checklist +- [ ] All dependencies installed +- [ ] Configuration files created +- [ ] GitHub Actions workflows tested +- [ ] Team trained on Conventional Commits +- [ ] Documentation updated +- [ ] Backup of current system created + +### Post-Migration Validation +- [ ] Successful release created from main branch +- [ ] Pre-release created from dev branch +- [ ] Changelog automatically generated +- [ ] GitHub releases properly formatted +- [ ] Version bumping working correctly +- [ ] No infinite loops or workflow conflicts + +### Testing Scenarios +1. **Feature Release**: Merge feat commit to main → Minor version bump +2. **Bug Fix Release**: Merge fix commit to main → Patch version bump +3. **Breaking Change**: Merge feat! commit to main → Major version bump +4. **Pre-release**: Push to dev branch → Pre-release version +5. **Documentation**: Merge docs commit → No release (configurable) + +## Rollback Plan + +### Emergency Rollback Procedure + +If critical issues arise during migration: + +1. **Immediate Actions:** + ```bash + # Disable semantic-release workflow + mv .github/workflows/semantic-release.yml .github/workflows/semantic-release.yml.disabled + + # Restore custom workflows from backup + git checkout HEAD~1 -- .github/workflows/ + git checkout HEAD~1 -- scripts/ + git checkout HEAD~1 -- VERSION VERSION.meta + ``` + +2. **Restore Custom System:** + - Revert pyproject.toml changes + - Restore version files + - Re-enable custom workflows + - Create hotfix release using old system + +3. **Communication:** + - Notify team of rollback + - Document issues encountered + - Plan remediation strategy + +### Rollback Triggers +- Infinite loop detection in workflows +- Failed releases blocking development +- Critical functionality broken +- Team unable to adapt to new process + +## Success Metrics + +### Technical Metrics +- Zero workflow infinite loops +- 100% successful releases +- Reduced release time (target: <5 minutes) +- Eliminated manual version management + +### Process Metrics +- Team adoption of Conventional Commits (target: >90%) +- Reduced release-related issues (target: 50% reduction) +- Improved changelog quality +- Faster hotfix deployment + +### Maintenance Metrics +- Reduced custom code maintenance (327 lines → 0) +- Simplified workflow debugging +- Improved error handling and recovery +- Better compliance with GitHub best practices + +## Conclusion + +This migration plan provides a comprehensive roadmap for replacing Hatchling's custom versioning system with semantic-release. The new system will eliminate architectural flaws while maintaining fully automated versioning through industry-standard practices. + +**Key Benefits Achieved:** +- ✅ Eliminated infinite loop risks +- ✅ Simplified architecture with proven tools +- ✅ Full GitHub branch protection compliance +- ✅ Atomic release operations +- ✅ Industry-standard Conventional Commits +- ✅ Comprehensive error handling +- ✅ Zero maintenance overhead for version management + +The migration is designed to be executed in phases with comprehensive testing and validation at each step, ensuring a smooth transition with minimal risk to the development process. diff --git a/LLM_Reports/Semantic_Release_Migration_Plan_v2.md b/LLM_Reports/Semantic_Release_Migration_Plan_v2.md new file mode 100644 index 0000000..a76fe00 --- /dev/null +++ b/LLM_Reports/Semantic_Release_Migration_Plan_v2.md @@ -0,0 +1,733 @@ +# Semantic Release Migration Plan v2: Comprehensive Analysis & Implementation + +## Executive Summary + +This updated migration plan addresses all identified concerns and provides detailed analysis based on the latest semantic-release documentation. The migration will replace Hatchling's custom automated versioning system with the industry-standard `semantic-release` while maintaining fully automated versioning and addressing all technical requirements. + +**Key Decisions Based on Research:** + +- ✅ Use language-agnostic `semantic-release` (Node.js) - sufficient for Python projects +- ✅ Remove VERSION file - semantic-release handles version management natively +- ✅ Disable automated publishing - configure for development phase projects +- ✅ Maintain 0.x.x versioning through careful commit practices +- ✅ Integrate with existing unittest framework via custom test runner +- ✅ No dedicated GitHub App needed - standard GITHUB_TOKEN sufficient + +## Detailed Analysis of Concerns + +### 1. VERSION File Retention Analysis + +**Decision: Remove VERSION file completely** + +**Rationale:** + +- Semantic-release manages version in `pyproject.toml` directly via `@semantic-release/git` plugin +- Eliminates dual-file complexity and potential synchronization issues +- Native integration with Python packaging standards +- Reduces maintenance overhead and eliminates custom version management code + +**Implementation:** + +```toml +# pyproject.toml - Remove dynamic version +[project] +name = "hatchling" +version = "0.4.0" # Static initial version, managed by semantic-release +``` + +### 2. Asset Publishing Configuration + +**Decision: Disable automated package publishing** + +**Rationale:** + +- Development phase projects should not auto-publish to PyPI +- GitHub releases provide sufficient distribution for development +- Can be enabled later when ready for public distribution + +**Configuration:** + +```json +{ + "plugins": [ + "@semantic-release/commit-analyzer", + "@semantic-release/release-notes-generator", + "@semantic-release/changelog", + ["@semantic-release/git", { + "assets": ["CHANGELOG.md", "pyproject.toml"], + "message": "chore(release): ${nextRelease.version} [skip ci]\n\n${nextRelease.notes}" + }], + ["@semantic-release/github", { + "assets": false, // No asset uploads + "successComment": false, // Disable PR/issue comments for development + "failComment": false + }] + ] +} +``` + +### 3. Git Tagging Analysis + +**Decision: Semantic-release automatic tagging is sufficient** + +**Rationale:** + +- Semantic-release automatically creates Git tags for each release +- Tags follow semantic versioning format (v1.0.0, v1.1.0, etc.) +- Supports version-based cloning: `git clone --branch v1.0.0 ` +- No additional tag management needed + +**Tag Format:** + +- Production releases: `v1.0.0`, `v1.1.0`, `v2.0.0` +- Pre-releases: `v1.1.0-dev.1`, `v1.1.0-beta.1` + +### 4. Development Versioning (0.x.x) Strategy + +**Decision: Maintain 0.x.x through commit discipline** + +**Rationale:** + +- Semantic-release respects current version in `pyproject.toml` +- Starting at `0.4.0` will continue 0.x.x series +- Avoid `BREAKING CHANGE` commits to prevent 1.0.0 release +- Use `feat!:` syntax sparingly until ready for 1.0.0 + +**Implementation Strategy:** + +```bash +# Safe commit types for 0.x.x maintenance: +feat: new feature # 0.4.0 → 0.5.0 +fix: bug fix # 0.4.0 → 0.4.1 +docs: documentation # No version change +chore: maintenance # No version change + +# Avoid until ready for 1.0.0: +feat!: breaking change # Would trigger 0.4.0 → 1.0.0 +BREAKING CHANGE: in footer # Would trigger 0.4.0 → 1.0.0 +``` + +### 5. Documentation Updates Required + +**Files to Update:** + +1. `docs/articles/devs/versioning.md` - Complete rewrite +2. `README.md` - Update development section +3. `CONTRIBUTING.md` - Create with Conventional Commits guide + +**Key Changes:** + +- Remove all references to VERSION/VERSION.meta files +- Replace branch-based versioning with commit-based versioning +- Update workflow documentation +- Add Conventional Commits examples + +### 6. Contributor Requirements Analysis + +**Decision: Gradual adoption with tooling support** + +**Based on Conventional Commits FAQ:** + +- Not all contributors need to follow specification initially +- Squash merging can clean up commit history +- Provide tooling (commitizen) for guided commits +- Enforce via PR checks rather than blocking contributions + +**Implementation:** + +```json +// package.json +{ + "scripts": { + "commit": "cz", + "prepare": "husky install" + }, + "config": { + "commitizen": { + "path": "./node_modules/cz-conventional-changelog" + } + } +} +``` + +### 7. Testing Framework Integration + +**Decision: Maintain existing unittest framework** + +**Rationale:** + +- Existing `run_tests.py` provides comprehensive test management +- No need to migrate to pytest for semantic-release +- Semantic-release only needs test command to pass/fail +- Custom test runner supports advanced filtering and categorization + +**GitHub Actions Integration:** + +```yaml +- name: Run tests + run: python run_tests.py --regression --feature +``` + +### 8. Tool Selection: semantic-release vs python-semantic-release + +**Decision: Use language-agnostic `semantic-release` (Node.js)** + +**Rationale from Official Documentation:** + +- More mature and feature-complete +- Larger plugin ecosystem +- Better GitHub Actions integration +- Official documentation recommends Node.js version +- Python projects commonly use Node.js semantic-release + +**Evidence from GitHub Actions docs:** + +```yaml +# Official semantic-release GitHub Actions example +- name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: "lts/*" +- name: Release + run: npx semantic-release +``` + +## Updated Implementation Plan + +### Phase 1: Preparation (Week 1) + +#### 1.1 Install Node.js Dependencies + +Create `package.json`: + +```json +{ + "name": "hatchling", + "private": true, + "scripts": { + "commit": "cz", + "semantic-release": "semantic-release" + }, + "devDependencies": { + "semantic-release": "^22.0.12", + "@semantic-release/changelog": "^6.0.3", + "@semantic-release/git": "^10.0.1", + "@semantic-release/github": "^9.2.6", + "commitizen": "^4.3.0", + "@commitlint/cli": "^18.6.1", + "@commitlint/config-conventional": "^18.6.2", + "cz-conventional-changelog": "^3.3.0" + }, + "config": { + "commitizen": { + "path": "./node_modules/cz-conventional-changelog" + } + } +} +``` + +#### 1.2 Create Semantic Release Configuration + +Create `.releaserc.json`: + +```json +{ + "branches": [ + "main", + { + "name": "dev", + "prerelease": "dev" + } + ], + "plugins": [ + [ + "@semantic-release/commit-analyzer", + { + "preset": "conventionalcommits", + "releaseRules": [ + {"type": "docs", "scope": "README", "release": "patch"}, + {"type": "refactor", "release": "patch"}, + {"type": "style", "release": "patch"}, + {"type": "test", "release": false}, + {"type": "chore", "release": false} + ] + } + ], + [ + "@semantic-release/release-notes-generator", + { + "preset": "conventionalcommits", + "presetConfig": { + "types": [ + {"type": "feat", "section": "Features"}, + {"type": "fix", "section": "Bug Fixes"}, + {"type": "docs", "section": "Documentation"}, + {"type": "refactor", "section": "Code Refactoring"}, + {"type": "perf", "section": "Performance Improvements"} + ] + } + } + ], + [ + "@semantic-release/changelog", + { + "changelogFile": "CHANGELOG.md" + } + ], + [ + "@semantic-release/git", + { + "assets": ["CHANGELOG.md", "pyproject.toml"], + "message": "chore(release): ${nextRelease.version} [skip ci]\n\n${nextRelease.notes}" + } + ], + [ + "@semantic-release/github", + { + "successComment": false, + "failComment": false, + "releasedLabels": false + } + ] + ] +} +``` + +#### 1.3 Create Commitlint Configuration + +Create `.commitlintrc.json`: + +```json +{ + "extends": ["@commitlint/config-conventional"], + "rules": { + "type-enum": [ + 2, + "always", + [ + "build", + "chore", + "ci", + "docs", + "feat", + "fix", + "perf", + "refactor", + "revert", + "style", + "test" + ] + ], + "subject-case": [2, "never", ["start-case", "pascal-case", "upper-case"]], + "subject-empty": [2, "never"], + "subject-full-stop": [2, "never", "."], + "header-max-length": [2, "always", 72] + } +} +``` + +### Phase 2: GitHub Actions Setup (Week 1) + +#### 2.1 Create New Release Workflow + +Create `.github/workflows/semantic-release.yml`: + +```yaml +name: Semantic Release + +on: + push: + branches: + - main + - dev + +permissions: + contents: write + issues: write + pull-requests: write + id-token: write + +jobs: + test: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Setup Python + uses: actions/setup-python@v5 + with: + python-version: '3.12' + + - name: Install Python dependencies + run: | + python -m pip install --upgrade pip + pip install -e . + + - name: Run tests + run: python run_tests.py --regression --feature + + release: + needs: test + runs-on: ubuntu-latest + if: github.event_name == 'push' + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 0 + token: ${{ secrets.GITHUB_TOKEN }} + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: "lts/*" + + - name: Install Node dependencies + run: npm ci + + - name: Verify npm audit + run: npm audit signatures + + - name: Release + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: npx semantic-release +``` + +#### 2.2 Create Commit Lint Workflow + +Create `.github/workflows/commitlint.yml`: + +```yaml +name: Commit Lint + +on: + pull_request: + branches: [main, dev] + +jobs: + commitlint: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: "lts/*" + + - name: Install dependencies + run: npm ci + + - name: Validate PR commits with commitlint + run: npx commitlint --from ${{ github.event.pull_request.base.sha }} --to ${{ github.event.pull_request.head.sha }} --verbose +``` + +### Phase 3: Project Configuration Updates (Week 1) + +#### 3.1 Update pyproject.toml + +```toml +[project] +name = "hatchling" +version = "0.4.0" # Remove dynamic = ["version"] +description = "LLM with MCP Tool Calling" +# ... rest unchanged +``` + +#### 3.2 Create .gitignore Updates + +Add to `.gitignore`: + +``` +# Node.js dependencies for semantic-release +node_modules/ +npm-debug.log* +yarn-debug.log* +yarn-error.log* + +# Semantic-release +.semantic-release/ +``` + +### Phase 4: Migration Execution (Week 2) + +#### 4.1 Remove Custom System + +**Files to Delete:** + +```bash +# Remove custom versioning system +rm -rf scripts/ +rm VERSION VERSION.meta + +# Remove custom workflows +rm .github/workflows/auto_merge_version_bump.yml +rm .github/workflows/commit_version_tag.yml +rm .github/workflows/create_tag_on_main.yml +rm .github/workflows/tag-cleanup.yml +rm .github/workflows/tag-release.yml +rm .github/workflows/release.yml +``` + +#### 4.2 Initialize Semantic Release + +```bash +# Install Node dependencies +npm install + +# Test configuration +npx semantic-release --dry-run + +# Create initial migration commit +git add . +git commit -m "feat!: migrate to semantic-release + +BREAKING CHANGE: Replace custom versioning system with semantic-release. +This requires using Conventional Commits for all future changes. + +- Remove custom scripts and workflows +- Add semantic-release configuration +- Update project structure for automated releases" +``` + +### Phase 5: Documentation Updates (Week 2) + +#### 5.1 Update Versioning Documentation + +Replace `docs/articles/devs/versioning.md` content: + +```markdown +# Automated Versioning with Semantic Release + +Hatchling uses [semantic-release](https://semantic-release.gitbook.io/) for fully automated versioning and releases based on [Conventional Commits](https://www.conventionalcommits.org/). + +## How It Works + +1. **Commit Analysis**: Analyzes commit messages to determine release type +2. **Version Calculation**: Automatically calculates next version +3. **Changelog Generation**: Creates release notes from commits +4. **GitHub Release**: Publishes release with generated notes +5. **Version Update**: Updates pyproject.toml with new version + +## Commit Message Format + +Use [Conventional Commits](https://www.conventionalcommits.org/) format: + +``` + +[optional scope]: + +[optional body] + +[optional footer(s)] + +``` + +### Examples + +```bash +feat: add new LLM provider support +fix: resolve memory leak in streaming +docs: update API documentation +refactor: simplify provider registry +test: add integration tests for OpenAI +chore: update dependencies + +# Breaking changes (avoid until ready for v1.0.0) +feat!: change configuration format +``` + +### Version Impact + +- `feat:` → Minor version (0.4.0 → 0.5.0) +- `fix:` → Patch version (0.4.0 → 0.4.1) +- `feat!:` or `BREAKING CHANGE:` → Major version (0.4.0 → 1.0.0) +- `docs:`, `test:`, `chore:` → No release + +## Using Commitizen + +For guided commit messages: + +```bash +npm run commit +# or +npx cz +``` + +## Branches + +- **main**: Production releases (0.4.0, 0.5.0, etc.) +- **dev**: Pre-releases (0.5.0-dev.1, 0.5.0-dev.2, etc.) + +## Manual Testing + +Test semantic-release configuration: + +```bash +npx semantic-release --dry-run +``` + +``` + +#### 5.2 Create Contributing Guide + +Create `CONTRIBUTING.md`: +```markdown +# Contributing to Hatchling + +## Commit Message Format + +We use [Conventional Commits](https://www.conventionalcommits.org/) for automated versioning. + +### Quick Reference + +- `feat:` - New features +- `fix:` - Bug fixes +- `docs:` - Documentation changes +- `refactor:` - Code refactoring +- `test:` - Test changes +- `chore:` - Maintenance tasks + +### Using Commitizen + +For guided commits: +```bash +npm run commit +``` + +### Pull Requests + +- Use descriptive titles +- Reference related issues +- Ensure tests pass +- Follow commit message format + +``` + +## Branch Protection & Permissions + +### Required GitHub Settings + +**Branch Protection Rules for `main`:** +- ✅ Require a pull request before merging +- ✅ Require status checks to pass before merging + - ✅ `test` (from semantic-release workflow) + - ✅ `commitlint` (from commitlint workflow) +- ✅ Require branches to be up to date before merging +- ✅ Require linear history + +**Repository Permissions:** +- Semantic-release workflow uses `GITHUB_TOKEN` (no additional setup needed) +- Standard permissions sufficient: `contents: write`, `issues: write`, `pull-requests: write` + +## Testing Strategy + +### Pre-Migration Testing + +1. **Dry Run Test:** + ```bash + npx semantic-release --dry-run + ``` + +2. **Commit Format Validation:** + + ```bash + echo "feat: test commit" | npx commitlint + ``` + +3. **Workflow Validation:** + - Create test branch + - Make conventional commit + - Verify workflow triggers + +### Post-Migration Validation + +1. **Feature Release Test:** + + ```bash + git checkout -b feat/test-semantic-release + echo "# Test" >> test.md + git add test.md + git commit -m "feat: add test file for semantic-release validation" + # Create PR and merge to main + ``` + +2. **Pre-release Test:** + + ```bash + git checkout dev + git commit -m "feat: test dev pre-release" --allow-empty + git push origin dev + ``` + +## Rollback Plan + +### Emergency Rollback + +If critical issues arise: + +1. **Disable Workflows:** + + ```bash + mv .github/workflows/semantic-release.yml .github/workflows/semantic-release.yml.disabled + ``` + +2. **Restore Manual Versioning:** + + ```bash + # Create emergency VERSION file + echo "0.4.0" > VERSION + + # Update pyproject.toml + # Change: version = "0.4.0" + # To: dynamic = ["version"] + ``` + +3. **Emergency Release:** + + ```bash + git tag v0.4.1 + git push origin v0.4.1 + ``` + +## Success Metrics + +### Technical Metrics + +- ✅ Zero workflow failures +- ✅ Automated version management +- ✅ Consistent release notes +- ✅ Proper semantic versioning + +### Process Metrics + +- ✅ Team adoption of Conventional Commits +- ✅ Reduced manual release overhead +- ✅ Improved changelog quality +- ✅ Faster development cycle + +## Timeline Summary + +- **Week 1**: Setup and configuration +- **Week 2**: Migration execution and testing +- **Week 3**: Documentation and team training +- **Week 4**: Monitoring and optimization + +## Conclusion + +This migration plan provides a comprehensive, tested approach to replacing the custom versioning system with semantic-release. All concerns have been addressed with specific technical solutions based on official documentation and best practices. + +The new system will provide: + +- ✅ Fully automated versioning without manual intervention +- ✅ Industry-standard Conventional Commits workflow +- ✅ Elimination of complex custom code (327+ lines removed) +- ✅ Better compliance with GitHub best practices +- ✅ Improved developer experience with guided tooling diff --git a/LLM_Reports/Workflow_Optimization_Report.md b/LLM_Reports/Workflow_Optimization_Report.md new file mode 100644 index 0000000..8c0173f --- /dev/null +++ b/LLM_Reports/Workflow_Optimization_Report.md @@ -0,0 +1,555 @@ +# Workflow Optimization Report: Hatchling Automated Versioning System + +## Executive Summary + +This report evaluates the current Hatchling workflow architecture, identifies critical issues with infinite loops and complex dependencies, and proposes optimized solutions. The analysis reveals fundamental architectural problems that require immediate attention to prevent system failure. + +## Current Implementation Analysis + +### Workflow Dependency Chain + +**Current Flow**: + +``` +Push to dev/feat/fix → commit_version_tag.yml + ↓ + test_build.yml (reusable) + ↓ + Create PR to main + ↓ + validate-pr-to-main.yml + ↓ + validate-pr-branch-common.yml + ↓ + auto_merge_version_bump.yml + ↓ + Merge to main + ↓ + create_tag_on_main.yml +``` + +### Critical Issues Identified + +#### 1. Infinite Loop Risk (CRITICAL) + +**Problem**: Workflows can trigger each other indefinitely +**Scenarios**: + +- `commit_version_tag.yml` creates PR → triggers validation → triggers auto-merge → merges to main → could trigger `commit_version_tag.yml` again +- Failed auto-merge could retry indefinitely +- Multiple concurrent pushes could create cascading workflows + +**Risk Level**: CRITICAL - System can become completely unusable + +#### 2. Complex Dependency Chain (HIGH) + +**Problem**: 6+ workflows must execute in sequence for single version bump +**Issues**: + +- High failure probability (each step can fail) +- Difficult debugging and troubleshooting +- Long execution time +- Resource waste + +#### 3. Race Conditions (MEDIUM) + +**Problem**: Concurrent pushes can interfere with each other +**Scenarios**: + +- Multiple feature branches pushing simultaneously +- PR creation conflicts +- Version file conflicts + +#### 4. Lack of Atomic Operations (MEDIUM) + +**Problem**: Version updates span multiple commits and workflows +**Issues**: + +- Inconsistent state during failures +- Difficult rollback procedures +- Potential data loss + +## Workflow-by-Workflow Evaluation + +### 1. commit_version_tag.yml + +**Grade**: D +**Issues**: + +- Triggers on too many branches (dev, main, feat/*, fix/*) +- Creates complex PR workflow instead of direct commits +- No loop prevention mechanisms +- Overly complex for simple version updates + +**Strengths**: + +- Uses GitHub App authentication +- Includes proper testing via test_build.yml +- Handles artifact management + +### 2. auto_merge_version_bump.yml + +**Grade**: F +**Issues**: + +- Workflow chaining creates infinite loop risk +- Complex conditional logic prone to errors +- Depends on external workflow completion +- No fail-safe mechanisms + +**Recommendation**: DISABLE IMMEDIATELY + +### 3. validate-pr-to-main.yml & validate-pr-branch-common.yml + +**Grade**: B +**Issues**: + +- Adds unnecessary complexity to simple automation +- Creates additional failure points + +**Strengths**: + +- Well-designed validation logic +- Proper organization membership checks +- Reusable architecture + +### 4. test_build.yml + +**Grade**: A +**Issues**: None significant +**Strengths**: + +- Clean reusable workflow +- Proper artifact handling +- Good separation of concerns + +### 5. create_tag_on_main.yml + +**Grade**: B+ +**Issues**: + +- Relies on commit message parsing (fragile) +- No error handling for tag conflicts + +**Strengths**: + +- Simple and focused +- Proper conditional execution + +## Proposed Optimized Architectures + +### Option 1: Direct Commit Architecture (Recommended) + +**Simplified Flow**: + +``` +Push to dev/feat/fix → Single Workflow: + 1. Run tests + 2. Update version files + 3. Commit directly to branch + 4. Create tag (if main branch) + 5. Create release (if main branch) +``` + +**Implementation**: + +```yaml +name: Automated Versioning +on: + push: + branches: [main, dev, 'feat/*', 'fix/*'] + +jobs: + version-and-release: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + token: ${{ secrets.GITHUB_APP_TOKEN }} + + - name: Setup Python + uses: actions/setup-python@v5 + with: + python-version: '3.12' + + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install build twine + + - name: Run tests + run: python -m pytest tests/ + + - name: Update version + id: version + run: | + VERSION=$(python scripts/version_manager.py --update-for-branch ${{ github.ref_name }}) + echo "version=$VERSION" >> $GITHUB_OUTPUT + echo "Updated to version: $VERSION" + + - name: Build package + run: python -m build + + - name: Test package installation + run: pip install dist/*.whl + + - name: Commit version files + run: | + git config --local user.email "action@github.com" + git config --local user.name "Hatchling Bot" + git add VERSION VERSION.meta + if git diff --staged --quiet; then + echo "No version changes to commit" + else + git commit -m "chore: update version to ${{ steps.version.outputs.version }} [skip ci]" + git push + fi + + - name: Create tag and release (main branch only) + if: github.ref == 'refs/heads/main' + run: | + git tag -a "${{ steps.version.outputs.version }}" -m "Release ${{ steps.version.outputs.version }}" + git push origin "${{ steps.version.outputs.version }}" + + - name: Create GitHub Release (main branch only) + if: github.ref == 'refs/heads/main' + uses: softprops/action-gh-release@v2 + with: + tag_name: ${{ steps.version.outputs.version }} + name: Release ${{ steps.version.outputs.version }} + body: | + Release ${{ steps.version.outputs.version }} + + ## Installation + ```bash + pip install hatchling==${{ steps.version.outputs.version }} + ``` + files: dist/* +``` + +**Benefits**: + +- Single workflow eliminates dependency chains +- Atomic operations reduce failure points +- Direct commits bypass PR complexity +- Built-in loop prevention with [skip ci] +- Faster execution time + +### Option 2: Tag-Based Architecture + +**Flow**: + +``` +Manual tag creation → Workflow: + 1. Validate tag format + 2. Update version files + 3. Build and test + 4. Create release + 5. Publish packages +``` + +**Implementation**: + +```yaml +name: Release on Tag +on: + push: + tags: + - 'v*' + +jobs: + release: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Extract version + id: version + run: | + VERSION=${GITHUB_REF#refs/tags/} + echo "version=$VERSION" >> $GITHUB_OUTPUT + + - name: Update version files + run: | + # Update VERSION files to match tag + echo "${VERSION#v}" > VERSION + # Update VERSION.meta accordingly + + - name: Build and test + run: | + python -m pip install --upgrade pip build + python -m build + pip install dist/*.whl + python -m pytest + + - name: Create Release + uses: softprops/action-gh-release@v2 + with: + files: dist/* +``` + +**Benefits**: + +- Explicit release control +- No automatic triggers +- Simple and predictable +- Easy rollback via tag deletion + +### Option 3: Hybrid Architecture + +**Flow**: + +``` +Push to dev/feat/fix → Update versions only +Manual trigger → Create release from main +``` + +**Benefits**: + +- Automatic version management +- Manual release control +- Reduced complexity +- Better oversight + +## Loop Prevention Strategies + +### 1. Commit Message Filtering + +```yaml +on: + push: + branches: [main, dev] +jobs: + version: + if: "!contains(github.event.head_commit.message, '[skip ci]')" +``` + +### 2. Path-Based Filtering + +```yaml +on: + push: + branches: [main, dev] + paths-ignore: + - 'VERSION' + - 'VERSION.meta' + - '**.md' +``` + +### 3. Actor-Based Filtering + +```yaml +jobs: + version: + if: github.actor != 'github-actions[bot]' +``` + +### 4. Workflow State Checking + +```yaml +- name: Check for concurrent workflows + run: | + RUNNING=$(gh run list --workflow="${{ github.workflow }}" --status=in_progress --json databaseId --jq length) + if [ "$RUNNING" -gt 1 ]; then + echo "Another workflow is running, exiting" + exit 1 + fi +``` + +## Error Handling and Recovery + +### 1. Fail-Safe Mechanisms + +```yaml +- name: Version update with rollback + run: | + # Backup current state + cp VERSION VERSION.backup + cp VERSION.meta VERSION.meta.backup + + # Attempt update + if ! python scripts/version_manager.py --update-for-branch ${{ github.ref_name }}; then + # Restore backup on failure + mv VERSION.backup VERSION + mv VERSION.meta.backup VERSION.meta + exit 1 + fi + + # Clean up backup on success + rm -f VERSION.backup VERSION.meta.backup +``` + +### 2. Retry Logic + +```yaml +- name: Push with retry + uses: nick-fields/retry@v3 + with: + timeout_minutes: 5 + max_attempts: 3 + command: git push +``` + +### 3. Notification on Failure + +```yaml +- name: Notify on failure + if: failure() + uses: actions/github-script@v7 + with: + script: | + github.rest.issues.create({ + owner: context.repo.owner, + repo: context.repo.repo, + title: 'Automated versioning failed', + body: `Workflow failed: ${context.runId}` + }) +``` + +## Alternative Triggering Mechanisms + +### 1. Manual Workflow Dispatch + +```yaml +on: + workflow_dispatch: + inputs: + version_type: + description: 'Version increment type' + required: true + default: 'patch' + type: choice + options: + - major + - minor + - patch + - dev + - build +``` + +### 2. Issue-Based Triggers + +```yaml +on: + issues: + types: [opened] + +jobs: + release: + if: contains(github.event.issue.title, '[RELEASE]') +``` + +### 3. Schedule-Based Releases + +```yaml +on: + schedule: + - cron: '0 9 * * 1' # Weekly releases on Monday +``` + +### 4. External Webhook Triggers + +```yaml +on: + repository_dispatch: + types: [release-request] +``` + +## Performance Optimization + +### 1. Parallel Execution + +```yaml +jobs: + test: + strategy: + matrix: + python-version: [3.11, 3.12] + runs-on: ubuntu-latest + + version: + needs: test + runs-on: ubuntu-latest +``` + +### 2. Caching + +```yaml +- name: Cache dependencies + uses: actions/cache@v4 + with: + path: ~/.cache/pip + key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements.txt') }} +``` + +### 3. Conditional Execution + +```yaml +- name: Skip if no changes + id: changes + run: | + if git diff --quiet HEAD~1 -- scripts/ hatchling/; then + echo "skip=true" >> $GITHUB_OUTPUT + fi + +- name: Run tests + if: steps.changes.outputs.skip != 'true' + run: python -m pytest +``` + +## Implementation Grades and Recommendations + +### Current Implementation: D- + +**Issues**: + +- Critical infinite loop risk +- Overly complex architecture +- Multiple failure points +- Poor error handling + +### Recommended Implementation: A- + +**Option 1 (Direct Commit)**: + +- Simple and reliable +- Atomic operations +- Built-in loop prevention +- Fast execution +- Easy debugging + +### Migration Strategy + +#### Phase 1: Immediate (Week 1) + +1. **DISABLE** `auto_merge_version_bump.yml` +2. **MODIFY** `commit_version_tag.yml` to add loop prevention +3. **ADD** proper error handling + +#### Phase 2: Short-term (Week 2-3) + +1. **IMPLEMENT** Option 1 (Direct Commit Architecture) +2. **TEST** thoroughly in development environment +3. **MIGRATE** gradually (one branch at a time) + +#### Phase 3: Long-term (Month 2) + +1. **REMOVE** deprecated workflows +2. **OPTIMIZE** performance +3. **ADD** comprehensive monitoring + +## Conclusion + +The current Hatchling workflow architecture suffers from critical design flaws that pose immediate risks to system stability. The complex dependency chain and infinite loop potential require urgent remediation. + +**Immediate Actions Required**: + +1. Disable auto-merge workflow to prevent infinite loops +2. Implement loop prevention in existing workflows +3. Plan migration to simplified architecture + +**Recommended Solution**: Direct Commit Architecture (Option 1) provides the best balance of simplicity, reliability, and functionality while maintaining all required features. + +**Overall Grade**: Current (D-) → Recommended (A-) +**Priority**: URGENT - System stability at immediate risk diff --git a/README.md b/README.md index 03d16d4..3c3e690 100644 --- a/README.md +++ b/README.md @@ -135,4 +135,30 @@ These repositories work together to provide a comprehensive framework for creati ## Contributing -Checkout the [guides](./docs/articles/table_of_contents.md#contributing) \ No newline at end of file +We welcome contributions! Please see our [Contributing Guide](./CONTRIBUTING.md) for details. + +### Quick Start + +1. **Fork and clone** the repository +2. **Install dependencies**: `pip install -e .` and `npm install` +3. **Create a feature branch**: `git checkout -b feat/your-feature` +4. **Make changes** and add tests +5. **Use conventional commits**: `npm run commit` for guided commits +6. **Run tests**: `python run_tests.py --regression --feature` +7. **Create a pull request** + +### Commit Messages + +We use [Conventional Commits](https://www.conventionalcommits.org/) for automated versioning: + +```bash +feat: add new feature +fix: resolve bug +docs: update documentation +test: add tests +chore: maintenance tasks +``` + +Use `npm run commit` for guided commit messages. + +For detailed guidelines, see [CONTRIBUTING.md](./CONTRIBUTING.md) and [versioning docs](./docs/articles/devs/versioning.md). \ No newline at end of file diff --git a/VERSION b/VERSION deleted file mode 100644 index e5c326a..0000000 --- a/VERSION +++ /dev/null @@ -1 +0,0 @@ -0.4.2.dev27 \ No newline at end of file diff --git a/VERSION.meta b/VERSION.meta deleted file mode 100644 index 2e6ed7e..0000000 --- a/VERSION.meta +++ /dev/null @@ -1,10 +0,0 @@ -# Structured version file for human readability and CI/CD -# This file maintains detailed version component information -# The companion VERSION file contains the simple format for setuptools - -MAJOR=0 -MINOR=4 -PATCH=2 -DEV_NUMBER=27 -BUILD_NUMBER= -BRANCH=dev diff --git a/docs/articles/devs/versioning.md b/docs/articles/devs/versioning.md index b75f814..570393e 100644 --- a/docs/articles/devs/versioning.md +++ b/docs/articles/devs/versioning.md @@ -1,251 +1,186 @@ -# Automated Versioning System +# Automated Versioning with Semantic Release -This article is about: +Hatchling uses [semantic-release](https://semantic-release.gitbook.io/) for fully automated versioning and releases based on [Conventional Commits](https://www.conventionalcommits.org/). -- The dual-file versioning system in Hatchling -- How version information is managed for both humans and tools +## How It Works -Hatchling uses a dual-file versioning system to maintain both human-readable version information and compatibility with Python packaging tools. +1. **Commit Analysis**: Analyzes commit messages to determine release type +2. **Version Calculation**: Automatically calculates next version +3. **Changelog Generation**: Creates release notes from commits +4. **GitHub Release**: Publishes release with generated notes +5. **Version Update**: Updates pyproject.toml with new version -## Dual-File Versioning System +## Commit Message Format -### Files +Use [Conventional Commits](https://www.conventionalcommits.org/) format: -#### VERSION.meta +```txt +[optional scope]: -- Human-readable, structured version information for CI/CD and development -- Format: Key-value pairs with comments -- Example: +[optional body] - ```txt - MAJOR=0 - MINOR=5 - PATCH=0 - DEV_NUMBER=0 - BUILD_NUMBER=1 - BRANCH=feat/automated-versioning - ``` +[optional footer(s)] +``` -#### VERSION +### Examples -- Simple version string for setuptools and Python packaging -- Format: Standard semantic version string -- Example: `0.5.0.dev0+build1` +```bash +feat: add new LLM provider support +fix: resolve memory leak in streaming +docs: update API documentation +refactor: simplify provider registry +test: add integration tests for OpenAI +chore: update dependencies + +# Breaking changes (avoid until ready for v1.0.0) +feat!: change configuration format +``` -### Benefits +### Version Impact -1. **Human Readability**: `VERSION.meta` provides clear, structured version information -2. **Tool Compatibility**: `VERSION` maintains standard format for setuptools and other tools -3. **Build Metadata**: Preserves branch, build number, and dev version information -4. **CI/CD Integration**: Both files are automatically maintained by version management workflows +- `feat:` → Minor version (0.4.0 → 0.5.0) +- `fix:` → Patch version (0.4.0 → 0.4.1) +- `feat!:` or `BREAKING CHANGE:` → Major version (0.4.0 → 1.0.0) +- `docs:`, `test:`, `chore:` → No release -## Usage +## Using Commitizen -### Branch-based Versioning Logic +For guided commit messages: -- **Feature branches (`feat/`)**: - - If created from `main`, minor version is incremented, and both `DEV_NUMBER` and `BUILD_NUMBER` are reset to 0. - - If updating an existing feature branch, only the `BUILD_NUMBER` is incremented. -- **Fix branches (`fix/`)**: - - If created from any branch, patch version is incremented and `BUILD_NUMBER` is reset to 0. - - If updating the same fix branch, only the `BUILD_NUMBER` is incremented. - - If switching between fix branches, patch version is incremented. -- **Main branch (`main`)**: - - `DEV_NUMBER` and `BUILD_NUMBER` are cleared for clean releases. -- **Dev/other branches**: - - If coming from `main`, the minor version is incremented and `DEV_NUMBER` is reset to 0. - - Otherwise, `DEV_NUMBER` is incremented and `BUILD_NUMBER` is reset. +```bash +npm run commit +# or +npx cz +``` -### Workflow Examples +## Branches -#### Example 1: Feature Development +- **main**: Production releases (0.4.0, 0.5.0, etc.) +- **dev**: Pre-releases (0.5.0-dev.1, 0.5.0-dev.2, etc.) -1. **Starting State**: `main` branch at `v1.2.0` -2. **Create Feature Branch**: `git checkout -b feat/new-feature` - - Minor version is incremented: `v1.3.0.dev0+build0` -3. **First Push**: Increments to `v1.3.0.dev0+build1` -4. **Second Push**: Increments to `v1.3.0.dev0+build2` -5. **Merge to Dev**: `dev` branch becomes `v1.3.0.devN` -6. **Merge to Main**: `main` branch becomes `v1.3.0` +## Manual Testing -#### Example 2: Bug Fix +Test semantic-release configuration: -1. **Starting State**: `main` branch at `v1.2.0` -2. **Create Fix Branch**: `git checkout -b fix/critical-bug` - - Patch version is incremented: `v1.2.1.dev0+build0` -3. **First Push**: Increments to `v1.2.1.dev0+build1` -4. **Switch to another fix branch**: Patch version is incremented for the new branch. -5. **Merge to Dev**: `dev` branch becomes `v1.2.1.devN` -6. **Hotfix to Main**: `main` branch becomes `v1.2.1` +```bash +npx semantic-release --dry-run +``` ## GitHub Actions Workflows -### 1. Release Workflow (`release.yml`) +### 1. Semantic Release Workflow (`semantic-release.yml`) -**Triggered by**: Pushes to `main` branch +**Triggered by**: Pushes to `main` and `dev` branches **Actions**: -- Tests the package build -- Updates version for main branch (removes pre-release suffixes) -- Creates official release with version tag -- Uploads build artifacts -- Commits updated VERSION file +- Runs tests to ensure code quality +- Analyzes commits since last release +- Calculates next version based on commit types +- Generates changelog from commit messages +- Creates GitHub release with generated notes +- Updates pyproject.toml with new version +- Commits version changes back to repository -### 2. Pre-Release Workflow (`prerelease.yml`) +### 2. Commit Lint Workflow (`commitlint.yml`) -**Triggered by**: Pushes to `dev` branch +**Triggered by**: Pull requests to `main` and `dev` branches **Actions**: -- Tests the package build -- Updates version for dev branch (adds `-dev` suffix) -- Creates pre-release with version tag -- Uploads build artifacts -- Commits updated VERSION file +- Validates commit messages follow Conventional Commits format +- Ensures proper commit types and formatting +- Provides feedback on commit message issues -### 3. Feature/Fix Workflow (`feature-fix.yml`) +## Configuration Files -**Triggered by**: Pushes to `feat/` and `fix/` branches +### .releaserc.json -**Actions**: +Contains semantic-release configuration: -- Tests the package build -- Updates version based on branch type -- Increments build number on each push -- Creates lightweight tags for tracking -- Commits updated VERSION file +- Branch configuration for main and dev +- Plugin configuration for commit analysis +- Changelog and release note generation +- GitHub integration settings -### 4. Tag Cleanup Workflow (`tag-cleanup.yml`) +### .commitlintrc.json -**Triggered by**: Weekly schedule or manual dispatch +Contains commit message linting rules: -**Actions**: +- Enforces Conventional Commits format +- Validates commit types and structure +- Ensures consistent commit message style -- Identifies old tags for cleanup -- Removes build tags older than 7 days -- Removes dev tags older than 30 days -- Supports dry-run mode for testing +### package.json -## Manual Version Management +Contains Node.js dependencies for semantic-release: -The `scripts/version_manager.py` script provides manual control over versioning: +- semantic-release and plugins +- commitizen for guided commits +- commitlint for validation -### Get Current Version +## Best Practices -```bash -python scripts/version_manager.py --get -``` +1. **Use Conventional Commits** for all commit messages +2. **Use commitizen** (`npm run commit`) for guided commits +3. **Test changes** before merging to main or dev +4. **Avoid breaking changes** until ready for v1.0.0 +5. **Use descriptive commit messages** that explain the change +6. **Squash merge** PRs to maintain clean commit history -### Update Version for Branch +## Troubleshooting -```bash -python scripts/version_manager.py --update-for-branch feat/my-feature -python scripts/version_manager.py --update-for-branch dev -python scripts/version_manager.py --update-for-branch main -``` +### Commit Message Issues -### Increment Version Components +If commits don't follow the conventional format: ```bash -python scripts/version_manager.py --increment major -python scripts/version_manager.py --increment minor -python scripts/version_manager.py --increment patch -python scripts/version_manager.py --increment build -``` - -### Prepare for Building +# Use commitizen for guided commits +npm run commit -```bash -python scripts/prepare_version.py +# Or manually format commits +git commit -m "feat: add new feature description" ``` -This converts the structured VERSION file to a simple format that setuptools can read. - -## Integration with setuptools - -The `pyproject.toml` file is configured to read the version from the VERSION file: - -```toml -[tool.setuptools.dynamic] -version = {file = "VERSION"} -``` +### Testing Configuration -Before building, the `prepare_version.py` script converts the structured VERSION file to a simple format that setuptools understands. - -## Testing - -Run the versioning system tests: +Validate semantic-release setup: ```bash -python tests/test_versioning.py -``` - -This validates: - -- Version string generation -- Branch-based version updates -- Build number increments -- The examples from the project requirements - -## Best Practices - -1. **Never manually edit version numbers** - let the automation handle it -2. **Use descriptive branch names** with proper prefixes (`feat/`, `fix/`) -3. **Test in feature branches** before merging to dev -4. **Use dev branch** for integration testing before production -5. **Keep main branch stable** - only merge tested code from dev -6. **Monitor tag cleanup** to avoid repository bloat - -## Troubleshooting +# Test configuration without making changes +npx semantic-release --dry-run -### VERSION File Format Issues - -If the version files get corrupted, restore them as follows: - -- For the structured format, restore `VERSION.meta` with: - - ```txt - MAJOR=1 - MINOR=0 - PATCH=0 - DEV_NUMBER=0 - BUILD_NUMBER=0 - BRANCH=main - ``` +# Validate commit messages +echo "feat: test commit" | npx commitlint +``` -- For the simple format, regenerate `VERSION` by running: +### Release Issues - ```bash - python scripts/prepare_version.py - ``` +If releases fail: - This will convert the structured `VERSION.meta` to the correct setuptools-compatible `VERSION` file. +1. Check commit message format +2. Ensure branch is configured in .releaserc.json +3. Verify GitHub token permissions +4. Check workflow logs in GitHub Actions -### Build Failures +### Manual Release -If builds fail due to version format: +In emergency situations, create manual release: ```bash -python scripts/prepare_version.py -``` +# Create and push a tag manually +git tag v0.4.1 +git push origin v0.4.1 -### Testing Version Logic - -Run the test suite to verify versioning logic: - -```bash -python tests/test_versioning.py +# Then create GitHub release manually ``` -### Manual Tag Creation +## Testing -If GitHub Actions fail, manually create tags: +Run the test suite to ensure everything works: ```bash -# Ensure VERSION is up to date with VERSION.meta -python scripts/prepare_version.py -VERSION=$(python scripts/version_manager.py --get) -git tag $VERSION -git push origin $VERSION +python run_tests.py --regression --feature ``` + +This validates that the new versioning system doesn't break existing functionality. diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..00e26de --- /dev/null +++ b/package-lock.json @@ -0,0 +1,8790 @@ +{ + "name": "hatchling", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "hatchling", + "devDependencies": { + "@commitlint/cli": "^18.6.1", + "@commitlint/config-conventional": "^18.6.2", + "@semantic-release/changelog": "^6.0.3", + "@semantic-release/git": "^10.0.1", + "@semantic-release/github": "^9.2.6", + "commitizen": "^4.3.0", + "cz-conventional-changelog": "^3.3.0", + "semantic-release": "^22.0.12" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.27.1.tgz", + "integrity": "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-validator-identifier": "^7.27.1", + "js-tokens": "^4.0.0", + "picocolors": "^1.1.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.27.1.tgz", + "integrity": "sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@colors/colors": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz", + "integrity": "sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=0.1.90" + } + }, + "node_modules/@commitlint/cli": { + "version": "18.6.1", + "resolved": "https://registry.npmjs.org/@commitlint/cli/-/cli-18.6.1.tgz", + "integrity": "sha512-5IDE0a+lWGdkOvKH892HHAZgbAjcj1mT5QrfA/SVbLJV/BbBMGyKN0W5mhgjekPJJwEQdVNvhl9PwUacY58Usw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@commitlint/format": "^18.6.1", + "@commitlint/lint": "^18.6.1", + "@commitlint/load": "^18.6.1", + "@commitlint/read": "^18.6.1", + "@commitlint/types": "^18.6.1", + "execa": "^5.0.0", + "lodash.isfunction": "^3.0.9", + "resolve-from": "5.0.0", + "resolve-global": "1.0.0", + "yargs": "^17.0.0" + }, + "bin": { + "commitlint": "cli.js" + }, + "engines": { + "node": ">=v18" + } + }, + "node_modules/@commitlint/config-conventional": { + "version": "18.6.3", + "resolved": "https://registry.npmjs.org/@commitlint/config-conventional/-/config-conventional-18.6.3.tgz", + "integrity": "sha512-8ZrRHqF6je+TRaFoJVwszwnOXb/VeYrPmTwPhf0WxpzpGTcYy1p0SPyZ2eRn/sRi/obnWAcobtDAq6+gJQQNhQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@commitlint/types": "^18.6.1", + "conventional-changelog-conventionalcommits": "^7.0.2" + }, + "engines": { + "node": ">=v18" + } + }, + "node_modules/@commitlint/config-validator": { + "version": "18.6.1", + "resolved": "https://registry.npmjs.org/@commitlint/config-validator/-/config-validator-18.6.1.tgz", + "integrity": "sha512-05uiToBVfPhepcQWE1ZQBR/Io3+tb3gEotZjnI4tTzzPk16NffN6YABgwFQCLmzZefbDcmwWqJWc2XT47q7Znw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@commitlint/types": "^18.6.1", + "ajv": "^8.11.0" + }, + "engines": { + "node": ">=v18" + } + }, + "node_modules/@commitlint/ensure": { + "version": "18.6.1", + "resolved": "https://registry.npmjs.org/@commitlint/ensure/-/ensure-18.6.1.tgz", + "integrity": "sha512-BPm6+SspyxQ7ZTsZwXc7TRQL5kh5YWt3euKmEIBZnocMFkJevqs3fbLRb8+8I/cfbVcAo4mxRlpTPfz8zX7SnQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@commitlint/types": "^18.6.1", + "lodash.camelcase": "^4.3.0", + "lodash.kebabcase": "^4.1.1", + "lodash.snakecase": "^4.1.1", + "lodash.startcase": "^4.4.0", + "lodash.upperfirst": "^4.3.1" + }, + "engines": { + "node": ">=v18" + } + }, + "node_modules/@commitlint/execute-rule": { + "version": "18.6.1", + "resolved": "https://registry.npmjs.org/@commitlint/execute-rule/-/execute-rule-18.6.1.tgz", + "integrity": "sha512-7s37a+iWyJiGUeMFF6qBlyZciUkF8odSAnHijbD36YDctLhGKoYltdvuJ/AFfRm6cBLRtRk9cCVPdsEFtt/2rg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=v18" + } + }, + "node_modules/@commitlint/format": { + "version": "18.6.1", + "resolved": "https://registry.npmjs.org/@commitlint/format/-/format-18.6.1.tgz", + "integrity": "sha512-K8mNcfU/JEFCharj2xVjxGSF+My+FbUHoqR+4GqPGrHNqXOGNio47ziiR4HQUPKtiNs05o8/WyLBoIpMVOP7wg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@commitlint/types": "^18.6.1", + "chalk": "^4.1.0" + }, + "engines": { + "node": ">=v18" + } + }, + "node_modules/@commitlint/is-ignored": { + "version": "18.6.1", + "resolved": "https://registry.npmjs.org/@commitlint/is-ignored/-/is-ignored-18.6.1.tgz", + "integrity": "sha512-MOfJjkEJj/wOaPBw5jFjTtfnx72RGwqYIROABudOtJKW7isVjFe9j0t8xhceA02QebtYf4P/zea4HIwnXg8rvA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@commitlint/types": "^18.6.1", + "semver": "7.6.0" + }, + "engines": { + "node": ">=v18" + } + }, + "node_modules/@commitlint/lint": { + "version": "18.6.1", + "resolved": "https://registry.npmjs.org/@commitlint/lint/-/lint-18.6.1.tgz", + "integrity": "sha512-8WwIFo3jAuU+h1PkYe5SfnIOzp+TtBHpFr4S8oJWhu44IWKuVx6GOPux3+9H1iHOan/rGBaiacicZkMZuluhfQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@commitlint/is-ignored": "^18.6.1", + "@commitlint/parse": "^18.6.1", + "@commitlint/rules": "^18.6.1", + "@commitlint/types": "^18.6.1" + }, + "engines": { + "node": ">=v18" + } + }, + "node_modules/@commitlint/load": { + "version": "18.6.1", + "resolved": "https://registry.npmjs.org/@commitlint/load/-/load-18.6.1.tgz", + "integrity": "sha512-p26x8734tSXUHoAw0ERIiHyW4RaI4Bj99D8YgUlVV9SedLf8hlWAfyIFhHRIhfPngLlCe0QYOdRKYFt8gy56TA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@commitlint/config-validator": "^18.6.1", + "@commitlint/execute-rule": "^18.6.1", + "@commitlint/resolve-extends": "^18.6.1", + "@commitlint/types": "^18.6.1", + "chalk": "^4.1.0", + "cosmiconfig": "^8.3.6", + "cosmiconfig-typescript-loader": "^5.0.0", + "lodash.isplainobject": "^4.0.6", + "lodash.merge": "^4.6.2", + "lodash.uniq": "^4.5.0", + "resolve-from": "^5.0.0" + }, + "engines": { + "node": ">=v18" + } + }, + "node_modules/@commitlint/message": { + "version": "18.6.1", + "resolved": "https://registry.npmjs.org/@commitlint/message/-/message-18.6.1.tgz", + "integrity": "sha512-VKC10UTMLcpVjMIaHHsY1KwhuTQtdIKPkIdVEwWV+YuzKkzhlI3aNy6oo1eAN6b/D2LTtZkJe2enHmX0corYRw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=v18" + } + }, + "node_modules/@commitlint/parse": { + "version": "18.6.1", + "resolved": "https://registry.npmjs.org/@commitlint/parse/-/parse-18.6.1.tgz", + "integrity": "sha512-eS/3GREtvVJqGZrwAGRwR9Gdno3YcZ6Xvuaa+vUF8j++wsmxrA2En3n0ccfVO2qVOLJC41ni7jSZhQiJpMPGOQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@commitlint/types": "^18.6.1", + "conventional-changelog-angular": "^7.0.0", + "conventional-commits-parser": "^5.0.0" + }, + "engines": { + "node": ">=v18" + } + }, + "node_modules/@commitlint/read": { + "version": "18.6.1", + "resolved": "https://registry.npmjs.org/@commitlint/read/-/read-18.6.1.tgz", + "integrity": "sha512-ia6ODaQFzXrVul07ffSgbZGFajpe8xhnDeLIprLeyfz3ivQU1dIoHp7yz0QIorZ6yuf4nlzg4ZUkluDrGN/J/w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@commitlint/top-level": "^18.6.1", + "@commitlint/types": "^18.6.1", + "git-raw-commits": "^2.0.11", + "minimist": "^1.2.6" + }, + "engines": { + "node": ">=v18" + } + }, + "node_modules/@commitlint/resolve-extends": { + "version": "18.6.1", + "resolved": "https://registry.npmjs.org/@commitlint/resolve-extends/-/resolve-extends-18.6.1.tgz", + "integrity": "sha512-ifRAQtHwK+Gj3Bxj/5chhc4L2LIc3s30lpsyW67yyjsETR6ctHAHRu1FSpt0KqahK5xESqoJ92v6XxoDRtjwEQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@commitlint/config-validator": "^18.6.1", + "@commitlint/types": "^18.6.1", + "import-fresh": "^3.0.0", + "lodash.mergewith": "^4.6.2", + "resolve-from": "^5.0.0", + "resolve-global": "^1.0.0" + }, + "engines": { + "node": ">=v18" + } + }, + "node_modules/@commitlint/rules": { + "version": "18.6.1", + "resolved": "https://registry.npmjs.org/@commitlint/rules/-/rules-18.6.1.tgz", + "integrity": "sha512-kguM6HxZDtz60v/zQYOe0voAtTdGybWXefA1iidjWYmyUUspO1zBPQEmJZ05/plIAqCVyNUTAiRPWIBKLCrGew==", + "dev": true, + "license": "MIT", + "dependencies": { + "@commitlint/ensure": "^18.6.1", + "@commitlint/message": "^18.6.1", + "@commitlint/to-lines": "^18.6.1", + "@commitlint/types": "^18.6.1", + "execa": "^5.0.0" + }, + "engines": { + "node": ">=v18" + } + }, + "node_modules/@commitlint/to-lines": { + "version": "18.6.1", + "resolved": "https://registry.npmjs.org/@commitlint/to-lines/-/to-lines-18.6.1.tgz", + "integrity": "sha512-Gl+orGBxYSNphx1+83GYeNy5N0dQsHBQ9PJMriaLQDB51UQHCVLBT/HBdOx5VaYksivSf5Os55TLePbRLlW50Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=v18" + } + }, + "node_modules/@commitlint/top-level": { + "version": "18.6.1", + "resolved": "https://registry.npmjs.org/@commitlint/top-level/-/top-level-18.6.1.tgz", + "integrity": "sha512-HyiHQZUTf0+r0goTCDs/bbVv/LiiQ7AVtz6KIar+8ZrseB9+YJAIo8HQ2IC2QT1y3N1lbW6OqVEsTHjbT6hGSw==", + "dev": true, + "license": "MIT", + "dependencies": { + "find-up": "^5.0.0" + }, + "engines": { + "node": ">=v18" + } + }, + "node_modules/@commitlint/types": { + "version": "18.6.1", + "resolved": "https://registry.npmjs.org/@commitlint/types/-/types-18.6.1.tgz", + "integrity": "sha512-gwRLBLra/Dozj2OywopeuHj2ac26gjGkz2cZ+86cTJOdtWfiRRr4+e77ZDAGc6MDWxaWheI+mAV5TLWWRwqrFg==", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^4.1.0" + }, + "engines": { + "node": ">=v18" + } + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@octokit/auth-token": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-4.0.0.tgz", + "integrity": "sha512-tY/msAuJo6ARbK6SPIxZrPBms3xPbfwBrulZe0Wtr/DIY9lje2HeV1uoebShn6mx7SjCHif6EjMvoREj+gZ+SA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 18" + } + }, + "node_modules/@octokit/core": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/@octokit/core/-/core-5.2.2.tgz", + "integrity": "sha512-/g2d4sW9nUDJOMz3mabVQvOGhVa4e/BN/Um7yca9Bb2XTzPPnfTWHWQg+IsEYO7M3Vx+EXvaM/I2pJWIMun1bg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@octokit/auth-token": "^4.0.0", + "@octokit/graphql": "^7.1.0", + "@octokit/request": "^8.4.1", + "@octokit/request-error": "^5.1.1", + "@octokit/types": "^13.0.0", + "before-after-hook": "^2.2.0", + "universal-user-agent": "^6.0.0" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/@octokit/endpoint": { + "version": "9.0.6", + "resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-9.0.6.tgz", + "integrity": "sha512-H1fNTMA57HbkFESSt3Y9+FBICv+0jFceJFPWDePYlR/iMGrwM5ph+Dd4XRQs+8X+PUFURLQgX9ChPfhJ/1uNQw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@octokit/types": "^13.1.0", + "universal-user-agent": "^6.0.0" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/@octokit/graphql": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-7.1.1.tgz", + "integrity": "sha512-3mkDltSfcDUoa176nlGoA32RGjeWjl3K7F/BwHwRMJUW/IteSa4bnSV8p2ThNkcIcZU2umkZWxwETSSCJf2Q7g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@octokit/request": "^8.4.1", + "@octokit/types": "^13.0.0", + "universal-user-agent": "^6.0.0" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/@octokit/openapi-types": { + "version": "24.2.0", + "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-24.2.0.tgz", + "integrity": "sha512-9sIH3nSUttelJSXUrmGzl7QUBFul0/mB8HRYl3fOlgHbIWG+WnYDXU3v/2zMtAvuzZ/ed00Ei6on975FhBfzrg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@octokit/plugin-paginate-rest": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-9.2.2.tgz", + "integrity": "sha512-u3KYkGF7GcZnSD/3UP0S7K5XUFT2FkOQdcfXZGZQPGv3lm4F2Xbf71lvjldr8c1H3nNbF+33cLEkWYbokGWqiQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@octokit/types": "^12.6.0" + }, + "engines": { + "node": ">= 18" + }, + "peerDependencies": { + "@octokit/core": "5" + } + }, + "node_modules/@octokit/plugin-paginate-rest/node_modules/@octokit/openapi-types": { + "version": "20.0.0", + "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-20.0.0.tgz", + "integrity": "sha512-EtqRBEjp1dL/15V7WiX5LJMIxxkdiGJnabzYx5Apx4FkQIFgAfKumXeYAqqJCj1s+BMX4cPFIFC4OLCR6stlnA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@octokit/plugin-paginate-rest/node_modules/@octokit/types": { + "version": "12.6.0", + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-12.6.0.tgz", + "integrity": "sha512-1rhSOfRa6H9w4YwK0yrf5faDaDTb+yLyBUKOCV4xtCDB5VmIPqd/v9yr9o6SAzOAlRxMiRiCic6JVM1/kunVkw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@octokit/openapi-types": "^20.0.0" + } + }, + "node_modules/@octokit/plugin-retry": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/@octokit/plugin-retry/-/plugin-retry-6.1.0.tgz", + "integrity": "sha512-WrO3bvq4E1Xh1r2mT9w6SDFg01gFmP81nIG77+p/MqW1JeXXgL++6umim3t6x0Zj5pZm3rXAN+0HEjmmdhIRig==", + "dev": true, + "license": "MIT", + "dependencies": { + "@octokit/request-error": "^5.0.0", + "@octokit/types": "^13.0.0", + "bottleneck": "^2.15.3" + }, + "engines": { + "node": ">= 18" + }, + "peerDependencies": { + "@octokit/core": "5" + } + }, + "node_modules/@octokit/plugin-throttling": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/@octokit/plugin-throttling/-/plugin-throttling-8.2.0.tgz", + "integrity": "sha512-nOpWtLayKFpgqmgD0y3GqXafMFuKcA4tRPZIfu7BArd2lEZeb1988nhWhwx4aZWmjDmUfdgVf7W+Tt4AmvRmMQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@octokit/types": "^12.2.0", + "bottleneck": "^2.15.3" + }, + "engines": { + "node": ">= 18" + }, + "peerDependencies": { + "@octokit/core": "^5.0.0" + } + }, + "node_modules/@octokit/plugin-throttling/node_modules/@octokit/openapi-types": { + "version": "20.0.0", + "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-20.0.0.tgz", + "integrity": "sha512-EtqRBEjp1dL/15V7WiX5LJMIxxkdiGJnabzYx5Apx4FkQIFgAfKumXeYAqqJCj1s+BMX4cPFIFC4OLCR6stlnA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@octokit/plugin-throttling/node_modules/@octokit/types": { + "version": "12.6.0", + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-12.6.0.tgz", + "integrity": "sha512-1rhSOfRa6H9w4YwK0yrf5faDaDTb+yLyBUKOCV4xtCDB5VmIPqd/v9yr9o6SAzOAlRxMiRiCic6JVM1/kunVkw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@octokit/openapi-types": "^20.0.0" + } + }, + "node_modules/@octokit/request": { + "version": "8.4.1", + "resolved": "https://registry.npmjs.org/@octokit/request/-/request-8.4.1.tgz", + "integrity": "sha512-qnB2+SY3hkCmBxZsR/MPCybNmbJe4KAlfWErXq+rBKkQJlbjdJeS85VI9r8UqeLYLvnAenU8Q1okM/0MBsAGXw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@octokit/endpoint": "^9.0.6", + "@octokit/request-error": "^5.1.1", + "@octokit/types": "^13.1.0", + "universal-user-agent": "^6.0.0" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/@octokit/request-error": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-5.1.1.tgz", + "integrity": "sha512-v9iyEQJH6ZntoENr9/yXxjuezh4My67CBSu9r6Ve/05Iu5gNgnisNWOsoJHTP6k0Rr0+HQIpnH+kyammu90q/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@octokit/types": "^13.1.0", + "deprecation": "^2.0.0", + "once": "^1.4.0" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/@octokit/types": { + "version": "13.10.0", + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-13.10.0.tgz", + "integrity": "sha512-ifLaO34EbbPj0Xgro4G5lP5asESjwHracYJvVaPIyXMuiuXLlhic3S47cBdTb+jfODkTE5YtGCLt3Ay3+J97sA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@octokit/openapi-types": "^24.2.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==", + "dev": true, + "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==", + "dev": true, + "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==", + "dev": true, + "license": "ISC" + }, + "node_modules/@pnpm/npm-conf": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/@pnpm/npm-conf/-/npm-conf-2.3.1.tgz", + "integrity": "sha512-c83qWb22rNRuB0UaVCI0uRPNRr8Z0FWnEIvT47jiHAmOIUHbBOg5XvV7pM5x+rKn9HRpjxquDbXYSXr3fAKFcw==", + "dev": true, + "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/@semantic-release/changelog": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/@semantic-release/changelog/-/changelog-6.0.3.tgz", + "integrity": "sha512-dZuR5qByyfe3Y03TpmCvAxCyTnp7r5XwtHRf/8vD9EAn4ZWbavUX8adMtXYzE86EVh0gyLA7lm5yW4IV30XUag==", + "dev": true, + "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/commit-analyzer": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/@semantic-release/commit-analyzer/-/commit-analyzer-11.1.0.tgz", + "integrity": "sha512-cXNTbv3nXR2hlzHjAMgbuiQVtvWHTlwwISt60B+4NZv01y/QRY7p2HcJm8Eh2StzcTJoNnflvKjHH/cjFS7d5g==", + "dev": true, + "license": "MIT", + "dependencies": { + "conventional-changelog-angular": "^7.0.0", + "conventional-commits-filter": "^4.0.0", + "conventional-commits-parser": "^5.0.0", + "debug": "^4.0.0", + "import-from-esm": "^1.0.3", + "lodash-es": "^4.17.21", + "micromatch": "^4.0.2" + }, + "engines": { + "node": "^18.17 || >=20.6.1" + }, + "peerDependencies": { + "semantic-release": ">=20.1.0" + } + }, + "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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.17" + } + }, + "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==", + "dev": true, + "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/github": { + "version": "9.2.6", + "resolved": "https://registry.npmjs.org/@semantic-release/github/-/github-9.2.6.tgz", + "integrity": "sha512-shi+Lrf6exeNZF+sBhK+P011LSbhmIAoUEgEY6SsxF8irJ+J2stwI5jkyDQ+4gzYyDImzV6LCKdYB9FXnQRWKA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@octokit/core": "^5.0.0", + "@octokit/plugin-paginate-rest": "^9.0.0", + "@octokit/plugin-retry": "^6.0.0", + "@octokit/plugin-throttling": "^8.0.0", + "@semantic-release/error": "^4.0.0", + "aggregate-error": "^5.0.0", + "debug": "^4.3.4", + "dir-glob": "^3.0.1", + "globby": "^14.0.0", + "http-proxy-agent": "^7.0.0", + "https-proxy-agent": "^7.0.0", + "issue-parser": "^6.0.0", + "lodash-es": "^4.17.21", + "mime": "^4.0.0", + "p-filter": "^4.0.0", + "url-join": "^5.0.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "semantic-release": ">=20.1.0" + } + }, + "node_modules/@semantic-release/github/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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/@semantic-release/github/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==", + "dev": true, + "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/@semantic-release/github/node_modules/clean-stack": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-5.2.0.tgz", + "integrity": "sha512-TyUIUJgdFnCISzG5zu3291TAsE77ddchd0bepon1VVQrKLGKFED4iXFEDQ24mIPdPBbyE16PK3F8MYE1CmcBEQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "escape-string-regexp": "5.0.0" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@semantic-release/github/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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@semantic-release/github/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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@semantic-release/npm": { + "version": "11.0.3", + "resolved": "https://registry.npmjs.org/@semantic-release/npm/-/npm-11.0.3.tgz", + "integrity": "sha512-KUsozQGhRBAnoVg4UMZj9ep436VEGwT536/jwSqB7vcEfA6oncCUU7UIYTRdLx7GvTtqn0kBjnkfLVkcnBa2YQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@semantic-release/error": "^4.0.0", + "aggregate-error": "^5.0.0", + "execa": "^8.0.0", + "fs-extra": "^11.0.0", + "lodash-es": "^4.17.21", + "nerf-dart": "^1.0.0", + "normalize-url": "^8.0.0", + "npm": "^10.5.0", + "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": "^18.17 || >=20" + }, + "peerDependencies": { + "semantic-release": ">=20.1.0" + } + }, + "node_modules/@semantic-release/npm/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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/@semantic-release/npm/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==", + "dev": true, + "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/@semantic-release/npm/node_modules/clean-stack": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-5.2.0.tgz", + "integrity": "sha512-TyUIUJgdFnCISzG5zu3291TAsE77ddchd0bepon1VVQrKLGKFED4iXFEDQ24mIPdPBbyE16PK3F8MYE1CmcBEQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "escape-string-regexp": "5.0.0" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@semantic-release/npm/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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@semantic-release/npm/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==", + "dev": true, + "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/@semantic-release/npm/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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@semantic-release/npm/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==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=16.17.0" + } + }, + "node_modules/@semantic-release/npm/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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@semantic-release/npm/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==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@semantic-release/npm/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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@semantic-release/npm/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==", + "dev": true, + "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/@semantic-release/npm/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==", + "dev": true, + "license": "MIT", + "dependencies": { + "mimic-fn": "^4.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@semantic-release/npm/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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@semantic-release/npm/node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@semantic-release/npm/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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@semantic-release/release-notes-generator": { + "version": "12.1.0", + "resolved": "https://registry.npmjs.org/@semantic-release/release-notes-generator/-/release-notes-generator-12.1.0.tgz", + "integrity": "sha512-g6M9AjUKAZUZnxaJZnouNBeDNTCUrJ5Ltj+VJ60gJeDaRRahcHsry9HW8yKrnKkKNkx5lbWiEP1FPMqVNQz8Kg==", + "dev": true, + "license": "MIT", + "dependencies": { + "conventional-changelog-angular": "^7.0.0", + "conventional-changelog-writer": "^7.0.0", + "conventional-commits-filter": "^4.0.0", + "conventional-commits-parser": "^5.0.0", + "debug": "^4.0.0", + "get-stream": "^7.0.0", + "import-from-esm": "^1.0.3", + "into-stream": "^7.0.0", + "lodash-es": "^4.17.21", + "read-pkg-up": "^11.0.0" + }, + "engines": { + "node": "^18.17 || >=20.6.1" + }, + "peerDependencies": { + "semantic-release": ">=20.1.0" + } + }, + "node_modules/@semantic-release/release-notes-generator/node_modules/get-stream": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-7.0.1.tgz", + "integrity": "sha512-3M8C1EOFN6r8AMUhwUAACIoXZJEOufDU5+0gFFN5uNs6XYOralD2Pqkl7m046va6x77FwposWXbAhPPIOus7mQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/is?sponsor=1" + } + }, + "node_modules/@sindresorhus/merge-streams": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/merge-streams/-/merge-streams-2.3.0.tgz", + "integrity": "sha512-LtoMMhxAlorcGhmFYI+LhPgbPZCkgP6ra1YL604EeF6U98pLlQ3iWIGMdWSC+vWmPBWBNgmDBAhnAobLROJmwg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@types/minimist": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-hov8bUuiLiyFPGyFPE1lwWhmzYbirOXQNNo40+y3zow8aFVTeyn3VWL0VFFfdNddA8S4Vf0Tc062rzyNr7Paag==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/node": { + "version": "24.3.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-24.3.0.tgz", + "integrity": "sha512-aPTXCrfwnDLj4VvXrm+UUCQjNEvJgNA8s5F1cvwQU+3KNltTOkBm1j30uNLyqqPNe7gE3KFzImYoZEfLhp4Yow==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "undici-types": "~7.10.0" + } + }, + "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==", + "dev": true, + "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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 14" + } + }, + "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==", + "dev": true, + "license": "MIT", + "dependencies": { + "clean-stack": "^2.0.0", + "indent-string": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ajv": { + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", + "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ansi-escapes": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", + "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "type-fest": "^0.21.3" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/ansicolors": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/ansicolors/-/ansicolors-0.3.2.tgz", + "integrity": "sha512-QXu7BPrP29VllRxH8GwB7x5iX5qWKAAMLqKQGWTeLWVlNHNOpVMJ91dsxQAIWXpjuW5wqvxu3Jd/nRjrJ+0pqg==", + "dev": true, + "license": "MIT" + }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true, + "license": "Python-2.0" + }, + "node_modules/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==", + "dev": true, + "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==", + "dev": true, + "license": "MIT" + }, + "node_modules/arrify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", + "integrity": "sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/at-least-node": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", + "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/before-after-hook": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-2.2.3.tgz", + "integrity": "sha512-NzUnlZexiaH/46WDhANlyR2bXRopNg4F/zuSA3OpZnllCUgRaOF2znDioDWrmbNVsuZk6l9pMquQB38cfBZwkQ==", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/bl": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", + "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "buffer": "^5.5.0", + "inherits": "^2.0.4", + "readable-stream": "^3.4.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==", + "dev": true, + "license": "MIT" + }, + "node_modules/brace-expansion": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "dev": true, + "license": "MIT", + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, + "node_modules/cachedir": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/cachedir/-/cachedir-2.3.0.tgz", + "integrity": "sha512-A+Fezp4zxnit6FanDmv9EqXNAi3vt9DWp51/71UEhXukb7QUuvtv9344h91dyAxuTLoSYJFU299qzR3tzwPAhw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/camelcase-keys": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-6.2.2.tgz", + "integrity": "sha512-YrwaA0vEKazPBkn0ipTiMpSajYDSe+KjQfrjhcBMxJt/znbvlHd8Pw/Vamaz5EB4Wfhs3SUR3Z9mwRu/P3s3Yg==", + "dev": true, + "license": "MIT", + "dependencies": { + "camelcase": "^5.3.1", + "map-obj": "^4.0.0", + "quick-lru": "^4.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cardinal": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/cardinal/-/cardinal-2.1.1.tgz", + "integrity": "sha512-JSr5eOgoEymtYHBjNWyjrMqet9Am2miJhlfKNdqLp6zoeAh0KN5dRAcxlecj5mAJrmQomgiOBj35xHLrFjqBpw==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansicolors": "~0.3.2", + "redeyed": "~2.1.0" + }, + "bin": { + "cdl": "bin/cdl.js" + } + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "node_modules/chardet": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", + "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", + "dev": true, + "license": "MIT" + }, + "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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/cli-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", + "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", + "dev": true, + "license": "MIT", + "dependencies": { + "restore-cursor": "^3.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cli-spinners": { + "version": "2.9.2", + "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.9.2.tgz", + "integrity": "sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "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==", + "dev": true, + "license": "MIT", + "dependencies": { + "string-width": "^4.2.0" + }, + "engines": { + "node": "10.* || >= 12.*" + }, + "optionalDependencies": { + "@colors/colors": "1.5.0" + } + }, + "node_modules/cli-width": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-3.0.0.tgz", + "integrity": "sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">= 10" + } + }, + "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==", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/clone": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", + "integrity": "sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, + "license": "MIT" + }, + "node_modules/commitizen": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/commitizen/-/commitizen-4.3.1.tgz", + "integrity": "sha512-gwAPAVTy/j5YcOOebcCRIijn+mSjWJC+IYKivTu6aG8Ei/scoXgfsMRnuAk6b0GRste2J4NGxVdMN3ZpfNaVaw==", + "dev": true, + "license": "MIT", + "dependencies": { + "cachedir": "2.3.0", + "cz-conventional-changelog": "3.3.0", + "dedent": "0.7.0", + "detect-indent": "6.1.0", + "find-node-modules": "^2.1.2", + "find-root": "1.1.0", + "fs-extra": "9.1.0", + "glob": "7.2.3", + "inquirer": "8.2.5", + "is-utf8": "^0.2.1", + "lodash": "4.17.21", + "minimist": "1.2.7", + "strip-bom": "4.0.0", + "strip-json-comments": "3.1.1" + }, + "bin": { + "commitizen": "bin/commitizen", + "cz": "bin/git-cz", + "git-cz": "bin/git-cz" + }, + "engines": { + "node": ">= 12" + } + }, + "node_modules/commitizen/node_modules/fs-extra": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", + "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "at-least-node": "^1.0.0", + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/commitizen/node_modules/minimist": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.7.tgz", + "integrity": "sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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==", + "dev": true, + "license": "MIT", + "dependencies": { + "array-ify": "^1.0.0", + "dot-prop": "^5.1.0" + } + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true, + "license": "MIT" + }, + "node_modules/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==", + "dev": true, + "license": "MIT", + "dependencies": { + "ini": "^1.3.4", + "proto-list": "~1.2.1" + } + }, + "node_modules/conventional-changelog-angular": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/conventional-changelog-angular/-/conventional-changelog-angular-7.0.0.tgz", + "integrity": "sha512-ROjNchA9LgfNMTTFSIWPzebCwOGFdgkEq45EnvvrmSLvCtAw0HSmrCs7/ty+wAeYUZyNay0YMUNYFTRL72PkBQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "compare-func": "^2.0.0" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/conventional-changelog-conventionalcommits": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/conventional-changelog-conventionalcommits/-/conventional-changelog-conventionalcommits-7.0.2.tgz", + "integrity": "sha512-NKXYmMR/Hr1DevQegFB4MwfM5Vv0m4UIxKZTTYuD98lpTknaZlSRrDOG4X7wIXpGkfsYxZTghUN+Qq+T0YQI7w==", + "dev": true, + "license": "ISC", + "dependencies": { + "compare-func": "^2.0.0" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/conventional-changelog-writer": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/conventional-changelog-writer/-/conventional-changelog-writer-7.0.1.tgz", + "integrity": "sha512-Uo+R9neH3r/foIvQ0MKcsXkX642hdm9odUp7TqgFS7BsalTcjzRlIfWZrZR1gbxOozKucaKt5KAbjW8J8xRSmA==", + "dev": true, + "license": "MIT", + "dependencies": { + "conventional-commits-filter": "^4.0.0", + "handlebars": "^4.7.7", + "json-stringify-safe": "^5.0.1", + "meow": "^12.0.1", + "semver": "^7.5.2", + "split2": "^4.0.0" + }, + "bin": { + "conventional-changelog-writer": "cli.mjs" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/conventional-commit-types": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/conventional-commit-types/-/conventional-commit-types-3.0.0.tgz", + "integrity": "sha512-SmmCYnOniSsAa9GqWOeLqc179lfr5TRu5b4QFDkbsrJ5TZjPJx85wtOr3zn+1dbeNiXDKGPbZ72IKbPhLXh/Lg==", + "dev": true, + "license": "ISC" + }, + "node_modules/conventional-commits-filter": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/conventional-commits-filter/-/conventional-commits-filter-4.0.0.tgz", + "integrity": "sha512-rnpnibcSOdFcdclpFwWa+pPlZJhXE7l+XK04zxhbWrhgpR96h33QLz8hITTXbcYICxVr3HZFtbtUAQ+4LdBo9A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=16" + } + }, + "node_modules/conventional-commits-parser": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/conventional-commits-parser/-/conventional-commits-parser-5.0.0.tgz", + "integrity": "sha512-ZPMl0ZJbw74iS9LuX9YIAiW8pfM5p3yh2o/NbXHbkFuZzY5jvdi5jFycEOkmBW5H5I7nA+D6f3UcsCLP2vvSEA==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-text-path": "^2.0.0", + "JSONStream": "^1.3.5", + "meow": "^12.0.1", + "split2": "^4.0.0" + }, + "bin": { + "conventional-commits-parser": "cli.mjs" + }, + "engines": { + "node": ">=16" + } + }, + "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==", + "dev": true, + "license": "MIT" + }, + "node_modules/cosmiconfig": { + "version": "8.3.6", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-8.3.6.tgz", + "integrity": "sha512-kcZ6+W5QzcJ3P1Mt+83OUv/oHFqZHIx8DuxG6eZ5RGMERoLqp4BuGjhHLYGK+Kf5XVkQvqBSmAy/nGWN3qDgEA==", + "dev": true, + "license": "MIT", + "dependencies": { + "import-fresh": "^3.3.0", + "js-yaml": "^4.1.0", + "parse-json": "^5.2.0", + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/d-fischer" + }, + "peerDependencies": { + "typescript": ">=4.9.5" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/cosmiconfig-typescript-loader": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/cosmiconfig-typescript-loader/-/cosmiconfig-typescript-loader-5.1.0.tgz", + "integrity": "sha512-7PtBB+6FdsOvZyJtlF3hEPpACq7RQX6BVGsgC7/lfVXnKMvNCu/XY3ykreqG5w/rBNdu2z8LCIKoF3kpHHdHlA==", + "dev": true, + "license": "MIT", + "dependencies": { + "jiti": "^1.21.6" + }, + "engines": { + "node": ">=v16" + }, + "peerDependencies": { + "@types/node": "*", + "cosmiconfig": ">=8.2", + "typescript": ">=4" + } + }, + "node_modules/cross-spawn": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "dev": true, + "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==", + "dev": true, + "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==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cz-conventional-changelog": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/cz-conventional-changelog/-/cz-conventional-changelog-3.3.0.tgz", + "integrity": "sha512-U466fIzU5U22eES5lTNiNbZ+d8dfcHcssH4o7QsdWaCcRs/feIPCxKYSWkYBNs5mny7MvEfwpTLWjvbm94hecw==", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^2.4.1", + "commitizen": "^4.0.3", + "conventional-commit-types": "^3.0.0", + "lodash.map": "^4.5.1", + "longest": "^2.0.1", + "word-wrap": "^1.0.3" + }, + "engines": { + "node": ">= 10" + }, + "optionalDependencies": { + "@commitlint/load": ">6.1.1" + } + }, + "node_modules/cz-conventional-changelog/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==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/cz-conventional-changelog/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==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/cz-conventional-changelog/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==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/cz-conventional-changelog/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==", + "dev": true, + "license": "MIT" + }, + "node_modules/cz-conventional-changelog/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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/cz-conventional-changelog/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==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/dargs": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/dargs/-/dargs-7.0.0.tgz", + "integrity": "sha512-2iy1EkLdlBzQGvbweYRFxmFath8+K7+AKB0TlhHWkNuH+TmovaMH/Wp7V7R4u7f4SnX3OgLsU9t1NI9ioDnUpg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/debug": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz", + "integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/decamelize-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/decamelize-keys/-/decamelize-keys-1.1.1.tgz", + "integrity": "sha512-WiPxgEirIV0/eIOMcnFBA3/IJZAZqKnwAwWyvvdi4lsr1WCN22nhdf/3db3DoZcUjTV2SqfzIwNyp6y2xs3nmg==", + "dev": true, + "license": "MIT", + "dependencies": { + "decamelize": "^1.1.0", + "map-obj": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/decamelize-keys/node_modules/map-obj": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", + "integrity": "sha512-7N/q3lyZ+LVCp7PzuxrJr4KMbBE2hW7BT7YNia330OFxIf4d3r5zVpicP2650l7CPN6RM9zOJRl3NGpqSiw3Eg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/dedent": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz", + "integrity": "sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA==", + "dev": true, + "license": "MIT" + }, + "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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/defaults": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.4.tgz", + "integrity": "sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==", + "dev": true, + "license": "MIT", + "dependencies": { + "clone": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/deprecation": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/deprecation/-/deprecation-2.3.1.tgz", + "integrity": "sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/detect-file": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/detect-file/-/detect-file-1.0.0.tgz", + "integrity": "sha512-DtCOLG98P007x7wiiOmfI0fi3eIKyWiLTGJ2MDnVi/E04lWGbf+JzrRHMm0rgIIZJGtHpKpbVgLWHrv8xXpc3Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/detect-indent": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-6.1.0.tgz", + "integrity": "sha512-reYkTUJAZb9gUuZ2RvVCNhVHdg62RHnJ7WJl8ftMi4diZ6NWlciOzQN88pUhSELEwflJht4oQDv0F0BMlwaYtA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "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==", + "dev": true, + "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==", + "dev": true, + "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==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "readable-stream": "^2.0.2" + } + }, + "node_modules/duplexer2/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==", + "dev": true, + "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/duplexer2/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==", + "dev": true, + "license": "MIT" + }, + "node_modules/duplexer2/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==", + "dev": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/emojilib": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/emojilib/-/emojilib-2.4.0.tgz", + "integrity": "sha512-5U0rVMU5Y2n2+ykNLQqMoqklN9ICBT/KsvC1Gz6vqHbz2AXXGkG+Pm5rMWk/8Vjrr/mY9985Hi8DYzn1F09Nyw==", + "dev": true, + "license": "MIT" + }, + "node_modules/env-ci": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/env-ci/-/env-ci-10.0.0.tgz", + "integrity": "sha512-U4xcd/utDYFgMh0yWj07R1H6L5fwhVbmxBCpnL0DbVSDZVnsC82HONw0wxtxNkIAcua3KtbomQvIk5xFZGAQJw==", + "dev": true, + "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==", + "dev": true, + "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==", + "dev": true, + "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==", + "dev": true, + "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==", + "dev": true, + "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/mimic-fn": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz", + "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "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==", + "dev": true, + "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/onetime": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz", + "integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "mimic-fn": "^4.0.0" + }, + "engines": { + "node": ">=12" + }, + "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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/env-ci/node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "dev": true, + "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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true, + "license": "BSD-2-Clause", + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/execa": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", + "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", + "dev": true, + "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/expand-tilde": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-2.0.2.tgz", + "integrity": "sha512-A5EmesHW6rfnZ9ysHQjPdJRni0SRar0tjtG5MNtm9n5TUvsYU8oozprtRD4AqHxcZWWlVuAmQo2nWKfN9oyjTw==", + "dev": true, + "license": "MIT", + "dependencies": { + "homedir-polyfill": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/external-editor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", + "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", + "dev": true, + "license": "MIT", + "dependencies": { + "chardet": "^0.7.0", + "iconv-lite": "^0.4.24", + "tmp": "^0.0.33" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-glob": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz", + "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.8" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fast-uri": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.0.tgz", + "integrity": "sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "BSD-3-Clause" + }, + "node_modules/fastq": { + "version": "1.19.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.19.1.tgz", + "integrity": "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/figures": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", + "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", + "dev": true, + "license": "MIT", + "dependencies": { + "escape-string-regexp": "^1.0.5" + }, + "engines": { + "node": ">=8" + }, + "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==", + "dev": true, + "license": "MIT", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/find-node-modules": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/find-node-modules/-/find-node-modules-2.1.3.tgz", + "integrity": "sha512-UC2I2+nx1ZuOBclWVNdcnbDR5dlrOdVb7xNjmT/lHE+LsgztWks3dG7boJ37yTS/venXw84B/mAW9uHVoC5QRg==", + "dev": true, + "license": "MIT", + "dependencies": { + "findup-sync": "^4.0.0", + "merge": "^2.1.1" + } + }, + "node_modules/find-root": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/find-root/-/find-root-1.1.0.tgz", + "integrity": "sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==", + "dev": true, + "license": "MIT" + }, + "node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/find-versions": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/find-versions/-/find-versions-5.1.0.tgz", + "integrity": "sha512-+iwzCJ7C5v5KgcBuueqVoNiHVoQpwiUK5XFLjf0affFTep+Wcw93tPvmb8tqujDNmzhBDPddnWV/qgWSXgq+Hg==", + "dev": true, + "license": "MIT", + "dependencies": { + "semver-regex": "^4.0.5" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/findup-sync": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-4.0.0.tgz", + "integrity": "sha512-6jvvn/12IC4quLBL1KNokxC7wWTvYncaVUYSoxWw7YykPLuRrnv4qdHcSOywOI5RpkOVGeQRtWM8/q+G6W6qfQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "detect-file": "^1.0.0", + "is-glob": "^4.0.0", + "micromatch": "^4.0.2", + "resolve-dir": "^1.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/from2": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/from2/-/from2-2.3.0.tgz", + "integrity": "sha512-OMcX/4IC/uqEPVgGeyfN22LJk6AZrMkRZHxcHBMBvHScDGgwTm2GT2Wkgtocyd3JfZffjj2kYUDXXII0Fk9W0g==", + "dev": true, + "license": "MIT", + "dependencies": { + "inherits": "^2.0.1", + "readable-stream": "^2.0.0" + } + }, + "node_modules/from2/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==", + "dev": true, + "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/from2/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==", + "dev": true, + "license": "MIT" + }, + "node_modules/from2/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==", + "dev": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/fs-extra": { + "version": "11.3.1", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.3.1.tgz", + "integrity": "sha512-eXvGGwZ5CL17ZSwHWd3bbgk7UUpF6IFHtP57NYYakPvHOs8GDgDe5KJI36jIJzDkJ6eJjuzRA8eBQb6SkKue0g==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=14.14" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true, + "license": "ISC" + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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==", + "dev": true, + "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==", + "dev": true, + "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==", + "dev": true, + "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/git-log-parser/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==", + "dev": true, + "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/git-log-parser/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==", + "dev": true, + "license": "MIT" + }, + "node_modules/git-log-parser/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==", + "dev": true, + "license": "ISC", + "dependencies": { + "through2": "~2.0.0" + } + }, + "node_modules/git-log-parser/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==", + "dev": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/git-log-parser/node_modules/through2": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", + "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "readable-stream": "~2.3.6", + "xtend": "~4.0.1" + } + }, + "node_modules/git-raw-commits": { + "version": "2.0.11", + "resolved": "https://registry.npmjs.org/git-raw-commits/-/git-raw-commits-2.0.11.tgz", + "integrity": "sha512-VnctFhw+xfj8Va1xtfEqCUD2XDrbAPSJx+hSrE5K7fGdjZruW7XV+QOrN7LF/RJyvspRiD2I0asWsxFp0ya26A==", + "dev": true, + "license": "MIT", + "dependencies": { + "dargs": "^7.0.0", + "lodash": "^4.17.15", + "meow": "^8.0.0", + "split2": "^3.0.0", + "through2": "^4.0.0" + }, + "bin": { + "git-raw-commits": "cli.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/git-raw-commits/node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/git-raw-commits/node_modules/hosted-git-info": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.1.0.tgz", + "integrity": "sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA==", + "dev": true, + "license": "ISC", + "dependencies": { + "lru-cache": "^6.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/git-raw-commits/node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/git-raw-commits/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/git-raw-commits/node_modules/meow": { + "version": "8.1.2", + "resolved": "https://registry.npmjs.org/meow/-/meow-8.1.2.tgz", + "integrity": "sha512-r85E3NdZ+mpYk1C6RjPFEMSE+s1iZMuHtsHAqY0DT3jZczl0diWUZ8g6oU7h0M9cD2EL+PzaYghhCLzR0ZNn5Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/minimist": "^1.2.0", + "camelcase-keys": "^6.2.2", + "decamelize-keys": "^1.1.0", + "hard-rejection": "^2.1.0", + "minimist-options": "4.1.0", + "normalize-package-data": "^3.0.0", + "read-pkg-up": "^7.0.1", + "redent": "^3.0.0", + "trim-newlines": "^3.0.0", + "type-fest": "^0.18.0", + "yargs-parser": "^20.2.3" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/git-raw-commits/node_modules/normalize-package-data": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-3.0.3.tgz", + "integrity": "sha512-p2W1sgqij3zMMyRC067Dg16bfzVH+w7hyegmpIvZ4JNjqtGOVAIvLmjBx3yP7YTe9vKJgkoNOPjwQGogDoMXFA==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "hosted-git-info": "^4.0.1", + "is-core-module": "^2.5.0", + "semver": "^7.3.4", + "validate-npm-package-license": "^3.0.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/git-raw-commits/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/git-raw-commits/node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/git-raw-commits/node_modules/read-pkg": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", + "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/normalize-package-data": "^2.4.0", + "normalize-package-data": "^2.5.0", + "parse-json": "^5.0.0", + "type-fest": "^0.6.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/git-raw-commits/node_modules/read-pkg-up": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", + "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", + "dev": true, + "license": "MIT", + "dependencies": { + "find-up": "^4.1.0", + "read-pkg": "^5.2.0", + "type-fest": "^0.8.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/git-raw-commits/node_modules/read-pkg-up/node_modules/type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=8" + } + }, + "node_modules/git-raw-commits/node_modules/read-pkg/node_modules/hosted-git-info": { + "version": "2.8.9", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", + "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", + "dev": true, + "license": "ISC" + }, + "node_modules/git-raw-commits/node_modules/read-pkg/node_modules/normalize-package-data": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", + "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + } + }, + "node_modules/git-raw-commits/node_modules/read-pkg/node_modules/semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/git-raw-commits/node_modules/read-pkg/node_modules/type-fest": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", + "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=8" + } + }, + "node_modules/git-raw-commits/node_modules/split2": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/split2/-/split2-3.2.2.tgz", + "integrity": "sha512-9NThjpgZnifTkJpzTZ7Eue85S49QwpNhZTq6GRJwObb6jnLFNGB7Qm73V5HewTROPyxD0C29xqmaI68bQtV+hg==", + "dev": true, + "license": "ISC", + "dependencies": { + "readable-stream": "^3.0.0" + } + }, + "node_modules/git-raw-commits/node_modules/type-fest": { + "version": "0.18.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.18.1.tgz", + "integrity": "sha512-OIAYXk8+ISY+qTOwkHtKqzAuxchoMiD9Udx+FSGQDuiRR+PJKJHc2NJAXlbhkGwTt/4/nKZxELY1w3ReWOL8mw==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/git-raw-commits/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==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Glob versions prior to v9 are no longer supported", + "dev": true, + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/global-dirs": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-0.1.1.tgz", + "integrity": "sha512-NknMLn7F2J7aflwFOlGdNIuCDpN3VGoSoB+aap3KABFWbHVn1TCgFC+np23J8W2BiZbjfEw3BFBycSMv1AFblg==", + "dev": true, + "license": "MIT", + "dependencies": { + "ini": "^1.3.4" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/global-modules": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-1.0.0.tgz", + "integrity": "sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg==", + "dev": true, + "license": "MIT", + "dependencies": { + "global-prefix": "^1.0.1", + "is-windows": "^1.0.1", + "resolve-dir": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/global-prefix": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-1.0.2.tgz", + "integrity": "sha512-5lsx1NUDHtSjfg0eHlmYvZKv8/nVqX4ckFbM+FrGcQ+04KWcWFo9P5MxPZYSzUvyzmdTbI7Eix8Q4IbELDqzKg==", + "dev": true, + "license": "MIT", + "dependencies": { + "expand-tilde": "^2.0.2", + "homedir-polyfill": "^1.0.1", + "ini": "^1.3.4", + "is-windows": "^1.0.1", + "which": "^1.2.14" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/global-prefix/node_modules/which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "which": "bin/which" + } + }, + "node_modules/globby": { + "version": "14.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-14.1.0.tgz", + "integrity": "sha512-0Ia46fDOaT7k4og1PDW4YbodWWr3scS2vAr2lTbsplOt2WkKp0vQbkI9wKis/T5LV/dqPjO3bpS/z6GTJB82LA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@sindresorhus/merge-streams": "^2.1.0", + "fast-glob": "^3.3.3", + "ignore": "^7.0.3", + "path-type": "^6.0.0", + "slash": "^5.1.0", + "unicorn-magic": "^0.3.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/globby/node_modules/path-type": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-6.0.0.tgz", + "integrity": "sha512-Vj7sf++t5pBD637NSfkxpHSMfWaeig5+DKWLhcqIYx6mWQz5hdJTGDVMQiJcw1ZYkhs7AazKDGpRVji1LJCZUQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "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==", + "dev": true, + "license": "ISC" + }, + "node_modules/handlebars": { + "version": "4.7.8", + "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.8.tgz", + "integrity": "sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ==", + "dev": true, + "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/hard-rejection": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/hard-rejection/-/hard-rejection-2.1.0.tgz", + "integrity": "sha512-VIZB+ibDhx7ObhAe7OVtoEbuP4h/MuOTHJ+J8h/eBXotJYl0fBgR72xDFCKgIh22OJZIOVNxBMWuhAr10r8HdA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/homedir-polyfill": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz", + "integrity": "sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA==", + "dev": true, + "license": "MIT", + "dependencies": { + "parse-passwd": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/hook-std": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/hook-std/-/hook-std-3.0.0.tgz", + "integrity": "sha512-jHRQzjSDzMtFy34AGj1DN+vq54WVuhSvKgrHf0OMiFQTwDD4L/qqofVEWjLOBMTn5+lCD3fPg32W9yOfnEJTTw==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "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==", + "dev": true, + "license": "ISC", + "dependencies": { + "lru-cache": "^10.0.1" + }, + "engines": { + "node": "^16.14.0 || >=18.0.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==", + "dev": true, + "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==", + "dev": true, + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.2", + "debug": "4" + }, + "engines": { + "node": ">= 14" + } + }, + "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==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=10.17.0" + } + }, + "node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dev": true, + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "BSD-3-Clause" + }, + "node_modules/ignore": { + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.5.tgz", + "integrity": "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/import-fresh": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz", + "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/import-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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/import-from-esm": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/import-from-esm/-/import-from-esm-1.3.4.tgz", + "integrity": "sha512-7EyUlPFC0HOlBDpUFGfYstsU7XHxZJKAAMzCT8wZ0hMW7b+hG51LIKTDcsgtz8Pu6YC0HqRVbX+rVUtsGMUKvg==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^4.3.4", + "import-meta-resolve": "^4.0.0" + }, + "engines": { + "node": ">=16.20" + } + }, + "node_modules/import-meta-resolve": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/import-meta-resolve/-/import-meta-resolve-4.1.0.tgz", + "integrity": "sha512-I6fiaX09Xivtk+THaMfAwnA3MVA5Big1WHF1Dfx9hFuvNIWpXnorlkzhcQf6ehrqQiiZECRt1poOAkPmer3ruw==", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/index-to-position": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/index-to-position/-/index-to-position-1.1.0.tgz", + "integrity": "sha512-XPdx9Dq4t9Qk1mTMbWONJqU7boCoumEH7fRET37HX5+khDUl3J2W6PdALxhILYlIYx2amlwYcRPp28p0tSiojg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", + "dev": true, + "license": "ISC", + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true, + "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==", + "dev": true, + "license": "ISC" + }, + "node_modules/inquirer": { + "version": "8.2.5", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-8.2.5.tgz", + "integrity": "sha512-QAgPDQMEgrDssk1XiwwHoOGYF9BAbUcc1+j+FhEvaOt8/cKRqyLn0U5qA6F74fGhTMGxf92pOvPBeh29jQJDTQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-escapes": "^4.2.1", + "chalk": "^4.1.1", + "cli-cursor": "^3.1.0", + "cli-width": "^3.0.0", + "external-editor": "^3.0.3", + "figures": "^3.0.0", + "lodash": "^4.17.21", + "mute-stream": "0.0.8", + "ora": "^5.4.1", + "run-async": "^2.4.0", + "rxjs": "^7.5.5", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0", + "through": "^2.3.6", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/into-stream": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/into-stream/-/into-stream-7.0.0.tgz", + "integrity": "sha512-2dYz766i9HprMBasCMvHMuazJ7u4WzhJwo5kb3iPSiW/iRYV6uPari3zHoqZlnuaR7V1bEiNMxikhp37rdBXbw==", + "dev": true, + "license": "MIT", + "dependencies": { + "from2": "^2.3.0", + "p-is-promise": "^3.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "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==", + "dev": true, + "license": "MIT" + }, + "node_modules/is-core-module": { + "version": "2.16.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz", + "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==", + "dev": true, + "license": "MIT", + "dependencies": { + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-interactive": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-1.0.0.tgz", + "integrity": "sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==", + "dev": true, + "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==", + "dev": true, + "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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-plain-obj": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", + "integrity": "sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-text-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-text-path/-/is-text-path-2.0.0.tgz", + "integrity": "sha512-+oDTluR6WEjdXEJMnC2z6A4FRwFoYuvShVVEGsS7ewc0UTi2QtAKMDJuL4BDEVt+5T7MjFo12RP8ghOM75oKJw==", + "dev": true, + "license": "MIT", + "dependencies": { + "text-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-unicode-supported": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", + "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-utf8": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", + "integrity": "sha512-rMYPYvCzsXywIsldgLaSoPlw5PfoB/ssr7hY4pLfcodrA5M/eArza1a9VmTiNIBNMjOGr1Ow9mTyU2o69U6U9Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/is-windows": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", + "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true, + "license": "ISC" + }, + "node_modules/issue-parser": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/issue-parser/-/issue-parser-6.0.0.tgz", + "integrity": "sha512-zKa/Dxq2lGsBIXQ7CUZWTHfvxPC2ej0KfO7fIPqLlHB9J2hJ7rGhZ5rilhuufylr4RXYPzJUeFjKxz305OsNlA==", + "dev": true, + "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": ">=10.13" + } + }, + "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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6.0" + } + }, + "node_modules/jiti": { + "version": "1.21.7", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.7.tgz", + "integrity": "sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A==", + "dev": true, + "license": "MIT", + "bin": { + "jiti": "bin/jiti.js" + } + }, + "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==", + "dev": true, + "license": "MIT" + }, + "node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "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==", + "dev": true, + "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==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==", + "dev": true, + "license": "ISC" + }, + "node_modules/jsonfile": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.2.0.tgz", + "integrity": "sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg==", + "dev": true, + "license": "MIT", + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/jsonparse": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz", + "integrity": "sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==", + "dev": true, + "engines": [ + "node >= 0.2.0" + ], + "license": "MIT" + }, + "node_modules/JSONStream": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.5.tgz", + "integrity": "sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==", + "dev": true, + "license": "(MIT OR Apache-2.0)", + "dependencies": { + "jsonparse": "^1.2.0", + "through": ">=2.2.7 <3" + }, + "bin": { + "JSONStream": "bin.js" + }, + "engines": { + "node": "*" + } + }, + "node_modules/kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", + "dev": true, + "license": "MIT" + }, + "node_modules/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==", + "dev": true, + "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==", + "dev": true, + "license": "MIT", + "dependencies": { + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/load-json-file/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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash-es": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz", + "integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.camelcase": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", + "integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==", + "dev": true, + "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==", + "dev": true, + "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==", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.isfunction": { + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/lodash.isfunction/-/lodash.isfunction-3.0.9.tgz", + "integrity": "sha512-AirXNj15uRIMMPihnkInB4i3NHeb4iBtNg9WRWuK2o31S+ePwwNmDPaTL3o7dTJ+VXNZim7rFs4rxN4YU1oUJw==", + "dev": true, + "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==", + "dev": true, + "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==", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.kebabcase": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lodash.kebabcase/-/lodash.kebabcase-4.1.1.tgz", + "integrity": "sha512-N8XRTIMMqqDgSy4VLKPnJ/+hpGZN+PHQiJnSenYqPaVV/NCqEogTnAdZLQiGKhxX+JCs8waWq2t1XHWKOmlY8g==", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.map": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/lodash.map/-/lodash.map-4.6.0.tgz", + "integrity": "sha512-worNHGKLDetmcEYDvh2stPCrrQRkP20E4l0iIS7F8EvzMqBBi7ltvFN5m1HvTf1P7Jk1txKhvFcmYsCr8O2F1Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.mergewith": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.mergewith/-/lodash.mergewith-4.6.2.tgz", + "integrity": "sha512-GK3g5RPZWTRSeLSpgP8Xhra+pnjBC56q9FZYe1d5RN3TJ35dbkGy3YqBSMbyCrlbi+CM9Z3Jk5yTL7RCsqboyQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.snakecase": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lodash.snakecase/-/lodash.snakecase-4.1.1.tgz", + "integrity": "sha512-QZ1d4xoBHYUeuouhEq3lk3Uq7ldgyFXGBhg04+oRLnIz8o9T65Eh+8YdroUwn846zchkA9yDsDl5CVVaV2nqYw==", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.startcase": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.startcase/-/lodash.startcase-4.4.0.tgz", + "integrity": "sha512-+WKqsK294HMSc2jEbNgpHpd0JfIBhp7rEV4aqXWqFr6AlXov+SlcgB1Fv01y2kGe3Gc8nMW7VA0SrGuSkRfIEg==", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.uniq": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz", + "integrity": "sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ==", + "dev": true, + "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==", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.upperfirst": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/lodash.upperfirst/-/lodash.upperfirst-4.3.1.tgz", + "integrity": "sha512-sReKOYJIJf74dhJONhU4e0/shzi1trVbSWDOhKYE5XV2O+H7Sb2Dihwuc7xWxVl+DgFPyTqIN3zMfT9cq5iWDg==", + "dev": true, + "license": "MIT" + }, + "node_modules/log-symbols": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", + "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^4.1.0", + "is-unicode-supported": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/longest": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/longest/-/longest-2.0.1.tgz", + "integrity": "sha512-Ajzxb8CM6WAnFjgiloPsI3bF+WCxcvhdIG3KNA2KN962+tdBsHcuQ4k4qX/EcS/2CRkcc0iAkR956Nib6aXU/Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/map-obj": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-4.3.0.tgz", + "integrity": "sha512-hdN1wVrZbb29eBGiGjJbeP8JbKjq1urkHJ/LIP/NY48MZ1QVXUsQBV1G1zvYFHn1XE06cwjBsOI2K3Ulnj1YXQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/marked": { + "version": "9.1.6", + "resolved": "https://registry.npmjs.org/marked/-/marked-9.1.6.tgz", + "integrity": "sha512-jcByLnIFkd5gSXZmjNvS1TlmRhCXZjIzHYlaGkPlLIekG55JDR2Z4va9tZwCiP+/RDERiNhMOFu01xd6O5ct1Q==", + "dev": true, + "license": "MIT", + "bin": { + "marked": "bin/marked.js" + }, + "engines": { + "node": ">= 16" + } + }, + "node_modules/marked-terminal": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/marked-terminal/-/marked-terminal-6.2.0.tgz", + "integrity": "sha512-ubWhwcBFHnXsjYNsu+Wndpg0zhY4CahSpPlA70PlO0rR9r2sZpkyU+rkCsOWH+KMEkx847UpALON+HWgxowFtw==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-escapes": "^6.2.0", + "cardinal": "^2.1.1", + "chalk": "^5.3.0", + "cli-table3": "^0.6.3", + "node-emoji": "^2.1.3", + "supports-hyperlinks": "^3.0.0" + }, + "engines": { + "node": ">=16.0.0" + }, + "peerDependencies": { + "marked": ">=1 <12" + } + }, + "node_modules/marked-terminal/node_modules/ansi-escapes": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-6.2.1.tgz", + "integrity": "sha512-4nJ3yixlEthEJ9Rk4vPcdBRkZvQZlYyu8j4/Mqz5sgIkddmEnH2Yj2ZrnP9S3tQOvSNRUIgVNF/1yPpRAGNRig==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/marked-terminal/node_modules/chalk": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.6.0.tgz", + "integrity": "sha512-46QrSQFyVSEyYAgQ22hQ+zDa60YHA4fBstHmtSApj1Y5vKtG27fWowW03jCk5KcbXEWPZUIR894aARCA/G1kfQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/meow": { + "version": "12.1.1", + "resolved": "https://registry.npmjs.org/meow/-/meow-12.1.1.tgz", + "integrity": "sha512-BhXM0Au22RwUneMPwSCnyhTOizdWoIEPU9sp0Aqa1PnDMR5Wv2FGXYDjuzJEIX+Eo2Rb8xuYe5jrnm5QowQFkw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=16.10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/merge": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/merge/-/merge-2.1.1.tgz", + "integrity": "sha512-jz+Cfrg9GWOZbQAnDQ4hlVnQky+341Yk5ru8bZSe6sIDTCIg8n9i/u7hSQGSVOF3C7lH6mGtqjkiT9G4wFLL0w==", + "dev": true, + "license": "MIT" + }, + "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==", + "dev": true, + "license": "MIT" + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/micromatch": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", + "dev": true, + "license": "MIT", + "dependencies": { + "braces": "^3.0.3", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/mime": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/mime/-/mime-4.0.7.tgz", + "integrity": "sha512-2OfDPL+e03E0LrXaGYOtTFIYhiuzep94NSsuhrNULq+stylcJedcHdzHtz0atMUuGwJfFYs0YL5xeC/Ca2x0eQ==", + "dev": true, + "funding": [ + "https://github.com/sponsors/broofa" + ], + "license": "MIT", + "bin": { + "mime": "bin/cli.js" + }, + "engines": { + "node": ">=16" + } + }, + "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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/min-indent": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", + "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/minimist-options": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/minimist-options/-/minimist-options-4.1.0.tgz", + "integrity": "sha512-Q4r8ghd80yhO/0j1O3B2BjweX3fiHg9cdOwjJd2J76Q135c+NDxGCqdYKQ1SKBuFfgWbAUzBfvYjPUEeNgqN1A==", + "dev": true, + "license": "MIT", + "dependencies": { + "arrify": "^1.0.1", + "is-plain-obj": "^1.1.0", + "kind-of": "^6.0.3" + }, + "engines": { + "node": ">= 6" + } + }, + "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==", + "dev": true, + "license": "MIT" + }, + "node_modules/mute-stream": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", + "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==", + "dev": true, + "license": "ISC" + }, + "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==", + "dev": true, + "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==", + "dev": true, + "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==", + "dev": true, + "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==", + "dev": true, + "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-url": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-8.0.2.tgz", + "integrity": "sha512-Ee/R3SyN4BuynXcnTaekmaVdbDAEiNrHqjQIA37mHU8G9pf7aaAD4ZX3XjBLo6rsdcxA/gtkcNYZLt30ACgynw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/npm": { + "version": "10.9.3", + "resolved": "https://registry.npmjs.org/npm/-/npm-10.9.3.tgz", + "integrity": "sha512-6Eh1u5Q+kIVXeA8e7l2c/HpnFFcwrkt37xDMujD5be1gloWa9p6j3Fsv3mByXXmqJHy+2cElRMML8opNT7xIJQ==", + "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" + ], + "dev": true, + "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.1", + "@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.2", + "@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.4.1", + "ci-info": "^4.2.0", + "cli-columns": "^4.0.0", + "fastest-levenshtein": "^1.0.16", + "fs-minipass": "^3.0.3", + "glob": "^10.4.5", + "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.1", + "libnpmexec": "^9.0.1", + "libnpmfund": "^6.0.1", + "libnpmhook": "^11.0.0", + "libnpmorg": "^7.0.0", + "libnpmpack": "^8.0.1", + "libnpmpublish": "^10.0.1", + "libnpmsearch": "^8.0.0", + "libnpmteam": "^7.0.0", + "libnpmversion": "^7.0.0", + "make-fetch-happen": "^14.0.3", + "minimatch": "^9.0.5", + "minipass": "^7.1.1", + "minipass-pipeline": "^1.2.4", + "ms": "^2.1.2", + "node-gyp": "^11.2.0", + "nopt": "^8.1.0", + "normalize-package-data": "^7.0.0", + "npm-audit-report": "^6.0.0", + "npm-install-checks": "^7.1.1", + "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.3", + "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.2", + "spdx-expression-parse": "^4.0.0", + "ssri": "^12.0.0", + "supports-color": "^9.4.0", + "tar": "^6.2.1", + "text-table": "~0.2.0", + "tiny-relative-date": "^1.3.0", + "treeverse": "^3.0.0", + "validate-npm-package-name": "^6.0.1", + "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": "4.0.1", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/npm/node_modules/@isaacs/cliui": { + "version": "8.0.2", + "dev": true, + "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.1.0", + "dev": true, + "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", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/@isaacs/cliui/node_modules/string-width": { + "version": "5.1.2", + "dev": true, + "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.1.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "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", + "dev": true, + "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", + "dev": true, + "inBundle": true, + "license": "ISC" + }, + "node_modules/npm/node_modules/@npmcli/agent": { + "version": "3.0.0", + "dev": true, + "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.1", + "dev": true, + "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", + "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", + "dev": true, + "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", + "dev": true, + "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", + "dev": true, + "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", + "dev": true, + "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", + "dev": true, + "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", + "dev": true, + "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.0", + "dev": true, + "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": "^6.1.11" + }, + "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", + "dev": true, + "inBundle": true, + "license": "ISC", + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/@npmcli/node-gyp": { + "version": "4.0.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/@npmcli/package-json": { + "version": "6.2.0", + "dev": true, + "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.2", + "dev": true, + "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", + "dev": true, + "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", + "dev": true, + "inBundle": true, + "license": "ISC", + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/@npmcli/run-script": { + "version": "9.1.0", + "dev": true, + "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", + "dev": true, + "inBundle": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=14" + } + }, + "node_modules/npm/node_modules/@sigstore/protobuf-specs": { + "version": "0.4.3", + "dev": true, + "inBundle": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/@sigstore/tuf": { + "version": "3.1.1", + "dev": true, + "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/@tufjs/canonical-json": { + "version": "2.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/abbrev": { + "version": "3.0.1", + "dev": true, + "inBundle": true, + "license": "ISC", + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/agent-base": { + "version": "7.1.3", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">= 14" + } + }, + "node_modules/npm/node_modules/ansi-regex": { + "version": "5.0.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/npm/node_modules/ansi-styles": { + "version": "6.2.1", + "dev": true, + "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.0.0", + "dev": true, + "inBundle": true, + "license": "ISC" + }, + "node_modules/npm/node_modules/archy": { + "version": "1.0.0", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/balanced-match": { + "version": "1.0.2", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/bin-links": { + "version": "5.0.0", + "dev": true, + "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", + "dev": true, + "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", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/npm/node_modules/cacache": { + "version": "19.0.1", + "dev": true, + "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/cacache/node_modules/chownr": { + "version": "3.0.0", + "dev": true, + "inBundle": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=18" + } + }, + "node_modules/npm/node_modules/cacache/node_modules/mkdirp": { + "version": "3.0.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "bin": { + "mkdirp": "dist/cjs/src/bin.js" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/npm/node_modules/cacache/node_modules/tar": { + "version": "7.4.3", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "@isaacs/fs-minipass": "^4.0.0", + "chownr": "^3.0.0", + "minipass": "^7.1.2", + "minizlib": "^3.0.1", + "mkdirp": "^3.0.1", + "yallist": "^5.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/npm/node_modules/cacache/node_modules/yallist": { + "version": "5.0.0", + "dev": true, + "inBundle": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=18" + } + }, + "node_modules/npm/node_modules/chalk": { + "version": "5.4.1", + "dev": true, + "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": "2.0.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "node_modules/npm/node_modules/ci-info": { + "version": "4.2.0", + "dev": true, + "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", + "dev": true, + "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", + "dev": true, + "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", + "dev": true, + "inBundle": true, + "license": "ISC", + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/color-convert": { + "version": "2.0.1", + "dev": true, + "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", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/common-ancestor-path": { + "version": "1.0.1", + "dev": true, + "inBundle": true, + "license": "ISC" + }, + "node_modules/npm/node_modules/cross-spawn": { + "version": "7.0.6", + "dev": true, + "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", + "dev": true, + "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", + "dev": true, + "inBundle": true, + "license": "MIT", + "bin": { + "cssesc": "bin/cssesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/npm/node_modules/debug": { + "version": "4.4.1", + "dev": true, + "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.0", + "dev": true, + "inBundle": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/npm/node_modules/eastasianwidth": { + "version": "0.2.0", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/emoji-regex": { + "version": "8.0.0", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/encoding": { + "version": "0.1.13", + "dev": true, + "inBundle": true, + "license": "MIT", + "optional": true, + "dependencies": { + "iconv-lite": "^0.6.2" + } + }, + "node_modules/npm/node_modules/env-paths": { + "version": "2.2.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/npm/node_modules/err-code": { + "version": "2.0.3", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/exponential-backoff": { + "version": "3.1.2", + "dev": true, + "inBundle": true, + "license": "Apache-2.0" + }, + "node_modules/npm/node_modules/fastest-levenshtein": { + "version": "1.0.16", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">= 4.9.1" + } + }, + "node_modules/npm/node_modules/foreground-child": { + "version": "3.3.1", + "dev": true, + "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", + "dev": true, + "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.4.5", + "dev": true, + "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", + "dev": true, + "inBundle": true, + "license": "ISC" + }, + "node_modules/npm/node_modules/hosted-git-info": { + "version": "8.1.0", + "dev": true, + "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", + "dev": true, + "inBundle": true, + "license": "BSD-2-Clause" + }, + "node_modules/npm/node_modules/http-proxy-agent": { + "version": "7.0.2", + "dev": true, + "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", + "dev": true, + "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", + "dev": true, + "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", + "dev": true, + "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", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/npm/node_modules/ini": { + "version": "5.0.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/init-package-json": { + "version": "7.0.2", + "dev": true, + "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": "9.0.5", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "jsbn": "1.1.0", + "sprintf-js": "^1.1.3" + }, + "engines": { + "node": ">= 12" + } + }, + "node_modules/npm/node_modules/ip-regex": { + "version": "5.0.0", + "dev": true, + "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", + "dev": true, + "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", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/npm/node_modules/isexe": { + "version": "2.0.0", + "dev": true, + "inBundle": true, + "license": "ISC" + }, + "node_modules/npm/node_modules/jackspeak": { + "version": "3.4.3", + "dev": true, + "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/jsbn": { + "version": "1.1.0", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/json-parse-even-better-errors": { + "version": "4.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/json-stringify-nice": { + "version": "1.1.4", + "dev": true, + "inBundle": true, + "license": "ISC", + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/npm/node_modules/jsonparse": { + "version": "1.3.1", + "dev": true, + "engines": [ + "node >= 0.2.0" + ], + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/just-diff": { + "version": "6.0.2", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/just-diff-apply": { + "version": "5.5.0", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/libnpmaccess": { + "version": "9.0.0", + "dev": true, + "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.1", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "@npmcli/arborist": "^8.0.1", + "@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": "^6.2.1" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/libnpmexec": { + "version": "9.0.1", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "@npmcli/arborist": "^8.0.1", + "@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.1", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "@npmcli/arborist": "^8.0.1" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/libnpmhook": { + "version": "11.0.0", + "dev": true, + "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", + "dev": true, + "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.1", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "@npmcli/arborist": "^8.0.1", + "@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.1", + "dev": true, + "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", + "dev": true, + "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", + "dev": true, + "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", + "dev": true, + "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", + "dev": true, + "inBundle": true, + "license": "ISC" + }, + "node_modules/npm/node_modules/make-fetch-happen": { + "version": "14.0.3", + "dev": true, + "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/make-fetch-happen/node_modules/negotiator": { + "version": "1.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/npm/node_modules/minimatch": { + "version": "9.0.5", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/npm/node_modules/minipass": { + "version": "7.1.2", + "dev": true, + "inBundle": true, + "license": "ISC", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/npm/node_modules/minipass-collect": { + "version": "2.0.1", + "dev": true, + "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", + "dev": true, + "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", + "dev": true, + "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", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/npm/node_modules/minipass-pipeline": { + "version": "1.2.4", + "dev": true, + "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", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/npm/node_modules/minipass-sized": { + "version": "1.0.3", + "dev": true, + "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", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/npm/node_modules/minizlib": { + "version": "3.0.2", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "minipass": "^7.1.2" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/npm/node_modules/mkdirp": { + "version": "1.0.4", + "dev": true, + "inBundle": true, + "license": "MIT", + "bin": { + "mkdirp": "bin/cmd.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/npm/node_modules/ms": { + "version": "2.1.3", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/mute-stream": { + "version": "2.0.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/node-gyp": { + "version": "11.2.0", + "dev": true, + "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/node-gyp/node_modules/chownr": { + "version": "3.0.0", + "dev": true, + "inBundle": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=18" + } + }, + "node_modules/npm/node_modules/node-gyp/node_modules/mkdirp": { + "version": "3.0.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "bin": { + "mkdirp": "dist/cjs/src/bin.js" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/npm/node_modules/node-gyp/node_modules/tar": { + "version": "7.4.3", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "@isaacs/fs-minipass": "^4.0.0", + "chownr": "^3.0.0", + "minipass": "^7.1.2", + "minizlib": "^3.0.1", + "mkdirp": "^3.0.1", + "yallist": "^5.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/npm/node_modules/node-gyp/node_modules/yallist": { + "version": "5.0.0", + "dev": true, + "inBundle": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=18" + } + }, + "node_modules/npm/node_modules/nopt": { + "version": "8.1.0", + "dev": true, + "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.0", + "dev": true, + "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", + "dev": true, + "inBundle": true, + "license": "ISC", + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/npm-bundled": { + "version": "4.0.0", + "dev": true, + "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.1", + "dev": true, + "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", + "dev": true, + "inBundle": true, + "license": "ISC", + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/npm-package-arg": { + "version": "12.0.2", + "dev": true, + "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", + "dev": true, + "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", + "dev": true, + "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", + "dev": true, + "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", + "dev": true, + "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", + "dev": true, + "inBundle": true, + "license": "BSD-2-Clause", + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/p-map": { + "version": "7.0.3", + "dev": true, + "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", + "dev": true, + "inBundle": true, + "license": "BlueOak-1.0.0" + }, + "node_modules/npm/node_modules/pacote": { + "version": "19.0.1", + "dev": true, + "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": "^6.1.11" + }, + "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", + "dev": true, + "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", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/npm/node_modules/path-scurry": { + "version": "1.11.1", + "dev": true, + "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/postcss-selector-parser": { + "version": "7.1.0", + "dev": true, + "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", + "dev": true, + "inBundle": true, + "license": "ISC", + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/proggy": { + "version": "3.0.0", + "dev": true, + "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", + "dev": true, + "inBundle": true, + "license": "ISC", + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/npm/node_modules/promise-call-limit": { + "version": "3.0.2", + "dev": true, + "inBundle": true, + "license": "ISC", + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/npm/node_modules/promise-retry": { + "version": "2.0.1", + "dev": true, + "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", + "dev": true, + "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", + "dev": true, + "inBundle": true, + "bin": { + "qrcode-terminal": "bin/qrcode-terminal.js" + } + }, + "node_modules/npm/node_modules/read": { + "version": "4.1.0", + "dev": true, + "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", + "dev": true, + "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", + "dev": true, + "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", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/npm/node_modules/safer-buffer": { + "version": "2.1.2", + "dev": true, + "inBundle": true, + "license": "MIT", + "optional": true + }, + "node_modules/npm/node_modules/semver": { + "version": "7.7.2", + "dev": true, + "inBundle": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/npm/node_modules/shebang-command": { + "version": "2.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/npm/node_modules/shebang-regex": { + "version": "3.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/npm/node_modules/signal-exit": { + "version": "4.1.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/npm/node_modules/sigstore": { + "version": "3.1.0", + "dev": true, + "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/sigstore/node_modules/@sigstore/bundle": { + "version": "3.1.0", + "dev": true, + "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/node_modules/@sigstore/core": { + "version": "2.0.0", + "dev": true, + "inBundle": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/sigstore/node_modules/@sigstore/sign": { + "version": "3.1.0", + "dev": true, + "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/node_modules/@sigstore/verify": { + "version": "2.1.1", + "dev": true, + "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/smart-buffer": { + "version": "4.2.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">= 6.0.0", + "npm": ">= 3.0.0" + } + }, + "node_modules/npm/node_modules/socks": { + "version": "2.8.5", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "ip-address": "^9.0.5", + "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", + "dev": true, + "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", + "dev": true, + "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", + "dev": true, + "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", + "dev": true, + "inBundle": true, + "license": "CC-BY-3.0" + }, + "node_modules/npm/node_modules/spdx-expression-parse": { + "version": "4.0.0", + "dev": true, + "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.21", + "dev": true, + "inBundle": true, + "license": "CC0-1.0" + }, + "node_modules/npm/node_modules/sprintf-js": { + "version": "1.1.3", + "dev": true, + "inBundle": true, + "license": "BSD-3-Clause" + }, + "node_modules/npm/node_modules/ssri": { + "version": "12.0.0", + "dev": true, + "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", + "dev": true, + "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", + "dev": true, + "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", + "dev": true, + "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", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/npm/node_modules/supports-color": { + "version": "9.4.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/npm/node_modules/tar": { + "version": "6.2.1", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "chownr": "^2.0.0", + "fs-minipass": "^2.0.0", + "minipass": "^5.0.0", + "minizlib": "^2.1.1", + "mkdirp": "^1.0.3", + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/npm/node_modules/tar/node_modules/fs-minipass": { + "version": "2.1.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/npm/node_modules/tar/node_modules/fs-minipass/node_modules/minipass": { + "version": "3.3.6", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/npm/node_modules/tar/node_modules/minipass": { + "version": "5.0.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "engines": { + "node": ">=8" + } + }, + "node_modules/npm/node_modules/tar/node_modules/minizlib": { + "version": "2.1.2", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "minipass": "^3.0.0", + "yallist": "^4.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/npm/node_modules/tar/node_modules/minizlib/node_modules/minipass": { + "version": "3.3.6", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/npm/node_modules/text-table": { + "version": "0.2.0", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/tiny-relative-date": { + "version": "1.3.0", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/tinyglobby": { + "version": "0.2.14", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "fdir": "^6.4.4", + "picomatch": "^4.0.2" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, + "node_modules/npm/node_modules/tinyglobby/node_modules/fdir": { + "version": "6.4.6", + "dev": true, + "inBundle": true, + "license": "MIT", + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/npm/node_modules/tinyglobby/node_modules/picomatch": { + "version": "4.0.2", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/npm/node_modules/treeverse": { + "version": "3.0.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/tuf-js": { + "version": "3.0.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "@tufjs/models": "3.0.1", + "debug": "^4.3.6", + "make-fetch-happen": "^14.0.1" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/tuf-js/node_modules/@tufjs/models": { + "version": "3.0.1", + "dev": true, + "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", + "dev": true, + "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", + "dev": true, + "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", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/validate-npm-package-license": { + "version": "3.0.4", + "dev": true, + "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", + "dev": true, + "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.1", + "dev": true, + "inBundle": true, + "license": "ISC", + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/walk-up-path": { + "version": "3.0.1", + "dev": true, + "inBundle": true, + "license": "ISC" + }, + "node_modules/npm/node_modules/which": { + "version": "5.0.0", + "dev": true, + "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.1", + "dev": true, + "inBundle": true, + "license": "ISC", + "engines": { + "node": ">=16" + } + }, + "node_modules/npm/node_modules/wrap-ansi": { + "version": "8.1.0", + "dev": true, + "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", + "dev": true, + "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", + "dev": true, + "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.1.0", + "dev": true, + "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", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/wrap-ansi/node_modules/string-width": { + "version": "5.1.2", + "dev": true, + "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.1.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "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", + "dev": true, + "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": "4.0.0", + "dev": true, + "inBundle": true, + "license": "ISC" + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, + "license": "ISC", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ora": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/ora/-/ora-5.4.1.tgz", + "integrity": "sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "bl": "^4.1.0", + "chalk": "^4.1.0", + "cli-cursor": "^3.1.0", + "cli-spinners": "^2.5.0", + "is-interactive": "^1.0.0", + "is-unicode-supported": "^0.1.0", + "log-symbols": "^4.1.0", + "strip-ansi": "^6.0.0", + "wcwidth": "^1.0.1" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "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==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-map": "^7.0.1" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-is-promise": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-is-promise/-/p-is-promise-3.0.0.tgz", + "integrity": "sha512-Wo8VsW4IRQSKVXsJCn7TomUaVtyfjVDn3nUP7kE967BQk0CwFpdbZs0X0uk5sW9mkBa9eNM7hCMaG93WUAwxYQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-map": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-7.0.3.tgz", + "integrity": "sha512-VkndIv2fIB99swvQoA65bm+fsmt6UNdGeIB0oxBs+WhAhdh08QA04JXpI7rbB9r08/nkbysKoya9rtDERYOYMA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-reduce": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/p-reduce/-/p-reduce-2.1.0.tgz", + "integrity": "sha512-2USApvnsutq8uoxZBGbbWM0JIYLiEMJ9RlaN7fAzVNb9OZN0SHjjTTfIcb667XynS5Y1VhwDJVDa72TnPzAYWw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "license": "MIT", + "dependencies": { + "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==", + "dev": true, + "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-passwd": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz", + "integrity": "sha512-1Y1A//QUXEZK7YKz+rD9WydcE1+EuPr6ZBgKecAB8tmoW6UFv0NREVJe1p+jRxtThkcbbKkfwIbWJe/IeE6m2Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true, + "license": "MIT" + }, + "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==", + "dev": true, + "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==", + "dev": true, + "license": "ISC" + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=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==", + "dev": true, + "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==", + "dev": true, + "license": "MIT", + "dependencies": { + "find-up": "^2.0.0", + "load-json-file": "^4.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/pkg-conf/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==", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/pkg-conf/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==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/pkg-conf/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==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-try": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/pkg-conf/node_modules/p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha512-nQja7m7gSKuewoVRen45CtVfODR3crN3goVQ0DDZ9N3yHxgpkuBhZqsaiotSQRrADUrne346peY7kT3TSACykg==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^1.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/pkg-conf/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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/pkg-conf/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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "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==", + "dev": true, + "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==", + "dev": true, + "license": "ISC" + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/quick-lru": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-4.0.1.tgz", + "integrity": "sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/rc": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", + "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", + "dev": true, + "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/rc/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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "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==", + "dev": true, + "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-up": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-11.0.0.tgz", + "integrity": "sha512-LOVbvF1Q0SZdjClSefZ0Nz5z8u+tIE7mV5NibzmE9VYmDe9CaBbAVtz1veOSZbofrdsilxuDAYnFenukZVp8/Q==", + "deprecated": "Renamed to read-package-up", + "dev": true, + "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-up/node_modules/type-fest": { + "version": "4.41.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.41.0.tgz", + "integrity": "sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=16" + }, + "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==", + "dev": true, + "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/type-fest": { + "version": "4.41.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.41.0.tgz", + "integrity": "sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=16" + }, + "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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dev": true, + "license": "MIT", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/redent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz", + "integrity": "sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==", + "dev": true, + "license": "MIT", + "dependencies": { + "indent-string": "^4.0.0", + "strip-indent": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/redeyed": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/redeyed/-/redeyed-2.1.1.tgz", + "integrity": "sha512-FNpGGo1DycYAdnrKFxCMmKYgo/mILAqtRYbkdQD8Ep/Hk2PQ5+aEAEx+IU713RTDmuBaH0c8P5ZozurNu5ObRQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "esprima": "~4.0.0" + } + }, + "node_modules/registry-auth-token": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-5.1.0.tgz", + "integrity": "sha512-GdekYuwLXLxMuFTwAPg5UKGLW/UXzQrZvH/Zj791BQif5T05T0RsaLfHc9q3ZOKi7n+BoprPD9mJ0O0k4xzUlw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@pnpm/npm-conf": "^2.1.0" + }, + "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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/resolve": { + "version": "1.22.10", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.10.tgz", + "integrity": "sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-core-module": "^2.16.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve-dir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/resolve-dir/-/resolve-dir-1.0.1.tgz", + "integrity": "sha512-R7uiTjECzvOsWSfdM0QKFNBVFcK27aHOUwdvK53BcW8zqnGdYp0Fbj82cy54+2A4P2tFM22J5kRfe1R+lM/1yg==", + "dev": true, + "license": "MIT", + "dependencies": { + "expand-tilde": "^2.0.0", + "global-modules": "^1.0.0" + }, + "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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/resolve-global": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/resolve-global/-/resolve-global-1.0.0.tgz", + "integrity": "sha512-zFa12V4OLtT5XUX/Q4VLvTfBf+Ok0SPc1FNGM/z9ctUdiU618qwKpWnd0CHs3+RqROfyEg/DhuHbMWYqcgljEw==", + "dev": true, + "license": "MIT", + "dependencies": { + "global-dirs": "^0.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/restore-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", + "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", + "dev": true, + "license": "MIT", + "dependencies": { + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/reusify": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", + "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==", + "dev": true, + "license": "MIT", + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/run-async": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz", + "integrity": "sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/rxjs": { + "version": "7.8.2", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.2.tgz", + "integrity": "sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.1.0" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true, + "license": "MIT" + }, + "node_modules/semantic-release": { + "version": "22.0.12", + "resolved": "https://registry.npmjs.org/semantic-release/-/semantic-release-22.0.12.tgz", + "integrity": "sha512-0mhiCR/4sZb00RVFJIUlMuiBkW3NMpVIW2Gse7noqEMoFGkvfPPAImEQbkBV8xga4KOPP4FdTRYuLLy32R1fPw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@semantic-release/commit-analyzer": "^11.0.0", + "@semantic-release/error": "^4.0.0", + "@semantic-release/github": "^9.0.0", + "@semantic-release/npm": "^11.0.0", + "@semantic-release/release-notes-generator": "^12.0.0", + "aggregate-error": "^5.0.0", + "cosmiconfig": "^8.0.0", + "debug": "^4.0.0", + "env-ci": "^10.0.0", + "execa": "^8.0.0", + "figures": "^6.0.0", + "find-versions": "^5.1.0", + "get-stream": "^6.0.0", + "git-log-parser": "^1.2.0", + "hook-std": "^3.0.0", + "hosted-git-info": "^7.0.0", + "import-from-esm": "^1.3.1", + "lodash-es": "^4.17.21", + "marked": "^9.0.0", + "marked-terminal": "^6.0.0", + "micromatch": "^4.0.2", + "p-each-series": "^3.0.0", + "p-reduce": "^3.0.0", + "read-pkg-up": "^11.0.0", + "resolve-from": "^5.0.0", + "semver": "^7.3.2", + "semver-diff": "^4.0.0", + "signale": "^1.2.1", + "yargs": "^17.5.1" + }, + "bin": { + "semantic-release": "bin/semantic-release.js" + }, + "engines": { + "node": "^18.17 || >=20.6.1" + } + }, + "node_modules/semantic-release/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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/semantic-release/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==", + "dev": true, + "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/semantic-release/node_modules/clean-stack": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-5.2.0.tgz", + "integrity": "sha512-TyUIUJgdFnCISzG5zu3291TAsE77ddchd0bepon1VVQrKLGKFED4iXFEDQ24mIPdPBbyE16PK3F8MYE1CmcBEQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "escape-string-regexp": "5.0.0" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/semantic-release/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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/semantic-release/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==", + "dev": true, + "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/semantic-release/node_modules/execa/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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/semantic-release/node_modules/figures": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-6.1.0.tgz", + "integrity": "sha512-d+l3qxjSesT4V7v2fh+QnmFnUWv9lSpjarhShNTgBOfA0ttejbQUAlHLitbjkoRiDulW0OPoQPYIGhIC8ohejg==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-unicode-supported": "^2.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/semantic-release/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==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=16.17.0" + } + }, + "node_modules/semantic-release/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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/semantic-release/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==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/semantic-release/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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/semantic-release/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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/semantic-release/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==", + "dev": true, + "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/semantic-release/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==", + "dev": true, + "license": "MIT", + "dependencies": { + "mimic-fn": "^4.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/semantic-release/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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/semantic-release/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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/semantic-release/node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/semantic-release/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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/semver": { + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", + "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", + "dev": true, + "license": "ISC", + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/semver-diff": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/semver-diff/-/semver-diff-4.0.0.tgz", + "integrity": "sha512-0Ju4+6A8iOnpL/Thra7dZsSlOHYAHIeMxfhWQRI1/VLcT3WDBZKKtQt/QkBOsiIN9ZpuvHE6cGZ0x4glCMmfiA==", + "dev": true, + "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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/semver/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "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==", + "dev": true, + "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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "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==", + "dev": true, + "license": "ISC" + }, + "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==", + "dev": true, + "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==", + "dev": true, + "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==", + "dev": true, + "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==", + "dev": true, + "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==", + "dev": true, + "license": "MIT" + }, + "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==", + "dev": true, + "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==", + "dev": true, + "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==", + "dev": true, + "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==", + "dev": true, + "license": "MIT", + "dependencies": { + "unicode-emoji-modifier-base": "^1.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/slash": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-5.1.0.tgz", + "integrity": "sha512-ZA6oR3T/pEyuqwMgAKT0/hAv8oAXckzbkmR0UkUosQ+Mc4RxGoJkRmwHgHufaenlyAgE1Mxgpdcrf75y6XcnDg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "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==", + "dev": true, + "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==", + "dev": true, + "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==", + "dev": true, + "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==", + "dev": true, + "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==", + "dev": true, + "license": "MIT", + "dependencies": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-license-ids": { + "version": "3.0.22", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.22.tgz", + "integrity": "sha512-4PRT4nh1EImPbt2jASOKHX7PB7I+e4IWNLvkKFDxNhJlfjbYlleYQh285Z/3mPTHSAK/AvdMmw5BNNuYH8ShgQ==", + "dev": true, + "license": "CC0-1.0" + }, + "node_modules/split2": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz", + "integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">= 10.x" + } + }, + "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==", + "dev": true, + "license": "MIT", + "dependencies": { + "duplexer2": "~0.1.0", + "readable-stream": "^2.0.2" + } + }, + "node_modules/stream-combiner2/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==", + "dev": true, + "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/stream-combiner2/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==", + "dev": true, + "license": "MIT" + }, + "node_modules/stream-combiner2/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==", + "dev": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dev": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.2.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==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-bom": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", + "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/strip-indent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz", + "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "min-indent": "^1.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "license": "MIT", + "dependencies": { + "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==", + "dev": true, + "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/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.16" + } + }, + "node_modules/tempy": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/tempy/-/tempy-3.1.0.tgz", + "integrity": "sha512-7jDLIdD2Zp0bDe5r3D2qtkd1QOCacylBuL7oa4udvN6v2pqr4+LcCr67C8DR1zkpaZ8XosF5m1yQSabKAW6f2g==", + "dev": true, + "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==", + "dev": true, + "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==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=12.20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/text-extensions": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/text-extensions/-/text-extensions-2.4.0.tgz", + "integrity": "sha512-te/NtwBwfiNRLf9Ijqx3T0nlqZiQ2XrrtBvu+cLL8ZRrGkO0NHTug8MYFKyoSrv/sHTaSKfilUkizV6XhxMJ3g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", + "dev": true, + "license": "MIT" + }, + "node_modules/through2": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/through2/-/through2-4.0.2.tgz", + "integrity": "sha512-iOqSav00cVxEEICeD7TjLB1sueEL+81Wpzp2bY17uZjZN0pWZPuo4suZ/61VujxmqSGFfgOcNuTZ85QJwNZQpw==", + "dev": true, + "license": "MIT", + "dependencies": { + "readable-stream": "3" + } + }, + "node_modules/tmp": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", + "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "dev": true, + "license": "MIT", + "dependencies": { + "os-tmpdir": "~1.0.2" + }, + "engines": { + "node": ">=0.6.0" + } + }, + "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==", + "dev": true, + "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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/trim-newlines": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-3.0.1.tgz", + "integrity": "sha512-c1PTsA3tYrIsLGkJkzHF+w9F2EyxfXGo4UyJc4pFL++FMjnq0HJS69T3M7d//gKrFKwy429bouPescbjecU+Zw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "dev": true, + "license": "0BSD" + }, + "node_modules/type-fest": { + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/typescript": { + "version": "5.9.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.2.tgz", + "integrity": "sha512-CWBzXQrc/qOkhidw1OzBTQuYRbfyxDXJMVJ1XNwUHGROVmuaeiEm3OslpZ1RV96d7SKKjZKrSJu3+t/xlw3R9A==", + "dev": true, + "license": "Apache-2.0", + "peer": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "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==", + "dev": true, + "license": "BSD-2-Clause", + "optional": true, + "bin": { + "uglifyjs": "bin/uglifyjs" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/undici-types": { + "version": "7.10.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.10.0.tgz", + "integrity": "sha512-t5Fy/nfn+14LuOc2KNYg75vZqClpAiqscVvMygNnlsHBFpSXdJaYtXMcdNLpl/Qvc3P2cB3s6lOV51nqsFq4ag==", + "dev": true, + "license": "MIT", + "peer": true + }, + "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==", + "dev": true, + "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==", + "dev": true, + "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==", + "dev": true, + "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": "6.0.1", + "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-6.0.1.tgz", + "integrity": "sha512-yCzhz6FN2wU1NiiQRogkTQszlQSlpWaw8SvVegAc+bDxbzHgh1vX8uIe8OYyMH6DwH+sdTJsgMl36+mSMdRJIQ==", + "dev": true, + "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==", + "dev": true, + "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==", + "dev": true, + "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==", + "dev": true, + "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==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, + "node_modules/wcwidth": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", + "integrity": "sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==", + "dev": true, + "license": "MIT", + "dependencies": { + "defaults": "^1.0.3" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/word-wrap": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/wordwrap": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", + "integrity": "sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==", + "dev": true, + "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==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "dev": true, + "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==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true, + "license": "ISC" + }, + "node_modules/yargs": { + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "dev": true, + "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==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..84c4265 --- /dev/null +++ b/package.json @@ -0,0 +1,23 @@ +{ + "name": "hatchling", + "private": true, + "scripts": { + "commit": "cz", + "semantic-release": "semantic-release" + }, + "devDependencies": { + "semantic-release": "^22.0.12", + "@semantic-release/changelog": "^6.0.3", + "@semantic-release/git": "^10.0.1", + "@semantic-release/github": "^9.2.6", + "commitizen": "^4.3.0", + "@commitlint/cli": "^18.6.1", + "@commitlint/config-conventional": "^18.6.2", + "cz-conventional-changelog": "^3.3.0" + }, + "config": { + "commitizen": { + "path": "./node_modules/cz-conventional-changelog" + } + } +} diff --git a/pyproject.toml b/pyproject.toml index 4e71916..c12c6df 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "hatchling" -dynamic = ["version"] +version = "0.4.0" description = "LLM with MCP Tool Calling" readme = "README.md" requires-python = ">=3.12" @@ -49,8 +49,7 @@ where = ["."] [tool.setuptools.package-data] hatchling = ["config/languages/*.toml"] -[tool.setuptools.dynamic] -version = {file = "VERSION"} + [project.urls] "Repository" = "https://github.com/CrackingShells/Hatchling" \ No newline at end of file diff --git a/scripts/prepare_version.py b/scripts/prepare_version.py deleted file mode 100755 index 3bf9f11..0000000 --- a/scripts/prepare_version.py +++ /dev/null @@ -1,37 +0,0 @@ -#!/usr/bin/env python3 -""" -Build helper script that prepares the VERSION file for setuptools. -This should be run before building the package. -""" - -import os -import sys -from pathlib import Path - -# Add the scripts directory to Python path -script_dir = Path(__file__).parent -sys.path.insert(0, str(script_dir)) - -from version_manager import VersionManager - -def main(): - """Convert VERSION.meta to simple VERSION format for setuptools.""" - try: - vm = VersionManager() - - # Read from VERSION.meta (structured format) - version_data = vm.read_version_file() - version_string = vm.get_version_string(version_data) - - # Write both files: keep VERSION.meta unchanged, update VERSION for setuptools - vm.write_simple_version_file(version_data) - - print(f"VERSION file prepared for build: {version_string.lstrip('v')}") - print("VERSION.meta preserved with structured format") - - except Exception as e: - print(f"Error preparing VERSION file: {e}", file=sys.stderr) - sys.exit(1) - -if __name__ == '__main__': - main() \ No newline at end of file diff --git a/scripts/tag_cleanup.py b/scripts/tag_cleanup.py deleted file mode 100644 index 673477b..0000000 --- a/scripts/tag_cleanup.py +++ /dev/null @@ -1,94 +0,0 @@ -#!/usr/bin/env python3 -""" -Tag cleanup helper script for CI/CD. -Removes old build and dev tags according to project policy. -""" - -import subprocess -import re -import sys -from datetime import datetime, timedelta -from typing import List, Tuple - -def get_all_tags() -> List[Tuple[str, str]]: - """Get all tags with their creation dates.""" - try: - result = subprocess.run( - ['git', 'for-each-ref', '--format=%(refname:short)|%(creatordate:iso8601)', 'refs/tags'], - capture_output=True, - text=True, - check=True - ) - tags = [] - for line in result.stdout.strip().split('\n'): - if '|' in line: - tag, date_str = line.split('|', 1) - tags.append((tag, date_str)) - return tags - except subprocess.CalledProcessError: - return [] - -def is_build_tag(tag: str) -> bool: - """Check if tag is a build tag (contains +build followed by number).""" - return bool(re.search(r'\+build\d+$', tag)) - -def is_dev_tag(tag: str) -> bool: - """Check if tag is a dev tag (contains .dev).""" - return bool(re.search(r'\.dev\d+', tag)) - -def is_old_tag(date_str: str, days: int = 30) -> bool: - """Check if tag is older than specified days.""" - try: - tag_date = datetime.fromisoformat(date_str.replace('Z', '+00:00')) - cutoff_date = datetime.now().astimezone() - timedelta(days=days) - return tag_date < cutoff_date - except Exception: - return False - -def main(): - dry_run = sys.argv[1].lower() == 'true' if len(sys.argv) > 1 else True - - all_tags = get_all_tags() - if not all_tags: - print("No tags found.") - return - - tags_to_delete = [] - for tag, date_str in all_tags: - should_delete = False - reason = "" - if is_build_tag(tag) and is_old_tag(date_str, 7): - should_delete = True - reason = "old build tag (>7 days)" - elif is_dev_tag(tag) and is_old_tag(date_str, 30): - should_delete = True - reason = "old dev tag (>30 days)" - if should_delete: - tags_to_delete.append((tag, reason)) - - if not tags_to_delete: - print("No tags need cleanup.") - return - - print(f"Found {len(tags_to_delete)} tags for cleanup:") - for tag, reason in tags_to_delete: - print(f" - {tag} ({reason})") - - if dry_run: - print("\\nDry run mode - no tags were actually deleted.") - return - - deleted_count = 0 - for tag, reason in tags_to_delete: - try: - subprocess.run(['git', 'tag', '-d', tag], check=True, capture_output=True) - subprocess.run(['git', 'push', 'origin', '--delete', tag], check=True, capture_output=True) - print(f"Deleted {tag} ({reason})") - deleted_count += 1 - except subprocess.CalledProcessError as e: - print(f"Failed to delete {tag}: {e}") - - print(f"\\nDeleted {deleted_count} tags.") - -if __name__ == '__main__': - main() \ No newline at end of file diff --git a/scripts/version_manager.py b/scripts/version_manager.py deleted file mode 100755 index a5d369a..0000000 --- a/scripts/version_manager.py +++ /dev/null @@ -1,327 +0,0 @@ -#!/usr/bin/env python3 -""" -Version management script for Hatchling with dual-file system. - -This script manages two version files: -- VERSION.meta: Structured, human-readable format with detailed version components -- VERSION: Simple format for setuptools compatibility - -The dual-file system preserves detailed version information while maintaining -compatibility with Python packaging tools. -""" - -import os -import sys -import argparse -import subprocess -from pathlib import Path -from typing import Dict, Tuple, Optional - - -class VersionManager: - def __init__(self, version_file_path: str = "VERSION"): - self.version_file = Path(version_file_path) - self.version_meta_file = Path(str(version_file_path) + ".meta") - - # Check if we have a structured meta file, otherwise try to read from VERSION - if not self.version_meta_file.exists() and not self.version_file.exists(): - raise FileNotFoundError(f"Neither VERSION file nor VERSION.meta found at {version_file_path}") - - # If VERSION.meta doesn't exist but VERSION does, create it from current VERSION - if not self.version_meta_file.exists() and self.version_file.exists(): - self._create_meta_from_simple_version() - - def _create_meta_from_simple_version(self) -> None: - """Create VERSION.meta from a simple VERSION file if it doesn't exist.""" - try: - with open(self.version_file, 'r') as f: - simple_version = f.read().strip() - - # Parse the simple version string to extract components - # Example: "0.4.0.dev0+build0" -> MAJOR=0, MINOR=4, PATCH=0, DEV_NUMBER=0, BUILD_NUMBER=0 - version_parts = simple_version.replace('+build', '.build').replace('.dev', '.dev').split('.') - - major, minor, patch = version_parts[0], version_parts[1], version_parts[2] - dev_number = "" - build_number = "" - - for part in version_parts[3:]: - if part.startswith('dev'): - dev_number = part[3:] - elif part.startswith('build'): - build_number = part[5:] - - # Get current branch - branch = self.get_current_branch() - - # Write structured format to VERSION.meta - version_data = { - 'MAJOR': major, - 'MINOR': minor, - 'PATCH': patch, - 'DEV_NUMBER': dev_number, - 'BUILD_NUMBER': build_number, - 'BRANCH': branch - } - self.write_version_meta_file(version_data) - - except Exception as e: - # If we can't parse, create a default meta file - default_data = { - 'MAJOR': '0', - 'MINOR': '0', - 'PATCH': '0', - 'DEV_NUMBER': '', - 'BUILD_NUMBER': '', - 'BRANCH': self.get_current_branch() - } - self.write_version_meta_file(default_data) - - def read_version_file(self) -> Dict[str, str]: - """Read the VERSION.meta file and parse version components.""" - version_data = {} - - # Always read from VERSION.meta for structured data - if self.version_meta_file.exists(): - with open(self.version_meta_file, 'r') as f: - for line in f: - line = line.strip() - if '=' in line and not line.startswith('#'): - key, value = line.split('=', 1) - version_data[key.strip()] = value.strip() - else: - # Fallback: try to create from simple VERSION file - self._create_meta_from_simple_version() - return self.read_version_file() - - return version_data - - def write_version_file(self, version_data: Dict[str, str]) -> None: - """Write version data to both VERSION.meta (structured) and VERSION (simple).""" - # Write structured format to VERSION.meta - self.write_version_meta_file(version_data) - - # Write simple format to VERSION for setuptools compatibility - self.write_simple_version_file(version_data) - - def write_version_meta_file(self, version_data: Dict[str, str]) -> None: - """Write version data to VERSION.meta in structured format.""" - with open(self.version_meta_file, 'w') as f: - f.write("# Structured version file for human readability and CI/CD\n") - f.write("# This file maintains detailed version component information\n") - f.write("# The companion VERSION file contains the simple format for setuptools\n\n") - for key in ['MAJOR', 'MINOR', 'PATCH', 'DEV_NUMBER', 'BUILD_NUMBER', 'BRANCH']: - value = version_data.get(key, '') - f.write(f"{key}={value}\n") - - def write_simple_version_file(self, version_data: Optional[Dict[str, str]] = None) -> None: - """Write a simple version string to VERSION file for setuptools compatibility.""" - if version_data is None: - version_data = self.read_version_file() - - version_string = self.get_version_string(version_data) - # Remove 'v' prefix for setuptools - simple_version = version_string.lstrip('v') - - # Write to VERSION file in simple format for setuptools - with open(self.version_file, 'w') as f: - f.write(simple_version) - - def get_version_string(self, version_data: Optional[Dict[str, str]] = None) -> str: - """Generate semantic version string from version data.""" - if version_data is None: - version_data = self.read_version_file() - - major = version_data.get('MAJOR', '1') - minor = version_data.get('MINOR', '0') - patch = version_data.get('PATCH', '0') - dev_number = version_data.get('DEV_NUMBER', '') - build_number = version_data.get('BUILD_NUMBER', '') - - version = f"v{major}.{minor}.{patch}" - - if dev_number: - version += f".dev{dev_number}" - - if build_number: - version += f"+build{build_number}" - - return version - - def get_current_branch(self) -> str: - """Get the current git branch.""" - try: - result = subprocess.run( - ['git', 'rev-parse', '--abbrev-ref', 'HEAD'], - capture_output=True, - text=True, - check=True - ) - return result.stdout.strip() - except subprocess.CalledProcessError: - return "unknown" - - def increment_version(self, increment_type: str, branch: str = None) -> Dict[str, str]: - """Increment version based on type and branch.""" - version_data = self.read_version_file() - - if branch is None: - branch = self.get_current_branch() - - major = int(version_data.get('MAJOR', '1')) - minor = int(version_data.get('MINOR', '0')) - patch = int(version_data.get('PATCH', '0')) - dev_number = int(version_data.get('DEV_NUMBER', '0')) if version_data.get('DEV_NUMBER', '') else 0 - build_number = int(version_data.get('BUILD_NUMBER', '0')) if version_data.get('BUILD_NUMBER', '') else 0 - - # Handle different increment types - if increment_type == 'major': - major += 1 - minor = 0 - patch = 0 - elif increment_type == 'minor': - minor += 1 - patch = 0 - elif increment_type == 'patch': - patch += 1 - elif increment_type == 'dev': - dev_number += 1 - elif increment_type == 'build': - build_number += 1 - - # Set dev_number and build_number based on branch - dev_num_str = "" - build_num_str = "" - - if branch == 'main': - # Main branch gets clean releases - dev_num_str = "" - build_num_str = "" - elif branch == 'dev': - # Dev branch gets dev prerelease - dev_num_str = str(dev_number) if dev_number > 0 else "" - build_num_str = "" - elif branch.startswith('feat/') or branch.startswith('fix/'): - # Feature/fix branches get dev prerelease with build number - dev_num_str = str(dev_number) # Always include dev number for feat/fix branches - build_num_str = str(build_number) if build_number > 0 else "" - else: - # Other branches get dev prerelease - dev_num_str = str(dev_number) if dev_number > 0 else "" - build_num_str = "" - - return { - 'MAJOR': str(major), - 'MINOR': str(minor), - 'PATCH': str(patch), - 'DEV_NUMBER': dev_num_str, - 'BUILD_NUMBER': build_num_str, - 'BRANCH': branch - } - - def update_version_for_branch(self, branch: str = None) -> str: - """Update version based on branch type.""" - if branch is None: - branch = self.get_current_branch() - - current_data = self.read_version_file() - new_data = current_data.copy() - - if branch.startswith('feat/'): - - if current_data.get('BRANCH') == 'main': #it means we are creating a new feature branch - #increment minor version - new_data = self.increment_version('minor', branch) #takes care of incrementing and updating the branch field - new_data['DEV_NUMBER'] = '0' # Reset dev number for new feature branch - new_data['BUILD_NUMBER'] = '0' # Start with build0 - - else: #it means we are updating an existing feature branch, whether from dev or `feat/` - # Increment build number for the same feature branch - new_data = self.increment_version('build', branch) - - elif branch.startswith('fix/'): - # If current branch is the same as the one in VERSION.meta, - # increment the build number - if current_data.get('BRANCH') == branch: - # Increment build number for the same fix branch - new_data = self.increment_version('build', branch) - - # If the current branch is a fix branch but not the same as the one in VERSION.meta, - # increment the patch version, but don't change the build number - elif current_data.get('BRANCH').startswith('fix/'): - new_data = self.increment_version('patch', branch) - - else: #it means we are creating a new fix branch - new_data = self.increment_version('patch', branch) #takes care of incrementing and updating the branch field - new_data['BUILD_NUMBER'] = '0' # Start with build0 - - elif branch == 'main': - # Main branch gets clean releases - new_data = current_data.copy() - new_data['DEV_NUMBER'] = '' - new_data['BUILD_NUMBER'] = '' - - else: # Dev and other branches - # If starting from main (there was a rebased dev on a clean - # release), reset dev and build numbers - if current_data.get('BRANCH') == 'main': - new_data = self.increment_version('minor', branch) - new_data['DEV_NUMBER'] = '0' - - # If updating from another branch (fix, feat, dev itself, or docs, etc.), - # increment dev number and reset build number - else: - new_data = self.increment_version('dev', branch) - - new_data['BUILD_NUMBER'] = '' - - # Update branch field - new_data['BRANCH'] = branch - - self.write_version_file(new_data) - return self.get_version_string(new_data) - - def write_simple_version(self) -> None: - """Write a simple version string for setuptools compatibility.""" - version_data = self.read_version_file() - self.write_simple_version_file(version_data) - - -def main(): - parser = argparse.ArgumentParser(description='Manage project version using dual-file system (VERSION.meta + VERSION)') - parser.add_argument('--get', action='store_true', help='Get current version string') - parser.add_argument('--increment', choices=['major', 'minor', 'patch', 'dev', 'build'], - help='Increment version component (updates both VERSION.meta and VERSION)') - parser.add_argument('--update-for-branch', metavar='BRANCH', - help='Update version for specific branch (updates both files)') - parser.add_argument('--simple', action='store_true', - help='Write simple version format to VERSION file (from VERSION.meta)') - parser.add_argument('--branch', help='Override current branch detection') - - args = parser.parse_args() - - try: - vm = VersionManager() - - if args.get: - print(vm.get_version_string()) - elif args.increment: - new_data = vm.increment_version(args.increment, args.branch) - vm.write_version_file(new_data) - print(vm.get_version_string(new_data)) - elif args.update_for_branch is not None: - version = vm.update_version_for_branch(args.update_for_branch) - print(version) - elif args.simple: - vm.write_simple_version() - print("Simple version written to VERSION file") - else: - print(vm.get_version_string()) - - except Exception as e: - print(f"Error: {e}", file=sys.stderr) - sys.exit(1) - - -if __name__ == '__main__': - main() \ No newline at end of file From 2dfd324689062f9622b5c9468414133aa6493a88 Mon Sep 17 00:00:00 2001 From: LittleCoinCoin Date: Tue, 26 Aug 2025 09:50:54 +0900 Subject: [PATCH 2/4] docs(dev): remove design reports **Major**: - Cleaning up the context documentation used for the CI update to `semantic-release` --- LLM_Reports/Architecture_Analysis_Report.md | 164 ---- .../GitHub_Specific_Solutions_Report.md | 503 ----------- LLM_Reports/Industry_Best_Practices_Report.md | 324 ------- ...ntegrated_Automated_Versioning_Strategy.md | 842 ------------------ .../Semantic_Release_Migration_Plan.md | 689 -------------- .../Semantic_Release_Migration_Plan_v2.md | 733 --------------- LLM_Reports/Workflow_Optimization_Report.md | 555 ------------ 7 files changed, 3810 deletions(-) delete mode 100644 LLM_Reports/Architecture_Analysis_Report.md delete mode 100644 LLM_Reports/GitHub_Specific_Solutions_Report.md delete mode 100644 LLM_Reports/Industry_Best_Practices_Report.md delete mode 100644 LLM_Reports/Integrated_Automated_Versioning_Strategy.md delete mode 100644 LLM_Reports/Semantic_Release_Migration_Plan.md delete mode 100644 LLM_Reports/Semantic_Release_Migration_Plan_v2.md delete mode 100644 LLM_Reports/Workflow_Optimization_Report.md diff --git a/LLM_Reports/Architecture_Analysis_Report.md b/LLM_Reports/Architecture_Analysis_Report.md deleted file mode 100644 index c071be8..0000000 --- a/LLM_Reports/Architecture_Analysis_Report.md +++ /dev/null @@ -1,164 +0,0 @@ -# Architecture Analysis Report: Hatchling Automated Versioning System - -## Executive Summary - -The Hatchling repository implements a sophisticated automated versioning system that combines Python helper scripts with GitHub Actions workflows to manage semantic versioning across multiple branches. The system uses a dual-file approach (VERSION and VERSION.meta) and attempts to work around branch protection rules through a complex PR-based workflow. - -**Current Status**: The system is experiencing critical issues with infinite workflow loops and branch protection conflicts, requiring immediate architectural review. - -## System Components Overview - -### 1. Helper Scripts (`/scripts/`) - -#### `version_manager.py` (327 lines) -**Purpose**: Core versioning logic with dual-file system management -**Key Features**: -- Manages VERSION (simple format) and VERSION.meta (structured format) -- Implements branch-specific versioning rules -- Supports semantic versioning with dev/build suffixes -- Handles version increments based on branch type - -**Versioning Rules**: -- `main`: Clean releases (no dev/build suffixes) -- `dev`: Development prereleases with dev numbers -- `feat/*`: Minor version increment + dev/build numbers -- `fix/*`: Patch version increment + dev/build numbers - -**Strengths**: -- Comprehensive versioning logic -- Dual-file system preserves metadata while maintaining setuptools compatibility -- Branch-aware version management -- Well-structured Python code - -**Weaknesses**: -- Complex branching logic that may be difficult to maintain -- No validation of version consistency across branches -- Limited error handling for edge cases - -#### `prepare_version.py` (37 lines) -**Purpose**: Build-time VERSION file preparation for setuptools -**Function**: Converts VERSION.meta to simple VERSION format -**Assessment**: Simple, focused utility with clear purpose - -#### `tag_cleanup.py` (94 lines) -**Purpose**: Automated cleanup of old development and build tags -**Features**: -- Removes build tags older than 7 days -- Removes dev tags older than 30 days -- Dry-run capability -**Assessment**: Well-designed maintenance utility - -### 2. GitHub Actions Workflows (`/.github/workflows/`) - -#### Core Versioning Workflows - -**`test_build.yml`** (Reusable workflow) -- Updates VERSION files based on branch -- Builds and tests package -- Uploads VERSION artifacts -- **Status**: Functional, well-designed - -**`commit_version_tag.yml`** (84 lines) -- **Triggers**: Push to dev, main, feat/*, fix/* -- **Function**: Creates version-bump PR to main -- **Critical Issues**: - - Uses GitHub App token but still creates PR workflow - - Potential for infinite loops with other workflows - - Complex dependency chain - -**`auto_merge_version_bump.yml`** (110 lines) -- **Triggers**: Completion of "Validate PR Branches to Main" workflow -- **Function**: Auto-merges version-bump PRs -- **Critical Issues**: - - Workflow chaining creates complex dependencies - - Risk of infinite loops - - Multiple points of failure - -**`validate-pr-to-main.yml`** (18 lines) -- **Function**: Validates PR branch names and authors -- **Issues**: Triggers validation workflow that feeds into auto-merge - -**`validate-pr-branch-common.yml`** (142 lines) -- **Function**: Reusable PR validation logic -- **Features**: Organization membership checks, app authentication -- **Assessment**: Well-designed but complex - -**`create_tag_on_main.yml`** (35 lines) -- **Triggers**: Push to main with version update commit message -- **Function**: Creates git tags for releases -- **Assessment**: Simple and focused - -## Current Architecture Flow - -``` -Push to dev/feat/fix → commit_version_tag.yml → test_build.yml → Create PR to main - ↓ - validate-pr-to-main.yml - ↓ - validate-pr-branch-common.yml - ↓ - auto_merge_version_bump.yml - ↓ - Merge to main → create_tag_on_main.yml -``` - -## Architectural Strengths - -1. **Comprehensive Versioning Logic**: The version_manager.py provides sophisticated branch-aware versioning -2. **Dual-File System**: Maintains both human-readable and setuptools-compatible formats -3. **Automated Testing**: Integration with build/test workflows -4. **Tag Management**: Automated cleanup of old tags -5. **Security Considerations**: Uses GitHub App tokens for authentication -6. **Branch Protection Awareness**: Attempts to work within GitHub's protection rules - -## Critical Architectural Weaknesses - -### 1. Infinite Loop Risk -- **Issue**: Workflows trigger each other in a chain that could become circular -- **Risk Level**: HIGH -- **Impact**: Repository becomes unusable, CI/CD system fails - -### 2. Complex Workflow Dependencies -- **Issue**: 4+ workflows must execute in sequence for a single version bump -- **Risk Level**: MEDIUM -- **Impact**: High failure rate, difficult debugging - -### 3. Branch Protection Workaround Complexity -- **Issue**: Creating PRs to bypass protection adds significant complexity -- **Risk Level**: MEDIUM -- **Impact**: Maintenance burden, potential security gaps - -### 4. Lack of Atomic Operations -- **Issue**: Version updates span multiple commits and PRs -- **Risk Level**: MEDIUM -- **Impact**: Inconsistent state during failures - -### 5. GitHub App Configuration Dependency -- **Issue**: System relies on external GitHub App configuration -- **Risk Level**: LOW -- **Impact**: Additional setup complexity, potential access issues - -## Recommendations - -### Immediate Actions (Critical) -1. **Disable auto_merge_version_bump.yml** to prevent infinite loops -2. **Review and simplify workflow triggers** to break circular dependencies -3. **Implement workflow run conditions** to prevent cascading executions - -### Short-term Improvements -1. **Consolidate workflows** into fewer, more focused actions -2. **Implement proper error handling** and rollback mechanisms -3. **Add workflow state validation** to prevent inconsistent executions - -### Long-term Architectural Changes -1. **Consider tag-based triggering** instead of branch-based workflows -2. **Evaluate GitHub Apps vs. service account approaches** -3. **Implement atomic version update operations** -4. **Design fail-safe mechanisms** for workflow failures - -## Conclusion - -The current architecture demonstrates sophisticated understanding of versioning requirements but suffers from over-engineering and circular dependency issues. The system requires immediate stabilization followed by systematic simplification to achieve reliable automated versioning while maintaining branch protection. - -**Overall Grade**: C- (Functional concept with critical implementation flaws) -**Priority**: URGENT - System stability at risk diff --git a/LLM_Reports/GitHub_Specific_Solutions_Report.md b/LLM_Reports/GitHub_Specific_Solutions_Report.md deleted file mode 100644 index 7558903..0000000 --- a/LLM_Reports/GitHub_Specific_Solutions_Report.md +++ /dev/null @@ -1,503 +0,0 @@ -# GitHub-Specific Solutions Report: Automated Workflows with Branch Protection - -## Executive Summary - -This report provides comprehensive guidance on implementing automated versioning workflows while maintaining GitHub branch protection rules. It covers GitHub Apps, service accounts, organization-level configurations, and specific GitHub features that enable secure automation. - -## GitHub Branch Protection Overview - -### Core Protection Features - -- **Pull Request Requirements**: Enforce code review before merging -- **Status Check Requirements**: Require CI/CD checks to pass -- **Conversation Resolution**: Ensure all comments are addressed -- **Signed Commits**: Require cryptographic verification -- **Linear History**: Prevent merge commits -- **Merge Queue**: Automated merge management -- **Deployment Requirements**: Require successful deployments -- **Branch Locking**: Make branches read-only -- **Push Restrictions**: Limit who can push directly - -### Bypass Mechanisms - -1. **Administrator Override**: Repository admins can bypass by default -2. **Custom Roles**: Organization-level roles with bypass permissions -3. **GitHub Apps**: Applications added to bypass list -4. **Service Accounts**: Dedicated automation accounts - -## GitHub Apps: The Preferred Solution - -### Why GitHub Apps Are Recommended - -**Security Benefits**: - -- Fine-grained permissions (repository-specific) -- No personal access token exposure -- Automatic token rotation -- Audit trail for all actions -- Organization-level management - -**Operational Benefits**: - -- Can be added to branch protection bypass lists -- Works across multiple repositories -- Centralized credential management -- No dependency on individual user accounts - -### GitHub App Setup Process - -#### Step 1: Create GitHub App - -1. **Navigate to GitHub Settings**: - - Organization: `Settings` → `Developer settings` → `GitHub Apps` - - Personal: `Settings` → `Developer settings` → `GitHub Apps` - -2. **Basic Information**: - - ``` - App Name: [Organization]-Versioning-Bot - Homepage URL: https://github.com/[org]/[repo] - Description: Automated versioning and release management - ``` - -3. **Webhook Configuration**: - - ``` - Webhook URL: [Optional - leave blank for simple automation] - Webhook Secret: [Optional] - SSL Verification: Enabled - ``` - -#### Step 2: Configure Permissions - -**Repository Permissions**: - -``` -Contents: Read & Write (required for commits/tags) -Metadata: Read (required for basic repository access) -Pull Requests: Write (if using PR-based workflow) -Actions: Read (if triggering workflows) -Checks: Write (if updating status checks) -``` - -**Organization Permissions**: - -``` -Members: Read (if checking organization membership) -``` - -**Account Permissions**: - -``` -Email addresses: Read (if needed for commit attribution) -``` - -#### Step 3: Generate Private Key - -1. Scroll to "Private keys" section -2. Click "Generate a private key" -3. Download and securely store the `.pem` file -4. Note the App ID from the app settings - -#### Step 4: Install App - -1. Go to "Install App" tab -2. Select target organization/repositories -3. Choose "All repositories" or "Selected repositories" -4. Complete installation - -### GitHub App Authentication in Workflows - -#### Using tibdex/github-app-token Action - -```yaml -name: Automated Versioning -on: - push: - branches: [main, dev] - -jobs: - version-and-release: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - with: - fetch-depth: 0 - - - name: Generate GitHub App Token - id: generate-token - uses: tibdex/github-app-token@v2 - with: - app_id: ${{ secrets.APP_ID }} - private_key: ${{ secrets.APP_PRIVATE_KEY }} - - - name: Configure Git - run: | - git config --local user.email "action@github.com" - git config --local user.name "Versioning Bot" - - - name: Update Version and Commit - run: | - # Your versioning logic here - python scripts/version_manager.py --update-for-branch ${{ github.ref_name }} - git add VERSION VERSION.meta - git commit -m "chore: update version files [skip ci]" - git push - env: - GITHUB_TOKEN: ${{ steps.generate-token.outputs.token }} -``` - -#### Storing Secrets - -1. **Repository Secrets**: - - `Settings` → `Secrets and variables` → `Actions` - - Add `APP_ID` (GitHub App ID) - - Add `APP_PRIVATE_KEY` (contents of .pem file) - -2. **Organization Secrets** (for multiple repositories): - - Organization `Settings` → `Secrets and variables` → `Actions` - - Set repository access permissions - -### Adding GitHub App to Branch Protection Bypass - -#### Repository Level - -1. Navigate to repository `Settings` → `Branches` -2. Edit existing branch protection rule or create new one -3. Scroll to "Restrict pushes that create files" -4. In "Bypass restrictions" section: - - Check "Apps" checkbox - - Select your GitHub App from dropdown -5. Save changes - -#### Organization Level (Enterprise) - -For GitHub Enterprise Cloud organizations: - -1. Organization `Settings` → `Repository defaults` -2. Configure default branch protection rules -3. Add GitHub App to bypass list -4. Apply to new repositories automatically - -## Alternative Authentication Methods - -### 1. Fine-Grained Personal Access Tokens (Beta) - -**Setup**: - -``` -Token Name: Versioning Automation -Expiration: 1 year (maximum) -Resource Owner: [Organization] -Repository Access: Selected repositories -Permissions: - - Contents: Write - - Metadata: Read - - Pull Requests: Write (if needed) -``` - -**Usage**: - -```yaml -- uses: actions/checkout@v4 - with: - token: ${{ secrets.FINE_GRAINED_PAT }} -``` - -**Limitations**: - -- Still in beta -- Requires manual token rotation -- Tied to user account -- Limited organization support - -### 2. Deploy Keys (Read-Only Alternative) - -**Use Case**: For read-only operations or when combined with other auth methods - -**Setup**: - -1. Generate SSH key pair: `ssh-keygen -t ed25519 -C "deploy-key"` -2. Add public key to repository `Settings` → `Deploy keys` -3. Store private key as repository secret - -**Limitations**: - -- Read-only by default -- Repository-specific -- Cannot bypass branch protection - -### 3. Service Account with PAT (Legacy) - -**Setup**: - -1. Create dedicated GitHub user account -2. Add to organization with appropriate permissions -3. Generate classic PAT with required scopes -4. Add to branch protection bypass list - -**Disadvantages**: - -- Requires paid seat in organization -- Manual token rotation -- Security risk if token is compromised -- Tied to user account lifecycle - -## Branch Protection Configuration Best Practices - -### Recommended Settings for Automated Versioning - -```yaml -# Example branch protection configuration -Branch Protection Rule: main -Settings: - ✅ Require pull request reviews: false (for direct automation) - ✅ Require status checks: true - - Required checks: ["test", "build", "lint"] - - Require up-to-date branches: true - ❌ Require conversation resolution: false - ✅ Require signed commits: true (recommended) - ❌ Require linear history: false (allows merge commits) - ❌ Require merge queue: false (unless high-traffic) - ❌ Lock branch: false - ❌ Do not allow bypassing: false (allow bypass for automation) - ✅ Restrict pushes: true - - Bypass restrictions: [Your GitHub App] - ❌ Allow force pushes: false - ❌ Allow deletions: false -``` - -### Development Branch Configuration - -```yaml -Branch Protection Rule: dev -Settings: - ❌ Require pull request reviews: false - ✅ Require status checks: true - - Required checks: ["test", "build"] - - Require up-to-date branches: false - ❌ Require conversation resolution: false - ❌ Require signed commits: false - ❌ Require linear history: false - ❌ Lock branch: false - ❌ Do not allow bypassing: false - ✅ Restrict pushes: true - - Bypass restrictions: [Your GitHub App, Developers Team] - ❌ Allow force pushes: false - ❌ Allow deletions: false -``` - -## Advanced GitHub Features - -### 1. Repository Rulesets (New Alternative) - -**Benefits over Branch Protection**: - -- More flexible targeting -- Better inheritance model -- Improved API support -- Organization-level management - -**Configuration**: - -```yaml -# .github/rulesets/main-protection.yml -name: Main Branch Protection -target: branch -enforcement: active -conditions: - ref_name: - include: ["refs/heads/main"] -rules: - - type: required_status_checks - parameters: - required_status_checks: - - context: "test" - - context: "build" - - type: restrict_pushes - parameters: - restrict_pushes: true -bypass_actors: - - actor_id: [GitHub App ID] - actor_type: Integration - bypass_mode: always -``` - -### 2. Merge Queues - -**Use Case**: High-traffic repositories with frequent merges - -**Benefits**: - -- Automatic conflict resolution -- Parallel testing -- Reduced developer wait time -- Maintains branch protection - -**Configuration**: - -```yaml -# In branch protection settings -Require merge queue: true -Merge method: merge (or squash/rebase) -Build concurrency: 5 -Merge timeout: 60 minutes -``` - -### 3. Required Deployments - -**Use Case**: Ensure staging deployment before production merge - -**Configuration**: - -```yaml -Required deployments before merging: - - staging - - integration-tests -``` - -## Security Considerations - -### 1. Principle of Least Privilege - -**GitHub App Permissions**: - -- Only grant minimum required permissions -- Use repository-specific installations when possible -- Regular permission audits - -**Branch Protection**: - -- Limit bypass actors to essential automation only -- Use separate apps for different functions -- Monitor bypass usage - -### 2. Audit and Monitoring - -**GitHub Audit Log**: - -- Monitor app token usage -- Track bypass events -- Review permission changes - -**Workflow Monitoring**: - -```yaml -- name: Audit Workflow Run - run: | - echo "Workflow: ${{ github.workflow }}" - echo "Actor: ${{ github.actor }}" - echo "Event: ${{ github.event_name }}" - echo "Ref: ${{ github.ref }}" -``` - -### 3. Secret Management - -**Best Practices**: - -- Use GitHub App tokens over PATs -- Rotate secrets regularly -- Use organization-level secrets for shared resources -- Implement secret scanning - -**Secret Rotation**: - -```yaml -# Automated secret rotation workflow -name: Rotate GitHub App Key -on: - schedule: - - cron: '0 0 1 */3 *' # Quarterly -jobs: - rotate: - runs-on: ubuntu-latest - steps: - - name: Generate New Key - # Implementation depends on your key management system -``` - -## Troubleshooting Common Issues - -### 1. "GH006: Protected branch update failed" - -**Cause**: GitHub App not in bypass list or insufficient permissions - -**Solution**: - -1. Verify app is added to branch protection bypass -2. Check app has "Contents: Write" permission -3. Ensure app is installed on repository - -### 2. "Resource not accessible by integration" - -**Cause**: Missing permissions or incorrect token scope - -**Solution**: - -1. Review GitHub App permissions -2. Verify token generation in workflow -3. Check repository installation - -### 3. Workflow Infinite Loops - -**Cause**: Workflow triggering itself - -**Solution**: - -```yaml -# Use [skip ci] in commit messages -git commit -m "chore: update version [skip ci]" - -# Or use conditional triggers -on: - push: - branches: [main] - paths-ignore: - - 'VERSION' - - 'VERSION.meta' -``` - -## Recommendations for Hatchling - -### Immediate Implementation - -1. **Create GitHub App**: - - Name: "Hatchling-Versioning-Bot" - - Permissions: Contents (Write), Metadata (Read) - - Install on Hatchling repository - -2. **Update Branch Protection**: - - Add GitHub App to bypass list for main branch - - Maintain status check requirements - - Remove complex workflow chains - -3. **Simplify Workflows**: - - Use direct commits instead of PR-based flow - - Implement proper [skip ci] usage - - Add fail-safe mechanisms - -### Long-term Strategy - -1. **Organization-wide Deployment**: - - Install app across all repositories - - Standardize branch protection rules - - Implement centralized secret management - -2. **Advanced Features**: - - Evaluate repository rulesets - - Consider merge queues for high-traffic repos - - Implement comprehensive audit logging - -## Conclusion - -GitHub Apps provide the most secure and scalable solution for automated versioning in protected repositories. The combination of fine-grained permissions, bypass capabilities, and centralized management makes them superior to alternative authentication methods. - -**Key Success Factors**: - -1. Proper GitHub App configuration with minimal permissions -2. Correct branch protection bypass setup -3. Simplified workflow architecture -4. Comprehensive monitoring and auditing - -**Grade**: GitHub's native solutions are mature and well-supported (A) -**Recommendation**: Implement GitHub App-based authentication immediately diff --git a/LLM_Reports/Industry_Best_Practices_Report.md b/LLM_Reports/Industry_Best_Practices_Report.md deleted file mode 100644 index c88bb70..0000000 --- a/LLM_Reports/Industry_Best_Practices_Report.md +++ /dev/null @@ -1,324 +0,0 @@ -# Industry Best Practices Report: Automated Versioning in Protected Repositories - -## Executive Summary - -This report analyzes mainstream CI/CD approaches for automated versioning in protected repositories, examining solutions from major projects and organizations. The research reveals several established patterns and emerging best practices that address the fundamental tension between automation and security in modern software development. - -## Key Findings - -1. **Semantic Release** is the industry standard for automated versioning -2. **GitHub Apps** are the preferred solution for bypassing branch protection -3. **Tag-based workflows** are increasingly favored over branch-based approaches -4. **Atomic operations** are critical for maintaining repository consistency -5. **Fail-safe mechanisms** are essential for production environments - -## Industry Standard Solutions - -### 1. Semantic Release Ecosystem - -**Overview**: The most widely adopted automated versioning solution in the JavaScript/Node.js ecosystem, with growing adoption in other languages. - -**Key Features**: - -- Conventional commit parsing -- Automatic version calculation -- Changelog generation -- Multi-platform publishing -- Plugin architecture - -**Branch Protection Strategy**: - -- Uses GitHub Apps for authentication -- Bypasses branch protection through app permissions -- Supports both direct commits and PR-based workflows - -**Major Adopters**: - -- Angular (Google) -- React (Meta) -- Vue.js -- Webpack -- Babel - -**Implementation Pattern**: - -```yaml -# Typical semantic-release workflow -name: Release -on: - push: - branches: [main] -jobs: - release: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - with: - token: ${{ secrets.GITHUB_APP_TOKEN }} - - run: npx semantic-release -``` - -### 2. GitHub Apps for Branch Protection Bypass - -**Industry Consensus**: GitHub Apps are the recommended approach for automated workflows that need to bypass branch protection rules. - -**Advantages**: - -- Fine-grained permissions -- Organization-level management -- Audit trail -- No personal access tokens required -- Can be added to branch protection bypass list - -**Configuration Requirements**: - -- Repository permissions: Contents (Read & Write) -- Metadata permissions: Read -- Pull requests permissions: Write (if using PR workflow) -- Add app to branch protection bypass list - -**Major Implementations**: - -- **Dependabot**: GitHub's own dependency update bot -- **Renovate**: Popular dependency management tool -- **Release Please**: Google's release automation tool -- **Semantic Release**: Via community GitHub Apps - -### 3. Tag-Based Release Workflows - -**Trend**: Moving away from branch-based triggers to tag-based workflows for better control and atomicity. - -**Pattern**: - -```yaml -# Tag-based release trigger -on: - push: - tags: - - 'v*' -``` - -**Benefits**: - -- Explicit release control -- Atomic version operations -- Cleaner git history -- Reduced workflow complexity -- Better rollback capabilities - -**Adopters**: - -- Kubernetes -- Docker -- Terraform -- Go standard library - -### 4. Release Please (Google's Approach) - -**Overview**: Google's open-source solution for automated releases, used across many Google projects. - -**Key Features**: - -- Language-agnostic -- Conventional commit support -- PR-based workflow -- Automatic changelog generation -- Multi-package repository support - -**Workflow Pattern**: - -1. Analyzes commits since last release -2. Creates a "release PR" with version bumps -3. When PR is merged, creates release and tags -4. Publishes packages - -**Benefits**: - -- Human oversight through PR review -- Atomic release operations -- Clear audit trail -- Supports complex repository structures - -## Enterprise Patterns - -### 1. Microsoft's Approach (Azure DevOps) - -**Strategy**: Service connections with managed identities - -- Uses Azure service principals -- Fine-grained RBAC permissions -- Centralized credential management -- Audit logging - -### 2. GitLab's Built-in Solutions - -**Features**: - -- Push rules for branch protection -- Deploy tokens for automation -- Project access tokens -- CI/CD variables for secrets - -**Pattern**: - -```yaml -# GitLab CI pattern -release: - stage: release - rules: - - if: $CI_COMMIT_BRANCH == "main" - script: - - semantic-release - variables: - GITLAB_TOKEN: $CI_JOB_TOKEN -``` - -### 3. Atlassian's Bitbucket Approach - -**Strategy**: App passwords and repository access keys - -- App-specific passwords -- Repository access keys for read-only access -- Webhook-based automation -- Branch permissions with service account bypass - -## Language-Specific Best Practices - -### JavaScript/Node.js - -- **Standard**: semantic-release -- **Alternative**: release-please -- **Package Management**: npm, yarn -- **Registry**: npmjs.com - -### Python - -- **Tools**: bump2version, semantic-release-python -- **Package Management**: pip, poetry -- **Registry**: PyPI -- **Pattern**: setuptools_scm for version from git tags - -### Go - -- **Approach**: Git tags as versions -- **Tools**: goreleaser -- **Pattern**: Module versioning through tags -- **Registry**: pkg.go.dev - -### Rust - -- **Tools**: cargo-release -- **Package Management**: cargo -- **Registry**: crates.io -- **Pattern**: Cargo.toml version management - -### Java - -- **Tools**: Maven Release Plugin, Gradle Release Plugin -- **Pattern**: POM/build.gradle version management -- **Registry**: Maven Central - -## Security Considerations - -### 1. Principle of Least Privilege - -- Use GitHub Apps instead of personal access tokens -- Limit permissions to minimum required -- Regular permission audits -- Rotate credentials regularly - -### 2. Audit and Monitoring - -- Log all automated actions -- Monitor for unusual activity -- Set up alerts for failed releases -- Regular security reviews - -### 3. Fail-Safe Mechanisms - -- Dry-run capabilities -- Rollback procedures -- Manual override options -- Circuit breakers for repeated failures - -## Emerging Trends - -### 1. GitOps Integration - -- ArgoCD and Flux integration -- Kubernetes-native versioning -- Infrastructure as Code versioning -- Multi-repository coordination - -### 2. Supply Chain Security - -- SLSA compliance -- Signed commits and tags -- Provenance tracking -- Vulnerability scanning integration - -### 3. Monorepo Support - -- Multi-package versioning -- Selective releases -- Dependency graph analysis -- Coordinated releases - -## Anti-Patterns to Avoid - -### 1. Personal Access Tokens for Automation - -- **Problem**: Security risk, tied to individual users -- **Solution**: Use GitHub Apps or service accounts - -### 2. Complex Workflow Chains - -- **Problem**: Difficult to debug, prone to infinite loops -- **Solution**: Simplify triggers, use atomic operations - -### 3. Manual Version Management - -- **Problem**: Human error, inconsistency -- **Solution**: Automate based on conventional commits - -### 4. Bypassing All Protection - -- **Problem**: Removes safety nets -- **Solution**: Selective bypass with proper permissions - -## Recommendations for Hatchling - -### Immediate Actions - -1. **Adopt semantic-release** or release-please pattern -2. **Implement GitHub App** for authentication -3. **Simplify workflow triggers** to prevent loops -4. **Add fail-safe mechanisms** for error recovery - -### Strategic Improvements - -1. **Move to tag-based releases** for better control -2. **Implement conventional commits** for automation -3. **Add comprehensive testing** before releases -4. **Create rollback procedures** for failed releases - -### Long-term Considerations - -1. **Evaluate monorepo patterns** if expanding -2. **Implement supply chain security** measures -3. **Consider GitOps integration** for deployment -4. **Plan for multi-language support** if needed - -## Conclusion - -The industry has converged on several key patterns for automated versioning in protected repositories: - -1. **GitHub Apps** are the standard for authentication and bypass -2. **Semantic versioning** with conventional commits is widely adopted -3. **Atomic operations** through tags or PRs are preferred -4. **Fail-safe mechanisms** are essential for production use - -The Hatchling project should align with these industry standards while maintaining its specific requirements for branch-based development workflows. - -**Grade**: Industry practices are mature and well-established (A) -**Recommendation**: Adopt proven patterns rather than custom solutions diff --git a/LLM_Reports/Integrated_Automated_Versioning_Strategy.md b/LLM_Reports/Integrated_Automated_Versioning_Strategy.md deleted file mode 100644 index 8b13350..0000000 --- a/LLM_Reports/Integrated_Automated_Versioning_Strategy.md +++ /dev/null @@ -1,842 +0,0 @@ -# Integrated Automated Versioning Strategy: Preserving Emergent Versioning While Fixing Architectural Issues - -## Executive Summary - -This report synthesizes insights from all previous analyses and extensive research into state-of-the-art automated versioning solutions to propose a comprehensive strategy that **preserves the automatic, emergent versioning behavior** of the current Hatchling system while eliminating the critical architectural flaws. - -The solution combines industry-standard tools (semantic-release/release-please) with custom branch-pattern automation to maintain the "hands-off" developer experience while achieving enterprise-grade reliability and compliance with GitHub branch protection. - -## Core Requirement Analysis - -### What Must Be Preserved - -The current system's **key value proposition** is automatic version bumping based on git workflow patterns: - -- **feat/* branches** → Minor version increment + dev/build numbers -- **fix/* branches** → Patch version increment + dev/build numbers -- **dev branch** → Development prereleases with dev numbers -- **main branch** → Clean releases (no dev/build suffixes) - -**Critical Success Factor**: Developers never need to think about versioning - it emerges naturally from their git workflow patterns. - -### What Must Be Fixed - -1. **Infinite loop risk** from workflow chains -2. **Complex dependency chains** with multiple failure points -3. **Branch protection conflicts** requiring PR-based workarounds -4. **Non-atomic operations** spanning multiple commits -5. **Poor error handling** and recovery mechanisms - -## Research Findings: State-of-the-Art Solutions - -### 1. Semantic Release with Branch Configuration - -**Key Discovery**: Semantic-release supports sophisticated branch-based workflows through its `branches` configuration: - -```javascript -// .releaserc.js -module.exports = { - branches: [ - 'main', - { name: 'dev', prerelease: 'dev' }, - { name: 'feat/*', prerelease: '${name.replace(/^feat\\//g, "")}-dev' }, - { name: 'fix/*', prerelease: '${name.replace(/^fix\\//g, "")}-fix' } - ], - plugins: [ - '@semantic-release/commit-analyzer', - '@semantic-release/release-notes-generator', - '@semantic-release/changelog', - '@semantic-release/npm', - '@semantic-release/github', - '@semantic-release/git' - ] -} -``` - -**Benefits**: - -- Automatic version calculation based on conventional commits -- Branch-specific prerelease patterns -- Built-in loop prevention -- GitHub App authentication support -- Atomic operations - -### 2. Release Please with Custom Configuration - -**Key Discovery**: Release-please can be configured for branch-based automation while maintaining PR-based oversight: - -```yaml -# release-please-config.json -{ - "packages": { - ".": { - "release-type": "python", - "include-component-in-tag": false, - "include-v-in-tag": true - } - }, - "branches": ["main", "dev"], - "changelog-sections": [ - {"type": "feat", "section": "Features"}, - {"type": "fix", "section": "Bug Fixes"}, - {"type": "chore", "section": "Miscellaneous", "hidden": true} - ] -} -``` - -### 3. Advanced GitHub Actions Patterns - -**Key Discovery**: Modern GitHub Actions patterns for automated versioning include: - -1. **Conditional Execution** to prevent loops -2. **GitHub App Authentication** for branch protection bypass -3. **Atomic Commit Strategies** for consistency -4. **Branch Pattern Triggers** for emergent behavior -5. **Fail-Safe Mechanisms** for error recovery - -## Proposed Integrated Solutions - -### Option 1: Enhanced Semantic Release (Recommended) - -**Architecture**: Direct commit with semantic-release + custom branch logic - -```yaml -name: Automated Versioning -on: - push: - branches: [main, dev, 'feat/*', 'fix/*'] - workflow_dispatch: - inputs: - force_release: - description: 'Force release creation' - required: false - default: false - -jobs: - version-and-release: - runs-on: ubuntu-latest - if: "!contains(github.event.head_commit.message, '[skip ci]') && github.actor != 'github-actions[bot]'" - - steps: - - name: Generate GitHub App Token - id: generate-token - uses: tibdex/github-app-token@v2 - with: - app_id: ${{ secrets.HATCHLING_APP_ID }} - private_key: ${{ secrets.HATCHLING_APP_PRIVATE_KEY }} - - - uses: actions/checkout@v4 - with: - fetch-depth: 0 - token: ${{ steps.generate-token.outputs.token }} - - - name: Setup Python - uses: actions/setup-python@v5 - with: - python-version: '3.12' - - - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install build twine semantic-release - - - name: Configure Git - run: | - git config --local user.email "hatchling-bot@users.noreply.github.com" - git config --local user.name "Hatchling Bot" - - - name: Determine Version Strategy - id: strategy - run: | - BRANCH="${{ github.ref_name }}" - if [[ "$BRANCH" == "main" ]]; then - echo "strategy=release" >> $GITHUB_OUTPUT - echo "prerelease=false" >> $GITHUB_OUTPUT - elif [[ "$BRANCH" == "dev" ]]; then - echo "strategy=prerelease" >> $GITHUB_OUTPUT - echo "prerelease=dev" >> $GITHUB_OUTPUT - elif [[ "$BRANCH" =~ ^feat/ ]]; then - FEATURE_NAME=$(echo "$BRANCH" | sed 's/^feat\///') - echo "strategy=prerelease" >> $GITHUB_OUTPUT - echo "prerelease=${FEATURE_NAME}-dev" >> $GITHUB_OUTPUT - elif [[ "$BRANCH" =~ ^fix/ ]]; then - FIX_NAME=$(echo "$BRANCH" | sed 's/^fix\///') - echo "strategy=prerelease" >> $GITHUB_OUTPUT - echo "prerelease=${FIX_NAME}-fix" >> $GITHUB_OUTPUT - else - echo "strategy=skip" >> $GITHUB_OUTPUT - fi - - - name: Run Tests - if: steps.strategy.outputs.strategy != 'skip' - run: python -m pytest tests/ || exit 1 - - - name: Semantic Release - if: steps.strategy.outputs.strategy != 'skip' - env: - GITHUB_TOKEN: ${{ steps.generate-token.outputs.token }} - GH_TOKEN: ${{ steps.generate-token.outputs.token }} - run: | - # Configure semantic-release for current branch - cat > .releaserc.js << EOF - module.exports = { - branches: [ - 'main', - { name: 'dev', prerelease: 'dev' }, - { name: 'feat/*', prerelease: '\${name.replace(/^feat\\\\//g, "")}-dev' }, - { name: 'fix/*', prerelease: '\${name.replace(/^fix\\\\//g, "")}-fix' } - ], - plugins: [ - '@semantic-release/commit-analyzer', - '@semantic-release/release-notes-generator', - '@semantic-release/changelog', - [ - '@semantic-release/exec', - { - prepareCmd: 'python scripts/version_manager.py --set-version \${nextRelease.version}', - publishCmd: 'python -m build && python -m twine check dist/*' - } - ], - [ - '@semantic-release/git', - { - assets: ['VERSION', 'VERSION.meta', 'CHANGELOG.md'], - message: 'chore(release): \${nextRelease.version} [skip ci]\\n\\n\${nextRelease.notes}' - } - ], - '@semantic-release/github' - ] - } - EOF - - npx semantic-release - - - name: Cleanup Old Tags (main branch only) - if: github.ref == 'refs/heads/main' - run: python scripts/tag_cleanup.py --execute -``` - -**Benefits**: - -- **Preserves emergent versioning**: Branch patterns automatically determine version strategy -- **Eliminates infinite loops**: Built-in semantic-release loop prevention + [skip ci] -- **Atomic operations**: Single workflow handles entire version lifecycle -- **GitHub App authentication**: Bypasses branch protection cleanly -- **Industry standard**: Uses proven semantic-release patterns -- **Fail-safe**: Comprehensive error handling and rollback - -### Option 2: Hybrid Release Please + Custom Logic - -**Architecture**: Release Please for main releases + custom logic for development branches - -```yaml -name: Development Branch Versioning -on: - push: - branches: [dev, 'feat/*', 'fix/*'] - -jobs: - dev-versioning: - runs-on: ubuntu-latest - if: "!contains(github.event.head_commit.message, '[skip ci]')" - - steps: - - name: Generate GitHub App Token - id: generate-token - uses: tibdex/github-app-token@v2 - with: - app_id: ${{ secrets.HATCHLING_APP_ID }} - private_key: ${{ secrets.HATCHLING_APP_PRIVATE_KEY }} - - - uses: actions/checkout@v4 - with: - fetch-depth: 0 - token: ${{ steps.generate-token.outputs.token }} - - - name: Update Development Version - run: | - # Custom logic preserving current branch-based versioning - python scripts/version_manager.py --update-for-branch ${{ github.ref_name }} - - git config --local user.email "hatchling-bot@users.noreply.github.com" - git config --local user.name "Hatchling Bot" - git add VERSION VERSION.meta - git commit -m "chore: update version for ${{ github.ref_name }} [skip ci]" || exit 0 - git push -``` - -```yaml -name: Main Branch Release Please -on: - push: - branches: [main] - -jobs: - release-please: - runs-on: ubuntu-latest - steps: - - uses: googleapis/release-please-action@v4 - id: release - with: - token: ${{ secrets.GITHUB_APP_TOKEN }} - release-type: python - - - uses: actions/checkout@v4 - if: ${{ steps.release.outputs.release_created }} - - - name: Build and Publish - if: ${{ steps.release.outputs.release_created }} - run: | - python -m pip install --upgrade pip build twine - python -m build - python -m twine upload dist/* - env: - TWINE_USERNAME: __token__ - TWINE_PASSWORD: ${{ secrets.PYPI_TOKEN }} -``` - -### Option 3: Custom Conventional Commit Automation - -**Architecture**: Custom implementation using conventional commits with branch pattern enhancement - -```yaml -name: Branch-Aware Conventional Versioning -on: - push: - branches: [main, dev, 'feat/*', 'fix/*'] - -jobs: - version: - runs-on: ubuntu-latest - if: "!contains(github.event.head_commit.message, '[skip ci]') && github.actor != 'github-actions[bot]'" - - steps: - - name: Generate GitHub App Token - id: generate-token - uses: tibdex/github-app-token@v2 - with: - app_id: ${{ secrets.HATCHLING_APP_ID }} - private_key: ${{ secrets.HATCHLING_APP_PRIVATE_KEY }} - - - uses: actions/checkout@v4 - with: - fetch-depth: 0 - token: ${{ steps.generate-token.outputs.token }} - - - name: Analyze Commits and Determine Version - id: version - run: | - # Enhanced version_manager.py with conventional commit parsing - python scripts/enhanced_version_manager.py \ - --branch ${{ github.ref_name }} \ - --analyze-commits \ - --output-github-actions - - - name: Update Version Files - if: steps.version.outputs.should_release == 'true' - run: | - python scripts/enhanced_version_manager.py \ - --branch ${{ github.ref_name }} \ - --set-version ${{ steps.version.outputs.next_version }} - - - name: Build and Test - if: steps.version.outputs.should_release == 'true' - run: | - python -m pip install --upgrade pip build - python -m build - python -m pytest tests/ - - - name: Commit and Tag - if: steps.version.outputs.should_release == 'true' - run: | - git config --local user.email "hatchling-bot@users.noreply.github.com" - git config --local user.name "Hatchling Bot" - - git add VERSION VERSION.meta - git commit -m "chore(release): ${{ steps.version.outputs.next_version }} [skip ci]" - - if [[ "${{ github.ref_name }}" == "main" ]]; then - git tag -a "v${{ steps.version.outputs.next_version }}" -m "Release v${{ steps.version.outputs.next_version }}" - git push origin "v${{ steps.version.outputs.next_version }}" - fi - - git push -``` - -## Implementation Roadmap - -### Phase 1: Immediate Stabilization (Week 1) - -1. **DISABLE** `auto_merge_version_bump.yml` to prevent infinite loops -2. **CREATE** GitHub App with proper permissions -3. **IMPLEMENT** Option 1 (Enhanced Semantic Release) in development environment -4. **TEST** thoroughly with all branch patterns - -### Phase 2: Migration (Week 2-3) - -1. **DEPLOY** new workflow to production -2. **MONITOR** for 1 week with existing workflows disabled -3. **VALIDATE** version generation matches expected patterns -4. **REMOVE** deprecated workflows once stable - -### Phase 3: Enhancement (Month 2) - -1. **ADD** advanced features (changelog generation, release notes) -2. **IMPLEMENT** comprehensive monitoring and alerting -3. **OPTIMIZE** performance and reliability -4. **DOCUMENT** new workflow for team - -## Loop Prevention Strategies - -### 1. Multi-Layer Protection - -```yaml -# Workflow level -if: "!contains(github.event.head_commit.message, '[skip ci]') && github.actor != 'github-actions[bot]'" - -# Commit level -git commit -m "chore(release): ${version} [skip ci]" - -# Path-based (if needed) -on: - push: - paths-ignore: - - 'VERSION' - - 'VERSION.meta' -``` - -### 2. Workflow State Validation - -```yaml -- name: Check for concurrent workflows - run: | - RUNNING=$(gh run list --workflow="${{ github.workflow }}" --status=in_progress --json databaseId --jq length) - if [ "$RUNNING" -gt 1 ]; then - echo "Another workflow is running, exiting gracefully" - exit 0 - fi -``` - -### 3. Branch-Specific Logic - -```yaml -- name: Validate branch for release - run: | - if [[ "${{ github.ref_name }}" =~ ^(main|dev|feat/|fix/).*$ ]]; then - echo "Valid branch for versioning" - else - echo "Skipping versioning for branch: ${{ github.ref_name }}" - exit 0 - fi -``` - -## Error Handling and Recovery - -### 1. Atomic Operations with Rollback - -```yaml -- name: Version update with rollback - run: | - # Create backup - cp VERSION VERSION.backup - cp VERSION.meta VERSION.meta.backup - - # Attempt update - if ! python scripts/version_manager.py --update; then - # Restore on failure - mv VERSION.backup VERSION - mv VERSION.meta.backup VERSION.meta - echo "Version update failed, restored backup" - exit 1 - fi - - # Clean up on success - rm -f *.backup -``` - -### 2. Comprehensive Monitoring - -```yaml -- name: Report status - if: always() - run: | - if [[ "${{ job.status }}" == "failure" ]]; then - gh issue create \ - --title "Automated versioning failed on ${{ github.ref_name }}" \ - --body "Workflow run: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}" - fi -``` - -## Migration Strategy - -### Step 1: GitHub App Setup - -1. Create GitHub App with permissions: - - Contents: Read & Write - - Metadata: Read - - Pull Requests: Write (if using Option 2) -2. Install app on repository -3. Add app to branch protection bypass list -4. Store app credentials as repository secrets - -### Step 2: Workflow Implementation - -1. Implement chosen option in `.github/workflows/` -2. Test in development environment -3. Gradually migrate branch by branch -4. Monitor and adjust as needed - -### Step 3: Legacy Cleanup - -1. Disable old workflows -2. Remove deprecated files -3. Update documentation -4. Train team on new process - -## Enhanced Version Manager Implementation - -To support the new workflows, the existing `version_manager.py` needs enhancement to work with conventional commits and semantic-release patterns: - -```python -# Enhanced version_manager.py additions -import re -from typing import Dict, List, Tuple - -class ConventionalCommitAnalyzer: - """Analyzes conventional commits to determine version bumps""" - - COMMIT_PATTERN = re.compile( - r'^(?P\w+)(?:\((?P[\w\-]+)\))?(?P!)?: (?P.+)$' - ) - - VERSION_BUMPS = { - 'feat': 'minor', - 'fix': 'patch', - 'perf': 'patch', - 'revert': 'patch', - 'docs': None, - 'style': None, - 'refactor': None, - 'test': None, - 'build': None, - 'ci': None, - 'chore': None - } - - def analyze_commits_since_last_release(self, branch: str) -> str: - """Determine version bump type based on commits since last release""" - commits = self._get_commits_since_last_release(branch) - - has_breaking = False - has_feature = False - has_fix = False - - for commit in commits: - match = self.COMMIT_PATTERN.match(commit.message.split('\n')[0]) - if not match: - continue - - commit_type = match.group('type') - is_breaking = match.group('breaking') == '!' or 'BREAKING CHANGE' in commit.message - - if is_breaking: - has_breaking = True - elif commit_type == 'feat': - has_feature = True - elif commit_type in ['fix', 'perf']: - has_fix = True - - if has_breaking: - return 'major' - elif has_feature: - return 'minor' - elif has_fix: - return 'patch' - else: - return None # No releasable changes - -def enhanced_version_manager_cli(): - """Enhanced CLI for integration with semantic-release""" - parser = argparse.ArgumentParser(description='Enhanced Version Manager') - parser.add_argument('--analyze-commits', action='store_true', - help='Analyze commits to determine version bump') - parser.add_argument('--set-version', type=str, - help='Set specific version (for semantic-release integration)') - parser.add_argument('--output-github-actions', action='store_true', - help='Output GitHub Actions compatible variables') - - args = parser.parse_args() - - if args.analyze_commits: - analyzer = ConventionalCommitAnalyzer() - bump_type = analyzer.analyze_commits_since_last_release(args.branch) - - if args.output_github_actions: - print(f"should_release={'true' if bump_type else 'false'}") - if bump_type: - current_version = get_current_version() - next_version = calculate_next_version(current_version, bump_type, args.branch) - print(f"next_version={next_version}") -``` - -## Real-World Implementation Examples - -### Example 1: Feature Branch Workflow - -**Developer Action**: - -```bash -git checkout -b feat/user-authentication -# ... make changes ... -git commit -m "feat: add user authentication system" -git push origin feat/user-authentication -``` - -**Automated Result**: - -- Workflow triggers on `feat/user-authentication` branch -- Semantic-release analyzes commit: `feat:` → minor version bump -- Version becomes: `1.2.0-user-authentication-dev.1` -- VERSION files updated automatically -- No manual intervention required - -### Example 2: Bug Fix Workflow - -**Developer Action**: - -```bash -git checkout -b fix/login-validation -git commit -m "fix: resolve login validation issue" -git push origin fix/login-validation -``` - -**Automated Result**: - -- Workflow triggers on `fix/login-validation` branch -- Semantic-release analyzes commit: `fix:` → patch version bump -- Version becomes: `1.1.1-login-validation-fix.1` -- Automatic testing and validation -- Clean integration with existing patterns - -### Example 3: Main Branch Release - -**Developer Action**: - -```bash -git checkout main -git merge feat/user-authentication -git push origin main -``` - -**Automated Result**: - -- Workflow triggers on main branch -- Analyzes all commits since last release -- Determines version: `1.2.0` (clean release) -- Creates git tag: `v1.2.0` -- Generates GitHub release with changelog -- Updates VERSION files with clean version - -## Advanced Configuration Options - -### Semantic Release Configuration - -```javascript -// .releaserc.js - Advanced configuration -module.exports = { - branches: [ - 'main', - { name: 'dev', prerelease: 'dev' }, - { name: 'feat/*', prerelease: '${name.replace(/^feat\\//g, "")}-dev' }, - { name: 'fix/*', prerelease: '${name.replace(/^fix\\//g, "")}-fix' } - ], - plugins: [ - [ - '@semantic-release/commit-analyzer', - { - preset: 'conventionalcommits', - releaseRules: [ - { type: 'feat', release: 'minor' }, - { type: 'fix', release: 'patch' }, - { type: 'perf', release: 'patch' }, - { type: 'revert', release: 'patch' }, - { type: 'docs', release: false }, - { type: 'style', release: false }, - { type: 'chore', release: false }, - { type: 'refactor', release: false }, - { type: 'test', release: false }, - { type: 'build', release: false }, - { type: 'ci', release: false } - ] - } - ], - [ - '@semantic-release/release-notes-generator', - { - preset: 'conventionalcommits', - presetConfig: { - types: [ - { type: 'feat', section: 'Features' }, - { type: 'fix', section: 'Bug Fixes' }, - { type: 'perf', section: 'Performance Improvements' }, - { type: 'revert', section: 'Reverts' }, - { type: 'docs', section: 'Documentation', hidden: true }, - { type: 'style', section: 'Styles', hidden: true }, - { type: 'chore', section: 'Miscellaneous Chores', hidden: true }, - { type: 'refactor', section: 'Code Refactoring', hidden: true }, - { type: 'test', section: 'Tests', hidden: true }, - { type: 'build', section: 'Build System', hidden: true }, - { type: 'ci', section: 'Continuous Integration', hidden: true } - ] - } - } - ], - '@semantic-release/changelog', - [ - '@semantic-release/exec', - { - prepareCmd: 'python scripts/enhanced_version_manager.py --set-version ${nextRelease.version}', - publishCmd: 'python -m build && python -m twine check dist/*' - } - ], - [ - '@semantic-release/git', - { - assets: ['VERSION', 'VERSION.meta', 'CHANGELOG.md'], - message: 'chore(release): ${nextRelease.version} [skip ci]\n\n${nextRelease.notes}' - } - ], - [ - '@semantic-release/github', - { - successComment: false, - failComment: false, - releasedLabels: ['released'] - } - ] - ] -} -``` - -### GitHub App Permissions Checklist - -**Required Permissions**: - -- ✅ Contents: Read & Write (for commits and tags) -- ✅ Metadata: Read (for repository access) -- ✅ Actions: Read (for workflow status) -- ✅ Pull Requests: Write (if using PR-based option) -- ✅ Issues: Write (for error reporting) - -**Branch Protection Configuration**: - -- ✅ Add GitHub App to bypass list -- ✅ Require status checks: `Automated Versioning` -- ✅ Require up-to-date branches: true -- ✅ Restrict pushes: true -- ✅ Allow bypass for: [Your GitHub App] - -## Monitoring and Observability - -### Workflow Monitoring - -```yaml -- name: Report Workflow Metrics - if: always() - run: | - echo "::notice title=Workflow Status::Status: ${{ job.status }}" - echo "::notice title=Branch::${{ github.ref_name }}" - echo "::notice title=Commit::${{ github.sha }}" - - if [[ "${{ job.status }}" == "success" ]]; then - echo "::notice title=Version::Successfully processed version update" - else - echo "::error title=Failure::Workflow failed - check logs" - fi -``` - -### Error Alerting - -```yaml -- name: Create Issue on Failure - if: failure() - uses: actions/github-script@v7 - with: - script: | - github.rest.issues.create({ - owner: context.repo.owner, - repo: context.repo.repo, - title: `Automated versioning failed on ${context.ref}`, - body: ` - ## Workflow Failure Report - - **Branch**: ${context.ref} - **Commit**: ${context.sha} - **Run**: ${context.serverUrl}/${context.repo.owner}/${context.repo.repo}/actions/runs/${context.runId} - **Actor**: ${context.actor} - - Please investigate and resolve the issue. - `, - labels: ['bug', 'automation', 'versioning'] - }) -``` - -## Performance Optimizations - -### Caching Strategy - -```yaml -- name: Cache Python dependencies - uses: actions/cache@v4 - with: - path: ~/.cache/pip - key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements.txt') }} - restore-keys: | - ${{ runner.os }}-pip- - -- name: Cache semantic-release - uses: actions/cache@v4 - with: - path: ~/.npm - key: ${{ runner.os }}-npm-${{ hashFiles('**/package-lock.json') }} - restore-keys: | - ${{ runner.os }}-npm- -``` - -### Conditional Execution - -```yaml -- name: Check if version update needed - id: check - run: | - if git log --oneline -1 | grep -q '\[skip ci\]'; then - echo "skip=true" >> $GITHUB_OUTPUT - else - echo "skip=false" >> $GITHUB_OUTPUT - fi - -- name: Run versioning - if: steps.check.outputs.skip == 'false' - # ... rest of workflow -``` - -## Conclusion - -The **Enhanced Semantic Release** approach (Option 1) provides the optimal balance of: - -- **Preserving emergent versioning behavior** through branch pattern automation -- **Eliminating architectural issues** with proven industry-standard tools -- **Maintaining developer experience** with zero manual intervention required -- **Ensuring enterprise reliability** with comprehensive error handling - -This solution transforms the current system from a custom, fragile implementation into a robust, industry-standard automated versioning system while preserving the core value proposition that makes it valuable to developers. - -**Recommendation**: Implement Option 1 immediately to resolve critical stability issues while maintaining the automatic, hands-off versioning behavior that developers rely on. - -**Next Steps**: - -1. Create GitHub App and configure permissions -2. Implement enhanced version manager with conventional commit support -3. Deploy new workflow with comprehensive testing -4. Monitor and iterate based on real-world usage -5. Remove legacy workflows once stable diff --git a/LLM_Reports/Semantic_Release_Migration_Plan.md b/LLM_Reports/Semantic_Release_Migration_Plan.md deleted file mode 100644 index 8b6e600..0000000 --- a/LLM_Reports/Semantic_Release_Migration_Plan.md +++ /dev/null @@ -1,689 +0,0 @@ -# Semantic Release Migration Plan: Complete Replacement of Custom Versioning System - -## Executive Summary - -This comprehensive migration plan details the complete replacement of Hatchling's custom automated versioning system with `semantic-release`, a battle-tested industry standard. The migration will eliminate all architectural flaws while maintaining fully automated versioning through Conventional Commits and branch-based workflows. - -**Key Benefits:** -- ✅ Eliminates infinite loop risks and complex dependency chains -- ✅ Full GitHub branch protection compliance -- ✅ Atomic operations with proper error handling -- ✅ Industry-standard Conventional Commits workflow -- ✅ Maintains fully automated versioning without manual intervention -- ✅ Supports pre-releases and multiple distribution channels - -## Current State Analysis - -### What Will Be Removed - -The following custom implementation components will be completely removed: - -**Scripts to Remove:** -- `scripts/version_manager.py` (327 lines of complex version logic) -- `scripts/prepare_version.py` (version preparation logic) -- `scripts/tag_cleanup.py` (cleanup utilities) - -**Workflows to Remove:** -- `.github/workflows/auto_merge_version_bump.yml` -- `.github/workflows/commit_version_tag.yml` -- `.github/workflows/create_tag_on_main.yml` -- `.github/workflows/tag-cleanup.yml` -- `.github/workflows/tag-release.yml` -- `.github/workflows/release.yml` (current release workflow) - -**Files to Remove:** -- `VERSION` (simple version file) -- `VERSION.meta` (structured version metadata) - -### Current System Issues - -1. **Infinite Loop Risk**: Workflows trigger other workflows creating potential loops -2. **Complex Dependencies**: Multi-step chains with numerous failure points -3. **Branch Protection Conflicts**: Requires PR-based workarounds for protected branches -4. **Non-Atomic Operations**: Version updates span multiple commits and workflows -5. **Poor Error Handling**: Limited recovery mechanisms for failed operations -6. **Maintenance Overhead**: 327+ lines of custom version management code - -## Semantic Release Overview - -### How Semantic Release Works - -Semantic Release automates the entire release workflow based on commit message analysis: - -1. **Commit Analysis**: Analyzes commit messages using Conventional Commits format -2. **Version Calculation**: Determines next version based on commit types: - - `fix:` → Patch release (1.0.0 → 1.0.1) - - `feat:` → Minor release (1.0.0 → 1.1.0) - - `BREAKING CHANGE:` → Major release (1.0.0 → 2.0.0) -3. **Release Generation**: Creates GitHub releases with auto-generated changelogs -4. **Asset Publishing**: Publishes to npm, PyPI, or other registries -5. **Notification**: Updates issues/PRs and sends notifications - -### Key Advantages - -- **Battle-Tested**: Used by thousands of projects including major open source libraries -- **Atomic Operations**: All release steps happen in a single workflow run -- **Branch Protection Compliant**: Works seamlessly with protected branches -- **Extensible**: Rich plugin ecosystem for customization -- **Zero Configuration**: Works out-of-the-box with sensible defaults - -## Conventional Commits Integration - -### Transition from Current Practices - -**Current Approach**: Branch naming patterns determine version increments -- `feat/*` branches → Minor version increment -- `fix/*` branches → Patch version increment - -**New Approach**: Commit message format determines version increments -- `feat: add new feature` → Minor version increment -- `fix: resolve bug` → Patch version increment -- `feat!: breaking change` → Major version increment - -### Conventional Commits Format - -``` -[optional scope]: - -[optional body] - -[optional footer(s)] -``` - -**Common Types:** -- `feat`: New feature (minor version) -- `fix`: Bug fix (patch version) -- `docs`: Documentation changes -- `style`: Code style changes (formatting, etc.) -- `refactor`: Code refactoring -- `test`: Adding or updating tests -- `chore`: Maintenance tasks - -**Breaking Changes:** -- Add `!` after type: `feat!: breaking change` -- Or add footer: `BREAKING CHANGE: description` - -### Migration Strategy for Commit Messages - -**Phase 1**: Education and tooling setup -- Install commitizen for guided commit messages -- Add commit message linting with commitlint -- Update documentation with examples - -**Phase 2**: Gradual adoption -- Encourage conventional commits in new PRs -- Provide commit message templates -- Add PR checks for commit format - -**Phase 3**: Enforcement -- Require conventional commits for all new changes -- Use squash merging to clean up commit history - -## Step-by-Step Migration Plan - -### Phase 1: Preparation and Setup (Week 1) - -#### 1.1 Install Dependencies - -Add to `pyproject.toml`: -```toml -[tool.semantic_release] -version_toml = ["pyproject.toml:project.version"] -build_command = "python -m build" -dist_path = "dist/" -upload_to_pypi = false -upload_to_release = true -remove_dist = false - -[tool.semantic_release.branches.main] -match = "main" -prerelease = false - -[tool.semantic_release.branches.dev] -match = "dev" -prerelease = "dev" - -[tool.semantic_release.changelog] -template_dir = "templates" -changelog_file = "CHANGELOG.md" - -[tool.semantic_release.commit_parser_options] -allowed_tags = ["build", "chore", "ci", "docs", "feat", "fix", "perf", "style", "refactor", "test"] -minor_tags = ["feat"] -patch_tags = ["fix", "perf"] -``` - -#### 1.2 Create Package.json for Node Dependencies - -Create `package.json`: -```json -{ - "name": "hatchling", - "private": true, - "devDependencies": { - "semantic-release": "^22.0.0", - "@semantic-release/changelog": "^6.0.0", - "@semantic-release/git": "^10.0.0", - "@semantic-release/github": "^9.0.0", - "commitizen": "^4.3.0", - "@commitlint/cli": "^18.0.0", - "@commitlint/config-conventional": "^18.0.0", - "cz-conventional-changelog": "^3.3.0" - }, - "config": { - "commitizen": { - "path": "./node_modules/cz-conventional-changelog" - } - } -} -``` - -#### 1.3 Create Semantic Release Configuration - -Create `.releaserc.json`: -```json -{ - "branches": [ - "main", - { - "name": "dev", - "prerelease": "dev" - } - ], - "plugins": [ - "@semantic-release/commit-analyzer", - "@semantic-release/release-notes-generator", - "@semantic-release/changelog", - [ - "@semantic-release/git", - { - "assets": ["CHANGELOG.md", "pyproject.toml"], - "message": "chore(release): ${nextRelease.version} [skip ci]\n\n${nextRelease.notes}" - } - ], - "@semantic-release/github" - ] -} -``` - -### Phase 2: GitHub Actions Setup (Week 1) - -#### 2.1 Create New Release Workflow - -Create `.github/workflows/semantic-release.yml`: -```yaml -name: Semantic Release - -on: - push: - branches: - - main - - dev - pull_request: - branches: - - main - -permissions: - contents: write - issues: write - pull-requests: write - id-token: write - -jobs: - test: - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v4 - with: - fetch-depth: 0 - - - name: Setup Python - uses: actions/setup-python@v5 - with: - python-version: '3.12' - - - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install -e . - pip install pytest - - - name: Run tests - run: python run_tests.py - - release: - needs: test - runs-on: ubuntu-latest - if: github.event_name == 'push' - steps: - - name: Checkout - uses: actions/checkout@v4 - with: - fetch-depth: 0 - token: ${{ secrets.GITHUB_TOKEN }} - - - name: Setup Node.js - uses: actions/setup-node@v4 - with: - node-version: "lts/*" - - - name: Setup Python - uses: actions/setup-python@v5 - with: - python-version: '3.12' - - - name: Install dependencies - run: | - npm ci - python -m pip install --upgrade pip - pip install build python-semantic-release - - - name: Verify the integrity of provenance attestations and registry signatures for installed dependencies - run: npm audit signatures - - - name: Release - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: npx semantic-release -``` - -#### 2.2 Create Commit Lint Workflow - -Create `.github/workflows/commitlint.yml`: -```yaml -name: Commit Lint - -on: - pull_request: - branches: [main, dev] - -jobs: - commitlint: - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v4 - with: - fetch-depth: 0 - - - name: Setup Node.js - uses: actions/setup-node@v4 - with: - node-version: "lts/*" - - - name: Install dependencies - run: npm ci - - - name: Validate current commit (last commit) with commitlint - if: github.event_name == 'push' - run: npx commitlint --last --verbose - - - name: Validate PR commits with commitlint - if: github.event_name == 'pull_request' - run: npx commitlint --from ${{ github.event.pull_request.head.sha }}~${{ github.event.pull_request.commits }} --to ${{ github.event.pull_request.head.sha }} --verbose -``` - -### Phase 3: Configuration Files (Week 1) - -#### 3.1 Create Commitlint Configuration - -Create `.commitlintrc.json`: -```json -{ - "extends": ["@commitlint/config-conventional"], - "rules": { - "type-enum": [ - 2, - "always", - [ - "build", - "chore", - "ci", - "docs", - "feat", - "fix", - "perf", - "refactor", - "revert", - "style", - "test" - ] - ] - } -} -``` - -#### 3.2 Update Pyproject.toml - -Update version configuration in `pyproject.toml`: -```toml -[project] -name = "hatchling" -version = "0.4.0" # Remove dynamic = ["version"] -# ... rest of configuration -``` - -### Phase 4: Migration Execution (Week 2) - -#### 4.1 Remove Custom System - -1. **Delete custom scripts:** - ```bash - rm -rf scripts/ - ``` - -2. **Delete custom workflows:** - ```bash - rm .github/workflows/auto_merge_version_bump.yml - rm .github/workflows/commit_version_tag.yml - rm .github/workflows/create_tag_on_main.yml - rm .github/workflows/tag-cleanup.yml - rm .github/workflows/tag-release.yml - rm .github/workflows/release.yml - ``` - -3. **Delete version files:** - ```bash - rm VERSION VERSION.meta - ``` - -#### 4.2 Initialize Semantic Release - -1. **Install Node dependencies:** - ```bash - npm install - ``` - -2. **Set up initial version:** - ```bash - # Update pyproject.toml with current version - # Commit with conventional format - git add . - git commit -m "feat!: migrate to semantic-release - - BREAKING CHANGE: Replace custom versioning system with semantic-release. - This requires using Conventional Commits for all future changes." - ``` - -3. **Test the new system:** - ```bash - # Dry run to verify configuration - npx semantic-release --dry-run - ``` - -### Phase 5: Validation and Testing (Week 2) - -#### 5.1 Test Release Process - -1. **Create test feature branch:** - ```bash - git checkout -b feat/test-semantic-release - echo "# Test" >> test.md - git add test.md - git commit -m "feat: add test file for semantic-release validation" - git push origin feat/test-semantic-release - ``` - -2. **Create PR and merge to trigger release** - -3. **Verify release creation:** - - Check GitHub releases page - - Verify changelog generation - - Confirm version bumping - -#### 5.2 Test Pre-release Process - -1. **Push to dev branch:** - ```bash - git checkout dev - git commit -m "feat: test dev pre-release" --allow-empty - git push origin dev - ``` - -2. **Verify pre-release creation:** - - Check for dev pre-release tags - - Verify pre-release marking in GitHub - -### Phase 6: Documentation and Training (Week 3) - -#### 6.1 Update Documentation - -Create `docs/CONTRIBUTING.md`: -```markdown -# Contributing to Hatchling - -## Commit Message Format - -We use [Conventional Commits](https://www.conventionalcommits.org/) for all commit messages. - -### Format -``` -[optional scope]: - -[optional body] - -[optional footer(s)] -``` - -### Examples -- `feat: add new LLM provider` -- `fix: resolve memory leak in streaming` -- `docs: update API documentation` -- `feat!: change configuration format` - -### Using Commitizen -For guided commit messages, use: -```bash -npm run commit -# or -npx cz -``` -``` - -#### 6.2 Update README - -Add to `README.md`: -```markdown -## Development - -### Commit Messages -This project uses [Conventional Commits](https://www.conventionalcommits.org/). -Please format your commit messages accordingly: - -- `feat:` for new features -- `fix:` for bug fixes -- `docs:` for documentation changes -- `test:` for test changes -- `chore:` for maintenance tasks - -### Releases -Releases are automatically created when changes are merged to `main` using -[semantic-release](https://semantic-release.gitbook.io/). -``` - -## Configuration Examples - -### Complete .releaserc.json -```json -{ - "branches": [ - "main", - { - "name": "dev", - "prerelease": "dev" - }, - { - "name": "beta", - "prerelease": "beta" - } - ], - "plugins": [ - [ - "@semantic-release/commit-analyzer", - { - "preset": "conventionalcommits", - "releaseRules": [ - {"type": "docs", "scope": "README", "release": "patch"}, - {"type": "refactor", "release": "patch"}, - {"type": "style", "release": "patch"} - ] - } - ], - [ - "@semantic-release/release-notes-generator", - { - "preset": "conventionalcommits", - "presetConfig": { - "types": [ - {"type": "feat", "section": "Features"}, - {"type": "fix", "section": "Bug Fixes"}, - {"type": "chore", "hidden": true}, - {"type": "docs", "section": "Documentation"}, - {"type": "style", "hidden": true}, - {"type": "refactor", "section": "Code Refactoring"}, - {"type": "perf", "section": "Performance Improvements"}, - {"type": "test", "hidden": true} - ] - } - } - ], - [ - "@semantic-release/changelog", - { - "changelogFile": "CHANGELOG.md" - } - ], - [ - "@semantic-release/git", - { - "assets": ["CHANGELOG.md", "pyproject.toml"], - "message": "chore(release): ${nextRelease.version} [skip ci]\n\n${nextRelease.notes}" - } - ], - [ - "@semantic-release/github", - { - "successComment": "🎉 This ${issue.pull_request ? 'PR is included' : 'issue has been resolved'} in version ${nextRelease.version} 🎉", - "labels": ["released"], - "releasedLabels": ["released<%= nextRelease.type === 'prerelease' ? ` on @${nextRelease.channel}` : '' %>"] - } - ] - ] -} -``` - -## Migration Timeline - -### Week 1: Setup and Configuration -- **Day 1-2**: Install dependencies and create configuration files -- **Day 3-4**: Set up GitHub Actions workflows -- **Day 5**: Create commit lint and validation workflows - -### Week 2: Migration Execution -- **Day 1-2**: Remove custom system components -- **Day 3-4**: Initialize semantic-release and test -- **Day 5**: Validation and troubleshooting - -### Week 3: Documentation and Training -- **Day 1-2**: Update all documentation -- **Day 3-4**: Team training on Conventional Commits -- **Day 5**: Final testing and go-live - -### Week 4: Monitoring and Optimization -- **Day 1-3**: Monitor release process -- **Day 4-5**: Optimize configuration based on usage - -## Validation and Testing - -### Pre-Migration Checklist -- [ ] All dependencies installed -- [ ] Configuration files created -- [ ] GitHub Actions workflows tested -- [ ] Team trained on Conventional Commits -- [ ] Documentation updated -- [ ] Backup of current system created - -### Post-Migration Validation -- [ ] Successful release created from main branch -- [ ] Pre-release created from dev branch -- [ ] Changelog automatically generated -- [ ] GitHub releases properly formatted -- [ ] Version bumping working correctly -- [ ] No infinite loops or workflow conflicts - -### Testing Scenarios -1. **Feature Release**: Merge feat commit to main → Minor version bump -2. **Bug Fix Release**: Merge fix commit to main → Patch version bump -3. **Breaking Change**: Merge feat! commit to main → Major version bump -4. **Pre-release**: Push to dev branch → Pre-release version -5. **Documentation**: Merge docs commit → No release (configurable) - -## Rollback Plan - -### Emergency Rollback Procedure - -If critical issues arise during migration: - -1. **Immediate Actions:** - ```bash - # Disable semantic-release workflow - mv .github/workflows/semantic-release.yml .github/workflows/semantic-release.yml.disabled - - # Restore custom workflows from backup - git checkout HEAD~1 -- .github/workflows/ - git checkout HEAD~1 -- scripts/ - git checkout HEAD~1 -- VERSION VERSION.meta - ``` - -2. **Restore Custom System:** - - Revert pyproject.toml changes - - Restore version files - - Re-enable custom workflows - - Create hotfix release using old system - -3. **Communication:** - - Notify team of rollback - - Document issues encountered - - Plan remediation strategy - -### Rollback Triggers -- Infinite loop detection in workflows -- Failed releases blocking development -- Critical functionality broken -- Team unable to adapt to new process - -## Success Metrics - -### Technical Metrics -- Zero workflow infinite loops -- 100% successful releases -- Reduced release time (target: <5 minutes) -- Eliminated manual version management - -### Process Metrics -- Team adoption of Conventional Commits (target: >90%) -- Reduced release-related issues (target: 50% reduction) -- Improved changelog quality -- Faster hotfix deployment - -### Maintenance Metrics -- Reduced custom code maintenance (327 lines → 0) -- Simplified workflow debugging -- Improved error handling and recovery -- Better compliance with GitHub best practices - -## Conclusion - -This migration plan provides a comprehensive roadmap for replacing Hatchling's custom versioning system with semantic-release. The new system will eliminate architectural flaws while maintaining fully automated versioning through industry-standard practices. - -**Key Benefits Achieved:** -- ✅ Eliminated infinite loop risks -- ✅ Simplified architecture with proven tools -- ✅ Full GitHub branch protection compliance -- ✅ Atomic release operations -- ✅ Industry-standard Conventional Commits -- ✅ Comprehensive error handling -- ✅ Zero maintenance overhead for version management - -The migration is designed to be executed in phases with comprehensive testing and validation at each step, ensuring a smooth transition with minimal risk to the development process. diff --git a/LLM_Reports/Semantic_Release_Migration_Plan_v2.md b/LLM_Reports/Semantic_Release_Migration_Plan_v2.md deleted file mode 100644 index a76fe00..0000000 --- a/LLM_Reports/Semantic_Release_Migration_Plan_v2.md +++ /dev/null @@ -1,733 +0,0 @@ -# Semantic Release Migration Plan v2: Comprehensive Analysis & Implementation - -## Executive Summary - -This updated migration plan addresses all identified concerns and provides detailed analysis based on the latest semantic-release documentation. The migration will replace Hatchling's custom automated versioning system with the industry-standard `semantic-release` while maintaining fully automated versioning and addressing all technical requirements. - -**Key Decisions Based on Research:** - -- ✅ Use language-agnostic `semantic-release` (Node.js) - sufficient for Python projects -- ✅ Remove VERSION file - semantic-release handles version management natively -- ✅ Disable automated publishing - configure for development phase projects -- ✅ Maintain 0.x.x versioning through careful commit practices -- ✅ Integrate with existing unittest framework via custom test runner -- ✅ No dedicated GitHub App needed - standard GITHUB_TOKEN sufficient - -## Detailed Analysis of Concerns - -### 1. VERSION File Retention Analysis - -**Decision: Remove VERSION file completely** - -**Rationale:** - -- Semantic-release manages version in `pyproject.toml` directly via `@semantic-release/git` plugin -- Eliminates dual-file complexity and potential synchronization issues -- Native integration with Python packaging standards -- Reduces maintenance overhead and eliminates custom version management code - -**Implementation:** - -```toml -# pyproject.toml - Remove dynamic version -[project] -name = "hatchling" -version = "0.4.0" # Static initial version, managed by semantic-release -``` - -### 2. Asset Publishing Configuration - -**Decision: Disable automated package publishing** - -**Rationale:** - -- Development phase projects should not auto-publish to PyPI -- GitHub releases provide sufficient distribution for development -- Can be enabled later when ready for public distribution - -**Configuration:** - -```json -{ - "plugins": [ - "@semantic-release/commit-analyzer", - "@semantic-release/release-notes-generator", - "@semantic-release/changelog", - ["@semantic-release/git", { - "assets": ["CHANGELOG.md", "pyproject.toml"], - "message": "chore(release): ${nextRelease.version} [skip ci]\n\n${nextRelease.notes}" - }], - ["@semantic-release/github", { - "assets": false, // No asset uploads - "successComment": false, // Disable PR/issue comments for development - "failComment": false - }] - ] -} -``` - -### 3. Git Tagging Analysis - -**Decision: Semantic-release automatic tagging is sufficient** - -**Rationale:** - -- Semantic-release automatically creates Git tags for each release -- Tags follow semantic versioning format (v1.0.0, v1.1.0, etc.) -- Supports version-based cloning: `git clone --branch v1.0.0 ` -- No additional tag management needed - -**Tag Format:** - -- Production releases: `v1.0.0`, `v1.1.0`, `v2.0.0` -- Pre-releases: `v1.1.0-dev.1`, `v1.1.0-beta.1` - -### 4. Development Versioning (0.x.x) Strategy - -**Decision: Maintain 0.x.x through commit discipline** - -**Rationale:** - -- Semantic-release respects current version in `pyproject.toml` -- Starting at `0.4.0` will continue 0.x.x series -- Avoid `BREAKING CHANGE` commits to prevent 1.0.0 release -- Use `feat!:` syntax sparingly until ready for 1.0.0 - -**Implementation Strategy:** - -```bash -# Safe commit types for 0.x.x maintenance: -feat: new feature # 0.4.0 → 0.5.0 -fix: bug fix # 0.4.0 → 0.4.1 -docs: documentation # No version change -chore: maintenance # No version change - -# Avoid until ready for 1.0.0: -feat!: breaking change # Would trigger 0.4.0 → 1.0.0 -BREAKING CHANGE: in footer # Would trigger 0.4.0 → 1.0.0 -``` - -### 5. Documentation Updates Required - -**Files to Update:** - -1. `docs/articles/devs/versioning.md` - Complete rewrite -2. `README.md` - Update development section -3. `CONTRIBUTING.md` - Create with Conventional Commits guide - -**Key Changes:** - -- Remove all references to VERSION/VERSION.meta files -- Replace branch-based versioning with commit-based versioning -- Update workflow documentation -- Add Conventional Commits examples - -### 6. Contributor Requirements Analysis - -**Decision: Gradual adoption with tooling support** - -**Based on Conventional Commits FAQ:** - -- Not all contributors need to follow specification initially -- Squash merging can clean up commit history -- Provide tooling (commitizen) for guided commits -- Enforce via PR checks rather than blocking contributions - -**Implementation:** - -```json -// package.json -{ - "scripts": { - "commit": "cz", - "prepare": "husky install" - }, - "config": { - "commitizen": { - "path": "./node_modules/cz-conventional-changelog" - } - } -} -``` - -### 7. Testing Framework Integration - -**Decision: Maintain existing unittest framework** - -**Rationale:** - -- Existing `run_tests.py` provides comprehensive test management -- No need to migrate to pytest for semantic-release -- Semantic-release only needs test command to pass/fail -- Custom test runner supports advanced filtering and categorization - -**GitHub Actions Integration:** - -```yaml -- name: Run tests - run: python run_tests.py --regression --feature -``` - -### 8. Tool Selection: semantic-release vs python-semantic-release - -**Decision: Use language-agnostic `semantic-release` (Node.js)** - -**Rationale from Official Documentation:** - -- More mature and feature-complete -- Larger plugin ecosystem -- Better GitHub Actions integration -- Official documentation recommends Node.js version -- Python projects commonly use Node.js semantic-release - -**Evidence from GitHub Actions docs:** - -```yaml -# Official semantic-release GitHub Actions example -- name: Setup Node.js - uses: actions/setup-node@v4 - with: - node-version: "lts/*" -- name: Release - run: npx semantic-release -``` - -## Updated Implementation Plan - -### Phase 1: Preparation (Week 1) - -#### 1.1 Install Node.js Dependencies - -Create `package.json`: - -```json -{ - "name": "hatchling", - "private": true, - "scripts": { - "commit": "cz", - "semantic-release": "semantic-release" - }, - "devDependencies": { - "semantic-release": "^22.0.12", - "@semantic-release/changelog": "^6.0.3", - "@semantic-release/git": "^10.0.1", - "@semantic-release/github": "^9.2.6", - "commitizen": "^4.3.0", - "@commitlint/cli": "^18.6.1", - "@commitlint/config-conventional": "^18.6.2", - "cz-conventional-changelog": "^3.3.0" - }, - "config": { - "commitizen": { - "path": "./node_modules/cz-conventional-changelog" - } - } -} -``` - -#### 1.2 Create Semantic Release Configuration - -Create `.releaserc.json`: - -```json -{ - "branches": [ - "main", - { - "name": "dev", - "prerelease": "dev" - } - ], - "plugins": [ - [ - "@semantic-release/commit-analyzer", - { - "preset": "conventionalcommits", - "releaseRules": [ - {"type": "docs", "scope": "README", "release": "patch"}, - {"type": "refactor", "release": "patch"}, - {"type": "style", "release": "patch"}, - {"type": "test", "release": false}, - {"type": "chore", "release": false} - ] - } - ], - [ - "@semantic-release/release-notes-generator", - { - "preset": "conventionalcommits", - "presetConfig": { - "types": [ - {"type": "feat", "section": "Features"}, - {"type": "fix", "section": "Bug Fixes"}, - {"type": "docs", "section": "Documentation"}, - {"type": "refactor", "section": "Code Refactoring"}, - {"type": "perf", "section": "Performance Improvements"} - ] - } - } - ], - [ - "@semantic-release/changelog", - { - "changelogFile": "CHANGELOG.md" - } - ], - [ - "@semantic-release/git", - { - "assets": ["CHANGELOG.md", "pyproject.toml"], - "message": "chore(release): ${nextRelease.version} [skip ci]\n\n${nextRelease.notes}" - } - ], - [ - "@semantic-release/github", - { - "successComment": false, - "failComment": false, - "releasedLabels": false - } - ] - ] -} -``` - -#### 1.3 Create Commitlint Configuration - -Create `.commitlintrc.json`: - -```json -{ - "extends": ["@commitlint/config-conventional"], - "rules": { - "type-enum": [ - 2, - "always", - [ - "build", - "chore", - "ci", - "docs", - "feat", - "fix", - "perf", - "refactor", - "revert", - "style", - "test" - ] - ], - "subject-case": [2, "never", ["start-case", "pascal-case", "upper-case"]], - "subject-empty": [2, "never"], - "subject-full-stop": [2, "never", "."], - "header-max-length": [2, "always", 72] - } -} -``` - -### Phase 2: GitHub Actions Setup (Week 1) - -#### 2.1 Create New Release Workflow - -Create `.github/workflows/semantic-release.yml`: - -```yaml -name: Semantic Release - -on: - push: - branches: - - main - - dev - -permissions: - contents: write - issues: write - pull-requests: write - id-token: write - -jobs: - test: - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v4 - with: - fetch-depth: 0 - - - name: Setup Python - uses: actions/setup-python@v5 - with: - python-version: '3.12' - - - name: Install Python dependencies - run: | - python -m pip install --upgrade pip - pip install -e . - - - name: Run tests - run: python run_tests.py --regression --feature - - release: - needs: test - runs-on: ubuntu-latest - if: github.event_name == 'push' - steps: - - name: Checkout - uses: actions/checkout@v4 - with: - fetch-depth: 0 - token: ${{ secrets.GITHUB_TOKEN }} - - - name: Setup Node.js - uses: actions/setup-node@v4 - with: - node-version: "lts/*" - - - name: Install Node dependencies - run: npm ci - - - name: Verify npm audit - run: npm audit signatures - - - name: Release - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: npx semantic-release -``` - -#### 2.2 Create Commit Lint Workflow - -Create `.github/workflows/commitlint.yml`: - -```yaml -name: Commit Lint - -on: - pull_request: - branches: [main, dev] - -jobs: - commitlint: - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v4 - with: - fetch-depth: 0 - - - name: Setup Node.js - uses: actions/setup-node@v4 - with: - node-version: "lts/*" - - - name: Install dependencies - run: npm ci - - - name: Validate PR commits with commitlint - run: npx commitlint --from ${{ github.event.pull_request.base.sha }} --to ${{ github.event.pull_request.head.sha }} --verbose -``` - -### Phase 3: Project Configuration Updates (Week 1) - -#### 3.1 Update pyproject.toml - -```toml -[project] -name = "hatchling" -version = "0.4.0" # Remove dynamic = ["version"] -description = "LLM with MCP Tool Calling" -# ... rest unchanged -``` - -#### 3.2 Create .gitignore Updates - -Add to `.gitignore`: - -``` -# Node.js dependencies for semantic-release -node_modules/ -npm-debug.log* -yarn-debug.log* -yarn-error.log* - -# Semantic-release -.semantic-release/ -``` - -### Phase 4: Migration Execution (Week 2) - -#### 4.1 Remove Custom System - -**Files to Delete:** - -```bash -# Remove custom versioning system -rm -rf scripts/ -rm VERSION VERSION.meta - -# Remove custom workflows -rm .github/workflows/auto_merge_version_bump.yml -rm .github/workflows/commit_version_tag.yml -rm .github/workflows/create_tag_on_main.yml -rm .github/workflows/tag-cleanup.yml -rm .github/workflows/tag-release.yml -rm .github/workflows/release.yml -``` - -#### 4.2 Initialize Semantic Release - -```bash -# Install Node dependencies -npm install - -# Test configuration -npx semantic-release --dry-run - -# Create initial migration commit -git add . -git commit -m "feat!: migrate to semantic-release - -BREAKING CHANGE: Replace custom versioning system with semantic-release. -This requires using Conventional Commits for all future changes. - -- Remove custom scripts and workflows -- Add semantic-release configuration -- Update project structure for automated releases" -``` - -### Phase 5: Documentation Updates (Week 2) - -#### 5.1 Update Versioning Documentation - -Replace `docs/articles/devs/versioning.md` content: - -```markdown -# Automated Versioning with Semantic Release - -Hatchling uses [semantic-release](https://semantic-release.gitbook.io/) for fully automated versioning and releases based on [Conventional Commits](https://www.conventionalcommits.org/). - -## How It Works - -1. **Commit Analysis**: Analyzes commit messages to determine release type -2. **Version Calculation**: Automatically calculates next version -3. **Changelog Generation**: Creates release notes from commits -4. **GitHub Release**: Publishes release with generated notes -5. **Version Update**: Updates pyproject.toml with new version - -## Commit Message Format - -Use [Conventional Commits](https://www.conventionalcommits.org/) format: - -``` - -[optional scope]: - -[optional body] - -[optional footer(s)] - -``` - -### Examples - -```bash -feat: add new LLM provider support -fix: resolve memory leak in streaming -docs: update API documentation -refactor: simplify provider registry -test: add integration tests for OpenAI -chore: update dependencies - -# Breaking changes (avoid until ready for v1.0.0) -feat!: change configuration format -``` - -### Version Impact - -- `feat:` → Minor version (0.4.0 → 0.5.0) -- `fix:` → Patch version (0.4.0 → 0.4.1) -- `feat!:` or `BREAKING CHANGE:` → Major version (0.4.0 → 1.0.0) -- `docs:`, `test:`, `chore:` → No release - -## Using Commitizen - -For guided commit messages: - -```bash -npm run commit -# or -npx cz -``` - -## Branches - -- **main**: Production releases (0.4.0, 0.5.0, etc.) -- **dev**: Pre-releases (0.5.0-dev.1, 0.5.0-dev.2, etc.) - -## Manual Testing - -Test semantic-release configuration: - -```bash -npx semantic-release --dry-run -``` - -``` - -#### 5.2 Create Contributing Guide - -Create `CONTRIBUTING.md`: -```markdown -# Contributing to Hatchling - -## Commit Message Format - -We use [Conventional Commits](https://www.conventionalcommits.org/) for automated versioning. - -### Quick Reference - -- `feat:` - New features -- `fix:` - Bug fixes -- `docs:` - Documentation changes -- `refactor:` - Code refactoring -- `test:` - Test changes -- `chore:` - Maintenance tasks - -### Using Commitizen - -For guided commits: -```bash -npm run commit -``` - -### Pull Requests - -- Use descriptive titles -- Reference related issues -- Ensure tests pass -- Follow commit message format - -``` - -## Branch Protection & Permissions - -### Required GitHub Settings - -**Branch Protection Rules for `main`:** -- ✅ Require a pull request before merging -- ✅ Require status checks to pass before merging - - ✅ `test` (from semantic-release workflow) - - ✅ `commitlint` (from commitlint workflow) -- ✅ Require branches to be up to date before merging -- ✅ Require linear history - -**Repository Permissions:** -- Semantic-release workflow uses `GITHUB_TOKEN` (no additional setup needed) -- Standard permissions sufficient: `contents: write`, `issues: write`, `pull-requests: write` - -## Testing Strategy - -### Pre-Migration Testing - -1. **Dry Run Test:** - ```bash - npx semantic-release --dry-run - ``` - -2. **Commit Format Validation:** - - ```bash - echo "feat: test commit" | npx commitlint - ``` - -3. **Workflow Validation:** - - Create test branch - - Make conventional commit - - Verify workflow triggers - -### Post-Migration Validation - -1. **Feature Release Test:** - - ```bash - git checkout -b feat/test-semantic-release - echo "# Test" >> test.md - git add test.md - git commit -m "feat: add test file for semantic-release validation" - # Create PR and merge to main - ``` - -2. **Pre-release Test:** - - ```bash - git checkout dev - git commit -m "feat: test dev pre-release" --allow-empty - git push origin dev - ``` - -## Rollback Plan - -### Emergency Rollback - -If critical issues arise: - -1. **Disable Workflows:** - - ```bash - mv .github/workflows/semantic-release.yml .github/workflows/semantic-release.yml.disabled - ``` - -2. **Restore Manual Versioning:** - - ```bash - # Create emergency VERSION file - echo "0.4.0" > VERSION - - # Update pyproject.toml - # Change: version = "0.4.0" - # To: dynamic = ["version"] - ``` - -3. **Emergency Release:** - - ```bash - git tag v0.4.1 - git push origin v0.4.1 - ``` - -## Success Metrics - -### Technical Metrics - -- ✅ Zero workflow failures -- ✅ Automated version management -- ✅ Consistent release notes -- ✅ Proper semantic versioning - -### Process Metrics - -- ✅ Team adoption of Conventional Commits -- ✅ Reduced manual release overhead -- ✅ Improved changelog quality -- ✅ Faster development cycle - -## Timeline Summary - -- **Week 1**: Setup and configuration -- **Week 2**: Migration execution and testing -- **Week 3**: Documentation and team training -- **Week 4**: Monitoring and optimization - -## Conclusion - -This migration plan provides a comprehensive, tested approach to replacing the custom versioning system with semantic-release. All concerns have been addressed with specific technical solutions based on official documentation and best practices. - -The new system will provide: - -- ✅ Fully automated versioning without manual intervention -- ✅ Industry-standard Conventional Commits workflow -- ✅ Elimination of complex custom code (327+ lines removed) -- ✅ Better compliance with GitHub best practices -- ✅ Improved developer experience with guided tooling diff --git a/LLM_Reports/Workflow_Optimization_Report.md b/LLM_Reports/Workflow_Optimization_Report.md deleted file mode 100644 index 8c0173f..0000000 --- a/LLM_Reports/Workflow_Optimization_Report.md +++ /dev/null @@ -1,555 +0,0 @@ -# Workflow Optimization Report: Hatchling Automated Versioning System - -## Executive Summary - -This report evaluates the current Hatchling workflow architecture, identifies critical issues with infinite loops and complex dependencies, and proposes optimized solutions. The analysis reveals fundamental architectural problems that require immediate attention to prevent system failure. - -## Current Implementation Analysis - -### Workflow Dependency Chain - -**Current Flow**: - -``` -Push to dev/feat/fix → commit_version_tag.yml - ↓ - test_build.yml (reusable) - ↓ - Create PR to main - ↓ - validate-pr-to-main.yml - ↓ - validate-pr-branch-common.yml - ↓ - auto_merge_version_bump.yml - ↓ - Merge to main - ↓ - create_tag_on_main.yml -``` - -### Critical Issues Identified - -#### 1. Infinite Loop Risk (CRITICAL) - -**Problem**: Workflows can trigger each other indefinitely -**Scenarios**: - -- `commit_version_tag.yml` creates PR → triggers validation → triggers auto-merge → merges to main → could trigger `commit_version_tag.yml` again -- Failed auto-merge could retry indefinitely -- Multiple concurrent pushes could create cascading workflows - -**Risk Level**: CRITICAL - System can become completely unusable - -#### 2. Complex Dependency Chain (HIGH) - -**Problem**: 6+ workflows must execute in sequence for single version bump -**Issues**: - -- High failure probability (each step can fail) -- Difficult debugging and troubleshooting -- Long execution time -- Resource waste - -#### 3. Race Conditions (MEDIUM) - -**Problem**: Concurrent pushes can interfere with each other -**Scenarios**: - -- Multiple feature branches pushing simultaneously -- PR creation conflicts -- Version file conflicts - -#### 4. Lack of Atomic Operations (MEDIUM) - -**Problem**: Version updates span multiple commits and workflows -**Issues**: - -- Inconsistent state during failures -- Difficult rollback procedures -- Potential data loss - -## Workflow-by-Workflow Evaluation - -### 1. commit_version_tag.yml - -**Grade**: D -**Issues**: - -- Triggers on too many branches (dev, main, feat/*, fix/*) -- Creates complex PR workflow instead of direct commits -- No loop prevention mechanisms -- Overly complex for simple version updates - -**Strengths**: - -- Uses GitHub App authentication -- Includes proper testing via test_build.yml -- Handles artifact management - -### 2. auto_merge_version_bump.yml - -**Grade**: F -**Issues**: - -- Workflow chaining creates infinite loop risk -- Complex conditional logic prone to errors -- Depends on external workflow completion -- No fail-safe mechanisms - -**Recommendation**: DISABLE IMMEDIATELY - -### 3. validate-pr-to-main.yml & validate-pr-branch-common.yml - -**Grade**: B -**Issues**: - -- Adds unnecessary complexity to simple automation -- Creates additional failure points - -**Strengths**: - -- Well-designed validation logic -- Proper organization membership checks -- Reusable architecture - -### 4. test_build.yml - -**Grade**: A -**Issues**: None significant -**Strengths**: - -- Clean reusable workflow -- Proper artifact handling -- Good separation of concerns - -### 5. create_tag_on_main.yml - -**Grade**: B+ -**Issues**: - -- Relies on commit message parsing (fragile) -- No error handling for tag conflicts - -**Strengths**: - -- Simple and focused -- Proper conditional execution - -## Proposed Optimized Architectures - -### Option 1: Direct Commit Architecture (Recommended) - -**Simplified Flow**: - -``` -Push to dev/feat/fix → Single Workflow: - 1. Run tests - 2. Update version files - 3. Commit directly to branch - 4. Create tag (if main branch) - 5. Create release (if main branch) -``` - -**Implementation**: - -```yaml -name: Automated Versioning -on: - push: - branches: [main, dev, 'feat/*', 'fix/*'] - -jobs: - version-and-release: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - with: - fetch-depth: 0 - token: ${{ secrets.GITHUB_APP_TOKEN }} - - - name: Setup Python - uses: actions/setup-python@v5 - with: - python-version: '3.12' - - - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install build twine - - - name: Run tests - run: python -m pytest tests/ - - - name: Update version - id: version - run: | - VERSION=$(python scripts/version_manager.py --update-for-branch ${{ github.ref_name }}) - echo "version=$VERSION" >> $GITHUB_OUTPUT - echo "Updated to version: $VERSION" - - - name: Build package - run: python -m build - - - name: Test package installation - run: pip install dist/*.whl - - - name: Commit version files - run: | - git config --local user.email "action@github.com" - git config --local user.name "Hatchling Bot" - git add VERSION VERSION.meta - if git diff --staged --quiet; then - echo "No version changes to commit" - else - git commit -m "chore: update version to ${{ steps.version.outputs.version }} [skip ci]" - git push - fi - - - name: Create tag and release (main branch only) - if: github.ref == 'refs/heads/main' - run: | - git tag -a "${{ steps.version.outputs.version }}" -m "Release ${{ steps.version.outputs.version }}" - git push origin "${{ steps.version.outputs.version }}" - - - name: Create GitHub Release (main branch only) - if: github.ref == 'refs/heads/main' - uses: softprops/action-gh-release@v2 - with: - tag_name: ${{ steps.version.outputs.version }} - name: Release ${{ steps.version.outputs.version }} - body: | - Release ${{ steps.version.outputs.version }} - - ## Installation - ```bash - pip install hatchling==${{ steps.version.outputs.version }} - ``` - files: dist/* -``` - -**Benefits**: - -- Single workflow eliminates dependency chains -- Atomic operations reduce failure points -- Direct commits bypass PR complexity -- Built-in loop prevention with [skip ci] -- Faster execution time - -### Option 2: Tag-Based Architecture - -**Flow**: - -``` -Manual tag creation → Workflow: - 1. Validate tag format - 2. Update version files - 3. Build and test - 4. Create release - 5. Publish packages -``` - -**Implementation**: - -```yaml -name: Release on Tag -on: - push: - tags: - - 'v*' - -jobs: - release: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - - name: Extract version - id: version - run: | - VERSION=${GITHUB_REF#refs/tags/} - echo "version=$VERSION" >> $GITHUB_OUTPUT - - - name: Update version files - run: | - # Update VERSION files to match tag - echo "${VERSION#v}" > VERSION - # Update VERSION.meta accordingly - - - name: Build and test - run: | - python -m pip install --upgrade pip build - python -m build - pip install dist/*.whl - python -m pytest - - - name: Create Release - uses: softprops/action-gh-release@v2 - with: - files: dist/* -``` - -**Benefits**: - -- Explicit release control -- No automatic triggers -- Simple and predictable -- Easy rollback via tag deletion - -### Option 3: Hybrid Architecture - -**Flow**: - -``` -Push to dev/feat/fix → Update versions only -Manual trigger → Create release from main -``` - -**Benefits**: - -- Automatic version management -- Manual release control -- Reduced complexity -- Better oversight - -## Loop Prevention Strategies - -### 1. Commit Message Filtering - -```yaml -on: - push: - branches: [main, dev] -jobs: - version: - if: "!contains(github.event.head_commit.message, '[skip ci]')" -``` - -### 2. Path-Based Filtering - -```yaml -on: - push: - branches: [main, dev] - paths-ignore: - - 'VERSION' - - 'VERSION.meta' - - '**.md' -``` - -### 3. Actor-Based Filtering - -```yaml -jobs: - version: - if: github.actor != 'github-actions[bot]' -``` - -### 4. Workflow State Checking - -```yaml -- name: Check for concurrent workflows - run: | - RUNNING=$(gh run list --workflow="${{ github.workflow }}" --status=in_progress --json databaseId --jq length) - if [ "$RUNNING" -gt 1 ]; then - echo "Another workflow is running, exiting" - exit 1 - fi -``` - -## Error Handling and Recovery - -### 1. Fail-Safe Mechanisms - -```yaml -- name: Version update with rollback - run: | - # Backup current state - cp VERSION VERSION.backup - cp VERSION.meta VERSION.meta.backup - - # Attempt update - if ! python scripts/version_manager.py --update-for-branch ${{ github.ref_name }}; then - # Restore backup on failure - mv VERSION.backup VERSION - mv VERSION.meta.backup VERSION.meta - exit 1 - fi - - # Clean up backup on success - rm -f VERSION.backup VERSION.meta.backup -``` - -### 2. Retry Logic - -```yaml -- name: Push with retry - uses: nick-fields/retry@v3 - with: - timeout_minutes: 5 - max_attempts: 3 - command: git push -``` - -### 3. Notification on Failure - -```yaml -- name: Notify on failure - if: failure() - uses: actions/github-script@v7 - with: - script: | - github.rest.issues.create({ - owner: context.repo.owner, - repo: context.repo.repo, - title: 'Automated versioning failed', - body: `Workflow failed: ${context.runId}` - }) -``` - -## Alternative Triggering Mechanisms - -### 1. Manual Workflow Dispatch - -```yaml -on: - workflow_dispatch: - inputs: - version_type: - description: 'Version increment type' - required: true - default: 'patch' - type: choice - options: - - major - - minor - - patch - - dev - - build -``` - -### 2. Issue-Based Triggers - -```yaml -on: - issues: - types: [opened] - -jobs: - release: - if: contains(github.event.issue.title, '[RELEASE]') -``` - -### 3. Schedule-Based Releases - -```yaml -on: - schedule: - - cron: '0 9 * * 1' # Weekly releases on Monday -``` - -### 4. External Webhook Triggers - -```yaml -on: - repository_dispatch: - types: [release-request] -``` - -## Performance Optimization - -### 1. Parallel Execution - -```yaml -jobs: - test: - strategy: - matrix: - python-version: [3.11, 3.12] - runs-on: ubuntu-latest - - version: - needs: test - runs-on: ubuntu-latest -``` - -### 2. Caching - -```yaml -- name: Cache dependencies - uses: actions/cache@v4 - with: - path: ~/.cache/pip - key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements.txt') }} -``` - -### 3. Conditional Execution - -```yaml -- name: Skip if no changes - id: changes - run: | - if git diff --quiet HEAD~1 -- scripts/ hatchling/; then - echo "skip=true" >> $GITHUB_OUTPUT - fi - -- name: Run tests - if: steps.changes.outputs.skip != 'true' - run: python -m pytest -``` - -## Implementation Grades and Recommendations - -### Current Implementation: D- - -**Issues**: - -- Critical infinite loop risk -- Overly complex architecture -- Multiple failure points -- Poor error handling - -### Recommended Implementation: A- - -**Option 1 (Direct Commit)**: - -- Simple and reliable -- Atomic operations -- Built-in loop prevention -- Fast execution -- Easy debugging - -### Migration Strategy - -#### Phase 1: Immediate (Week 1) - -1. **DISABLE** `auto_merge_version_bump.yml` -2. **MODIFY** `commit_version_tag.yml` to add loop prevention -3. **ADD** proper error handling - -#### Phase 2: Short-term (Week 2-3) - -1. **IMPLEMENT** Option 1 (Direct Commit Architecture) -2. **TEST** thoroughly in development environment -3. **MIGRATE** gradually (one branch at a time) - -#### Phase 3: Long-term (Month 2) - -1. **REMOVE** deprecated workflows -2. **OPTIMIZE** performance -3. **ADD** comprehensive monitoring - -## Conclusion - -The current Hatchling workflow architecture suffers from critical design flaws that pose immediate risks to system stability. The complex dependency chain and infinite loop potential require urgent remediation. - -**Immediate Actions Required**: - -1. Disable auto-merge workflow to prevent infinite loops -2. Implement loop prevention in existing workflows -3. Plan migration to simplified architecture - -**Recommended Solution**: Direct Commit Architecture (Option 1) provides the best balance of simplicity, reliability, and functionality while maintaining all required features. - -**Overall Grade**: Current (D-) → Recommended (A-) -**Priority**: URGENT - System stability at immediate risk From c6d997625909c611074bb66c6fd14391872949e9 Mon Sep 17 00:00:00 2001 From: LittleCoinCoin Date: Tue, 26 Aug 2025 10:00:29 +0900 Subject: [PATCH 3/4] chore: set the static version number Before switching to `semantic-release` the version was 0.4.2 --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index c12c6df..17359b5 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "hatchling" -version = "0.4.0" +version = "0.4.2" description = "LLM with MCP Tool Calling" readme = "README.md" requires-python = ">=3.12" From 6658bad6106be378120c0764bd754f2647d340ea Mon Sep 17 00:00:00 2001 From: LittleCoinCoin Date: Tue, 26 Aug 2025 10:05:57 +0900 Subject: [PATCH 4/4] chore(ci): remove old workflows --- .github/workflows/feature-fix.yml | 106 ------------- .../workflows/validate-pr-branch-common.yml | 141 ------------------ .github/workflows/validate-pr-to-dev.yml | 17 --- .github/workflows/validate-pr-to-main.yml | 17 --- 4 files changed, 281 deletions(-) delete mode 100644 .github/workflows/feature-fix.yml delete mode 100644 .github/workflows/validate-pr-branch-common.yml delete mode 100644 .github/workflows/validate-pr-to-dev.yml delete mode 100644 .github/workflows/validate-pr-to-main.yml diff --git a/.github/workflows/feature-fix.yml b/.github/workflows/feature-fix.yml deleted file mode 100644 index f1b184c..0000000 --- a/.github/workflows/feature-fix.yml +++ /dev/null @@ -1,106 +0,0 @@ -name: Feature/Fix Branch - -on: - workflow_dispatch: - # This workflow became useless after the introduction of the `commit_version_tag.yml` workflow. - # Keeping for now until new version has been tested. - # push: - # branches: - # - 'feat/**' - # - 'fix/**' - # pull_request: - # branches: - # - 'feat/**' - # - 'fix/**' - -env: - PYTHON_VERSION: '3.12' - -jobs: - test: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - with: - fetch-depth: 0 - - - name: Set up Python - uses: actions/setup-python@v5 - with: - python-version: ${{ env.PYTHON_VERSION }} - - - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install build twine - - - name: Update version for branch - run: | - BRANCH_NAME=${GITHUB_REF#refs/heads/} - python scripts/version_manager.py --update-for-branch "$BRANCH_NAME" - - - name: Get version info - id: version - run: | - VERSION=$(python scripts/version_manager.py --get) - echo "version=$VERSION" >> $GITHUB_OUTPUT - echo "Version: $VERSION" - - - name: Prepare version for build - run: | - python scripts/prepare_version.py - - - name: Build package - run: | - python -m build - - - name: Test package installation - run: | - pip install dist/*.whl - - - name: Display version info - run: | - echo "Built version: ${{ steps.version.outputs.version }}" - echo "Branch: ${GITHUB_REF#refs/heads/}" - - version-increment: - if: github.event_name == 'push' - needs: test - runs-on: ubuntu-latest - permissions: - contents: write - - steps: - - uses: actions/checkout@v4 - with: - fetch-depth: 0 - - - name: Set up Python - uses: actions/setup-python@v5 - with: - python-version: ${{ env.PYTHON_VERSION }} - - - name: Increment build number - run: | - BRANCH_NAME=${GITHUB_REF#refs/heads/} - python scripts/version_manager.py --increment build --branch "$BRANCH_NAME" - - - name: Get updated version - id: version - run: | - VERSION=$(python scripts/version_manager.py --get) - echo "version=$VERSION" >> $GITHUB_OUTPUT - echo "Updated version: $VERSION" - - - name: Commit updated VERSION file - run: | - git config --local user.email "action@github.com" - git config --local user.name "GitHub Action" - git add VERSION - git diff --staged --quiet || git commit -m "Increment build number to ${{ steps.version.outputs.version }}" - git push - - - name: Create lightweight tag - run: | - git tag ${{ steps.version.outputs.version }} - git push origin ${{ steps.version.outputs.version }} \ No newline at end of file diff --git a/.github/workflows/validate-pr-branch-common.yml b/.github/workflows/validate-pr-branch-common.yml deleted file mode 100644 index 86165bc..0000000 --- a/.github/workflows/validate-pr-branch-common.yml +++ /dev/null @@ -1,141 +0,0 @@ -name: Reusable PR branch & author validator - -on: - workflow_call: - inputs: - allowed_prefixes: - required: true - type: string - allowed_exact: - required: false - type: string - default: '' - require_org_for: - required: false - type: string - default: '' - allowed_apps: - required: false - type: string - default: '' - org_name: - required: false - type: string - default: 'CrackingShells' - fail_message: - required: false - type: string - default: '' - -jobs: - validate: - runs-on: ubuntu-latest - outputs: - branch_valid: ${{ steps.check.outputs.branch_valid }} - steps: - - name: Generate GitHub App token - id: generate-token - uses: tibdex/github-app-token@v2 - with: - app_id: ${{ secrets.HATCH_WORKFLOW_APP_ID }} - private_key: ${{ secrets.HATCH_WORKFLOW_APP_PRIVATE_KEY }} - - - name: Run branch and author checks - id: check - uses: actions/github-script@v7 - with: - github-token: ${{ steps.generate-token.outputs.token }} - script: | - const branch = process.env.GITHUB_HEAD_REF || '${{ github.head_ref }}'; - const author = '${{ github.event.pull_request.user.login }}'; - const prNumber = ${{ github.event.pull_request.number }}; - const owner = context.repo.owner; - const repo = context.repo.repo; - - const allowedPrefixes = (`${{ inputs.allowed_prefixes }}` || '').split(',').map(s => s.trim()).filter(Boolean); - const allowedExact = (`${{ inputs.allowed_exact }}` || '').split(',').map(s => s.trim()).filter(Boolean); - const requireOrgFor = (`${{ inputs.require_org_for }}` || '').split(',').map(s => s.trim()).filter(Boolean); - const allowedApps = (`${{ inputs.allowed_apps }}` || '').split(',').map(s => s.trim()).filter(Boolean); - const failMessage = `${{ inputs.fail_message }}` || 'Branch not allowed to open PR to this target.'; - - function matchesAllowed() { - for (const p of allowedPrefixes) { - if (p.endsWith('/')) { - if (branch.startsWith(p)) return true; - } else { - if (branch === p) return true; - } - } - if (allowedExact.includes(branch)) return true; - return false; - } - - async function isOrgMember() { - const orgName = `${{ inputs.org_name }}` || 'CrackingShells'; - try { - const res = await github.rest.orgs.checkMembershipForUser({ org: orgName, username: author }); - return res.status === 204; - } catch (e) { - return false; - } - } - - // Allowed by prefix/exact test first - if (!matchesAllowed()) { - const message = `${failMessage}\nYour branch: ${branch}.`; - await github.rest.issues.createComment({ - issue_number: prNumber, - owner, - repo, - body: message - }); - core.setFailed('Invalid branch for PR.'); - core.setOutput('branch_valid', 'invalid'); - return; - } - - // If author is an allowed app, allow - if (allowedApps.includes(author)) { - console.log(`Author ${author} is in allowed apps list`); - core.setOutput('branch_valid', 'valid'); - return; - } - - // If this branch requires org membership, check - if (requireOrgFor.includes(branch) || requireOrgFor.some(b => b === branch)) { - if (!await isOrgMember()) { - const message = `⚠️ Only members of the ${`${{ inputs.org_name }}`} organization can open PRs from '${branch}' to this target.`; - await github.rest.issues.createComment({ - issue_number: prNumber, - owner, - repo, - body: message - }); - core.setFailed('PR author is not a member of the organization.'); - core.setOutput('branch_valid', 'invalid'); - return; - } - core.setOutput('branch_valid', 'valid'); - return; - } - - // Special case: version-bump behavior - allow if org member OR allowed app - if (branch === 'version-bump') { - if (await isOrgMember()) { core.setOutput('branch_valid', 'valid'); return; } - const isAllowedApp = allowedApps.includes(author); - if (isAllowedApp) { core.setOutput('branch_valid', 'valid'); return; } - const message = `❌ Only organization members or registered GitHub Apps (${allowedApps.join(', ')}) can open PRs from 'version-bump' to this target.\nYour author: ${author}`; - await github.rest.issues.createComment({ - issue_number: prNumber, - owner, - repo, - body: message - }); - core.setFailed('PR author is not allowed for version-bump branch.'); - core.setOutput('branch_valid', 'invalid'); - return; - } - - // Otherwise allowed - core.setOutput('branch_valid', 'valid'); - return; diff --git a/.github/workflows/validate-pr-to-dev.yml b/.github/workflows/validate-pr-to-dev.yml deleted file mode 100644 index 1ee00e0..0000000 --- a/.github/workflows/validate-pr-to-dev.yml +++ /dev/null @@ -1,17 +0,0 @@ -name: Validate PR Branches to Dev - -on: - pull_request: - branches: - - dev - -jobs: - validate-branch: - uses: ./.github/workflows/validate-pr-branch-common.yml - with: - allowed_prefixes: 'docs/,cicd/,feat/,fix/' - allowed_exact: '' - require_org_for: '' - allowed_apps: '' - org_name: 'CrackingShells' - fail_message: "❌ To automate versioning, only branches starting with 'docs/', 'cicd/', 'feat/' or 'fix/' are allowed to open PRs to 'dev'." diff --git a/.github/workflows/validate-pr-to-main.yml b/.github/workflows/validate-pr-to-main.yml deleted file mode 100644 index 6800fc8..0000000 --- a/.github/workflows/validate-pr-to-main.yml +++ /dev/null @@ -1,17 +0,0 @@ -name: Validate PR Branches to Main - -on: - pull_request: - branches: - - main - -jobs: - validate-branch: - uses: ./.github/workflows/validate-pr-branch-common.yml - with: - allowed_prefixes: 'fix/,dev,version-bump' - allowed_exact: '' - require_org_for: 'dev' - allowed_apps: 'github-actions[bot],hatch-workflow-app[bot]' - org_name: 'CrackingShells' - fail_message: "❌ To automate versioning, only 'fix/*', 'dev' or 'version-bump' branches may open PRs to 'main'."