diff --git a/.github/workflows/auto-ratchet.yml b/.github/workflows/auto-ratchet.yml new file mode 100644 index 0000000..c53b3c4 --- /dev/null +++ b/.github/workflows/auto-ratchet.yml @@ -0,0 +1,114 @@ +name: Auto-ratchet thresholds +on: + push: + branches: [main] + paths: + - 'packages/*/src/**' + - 'stryker.config.mjs' + +permissions: + contents: write + pull-requests: write + +jobs: + ratchet: + name: Check & ratchet + runs-on: ubuntu-latest + timeout-minutes: 120 + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup pnpm + uses: pnpm/action-setup@v4 + with: + version: 10 + + - name: Setup Node + uses: actions/setup-node@v4 + with: + node-version: '20' + cache: 'pnpm' + + - name: Install dependencies + run: pnpm install --frozen-lockfile + + - name: Build all packages + run: pnpm -r build + + - name: Run mutation for all packages + run: pnpm mutation || true + + - name: Update baseline scores (merge, don't overwrite) + run: | + node -e " + import { PACKAGES } from './stryker.config.mjs'; + import { readFileSync, writeFileSync } from 'fs'; + let existing = {}; + try { existing = JSON.parse(readFileSync('quality-baseline.json','utf8')); } catch {} + const baseline = { ...existing }; + for (const pkg of PACKAGES) { + const prev = existing[pkg] || {}; + let coverage = prev.coverage ?? null; + let mutation = prev.mutation ?? null; + try { + coverage = JSON.parse(readFileSync('packages/' + pkg + '/coverage/coverage-summary.json','utf8')).total.lines.pct; + } catch {} + try { + const r = JSON.parse(readFileSync('reports/mutation/' + pkg + '.json','utf8')); + const t = Object.values(r.files).reduce((a,f)=>{a.k+=f.mutants.filter(m=>m.status==='Killed').length;a.t+=f.mutants.length;return a},{k:0,t:0}); + mutation = parseFloat((t.t?t.k/t.t*100:0).toFixed(2)); + } catch {} + baseline[pkg] = { coverage, mutation }; + } + writeFileSync('quality-baseline.json', JSON.stringify(baseline, null, 2) + '\n'); + " --input-type=module + + - name: Try auto-ratchet + id: ratchet + run: | + if node scripts/auto-ratchet.mjs; then + echo "changed=true" >> "$GITHUB_OUTPUT" + else + echo "changed=false" >> "$GITHUB_OUTPUT" + fi + + - name: Open PR with updated baseline and thresholds + if: steps.ratchet.outputs.changed == 'true' + run: | + git config user.name "github-actions[bot]" + git config user.email "github-actions[bot]@users.noreply.github.com" + branch="auto-ratchet/$(date +%Y%m%d)-$(git rev-parse --short HEAD)" + git checkout -b "$branch" + git add stryker.config.mjs quality-baseline.json + git commit -m "chore: auto-ratchet mutation thresholds and update baseline" + git push origin "$branch" + gh pr create \ + --base main \ + --head "$branch" \ + --title "chore: auto-ratchet mutation thresholds" \ + --body "Mutation scores have improved beyond their thresholds by more than 5 points. This PR bumps the thresholds to lock in the gains and updates the quality baseline." + env: + GH_TOKEN: ${{ github.token }} + + - name: Open PR with updated baseline only + if: steps.ratchet.outputs.changed != 'true' + run: | + if git diff --quiet quality-baseline.json; then + echo "No baseline changes" + exit 0 + fi + git config user.name "github-actions[bot]" + git config user.email "github-actions[bot]@users.noreply.github.com" + branch="quality-baseline/$(date +%Y%m%d)-$(git rev-parse --short HEAD)" + git checkout -b "$branch" + git add quality-baseline.json + git commit -m "chore: update quality baseline scores" + git push origin "$branch" + gh pr create \ + --base main \ + --head "$branch" \ + --title "chore: update quality baseline scores" \ + --body "Post-merge quality baseline update. No threshold changes." + env: + GH_TOKEN: ${{ github.token }} diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b67da38..4cac9a5 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -7,7 +7,7 @@ on: branches: [main] workflow_dispatch: -# Minimal permissions — CI only needs to read code +# Minimal permissions -- CI only needs to read code permissions: contents: read diff --git a/.github/workflows/mutation.yml b/.github/workflows/mutation.yml new file mode 100644 index 0000000..0e9aab3 --- /dev/null +++ b/.github/workflows/mutation.yml @@ -0,0 +1,205 @@ +name: Quality +on: + pull_request: + types: [opened, synchronize, reopened] + +permissions: + contents: read + pull-requests: write + issues: write + +jobs: + quality: + name: quality / ${{ matrix.package }} + runs-on: ubuntu-latest + timeout-minutes: 90 + strategy: + fail-fast: false + matrix: + package: [adapter-claude, sdk, mcp-server, cli, sidecar] + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 1 + + - name: Setup pnpm + uses: pnpm/action-setup@v4 + with: + version: 10 + + - name: Setup Node + uses: actions/setup-node@v4 + with: + node-version: '20' + cache: 'pnpm' + + - name: Install dependencies + run: pnpm install --frozen-lockfile + + - name: Build all packages + run: pnpm -r build + + - name: Run tests with coverage + continue-on-error: true + working-directory: packages/${{ matrix.package }} + run: npx vitest run --coverage --coverage.reporter=json-summary --coverage.reportsDirectory=coverage + + - name: Restore Stryker incremental cache + uses: actions/cache@v4 + with: + path: .stryker-tmp/${{ matrix.package }}-incremental.json + key: stryker-${{ matrix.package }}-${{ hashFiles(format('packages/{0}/src/**', matrix.package), 'stryker.config.mjs') }} + restore-keys: | + stryker-${{ matrix.package }}- + + - name: Run Stryker + id: stryker-run + run: | + if pnpm mutation ${{ matrix.package }}; then + echo "failed=false" >> "$GITHUB_OUTPUT" + else + echo "failed=true" >> "$GITHUB_OUTPUT" + fi + + - name: Annotate surviving mutants on PR diff + if: always() + run: node scripts/annotate-survivors.mjs reports/mutation/${{ matrix.package }}.json || true + + - name: Extract mutation score + if: always() + id: stryker + run: | + file="reports/mutation/${{ matrix.package }}.json" + if [ -f "$file" ]; then + score=$(node -e "const r=JSON.parse(require('fs').readFileSync('$file','utf8'));const t=Object.values(r.files).reduce((a,f)=>{a.k+=f.mutants.filter(m=>m.status==='Killed').length;a.t+=f.mutants.length;return a},{k:0,t:0});console.log((t.t?t.k/t.t*100:0).toFixed(2))") + echo "score=${score}" >> "$GITHUB_OUTPUT" + else + echo "score=N/A" >> "$GITHUB_OUTPUT" + fi + + - name: Extract coverage percentage + if: always() + id: coverage + run: | + file="packages/${{ matrix.package }}/coverage/coverage-summary.json" + if [ -f "$file" ]; then + pct=$(node -e "const s=JSON.parse(require('fs').readFileSync('$file','utf8'));console.log(s.total.lines.pct)") + echo "lines=${pct}" >> "$GITHUB_OUTPUT" + else + echo "lines=N/A" >> "$GITHUB_OUTPUT" + fi + + - name: Write score artifact + if: always() + run: | + mkdir -p .quality-scores + echo '{"package":"${{ matrix.package }}","coverage":"${{ steps.coverage.outputs.lines }}","mutation":"${{ steps.stryker.outputs.score }}"}' > .quality-scores/${{ matrix.package }}.json + + - name: Upload scores + if: always() + uses: actions/upload-artifact@v4 + with: + name: quality-score-${{ matrix.package }} + path: .quality-scores/${{ matrix.package }}.json + + - name: Upload Stryker HTML report + if: always() + uses: actions/upload-artifact@v4 + with: + name: mutation-report-${{ matrix.package }} + path: reports/mutation/${{ matrix.package }}.html + retention-days: 14 + + - name: Enforce mutation threshold + if: steps.stryker-run.outputs.failed == 'true' + run: | + echo "Mutation score below threshold for ${{ matrix.package }}" + exit 1 + + comment: + name: PR Comment + needs: quality + if: always() && github.event.pull_request.head.repo.full_name == github.repository + runs-on: ubuntu-latest + steps: + - name: Checkout (for baseline file) + uses: actions/checkout@v4 + with: + ref: main + sparse-checkout: quality-baseline.json + sparse-checkout-cone-mode: false + + - name: Download all score artifacts + uses: actions/download-artifact@v4 + with: + pattern: quality-score-* + merge-multiple: true + path: scores + + - name: Build and post comment + uses: actions/github-script@v7 + with: + script: | + const fs = require('fs'); + + // Load baseline from main (may not exist yet) + let baseline = {}; + try { baseline = JSON.parse(fs.readFileSync('quality-baseline.json', 'utf8')); } catch {} + + const files = fs.readdirSync('scores').filter(f => f.endsWith('.json')); + const rows = files + .map(f => JSON.parse(fs.readFileSync(`scores/${f}`, 'utf8'))) + .sort((a, b) => a.package.localeCompare(b.package)) + .map(r => { + const base = baseline[r.package] || {}; + const fmtDelta = (cur, prev) => { + if (cur === 'N/A' || prev == null) return ''; + const d = (parseFloat(cur) - prev).toFixed(1); + if (d > 0) return ` (+${d})`; + if (d < 0) return ` (${d})`; + return ''; + }; + const cov = r.coverage === 'N/A' ? 'N/A' : r.coverage + '%' + fmtDelta(r.coverage, base.coverage); + const mut = r.mutation === 'N/A' ? 'N/A' : r.mutation + '%' + fmtDelta(r.mutation, base.mutation); + return `| ${r.package} | ${cov} | ${mut} |`; + }) + .join('\n'); + + const body = [ + '## Quality Report', + '', + '| Package | Line Coverage | Mutation Score |', + '|---------|-------------|----------------|', + rows, + '', + '> Coverage = % of lines your tests touch. Mutation = % of code changes your tests catch.', + '> Deltas shown vs `main` baseline. Mutation reports available as workflow artifacts.', + ].join('\n'); + + const marker = ''; + const fullBody = marker + '\n' + body; + + const { data: comments } = await github.rest.issues.listComments({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: context.issue.number, + }); + + const existing = comments.find(c => c.body?.includes(marker)); + + if (existing) { + await github.rest.issues.updateComment({ + owner: context.repo.owner, + repo: context.repo.repo, + comment_id: existing.id, + body: fullBody, + }); + } else { + await github.rest.issues.createComment({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: context.issue.number, + body: fullBody, + }); + } diff --git a/.gitignore b/.gitignore index 26c5207..9f14f91 100644 --- a/.gitignore +++ b/.gitignore @@ -59,6 +59,10 @@ packages/sdk-python/.venv/ # ── Worktrees ───────────────────────────────────────────────────────────────── .worktrees/ +# ── Stryker (mutation testing) ──────────────────────────────────────────────── +.stryker-tmp/ +reports/mutation/ + # ── Misc ────────────────────────────────────────────────────────────────────── *.ots commit.txt diff --git a/docs/guides/mutation-testing.md b/docs/guides/mutation-testing.md new file mode 100644 index 0000000..69c5ca6 --- /dev/null +++ b/docs/guides/mutation-testing.md @@ -0,0 +1,61 @@ +# Mutation Testing + +## Why + +Test coverage tells you which lines ran. Mutation testing tells you which lines your tests actually verify. Stryker modifies production code in small ways (negate a condition, drop a statement, swap an operator) and re-runs the suite. If the suite still passes, the mutant "survived" and the test is too weak. + +This matters most for security-adjacent code like path-traversal guards and tag-breakout escapes, where a `expect(ctx).not.toContain(...)` assertion can stay green even if the guard silently breaks. + +## What was added + +No production code changes. Infrastructure only: + +- `stryker.config.mjs` -- single root config with per-package threshold map +- `scripts/mutation.mjs` -- wrapper: `pnpm mutation adapter-claude` or `pnpm mutation` for all +- `scripts/annotate-survivors.mjs` -- emits GitHub warning annotations on PR diffs for surviving mutants +- `scripts/auto-ratchet.mjs` -- bumps thresholds when scores improve by more than 5 points +- `quality-baseline.json` -- last-known scores on main, used for delta display in PR comments +- `.github/workflows/mutation.yml` -- Quality workflow: coverage + mutation per package, unified PR comment +- `.github/workflows/auto-ratchet.yml` -- post-merge: updates baseline, opens ratchet PR if thresholds can be bumped + +## Running locally + +```bash +pnpm mutation adapter-claude # single package +pnpm mutation # all packages sequentially +``` + +Each run produces an HTML report at `reports/mutation/.html` and a JSON report at `reports/mutation/.json`. First run is slow; subsequent runs use incremental cache. + +## What you see on PRs + +**Quality Report comment** (one sticky comment, updated on each push): + +| Package | Line Coverage | Mutation Score | +|---------|--------------|----------------| +| adapter-claude | 83.9% (+1.2) | 50.8% (+0.5) | +| sdk | 67.2% | 54.3% (-0.3) | + +Deltas are vs the `main` baseline stored in `quality-baseline.json`. + +**Inline annotations**: surviving mutants appear as warnings directly on the PR diff, on the exact line Stryker mutated. No need to download the HTML report for the most common case. + +## Thresholds + +| Package | Threshold | Baseline score | +|---|---|---| +| adapter-claude | 45 | 49.57% | +| sdk | 49 | 54.31% | +| mcp-server | 26 | 31.31% | +| cli | 45 | 49.50% | +| sidecar | 46 | 51.43% | + +Thresholds live in the `THRESHOLDS` map in `stryker.config.mjs`. + +**Auto-ratchet**: when a PR merges to main and a package's score exceeds its threshold by more than 5 points, the `auto-ratchet.yml` workflow opens a PR to bump the threshold automatically. You review and merge it like any other PR. + +## When CI is red + +1. Check the inline annotations on your PR diff first -- they show the surviving mutants on the exact lines. +2. If you need more detail, download the `mutation-report-` artifact and open the HTML report. +3. Either write a stronger test or lower the threshold if the survivor is an equivalent mutant. diff --git a/package.json b/package.json index 8b1bfc5..0f691fe 100644 --- a/package.json +++ b/package.json @@ -13,9 +13,12 @@ "lint": "pnpm -r lint", "clean": "pnpm -r clean", "typecheck": "pnpm -r typecheck", - "schema:export": "tsx packages/sdk/src/scripts/export-schema.ts" + "schema:export": "tsx packages/sdk/src/scripts/export-schema.ts", + "mutation": "node scripts/mutation.mjs" }, "devDependencies": { + "@stryker-mutator/core": "^8.7.1", + "@stryker-mutator/vitest-runner": "^8.7.1", "@types/node": "^20.17.0", "@vitest/coverage-v8": "^2.1.9", "tsup": "^8.3.5", diff --git a/packages/adapter-claude/vitest.config.ts b/packages/adapter-claude/vitest.config.ts new file mode 100644 index 0000000..471771e --- /dev/null +++ b/packages/adapter-claude/vitest.config.ts @@ -0,0 +1,9 @@ +import { defineConfig } from 'vitest/config' + +export default defineConfig({ + test: { + globals: false, + environment: 'node', + include: ['src/**/*.test.ts'], + }, +}) diff --git a/packages/cli/vitest.config.ts b/packages/cli/vitest.config.ts new file mode 100644 index 0000000..1fb81a3 --- /dev/null +++ b/packages/cli/vitest.config.ts @@ -0,0 +1,11 @@ +import { defineConfig } from 'vitest/config' + +export default defineConfig({ + test: { + globals: false, + environment: 'node', + include: ['src/**/*.test.ts'], + // cli.test.ts spawns the built CLI binary; needs extra time + testTimeout: 15_000, + }, +}) diff --git a/packages/cli/vitest.stryker.config.ts b/packages/cli/vitest.stryker.config.ts new file mode 100644 index 0000000..4e90fc4 --- /dev/null +++ b/packages/cli/vitest.stryker.config.ts @@ -0,0 +1,14 @@ +import { defineConfig, mergeConfig } from 'vitest/config' +import baseConfig from './vitest.config' + +export default mergeConfig( + baseConfig, + defineConfig({ + test: { + // cli.test.ts spawns node dist/cli.js — those tests can't see Stryker + // mutations applied to src/, so they would mark every cli source mutant + // as "no coverage" and treat them as survived. Skip them under mutation. + exclude: ['**/node_modules/**', '**/dist/**', 'src/__tests__/cli.test.ts'], + }, + }), +) diff --git a/packages/mcp-server/vitest.config.ts b/packages/mcp-server/vitest.config.ts new file mode 100644 index 0000000..ec9f852 --- /dev/null +++ b/packages/mcp-server/vitest.config.ts @@ -0,0 +1,11 @@ +import { defineConfig } from 'vitest/config' + +export default defineConfig({ + test: { + globals: false, + environment: 'node', + include: ['src/**/*.test.ts'], + // transport.test.ts spawns tsx subprocesses; allow extra time per test + testTimeout: 15_000, + }, +}) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index c0d165a..288bfd2 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -8,6 +8,12 @@ importers: .: devDependencies: + '@stryker-mutator/core': + specifier: ^8.7.1 + version: 8.7.1 + '@stryker-mutator/vitest-runner': + specifier: ^8.7.1 + version: 8.7.1(@stryker-mutator/core@8.7.1)(vitest@2.1.9(@types/node@20.19.34)) '@types/node': specifier: ^20.17.0 version: 20.19.34 @@ -265,6 +271,76 @@ packages: '@anthropic-ai/sdk@0.39.0': resolution: {integrity: sha512-eMyDIPRZbt1CCLErRCi3exlAvNkBtRe+kW5vvJyef93PmNr/clstYgHhtvmkxN82nlKgzyGPCyGxrm0JQ1ZIdg==} + '@babel/code-frame@7.29.0': + resolution: {integrity: sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw==} + engines: {node: '>=6.9.0'} + + '@babel/compat-data@7.29.0': + resolution: {integrity: sha512-T1NCJqT/j9+cn8fvkt7jtwbLBfLC/1y1c7NtCeXFRgzGTsafi68MRv8yzkYSapBnFA6L3U2VSc02ciDzoAJhJg==} + engines: {node: '>=6.9.0'} + + '@babel/core@7.25.9': + resolution: {integrity: sha512-WYvQviPw+Qyib0v92AwNIrdLISTp7RfDkM7bPqBvpbnhY4wq8HvHBZREVdYDXk98C8BkOIVnHAY3yvj7AVISxQ==} + engines: {node: '>=6.9.0'} + + '@babel/generator@7.25.9': + resolution: {integrity: sha512-omlUGkr5EaoIJrhLf9CJ0TvjBRpd9+AXRG//0GEQ9THSo8wPiTlbpy1/Ow8ZTrbXpjd9FHXfbFQx32I04ht0FA==} + engines: {node: '>=6.9.0'} + + '@babel/generator@7.29.1': + resolution: {integrity: sha512-qsaF+9Qcm2Qv8SRIMMscAvG4O3lJ0F1GuMo5HR/Bp02LopNgnZBC/EkbevHFeGs4ls/oPz9v+Bsmzbkbe+0dUw==} + engines: {node: '>=6.9.0'} + + '@babel/helper-annotate-as-pure@7.27.3': + resolution: {integrity: sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg==} + engines: {node: '>=6.9.0'} + + '@babel/helper-compilation-targets@7.28.6': + resolution: {integrity: sha512-JYtls3hqi15fcx5GaSNL7SCTJ2MNmjrkHXg4FSpOA/grxK8KwyZ5bubHsCq8FXCkua6xhuaaBit+3b7+VZRfcA==} + engines: {node: '>=6.9.0'} + + '@babel/helper-create-class-features-plugin@7.28.6': + resolution: {integrity: sha512-dTOdvsjnG3xNT9Y0AUg1wAl38y+4Rl4sf9caSQZOXdNqVn+H+HbbJ4IyyHaIqNR6SW9oJpA/RuRjsjCw2IdIow==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/helper-globals@7.28.0': + resolution: {integrity: sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==} + engines: {node: '>=6.9.0'} + + '@babel/helper-member-expression-to-functions@7.28.5': + resolution: {integrity: sha512-cwM7SBRZcPCLgl8a7cY0soT1SptSzAlMH39vwiRpOQkJlh53r5hdHwLSCZpQdVLT39sZt+CRpNwYG4Y2v77atg==} + engines: {node: '>=6.9.0'} + + '@babel/helper-module-imports@7.28.6': + resolution: {integrity: sha512-l5XkZK7r7wa9LucGw9LwZyyCUscb4x37JWTPz7swwFE/0FMQAGpiWUZn8u9DzkSBWEcK25jmvubfpw2dnAMdbw==} + engines: {node: '>=6.9.0'} + + '@babel/helper-module-transforms@7.28.6': + resolution: {integrity: sha512-67oXFAYr2cDLDVGLXTEABjdBJZ6drElUSI7WKp70NrpyISso3plG9SAGEF6y7zbha/wOzUByWWTJvEDVNIUGcA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/helper-optimise-call-expression@7.27.1': + resolution: {integrity: sha512-URMGH08NzYFhubNSGJrpUEphGKQwMQYBySzat5cAByY1/YgIRkULnIy3tAMeszlL/so2HbeilYloUmSpd7GdVw==} + engines: {node: '>=6.9.0'} + + '@babel/helper-plugin-utils@7.28.6': + resolution: {integrity: sha512-S9gzZ/bz83GRysI7gAD4wPT/AI3uCnY+9xn+Mx/KPs2JwHJIz1W8PZkg2cqyt3RNOBM8ejcXhV6y8Og7ly/Dug==} + engines: {node: '>=6.9.0'} + + '@babel/helper-replace-supers@7.28.6': + resolution: {integrity: sha512-mq8e+laIk94/yFec3DxSjCRD2Z0TAjhVbEJY3UQrlwVo15Lmt7C2wAUbK4bjnTs4APkwsYLTahXRraQXhb1WCg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/helper-skip-transparent-expression-wrappers@7.27.1': + resolution: {integrity: sha512-Tub4ZKEXqbPjXgWLl2+3JpQAYBJ8+ikpQ2Ocj/q/r0LwE3UhENh7EUabyHjz2kCEsrRY83ew2DQdHluuiDQFzg==} + engines: {node: '>=6.9.0'} + '@babel/helper-string-parser@7.27.1': resolution: {integrity: sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==} engines: {node: '>=6.9.0'} @@ -273,11 +349,87 @@ packages: resolution: {integrity: sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==} engines: {node: '>=6.9.0'} + '@babel/helper-validator-option@7.27.1': + resolution: {integrity: sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==} + engines: {node: '>=6.9.0'} + + '@babel/helpers@7.29.2': + resolution: {integrity: sha512-HoGuUs4sCZNezVEKdVcwqmZN8GoHirLUcLaYVNBK2J0DadGtdcqgr3BCbvH8+XUo4NGjNl3VOtSjEKNzqfFgKw==} + engines: {node: '>=6.9.0'} + + '@babel/parser@7.25.9': + resolution: {integrity: sha512-aI3jjAAO1fh7vY/pBGsn1i9LDbRP43+asrRlkPuTXW5yHXtd1NgTEMudbBoDDxrf1daEEfPJqR+JBMakzrR4Dg==} + engines: {node: '>=6.0.0'} + hasBin: true + '@babel/parser@7.29.0': resolution: {integrity: sha512-IyDgFV5GeDUVX4YdF/3CPULtVGSXXMLh1xVIgdCgxApktqnQV0r7/8Nqthg+8YLGaAtdyIlo2qIdZrbCv4+7ww==} engines: {node: '>=6.0.0'} hasBin: true + '@babel/plugin-proposal-decorators@7.24.7': + resolution: {integrity: sha512-RL9GR0pUG5Kc8BUWLNDm2T5OpYwSX15r98I0IkgmRQTXuELq/OynH8xtMTMvTJFjXbMWFVTKtYkTaYQsuAwQlQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-proposal-explicit-resource-management@7.27.4': + resolution: {integrity: sha512-1SwtCDdZWQvUU1i7wt/ihP7W38WjC3CSTOHAl+Xnbze8+bbMNjRvRQydnj0k9J1jPqCAZctBFp6NHJXkrVVmEA==} + engines: {node: '>=6.9.0'} + deprecated: This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-explicit-resource-management instead. + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-decorators@7.28.6': + resolution: {integrity: sha512-71EYI0ONURHJBL4rSFXnITXqXrrY8q4P0q006DPfN+Rk+ASM+++IBXem/ruokgBZR8YNEWZ8R6B+rCb8VcUTqA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-jsx@7.28.6': + resolution: {integrity: sha512-wgEmr06G6sIpqr8YDwA2dSRTE3bJ+V0IfpzfSY3Lfgd7YWOaAdlykvJi13ZKBt8cZHfgH1IXN+CL656W3uUa4w==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-typescript@7.28.6': + resolution: {integrity: sha512-+nDNmQye7nlnuuHDboPbGm00Vqg3oO8niRRL27/4LYHUsHYh0zJ1xWOz0uRwNFmM1Avzk8wZbc6rdiYhomzv/A==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-destructuring@7.28.5': + resolution: {integrity: sha512-Kl9Bc6D0zTUcFUvkNuQh4eGXPKKNDOJQXVyyM4ZAQPMveniJdxi8XMJwLo+xSoW3MIq81bD33lcUe9kZpl0MCw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-modules-commonjs@7.28.6': + resolution: {integrity: sha512-jppVbf8IV9iWWwWTQIxJMAJCWBuuKx71475wHwYytrRGQ2CWiDvYlADQno3tcYpS/T2UUWFQp3nVtYfK/YBQrA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-typescript@7.28.6': + resolution: {integrity: sha512-0YWL2RFxOqEm9Efk5PvreamxPME8OyY0wM5wh5lHjF+VtVhdneCWGzZeSqzOfiobVqQaNCd2z0tQvnI9DaPWPw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/preset-typescript@7.24.7': + resolution: {integrity: sha512-SyXRe3OdWwIwalxDg5UtJnJQO+YPcTfwiIY2B0Xlddh9o7jpWLvv8X1RthIeDOxQ+O1ML5BLPCONToObyVQVuQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/template@7.28.6': + resolution: {integrity: sha512-YA6Ma2KsCdGb+WC6UpBVFJGXL58MDA6oyONbjyF/+5sBgxY/dwkhLogbMT2GXXyU84/IhRw/2D1Os1B/giz+BQ==} + engines: {node: '>=6.9.0'} + + '@babel/traverse@7.29.0': + resolution: {integrity: sha512-4HPiQr0X7+waHfyXPZpWPfWL/J7dcN1mx9gL6WdQVMbPnF3+ZhSMs8tCxN7oHddJE9fhNE7+lxdnlyemKfJRuA==} + engines: {node: '>=6.9.0'} + '@babel/types@7.29.0': resolution: {integrity: sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==} engines: {node: '>=6.9.0'} @@ -636,6 +788,62 @@ packages: '@iconify/types@2.0.0': resolution: {integrity: sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg==} + '@inquirer/checkbox@3.0.1': + resolution: {integrity: sha512-0hm2nrToWUdD6/UHnel/UKGdk1//ke5zGUpHIvk5ZWmaKezlGxZkOJXNSWsdxO/rEqTkbB3lNC2J6nBElV2aAQ==} + engines: {node: '>=18'} + + '@inquirer/confirm@4.0.1': + resolution: {integrity: sha512-46yL28o2NJ9doViqOy0VDcoTzng7rAb6yPQKU7VDLqkmbCaH4JqK4yk4XqlzNWy9PVC5pG1ZUXPBQv+VqnYs2w==} + engines: {node: '>=18'} + + '@inquirer/core@9.2.1': + resolution: {integrity: sha512-F2VBt7W/mwqEU4bL0RnHNZmC/OxzNx9cOYxHqnXX3MP6ruYvZUZAW9imgN9+h/uBT/oP8Gh888J2OZSbjSeWcg==} + engines: {node: '>=18'} + + '@inquirer/editor@3.0.1': + resolution: {integrity: sha512-VA96GPFaSOVudjKFraokEEmUQg/Lub6OXvbIEZU1SDCmBzRkHGhxoFAVaF30nyiB4m5cEbDgiI2QRacXZ2hw9Q==} + engines: {node: '>=18'} + + '@inquirer/expand@3.0.1': + resolution: {integrity: sha512-ToG8d6RIbnVpbdPdiN7BCxZGiHOTomOX94C2FaT5KOHupV40tKEDozp12res6cMIfRKrXLJyexAZhWVHgbALSQ==} + engines: {node: '>=18'} + + '@inquirer/figures@1.0.15': + resolution: {integrity: sha512-t2IEY+unGHOzAaVM5Xx6DEWKeXlDDcNPeDyUpsRc6CUhBfU3VQOEl+Vssh7VNp1dR8MdUJBWhuObjXCsVpjN5g==} + engines: {node: '>=18'} + + '@inquirer/input@3.0.1': + resolution: {integrity: sha512-BDuPBmpvi8eMCxqC5iacloWqv+5tQSJlUafYWUe31ow1BVXjW2a5qe3dh4X/Z25Wp22RwvcaLCc2siHobEOfzg==} + engines: {node: '>=18'} + + '@inquirer/number@2.0.1': + resolution: {integrity: sha512-QpR8jPhRjSmlr/mD2cw3IR8HRO7lSVOnqUvQa8scv1Lsr3xoAMMworcYW3J13z3ppjBFBD2ef1Ci6AE5Qn8goQ==} + engines: {node: '>=18'} + + '@inquirer/password@3.0.1': + resolution: {integrity: sha512-haoeEPUisD1NeE2IanLOiFr4wcTXGWrBOyAyPZi1FfLJuXOzNmxCJPgUrGYKVh+Y8hfGJenIfz5Wb/DkE9KkMQ==} + engines: {node: '>=18'} + + '@inquirer/prompts@6.0.1': + resolution: {integrity: sha512-yl43JD/86CIj3Mz5mvvLJqAOfIup7ncxfJ0Btnl0/v5TouVUyeEdcpknfgc+yMevS/48oH9WAkkw93m7otLb/A==} + engines: {node: '>=18'} + + '@inquirer/rawlist@3.0.1': + resolution: {integrity: sha512-VgRtFIwZInUzTiPLSfDXK5jLrnpkuSOh1ctfaoygKAdPqjcjKYmGh6sCY1pb0aGnCGsmhUxoqLDUAU0ud+lGXQ==} + engines: {node: '>=18'} + + '@inquirer/search@2.0.1': + resolution: {integrity: sha512-r5hBKZk3g5MkIzLVoSgE4evypGqtOannnB3PKTG9NRZxyFRKcfzrdxXXPcoJQsxJPzvdSU2Rn7pB7lw0GCmGAg==} + engines: {node: '>=18'} + + '@inquirer/select@3.0.1': + resolution: {integrity: sha512-lUDGUxPhdWMkN/fHy1Lk7pF3nK1fh/gqeyWXmctefhxLYxlDsc7vsPBEpxrfVGDsVdyYJsiJoD4bJ1b623cV1Q==} + engines: {node: '>=18'} + + '@inquirer/type@2.0.0': + resolution: {integrity: sha512-XvJRx+2KR3YXyYtPUUy+qd9i7p+GO9Ko6VIIpWlBrpWwXDv8WLFeHTxz35CfQFUiBMLXlGHhGzys7lqit9gWag==} + engines: {node: '>=18'} + '@isaacs/cliui@8.0.2': resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} engines: {node: '>=12'} @@ -702,66 +910,79 @@ packages: resolution: {integrity: sha512-t4ONHboXi/3E0rT6OZl1pKbl2Vgxf9vJfWgmUoCEVQVxhW6Cw/c8I6hbbu7DAvgp82RKiH7TpLwxnJeKv2pbsw==} cpu: [arm] os: [linux] + libc: [glibc] '@rollup/rollup-linux-arm-musleabihf@4.59.0': resolution: {integrity: sha512-CikFT7aYPA2ufMD086cVORBYGHffBo4K8MQ4uPS/ZnY54GKj36i196u8U+aDVT2LX4eSMbyHtyOh7D7Zvk2VvA==} cpu: [arm] os: [linux] + libc: [musl] '@rollup/rollup-linux-arm64-gnu@4.59.0': resolution: {integrity: sha512-jYgUGk5aLd1nUb1CtQ8E+t5JhLc9x5WdBKew9ZgAXg7DBk0ZHErLHdXM24rfX+bKrFe+Xp5YuJo54I5HFjGDAA==} cpu: [arm64] os: [linux] + libc: [glibc] '@rollup/rollup-linux-arm64-musl@4.59.0': resolution: {integrity: sha512-peZRVEdnFWZ5Bh2KeumKG9ty7aCXzzEsHShOZEFiCQlDEepP1dpUl/SrUNXNg13UmZl+gzVDPsiCwnV1uI0RUA==} cpu: [arm64] os: [linux] + libc: [musl] '@rollup/rollup-linux-loong64-gnu@4.59.0': resolution: {integrity: sha512-gbUSW/97f7+r4gHy3Jlup8zDG190AuodsWnNiXErp9mT90iCy9NKKU0Xwx5k8VlRAIV2uU9CsMnEFg/xXaOfXg==} cpu: [loong64] os: [linux] + libc: [glibc] '@rollup/rollup-linux-loong64-musl@4.59.0': resolution: {integrity: sha512-yTRONe79E+o0FWFijasoTjtzG9EBedFXJMl888NBEDCDV9I2wGbFFfJQQe63OijbFCUZqxpHz1GzpbtSFikJ4Q==} cpu: [loong64] os: [linux] + libc: [musl] '@rollup/rollup-linux-ppc64-gnu@4.59.0': resolution: {integrity: sha512-sw1o3tfyk12k3OEpRddF68a1unZ5VCN7zoTNtSn2KndUE+ea3m3ROOKRCZxEpmT9nsGnogpFP9x6mnLTCaoLkA==} cpu: [ppc64] os: [linux] + libc: [glibc] '@rollup/rollup-linux-ppc64-musl@4.59.0': resolution: {integrity: sha512-+2kLtQ4xT3AiIxkzFVFXfsmlZiG5FXYW7ZyIIvGA7Bdeuh9Z0aN4hVyXS/G1E9bTP/vqszNIN/pUKCk/BTHsKA==} cpu: [ppc64] os: [linux] + libc: [musl] '@rollup/rollup-linux-riscv64-gnu@4.59.0': resolution: {integrity: sha512-NDYMpsXYJJaj+I7UdwIuHHNxXZ/b/N2hR15NyH3m2qAtb/hHPA4g4SuuvrdxetTdndfj9b1WOmy73kcPRoERUg==} cpu: [riscv64] os: [linux] + libc: [glibc] '@rollup/rollup-linux-riscv64-musl@4.59.0': resolution: {integrity: sha512-nLckB8WOqHIf1bhymk+oHxvM9D3tyPndZH8i8+35p/1YiVoVswPid2yLzgX7ZJP0KQvnkhM4H6QZ5m0LzbyIAg==} cpu: [riscv64] os: [linux] + libc: [musl] '@rollup/rollup-linux-s390x-gnu@4.59.0': resolution: {integrity: sha512-oF87Ie3uAIvORFBpwnCvUzdeYUqi2wY6jRFWJAy1qus/udHFYIkplYRW+wo+GRUP4sKzYdmE1Y3+rY5Gc4ZO+w==} cpu: [s390x] os: [linux] + libc: [glibc] '@rollup/rollup-linux-x64-gnu@4.59.0': resolution: {integrity: sha512-3AHmtQq/ppNuUspKAlvA8HtLybkDflkMuLK4DPo77DfthRb71V84/c4MlWJXixZz4uruIH4uaa07IqoAkG64fg==} cpu: [x64] os: [linux] + libc: [glibc] '@rollup/rollup-linux-x64-musl@4.59.0': resolution: {integrity: sha512-2UdiwS/9cTAx7qIUZB/fWtToJwvt0Vbo0zmnYt7ED35KPg13Q0ym1g442THLC7VyI6JfYTP4PiSOWyoMdV2/xg==} cpu: [x64] os: [linux] + libc: [musl] '@rollup/rollup-openbsd-x64@4.59.0': resolution: {integrity: sha512-M3bLRAVk6GOwFlPTIxVBSYKUaqfLrn8l0psKinkCFxl4lQvOSz8ZrKDz2gxcBwHFpci0B6rttydI4IpS4IS/jQ==} @@ -827,6 +1048,29 @@ packages: resolution: {integrity: sha512-tlqY9xq5ukxTUZBmoOp+m61cqwQD5pHJtFY3Mn8CA8ps6yghLH/Hw8UPdqg4OLmFW3IFlcXnQNmo/dh8HzXYIQ==} engines: {node: '>=18'} + '@stryker-mutator/api@8.7.1': + resolution: {integrity: sha512-56vxcVxIfW0jxJhr7HB9Zx6Xr5/M95RG9MUK1DtbQhlmQesjpfBBsrPLOPzBJaITPH/vOYykuJ69vgSAMccQyw==} + engines: {node: '>=18.0.0'} + + '@stryker-mutator/core@8.7.1': + resolution: {integrity: sha512-r2AwhHWkHq6yEe5U8mAzPSWewULbv9YMabLHRzLjZnjj+Ipxtg+Zo22rrUc2Zl7mnYvb9w34bdlEzGz6MKgX2g==} + engines: {node: '>=18.0.0'} + hasBin: true + + '@stryker-mutator/instrumenter@8.7.1': + resolution: {integrity: sha512-HSq4VHXesQCMR3hr6bn41DAeJ0yuP2vp9KSnls2TySNawFVWOCaKXpBX29Skj3zJQh7dnm7HuQg8HuXvJK15oA==} + engines: {node: '>=18.0.0'} + + '@stryker-mutator/util@8.7.1': + resolution: {integrity: sha512-Oj/sIHZI1GLfGOHKnud4Gw0ZRufm7ONoQYNnhcaAYEXTWraYVcV7mue/th8fZComTHvDPA8Ge8U16FvWYEb8dg==} + + '@stryker-mutator/vitest-runner@8.7.1': + resolution: {integrity: sha512-vNRTM6MEy+0hNK5UhJ44euEIRjluDV43UROcMAKIMbT9ELdp8XgM/tA5GrTcp5QadnvrBwvEcCRQk+ARL+e0sg==} + engines: {node: '>=14.18.0'} + peerDependencies: + '@stryker-mutator/core': ~8.7.0 + vitest: '>=0.31.2' + '@types/estree@1.0.8': resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==} @@ -848,6 +1092,9 @@ packages: '@types/mdurl@2.0.0': resolution: {integrity: sha512-RGdgjQUZba5p6QEFAVx2OGb8rQDL/cPRG7GiedRzMcJ1tYnUANBncjbSB1NRGwbvjcPeikRABz2nshyPk1bhWg==} + '@types/mute-stream@0.0.4': + resolution: {integrity: sha512-CPM9nzrCPPJHQNA9keH9CVkVI+WR5kMa+7XEs5jcGQ0VoAGnLv242w8lIVgwAEfmE4oufJRaTc9PNLQl0ioAow==} + '@types/node-fetch@2.6.13': resolution: {integrity: sha512-QGpRVpzSaUs30JBSGPjOg4Uveu384erbHBoT1zeONvyCfwQxIkUshLAOqN/k9EjGviPRmWTTe6aH2qySWKTVSw==} @@ -860,12 +1107,18 @@ packages: '@types/node@20.19.37': resolution: {integrity: sha512-8kzdPJ3FsNsVIurqBs7oodNnCEVbni9yUEkaHbgptDACOPW04jimGagZ51E6+lXUwJjgnBw+hyko/lkFWCldqw==} + '@types/node@22.19.17': + resolution: {integrity: sha512-wGdMcf+vPYM6jikpS/qhg6WiqSV/OhG+jeeHT/KlVqxYfD40iYJf9/AE1uQxVWFvU7MipKRkRv8NSHiCGgPr8Q==} + '@types/unist@3.0.3': resolution: {integrity: sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==} '@types/web-bluetooth@0.0.21': resolution: {integrity: sha512-oIQLCGWtcFZy2JW77j9k8nHzAOpqMHLQejDA48XXMWH6tjCQHz5RCFz1bzsmROyL6PUm+LLnUiI4BCn221inxA==} + '@types/wrap-ansi@3.0.0': + resolution: {integrity: sha512-ltIpx+kM7g/MLRZfkbL7EsCEjfzCcScLpkg37eXEtx5kmrAKBkTJwd1GIAjDSL8wTpM6Hzn5YO4pSb91BEwu1g==} + '@ungap/structured-clone@1.3.0': resolution: {integrity: sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==} @@ -1053,6 +1306,9 @@ packages: ajv: optional: true + ajv@8.17.1: + resolution: {integrity: sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==} + ajv@8.18.0: resolution: {integrity: sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A==} @@ -1060,6 +1316,14 @@ packages: resolution: {integrity: sha512-X3Pp2aRQhg4xUC6PQtkubn5NpRKuUPQ9FPDQlx36SmpFwwH2N0/tw4c+NXV3nw3PsgeUs+BuWGP0gjz3TvENLQ==} engines: {node: '>= 14.0.0'} + angular-html-parser@6.0.2: + resolution: {integrity: sha512-8+sH1TwYxv8XsQes1psxTHMtWRBbJFA/jY0ThqpT4AgCiRdhTtRxru0vlBfyRJpL9CHd3G06k871bR2vyqaM6A==} + engines: {node: '>= 14'} + + ansi-escapes@4.3.2: + resolution: {integrity: sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==} + engines: {node: '>=8'} + ansi-regex@5.0.1: resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} engines: {node: '>=8'} @@ -1110,6 +1374,11 @@ packages: resolution: {integrity: sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==} engines: {node: 18 || 20 || >=22} + baseline-browser-mapping@2.10.18: + resolution: {integrity: sha512-VSnGQAOLtP5mib/DPyg2/t+Tlv65NTBz83BJBJvmLVHHuKJVaDOBvJJykiT5TR++em5nfAySPccDZDa4oSrn8A==} + engines: {node: '>=6.0.0'} + hasBin: true + birpc@2.9.0: resolution: {integrity: sha512-KrayHS5pBi69Xi9JmvoqrIgYGDkD6mcSe/i6YKi3w5kekCLzrX4+nawcXqrj2tIp50Kw/mT/s3p+GVK0A0sKxw==} @@ -1120,6 +1389,11 @@ packages: resolution: {integrity: sha512-h+DEnpVvxmfVefa4jFbCf5HdH5YMDXRsmKflpf1pILZWRFlTbJpxeU55nJl4Smt5HQaGzg1o6RHFPJaOqnmBDg==} engines: {node: 18 || 20 || >=22} + browserslist@4.28.2: + resolution: {integrity: sha512-48xSriZYYg+8qXna9kwqjIVzuQxi+KYWp2+5nCYnYKPTr0LvD89Jqk2Or5ogxz0NUMfIjhh2lIUX/LyX9B4oIg==} + engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} + hasBin: true + bundle-require@5.1.0: resolution: {integrity: sha512-3WrrOuZiyaaZPWiEt4G3+IffISVC9HYlWueJEBWED4ZH4aIAC2PnkdnuRrR94M+w6yGWn4AglWtJtBI8YqvgoA==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} @@ -1134,6 +1408,13 @@ packages: resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==} engines: {node: '>= 0.4'} + call-bound@1.0.4: + resolution: {integrity: sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==} + engines: {node: '>= 0.4'} + + caniuse-lite@1.0.30001787: + resolution: {integrity: sha512-mNcrMN9KeI68u7muanUpEejSLghOKlVhRqS/Za2IeyGllJ9I9otGpR9g3nsw7n4W378TE/LyIteA0+/FOZm4Kg==} + ccount@2.0.1: resolution: {integrity: sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==} @@ -1145,6 +1426,10 @@ packages: resolution: {integrity: sha512-4zNhdJD/iOjSH0A05ea+Ke6MU5mmpQcbQsSOkgdaUMJ9zTlDTD/GYlwohmIE2u0gaxHYiVHEn1Fw9mZ/ktJWgw==} engines: {node: '>=18'} + chalk@5.3.0: + resolution: {integrity: sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==} + engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} + chalk@5.6.2: resolution: {integrity: sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==} engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} @@ -1155,6 +1440,9 @@ packages: character-entities-legacy@3.0.0: resolution: {integrity: sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==} + chardet@0.7.0: + resolution: {integrity: sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==} + check-error@1.0.3: resolution: {integrity: sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg==} @@ -1166,6 +1454,10 @@ packages: resolution: {integrity: sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==} engines: {node: '>= 14.16.0'} + cli-width@4.1.0: + resolution: {integrity: sha512-ouuZd4/dm2Sw5Gmqy6bGyNNNe1qt9RpmxveLSO7KcgsTnU7RXfsw+/bukWGo1abgBiMAic068rclZsO4IWmmxQ==} + engines: {node: '>= 12'} + color-convert@2.0.1: resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} engines: {node: '>=7.0.0'} @@ -1195,6 +1487,9 @@ packages: resolution: {integrity: sha512-5IKcdX0nnYavi6G7TtOhwkYzyjfJlatbjMjuLSfE2kYT5pMDOilZ4OvMhi637CcDICTmz3wARPoyhqyX1Y+XvA==} engines: {node: ^14.18.0 || >=16.10.0} + convert-source-map@2.0.0: + resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} + cookie@0.7.2: resolution: {integrity: sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==} engines: {node: '>= 0.6'} @@ -1235,9 +1530,15 @@ packages: resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==} engines: {node: '>=6'} + des.js@1.1.0: + resolution: {integrity: sha512-r17GxjhUCjSRy8aiJpr8/UadFIzMzJGexI3Nmz4ADi9LYSFx4gTBp80+NaX/YsXWWLhpZ7v/v/ubEc/bCNfKwg==} + devlop@1.1.0: resolution: {integrity: sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==} + diff-match-patch@1.0.5: + resolution: {integrity: sha512-IayShXAgj/QMXgB0IWmKx+rOPuGMhqm5w6jvFxmVenXKIzRqTAAsbBPT3kWQeGANj3jGgvcvv4yK6SxqYmikgw==} + diff-sequences@29.6.3: resolution: {integrity: sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} @@ -1249,9 +1550,15 @@ packages: eastasianwidth@0.2.0: resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} + electron-to-chromium@1.5.335: + resolution: {integrity: sha512-q9n5T4BR4Xwa2cwbrwcsDJtHD/enpQ5S1xF1IAtdqf5AAgqDFmR/aakqH3ChFdqd/QXJhS3rnnXFtexU7rax6Q==} + emoji-regex-xs@1.0.0: resolution: {integrity: sha512-LRlerrMYoIDrT6jgpeZ2YYl/L8EulRTt5hQcYjy5AInh7HWXKimpqx68aknBFpGL2+/IcogTcaydJEgaTmOpDg==} + emoji-regex@10.4.0: + resolution: {integrity: sha512-EC+0oUMY1Rqm4O6LLrgjtYDvcVYTy7chDnM4Q7030tP4Kwj3u/pR6gP9ygnp2CJMK5Gq+9Q2oqmrFJAz01DXjw==} + emoji-regex@8.0.0: resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} @@ -1294,6 +1601,10 @@ packages: engines: {node: '>=18'} hasBin: true + escalade@3.2.0: + resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} + engines: {node: '>=6'} + estree-walker@2.0.2: resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==} @@ -1308,6 +1619,10 @@ packages: resolution: {integrity: sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==} engines: {node: '>=16.17'} + execa@9.4.1: + resolution: {integrity: sha512-5eo/BRqZm3GYce+1jqX/tJ7duA2AnE39i88fuedNFUV8XxGxUpF3aWkBRfbUcjV49gCkvS/pzc0YrCPhaIewdg==} + engines: {node: ^18.19.0 || >=20.5.0} + execa@9.6.1: resolution: {integrity: sha512-9Be3ZoN4LmYR90tUoVu2te2BsbzHfhJyfEiAVfz7N5/zv+jduIfLrV2xdQXOHbaD6KgpGdO9PRPM1Y4Q9QkPkA==} engines: {node: ^18.19.0 || >=20.5.0} @@ -1316,6 +1631,10 @@ packages: resolution: {integrity: sha512-knvyeauYhqjOYvQ66MznSMs83wmHrCycNEN6Ao+2AeYEfxUIkuiVxdEa1qlGEPK+We3n0THiDciYSsCcgW/DoA==} engines: {node: '>=12.0.0'} + external-editor@3.1.0: + resolution: {integrity: sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==} + engines: {node: '>=4'} + fast-content-type-parse@1.1.0: resolution: {integrity: sha512-fBHHqSTFLVnR61C+gltJuE5GkVQMV0S2nqUO8TJ+5Z3qAKG8vAx4FKai1s5jq/inV1+sREynIWSuQ6HgoSXpDQ==} @@ -1359,6 +1678,10 @@ packages: resolution: {integrity: sha512-d+l3qxjSesT4V7v2fh+QnmFnUWv9lSpjarhShNTgBOfA0ttejbQUAlHLitbjkoRiDulW0OPoQPYIGhIC8ohejg==} engines: {node: '>=18'} + file-url@4.0.0: + resolution: {integrity: sha512-vRCdScQ6j3Ku6Kd7W1kZk9c++5SqD6Xz5Jotrjr/nkY714M14RFHy/AAVA2WQvpsqVAVgTbDrYyBpU205F0cLw==} + engines: {node: '>=12'} + find-my-way@8.2.2: resolution: {integrity: sha512-Dobi7gcTEq8yszimcfp/R7+owiT4WncAJ7VTTgFH1jYJ5GaG1FbhjwDG820hptN0QDFvzVY3RfCzdInvGPGzjA==} engines: {node: '>=14'} @@ -1396,6 +1719,10 @@ packages: function-bind@1.1.2: resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} + gensync@1.0.0-beta.2: + resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} + engines: {node: '>=6.9.0'} + get-func-name@2.0.2: resolution: {integrity: sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==} @@ -1469,6 +1796,13 @@ packages: humanize-ms@1.2.1: resolution: {integrity: sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==} + iconv-lite@0.4.24: + resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==} + engines: {node: '>=0.10.0'} + + inherits@2.0.4: + resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} + ipaddr.js@1.9.1: resolution: {integrity: sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==} engines: {node: '>= 0.10'} @@ -1523,6 +1857,12 @@ packages: resolution: {integrity: sha512-34wB/Y7MW7bzjKRjUKTa46I2Z7eV62Rkhva+KkopW7Qvv/OSWBqvkSY7vusOPrNuZcUG3tApvdVgNB8POj3SPw==} engines: {node: '>=10'} + js-md4@0.3.2: + resolution: {integrity: sha512-/GDnfQYsltsjRswQhN9fhv3EMw2sCpUdrdxyWDOUK7eyD++r3gRhzgiQgc/x4MAv2i1iuQ4lxO5mvqM3vj4bwA==} + + js-tokens@4.0.0: + resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} + js-tokens@9.0.1: resolution: {integrity: sha512-mxa9E9ITFOt0ban3j6L5MpjwegGz6lBQmM1IJkWeBZGcMxto50+eWdjC/52xDbS2vy0k7vIMK0Fe2wfL9OQSpQ==} @@ -1530,12 +1870,22 @@ packages: resolution: {integrity: sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==} hasBin: true + jsesc@3.1.0: + resolution: {integrity: sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==} + engines: {node: '>=6'} + hasBin: true + json-schema-ref-resolver@1.0.1: resolution: {integrity: sha512-EJAj1pgHc1hxF6vo2Z3s69fMjO1INq6eGHXZ8Z6wCQeldCuwxGK9Sxf4/cScGn3FZubCVUehfWtcDM/PLteCQw==} json-schema-traverse@1.0.0: resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==} + json5@2.2.3: + resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==} + engines: {node: '>=6'} + hasBin: true + light-my-request@5.14.0: resolution: {integrity: sha512-aORPWntbpH5esaYpGOOmri0OHDOe3wC5M2MQxZ9dvMLZm6DnaAn0kJlcbU9hwsQgLzmZyReKwFwwPkR+nHu5kA==} @@ -1554,6 +1904,9 @@ packages: resolution: {integrity: sha512-9rrA30MRRP3gBD3HTGnC6cDFpaE1kVDWxWgqWJUN0RvDNAo+Nz/9GxB+nHOH0ifbVFy0hSA1V6vFDvnx54lTEQ==} engines: {node: '>=14'} + lodash.groupby@4.6.0: + resolution: {integrity: sha512-5dcWxm23+VAoz+awKmBaiBvzox8+RqMgFhi7UvX9DHZr2HdxHXM/Wrf8cfKpsW37RNrvtPn6hSwNqurSILbmJw==} + loupe@2.3.7: resolution: {integrity: sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA==} @@ -1563,6 +1916,9 @@ packages: lru-cache@10.4.3: resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==} + lru-cache@5.1.1: + resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} + magic-string@0.30.21: resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==} @@ -1613,6 +1969,9 @@ packages: resolution: {integrity: sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==} engines: {node: '>=12'} + minimalistic-assert@1.0.1: + resolution: {integrity: sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==} + minimatch@10.2.4: resolution: {integrity: sha512-oRjTw/97aTBN0RHbYCdtF1MQfvusSIBQM0IZEgzl6426+8jSC0nF1a/GmnVLpfB9yyr6g6FTqWqiZVbxrtaCIg==} engines: {node: 18 || 20 || >=22} @@ -1637,6 +1996,19 @@ packages: ms@2.1.3: resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + mutation-testing-elements@3.4.0: + resolution: {integrity: sha512-zFJtGlobq+Fyq95JoJj0iqrmwLSLQyIJuDATLwFMDSJCxpGN8kHCA6S4LoLJnkSL6bg4Aqultp8OBSMxGbW3EA==} + + mutation-testing-metrics@3.3.0: + resolution: {integrity: sha512-vZEJ84SpK3Rwyk7k28SORS5o6ZDtehwifLPH6fQULrozJqlz2Nj8vi52+CjA+aMZCyyKB+9eYUh1HtiWVo4o/A==} + + mutation-testing-report-schema@3.3.0: + resolution: {integrity: sha512-DF56q0sb0GYzxYUYNdzlfQzyE5oJBEasz8zL76bt3OFJU8q4iHSdUDdihPWWJD+4JLxSs3neM/R968zYdy0SWQ==} + + mute-stream@1.0.0: + resolution: {integrity: sha512-avsJQhyd+680gKXyG/sQc0nXaC6rBkPOfyHYcFb9+hdkqQkR9bdnkJ0AMZhke0oesPqIO+mFFJ+IdBc7mst4IA==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + mz@2.7.0: resolution: {integrity: sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==} @@ -1659,6 +2031,9 @@ packages: encoding: optional: true + node-releases@2.0.37: + resolution: {integrity: sha512-1h5gKZCF+pO/o3Iqt5Jp7wc9rH3eJJ0+nh/CIoiRwjRxde/hAHyLPXYN4V3CqKAbiZPSeJFSWHmJsbkicta0Eg==} + npm-run-path@5.3.0: resolution: {integrity: sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} @@ -1671,6 +2046,10 @@ packages: resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} engines: {node: '>=0.10.0'} + object-inspect@1.13.4: + resolution: {integrity: sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==} + engines: {node: '>= 0.4'} + on-exit-leak-free@2.1.2: resolution: {integrity: sha512-0eJJY6hXLGf1udHwfNftBqH+g73EU4B504nZeKpz1sYRKafAghwxEJunB2O7rDZkL4PGfsMVnTXZ2EjibbqcsA==} engines: {node: '>=14.0.0'} @@ -1685,6 +2064,10 @@ packages: oniguruma-to-es@3.1.1: resolution: {integrity: sha512-bUH8SDvPkH3ho3dvwJwfonjlQ4R80vjyvrU8YpxuROddv55vAEJrTuCuCVUhhsHbtlD9tGGbaNApGQckXhS8iQ==} + os-tmpdir@1.0.2: + resolution: {integrity: sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==} + engines: {node: '>=0.10.0'} + p-limit@5.0.0: resolution: {integrity: sha512-/Eaoq+QyLSiXQ4lyYV23f14mZRQcXnxfHrN0vCai+ak9G0pp9iEQukIIZq5NccEvwRB8PUnZT0KsOoDCINS1qQ==} engines: {node: '>=18'} @@ -1787,6 +2170,10 @@ packages: process-warning@5.0.0: resolution: {integrity: sha512-a39t9ApHNx2L4+HBnQKqxxHNs1r7KF+Intd8Q/g1bUh6q0WIp9voPXJ/x0j+ZL45KF1pJd9+q2jLIRMfvEshkA==} + progress@2.0.3: + resolution: {integrity: sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==} + engines: {node: '>=0.4.0'} + property-information@7.1.0: resolution: {integrity: sha512-TwEZ+X+yCJmYfL7TPUOcvBZ4QfoT5YenQiJuX//0th53DE6w0xxLEtfK3iyryQFddXuvkIk51EEgrJQ0WJkOmQ==} @@ -1794,6 +2181,10 @@ packages: resolution: {integrity: sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==} engines: {node: '>= 0.10'} + qs@6.15.1: + resolution: {integrity: sha512-6YHEFRL9mfgcAvql/XhwTvf5jKcOiiupt2FiJxHkiX1z4j7WL8J/jRHYLluORvc1XxB5rV20KoeK00gVJamspg==} + engines: {node: '>=0.6'} + quick-format-unescaped@4.0.4: resolution: {integrity: sha512-tYC1Q1hgyRuHgloV/YXs2w15unPVh8qfu/qCTfhTYamaw7fyhumKa2yGpdSo87vY32rIclj+4fWYQXUMs9EHvg==} @@ -1844,6 +2235,9 @@ packages: engines: {node: '>=18.0.0', npm: '>=8.0.0'} hasBin: true + rxjs@7.8.2: + resolution: {integrity: sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA==} + safe-regex2@3.1.0: resolution: {integrity: sha512-RAAZAGbap2kBfbVhvmnTFv73NWLMvDGOITFYTZBAaY8eR+Ir4ef7Up/e7amo+y1+AH+3PtLkrt9mvcTsG9LXug==} @@ -1851,12 +2245,24 @@ packages: resolution: {integrity: sha512-b3rppTKm9T+PsVCBEOUR46GWI7fdOs00VKZ1+9c1EWDaDMvjQc6tUwuFyIprgGgTcWoVHSKrU8H31ZHA2e0RHA==} engines: {node: '>=10'} + safer-buffer@2.1.2: + resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} + search-insights@2.17.3: resolution: {integrity: sha512-RQPdCYTa8A68uM2jwxoY842xDhvx3E5LFL1LxvxCNMev4o5mLuokczhzjAgGwUZBAmOKZknArSxLKmXtIi2AxQ==} secure-json-parse@2.7.0: resolution: {integrity: sha512-6aU+Rwsezw7VR8/nyvKTx8QpWH9FrcYiXXlqC4z5d5XQBDRqtbfsRjnwGyqbi3gddNtWHuEk9OANUotL26qKUw==} + semver@6.3.1: + resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} + hasBin: true + + semver@7.6.3: + resolution: {integrity: sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==} + engines: {node: '>=10'} + hasBin: true + semver@7.7.4: resolution: {integrity: sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==} engines: {node: '>=10'} @@ -1876,6 +2282,22 @@ packages: shiki@2.5.0: resolution: {integrity: sha512-mI//trrsaiCIPsja5CNfsyNOqgAZUb6VpJA+340toL42UpzQlXpwRV9nch69X6gaUxrr9kaOOa6e3y3uAkGFxQ==} + side-channel-list@1.0.1: + resolution: {integrity: sha512-mjn/0bi/oUURjc5Xl7IaWi/OJJJumuoJFQJfDDyO46+hBWsfaVM65TBHq2eoZBhzl9EchxOijpkbRC8SVBQU0w==} + engines: {node: '>= 0.4'} + + side-channel-map@1.0.1: + resolution: {integrity: sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==} + engines: {node: '>= 0.4'} + + side-channel-weakmap@1.0.2: + resolution: {integrity: sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==} + engines: {node: '>= 0.4'} + + side-channel@1.1.0: + resolution: {integrity: sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==} + engines: {node: '>= 0.4'} + siginfo@2.0.0: resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==} @@ -2004,6 +2426,10 @@ packages: resolution: {integrity: sha512-n1cw8k1k0x4pgA2+9XrOkFydTerNcJ1zWCO5Nn9scWHTD+5tp8dghT2x1uduQePZTZgd3Tupf+x9BxJjeJi77Q==} engines: {node: '>=14.0.0'} + tmp@0.0.33: + resolution: {integrity: sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==} + engines: {node: '>=0.6.0'} + toad-cache@3.7.0: resolution: {integrity: sha512-/m8M+2BJUpoJdgAHoG+baCwBT+tf2VraSfkBgl0Y00qIWt41DJ8R5B8nsEw0I58YwF5IZH6z24/2TobDKnqSWw==} engines: {node: '>=12'} @@ -2021,6 +2447,9 @@ packages: ts-interface-checker@0.1.13: resolution: {integrity: sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==} + tslib@2.7.0: + resolution: {integrity: sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA==} + tsup@8.5.1: resolution: {integrity: sha512-xtgkqwdhpKWr3tKPmCkvYmS9xnQK3m3XgxZHwSUjvfTjp7YfXe5tT3GgWi0F2N+ZSMsOeWeZFh7ZZFg5iPhing==} engines: {node: '>=18'} @@ -2045,10 +2474,26 @@ packages: engines: {node: '>=18.0.0'} hasBin: true + tunnel@0.0.6: + resolution: {integrity: sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg==} + engines: {node: '>=0.6.11 <=0.7.0 || >=0.7.3'} + type-detect@4.1.0: resolution: {integrity: sha512-Acylog8/luQ8L7il+geoSxhEkazvkslg7PSNKOX59mbB9cOveP5aq9h74Y7YU8yDpJwetzQQrfIwtf4Wp4LKcw==} engines: {node: '>=4'} + type-fest@0.21.3: + resolution: {integrity: sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==} + engines: {node: '>=10'} + + typed-inject@4.0.0: + resolution: {integrity: sha512-OuBL3G8CJlS/kjbGV/cN8Ni32+ktyyi6ADDZpKvksbX0fYBV5WcukhRCYa7WqLce7dY/Br2dwtmJ9diiadLFpg==} + engines: {node: '>=16'} + + typed-rest-client@2.1.0: + resolution: {integrity: sha512-Nel9aPbgSzRxfs1+4GoSB4wexCF+4Axlk7OSGVQCMa+4fWcyxIsN/YNmkp0xTT2iQzMD98h8yFLav/cNaULmRA==} + engines: {node: '>= 16.0.0'} + typescript@5.9.3: resolution: {integrity: sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==} engines: {node: '>=14.17'} @@ -2057,6 +2502,9 @@ packages: ufo@1.6.3: resolution: {integrity: sha512-yDJTmhydvl5lJzBmy/hyOAA0d+aqCBuwl818haVdYCRrWV84o7YyeVm4QlVHStqNrrJSTb6jKuFAVqAFsr+K3Q==} + underscore@1.13.8: + resolution: {integrity: sha512-DXtD3ZtEQzc7M8m4cXotyHR+FAS18C64asBYY5vqZexfYryNNnDc02W4hKg3rdQuqOYas1jkseX0+nZXjTXnvQ==} + undici-types@5.26.5: resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==} @@ -2086,6 +2534,12 @@ packages: unist-util-visit@5.1.0: resolution: {integrity: sha512-m+vIdyeCOpdr/QeQCu2EzxX/ohgS8KbnPDgFni4dQsfSCtpz8UqDyY5GjRru8PDKuYn7Fq19j1CQ+nJSsGKOzg==} + update-browserslist-db@1.2.3: + resolution: {integrity: sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==} + hasBin: true + peerDependencies: + browserslist: '>= 4.21.0' + vfile-message@4.0.3: resolution: {integrity: sha512-QTHzsGd1EhbZs4AsQ20JX1rC3cOlt/IWJruk893DfLRr57lcnOeMaWG4K0JrRta4mIJZKth2Au3mM3u03/JWKw==} @@ -2203,6 +2657,9 @@ packages: typescript: optional: true + weapon-regex@1.3.6: + resolution: {integrity: sha512-wsf1m1jmMrso5nhwVFJJHSubEBf3+pereGd7+nBKtYJ18KoB/PWJOHS3WRkwS04VrOU0iJr2bZU+l1QaTJ+9nA==} + web-streams-polyfill@4.0.0-beta.3: resolution: {integrity: sha512-QW95TCTaHmsYfHDybGMwO5IJIM93I/6vTRk+daHTWFPhwh+C8Cg7j7XyKrwrj8Ib6vYXe0ocYNrmzY4xAAN6ug==} engines: {node: '>= 14'} @@ -2223,6 +2680,10 @@ packages: engines: {node: '>=8'} hasBin: true + wrap-ansi@6.2.0: + resolution: {integrity: sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==} + engines: {node: '>=8'} + wrap-ansi@7.0.0: resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} engines: {node: '>=10'} @@ -2246,10 +2707,17 @@ packages: utf-8-validate: optional: true + yallist@3.1.1: + resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} + yocto-queue@1.2.2: resolution: {integrity: sha512-4LCcse/U2MHZ63HAJVE+v71o7yOdIe4cZ70Wpf8D/IyjDKYQLV5GD46B+hSTjJsvV5PztjvHoU580EftxjDZFQ==} engines: {node: '>=12.20'} + yoctocolors-cjs@2.1.3: + resolution: {integrity: sha512-U/PBtDf35ff0D8X8D0jfdzHYEPFxAI7jJlxZXwCSez5M3190m+QobIfh+sWDWSHMCWWJN2AWamkegn6vr6YBTw==} + engines: {node: '>=18'} + yoctocolors@2.1.2: resolution: {integrity: sha512-CzhO+pFNo8ajLM2d2IW/R93ipy99LWjtwblvC1RsoSUMZgyLbYFr221TnSNT7GjGdYui6P459mw9JH/g/zW2ug==} engines: {node: '>=18'} @@ -2409,14 +2877,228 @@ snapshots: - encoding optional: true + '@babel/code-frame@7.29.0': + dependencies: + '@babel/helper-validator-identifier': 7.28.5 + js-tokens: 4.0.0 + picocolors: 1.1.1 + + '@babel/compat-data@7.29.0': {} + + '@babel/core@7.25.9': + dependencies: + '@ampproject/remapping': 2.3.0 + '@babel/code-frame': 7.29.0 + '@babel/generator': 7.25.9 + '@babel/helper-compilation-targets': 7.28.6 + '@babel/helper-module-transforms': 7.28.6(@babel/core@7.25.9) + '@babel/helpers': 7.29.2 + '@babel/parser': 7.29.0 + '@babel/template': 7.28.6 + '@babel/traverse': 7.29.0 + '@babel/types': 7.29.0 + convert-source-map: 2.0.0 + debug: 4.4.3 + gensync: 1.0.0-beta.2 + json5: 2.2.3 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + + '@babel/generator@7.25.9': + dependencies: + '@babel/types': 7.29.0 + '@jridgewell/gen-mapping': 0.3.13 + '@jridgewell/trace-mapping': 0.3.31 + jsesc: 3.1.0 + + '@babel/generator@7.29.1': + dependencies: + '@babel/parser': 7.29.0 + '@babel/types': 7.29.0 + '@jridgewell/gen-mapping': 0.3.13 + '@jridgewell/trace-mapping': 0.3.31 + jsesc: 3.1.0 + + '@babel/helper-annotate-as-pure@7.27.3': + dependencies: + '@babel/types': 7.29.0 + + '@babel/helper-compilation-targets@7.28.6': + dependencies: + '@babel/compat-data': 7.29.0 + '@babel/helper-validator-option': 7.27.1 + browserslist: 4.28.2 + lru-cache: 5.1.1 + semver: 6.3.1 + + '@babel/helper-create-class-features-plugin@7.28.6(@babel/core@7.25.9)': + dependencies: + '@babel/core': 7.25.9 + '@babel/helper-annotate-as-pure': 7.27.3 + '@babel/helper-member-expression-to-functions': 7.28.5 + '@babel/helper-optimise-call-expression': 7.27.1 + '@babel/helper-replace-supers': 7.28.6(@babel/core@7.25.9) + '@babel/helper-skip-transparent-expression-wrappers': 7.27.1 + '@babel/traverse': 7.29.0 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + + '@babel/helper-globals@7.28.0': {} + + '@babel/helper-member-expression-to-functions@7.28.5': + dependencies: + '@babel/traverse': 7.29.0 + '@babel/types': 7.29.0 + transitivePeerDependencies: + - supports-color + + '@babel/helper-module-imports@7.28.6': + dependencies: + '@babel/traverse': 7.29.0 + '@babel/types': 7.29.0 + transitivePeerDependencies: + - supports-color + + '@babel/helper-module-transforms@7.28.6(@babel/core@7.25.9)': + dependencies: + '@babel/core': 7.25.9 + '@babel/helper-module-imports': 7.28.6 + '@babel/helper-validator-identifier': 7.28.5 + '@babel/traverse': 7.29.0 + transitivePeerDependencies: + - supports-color + + '@babel/helper-optimise-call-expression@7.27.1': + dependencies: + '@babel/types': 7.29.0 + + '@babel/helper-plugin-utils@7.28.6': {} + + '@babel/helper-replace-supers@7.28.6(@babel/core@7.25.9)': + dependencies: + '@babel/core': 7.25.9 + '@babel/helper-member-expression-to-functions': 7.28.5 + '@babel/helper-optimise-call-expression': 7.27.1 + '@babel/traverse': 7.29.0 + transitivePeerDependencies: + - supports-color + + '@babel/helper-skip-transparent-expression-wrappers@7.27.1': + dependencies: + '@babel/traverse': 7.29.0 + '@babel/types': 7.29.0 + transitivePeerDependencies: + - supports-color + '@babel/helper-string-parser@7.27.1': {} '@babel/helper-validator-identifier@7.28.5': {} + '@babel/helper-validator-option@7.27.1': {} + + '@babel/helpers@7.29.2': + dependencies: + '@babel/template': 7.28.6 + '@babel/types': 7.29.0 + + '@babel/parser@7.25.9': + dependencies: + '@babel/types': 7.29.0 + '@babel/parser@7.29.0': dependencies: '@babel/types': 7.29.0 + '@babel/plugin-proposal-decorators@7.24.7(@babel/core@7.25.9)': + dependencies: + '@babel/core': 7.25.9 + '@babel/helper-create-class-features-plugin': 7.28.6(@babel/core@7.25.9) + '@babel/helper-plugin-utils': 7.28.6 + '@babel/plugin-syntax-decorators': 7.28.6(@babel/core@7.25.9) + transitivePeerDependencies: + - supports-color + + '@babel/plugin-proposal-explicit-resource-management@7.27.4(@babel/core@7.25.9)': + dependencies: + '@babel/core': 7.25.9 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/plugin-transform-destructuring': 7.28.5(@babel/core@7.25.9) + transitivePeerDependencies: + - supports-color + + '@babel/plugin-syntax-decorators@7.28.6(@babel/core@7.25.9)': + dependencies: + '@babel/core': 7.25.9 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-syntax-jsx@7.28.6(@babel/core@7.25.9)': + dependencies: + '@babel/core': 7.25.9 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-syntax-typescript@7.28.6(@babel/core@7.25.9)': + dependencies: + '@babel/core': 7.25.9 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-destructuring@7.28.5(@babel/core@7.25.9)': + dependencies: + '@babel/core': 7.25.9 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/traverse': 7.29.0 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-modules-commonjs@7.28.6(@babel/core@7.25.9)': + dependencies: + '@babel/core': 7.25.9 + '@babel/helper-module-transforms': 7.28.6(@babel/core@7.25.9) + '@babel/helper-plugin-utils': 7.28.6 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-typescript@7.28.6(@babel/core@7.25.9)': + dependencies: + '@babel/core': 7.25.9 + '@babel/helper-annotate-as-pure': 7.27.3 + '@babel/helper-create-class-features-plugin': 7.28.6(@babel/core@7.25.9) + '@babel/helper-plugin-utils': 7.28.6 + '@babel/helper-skip-transparent-expression-wrappers': 7.27.1 + '@babel/plugin-syntax-typescript': 7.28.6(@babel/core@7.25.9) + transitivePeerDependencies: + - supports-color + + '@babel/preset-typescript@7.24.7(@babel/core@7.25.9)': + dependencies: + '@babel/core': 7.25.9 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/helper-validator-option': 7.27.1 + '@babel/plugin-syntax-jsx': 7.28.6(@babel/core@7.25.9) + '@babel/plugin-transform-modules-commonjs': 7.28.6(@babel/core@7.25.9) + '@babel/plugin-transform-typescript': 7.28.6(@babel/core@7.25.9) + transitivePeerDependencies: + - supports-color + + '@babel/template@7.28.6': + dependencies: + '@babel/code-frame': 7.29.0 + '@babel/parser': 7.29.0 + '@babel/types': 7.29.0 + + '@babel/traverse@7.29.0': + dependencies: + '@babel/code-frame': 7.29.0 + '@babel/generator': 7.29.1 + '@babel/helper-globals': 7.28.0 + '@babel/parser': 7.29.0 + '@babel/template': 7.28.6 + '@babel/types': 7.29.0 + debug: 4.4.3 + transitivePeerDependencies: + - supports-color + '@babel/types@7.29.0': dependencies: '@babel/helper-string-parser': 7.27.1 @@ -2650,6 +3332,102 @@ snapshots: '@iconify/types@2.0.0': {} + '@inquirer/checkbox@3.0.1': + dependencies: + '@inquirer/core': 9.2.1 + '@inquirer/figures': 1.0.15 + '@inquirer/type': 2.0.0 + ansi-escapes: 4.3.2 + yoctocolors-cjs: 2.1.3 + + '@inquirer/confirm@4.0.1': + dependencies: + '@inquirer/core': 9.2.1 + '@inquirer/type': 2.0.0 + + '@inquirer/core@9.2.1': + dependencies: + '@inquirer/figures': 1.0.15 + '@inquirer/type': 2.0.0 + '@types/mute-stream': 0.0.4 + '@types/node': 22.19.17 + '@types/wrap-ansi': 3.0.0 + ansi-escapes: 4.3.2 + cli-width: 4.1.0 + mute-stream: 1.0.0 + signal-exit: 4.1.0 + strip-ansi: 6.0.1 + wrap-ansi: 6.2.0 + yoctocolors-cjs: 2.1.3 + + '@inquirer/editor@3.0.1': + dependencies: + '@inquirer/core': 9.2.1 + '@inquirer/type': 2.0.0 + external-editor: 3.1.0 + + '@inquirer/expand@3.0.1': + dependencies: + '@inquirer/core': 9.2.1 + '@inquirer/type': 2.0.0 + yoctocolors-cjs: 2.1.3 + + '@inquirer/figures@1.0.15': {} + + '@inquirer/input@3.0.1': + dependencies: + '@inquirer/core': 9.2.1 + '@inquirer/type': 2.0.0 + + '@inquirer/number@2.0.1': + dependencies: + '@inquirer/core': 9.2.1 + '@inquirer/type': 2.0.0 + + '@inquirer/password@3.0.1': + dependencies: + '@inquirer/core': 9.2.1 + '@inquirer/type': 2.0.0 + ansi-escapes: 4.3.2 + + '@inquirer/prompts@6.0.1': + dependencies: + '@inquirer/checkbox': 3.0.1 + '@inquirer/confirm': 4.0.1 + '@inquirer/editor': 3.0.1 + '@inquirer/expand': 3.0.1 + '@inquirer/input': 3.0.1 + '@inquirer/number': 2.0.1 + '@inquirer/password': 3.0.1 + '@inquirer/rawlist': 3.0.1 + '@inquirer/search': 2.0.1 + '@inquirer/select': 3.0.1 + + '@inquirer/rawlist@3.0.1': + dependencies: + '@inquirer/core': 9.2.1 + '@inquirer/type': 2.0.0 + yoctocolors-cjs: 2.1.3 + + '@inquirer/search@2.0.1': + dependencies: + '@inquirer/core': 9.2.1 + '@inquirer/figures': 1.0.15 + '@inquirer/type': 2.0.0 + yoctocolors-cjs: 2.1.3 + + '@inquirer/select@3.0.1': + dependencies: + '@inquirer/core': 9.2.1 + '@inquirer/figures': 1.0.15 + '@inquirer/type': 2.0.0 + ansi-escapes: 4.3.2 + yoctocolors-cjs: 2.1.3 + + '@inquirer/type@2.0.0': + dependencies: + mute-stream: 1.0.0 + '@isaacs/cliui@8.0.2': dependencies: string-width: 5.1.2 @@ -2805,6 +3583,69 @@ snapshots: '@sindresorhus/merge-streams@4.0.0': {} + '@stryker-mutator/api@8.7.1': + dependencies: + mutation-testing-metrics: 3.3.0 + mutation-testing-report-schema: 3.3.0 + tslib: 2.7.0 + typed-inject: 4.0.0 + + '@stryker-mutator/core@8.7.1': + dependencies: + '@inquirer/prompts': 6.0.1 + '@stryker-mutator/api': 8.7.1 + '@stryker-mutator/instrumenter': 8.7.1 + '@stryker-mutator/util': 8.7.1 + ajv: 8.17.1 + chalk: 5.3.0 + commander: 12.1.0 + diff-match-patch: 1.0.5 + emoji-regex: 10.4.0 + execa: 9.4.1 + file-url: 4.0.0 + lodash.groupby: 4.6.0 + minimatch: 9.0.9 + mutation-testing-elements: 3.4.0 + mutation-testing-metrics: 3.3.0 + mutation-testing-report-schema: 3.3.0 + npm-run-path: 6.0.0 + progress: 2.0.3 + rxjs: 7.8.2 + semver: 7.7.4 + source-map: 0.7.6 + tree-kill: 1.2.2 + tslib: 2.7.0 + typed-inject: 4.0.0 + typed-rest-client: 2.1.0 + transitivePeerDependencies: + - supports-color + + '@stryker-mutator/instrumenter@8.7.1': + dependencies: + '@babel/core': 7.25.9 + '@babel/generator': 7.25.9 + '@babel/parser': 7.25.9 + '@babel/plugin-proposal-decorators': 7.24.7(@babel/core@7.25.9) + '@babel/plugin-proposal-explicit-resource-management': 7.27.4(@babel/core@7.25.9) + '@babel/preset-typescript': 7.24.7(@babel/core@7.25.9) + '@stryker-mutator/api': 8.7.1 + '@stryker-mutator/util': 8.7.1 + angular-html-parser: 6.0.2 + semver: 7.6.3 + weapon-regex: 1.3.6 + transitivePeerDependencies: + - supports-color + + '@stryker-mutator/util@8.7.1': {} + + '@stryker-mutator/vitest-runner@8.7.1(@stryker-mutator/core@8.7.1)(vitest@2.1.9(@types/node@20.19.34))': + dependencies: + '@stryker-mutator/api': 8.7.1 + '@stryker-mutator/core': 8.7.1 + '@stryker-mutator/util': 8.7.1 + tslib: 2.7.0 + vitest: 2.1.9(@types/node@20.19.34) + '@types/estree@1.0.8': {} '@types/hast@3.0.4': @@ -2826,6 +3667,10 @@ snapshots: '@types/mdurl@2.0.0': {} + '@types/mute-stream@0.0.4': + dependencies: + '@types/node': 20.19.37 + '@types/node-fetch@2.6.13': dependencies: '@types/node': 20.19.37 @@ -2843,10 +3688,16 @@ snapshots: dependencies: undici-types: 6.21.0 + '@types/node@22.19.17': + dependencies: + undici-types: 6.21.0 + '@types/unist@3.0.3': {} '@types/web-bluetooth@0.0.21': {} + '@types/wrap-ansi@3.0.0': {} + '@ungap/structured-clone@1.3.0': {} '@vitejs/plugin-vue@5.2.4(vite@5.4.21(@types/node@20.19.34))(vue@3.5.29(typescript@5.9.3))': @@ -3064,6 +3915,13 @@ snapshots: optionalDependencies: ajv: 8.18.0 + ajv@8.17.1: + dependencies: + fast-deep-equal: 3.1.3 + fast-uri: 3.1.0 + json-schema-traverse: 1.0.0 + require-from-string: 2.0.2 + ajv@8.18.0: dependencies: fast-deep-equal: 3.1.3 @@ -3088,6 +3946,14 @@ snapshots: '@algolia/requester-fetch': 5.49.1 '@algolia/requester-node-http': 5.49.1 + angular-html-parser@6.0.2: + dependencies: + tslib: 2.7.0 + + ansi-escapes@4.3.2: + dependencies: + type-fest: 0.21.3 + ansi-regex@5.0.1: {} ansi-regex@6.2.2: {} @@ -3121,6 +3987,8 @@ snapshots: balanced-match@4.0.4: {} + baseline-browser-mapping@2.10.18: {} + birpc@2.9.0: {} brace-expansion@2.0.2: @@ -3131,6 +3999,14 @@ snapshots: dependencies: balanced-match: 4.0.4 + browserslist@4.28.2: + dependencies: + baseline-browser-mapping: 2.10.18 + caniuse-lite: 1.0.30001787 + electron-to-chromium: 1.5.335 + node-releases: 2.0.37 + update-browserslist-db: 1.2.3(browserslist@4.28.2) + bundle-require@5.1.0(esbuild@0.27.3): dependencies: esbuild: 0.27.3 @@ -3143,6 +4019,13 @@ snapshots: es-errors: 1.3.0 function-bind: 1.1.2 + call-bound@1.0.4: + dependencies: + call-bind-apply-helpers: 1.0.2 + get-intrinsic: 1.3.0 + + caniuse-lite@1.0.30001787: {} + ccount@2.0.1: {} chai@4.5.0: @@ -3163,12 +4046,16 @@ snapshots: loupe: 3.2.1 pathval: 2.0.1 + chalk@5.3.0: {} + chalk@5.6.2: {} character-entities-html4@2.1.0: {} character-entities-legacy@3.0.0: {} + chardet@0.7.0: {} + check-error@1.0.3: dependencies: get-func-name: 2.0.2 @@ -3179,6 +4066,8 @@ snapshots: dependencies: readdirp: 4.1.2 + cli-width@4.1.0: {} + color-convert@2.0.1: dependencies: color-name: 1.1.4 @@ -3199,6 +4088,8 @@ snapshots: consola@3.4.2: {} + convert-source-map@2.0.0: {} + cookie@0.7.2: {} copy-anything@4.0.5: @@ -3227,10 +4118,17 @@ snapshots: dequal@2.0.3: {} + des.js@1.1.0: + dependencies: + inherits: 2.0.4 + minimalistic-assert: 1.0.1 + devlop@1.1.0: dependencies: dequal: 2.0.3 + diff-match-patch@1.0.5: {} + diff-sequences@29.6.3: {} dunder-proto@1.0.1: @@ -3241,8 +4139,12 @@ snapshots: eastasianwidth@0.2.0: {} + electron-to-chromium@1.5.335: {} + emoji-regex-xs@1.0.0: {} + emoji-regex@10.4.0: {} + emoji-regex@8.0.0: {} emoji-regex@9.2.2: {} @@ -3325,6 +4227,8 @@ snapshots: '@esbuild/win32-ia32': 0.27.3 '@esbuild/win32-x64': 0.27.3 + escalade@3.2.0: {} + estree-walker@2.0.2: {} estree-walker@3.0.3: @@ -3345,6 +4249,21 @@ snapshots: signal-exit: 4.1.0 strip-final-newline: 3.0.0 + execa@9.4.1: + dependencies: + '@sindresorhus/merge-streams': 4.0.0 + cross-spawn: 7.0.6 + figures: 6.1.0 + get-stream: 9.0.1 + human-signals: 8.0.1 + is-plain-obj: 4.1.0 + is-stream: 4.0.1 + npm-run-path: 6.0.0 + pretty-ms: 9.3.0 + signal-exit: 4.1.0 + strip-final-newline: 4.0.0 + yoctocolors: 2.1.2 + execa@9.6.1: dependencies: '@sindresorhus/merge-streams': 4.0.0 @@ -3362,6 +4281,12 @@ snapshots: expect-type@1.3.0: {} + external-editor@3.1.0: + dependencies: + chardet: 0.7.0 + iconv-lite: 0.4.24 + tmp: 0.0.33 + fast-content-type-parse@1.1.0: {} fast-decode-uri-component@1.0.1: {} @@ -3419,6 +4344,8 @@ snapshots: dependencies: is-unicode-supported: 2.1.0 + file-url@4.0.0: {} + find-my-way@8.2.2: dependencies: fast-deep-equal: 3.1.3 @@ -3462,6 +4389,8 @@ snapshots: function-bind@1.1.2: {} + gensync@1.0.0-beta.2: {} + get-func-name@2.0.2: {} get-intrinsic@1.3.0: @@ -3548,6 +4477,12 @@ snapshots: dependencies: ms: 2.1.3 + iconv-lite@0.4.24: + dependencies: + safer-buffer: 2.1.2 + + inherits@2.0.4: {} + ipaddr.js@1.9.1: {} is-fullwidth-code-point@3.0.0: {} @@ -3593,18 +4528,26 @@ snapshots: joycon@3.1.1: {} + js-md4@0.3.2: {} + + js-tokens@4.0.0: {} + js-tokens@9.0.1: {} js-yaml@4.1.1: dependencies: argparse: 2.0.1 + jsesc@3.1.0: {} + json-schema-ref-resolver@1.0.1: dependencies: fast-deep-equal: 3.1.3 json-schema-traverse@1.0.0: {} + json5@2.2.3: {} + light-my-request@5.14.0: dependencies: cookie: 0.7.2 @@ -3622,6 +4565,8 @@ snapshots: mlly: 1.8.0 pkg-types: 1.3.1 + lodash.groupby@4.6.0: {} + loupe@2.3.7: dependencies: get-func-name: 2.0.2 @@ -3630,6 +4575,10 @@ snapshots: lru-cache@10.4.3: {} + lru-cache@5.1.1: + dependencies: + yallist: 3.1.1 + magic-string@0.30.21: dependencies: '@jridgewell/sourcemap-codec': 1.5.5 @@ -3687,6 +4636,8 @@ snapshots: mimic-fn@4.0.0: {} + minimalistic-assert@1.0.1: {} + minimatch@10.2.4: dependencies: brace-expansion: 5.0.4 @@ -3710,6 +4661,16 @@ snapshots: ms@2.1.3: {} + mutation-testing-elements@3.4.0: {} + + mutation-testing-metrics@3.3.0: + dependencies: + mutation-testing-report-schema: 3.3.0 + + mutation-testing-report-schema@3.3.0: {} + + mute-stream@1.0.0: {} + mz@2.7.0: dependencies: any-promise: 1.3.0 @@ -3724,6 +4685,8 @@ snapshots: dependencies: whatwg-url: 5.0.0 + node-releases@2.0.37: {} + npm-run-path@5.3.0: dependencies: path-key: 4.0.0 @@ -3735,6 +4698,8 @@ snapshots: object-assign@4.1.1: {} + object-inspect@1.13.4: {} + on-exit-leak-free@2.1.2: {} once@1.4.0: @@ -3751,6 +4716,8 @@ snapshots: regex: 6.1.0 regex-recursion: 6.0.2 + os-tmpdir@1.0.2: {} + p-limit@5.0.0: dependencies: yocto-queue: 1.2.2 @@ -3839,6 +4806,8 @@ snapshots: process-warning@5.0.0: {} + progress@2.0.3: {} + property-information@7.1.0: {} proxy-addr@2.0.7: @@ -3846,6 +4815,10 @@ snapshots: forwarded: 0.2.0 ipaddr.js: 1.9.1 + qs@6.15.1: + dependencies: + side-channel: 1.1.0 + quick-format-unescaped@4.0.4: {} react-is@18.3.1: {} @@ -3907,16 +4880,26 @@ snapshots: '@rollup/rollup-win32-x64-msvc': 4.59.0 fsevents: 2.3.3 + rxjs@7.8.2: + dependencies: + tslib: 2.7.0 + safe-regex2@3.1.0: dependencies: ret: 0.4.3 safe-stable-stringify@2.5.0: {} + safer-buffer@2.1.2: {} + search-insights@2.17.3: {} secure-json-parse@2.7.0: {} + semver@6.3.1: {} + + semver@7.6.3: {} + semver@7.7.4: {} set-cookie-parser@2.7.2: {} @@ -3938,6 +4921,34 @@ snapshots: '@shikijs/vscode-textmate': 10.0.2 '@types/hast': 3.0.4 + side-channel-list@1.0.1: + dependencies: + es-errors: 1.3.0 + object-inspect: 1.13.4 + + side-channel-map@1.0.1: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + object-inspect: 1.13.4 + + side-channel-weakmap@1.0.2: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + object-inspect: 1.13.4 + side-channel-map: 1.0.1 + + side-channel@1.1.0: + dependencies: + es-errors: 1.3.0 + object-inspect: 1.13.4 + side-channel-list: 1.0.1 + side-channel-map: 1.0.1 + side-channel-weakmap: 1.0.2 + siginfo@2.0.0: {} signal-exit@4.1.0: {} @@ -4052,6 +5063,10 @@ snapshots: tinyspy@3.0.2: {} + tmp@0.0.33: + dependencies: + os-tmpdir: 1.0.2 + toad-cache@3.7.0: {} tr46@0.0.3: {} @@ -4062,6 +5077,8 @@ snapshots: ts-interface-checker@0.1.13: {} + tslib@2.7.0: {} + tsup@8.5.1(postcss@8.5.6)(tsx@4.21.0)(typescript@5.9.3): dependencies: bundle-require: 5.1.0(esbuild@0.27.3) @@ -4097,12 +5114,28 @@ snapshots: optionalDependencies: fsevents: 2.3.3 + tunnel@0.0.6: {} + type-detect@4.1.0: {} + type-fest@0.21.3: {} + + typed-inject@4.0.0: {} + + typed-rest-client@2.1.0: + dependencies: + des.js: 1.1.0 + js-md4: 0.3.2 + qs: 6.15.1 + tunnel: 0.0.6 + underscore: 1.13.8 + typescript@5.9.3: {} ufo@1.6.3: {} + underscore@1.13.8: {} + undici-types@5.26.5: {} undici-types@6.21.0: {} @@ -4136,6 +5169,12 @@ snapshots: unist-util-is: 6.0.1 unist-util-visit-parents: 6.0.2 + update-browserslist-db@1.2.3(browserslist@4.28.2): + dependencies: + browserslist: 4.28.2 + escalade: 3.2.0 + picocolors: 1.1.1 + vfile-message@4.0.3: dependencies: '@types/unist': 3.0.3 @@ -4328,6 +5367,8 @@ snapshots: optionalDependencies: typescript: 5.9.3 + weapon-regex@1.3.6: {} + web-streams-polyfill@4.0.0-beta.3: {} webidl-conversions@3.0.1: {} @@ -4346,6 +5387,12 @@ snapshots: siginfo: 2.0.0 stackback: 0.0.2 + wrap-ansi@6.2.0: + dependencies: + ansi-styles: 4.3.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + wrap-ansi@7.0.0: dependencies: ansi-styles: 4.3.0 @@ -4362,8 +5409,12 @@ snapshots: ws@8.19.0: {} + yallist@3.1.1: {} + yocto-queue@1.2.2: {} + yoctocolors-cjs@2.1.3: {} + yoctocolors@2.1.2: {} zod-to-json-schema@3.25.1(zod@3.25.76): diff --git a/quality-baseline.json b/quality-baseline.json new file mode 100644 index 0000000..59ff78d --- /dev/null +++ b/quality-baseline.json @@ -0,0 +1,7 @@ +{ + "adapter-claude": { "coverage": 83.93, "mutation": 50.85 }, + "sdk": { "coverage": null, "mutation": 54.31 }, + "mcp-server": { "coverage": null, "mutation": 31.31 }, + "cli": { "coverage": null, "mutation": 49.50 }, + "sidecar": { "coverage": null, "mutation": 51.43 } +} diff --git a/scripts/annotate-survivors.mjs b/scripts/annotate-survivors.mjs new file mode 100644 index 0000000..bf57081 --- /dev/null +++ b/scripts/annotate-survivors.mjs @@ -0,0 +1,33 @@ +#!/usr/bin/env node +// Emits GitHub Actions warning annotations for surviving mutants. +// Usage: node scripts/annotate-survivors.mjs reports/mutation/.json + +import { readFileSync } from 'node:fs' + +const file = process.argv[2] +if (!file) { console.error('Usage: annotate-survivors.mjs '); process.exit(1) } + +// GitHub Actions annotation escaping per +// https://github.com/actions/toolkit/blob/main/packages/core/src/command.ts +function escapeProperty(s) { + return s.replace(/%/g, '%25').replace(/\r/g, '%0D').replace(/\n/g, '%0A').replace(/:/g, '%3A').replace(/,/g, '%2C') +} + +function escapeMessage(s) { + return s.replace(/%/g, '%25').replace(/\r/g, '%0D').replace(/\n/g, '%0A') +} + +const report = JSON.parse(readFileSync(file, 'utf8')) + +for (const [filePath, fileReport] of Object.entries(report.files)) { + for (const mutant of fileReport.mutants) { + if (mutant.status !== 'Survived') continue + const loc = mutant.location?.start + if (!loc) continue + const desc = mutant.mutatorName || 'unknown mutator' + const replacement = mutant.replacement ? ` -> \`${mutant.replacement.slice(0, 60)}\`` : '' + const msg = escapeMessage(`Surviving mutant (${desc})${replacement}`) + const path = escapeProperty(filePath) + console.log(`::warning file=${path},line=${loc.line},col=${loc.column}::${msg}`) + } +} diff --git a/scripts/auto-ratchet.mjs b/scripts/auto-ratchet.mjs new file mode 100644 index 0000000..916ce9d --- /dev/null +++ b/scripts/auto-ratchet.mjs @@ -0,0 +1,54 @@ +#!/usr/bin/env node +// Reads current mutation scores and bumps thresholds in stryker.config.mjs +// when a package's score exceeds its threshold by more than 5 points. +// Usage: node scripts/auto-ratchet.mjs +// +// Outputs changed packages (if any) to stdout, one per line. +// Exits 0 if changes were made, 1 if nothing to ratchet. + +import { readFileSync, writeFileSync } from 'node:fs' + +const config = readFileSync('stryker.config.mjs', 'utf8') + +const thresholdMatch = config.match(/const THRESHOLDS\s*=\s*\{([^}]+)\}/) +if (!thresholdMatch) { console.error('Could not find THRESHOLDS in stryker.config.mjs'); process.exit(1) } + +const thresholds = {} +for (const line of thresholdMatch[1].split('\n')) { + const m = line.match(/'([^']+)':\s*(\d+)/) + if (m) thresholds[m[1]] = parseInt(m[2], 10) +} + +const changed = [] + +for (const [pkg, oldBreak] of Object.entries(thresholds)) { + const reportPath = `reports/mutation/${pkg}.json` + let score + try { + const report = JSON.parse(readFileSync(reportPath, 'utf8')) + const totals = Object.values(report.files).reduce( + (a, f) => { a.k += f.mutants.filter(m => m.status === 'Killed').length; a.t += f.mutants.length; return a }, + { k: 0, t: 0 }, + ) + score = totals.t ? (totals.k / totals.t) * 100 : 0 + } catch { + continue + } + + const newBreak = Math.floor(score) - 5 + if (newBreak > oldBreak) { + changed.push({ pkg, oldBreak, newBreak, score: score.toFixed(2) }) + } +} + +if (changed.length === 0) { + process.exit(1) +} + +let updated = config +for (const { pkg, oldBreak, newBreak } of changed) { + updated = updated.replace(`'${pkg}': ${oldBreak}`, `'${pkg}': ${newBreak}`) + console.log(`${pkg}: ${oldBreak} -> ${newBreak}`) +} + +writeFileSync('stryker.config.mjs', updated) diff --git a/scripts/mutation.mjs b/scripts/mutation.mjs new file mode 100644 index 0000000..aa09cf1 --- /dev/null +++ b/scripts/mutation.mjs @@ -0,0 +1,14 @@ +#!/usr/bin/env node +import { execSync } from 'node:child_process' +import { PACKAGES } from '../stryker.config.mjs' + +const targets = process.argv[2] ? [process.argv[2]] : PACKAGES + +for (const pkg of targets) { + if (!PACKAGES.includes(pkg)) { + console.error(`Unknown package: ${pkg}\nAvailable: ${PACKAGES.join(', ')}`) + process.exit(1) + } + console.log(`\n── mutation: ${pkg} ──\n`) + execSync('stryker run', { stdio: 'inherit', env: { ...process.env, STRYKER_PKG: pkg } }) +} diff --git a/stryker.config.mjs b/stryker.config.mjs new file mode 100644 index 0000000..8b31032 --- /dev/null +++ b/stryker.config.mjs @@ -0,0 +1,54 @@ +// Mutation testing config -- single source of truth for all packages. +// +// Per-package behavior is driven by the STRYKER_PKG env var, set by +// scripts/mutation.mjs. Thresholds live here, not in package.json. + +const PACKAGES = ['adapter-claude', 'sdk', 'mcp-server', 'cli', 'sidecar'] + +const THRESHOLDS = { + 'adapter-claude': 45, + 'sdk': 49, + 'mcp-server': 26, + 'cli': 45, + 'sidecar': 46, +} + +const pkg = process.env.STRYKER_PKG ?? '' +const breakThreshold = THRESHOLDS[pkg] ?? 40 + +const vitestConfigFile = pkg === 'cli' + ? 'packages/cli/vitest.stryker.config.ts' + : pkg + ? `packages/${pkg}/vitest.config.ts` + : undefined + +/** @type {import('@stryker-mutator/api/core').PartialStrykerOptions} */ +export default { + packageManager: 'pnpm', + testRunner: 'vitest', + plugins: ['@stryker-mutator/vitest-runner'], + reporters: ['html', 'progress', 'clear-text', 'json'], + coverageAnalysis: 'perTest', + incremental: true, + concurrency: 4, + timeoutMS: 60000, + thresholds: { high: 80, low: 40, break: breakThreshold }, + mutate: [ + `packages/${pkg || '*'}/src/**/*.ts`, + `!packages/${pkg || '*'}/src/**/*.test.ts`, + `!packages/${pkg || '*'}/src/**/__tests__/**`, + `!packages/${pkg || '*'}/src/**/*.d.ts`, + '!packages/sdk/src/scripts/export-schema.ts', + ], + tempDirName: '.stryker-tmp', + ...(pkg ? { incrementalFile: `.stryker-tmp/${pkg}-incremental.json` } : {}), + htmlReporter: { + fileName: pkg ? `reports/mutation/${pkg}.html` : 'reports/mutation/index.html', + }, + jsonReporter: { + fileName: pkg ? `reports/mutation/${pkg}.json` : 'reports/mutation/mutation.json', + }, + ...(vitestConfigFile ? { vitest: { configFile: vitestConfigFile, dir: `packages/${pkg}` } } : {}), +} + +export { PACKAGES, THRESHOLDS }