diff --git a/.changeset/README.md b/.changeset/README.md deleted file mode 100644 index e74974b36..000000000 --- a/.changeset/README.md +++ /dev/null @@ -1,6 +0,0 @@ -This directory is managed by Changesets. - -- Add a changeset locally with `pnpm changeset`. -- The CI "Release (prepare)" workflow opens/updates a Version Packages PR. -- Publishing happens from a GitHub Release via the "Publish to npm" workflow. - diff --git a/.changeset/config.json b/.changeset/config.json deleted file mode 100644 index 399245099..000000000 --- a/.changeset/config.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "$schema": "https://unpkg.com/@changesets/config/schema.json", - "changelog": "@changesets/cli/changelog", - "commit": false, - "fixed": [], - "linked": [], - "access": "public", - "baseBranch": "main", - "updateInternalDependencies": "patch", - "ignore": [] -} - diff --git a/.devcontainer/README.md b/.devcontainer/README.md index 989fa527f..c79b2619b 100644 --- a/.devcontainer/README.md +++ b/.devcontainer/README.md @@ -4,12 +4,10 @@ This directory contains the VS Code dev container configuration for OpenSpec dev ## What's Included -- **Node.js 20 LTS** (>=20.19.0) - TypeScript/JavaScript runtime -- **pnpm** - Fast, disk space efficient package manager +- **Bun** - Fast JavaScript runtime, bundler, and package manager - **Git + GitHub CLI** - Version control tools - **VS Code Extensions**: - ESLint & Prettier for code quality - - Vitest Explorer for running tests - GitLens for enhanced git integration - Error Lens for inline error highlighting - Code Spell Checker @@ -37,7 +35,7 @@ This directory contains the VS Code dev container configuration for OpenSpec dev 3. **Wait for Setup**: - The container will build (first time takes a few minutes) - - `pnpm install` runs automatically via `postCreateCommand` + - `bun install` runs automatically via `postCreateCommand` - All extensions install automatically ### Daily Development @@ -46,19 +44,16 @@ Once set up, the container preserves your development environment: ```bash # Run development build -pnpm run dev +bun run dev # Run CLI in development -pnpm run dev:cli +bun run dev:cli # Run tests -pnpm test - -# Run tests in watch mode -pnpm test:watch +bun test # Build the project -pnpm run build +bun run build ``` ### SSH Keys @@ -72,9 +67,9 @@ If you modify `.devcontainer/devcontainer.json`: ## Benefits -- No need to install Node.js or pnpm on your local machine +- No need to install Bun on your local machine - Consistent development environment across team members -- Isolated from other Node.js projects on your machine +- Isolated from other projects on your machine - All dependencies and tools containerized - Easy onboarding for new developers @@ -88,5 +83,5 @@ If you modify `.devcontainer/devcontainer.json`: - Rebuild the container: "Dev Containers: Rebuild Container" **Permission issues:** -- The container runs as the `node` user (non-root) +- The container runs as the `bun` user (non-root) - Files created in the container are owned by this user diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index c381b61fa..71f62a0be 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -1,8 +1,7 @@ { "name": "OpenSpec Development", - "image": "mcr.microsoft.com/devcontainers/typescript-node:1-20-bookworm", + "image": "oven/bun:latest", - // Additional tools and features "features": { "ghcr.io/devcontainers/features/git:1": { "version": "latest", @@ -13,10 +12,8 @@ } }, - // Configure tool-specific properties "customizations": { "vscode": { - // Set default container specific settings "settings": { "typescript.tsdk": "node_modules/typescript/lib", "typescript.enablePromptUseWorkspaceTsdk": true, @@ -29,19 +26,10 @@ "terminal.integrated.defaultProfile.linux": "bash" }, - // Add extensions you want installed when the container is created "extensions": [ - // TypeScript/JavaScript essentials "dbaeumer.vscode-eslint", "esbenp.prettier-vscode", - - // Testing - "vitest.explorer", - - // Git "eamodio.gitlens", - - // Utilities "streetsidesoftware.code-spell-checker", "usernamehw.errorlens", "christian-kohler.path-intellisense" @@ -49,20 +37,13 @@ } }, - // Use 'forwardPorts' to make a list of ports inside the container available locally - // "forwardPorts": [], - - // Use 'postCreateCommand' to run commands after the container is created - "postCreateCommand": "corepack enable && corepack prepare pnpm@latest --activate && pnpm install", + "postCreateCommand": "bun install", - // Configure mounts to preserve SSH keys for git operations "mounts": [ - "source=${localEnv:HOME}${localEnv:USERPROFILE}/.ssh,target=/home/node/.ssh,readonly,type=bind,consistency=cached" + "source=${localEnv:HOME}${localEnv:USERPROFILE}/.ssh,target=/home/bun/.ssh,readonly,type=bind,consistency=cached" ], - // Set the default user to 'node' (non-root user) - "remoteUser": "node", + "remoteUser": "bun", - // Ensure git is properly configured "initializeCommand": "echo 'Initializing dev container...'" } diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ff1eae8f9..29751746d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -5,7 +5,6 @@ on: branches: [main] push: branches: [main] - workflow_dispatch: permissions: contents: read @@ -15,211 +14,41 @@ concurrency: cancel-in-progress: true jobs: - test_pr: - name: Test - runs-on: ubuntu-latest - timeout-minutes: 10 - if: github.event_name == 'pull_request' - - steps: - - name: Checkout code - uses: actions/checkout@v4 - with: - fetch-depth: 0 - - - name: Setup pnpm - uses: pnpm/action-setup@v4 - with: - version: 9 - - - name: Setup Node.js - uses: actions/setup-node@v4 - with: - node-version: '20' - cache: 'pnpm' - - - name: Install dependencies - run: pnpm install --frozen-lockfile - - - name: Build project - run: pnpm run build - - - name: Run tests - run: pnpm test - - - name: Upload test coverage - uses: actions/upload-artifact@v4 - with: - name: coverage-report-pr - path: coverage/ - retention-days: 7 - - test_matrix: - name: Test (${{ matrix.label }}) + test: + name: Test (${{ matrix.os }}) runs-on: ${{ matrix.os }} - timeout-minutes: 15 - if: github.event_name != 'pull_request' + timeout-minutes: 10 strategy: fail-fast: false matrix: - include: - - os: ubuntu-latest - shell: bash - label: linux-bash - - os: macos-latest - shell: bash - label: macos-bash - - os: windows-latest - shell: pwsh - label: windows-pwsh - - defaults: - run: - shell: ${{ matrix.shell }} - + os: [ubuntu-latest, macos-latest, windows-latest] steps: - - name: Checkout code - uses: actions/checkout@v4 - with: - fetch-depth: 0 + - uses: actions/checkout@v4 - - name: Setup pnpm - uses: pnpm/action-setup@v4 + - uses: oven-sh/setup-bun@v2 with: - version: 9 - - - name: Setup Node.js - uses: actions/setup-node@v4 - with: - node-version: '20' - cache: 'pnpm' - - - name: Print environment diagnostics - run: | - node -p "JSON.stringify({ platform: process.platform, arch: process.arch, shell: process.env.SHELL || process.env.ComSpec || '' })" + bun-version: latest - - name: Install dependencies - run: pnpm install --frozen-lockfile + - run: bun install --frozen-lockfile - - name: Build project - run: pnpm run build + - run: bun run build - - name: Run tests - run: pnpm test - - - name: Upload test coverage - if: matrix.os == 'ubuntu-latest' - uses: actions/upload-artifact@v4 - with: - name: coverage-report-main - path: coverage/ - retention-days: 7 + - run: bun test lint: - name: Lint & Type Check + name: Lint runs-on: ubuntu-latest steps: - - name: Checkout code - uses: actions/checkout@v4 - - - name: Setup pnpm - uses: pnpm/action-setup@v4 - with: - version: 9 + - uses: actions/checkout@v4 - - name: Setup Node.js - uses: actions/setup-node@v4 + - uses: oven-sh/setup-bun@v2 with: - node-version: '20' - cache: 'pnpm' - - - name: Install dependencies - run: pnpm install --frozen-lockfile - - - name: Build project - run: pnpm run build + bun-version: latest - - name: Type check - run: pnpm exec tsc --noEmit + - run: bun install --frozen-lockfile - - name: Lint - run: pnpm lint + - run: bun run build - - name: Check for build artifacts - run: | - if [ ! -d "dist" ]; then - echo "Error: dist directory not found after build" - exit 1 - fi - if [ ! -f "dist/cli/index.js" ]; then - echo "Error: CLI entry point not found" - exit 1 - fi + - run: bun run typecheck - validate-changesets: - name: Validate Changesets - runs-on: ubuntu-latest - if: github.event_name == 'pull_request' - steps: - - name: Checkout code - uses: actions/checkout@v4 - with: - fetch-depth: 0 - - - name: Setup pnpm - uses: pnpm/action-setup@v4 - with: - version: 9 - - - name: Setup Node.js - uses: actions/setup-node@v4 - with: - node-version: '20' - cache: 'pnpm' - - - name: Install dependencies - run: pnpm install --frozen-lockfile - - - name: Validate changesets - run: | - if command -v changeset &> /dev/null; then - pnpm exec changeset status --since=origin/main - else - echo "Changesets not configured, skipping validation" - fi - - required-checks-pr: - name: All checks passed - runs-on: ubuntu-latest - needs: [test_pr, lint] - if: always() && github.event_name == 'pull_request' - steps: - - name: Verify all checks passed - run: | - if [[ "${{ needs.test_pr.result }}" != "success" ]]; then - echo "Test job failed" - exit 1 - fi - if [[ "${{ needs.lint.result }}" != "success" ]]; then - echo "Lint job failed" - exit 1 - fi - echo "All required checks passed!" - - required-checks-main: - name: All checks passed - runs-on: ubuntu-latest - needs: [test_matrix, lint] - if: always() && github.event_name != 'pull_request' - steps: - - name: Verify all checks passed - run: | - if [[ "${{ needs.test_matrix.result }}" != "success" ]]; then - echo "Matrix test job failed" - exit 1 - fi - if [[ "${{ needs.lint.result }}" != "success" ]]; then - echo "Lint job failed" - exit 1 - fi - echo "All required checks passed!" + - run: bun run lint diff --git a/.github/workflows/opencode.yml b/.github/workflows/opencode.yml new file mode 100644 index 000000000..12ea55bea --- /dev/null +++ b/.github/workflows/opencode.yml @@ -0,0 +1,31 @@ +name: opencode + +on: + issue_comment: + types: [created] + pull_request_review_comment: + types: [created] + +jobs: + opencode: + if: | + contains(github.event.comment.body, ' /oc') || + startsWith(github.event.comment.body, '/oc') || + contains(github.event.comment.body, ' /opencode') || + startsWith(github.event.comment.body, '/opencode') + runs-on: ubuntu-latest + permissions: + id-token: write + contents: read + pull-requests: read + issues: read + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Run opencode + uses: sst/opencode/github@latest + env: + OPENCODE_API_KEY: ${{ secrets.OPENCODE_API_KEY }} + with: + model: opencode/big-pickle \ No newline at end of file diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml new file mode 100644 index 000000000..5bba2f19c --- /dev/null +++ b/.github/workflows/publish.yml @@ -0,0 +1,50 @@ +name: Publish + +on: + release: + types: [published] + +permissions: + contents: write + +jobs: + publish: + name: Publish to npm + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - uses: oven-sh/setup-bun@v2 + with: + bun-version: latest + + - run: bun install --frozen-lockfile + + - run: bun run build + + - run: bun test + + - name: Set version from tag + run: | + VERSION="${GITHUB_REF_NAME#v}" + bun -e " + const pkg = require('./package.json'); + pkg.version = '$VERSION'; + require('fs').writeFileSync('./package.json', JSON.stringify(pkg, null, 2) + '\n'); + " + + - name: Determine npm tag + id: npm-tag + run: | + if [[ "$GITHUB_REF_NAME" == *"alpha"* ]]; then + echo "tag=alpha" >> $GITHUB_OUTPUT + elif [[ "$GITHUB_REF_NAME" == *"beta"* ]]; then + echo "tag=beta" >> $GITHUB_OUTPUT + else + echo "tag=latest" >> $GITHUB_OUTPUT + fi + + - name: Publish + run: bun publish --access public --tag ${{ steps.npm-tag.outputs.tag }} + env: + NPM_CONFIG_TOKEN: ${{ secrets.NPM_TOKEN }} diff --git a/.github/workflows/release-prepare.yml b/.github/workflows/release-prepare.yml deleted file mode 100644 index 055f4666a..000000000 --- a/.github/workflows/release-prepare.yml +++ /dev/null @@ -1,48 +0,0 @@ -name: Release (prepare) - -on: - push: - branches: [main] - -permissions: - contents: write - pull-requests: write - id-token: write # Required for npm OIDC trusted publishing - -concurrency: - group: release-${{ github.ref }} - cancel-in-progress: false - -jobs: - prepare: - if: github.repository == 'Fission-AI/OpenSpec' - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - with: - fetch-depth: 0 - - - uses: pnpm/action-setup@v4 - with: - version: 9 - - - uses: actions/setup-node@v4 - with: - node-version: '24' # Node 24 includes npm 11.5.1+ required for OIDC - cache: 'pnpm' - registry-url: 'https://registry.npmjs.org' - - - run: pnpm install --frozen-lockfile - - # Opens/updates the Version Packages PR; publishes when the Version PR merges - - name: Create/Update Version PR - uses: changesets/action@v1 - with: - title: 'chore(release): version packages' - createGithubReleases: true - # Use CI-specific release script: relies on version PR having been merged - # so package.json already contains the bumped version. - publish: pnpm run release:ci - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - # npm authentication handled via OIDC trusted publishing (no token needed) diff --git a/README.md b/README.md index 7b6c7354d..c936604fa 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@

- + @@ -10,12 +10,11 @@

Spec-driven development for AI coding assistants.

- CI - npm version - node version + CI + npm version + Bun License: MIT Conventional Commits - Discord

@@ -23,7 +22,7 @@

- Follow @0xTab on X for updates ¡ Join the OpenSpec Discord for help and questions. + Follow @ClankerGuru on X for updates.

# OpenSpec @@ -131,12 +130,17 @@ These tools automatically read workflow instructions from `openspec/AGENTS.md`. ### Install & Initialize #### Prerequisites -- **Node.js >= 20.19.0** - Check your version with `node --version` +- **Bun** - Install from [bun.sh](https://bun.sh) if you haven't already -#### Step 1: Install the CLI globally +#### Step 1: Run with bunx (recommended) ```bash -npm install -g @fission-ai/openspec@latest +bunx @clanker-guru/openspec +``` + +Or install globally: +```bash +bun install -g @clanker-guru/openspec ``` Verify installation: @@ -363,17 +367,17 @@ Run `openspec update` whenever someone switches tools so your agents pick up the 1. **Upgrade the package** ```bash - npm install -g @fission-ai/openspec@latest + bun install -g @clanker-guru/openspec@latest ``` 2. **Refresh agent instructions** - Run `openspec update` inside each project to regenerate AI guidance and ensure the latest slash commands are active. ## Contributing -- Install dependencies: `pnpm install` -- Build: `pnpm run build` -- Test: `pnpm test` -- Develop CLI locally: `pnpm run dev` or `pnpm run dev:cli` +- Install dependencies: `bun install` +- Build: `bun run build` +- Test: `bun test` +- Develop CLI locally: `bun run dev` or `bun run dev:cli` - Conventional commits (one-line): `type(scope): subject` ## License diff --git a/bin/openspec.js b/bin/openspec.js deleted file mode 100755 index 3341bce51..000000000 --- a/bin/openspec.js +++ /dev/null @@ -1,3 +0,0 @@ -#!/usr/bin/env node - -import '../dist/cli/index.js'; \ No newline at end of file diff --git a/bin/openspec.ts b/bin/openspec.ts new file mode 100755 index 000000000..da82cbebb --- /dev/null +++ b/bin/openspec.ts @@ -0,0 +1,3 @@ +#!/usr/bin/env bun + +import '../dist/cli/index.js'; diff --git a/build.js b/build.js deleted file mode 100644 index fc9aecf94..000000000 --- a/build.js +++ /dev/null @@ -1,31 +0,0 @@ -#!/usr/bin/env node - -import { execFileSync } from 'child_process'; -import { existsSync, rmSync } from 'fs'; -import { createRequire } from 'module'; - -const require = createRequire(import.meta.url); - -const runTsc = (args = []) => { - const tscPath = require.resolve('typescript/bin/tsc'); - execFileSync(process.execPath, [tscPath, ...args], { stdio: 'inherit' }); -}; - -console.log('🔨 Building OpenSpec...\n'); - -// Clean dist directory -if (existsSync('dist')) { - console.log('Cleaning dist directory...'); - rmSync('dist', { recursive: true, force: true }); -} - -// Run TypeScript compiler (use local version explicitly) -console.log('Compiling TypeScript...'); -try { - runTsc(['--version']); - runTsc(); - console.log('\n✅ Build completed successfully!'); -} catch (error) { - console.error('\n❌ Build failed!'); - process.exit(1); -} diff --git a/build.ts b/build.ts new file mode 100644 index 000000000..812b1eebc --- /dev/null +++ b/build.ts @@ -0,0 +1,21 @@ +#!/usr/bin/env bun + +import { existsSync, rmSync } from 'fs'; +import { $ } from 'bun'; + +console.log('🔨 Building OpenSpec...\n'); + +if (existsSync('dist')) { + console.log('Cleaning dist directory...'); + rmSync('dist', { recursive: true, force: true }); +} + +console.log('Compiling TypeScript...'); +try { + await $`bun x tsc --version`; + await $`bun x tsc`; + console.log('\n✅ Build completed successfully!'); +} catch { + console.error('\n❌ Build failed!'); + process.exit(1); +} diff --git a/bun.lock b/bun.lock new file mode 100644 index 000000000..e0c7ba4b4 --- /dev/null +++ b/bun.lock @@ -0,0 +1,377 @@ +{ + "lockfileVersion": 1, + "configVersion": 1, + "workspaces": { + "": { + "name": "@clanker-guru/openspec", + "dependencies": { + "@inquirer/core": "^10.2.2", + "@inquirer/prompts": "^7.8.0", + "chalk": "^5.5.0", + "commander": "^14.0.0", + "fast-glob": "^3.3.3", + "ora": "^8.2.0", + "yaml": "^2.8.2", + "zod": "^4.0.17", + }, + "devDependencies": { + "@types/bun": "^1.2.7", + "eslint": "^9.39.2", + "jiti": "^2.6.1", + "typescript": "^5.9.3", + "typescript-eslint": "^8.50.1", + }, + }, + }, + "packages": { + "@eslint-community/eslint-utils": ["@eslint-community/eslint-utils@4.9.0", "", { "dependencies": { "eslint-visitor-keys": "^3.4.3" }, "peerDependencies": { "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" } }, "sha512-ayVFHdtZ+hsq1t2Dy24wCmGXGe4q9Gu3smhLYALJrr473ZH27MsnSL+LKUlimp4BWJqMDMLmPpx/Q9R3OAlL4g=="], + + "@eslint-community/regexpp": ["@eslint-community/regexpp@4.12.2", "", {}, "sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew=="], + + "@eslint/config-array": ["@eslint/config-array@0.21.1", "", { "dependencies": { "@eslint/object-schema": "^2.1.7", "debug": "^4.3.1", "minimatch": "^3.1.2" } }, "sha512-aw1gNayWpdI/jSYVgzN5pL0cfzU02GT3NBpeT/DXbx1/1x7ZKxFPd9bwrzygx/qiwIQiJ1sw/zD8qY/kRvlGHA=="], + + "@eslint/config-helpers": ["@eslint/config-helpers@0.4.2", "", { "dependencies": { "@eslint/core": "^0.17.0" } }, "sha512-gBrxN88gOIf3R7ja5K9slwNayVcZgK6SOUORm2uBzTeIEfeVaIhOpCtTox3P6R7o2jLFwLFTLnC7kU/RGcYEgw=="], + + "@eslint/core": ["@eslint/core@0.17.0", "", { "dependencies": { "@types/json-schema": "^7.0.15" } }, "sha512-yL/sLrpmtDaFEiUj1osRP4TI2MDz1AddJL+jZ7KSqvBuliN4xqYY54IfdN8qD8Toa6g1iloph1fxQNkjOxrrpQ=="], + + "@eslint/eslintrc": ["@eslint/eslintrc@3.3.3", "", { "dependencies": { "ajv": "^6.12.4", "debug": "^4.3.2", "espree": "^10.0.1", "globals": "^14.0.0", "ignore": "^5.2.0", "import-fresh": "^3.2.1", "js-yaml": "^4.1.1", "minimatch": "^3.1.2", "strip-json-comments": "^3.1.1" } }, "sha512-Kr+LPIUVKz2qkx1HAMH8q1q6azbqBAsXJUxBl/ODDuVPX45Z9DfwB8tPjTi6nNZ8BuM3nbJxC5zCAg5elnBUTQ=="], + + "@eslint/js": ["@eslint/js@9.39.2", "", {}, "sha512-q1mjIoW1VX4IvSocvM/vbTiveKC4k9eLrajNEuSsmjymSDEbpGddtpfOoN7YGAqBK3NG+uqo8ia4PDTt8buCYA=="], + + "@eslint/object-schema": ["@eslint/object-schema@2.1.7", "", {}, "sha512-VtAOaymWVfZcmZbp6E2mympDIHvyjXs/12LqWYjVw6qjrfF+VK+fyG33kChz3nnK+SU5/NeHOqrTEHS8sXO3OA=="], + + "@eslint/plugin-kit": ["@eslint/plugin-kit@0.4.1", "", { "dependencies": { "@eslint/core": "^0.17.0", "levn": "^0.4.1" } }, "sha512-43/qtrDUokr7LJqoF2c3+RInu/t4zfrpYdoSDfYyhg52rwLV6TnOvdG4fXm7IkSB3wErkcmJS9iEhjVtOSEjjA=="], + + "@humanfs/core": ["@humanfs/core@0.19.1", "", {}, "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA=="], + + "@humanfs/node": ["@humanfs/node@0.16.7", "", { "dependencies": { "@humanfs/core": "^0.19.1", "@humanwhocodes/retry": "^0.4.0" } }, "sha512-/zUx+yOsIrG4Y43Eh2peDeKCxlRt/gET6aHfaKpuq267qXdYDFViVHfMaLyygZOnl0kGWxFIgsBy8QFuTLUXEQ=="], + + "@humanwhocodes/module-importer": ["@humanwhocodes/module-importer@1.0.1", "", {}, "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA=="], + + "@humanwhocodes/retry": ["@humanwhocodes/retry@0.4.3", "", {}, "sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ=="], + + "@inquirer/ansi": ["@inquirer/ansi@1.0.2", "", {}, "sha512-S8qNSZiYzFd0wAcyG5AXCvUHC5Sr7xpZ9wZ2py9XR88jUz8wooStVx5M6dRzczbBWjic9NP7+rY0Xi7qqK/aMQ=="], + + "@inquirer/checkbox": ["@inquirer/checkbox@4.3.2", "", { "dependencies": { "@inquirer/ansi": "^1.0.2", "@inquirer/core": "^10.3.2", "@inquirer/figures": "^1.0.15", "@inquirer/type": "^3.0.10", "yoctocolors-cjs": "^2.1.3" }, "peerDependencies": { "@types/node": ">=18" }, "optionalPeers": ["@types/node"] }, "sha512-VXukHf0RR1doGe6Sm4F0Em7SWYLTHSsbGfJdS9Ja2bX5/D5uwVOEjr07cncLROdBvmnvCATYEWlHqYmXv2IlQA=="], + + "@inquirer/confirm": ["@inquirer/confirm@5.1.21", "", { "dependencies": { "@inquirer/core": "^10.3.2", "@inquirer/type": "^3.0.10" }, "peerDependencies": { "@types/node": ">=18" }, "optionalPeers": ["@types/node"] }, "sha512-KR8edRkIsUayMXV+o3Gv+q4jlhENF9nMYUZs9PA2HzrXeHI8M5uDag70U7RJn9yyiMZSbtF5/UexBtAVtZGSbQ=="], + + "@inquirer/core": ["@inquirer/core@10.3.2", "", { "dependencies": { "@inquirer/ansi": "^1.0.2", "@inquirer/figures": "^1.0.15", "@inquirer/type": "^3.0.10", "cli-width": "^4.1.0", "mute-stream": "^2.0.0", "signal-exit": "^4.1.0", "wrap-ansi": "^6.2.0", "yoctocolors-cjs": "^2.1.3" }, "peerDependencies": { "@types/node": ">=18" }, "optionalPeers": ["@types/node"] }, "sha512-43RTuEbfP8MbKzedNqBrlhhNKVwoK//vUFNW3Q3vZ88BLcrs4kYpGg+B2mm5p2K/HfygoCxuKwJJiv8PbGmE0A=="], + + "@inquirer/editor": ["@inquirer/editor@4.2.23", "", { "dependencies": { "@inquirer/core": "^10.3.2", "@inquirer/external-editor": "^1.0.3", "@inquirer/type": "^3.0.10" }, "peerDependencies": { "@types/node": ">=18" }, "optionalPeers": ["@types/node"] }, "sha512-aLSROkEwirotxZ1pBaP8tugXRFCxW94gwrQLxXfrZsKkfjOYC1aRvAZuhpJOb5cu4IBTJdsCigUlf2iCOu4ZDQ=="], + + "@inquirer/expand": ["@inquirer/expand@4.0.23", "", { "dependencies": { "@inquirer/core": "^10.3.2", "@inquirer/type": "^3.0.10", "yoctocolors-cjs": "^2.1.3" }, "peerDependencies": { "@types/node": ">=18" }, "optionalPeers": ["@types/node"] }, "sha512-nRzdOyFYnpeYTTR2qFwEVmIWypzdAx/sIkCMeTNTcflFOovfqUk+HcFhQQVBftAh9gmGrpFj6QcGEqrDMDOiew=="], + + "@inquirer/external-editor": ["@inquirer/external-editor@1.0.3", "", { "dependencies": { "chardet": "^2.1.1", "iconv-lite": "^0.7.0" }, "peerDependencies": { "@types/node": ">=18" }, "optionalPeers": ["@types/node"] }, "sha512-RWbSrDiYmO4LbejWY7ttpxczuwQyZLBUyygsA9Nsv95hpzUWwnNTVQmAq3xuh7vNwCp07UTmE5i11XAEExx4RA=="], + + "@inquirer/figures": ["@inquirer/figures@1.0.15", "", {}, "sha512-t2IEY+unGHOzAaVM5Xx6DEWKeXlDDcNPeDyUpsRc6CUhBfU3VQOEl+Vssh7VNp1dR8MdUJBWhuObjXCsVpjN5g=="], + + "@inquirer/input": ["@inquirer/input@4.3.1", "", { "dependencies": { "@inquirer/core": "^10.3.2", "@inquirer/type": "^3.0.10" }, "peerDependencies": { "@types/node": ">=18" }, "optionalPeers": ["@types/node"] }, "sha512-kN0pAM4yPrLjJ1XJBjDxyfDduXOuQHrBB8aLDMueuwUGn+vNpF7Gq7TvyVxx8u4SHlFFj4trmj+a2cbpG4Jn1g=="], + + "@inquirer/number": ["@inquirer/number@3.0.23", "", { "dependencies": { "@inquirer/core": "^10.3.2", "@inquirer/type": "^3.0.10" }, "peerDependencies": { "@types/node": ">=18" }, "optionalPeers": ["@types/node"] }, "sha512-5Smv0OK7K0KUzUfYUXDXQc9jrf8OHo4ktlEayFlelCjwMXz0299Y8OrI+lj7i4gCBY15UObk76q0QtxjzFcFcg=="], + + "@inquirer/password": ["@inquirer/password@4.0.23", "", { "dependencies": { "@inquirer/ansi": "^1.0.2", "@inquirer/core": "^10.3.2", "@inquirer/type": "^3.0.10" }, "peerDependencies": { "@types/node": ">=18" }, "optionalPeers": ["@types/node"] }, "sha512-zREJHjhT5vJBMZX/IUbyI9zVtVfOLiTO66MrF/3GFZYZ7T4YILW5MSkEYHceSii/KtRk+4i3RE7E1CUXA2jHcA=="], + + "@inquirer/prompts": ["@inquirer/prompts@7.10.1", "", { "dependencies": { "@inquirer/checkbox": "^4.3.2", "@inquirer/confirm": "^5.1.21", "@inquirer/editor": "^4.2.23", "@inquirer/expand": "^4.0.23", "@inquirer/input": "^4.3.1", "@inquirer/number": "^3.0.23", "@inquirer/password": "^4.0.23", "@inquirer/rawlist": "^4.1.11", "@inquirer/search": "^3.2.2", "@inquirer/select": "^4.4.2" }, "peerDependencies": { "@types/node": ">=18" }, "optionalPeers": ["@types/node"] }, "sha512-Dx/y9bCQcXLI5ooQ5KyvA4FTgeo2jYj/7plWfV5Ak5wDPKQZgudKez2ixyfz7tKXzcJciTxqLeK7R9HItwiByg=="], + + "@inquirer/rawlist": ["@inquirer/rawlist@4.1.11", "", { "dependencies": { "@inquirer/core": "^10.3.2", "@inquirer/type": "^3.0.10", "yoctocolors-cjs": "^2.1.3" }, "peerDependencies": { "@types/node": ">=18" }, "optionalPeers": ["@types/node"] }, "sha512-+LLQB8XGr3I5LZN/GuAHo+GpDJegQwuPARLChlMICNdwW7OwV2izlCSCxN6cqpL0sMXmbKbFcItJgdQq5EBXTw=="], + + "@inquirer/search": ["@inquirer/search@3.2.2", "", { "dependencies": { "@inquirer/core": "^10.3.2", "@inquirer/figures": "^1.0.15", "@inquirer/type": "^3.0.10", "yoctocolors-cjs": "^2.1.3" }, "peerDependencies": { "@types/node": ">=18" }, "optionalPeers": ["@types/node"] }, "sha512-p2bvRfENXCZdWF/U2BXvnSI9h+tuA8iNqtUKb9UWbmLYCRQxd8WkvwWvYn+3NgYaNwdUkHytJMGG4MMLucI1kA=="], + + "@inquirer/select": ["@inquirer/select@4.4.2", "", { "dependencies": { "@inquirer/ansi": "^1.0.2", "@inquirer/core": "^10.3.2", "@inquirer/figures": "^1.0.15", "@inquirer/type": "^3.0.10", "yoctocolors-cjs": "^2.1.3" }, "peerDependencies": { "@types/node": ">=18" }, "optionalPeers": ["@types/node"] }, "sha512-l4xMuJo55MAe+N7Qr4rX90vypFwCajSakx59qe/tMaC1aEHWLyw68wF4o0A4SLAY4E0nd+Vt+EyskeDIqu1M6w=="], + + "@inquirer/type": ["@inquirer/type@3.0.10", "", { "peerDependencies": { "@types/node": ">=18" }, "optionalPeers": ["@types/node"] }, "sha512-BvziSRxfz5Ov8ch0z/n3oijRSEcEsHnhggm4xFZe93DHcUCTlutlq9Ox4SVENAfcRD22UQq7T/atg9Wr3k09eA=="], + + "@nodelib/fs.scandir": ["@nodelib/fs.scandir@2.1.5", "", { "dependencies": { "@nodelib/fs.stat": "2.0.5", "run-parallel": "^1.1.9" } }, "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g=="], + + "@nodelib/fs.stat": ["@nodelib/fs.stat@2.0.5", "", {}, "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A=="], + + "@nodelib/fs.walk": ["@nodelib/fs.walk@1.2.8", "", { "dependencies": { "@nodelib/fs.scandir": "2.1.5", "fastq": "^1.6.0" } }, "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg=="], + + "@types/bun": ["@types/bun@1.3.5", "", { "dependencies": { "bun-types": "1.3.5" } }, "sha512-RnygCqNrd3srIPEWBd5LFeUYG7plCoH2Yw9WaZGyNmdTEei+gWaHqydbaIRkIkcbXwhBT94q78QljxN0Sk838w=="], + + "@types/estree": ["@types/estree@1.0.8", "", {}, "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w=="], + + "@types/json-schema": ["@types/json-schema@7.0.15", "", {}, "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA=="], + + "@types/node": ["@types/node@25.0.3", "", { "dependencies": { "undici-types": "~7.16.0" } }, "sha512-W609buLVRVmeW693xKfzHeIV6nJGGz98uCPfeXI1ELMLXVeKYZ9m15fAMSaUPBHYLGFsVRcMmSCksQOrZV9BYA=="], + + "@typescript-eslint/eslint-plugin": ["@typescript-eslint/eslint-plugin@8.50.1", "", { "dependencies": { "@eslint-community/regexpp": "^4.10.0", "@typescript-eslint/scope-manager": "8.50.1", "@typescript-eslint/type-utils": "8.50.1", "@typescript-eslint/utils": "8.50.1", "@typescript-eslint/visitor-keys": "8.50.1", "ignore": "^7.0.0", "natural-compare": "^1.4.0", "ts-api-utils": "^2.1.0" }, "peerDependencies": { "@typescript-eslint/parser": "^8.50.1", "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "sha512-PKhLGDq3JAg0Jk/aK890knnqduuI/Qj+udH7wCf0217IGi4gt+acgCyPVe79qoT+qKUvHMDQkwJeKW9fwl8Cyw=="], + + "@typescript-eslint/parser": ["@typescript-eslint/parser@8.50.1", "", { "dependencies": { "@typescript-eslint/scope-manager": "8.50.1", "@typescript-eslint/types": "8.50.1", "@typescript-eslint/typescript-estree": "8.50.1", "@typescript-eslint/visitor-keys": "8.50.1", "debug": "^4.3.4" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "sha512-hM5faZwg7aVNa819m/5r7D0h0c9yC4DUlWAOvHAtISdFTc8xB86VmX5Xqabrama3wIPJ/q9RbGS1worb6JfnMg=="], + + "@typescript-eslint/project-service": ["@typescript-eslint/project-service@8.50.1", "", { "dependencies": { "@typescript-eslint/tsconfig-utils": "^8.50.1", "@typescript-eslint/types": "^8.50.1", "debug": "^4.3.4" }, "peerDependencies": { "typescript": ">=4.8.4 <6.0.0" } }, "sha512-E1ur1MCVf+YiP89+o4Les/oBAVzmSbeRB0MQLfSlYtbWU17HPxZ6Bhs5iYmKZRALvEuBoXIZMOIRRc/P++Ortg=="], + + "@typescript-eslint/scope-manager": ["@typescript-eslint/scope-manager@8.50.1", "", { "dependencies": { "@typescript-eslint/types": "8.50.1", "@typescript-eslint/visitor-keys": "8.50.1" } }, "sha512-mfRx06Myt3T4vuoHaKi8ZWNTPdzKPNBhiblze5N50//TSHOAQQevl/aolqA/BcqqbJ88GUnLqjjcBc8EWdBcVw=="], + + "@typescript-eslint/tsconfig-utils": ["@typescript-eslint/tsconfig-utils@8.50.1", "", { "peerDependencies": { "typescript": ">=4.8.4 <6.0.0" } }, "sha512-ooHmotT/lCWLXi55G4mvaUF60aJa012QzvLK0Y+Mp4WdSt17QhMhWOaBWeGTFVkb2gDgBe19Cxy1elPXylslDw=="], + + "@typescript-eslint/type-utils": ["@typescript-eslint/type-utils@8.50.1", "", { "dependencies": { "@typescript-eslint/types": "8.50.1", "@typescript-eslint/typescript-estree": "8.50.1", "@typescript-eslint/utils": "8.50.1", "debug": "^4.3.4", "ts-api-utils": "^2.1.0" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "sha512-7J3bf022QZE42tYMO6SL+6lTPKFk/WphhRPe9Tw/el+cEwzLz1Jjz2PX3GtGQVxooLDKeMVmMt7fWpYRdG5Etg=="], + + "@typescript-eslint/types": ["@typescript-eslint/types@8.50.1", "", {}, "sha512-v5lFIS2feTkNyMhd7AucE/9j/4V9v5iIbpVRncjk/K0sQ6Sb+Np9fgYS/63n6nwqahHQvbmujeBL7mp07Q9mlA=="], + + "@typescript-eslint/typescript-estree": ["@typescript-eslint/typescript-estree@8.50.1", "", { "dependencies": { "@typescript-eslint/project-service": "8.50.1", "@typescript-eslint/tsconfig-utils": "8.50.1", "@typescript-eslint/types": "8.50.1", "@typescript-eslint/visitor-keys": "8.50.1", "debug": "^4.3.4", "minimatch": "^9.0.4", "semver": "^7.6.0", "tinyglobby": "^0.2.15", "ts-api-utils": "^2.1.0" }, "peerDependencies": { "typescript": ">=4.8.4 <6.0.0" } }, "sha512-woHPdW+0gj53aM+cxchymJCrh0cyS7BTIdcDxWUNsclr9VDkOSbqC13juHzxOmQ22dDkMZEpZB+3X1WpUvzgVQ=="], + + "@typescript-eslint/utils": ["@typescript-eslint/utils@8.50.1", "", { "dependencies": { "@eslint-community/eslint-utils": "^4.7.0", "@typescript-eslint/scope-manager": "8.50.1", "@typescript-eslint/types": "8.50.1", "@typescript-eslint/typescript-estree": "8.50.1" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "sha512-lCLp8H1T9T7gPbEuJSnHwnSuO9mDf8mfK/Nion5mZmiEaQD9sWf9W4dfeFqRyqRjF06/kBuTmAqcs9sewM2NbQ=="], + + "@typescript-eslint/visitor-keys": ["@typescript-eslint/visitor-keys@8.50.1", "", { "dependencies": { "@typescript-eslint/types": "8.50.1", "eslint-visitor-keys": "^4.2.1" } }, "sha512-IrDKrw7pCRUR94zeuCSUWQ+w8JEf5ZX5jl/e6AHGSLi1/zIr0lgutfn/7JpfCey+urpgQEdrZVYzCaVVKiTwhQ=="], + + "acorn": ["acorn@8.15.0", "", { "bin": { "acorn": "bin/acorn" } }, "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg=="], + + "acorn-jsx": ["acorn-jsx@5.3.2", "", { "peerDependencies": { "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ=="], + + "ajv": ["ajv@6.12.6", "", { "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", "json-schema-traverse": "^0.4.1", "uri-js": "^4.2.2" } }, "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g=="], + + "ansi-regex": ["ansi-regex@6.2.2", "", {}, "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg=="], + + "ansi-styles": ["ansi-styles@4.3.0", "", { "dependencies": { "color-convert": "^2.0.1" } }, "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg=="], + + "argparse": ["argparse@2.0.1", "", {}, "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q=="], + + "balanced-match": ["balanced-match@1.0.2", "", {}, "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="], + + "brace-expansion": ["brace-expansion@1.1.12", "", { "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg=="], + + "braces": ["braces@3.0.3", "", { "dependencies": { "fill-range": "^7.1.1" } }, "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA=="], + + "bun-types": ["bun-types@1.3.5", "", { "dependencies": { "@types/node": "*" } }, "sha512-inmAYe2PFLs0SUbFOWSVD24sg1jFlMPxOjOSSCYqUgn4Hsc3rDc7dFvfVYjFPNHtov6kgUeulV4SxbuIV/stPw=="], + + "callsites": ["callsites@3.1.0", "", {}, "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ=="], + + "chalk": ["chalk@5.6.2", "", {}, "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA=="], + + "chardet": ["chardet@2.1.1", "", {}, "sha512-PsezH1rqdV9VvyNhxxOW32/d75r01NY7TQCmOqomRo15ZSOKbpTFVsfjghxo6JloQUCGnH4k1LGu0R4yCLlWQQ=="], + + "cli-cursor": ["cli-cursor@5.0.0", "", { "dependencies": { "restore-cursor": "^5.0.0" } }, "sha512-aCj4O5wKyszjMmDT4tZj93kxyydN/K5zPWSCe6/0AV/AA1pqe5ZBIw0a2ZfPQV7lL5/yb5HsUreJ6UFAF1tEQw=="], + + "cli-spinners": ["cli-spinners@2.9.2", "", {}, "sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg=="], + + "cli-width": ["cli-width@4.1.0", "", {}, "sha512-ouuZd4/dm2Sw5Gmqy6bGyNNNe1qt9RpmxveLSO7KcgsTnU7RXfsw+/bukWGo1abgBiMAic068rclZsO4IWmmxQ=="], + + "color-convert": ["color-convert@2.0.1", "", { "dependencies": { "color-name": "~1.1.4" } }, "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ=="], + + "color-name": ["color-name@1.1.4", "", {}, "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="], + + "commander": ["commander@14.0.2", "", {}, "sha512-TywoWNNRbhoD0BXs1P3ZEScW8W5iKrnbithIl0YH+uCmBd0QpPOA8yc82DS3BIE5Ma6FnBVUsJ7wVUDz4dvOWQ=="], + + "concat-map": ["concat-map@0.0.1", "", {}, "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg=="], + + "cross-spawn": ["cross-spawn@7.0.6", "", { "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", "which": "^2.0.1" } }, "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA=="], + + "debug": ["debug@4.4.3", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA=="], + + "deep-is": ["deep-is@0.1.4", "", {}, "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ=="], + + "emoji-regex": ["emoji-regex@10.6.0", "", {}, "sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A=="], + + "escape-string-regexp": ["escape-string-regexp@4.0.0", "", {}, "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA=="], + + "eslint": ["eslint@9.39.2", "", { "dependencies": { "@eslint-community/eslint-utils": "^4.8.0", "@eslint-community/regexpp": "^4.12.1", "@eslint/config-array": "^0.21.1", "@eslint/config-helpers": "^0.4.2", "@eslint/core": "^0.17.0", "@eslint/eslintrc": "^3.3.1", "@eslint/js": "9.39.2", "@eslint/plugin-kit": "^0.4.1", "@humanfs/node": "^0.16.6", "@humanwhocodes/module-importer": "^1.0.1", "@humanwhocodes/retry": "^0.4.2", "@types/estree": "^1.0.6", "ajv": "^6.12.4", "chalk": "^4.0.0", "cross-spawn": "^7.0.6", "debug": "^4.3.2", "escape-string-regexp": "^4.0.0", "eslint-scope": "^8.4.0", "eslint-visitor-keys": "^4.2.1", "espree": "^10.4.0", "esquery": "^1.5.0", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", "file-entry-cache": "^8.0.0", "find-up": "^5.0.0", "glob-parent": "^6.0.2", "ignore": "^5.2.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", "json-stable-stringify-without-jsonify": "^1.0.1", "lodash.merge": "^4.6.2", "minimatch": "^3.1.2", "natural-compare": "^1.4.0", "optionator": "^0.9.3" }, "peerDependencies": { "jiti": "*" }, "optionalPeers": ["jiti"], "bin": { "eslint": "bin/eslint.js" } }, "sha512-LEyamqS7W5HB3ujJyvi0HQK/dtVINZvd5mAAp9eT5S/ujByGjiZLCzPcHVzuXbpJDJF/cxwHlfceVUDZ2lnSTw=="], + + "eslint-scope": ["eslint-scope@8.4.0", "", { "dependencies": { "esrecurse": "^4.3.0", "estraverse": "^5.2.0" } }, "sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg=="], + + "eslint-visitor-keys": ["eslint-visitor-keys@4.2.1", "", {}, "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ=="], + + "espree": ["espree@10.4.0", "", { "dependencies": { "acorn": "^8.15.0", "acorn-jsx": "^5.3.2", "eslint-visitor-keys": "^4.2.1" } }, "sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ=="], + + "esquery": ["esquery@1.6.0", "", { "dependencies": { "estraverse": "^5.1.0" } }, "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg=="], + + "esrecurse": ["esrecurse@4.3.0", "", { "dependencies": { "estraverse": "^5.2.0" } }, "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag=="], + + "estraverse": ["estraverse@5.3.0", "", {}, "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA=="], + + "esutils": ["esutils@2.0.3", "", {}, "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g=="], + + "fast-deep-equal": ["fast-deep-equal@3.1.3", "", {}, "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q=="], + + "fast-glob": ["fast-glob@3.3.3", "", { "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" } }, "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg=="], + + "fast-json-stable-stringify": ["fast-json-stable-stringify@2.1.0", "", {}, "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw=="], + + "fast-levenshtein": ["fast-levenshtein@2.0.6", "", {}, "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw=="], + + "fastq": ["fastq@1.20.1", "", { "dependencies": { "reusify": "^1.0.4" } }, "sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw=="], + + "fdir": ["fdir@6.5.0", "", { "peerDependencies": { "picomatch": "^3 || ^4" }, "optionalPeers": ["picomatch"] }, "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg=="], + + "file-entry-cache": ["file-entry-cache@8.0.0", "", { "dependencies": { "flat-cache": "^4.0.0" } }, "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ=="], + + "fill-range": ["fill-range@7.1.1", "", { "dependencies": { "to-regex-range": "^5.0.1" } }, "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg=="], + + "find-up": ["find-up@5.0.0", "", { "dependencies": { "locate-path": "^6.0.0", "path-exists": "^4.0.0" } }, "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng=="], + + "flat-cache": ["flat-cache@4.0.1", "", { "dependencies": { "flatted": "^3.2.9", "keyv": "^4.5.4" } }, "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw=="], + + "flatted": ["flatted@3.3.3", "", {}, "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg=="], + + "get-east-asian-width": ["get-east-asian-width@1.4.0", "", {}, "sha512-QZjmEOC+IT1uk6Rx0sX22V6uHWVwbdbxf1faPqJ1QhLdGgsRGCZoyaQBm/piRdJy/D2um6hM1UP7ZEeQ4EkP+Q=="], + + "glob-parent": ["glob-parent@6.0.2", "", { "dependencies": { "is-glob": "^4.0.3" } }, "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A=="], + + "globals": ["globals@14.0.0", "", {}, "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ=="], + + "has-flag": ["has-flag@4.0.0", "", {}, "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ=="], + + "iconv-lite": ["iconv-lite@0.7.1", "", { "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" } }, "sha512-2Tth85cXwGFHfvRgZWszZSvdo+0Xsqmw8k8ZwxScfcBneNUraK+dxRxRm24nszx80Y0TVio8kKLt5sLE7ZCLlw=="], + + "ignore": ["ignore@5.3.2", "", {}, "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g=="], + + "import-fresh": ["import-fresh@3.3.1", "", { "dependencies": { "parent-module": "^1.0.0", "resolve-from": "^4.0.0" } }, "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ=="], + + "imurmurhash": ["imurmurhash@0.1.4", "", {}, "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA=="], + + "is-extglob": ["is-extglob@2.1.1", "", {}, "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ=="], + + "is-fullwidth-code-point": ["is-fullwidth-code-point@3.0.0", "", {}, "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg=="], + + "is-glob": ["is-glob@4.0.3", "", { "dependencies": { "is-extglob": "^2.1.1" } }, "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg=="], + + "is-interactive": ["is-interactive@2.0.0", "", {}, "sha512-qP1vozQRI+BMOPcjFzrjXuQvdak2pHNUMZoeG2eRbiSqyvbEf/wQtEOTOX1guk6E3t36RkaqiSt8A/6YElNxLQ=="], + + "is-number": ["is-number@7.0.0", "", {}, "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng=="], + + "is-unicode-supported": ["is-unicode-supported@2.1.0", "", {}, "sha512-mE00Gnza5EEB3Ds0HfMyllZzbBrmLOX3vfWoj9A9PEnTfratQ/BcaJOuMhnkhjXvb2+FkY3VuHqtAGpTPmglFQ=="], + + "isexe": ["isexe@2.0.0", "", {}, "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw=="], + + "jiti": ["jiti@2.6.1", "", { "bin": { "jiti": "lib/jiti-cli.mjs" } }, "sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ=="], + + "js-yaml": ["js-yaml@4.1.1", "", { "dependencies": { "argparse": "^2.0.1" }, "bin": { "js-yaml": "bin/js-yaml.js" } }, "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA=="], + + "json-buffer": ["json-buffer@3.0.1", "", {}, "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ=="], + + "json-schema-traverse": ["json-schema-traverse@0.4.1", "", {}, "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg=="], + + "json-stable-stringify-without-jsonify": ["json-stable-stringify-without-jsonify@1.0.1", "", {}, "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw=="], + + "keyv": ["keyv@4.5.4", "", { "dependencies": { "json-buffer": "3.0.1" } }, "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw=="], + + "levn": ["levn@0.4.1", "", { "dependencies": { "prelude-ls": "^1.2.1", "type-check": "~0.4.0" } }, "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ=="], + + "locate-path": ["locate-path@6.0.0", "", { "dependencies": { "p-locate": "^5.0.0" } }, "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw=="], + + "lodash.merge": ["lodash.merge@4.6.2", "", {}, "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ=="], + + "log-symbols": ["log-symbols@6.0.0", "", { "dependencies": { "chalk": "^5.3.0", "is-unicode-supported": "^1.3.0" } }, "sha512-i24m8rpwhmPIS4zscNzK6MSEhk0DUWa/8iYQWxhffV8jkI4Phvs3F+quL5xvS0gdQR0FyTCMMH33Y78dDTzzIw=="], + + "merge2": ["merge2@1.4.1", "", {}, "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg=="], + + "micromatch": ["micromatch@4.0.8", "", { "dependencies": { "braces": "^3.0.3", "picomatch": "^2.3.1" } }, "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA=="], + + "mimic-function": ["mimic-function@5.0.1", "", {}, "sha512-VP79XUPxV2CigYP3jWwAUFSku2aKqBH7uTAapFWCBqutsbmDo96KY5o8uh6U+/YSIn5OxJnXp73beVkpqMIGhA=="], + + "minimatch": ["minimatch@3.1.2", "", { "dependencies": { "brace-expansion": "^1.1.7" } }, "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw=="], + + "ms": ["ms@2.1.3", "", {}, "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="], + + "mute-stream": ["mute-stream@2.0.0", "", {}, "sha512-WWdIxpyjEn+FhQJQQv9aQAYlHoNVdzIzUySNV1gHUPDSdZJ3yZn7pAAbQcV7B56Mvu881q9FZV+0Vx2xC44VWA=="], + + "natural-compare": ["natural-compare@1.4.0", "", {}, "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw=="], + + "onetime": ["onetime@7.0.0", "", { "dependencies": { "mimic-function": "^5.0.0" } }, "sha512-VXJjc87FScF88uafS3JllDgvAm+c/Slfz06lorj2uAY34rlUu0Nt+v8wreiImcrgAjjIHp1rXpTDlLOGw29WwQ=="], + + "optionator": ["optionator@0.9.4", "", { "dependencies": { "deep-is": "^0.1.3", "fast-levenshtein": "^2.0.6", "levn": "^0.4.1", "prelude-ls": "^1.2.1", "type-check": "^0.4.0", "word-wrap": "^1.2.5" } }, "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g=="], + + "ora": ["ora@8.2.0", "", { "dependencies": { "chalk": "^5.3.0", "cli-cursor": "^5.0.0", "cli-spinners": "^2.9.2", "is-interactive": "^2.0.0", "is-unicode-supported": "^2.0.0", "log-symbols": "^6.0.0", "stdin-discarder": "^0.2.2", "string-width": "^7.2.0", "strip-ansi": "^7.1.0" } }, "sha512-weP+BZ8MVNnlCm8c0Qdc1WSWq4Qn7I+9CJGm7Qali6g44e/PUzbjNqJX5NJ9ljlNMosfJvg1fKEGILklK9cwnw=="], + + "p-limit": ["p-limit@3.1.0", "", { "dependencies": { "yocto-queue": "^0.1.0" } }, "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ=="], + + "p-locate": ["p-locate@5.0.0", "", { "dependencies": { "p-limit": "^3.0.2" } }, "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw=="], + + "parent-module": ["parent-module@1.0.1", "", { "dependencies": { "callsites": "^3.0.0" } }, "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g=="], + + "path-exists": ["path-exists@4.0.0", "", {}, "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w=="], + + "path-key": ["path-key@3.1.1", "", {}, "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q=="], + + "picomatch": ["picomatch@2.3.1", "", {}, "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="], + + "prelude-ls": ["prelude-ls@1.2.1", "", {}, "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g=="], + + "punycode": ["punycode@2.3.1", "", {}, "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg=="], + + "queue-microtask": ["queue-microtask@1.2.3", "", {}, "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A=="], + + "resolve-from": ["resolve-from@4.0.0", "", {}, "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g=="], + + "restore-cursor": ["restore-cursor@5.1.0", "", { "dependencies": { "onetime": "^7.0.0", "signal-exit": "^4.1.0" } }, "sha512-oMA2dcrw6u0YfxJQXm342bFKX/E4sG9rbTzO9ptUcR/e8A33cHuvStiYOwH7fszkZlZ1z/ta9AAoPk2F4qIOHA=="], + + "reusify": ["reusify@1.1.0", "", {}, "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw=="], + + "run-parallel": ["run-parallel@1.2.0", "", { "dependencies": { "queue-microtask": "^1.2.2" } }, "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA=="], + + "safer-buffer": ["safer-buffer@2.1.2", "", {}, "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="], + + "semver": ["semver@7.7.3", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q=="], + + "shebang-command": ["shebang-command@2.0.0", "", { "dependencies": { "shebang-regex": "^3.0.0" } }, "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA=="], + + "shebang-regex": ["shebang-regex@3.0.0", "", {}, "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A=="], + + "signal-exit": ["signal-exit@4.1.0", "", {}, "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw=="], + + "stdin-discarder": ["stdin-discarder@0.2.2", "", {}, "sha512-UhDfHmA92YAlNnCfhmq0VeNL5bDbiZGg7sZ2IvPsXubGkiNa9EC+tUTsjBRsYUAz87btI6/1wf4XoVvQ3uRnmQ=="], + + "string-width": ["string-width@7.2.0", "", { "dependencies": { "emoji-regex": "^10.3.0", "get-east-asian-width": "^1.0.0", "strip-ansi": "^7.1.0" } }, "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ=="], + + "strip-ansi": ["strip-ansi@7.1.2", "", { "dependencies": { "ansi-regex": "^6.0.1" } }, "sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA=="], + + "strip-json-comments": ["strip-json-comments@3.1.1", "", {}, "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig=="], + + "supports-color": ["supports-color@7.2.0", "", { "dependencies": { "has-flag": "^4.0.0" } }, "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw=="], + + "tinyglobby": ["tinyglobby@0.2.15", "", { "dependencies": { "fdir": "^6.5.0", "picomatch": "^4.0.3" } }, "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ=="], + + "to-regex-range": ["to-regex-range@5.0.1", "", { "dependencies": { "is-number": "^7.0.0" } }, "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ=="], + + "ts-api-utils": ["ts-api-utils@2.2.0", "", { "peerDependencies": { "typescript": ">=4.8.4" } }, "sha512-L6f5oQRAoLU1RwXz0Ab9mxsE7LtxeVB6AIR1lpkZMsOyg/JXeaxBaXa/FVCBZyNr9S9I4wkHrlZTklX+im+WMw=="], + + "type-check": ["type-check@0.4.0", "", { "dependencies": { "prelude-ls": "^1.2.1" } }, "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew=="], + + "typescript": ["typescript@5.9.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw=="], + + "typescript-eslint": ["typescript-eslint@8.50.1", "", { "dependencies": { "@typescript-eslint/eslint-plugin": "8.50.1", "@typescript-eslint/parser": "8.50.1", "@typescript-eslint/typescript-estree": "8.50.1", "@typescript-eslint/utils": "8.50.1" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "sha512-ytTHO+SoYSbhAH9CrYnMhiLx8To6PSSvqnvXyPUgPETCvB6eBKmTI9w6XMPS3HsBRGkwTVBX+urA8dYQx6bHfQ=="], + + "undici-types": ["undici-types@7.16.0", "", {}, "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw=="], + + "uri-js": ["uri-js@4.4.1", "", { "dependencies": { "punycode": "^2.1.0" } }, "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg=="], + + "which": ["which@2.0.2", "", { "dependencies": { "isexe": "^2.0.0" }, "bin": { "node-which": "./bin/node-which" } }, "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA=="], + + "word-wrap": ["word-wrap@1.2.5", "", {}, "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA=="], + + "wrap-ansi": ["wrap-ansi@6.2.0", "", { "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", "strip-ansi": "^6.0.0" } }, "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA=="], + + "yaml": ["yaml@2.8.2", "", { "bin": { "yaml": "bin.mjs" } }, "sha512-mplynKqc1C2hTVYxd0PU2xQAc22TI1vShAYGksCCfxbn/dFwnHTNi1bvYsBTkhdUNtGIf5xNOg938rrSSYvS9A=="], + + "yocto-queue": ["yocto-queue@0.1.0", "", {}, "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q=="], + + "yoctocolors-cjs": ["yoctocolors-cjs@2.1.3", "", {}, "sha512-U/PBtDf35ff0D8X8D0jfdzHYEPFxAI7jJlxZXwCSez5M3190m+QobIfh+sWDWSHMCWWJN2AWamkegn6vr6YBTw=="], + + "zod": ["zod@4.2.1", "", {}, "sha512-0wZ1IRqGGhMP76gLqz8EyfBXKk0J2qo2+H3fi4mcUP/KtTocoX08nmIAHl1Z2kJIZbZee8KOpBCSNPRgauucjw=="], + + "@eslint-community/eslint-utils/eslint-visitor-keys": ["eslint-visitor-keys@3.4.3", "", {}, "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag=="], + + "@typescript-eslint/eslint-plugin/ignore": ["ignore@7.0.5", "", {}, "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg=="], + + "@typescript-eslint/typescript-estree/minimatch": ["minimatch@9.0.5", "", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow=="], + + "eslint/chalk": ["chalk@4.1.2", "", { "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } }, "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA=="], + + "fast-glob/glob-parent": ["glob-parent@5.1.2", "", { "dependencies": { "is-glob": "^4.0.1" } }, "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow=="], + + "log-symbols/is-unicode-supported": ["is-unicode-supported@1.3.0", "", {}, "sha512-43r2mRvz+8JRIKnWJ+3j8JtjRKZ6GmjzfaE/qiBJnikNnYv/6bagRJ1kUhNk8R5EX/GkobD+r+sfxCPJsiKBLQ=="], + + "tinyglobby/picomatch": ["picomatch@4.0.3", "", {}, "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q=="], + + "wrap-ansi/string-width": ["string-width@4.2.3", "", { "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.1" } }, "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g=="], + + "wrap-ansi/strip-ansi": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="], + + "@typescript-eslint/typescript-estree/minimatch/brace-expansion": ["brace-expansion@2.0.2", "", { "dependencies": { "balanced-match": "^1.0.0" } }, "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ=="], + + "wrap-ansi/string-width/emoji-regex": ["emoji-regex@8.0.0", "", {}, "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="], + + "wrap-ansi/strip-ansi/ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="], + } +} diff --git a/eslint.config.js b/eslint.config.ts similarity index 56% rename from eslint.config.js rename to eslint.config.ts index b5437a91f..08b789a6c 100644 --- a/eslint.config.js +++ b/eslint.config.ts @@ -5,10 +5,6 @@ export default tseslint.config( files: ['src/**/*.ts'], extends: [...tseslint.configs.recommended], rules: { - // Prevent static imports of @inquirer modules to avoid pre-commit hook hangs. - // These modules have side effects that can keep the Node.js event loop alive - // when stdin is piped. Use dynamic import() instead. - // See: https://github.com/Fission-AI/OpenSpec/issues/367 'no-restricted-imports': [ 'error', { @@ -21,7 +17,6 @@ export default tseslint.config( ], }, ], - // Disable rules that need broader cleanup - focus on critical issues only '@typescript-eslint/no-explicit-any': 'off', '@typescript-eslint/no-unused-vars': 'off', 'no-empty': 'off', @@ -29,14 +24,12 @@ export default tseslint.config( }, }, { - // init.ts is dynamically imported from cli/index.ts, so static @inquirer - // imports there are safe - they won't be loaded at CLI startup files: ['src/core/init.ts'], rules: { 'no-restricted-imports': 'off', }, }, { - ignores: ['dist/**', 'node_modules/**', '*.js', '*.mjs'], + ignores: ['dist/**', 'node_modules/**'], } ); diff --git a/package.json b/package.json index 0c7c915e4..9beecf8f8 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { - "name": "@fission-ai/openspec", - "version": "0.17.2", + "name": "@clanker-guru/openspec", + "version": "0.0.1-alpha.1", "description": "AI-native system for spec-driven development", "keywords": [ "openspec", @@ -9,10 +9,10 @@ "ai", "development" ], - "homepage": "https://github.com/Fission-AI/OpenSpec", + "homepage": "https://github.com/clanker-guru/OpenSpec", "repository": { "type": "git", - "url": "https://github.com/Fission-AI/OpenSpec" + "url": "https://github.com/clanker-guru/OpenSpec" }, "license": "MIT", "author": "OpenSpec Contributors", @@ -27,46 +27,37 @@ } }, "bin": { - "openspec": "./bin/openspec.js" + "openspec": "./bin/openspec.ts" }, "files": [ "dist", "bin", - "scripts/postinstall.js", + "scripts/postinstall.ts", "!dist/**/*.test.js", "!dist/**/__tests__", "!dist/**/*.map" ], "scripts": { "lint": "eslint src/", - "build": "node build.js", + "build": "bun build.ts", "dev": "tsc --watch", - "dev:cli": "pnpm build && node bin/openspec.js", - "test": "vitest run", - "test:watch": "vitest", - "test:ui": "vitest --ui", - "test:coverage": "vitest --coverage", - "test:postinstall": "node scripts/postinstall.js", - "prepare": "pnpm run build", - "prepublishOnly": "pnpm run build", - "postinstall": "node scripts/postinstall.js", - "check:pack-version": "node scripts/pack-version-check.mjs", - "release": "pnpm run release:ci", - "release:ci": "pnpm run check:pack-version && pnpm exec changeset publish", - "release:local": "pnpm exec changeset version && pnpm run check:pack-version && pnpm exec changeset publish", - "changeset": "changeset" - }, - "engines": { - "node": ">=20.19.0" + "dev:cli": "bun run build && bun bin/openspec.js", + "test": "bun test", + "test:watch": "bun test --watch", + "test:coverage": "bun test --coverage", + "test:postinstall": "bun scripts/postinstall.ts", + "prepare": "bun run build", + "prepublishOnly": "bun run build", + "postinstall": "bun scripts/postinstall.ts", + "check:pack-version": "bun scripts/pack-version-check.ts", + "typecheck": "tsc --noEmit" }, "devDependencies": { - "@changesets/cli": "^2.27.7", - "@types/node": "^24.2.0", - "@vitest/ui": "^3.2.4", + "@types/bun": "^1.2.7", "eslint": "^9.39.2", + "jiti": "^2.6.1", "typescript": "^5.9.3", - "typescript-eslint": "^8.50.1", - "vitest": "^3.2.4" + "typescript-eslint": "^8.50.1" }, "dependencies": { "@inquirer/core": "^10.2.2", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml deleted file mode 100644 index 032d0d88d..000000000 --- a/pnpm-lock.yaml +++ /dev/null @@ -1,3100 +0,0 @@ -lockfileVersion: '9.0' - -settings: - autoInstallPeers: true - excludeLinksFromLockfile: false - -importers: - - .: - dependencies: - '@inquirer/core': - specifier: ^10.2.2 - version: 10.2.2(@types/node@24.2.0) - '@inquirer/prompts': - specifier: ^7.8.0 - version: 7.8.0(@types/node@24.2.0) - chalk: - specifier: ^5.5.0 - version: 5.5.0 - commander: - specifier: ^14.0.0 - version: 14.0.0 - fast-glob: - specifier: ^3.3.3 - version: 3.3.3 - ora: - specifier: ^8.2.0 - version: 8.2.0 - yaml: - specifier: ^2.8.2 - version: 2.8.2 - zod: - specifier: ^4.0.17 - version: 4.0.17 - devDependencies: - '@changesets/cli': - specifier: ^2.27.7 - version: 2.29.6(@types/node@24.2.0) - '@types/node': - specifier: ^24.2.0 - version: 24.2.0 - '@vitest/ui': - specifier: ^3.2.4 - version: 3.2.4(vitest@3.2.4) - eslint: - specifier: ^9.39.2 - version: 9.39.2 - typescript: - specifier: ^5.9.3 - version: 5.9.3 - typescript-eslint: - specifier: ^8.50.1 - version: 8.50.1(eslint@9.39.2)(typescript@5.9.3) - vitest: - specifier: ^3.2.4 - version: 3.2.4(@types/node@24.2.0)(@vitest/ui@3.2.4)(yaml@2.8.2) - -packages: - - '@babel/runtime@7.28.4': - resolution: {integrity: sha512-Q/N6JNWvIvPnLDvjlE1OUBLPQHH6l3CltCEsHIujp45zQUSSh8K+gHnaEX45yAT1nyngnINhvWtzN+Nb9D8RAQ==} - engines: {node: '>=6.9.0'} - - '@changesets/apply-release-plan@7.0.12': - resolution: {integrity: sha512-EaET7As5CeuhTzvXTQCRZeBUcisoYPDDcXvgTE/2jmmypKp0RC7LxKj/yzqeh/1qFTZI7oDGFcL1PHRuQuketQ==} - - '@changesets/assemble-release-plan@6.0.9': - resolution: {integrity: sha512-tPgeeqCHIwNo8sypKlS3gOPmsS3wP0zHt67JDuL20P4QcXiw/O4Hl7oXiuLnP9yg+rXLQ2sScdV1Kkzde61iSQ==} - - '@changesets/changelog-git@0.2.1': - resolution: {integrity: sha512-x/xEleCFLH28c3bQeQIyeZf8lFXyDFVn1SgcBiR2Tw/r4IAWlk1fzxCEZ6NxQAjF2Nwtczoen3OA2qR+UawQ8Q==} - - '@changesets/cli@2.29.6': - resolution: {integrity: sha512-6qCcVsIG1KQLhpQ5zE8N0PckIx4+9QlHK3z6/lwKnw7Tir71Bjw8BeOZaxA/4Jt00pcgCnCSWZnyuZf5Il05QQ==} - hasBin: true - - '@changesets/config@3.1.1': - resolution: {integrity: sha512-bd+3Ap2TKXxljCggI0mKPfzCQKeV/TU4yO2h2C6vAihIo8tzseAn2e7klSuiyYYXvgu53zMN1OeYMIQkaQoWnA==} - - '@changesets/errors@0.2.0': - resolution: {integrity: sha512-6BLOQUscTpZeGljvyQXlWOItQyU71kCdGz7Pi8H8zdw6BI0g3m43iL4xKUVPWtG+qrrL9DTjpdn8eYuCQSRpow==} - - '@changesets/get-dependents-graph@2.1.3': - resolution: {integrity: sha512-gphr+v0mv2I3Oxt19VdWRRUxq3sseyUpX9DaHpTUmLj92Y10AGy+XOtV+kbM6L/fDcpx7/ISDFK6T8A/P3lOdQ==} - - '@changesets/get-release-plan@4.0.13': - resolution: {integrity: sha512-DWG1pus72FcNeXkM12tx+xtExyH/c9I1z+2aXlObH3i9YA7+WZEVaiHzHl03thpvAgWTRaH64MpfHxozfF7Dvg==} - - '@changesets/get-version-range-type@0.4.0': - resolution: {integrity: sha512-hwawtob9DryoGTpixy1D3ZXbGgJu1Rhr+ySH2PvTLHvkZuQ7sRT4oQwMh0hbqZH1weAooedEjRsbrWcGLCeyVQ==} - - '@changesets/git@3.0.4': - resolution: {integrity: sha512-BXANzRFkX+XcC1q/d27NKvlJ1yf7PSAgi8JG6dt8EfbHFHi4neau7mufcSca5zRhwOL8j9s6EqsxmT+s+/E6Sw==} - - '@changesets/logger@0.1.1': - resolution: {integrity: sha512-OQtR36ZlnuTxKqoW4Sv6x5YIhOmClRd5pWsjZsddYxpWs517R0HkyiefQPIytCVh4ZcC5x9XaG8KTdd5iRQUfg==} - - '@changesets/parse@0.4.1': - resolution: {integrity: sha512-iwksMs5Bf/wUItfcg+OXrEpravm5rEd9Bf4oyIPL4kVTmJQ7PNDSd6MDYkpSJR1pn7tz/k8Zf2DhTCqX08Ou+Q==} - - '@changesets/pre@2.0.2': - resolution: {integrity: sha512-HaL/gEyFVvkf9KFg6484wR9s0qjAXlZ8qWPDkTyKF6+zqjBe/I2mygg3MbpZ++hdi0ToqNUF8cjj7fBy0dg8Ug==} - - '@changesets/read@0.6.5': - resolution: {integrity: sha512-UPzNGhsSjHD3Veb0xO/MwvasGe8eMyNrR/sT9gR8Q3DhOQZirgKhhXv/8hVsI0QpPjR004Z9iFxoJU6in3uGMg==} - - '@changesets/should-skip-package@0.1.2': - resolution: {integrity: sha512-qAK/WrqWLNCP22UDdBTMPH5f41elVDlsNyat180A33dWxuUDyNpg6fPi/FyTZwRriVjg0L8gnjJn2F9XAoF0qw==} - - '@changesets/types@4.1.0': - resolution: {integrity: sha512-LDQvVDv5Kb50ny2s25Fhm3d9QSZimsoUGBsUioj6MC3qbMUCuC8GPIvk/M6IvXx3lYhAs0lwWUQLb+VIEUCECw==} - - '@changesets/types@6.1.0': - resolution: {integrity: sha512-rKQcJ+o1nKNgeoYRHKOS07tAMNd3YSN0uHaJOZYjBAgxfV7TUE7JE+z4BzZdQwb5hKaYbayKN5KrYV7ODb2rAA==} - - '@changesets/write@0.4.0': - resolution: {integrity: sha512-CdTLvIOPiCNuH71pyDu3rA+Q0n65cmAbXnwWH84rKGiFumFzkmHNT8KHTMEchcxN+Kl8I54xGUhJ7l3E7X396Q==} - - '@esbuild/aix-ppc64@0.25.8': - resolution: {integrity: sha512-urAvrUedIqEiFR3FYSLTWQgLu5tb+m0qZw0NBEasUeo6wuqatkMDaRT+1uABiGXEu5vqgPd7FGE1BhsAIy9QVA==} - engines: {node: '>=18'} - cpu: [ppc64] - os: [aix] - - '@esbuild/android-arm64@0.25.8': - resolution: {integrity: sha512-OD3p7LYzWpLhZEyATcTSJ67qB5D+20vbtr6vHlHWSQYhKtzUYrETuWThmzFpZtFsBIxRvhO07+UgVA9m0i/O1w==} - engines: {node: '>=18'} - cpu: [arm64] - os: [android] - - '@esbuild/android-arm@0.25.8': - resolution: {integrity: sha512-RONsAvGCz5oWyePVnLdZY/HHwA++nxYWIX1atInlaW6SEkwq6XkP3+cb825EUcRs5Vss/lGh/2YxAb5xqc07Uw==} - engines: {node: '>=18'} - cpu: [arm] - os: [android] - - '@esbuild/android-x64@0.25.8': - resolution: {integrity: sha512-yJAVPklM5+4+9dTeKwHOaA+LQkmrKFX96BM0A/2zQrbS6ENCmxc4OVoBs5dPkCCak2roAD+jKCdnmOqKszPkjA==} - engines: {node: '>=18'} - cpu: [x64] - os: [android] - - '@esbuild/darwin-arm64@0.25.8': - resolution: {integrity: sha512-Jw0mxgIaYX6R8ODrdkLLPwBqHTtYHJSmzzd+QeytSugzQ0Vg4c5rDky5VgkoowbZQahCbsv1rT1KW72MPIkevw==} - engines: {node: '>=18'} - cpu: [arm64] - os: [darwin] - - '@esbuild/darwin-x64@0.25.8': - resolution: {integrity: sha512-Vh2gLxxHnuoQ+GjPNvDSDRpoBCUzY4Pu0kBqMBDlK4fuWbKgGtmDIeEC081xi26PPjn+1tct+Bh8FjyLlw1Zlg==} - engines: {node: '>=18'} - cpu: [x64] - os: [darwin] - - '@esbuild/freebsd-arm64@0.25.8': - resolution: {integrity: sha512-YPJ7hDQ9DnNe5vxOm6jaie9QsTwcKedPvizTVlqWG9GBSq+BuyWEDazlGaDTC5NGU4QJd666V0yqCBL2oWKPfA==} - engines: {node: '>=18'} - cpu: [arm64] - os: [freebsd] - - '@esbuild/freebsd-x64@0.25.8': - resolution: {integrity: sha512-MmaEXxQRdXNFsRN/KcIimLnSJrk2r5H8v+WVafRWz5xdSVmWLoITZQXcgehI2ZE6gioE6HirAEToM/RvFBeuhw==} - engines: {node: '>=18'} - cpu: [x64] - os: [freebsd] - - '@esbuild/linux-arm64@0.25.8': - resolution: {integrity: sha512-WIgg00ARWv/uYLU7lsuDK00d/hHSfES5BzdWAdAig1ioV5kaFNrtK8EqGcUBJhYqotlUByUKz5Qo6u8tt7iD/w==} - engines: {node: '>=18'} - cpu: [arm64] - os: [linux] - - '@esbuild/linux-arm@0.25.8': - resolution: {integrity: sha512-FuzEP9BixzZohl1kLf76KEVOsxtIBFwCaLupVuk4eFVnOZfU+Wsn+x5Ryam7nILV2pkq2TqQM9EZPsOBuMC+kg==} - engines: {node: '>=18'} - cpu: [arm] - os: [linux] - - '@esbuild/linux-ia32@0.25.8': - resolution: {integrity: sha512-A1D9YzRX1i+1AJZuFFUMP1E9fMaYY+GnSQil9Tlw05utlE86EKTUA7RjwHDkEitmLYiFsRd9HwKBPEftNdBfjg==} - engines: {node: '>=18'} - cpu: [ia32] - os: [linux] - - '@esbuild/linux-loong64@0.25.8': - resolution: {integrity: sha512-O7k1J/dwHkY1RMVvglFHl1HzutGEFFZ3kNiDMSOyUrB7WcoHGf96Sh+64nTRT26l3GMbCW01Ekh/ThKM5iI7hQ==} - engines: {node: '>=18'} - cpu: [loong64] - os: [linux] - - '@esbuild/linux-mips64el@0.25.8': - resolution: {integrity: sha512-uv+dqfRazte3BzfMp8PAQXmdGHQt2oC/y2ovwpTteqrMx2lwaksiFZ/bdkXJC19ttTvNXBuWH53zy/aTj1FgGw==} - engines: {node: '>=18'} - cpu: [mips64el] - os: [linux] - - '@esbuild/linux-ppc64@0.25.8': - resolution: {integrity: sha512-GyG0KcMi1GBavP5JgAkkstMGyMholMDybAf8wF5A70CALlDM2p/f7YFE7H92eDeH/VBtFJA5MT4nRPDGg4JuzQ==} - engines: {node: '>=18'} - cpu: [ppc64] - os: [linux] - - '@esbuild/linux-riscv64@0.25.8': - resolution: {integrity: sha512-rAqDYFv3yzMrq7GIcen3XP7TUEG/4LK86LUPMIz6RT8A6pRIDn0sDcvjudVZBiiTcZCY9y2SgYX2lgK3AF+1eg==} - engines: {node: '>=18'} - cpu: [riscv64] - os: [linux] - - '@esbuild/linux-s390x@0.25.8': - resolution: {integrity: sha512-Xutvh6VjlbcHpsIIbwY8GVRbwoviWT19tFhgdA7DlenLGC/mbc3lBoVb7jxj9Z+eyGqvcnSyIltYUrkKzWqSvg==} - engines: {node: '>=18'} - cpu: [s390x] - os: [linux] - - '@esbuild/linux-x64@0.25.8': - resolution: {integrity: sha512-ASFQhgY4ElXh3nDcOMTkQero4b1lgubskNlhIfJrsH5OKZXDpUAKBlNS0Kx81jwOBp+HCeZqmoJuihTv57/jvQ==} - engines: {node: '>=18'} - cpu: [x64] - os: [linux] - - '@esbuild/netbsd-arm64@0.25.8': - resolution: {integrity: sha512-d1KfruIeohqAi6SA+gENMuObDbEjn22olAR7egqnkCD9DGBG0wsEARotkLgXDu6c4ncgWTZJtN5vcgxzWRMzcw==} - engines: {node: '>=18'} - cpu: [arm64] - os: [netbsd] - - '@esbuild/netbsd-x64@0.25.8': - resolution: {integrity: sha512-nVDCkrvx2ua+XQNyfrujIG38+YGyuy2Ru9kKVNyh5jAys6n+l44tTtToqHjino2My8VAY6Lw9H7RI73XFi66Cg==} - engines: {node: '>=18'} - cpu: [x64] - os: [netbsd] - - '@esbuild/openbsd-arm64@0.25.8': - resolution: {integrity: sha512-j8HgrDuSJFAujkivSMSfPQSAa5Fxbvk4rgNAS5i3K+r8s1X0p1uOO2Hl2xNsGFppOeHOLAVgYwDVlmxhq5h+SQ==} - engines: {node: '>=18'} - cpu: [arm64] - os: [openbsd] - - '@esbuild/openbsd-x64@0.25.8': - resolution: {integrity: sha512-1h8MUAwa0VhNCDp6Af0HToI2TJFAn1uqT9Al6DJVzdIBAd21m/G0Yfc77KDM3uF3T/YaOgQq3qTJHPbTOInaIQ==} - engines: {node: '>=18'} - cpu: [x64] - os: [openbsd] - - '@esbuild/openharmony-arm64@0.25.8': - resolution: {integrity: sha512-r2nVa5SIK9tSWd0kJd9HCffnDHKchTGikb//9c7HX+r+wHYCpQrSgxhlY6KWV1nFo1l4KFbsMlHk+L6fekLsUg==} - engines: {node: '>=18'} - cpu: [arm64] - os: [openharmony] - - '@esbuild/sunos-x64@0.25.8': - resolution: {integrity: sha512-zUlaP2S12YhQ2UzUfcCuMDHQFJyKABkAjvO5YSndMiIkMimPmxA+BYSBikWgsRpvyxuRnow4nS5NPnf9fpv41w==} - engines: {node: '>=18'} - cpu: [x64] - os: [sunos] - - '@esbuild/win32-arm64@0.25.8': - resolution: {integrity: sha512-YEGFFWESlPva8hGL+zvj2z/SaK+pH0SwOM0Nc/d+rVnW7GSTFlLBGzZkuSU9kFIGIo8q9X3ucpZhu8PDN5A2sQ==} - engines: {node: '>=18'} - cpu: [arm64] - os: [win32] - - '@esbuild/win32-ia32@0.25.8': - resolution: {integrity: sha512-hiGgGC6KZ5LZz58OL/+qVVoZiuZlUYlYHNAmczOm7bs2oE1XriPFi5ZHHrS8ACpV5EjySrnoCKmcbQMN+ojnHg==} - engines: {node: '>=18'} - cpu: [ia32] - os: [win32] - - '@esbuild/win32-x64@0.25.8': - resolution: {integrity: sha512-cn3Yr7+OaaZq1c+2pe+8yxC8E144SReCQjN6/2ynubzYjvyqZjTXfQJpAcQpsdJq3My7XADANiYGHoFC69pLQw==} - engines: {node: '>=18'} - cpu: [x64] - os: [win32] - - '@eslint-community/eslint-utils@4.9.0': - resolution: {integrity: sha512-ayVFHdtZ+hsq1t2Dy24wCmGXGe4q9Gu3smhLYALJrr473ZH27MsnSL+LKUlimp4BWJqMDMLmPpx/Q9R3OAlL4g==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - peerDependencies: - eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 - - '@eslint-community/regexpp@4.12.2': - resolution: {integrity: sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==} - engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} - - '@eslint/config-array@0.21.1': - resolution: {integrity: sha512-aw1gNayWpdI/jSYVgzN5pL0cfzU02GT3NBpeT/DXbx1/1x7ZKxFPd9bwrzygx/qiwIQiJ1sw/zD8qY/kRvlGHA==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - - '@eslint/config-helpers@0.4.2': - resolution: {integrity: sha512-gBrxN88gOIf3R7ja5K9slwNayVcZgK6SOUORm2uBzTeIEfeVaIhOpCtTox3P6R7o2jLFwLFTLnC7kU/RGcYEgw==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - - '@eslint/core@0.17.0': - resolution: {integrity: sha512-yL/sLrpmtDaFEiUj1osRP4TI2MDz1AddJL+jZ7KSqvBuliN4xqYY54IfdN8qD8Toa6g1iloph1fxQNkjOxrrpQ==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - - '@eslint/eslintrc@3.3.3': - resolution: {integrity: sha512-Kr+LPIUVKz2qkx1HAMH8q1q6azbqBAsXJUxBl/ODDuVPX45Z9DfwB8tPjTi6nNZ8BuM3nbJxC5zCAg5elnBUTQ==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - - '@eslint/js@9.39.2': - resolution: {integrity: sha512-q1mjIoW1VX4IvSocvM/vbTiveKC4k9eLrajNEuSsmjymSDEbpGddtpfOoN7YGAqBK3NG+uqo8ia4PDTt8buCYA==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - - '@eslint/object-schema@2.1.7': - resolution: {integrity: sha512-VtAOaymWVfZcmZbp6E2mympDIHvyjXs/12LqWYjVw6qjrfF+VK+fyG33kChz3nnK+SU5/NeHOqrTEHS8sXO3OA==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - - '@eslint/plugin-kit@0.4.1': - resolution: {integrity: sha512-43/qtrDUokr7LJqoF2c3+RInu/t4zfrpYdoSDfYyhg52rwLV6TnOvdG4fXm7IkSB3wErkcmJS9iEhjVtOSEjjA==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - - '@humanfs/core@0.19.1': - resolution: {integrity: sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==} - engines: {node: '>=18.18.0'} - - '@humanfs/node@0.16.7': - resolution: {integrity: sha512-/zUx+yOsIrG4Y43Eh2peDeKCxlRt/gET6aHfaKpuq267qXdYDFViVHfMaLyygZOnl0kGWxFIgsBy8QFuTLUXEQ==} - engines: {node: '>=18.18.0'} - - '@humanwhocodes/module-importer@1.0.1': - resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==} - engines: {node: '>=12.22'} - - '@humanwhocodes/retry@0.4.3': - resolution: {integrity: sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==} - engines: {node: '>=18.18'} - - '@inquirer/ansi@1.0.0': - resolution: {integrity: sha512-JWaTfCxI1eTmJ1BIv86vUfjVatOdxwD0DAVKYevY8SazeUUZtW+tNbsdejVO1GYE0GXJW1N1ahmiC3TFd+7wZA==} - engines: {node: '>=18'} - - '@inquirer/checkbox@4.2.0': - resolution: {integrity: sha512-fdSw07FLJEU5vbpOPzXo5c6xmMGDzbZE2+niuDHX5N6mc6V0Ebso/q3xiHra4D73+PMsC8MJmcaZKuAAoaQsSA==} - engines: {node: '>=18'} - peerDependencies: - '@types/node': '>=18' - peerDependenciesMeta: - '@types/node': - optional: true - - '@inquirer/confirm@5.1.14': - resolution: {integrity: sha512-5yR4IBfe0kXe59r1YCTG8WXkUbl7Z35HK87Sw+WUyGD8wNUx7JvY7laahzeytyE1oLn74bQnL7hstctQxisQ8Q==} - engines: {node: '>=18'} - peerDependencies: - '@types/node': '>=18' - peerDependenciesMeta: - '@types/node': - optional: true - - '@inquirer/core@10.2.2': - resolution: {integrity: sha512-yXq/4QUnk4sHMtmbd7irwiepjB8jXU0kkFRL4nr/aDBA2mDz13cMakEWdDwX3eSCTkk03kwcndD1zfRAIlELxA==} - engines: {node: '>=18'} - peerDependencies: - '@types/node': '>=18' - peerDependenciesMeta: - '@types/node': - optional: true - - '@inquirer/editor@4.2.15': - resolution: {integrity: sha512-wst31XT8DnGOSS4nNJDIklGKnf+8shuauVrWzgKegWUe28zfCftcWZ2vktGdzJgcylWSS2SrDnYUb6alZcwnCQ==} - engines: {node: '>=18'} - peerDependencies: - '@types/node': '>=18' - peerDependenciesMeta: - '@types/node': - optional: true - - '@inquirer/expand@4.0.17': - resolution: {integrity: sha512-PSqy9VmJx/VbE3CT453yOfNa+PykpKg/0SYP7odez1/NWBGuDXgPhp4AeGYYKjhLn5lUUavVS/JbeYMPdH50Mw==} - engines: {node: '>=18'} - peerDependencies: - '@types/node': '>=18' - peerDependenciesMeta: - '@types/node': - optional: true - - '@inquirer/external-editor@1.0.1': - resolution: {integrity: sha512-Oau4yL24d2B5IL4ma4UpbQigkVhzPDXLoqy1ggK4gnHg/stmkffJE4oOXHXF3uz0UEpywG68KcyXsyYpA1Re/Q==} - engines: {node: '>=18'} - peerDependencies: - '@types/node': '>=18' - peerDependenciesMeta: - '@types/node': - optional: true - - '@inquirer/figures@1.0.13': - resolution: {integrity: sha512-lGPVU3yO9ZNqA7vTYz26jny41lE7yoQansmqdMLBEfqaGsmdg7V3W9mK9Pvb5IL4EVZ9GnSDGMO/cJXud5dMaw==} - engines: {node: '>=18'} - - '@inquirer/input@4.2.1': - resolution: {integrity: sha512-tVC+O1rBl0lJpoUZv4xY+WGWY8V5b0zxU1XDsMsIHYregdh7bN5X5QnIONNBAl0K765FYlAfNHS2Bhn7SSOVow==} - engines: {node: '>=18'} - peerDependencies: - '@types/node': '>=18' - peerDependenciesMeta: - '@types/node': - optional: true - - '@inquirer/number@3.0.17': - resolution: {integrity: sha512-GcvGHkyIgfZgVnnimURdOueMk0CztycfC8NZTiIY9arIAkeOgt6zG57G+7vC59Jns3UX27LMkPKnKWAOF5xEYg==} - engines: {node: '>=18'} - peerDependencies: - '@types/node': '>=18' - peerDependenciesMeta: - '@types/node': - optional: true - - '@inquirer/password@4.0.17': - resolution: {integrity: sha512-DJolTnNeZ00E1+1TW+8614F7rOJJCM4y4BAGQ3Gq6kQIG+OJ4zr3GLjIjVVJCbKsk2jmkmv6v2kQuN/vriHdZA==} - engines: {node: '>=18'} - peerDependencies: - '@types/node': '>=18' - peerDependenciesMeta: - '@types/node': - optional: true - - '@inquirer/prompts@7.8.0': - resolution: {integrity: sha512-JHwGbQ6wjf1dxxnalDYpZwZxUEosT+6CPGD9Zh4sm9WXdtUp9XODCQD3NjSTmu+0OAyxWXNOqf0spjIymJa2Tw==} - engines: {node: '>=18'} - peerDependencies: - '@types/node': '>=18' - peerDependenciesMeta: - '@types/node': - optional: true - - '@inquirer/rawlist@4.1.5': - resolution: {integrity: sha512-R5qMyGJqtDdi4Ht521iAkNqyB6p2UPuZUbMifakg1sWtu24gc2Z8CJuw8rP081OckNDMgtDCuLe42Q2Kr3BolA==} - engines: {node: '>=18'} - peerDependencies: - '@types/node': '>=18' - peerDependenciesMeta: - '@types/node': - optional: true - - '@inquirer/search@3.1.0': - resolution: {integrity: sha512-PMk1+O/WBcYJDq2H7foV0aAZSmDdkzZB9Mw2v/DmONRJopwA/128cS9M/TXWLKKdEQKZnKwBzqu2G4x/2Nqx8Q==} - engines: {node: '>=18'} - peerDependencies: - '@types/node': '>=18' - peerDependenciesMeta: - '@types/node': - optional: true - - '@inquirer/select@4.3.1': - resolution: {integrity: sha512-Gfl/5sqOF5vS/LIrSndFgOh7jgoe0UXEizDqahFRkq5aJBLegZ6WjuMh/hVEJwlFQjyLq1z9fRtvUMkb7jM1LA==} - engines: {node: '>=18'} - peerDependencies: - '@types/node': '>=18' - peerDependenciesMeta: - '@types/node': - optional: true - - '@inquirer/type@3.0.8': - resolution: {integrity: sha512-lg9Whz8onIHRthWaN1Q9EGLa/0LFJjyM8mEUbL1eTi6yMGvBf8gvyDLtxSXztQsxMvhxxNpJYrwa1YHdq+w4Jw==} - engines: {node: '>=18'} - peerDependencies: - '@types/node': '>=18' - peerDependenciesMeta: - '@types/node': - optional: true - - '@jridgewell/sourcemap-codec@1.5.4': - resolution: {integrity: sha512-VT2+G1VQs/9oz078bLrYbecdZKs912zQlkelYpuf+SXF+QvZDYJlbx/LSx+meSAwdDFnF8FVXW92AVjjkVmgFw==} - - '@manypkg/find-root@1.1.0': - resolution: {integrity: sha512-mki5uBvhHzO8kYYix/WRy2WX8S3B5wdVSc9D6KcU5lQNglP2yt58/VfLuAK49glRXChosY8ap2oJ1qgma3GUVA==} - - '@manypkg/get-packages@1.1.3': - resolution: {integrity: sha512-fo+QhuU3qE/2TQMQmbVMqaQ6EWbMhi4ABWP+O4AM1NqPBuy0OrApV5LO6BrrgnhtAHS2NH6RrVk9OL181tTi8A==} - - '@nodelib/fs.scandir@2.1.5': - resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} - engines: {node: '>= 8'} - - '@nodelib/fs.stat@2.0.5': - resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==} - engines: {node: '>= 8'} - - '@nodelib/fs.walk@1.2.8': - resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} - engines: {node: '>= 8'} - - '@polka/url@1.0.0-next.29': - resolution: {integrity: sha512-wwQAWhWSuHaag8c4q/KN/vCoeOJYshAIvMQwD4GpSb3OiZklFfvAgmj0VCBBImRpuF/aFgIRzllXlVX93Jevww==} - - '@rollup/rollup-android-arm-eabi@4.46.2': - resolution: {integrity: sha512-Zj3Hl6sN34xJtMv7Anwb5Gu01yujyE/cLBDB2gnHTAHaWS1Z38L7kuSG+oAh0giZMqG060f/YBStXtMH6FvPMA==} - cpu: [arm] - os: [android] - - '@rollup/rollup-android-arm64@4.46.2': - resolution: {integrity: sha512-nTeCWY83kN64oQ5MGz3CgtPx8NSOhC5lWtsjTs+8JAJNLcP3QbLCtDDgUKQc/Ro/frpMq4SHUaHN6AMltcEoLQ==} - cpu: [arm64] - os: [android] - - '@rollup/rollup-darwin-arm64@4.46.2': - resolution: {integrity: sha512-HV7bW2Fb/F5KPdM/9bApunQh68YVDU8sO8BvcW9OngQVN3HHHkw99wFupuUJfGR9pYLLAjcAOA6iO+evsbBaPQ==} - cpu: [arm64] - os: [darwin] - - '@rollup/rollup-darwin-x64@4.46.2': - resolution: {integrity: sha512-SSj8TlYV5nJixSsm/y3QXfhspSiLYP11zpfwp6G/YDXctf3Xkdnk4woJIF5VQe0of2OjzTt8EsxnJDCdHd2xMA==} - cpu: [x64] - os: [darwin] - - '@rollup/rollup-freebsd-arm64@4.46.2': - resolution: {integrity: sha512-ZyrsG4TIT9xnOlLsSSi9w/X29tCbK1yegE49RYm3tu3wF1L/B6LVMqnEWyDB26d9Ecx9zrmXCiPmIabVuLmNSg==} - cpu: [arm64] - os: [freebsd] - - '@rollup/rollup-freebsd-x64@4.46.2': - resolution: {integrity: sha512-pCgHFoOECwVCJ5GFq8+gR8SBKnMO+xe5UEqbemxBpCKYQddRQMgomv1104RnLSg7nNvgKy05sLsY51+OVRyiVw==} - cpu: [x64] - os: [freebsd] - - '@rollup/rollup-linux-arm-gnueabihf@4.46.2': - resolution: {integrity: sha512-EtP8aquZ0xQg0ETFcxUbU71MZlHaw9MChwrQzatiE8U/bvi5uv/oChExXC4mWhjiqK7azGJBqU0tt5H123SzVA==} - cpu: [arm] - os: [linux] - - '@rollup/rollup-linux-arm-musleabihf@4.46.2': - resolution: {integrity: sha512-qO7F7U3u1nfxYRPM8HqFtLd+raev2K137dsV08q/LRKRLEc7RsiDWihUnrINdsWQxPR9jqZ8DIIZ1zJJAm5PjQ==} - cpu: [arm] - os: [linux] - - '@rollup/rollup-linux-arm64-gnu@4.46.2': - resolution: {integrity: sha512-3dRaqLfcOXYsfvw5xMrxAk9Lb1f395gkoBYzSFcc/scgRFptRXL9DOaDpMiehf9CO8ZDRJW2z45b6fpU5nwjng==} - cpu: [arm64] - os: [linux] - - '@rollup/rollup-linux-arm64-musl@4.46.2': - resolution: {integrity: sha512-fhHFTutA7SM+IrR6lIfiHskxmpmPTJUXpWIsBXpeEwNgZzZZSg/q4i6FU4J8qOGyJ0TR+wXBwx/L7Ho9z0+uDg==} - cpu: [arm64] - os: [linux] - - '@rollup/rollup-linux-loongarch64-gnu@4.46.2': - resolution: {integrity: sha512-i7wfGFXu8x4+FRqPymzjD+Hyav8l95UIZ773j7J7zRYc3Xsxy2wIn4x+llpunexXe6laaO72iEjeeGyUFmjKeA==} - cpu: [loong64] - os: [linux] - - '@rollup/rollup-linux-ppc64-gnu@4.46.2': - resolution: {integrity: sha512-B/l0dFcHVUnqcGZWKcWBSV2PF01YUt0Rvlurci5P+neqY/yMKchGU8ullZvIv5e8Y1C6wOn+U03mrDylP5q9Yw==} - cpu: [ppc64] - os: [linux] - - '@rollup/rollup-linux-riscv64-gnu@4.46.2': - resolution: {integrity: sha512-32k4ENb5ygtkMwPMucAb8MtV8olkPT03oiTxJbgkJa7lJ7dZMr0GCFJlyvy+K8iq7F/iuOr41ZdUHaOiqyR3iQ==} - cpu: [riscv64] - os: [linux] - - '@rollup/rollup-linux-riscv64-musl@4.46.2': - resolution: {integrity: sha512-t5B2loThlFEauloaQkZg9gxV05BYeITLvLkWOkRXogP4qHXLkWSbSHKM9S6H1schf/0YGP/qNKtiISlxvfmmZw==} - cpu: [riscv64] - os: [linux] - - '@rollup/rollup-linux-s390x-gnu@4.46.2': - resolution: {integrity: sha512-YKjekwTEKgbB7n17gmODSmJVUIvj8CX7q5442/CK80L8nqOUbMtf8b01QkG3jOqyr1rotrAnW6B/qiHwfcuWQA==} - cpu: [s390x] - os: [linux] - - '@rollup/rollup-linux-x64-gnu@4.46.2': - resolution: {integrity: sha512-Jj5a9RUoe5ra+MEyERkDKLwTXVu6s3aACP51nkfnK9wJTraCC8IMe3snOfALkrjTYd2G1ViE1hICj0fZ7ALBPA==} - cpu: [x64] - os: [linux] - - '@rollup/rollup-linux-x64-musl@4.46.2': - resolution: {integrity: sha512-7kX69DIrBeD7yNp4A5b81izs8BqoZkCIaxQaOpumcJ1S/kmqNFjPhDu1LHeVXv0SexfHQv5cqHsxLOjETuqDuA==} - cpu: [x64] - os: [linux] - - '@rollup/rollup-win32-arm64-msvc@4.46.2': - resolution: {integrity: sha512-wiJWMIpeaak/jsbaq2HMh/rzZxHVW1rU6coyeNNpMwk5isiPjSTx0a4YLSlYDwBH/WBvLz+EtsNqQScZTLJy3g==} - cpu: [arm64] - os: [win32] - - '@rollup/rollup-win32-ia32-msvc@4.46.2': - resolution: {integrity: sha512-gBgaUDESVzMgWZhcyjfs9QFK16D8K6QZpwAaVNJxYDLHWayOta4ZMjGm/vsAEy3hvlS2GosVFlBlP9/Wb85DqQ==} - cpu: [ia32] - os: [win32] - - '@rollup/rollup-win32-x64-msvc@4.46.2': - resolution: {integrity: sha512-CvUo2ixeIQGtF6WvuB87XWqPQkoFAFqW+HUo/WzHwuHDvIwZCtjdWXoYCcr06iKGydiqTclC4jU/TNObC/xKZg==} - cpu: [x64] - os: [win32] - - '@types/chai@5.2.2': - resolution: {integrity: sha512-8kB30R7Hwqf40JPiKhVzodJs2Qc1ZJ5zuT3uzw5Hq/dhNCl3G3l83jfpdI1e20BP348+fV7VIL/+FxaXkqBmWg==} - - '@types/deep-eql@4.0.2': - resolution: {integrity: sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==} - - '@types/estree@1.0.8': - resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==} - - '@types/json-schema@7.0.15': - resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} - - '@types/node@12.20.55': - resolution: {integrity: sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==} - - '@types/node@24.2.0': - resolution: {integrity: sha512-3xyG3pMCq3oYCNg7/ZP+E1ooTaGB4cG8JWRsqqOYQdbWNY4zbaV0Ennrd7stjiJEFZCaybcIgpTjJWHRfBSIDw==} - - '@typescript-eslint/eslint-plugin@8.50.1': - resolution: {integrity: sha512-PKhLGDq3JAg0Jk/aK890knnqduuI/Qj+udH7wCf0217IGi4gt+acgCyPVe79qoT+qKUvHMDQkwJeKW9fwl8Cyw==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - peerDependencies: - '@typescript-eslint/parser': ^8.50.1 - eslint: ^8.57.0 || ^9.0.0 - typescript: '>=4.8.4 <6.0.0' - - '@typescript-eslint/parser@8.50.1': - resolution: {integrity: sha512-hM5faZwg7aVNa819m/5r7D0h0c9yC4DUlWAOvHAtISdFTc8xB86VmX5Xqabrama3wIPJ/q9RbGS1worb6JfnMg==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - peerDependencies: - eslint: ^8.57.0 || ^9.0.0 - typescript: '>=4.8.4 <6.0.0' - - '@typescript-eslint/project-service@8.50.1': - resolution: {integrity: sha512-E1ur1MCVf+YiP89+o4Les/oBAVzmSbeRB0MQLfSlYtbWU17HPxZ6Bhs5iYmKZRALvEuBoXIZMOIRRc/P++Ortg==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - peerDependencies: - typescript: '>=4.8.4 <6.0.0' - - '@typescript-eslint/scope-manager@8.50.1': - resolution: {integrity: sha512-mfRx06Myt3T4vuoHaKi8ZWNTPdzKPNBhiblze5N50//TSHOAQQevl/aolqA/BcqqbJ88GUnLqjjcBc8EWdBcVw==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - - '@typescript-eslint/tsconfig-utils@8.50.1': - resolution: {integrity: sha512-ooHmotT/lCWLXi55G4mvaUF60aJa012QzvLK0Y+Mp4WdSt17QhMhWOaBWeGTFVkb2gDgBe19Cxy1elPXylslDw==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - peerDependencies: - typescript: '>=4.8.4 <6.0.0' - - '@typescript-eslint/type-utils@8.50.1': - resolution: {integrity: sha512-7J3bf022QZE42tYMO6SL+6lTPKFk/WphhRPe9Tw/el+cEwzLz1Jjz2PX3GtGQVxooLDKeMVmMt7fWpYRdG5Etg==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - peerDependencies: - eslint: ^8.57.0 || ^9.0.0 - typescript: '>=4.8.4 <6.0.0' - - '@typescript-eslint/types@8.50.1': - resolution: {integrity: sha512-v5lFIS2feTkNyMhd7AucE/9j/4V9v5iIbpVRncjk/K0sQ6Sb+Np9fgYS/63n6nwqahHQvbmujeBL7mp07Q9mlA==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - - '@typescript-eslint/typescript-estree@8.50.1': - resolution: {integrity: sha512-woHPdW+0gj53aM+cxchymJCrh0cyS7BTIdcDxWUNsclr9VDkOSbqC13juHzxOmQ22dDkMZEpZB+3X1WpUvzgVQ==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - peerDependencies: - typescript: '>=4.8.4 <6.0.0' - - '@typescript-eslint/utils@8.50.1': - resolution: {integrity: sha512-lCLp8H1T9T7gPbEuJSnHwnSuO9mDf8mfK/Nion5mZmiEaQD9sWf9W4dfeFqRyqRjF06/kBuTmAqcs9sewM2NbQ==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - peerDependencies: - eslint: ^8.57.0 || ^9.0.0 - typescript: '>=4.8.4 <6.0.0' - - '@typescript-eslint/visitor-keys@8.50.1': - resolution: {integrity: sha512-IrDKrw7pCRUR94zeuCSUWQ+w8JEf5ZX5jl/e6AHGSLi1/zIr0lgutfn/7JpfCey+urpgQEdrZVYzCaVVKiTwhQ==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - - '@vitest/expect@3.2.4': - resolution: {integrity: sha512-Io0yyORnB6sikFlt8QW5K7slY4OjqNX9jmJQ02QDda8lyM6B5oNgVWoSoKPac8/kgnCUzuHQKrSLtu/uOqqrig==} - - '@vitest/mocker@3.2.4': - resolution: {integrity: sha512-46ryTE9RZO/rfDd7pEqFl7etuyzekzEhUbTW3BvmeO/BcCMEgq59BKhek3dXDWgAj4oMK6OZi+vRr1wPW6qjEQ==} - peerDependencies: - msw: ^2.4.9 - vite: ^5.0.0 || ^6.0.0 || ^7.0.0-0 - peerDependenciesMeta: - msw: - optional: true - vite: - optional: true - - '@vitest/pretty-format@3.2.4': - resolution: {integrity: sha512-IVNZik8IVRJRTr9fxlitMKeJeXFFFN0JaB9PHPGQ8NKQbGpfjlTx9zO4RefN8gp7eqjNy8nyK3NZmBzOPeIxtA==} - - '@vitest/runner@3.2.4': - resolution: {integrity: sha512-oukfKT9Mk41LreEW09vt45f8wx7DordoWUZMYdY/cyAk7w5TWkTRCNZYF7sX7n2wB7jyGAl74OxgwhPgKaqDMQ==} - - '@vitest/snapshot@3.2.4': - resolution: {integrity: sha512-dEYtS7qQP2CjU27QBC5oUOxLE/v5eLkGqPE0ZKEIDGMs4vKWe7IjgLOeauHsR0D5YuuycGRO5oSRXnwnmA78fQ==} - - '@vitest/spy@3.2.4': - resolution: {integrity: sha512-vAfasCOe6AIK70iP5UD11Ac4siNUNJ9i/9PZ3NKx07sG6sUxeag1LWdNrMWeKKYBLlzuK+Gn65Yd5nyL6ds+nw==} - - '@vitest/ui@3.2.4': - resolution: {integrity: sha512-hGISOaP18plkzbWEcP/QvtRW1xDXF2+96HbEX6byqQhAUbiS5oH6/9JwW+QsQCIYON2bI6QZBF+2PvOmrRZ9wA==} - peerDependencies: - vitest: 3.2.4 - - '@vitest/utils@3.2.4': - resolution: {integrity: sha512-fB2V0JFrQSMsCo9HiSq3Ezpdv4iYaXRG1Sx8edX3MwxfyNn83mKiGzOcH+Fkxt4MHxr3y42fQi1oeAInqgX2QA==} - - acorn-jsx@5.3.2: - resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} - peerDependencies: - acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 - - acorn@8.15.0: - resolution: {integrity: sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==} - engines: {node: '>=0.4.0'} - hasBin: true - - ajv@6.12.6: - resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} - - ansi-colors@4.1.3: - resolution: {integrity: sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==} - engines: {node: '>=6'} - - 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'} - - ansi-regex@6.1.0: - resolution: {integrity: sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==} - engines: {node: '>=12'} - - ansi-styles@4.3.0: - resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} - engines: {node: '>=8'} - - argparse@1.0.10: - resolution: {integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==} - - argparse@2.0.1: - resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} - - array-union@2.1.0: - resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==} - engines: {node: '>=8'} - - assertion-error@2.0.1: - resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==} - engines: {node: '>=12'} - - balanced-match@1.0.2: - resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} - - better-path-resolve@1.0.0: - resolution: {integrity: sha512-pbnl5XzGBdrFU/wT4jqmJVPn2B6UHPBOhzMQkY/SPUPB6QtUXtmBHBIwCbXJol93mOpGMnQyP/+BB19q04xj7g==} - engines: {node: '>=4'} - - brace-expansion@1.1.12: - resolution: {integrity: sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==} - - brace-expansion@2.0.2: - resolution: {integrity: sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==} - - braces@3.0.3: - resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} - engines: {node: '>=8'} - - cac@6.7.14: - resolution: {integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==} - engines: {node: '>=8'} - - callsites@3.1.0: - resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} - engines: {node: '>=6'} - - chai@5.2.1: - resolution: {integrity: sha512-5nFxhUrX0PqtyogoYOA8IPswy5sZFTOsBFl/9bNsmDLgsxYTzSZQJDPppDnZPTQbzSEm0hqGjWPzRemQCYbD6A==} - engines: {node: '>=18'} - - chalk@4.1.2: - resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} - engines: {node: '>=10'} - - chalk@5.5.0: - resolution: {integrity: sha512-1tm8DTaJhPBG3bIkVeZt1iZM9GfSX2lzOeDVZH9R9ffRHpmHvxZ/QhgQH/aDTkswQVt+YHdXAdS/In/30OjCbg==} - engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} - - chardet@0.7.0: - resolution: {integrity: sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==} - - chardet@2.1.0: - resolution: {integrity: sha512-bNFETTG/pM5ryzQ9Ad0lJOTa6HWD/YsScAR3EnCPZRPlQh77JocYktSHOUHelyhm8IARL+o4c4F1bP5KVOjiRA==} - - check-error@2.1.1: - resolution: {integrity: sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw==} - engines: {node: '>= 16'} - - ci-info@3.9.0: - resolution: {integrity: sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==} - engines: {node: '>=8'} - - cli-cursor@5.0.0: - resolution: {integrity: sha512-aCj4O5wKyszjMmDT4tZj93kxyydN/K5zPWSCe6/0AV/AA1pqe5ZBIw0a2ZfPQV7lL5/yb5HsUreJ6UFAF1tEQw==} - engines: {node: '>=18'} - - cli-spinners@2.9.2: - resolution: {integrity: sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg==} - engines: {node: '>=6'} - - 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'} - - color-name@1.1.4: - resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} - - commander@14.0.0: - resolution: {integrity: sha512-2uM9rYjPvyq39NwLRqaiLtWHyDC1FvryJDa2ATTVims5YAS4PupsEQsDvP14FqhFr0P49CYDugi59xaxJlTXRA==} - engines: {node: '>=20'} - - concat-map@0.0.1: - resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} - - cross-spawn@7.0.6: - resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} - engines: {node: '>= 8'} - - debug@4.4.1: - resolution: {integrity: sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==} - engines: {node: '>=6.0'} - peerDependencies: - supports-color: '*' - peerDependenciesMeta: - supports-color: - optional: true - - deep-eql@5.0.2: - resolution: {integrity: sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==} - engines: {node: '>=6'} - - deep-is@0.1.4: - resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} - - detect-indent@6.1.0: - resolution: {integrity: sha512-reYkTUJAZb9gUuZ2RvVCNhVHdg62RHnJ7WJl8ftMi4diZ6NWlciOzQN88pUhSELEwflJht4oQDv0F0BMlwaYtA==} - engines: {node: '>=8'} - - dir-glob@3.0.1: - resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==} - engines: {node: '>=8'} - - emoji-regex@10.4.0: - resolution: {integrity: sha512-EC+0oUMY1Rqm4O6LLrgjtYDvcVYTy7chDnM4Q7030tP4Kwj3u/pR6gP9ygnp2CJMK5Gq+9Q2oqmrFJAz01DXjw==} - - emoji-regex@8.0.0: - resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} - - enquirer@2.4.1: - resolution: {integrity: sha512-rRqJg/6gd538VHvR3PSrdRBb/1Vy2YfzHqzvbhGIQpDRKIa4FgV/54b5Q1xYSxOOwKvjXweS26E0Q+nAMwp2pQ==} - engines: {node: '>=8.6'} - - es-module-lexer@1.7.0: - resolution: {integrity: sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==} - - esbuild@0.25.8: - resolution: {integrity: sha512-vVC0USHGtMi8+R4Kz8rt6JhEWLxsv9Rnu/lGYbPR8u47B+DCBksq9JarW0zOO7bs37hyOK1l2/oqtbciutL5+Q==} - engines: {node: '>=18'} - hasBin: true - - escape-string-regexp@4.0.0: - resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} - engines: {node: '>=10'} - - eslint-scope@8.4.0: - resolution: {integrity: sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - - eslint-visitor-keys@3.4.3: - resolution: {integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - - eslint-visitor-keys@4.2.1: - resolution: {integrity: sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - - eslint@9.39.2: - resolution: {integrity: sha512-LEyamqS7W5HB3ujJyvi0HQK/dtVINZvd5mAAp9eT5S/ujByGjiZLCzPcHVzuXbpJDJF/cxwHlfceVUDZ2lnSTw==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - hasBin: true - peerDependencies: - jiti: '*' - peerDependenciesMeta: - jiti: - optional: true - - espree@10.4.0: - resolution: {integrity: sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - - esprima@4.0.1: - resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==} - engines: {node: '>=4'} - hasBin: true - - esquery@1.6.0: - resolution: {integrity: sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==} - engines: {node: '>=0.10'} - - esrecurse@4.3.0: - resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==} - engines: {node: '>=4.0'} - - estraverse@5.3.0: - resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} - engines: {node: '>=4.0'} - - estree-walker@3.0.3: - resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==} - - esutils@2.0.3: - resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} - engines: {node: '>=0.10.0'} - - expect-type@1.2.2: - resolution: {integrity: sha512-JhFGDVJ7tmDJItKhYgJCGLOWjuK9vPxiXoUFLwLDc99NlmklilbiQJwoctZtt13+xMw91MCk/REan6MWHqDjyA==} - engines: {node: '>=12.0.0'} - - extendable-error@0.1.7: - resolution: {integrity: sha512-UOiS2in6/Q0FK0R0q6UY9vYpQ21mr/Qn1KOnte7vsACuNJf514WvCCUHSRCPcgjPT2bAhNIJdlE6bVap1GKmeg==} - - external-editor@3.1.0: - resolution: {integrity: sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==} - engines: {node: '>=4'} - - fast-deep-equal@3.1.3: - resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} - - fast-glob@3.3.3: - resolution: {integrity: sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==} - engines: {node: '>=8.6.0'} - - fast-json-stable-stringify@2.1.0: - resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} - - fast-levenshtein@2.0.6: - resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} - - fastq@1.19.1: - resolution: {integrity: sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==} - - fdir@6.4.6: - resolution: {integrity: sha512-hiFoqpyZcfNm1yc4u8oWCf9A2c4D3QjCrks3zmoVKVxpQRzmPNar1hUJcBG2RQHvEVGDN+Jm81ZheVLAQMK6+w==} - peerDependencies: - picomatch: ^3 || ^4 - peerDependenciesMeta: - picomatch: - optional: true - - fdir@6.5.0: - resolution: {integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==} - engines: {node: '>=12.0.0'} - peerDependencies: - picomatch: ^3 || ^4 - peerDependenciesMeta: - picomatch: - optional: true - - fflate@0.8.2: - resolution: {integrity: sha512-cPJU47OaAoCbg0pBvzsgpTPhmhqI5eJjh/JIu8tPj5q+T7iLvW/JAYUqmE7KOB4R1ZyEhzBaIQpQpardBF5z8A==} - - file-entry-cache@8.0.0: - resolution: {integrity: sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==} - engines: {node: '>=16.0.0'} - - fill-range@7.1.1: - resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} - engines: {node: '>=8'} - - find-up@4.1.0: - resolution: {integrity: sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==} - engines: {node: '>=8'} - - find-up@5.0.0: - resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} - engines: {node: '>=10'} - - flat-cache@4.0.1: - resolution: {integrity: sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==} - engines: {node: '>=16'} - - flatted@3.3.3: - resolution: {integrity: sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==} - - fs-extra@7.0.1: - resolution: {integrity: sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==} - engines: {node: '>=6 <7 || >=8'} - - fs-extra@8.1.0: - resolution: {integrity: sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==} - engines: {node: '>=6 <7 || >=8'} - - fsevents@2.3.3: - resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} - engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} - os: [darwin] - - get-east-asian-width@1.3.0: - resolution: {integrity: sha512-vpeMIQKxczTD/0s2CdEWHcb0eeJe6TFjxb+J5xgX7hScxqrGuyjmv4c1D4A/gelKfyox0gJJwIHF+fLjeaM8kQ==} - engines: {node: '>=18'} - - glob-parent@5.1.2: - resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} - engines: {node: '>= 6'} - - glob-parent@6.0.2: - resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} - engines: {node: '>=10.13.0'} - - globals@14.0.0: - resolution: {integrity: sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==} - engines: {node: '>=18'} - - globby@11.1.0: - resolution: {integrity: sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==} - engines: {node: '>=10'} - - graceful-fs@4.2.11: - resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} - - has-flag@4.0.0: - resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} - engines: {node: '>=8'} - - human-id@4.1.1: - resolution: {integrity: sha512-3gKm/gCSUipeLsRYZbbdA1BD83lBoWUkZ7G9VFrhWPAU76KwYo5KR8V28bpoPm/ygy0x5/GCbpRQdY7VLYCoIg==} - hasBin: true - - iconv-lite@0.4.24: - resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==} - engines: {node: '>=0.10.0'} - - iconv-lite@0.6.3: - resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==} - engines: {node: '>=0.10.0'} - - ignore@5.3.2: - resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} - engines: {node: '>= 4'} - - ignore@7.0.5: - resolution: {integrity: sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==} - engines: {node: '>= 4'} - - import-fresh@3.3.1: - resolution: {integrity: sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==} - engines: {node: '>=6'} - - imurmurhash@0.1.4: - resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} - engines: {node: '>=0.8.19'} - - is-extglob@2.1.1: - resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} - engines: {node: '>=0.10.0'} - - is-fullwidth-code-point@3.0.0: - resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} - engines: {node: '>=8'} - - is-glob@4.0.3: - resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} - engines: {node: '>=0.10.0'} - - is-interactive@2.0.0: - resolution: {integrity: sha512-qP1vozQRI+BMOPcjFzrjXuQvdak2pHNUMZoeG2eRbiSqyvbEf/wQtEOTOX1guk6E3t36RkaqiSt8A/6YElNxLQ==} - engines: {node: '>=12'} - - is-number@7.0.0: - resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} - engines: {node: '>=0.12.0'} - - is-subdir@1.2.0: - resolution: {integrity: sha512-2AT6j+gXe/1ueqbW6fLZJiIw3F8iXGJtt0yDrZaBhAZEG1raiTxKWU+IPqMCzQAXOUCKdA4UDMgacKH25XG2Cw==} - engines: {node: '>=4'} - - is-unicode-supported@1.3.0: - resolution: {integrity: sha512-43r2mRvz+8JRIKnWJ+3j8JtjRKZ6GmjzfaE/qiBJnikNnYv/6bagRJ1kUhNk8R5EX/GkobD+r+sfxCPJsiKBLQ==} - engines: {node: '>=12'} - - is-unicode-supported@2.1.0: - resolution: {integrity: sha512-mE00Gnza5EEB3Ds0HfMyllZzbBrmLOX3vfWoj9A9PEnTfratQ/BcaJOuMhnkhjXvb2+FkY3VuHqtAGpTPmglFQ==} - engines: {node: '>=18'} - - is-windows@1.0.2: - resolution: {integrity: sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==} - engines: {node: '>=0.10.0'} - - isexe@2.0.0: - resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} - - js-tokens@9.0.1: - resolution: {integrity: sha512-mxa9E9ITFOt0ban3j6L5MpjwegGz6lBQmM1IJkWeBZGcMxto50+eWdjC/52xDbS2vy0k7vIMK0Fe2wfL9OQSpQ==} - - js-yaml@3.14.1: - resolution: {integrity: sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==} - hasBin: true - - js-yaml@4.1.1: - resolution: {integrity: sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==} - hasBin: true - - json-buffer@3.0.1: - resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==} - - json-schema-traverse@0.4.1: - resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} - - json-stable-stringify-without-jsonify@1.0.1: - resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} - - jsonfile@4.0.0: - resolution: {integrity: sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==} - - keyv@4.5.4: - resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} - - levn@0.4.1: - resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} - engines: {node: '>= 0.8.0'} - - locate-path@5.0.0: - resolution: {integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==} - engines: {node: '>=8'} - - locate-path@6.0.0: - resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} - engines: {node: '>=10'} - - lodash.merge@4.6.2: - resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} - - lodash.startcase@4.4.0: - resolution: {integrity: sha512-+WKqsK294HMSc2jEbNgpHpd0JfIBhp7rEV4aqXWqFr6AlXov+SlcgB1Fv01y2kGe3Gc8nMW7VA0SrGuSkRfIEg==} - - log-symbols@6.0.0: - resolution: {integrity: sha512-i24m8rpwhmPIS4zscNzK6MSEhk0DUWa/8iYQWxhffV8jkI4Phvs3F+quL5xvS0gdQR0FyTCMMH33Y78dDTzzIw==} - engines: {node: '>=18'} - - loupe@3.2.0: - resolution: {integrity: sha512-2NCfZcT5VGVNX9mSZIxLRkEAegDGBpuQZBy13desuHeVORmBDyAET4TkJr4SjqQy3A8JDofMN6LpkK8Xcm/dlw==} - - magic-string@0.30.17: - resolution: {integrity: sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==} - - merge2@1.4.1: - resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} - engines: {node: '>= 8'} - - micromatch@4.0.8: - resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} - engines: {node: '>=8.6'} - - mimic-function@5.0.1: - resolution: {integrity: sha512-VP79XUPxV2CigYP3jWwAUFSku2aKqBH7uTAapFWCBqutsbmDo96KY5o8uh6U+/YSIn5OxJnXp73beVkpqMIGhA==} - engines: {node: '>=18'} - - minimatch@3.1.2: - resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} - - minimatch@9.0.5: - resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==} - engines: {node: '>=16 || 14 >=14.17'} - - mri@1.2.0: - resolution: {integrity: sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==} - engines: {node: '>=4'} - - mrmime@2.0.1: - resolution: {integrity: sha512-Y3wQdFg2Va6etvQ5I82yUhGdsKrcYox6p7FfL1LbK2J4V01F9TGlepTIhnK24t7koZibmg82KGglhA1XK5IsLQ==} - engines: {node: '>=10'} - - ms@2.1.3: - resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} - - mute-stream@2.0.0: - resolution: {integrity: sha512-WWdIxpyjEn+FhQJQQv9aQAYlHoNVdzIzUySNV1gHUPDSdZJ3yZn7pAAbQcV7B56Mvu881q9FZV+0Vx2xC44VWA==} - engines: {node: ^18.17.0 || >=20.5.0} - - nanoid@3.3.11: - resolution: {integrity: sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==} - engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} - hasBin: true - - natural-compare@1.4.0: - resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} - - onetime@7.0.0: - resolution: {integrity: sha512-VXJjc87FScF88uafS3JllDgvAm+c/Slfz06lorj2uAY34rlUu0Nt+v8wreiImcrgAjjIHp1rXpTDlLOGw29WwQ==} - engines: {node: '>=18'} - - optionator@0.9.4: - resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==} - engines: {node: '>= 0.8.0'} - - ora@8.2.0: - resolution: {integrity: sha512-weP+BZ8MVNnlCm8c0Qdc1WSWq4Qn7I+9CJGm7Qali6g44e/PUzbjNqJX5NJ9ljlNMosfJvg1fKEGILklK9cwnw==} - engines: {node: '>=18'} - - os-tmpdir@1.0.2: - resolution: {integrity: sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==} - engines: {node: '>=0.10.0'} - - outdent@0.5.0: - resolution: {integrity: sha512-/jHxFIzoMXdqPzTaCpFzAAWhpkSjZPF4Vsn6jAfNpmbH/ymsmd7Qc6VE9BGn0L6YMj6uwpQLxCECpus4ukKS9Q==} - - p-filter@2.1.0: - resolution: {integrity: sha512-ZBxxZ5sL2HghephhpGAQdoskxplTwr7ICaehZwLIlfL6acuVgZPm8yBNuRAFBGEqtD/hmUeq9eqLg2ys9Xr/yw==} - engines: {node: '>=8'} - - p-limit@2.3.0: - resolution: {integrity: sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==} - engines: {node: '>=6'} - - p-limit@3.1.0: - resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} - engines: {node: '>=10'} - - p-locate@4.1.0: - resolution: {integrity: sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==} - engines: {node: '>=8'} - - p-locate@5.0.0: - resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} - engines: {node: '>=10'} - - p-map@2.1.0: - resolution: {integrity: sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==} - engines: {node: '>=6'} - - p-try@2.2.0: - resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==} - engines: {node: '>=6'} - - package-manager-detector@0.2.11: - resolution: {integrity: sha512-BEnLolu+yuz22S56CU1SUKq3XC3PkwD5wv4ikR4MfGvnRVcmzXR9DwSlW2fEamyTPyXHomBJRzgapeuBvRNzJQ==} - - parent-module@1.0.1: - resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} - engines: {node: '>=6'} - - path-exists@4.0.0: - resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} - engines: {node: '>=8'} - - path-key@3.1.1: - resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} - engines: {node: '>=8'} - - path-type@4.0.0: - resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} - engines: {node: '>=8'} - - pathe@2.0.3: - resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==} - - pathval@2.0.1: - resolution: {integrity: sha512-//nshmD55c46FuFw26xV/xFAaB5HF9Xdap7HJBBnrKdAd6/GxDBaNA1870O79+9ueg61cZLSVc+OaFlfmObYVQ==} - engines: {node: '>= 14.16'} - - picocolors@1.1.1: - resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} - - picomatch@2.3.1: - resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} - engines: {node: '>=8.6'} - - picomatch@4.0.3: - resolution: {integrity: sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==} - engines: {node: '>=12'} - - pify@4.0.1: - resolution: {integrity: sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==} - engines: {node: '>=6'} - - postcss@8.5.6: - resolution: {integrity: sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==} - engines: {node: ^10 || ^12 || >=14} - - prelude-ls@1.2.1: - resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} - engines: {node: '>= 0.8.0'} - - prettier@2.8.8: - resolution: {integrity: sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==} - engines: {node: '>=10.13.0'} - hasBin: true - - punycode@2.3.1: - resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} - engines: {node: '>=6'} - - quansync@0.2.11: - resolution: {integrity: sha512-AifT7QEbW9Nri4tAwR5M/uzpBuqfZf+zwaEM/QkzEjj7NBuFD2rBuy0K3dE+8wltbezDV7JMA0WfnCPYRSYbXA==} - - queue-microtask@1.2.3: - resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} - - read-yaml-file@1.1.0: - resolution: {integrity: sha512-VIMnQi/Z4HT2Fxuwg5KrY174U1VdUIASQVWXXyqtNRtxSr9IYkn1rsI6Tb6HsrHCmB7gVpNwX6JxPTHcH6IoTA==} - engines: {node: '>=6'} - - resolve-from@4.0.0: - resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} - engines: {node: '>=4'} - - resolve-from@5.0.0: - resolution: {integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==} - engines: {node: '>=8'} - - restore-cursor@5.1.0: - resolution: {integrity: sha512-oMA2dcrw6u0YfxJQXm342bFKX/E4sG9rbTzO9ptUcR/e8A33cHuvStiYOwH7fszkZlZ1z/ta9AAoPk2F4qIOHA==} - engines: {node: '>=18'} - - reusify@1.1.0: - resolution: {integrity: sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==} - engines: {iojs: '>=1.0.0', node: '>=0.10.0'} - - rollup@4.46.2: - resolution: {integrity: sha512-WMmLFI+Boh6xbop+OAGo9cQ3OgX9MIg7xOQjn+pTCwOkk+FNDAeAemXkJ3HzDJrVXleLOFVa1ipuc1AmEx1Dwg==} - engines: {node: '>=18.0.0', npm: '>=8.0.0'} - hasBin: true - - run-parallel@1.2.0: - resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} - - safer-buffer@2.1.2: - resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} - - semver@7.7.2: - resolution: {integrity: sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==} - engines: {node: '>=10'} - hasBin: true - - shebang-command@2.0.0: - resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} - engines: {node: '>=8'} - - shebang-regex@3.0.0: - resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} - engines: {node: '>=8'} - - siginfo@2.0.0: - resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==} - - signal-exit@4.1.0: - resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} - engines: {node: '>=14'} - - sirv@3.0.1: - resolution: {integrity: sha512-FoqMu0NCGBLCcAkS1qA+XJIQTR6/JHfQXl+uGteNCQ76T91DMUjPa9xfmeqMY3z80nLSg9yQmNjK0Px6RWsH/A==} - engines: {node: '>=18'} - - slash@3.0.0: - resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} - engines: {node: '>=8'} - - source-map-js@1.2.1: - resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} - engines: {node: '>=0.10.0'} - - spawndamnit@3.0.1: - resolution: {integrity: sha512-MmnduQUuHCoFckZoWnXsTg7JaiLBJrKFj9UI2MbRPGaJeVpsLcVBu6P/IGZovziM/YBsellCmsprgNA+w0CzVg==} - - sprintf-js@1.0.3: - resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==} - - stackback@0.0.2: - resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==} - - std-env@3.9.0: - resolution: {integrity: sha512-UGvjygr6F6tpH7o2qyqR6QYpwraIjKSdtzyBdyytFOHmPZY917kwdwLG0RbOjWOnKmnm3PeHjaoLLMie7kPLQw==} - - stdin-discarder@0.2.2: - resolution: {integrity: sha512-UhDfHmA92YAlNnCfhmq0VeNL5bDbiZGg7sZ2IvPsXubGkiNa9EC+tUTsjBRsYUAz87btI6/1wf4XoVvQ3uRnmQ==} - engines: {node: '>=18'} - - string-width@4.2.3: - resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} - engines: {node: '>=8'} - - string-width@7.2.0: - resolution: {integrity: sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==} - engines: {node: '>=18'} - - strip-ansi@6.0.1: - resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} - engines: {node: '>=8'} - - strip-ansi@7.1.0: - resolution: {integrity: sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==} - engines: {node: '>=12'} - - strip-bom@3.0.0: - resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==} - engines: {node: '>=4'} - - strip-json-comments@3.1.1: - resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} - engines: {node: '>=8'} - - strip-literal@3.0.0: - resolution: {integrity: sha512-TcccoMhJOM3OebGhSBEmp3UZ2SfDMZUEBdRA/9ynfLi8yYajyWX3JiXArcJt4Umh4vISpspkQIY8ZZoCqjbviA==} - - supports-color@7.2.0: - resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} - engines: {node: '>=8'} - - term-size@2.2.1: - resolution: {integrity: sha512-wK0Ri4fOGjv/XPy8SBHZChl8CM7uMc5VML7SqiQ0zG7+J5Vr+RMQDoHa2CNT6KHUnTGIXH34UDMkPzAUyapBZg==} - engines: {node: '>=8'} - - tinybench@2.9.0: - resolution: {integrity: sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==} - - tinyexec@0.3.2: - resolution: {integrity: sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==} - - tinyglobby@0.2.14: - resolution: {integrity: sha512-tX5e7OM1HnYr2+a2C/4V0htOcSQcoSTH9KgJnVvNm5zm/cyEWKJ7j7YutsH9CxMdtOkkLFy2AHrMci9IM8IPZQ==} - engines: {node: '>=12.0.0'} - - tinyglobby@0.2.15: - resolution: {integrity: sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==} - engines: {node: '>=12.0.0'} - - tinypool@1.1.1: - resolution: {integrity: sha512-Zba82s87IFq9A9XmjiX5uZA/ARWDrB03OHlq+Vw1fSdt0I+4/Kutwy8BP4Y/y/aORMo61FQ0vIb5j44vSo5Pkg==} - engines: {node: ^18.0.0 || >=20.0.0} - - tinyrainbow@2.0.0: - resolution: {integrity: sha512-op4nsTR47R6p0vMUUoYl/a+ljLFVtlfaXkLQmqfLR1qHma1h/ysYk4hEXZ880bf2CYgTskvTa/e196Vd5dDQXw==} - engines: {node: '>=14.0.0'} - - tinyspy@4.0.3: - resolution: {integrity: sha512-t2T/WLB2WRgZ9EpE4jgPJ9w+i66UZfDc8wHh0xrwiRNN+UwH98GIJkTeZqX9rg0i0ptwzqW+uYeIF0T4F8LR7A==} - engines: {node: '>=14.0.0'} - - tmp@0.0.33: - resolution: {integrity: sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==} - engines: {node: '>=0.6.0'} - - to-regex-range@5.0.1: - resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} - engines: {node: '>=8.0'} - - totalist@3.0.1: - resolution: {integrity: sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==} - engines: {node: '>=6'} - - ts-api-utils@2.1.0: - resolution: {integrity: sha512-CUgTZL1irw8u29bzrOD/nH85jqyc74D6SshFgujOIA7osm2Rz7dYH77agkx7H4FBNxDq7Cjf+IjaX/8zwFW+ZQ==} - engines: {node: '>=18.12'} - peerDependencies: - typescript: '>=4.8.4' - - type-check@0.4.0: - resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} - engines: {node: '>= 0.8.0'} - - type-fest@0.21.3: - resolution: {integrity: sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==} - engines: {node: '>=10'} - - typescript-eslint@8.50.1: - resolution: {integrity: sha512-ytTHO+SoYSbhAH9CrYnMhiLx8To6PSSvqnvXyPUgPETCvB6eBKmTI9w6XMPS3HsBRGkwTVBX+urA8dYQx6bHfQ==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - peerDependencies: - eslint: ^8.57.0 || ^9.0.0 - typescript: '>=4.8.4 <6.0.0' - - typescript@5.9.3: - resolution: {integrity: sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==} - engines: {node: '>=14.17'} - hasBin: true - - undici-types@7.10.0: - resolution: {integrity: sha512-t5Fy/nfn+14LuOc2KNYg75vZqClpAiqscVvMygNnlsHBFpSXdJaYtXMcdNLpl/Qvc3P2cB3s6lOV51nqsFq4ag==} - - universalify@0.1.2: - resolution: {integrity: sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==} - engines: {node: '>= 4.0.0'} - - uri-js@4.4.1: - resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} - - vite-node@3.2.4: - resolution: {integrity: sha512-EbKSKh+bh1E1IFxeO0pg1n4dvoOTt0UDiXMd/qn++r98+jPO1xtJilvXldeuQ8giIB5IkpjCgMleHMNEsGH6pg==} - engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0} - hasBin: true - - vite@7.0.6: - resolution: {integrity: sha512-MHFiOENNBd+Bd9uvc8GEsIzdkn1JxMmEeYX35tI3fv0sJBUTfW5tQsoaOwuY4KhBI09A3dUJ/DXf2yxPVPUceg==} - engines: {node: ^20.19.0 || >=22.12.0} - hasBin: true - peerDependencies: - '@types/node': ^20.19.0 || >=22.12.0 - jiti: '>=1.21.0' - less: ^4.0.0 - lightningcss: ^1.21.0 - sass: ^1.70.0 - sass-embedded: ^1.70.0 - stylus: '>=0.54.8' - sugarss: ^5.0.0 - terser: ^5.16.0 - tsx: ^4.8.1 - yaml: ^2.4.2 - peerDependenciesMeta: - '@types/node': - optional: true - jiti: - optional: true - less: - optional: true - lightningcss: - optional: true - sass: - optional: true - sass-embedded: - optional: true - stylus: - optional: true - sugarss: - optional: true - terser: - optional: true - tsx: - optional: true - yaml: - optional: true - - vitest@3.2.4: - resolution: {integrity: sha512-LUCP5ev3GURDysTWiP47wRRUpLKMOfPh+yKTx3kVIEiu5KOMeqzpnYNsKyOoVrULivR8tLcks4+lga33Whn90A==} - engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0} - hasBin: true - peerDependencies: - '@edge-runtime/vm': '*' - '@types/debug': ^4.1.12 - '@types/node': ^18.0.0 || ^20.0.0 || >=22.0.0 - '@vitest/browser': 3.2.4 - '@vitest/ui': 3.2.4 - happy-dom: '*' - jsdom: '*' - peerDependenciesMeta: - '@edge-runtime/vm': - optional: true - '@types/debug': - optional: true - '@types/node': - optional: true - '@vitest/browser': - optional: true - '@vitest/ui': - optional: true - happy-dom: - optional: true - jsdom: - optional: true - - which@2.0.2: - resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} - engines: {node: '>= 8'} - hasBin: true - - why-is-node-running@2.3.0: - resolution: {integrity: sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==} - engines: {node: '>=8'} - hasBin: true - - word-wrap@1.2.5: - resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==} - engines: {node: '>=0.10.0'} - - wrap-ansi@6.2.0: - resolution: {integrity: sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==} - engines: {node: '>=8'} - - yaml@2.8.2: - resolution: {integrity: sha512-mplynKqc1C2hTVYxd0PU2xQAc22TI1vShAYGksCCfxbn/dFwnHTNi1bvYsBTkhdUNtGIf5xNOg938rrSSYvS9A==} - engines: {node: '>= 14.6'} - hasBin: true - - yocto-queue@0.1.0: - resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} - engines: {node: '>=10'} - - yoctocolors-cjs@2.1.2: - resolution: {integrity: sha512-cYVsTjKl8b+FrnidjibDWskAv7UKOfcwaVZdp/it9n1s9fU3IkgDbhdIRKCW4JDsAlECJY0ytoVPT3sK6kideA==} - engines: {node: '>=18'} - - zod@4.0.17: - resolution: {integrity: sha512-1PHjlYRevNxxdy2JZ8JcNAw7rX8V9P1AKkP+x/xZfxB0K5FYfuV+Ug6P/6NVSR2jHQ+FzDDoDHS04nYUsOIyLQ==} - -snapshots: - - '@babel/runtime@7.28.4': {} - - '@changesets/apply-release-plan@7.0.12': - dependencies: - '@changesets/config': 3.1.1 - '@changesets/get-version-range-type': 0.4.0 - '@changesets/git': 3.0.4 - '@changesets/should-skip-package': 0.1.2 - '@changesets/types': 6.1.0 - '@manypkg/get-packages': 1.1.3 - detect-indent: 6.1.0 - fs-extra: 7.0.1 - lodash.startcase: 4.4.0 - outdent: 0.5.0 - prettier: 2.8.8 - resolve-from: 5.0.0 - semver: 7.7.2 - - '@changesets/assemble-release-plan@6.0.9': - dependencies: - '@changesets/errors': 0.2.0 - '@changesets/get-dependents-graph': 2.1.3 - '@changesets/should-skip-package': 0.1.2 - '@changesets/types': 6.1.0 - '@manypkg/get-packages': 1.1.3 - semver: 7.7.2 - - '@changesets/changelog-git@0.2.1': - dependencies: - '@changesets/types': 6.1.0 - - '@changesets/cli@2.29.6(@types/node@24.2.0)': - dependencies: - '@changesets/apply-release-plan': 7.0.12 - '@changesets/assemble-release-plan': 6.0.9 - '@changesets/changelog-git': 0.2.1 - '@changesets/config': 3.1.1 - '@changesets/errors': 0.2.0 - '@changesets/get-dependents-graph': 2.1.3 - '@changesets/get-release-plan': 4.0.13 - '@changesets/git': 3.0.4 - '@changesets/logger': 0.1.1 - '@changesets/pre': 2.0.2 - '@changesets/read': 0.6.5 - '@changesets/should-skip-package': 0.1.2 - '@changesets/types': 6.1.0 - '@changesets/write': 0.4.0 - '@inquirer/external-editor': 1.0.1(@types/node@24.2.0) - '@manypkg/get-packages': 1.1.3 - ansi-colors: 4.1.3 - ci-info: 3.9.0 - enquirer: 2.4.1 - fs-extra: 7.0.1 - mri: 1.2.0 - p-limit: 2.3.0 - package-manager-detector: 0.2.11 - picocolors: 1.1.1 - resolve-from: 5.0.0 - semver: 7.7.2 - spawndamnit: 3.0.1 - term-size: 2.2.1 - transitivePeerDependencies: - - '@types/node' - - '@changesets/config@3.1.1': - dependencies: - '@changesets/errors': 0.2.0 - '@changesets/get-dependents-graph': 2.1.3 - '@changesets/logger': 0.1.1 - '@changesets/types': 6.1.0 - '@manypkg/get-packages': 1.1.3 - fs-extra: 7.0.1 - micromatch: 4.0.8 - - '@changesets/errors@0.2.0': - dependencies: - extendable-error: 0.1.7 - - '@changesets/get-dependents-graph@2.1.3': - dependencies: - '@changesets/types': 6.1.0 - '@manypkg/get-packages': 1.1.3 - picocolors: 1.1.1 - semver: 7.7.2 - - '@changesets/get-release-plan@4.0.13': - dependencies: - '@changesets/assemble-release-plan': 6.0.9 - '@changesets/config': 3.1.1 - '@changesets/pre': 2.0.2 - '@changesets/read': 0.6.5 - '@changesets/types': 6.1.0 - '@manypkg/get-packages': 1.1.3 - - '@changesets/get-version-range-type@0.4.0': {} - - '@changesets/git@3.0.4': - dependencies: - '@changesets/errors': 0.2.0 - '@manypkg/get-packages': 1.1.3 - is-subdir: 1.2.0 - micromatch: 4.0.8 - spawndamnit: 3.0.1 - - '@changesets/logger@0.1.1': - dependencies: - picocolors: 1.1.1 - - '@changesets/parse@0.4.1': - dependencies: - '@changesets/types': 6.1.0 - js-yaml: 3.14.1 - - '@changesets/pre@2.0.2': - dependencies: - '@changesets/errors': 0.2.0 - '@changesets/types': 6.1.0 - '@manypkg/get-packages': 1.1.3 - fs-extra: 7.0.1 - - '@changesets/read@0.6.5': - dependencies: - '@changesets/git': 3.0.4 - '@changesets/logger': 0.1.1 - '@changesets/parse': 0.4.1 - '@changesets/types': 6.1.0 - fs-extra: 7.0.1 - p-filter: 2.1.0 - picocolors: 1.1.1 - - '@changesets/should-skip-package@0.1.2': - dependencies: - '@changesets/types': 6.1.0 - '@manypkg/get-packages': 1.1.3 - - '@changesets/types@4.1.0': {} - - '@changesets/types@6.1.0': {} - - '@changesets/write@0.4.0': - dependencies: - '@changesets/types': 6.1.0 - fs-extra: 7.0.1 - human-id: 4.1.1 - prettier: 2.8.8 - - '@esbuild/aix-ppc64@0.25.8': - optional: true - - '@esbuild/android-arm64@0.25.8': - optional: true - - '@esbuild/android-arm@0.25.8': - optional: true - - '@esbuild/android-x64@0.25.8': - optional: true - - '@esbuild/darwin-arm64@0.25.8': - optional: true - - '@esbuild/darwin-x64@0.25.8': - optional: true - - '@esbuild/freebsd-arm64@0.25.8': - optional: true - - '@esbuild/freebsd-x64@0.25.8': - optional: true - - '@esbuild/linux-arm64@0.25.8': - optional: true - - '@esbuild/linux-arm@0.25.8': - optional: true - - '@esbuild/linux-ia32@0.25.8': - optional: true - - '@esbuild/linux-loong64@0.25.8': - optional: true - - '@esbuild/linux-mips64el@0.25.8': - optional: true - - '@esbuild/linux-ppc64@0.25.8': - optional: true - - '@esbuild/linux-riscv64@0.25.8': - optional: true - - '@esbuild/linux-s390x@0.25.8': - optional: true - - '@esbuild/linux-x64@0.25.8': - optional: true - - '@esbuild/netbsd-arm64@0.25.8': - optional: true - - '@esbuild/netbsd-x64@0.25.8': - optional: true - - '@esbuild/openbsd-arm64@0.25.8': - optional: true - - '@esbuild/openbsd-x64@0.25.8': - optional: true - - '@esbuild/openharmony-arm64@0.25.8': - optional: true - - '@esbuild/sunos-x64@0.25.8': - optional: true - - '@esbuild/win32-arm64@0.25.8': - optional: true - - '@esbuild/win32-ia32@0.25.8': - optional: true - - '@esbuild/win32-x64@0.25.8': - optional: true - - '@eslint-community/eslint-utils@4.9.0(eslint@9.39.2)': - dependencies: - eslint: 9.39.2 - eslint-visitor-keys: 3.4.3 - - '@eslint-community/regexpp@4.12.2': {} - - '@eslint/config-array@0.21.1': - dependencies: - '@eslint/object-schema': 2.1.7 - debug: 4.4.1 - minimatch: 3.1.2 - transitivePeerDependencies: - - supports-color - - '@eslint/config-helpers@0.4.2': - dependencies: - '@eslint/core': 0.17.0 - - '@eslint/core@0.17.0': - dependencies: - '@types/json-schema': 7.0.15 - - '@eslint/eslintrc@3.3.3': - dependencies: - ajv: 6.12.6 - debug: 4.4.1 - espree: 10.4.0 - globals: 14.0.0 - ignore: 5.3.2 - import-fresh: 3.3.1 - js-yaml: 4.1.1 - minimatch: 3.1.2 - strip-json-comments: 3.1.1 - transitivePeerDependencies: - - supports-color - - '@eslint/js@9.39.2': {} - - '@eslint/object-schema@2.1.7': {} - - '@eslint/plugin-kit@0.4.1': - dependencies: - '@eslint/core': 0.17.0 - levn: 0.4.1 - - '@humanfs/core@0.19.1': {} - - '@humanfs/node@0.16.7': - dependencies: - '@humanfs/core': 0.19.1 - '@humanwhocodes/retry': 0.4.3 - - '@humanwhocodes/module-importer@1.0.1': {} - - '@humanwhocodes/retry@0.4.3': {} - - '@inquirer/ansi@1.0.0': {} - - '@inquirer/checkbox@4.2.0(@types/node@24.2.0)': - dependencies: - '@inquirer/core': 10.2.2(@types/node@24.2.0) - '@inquirer/figures': 1.0.13 - '@inquirer/type': 3.0.8(@types/node@24.2.0) - ansi-escapes: 4.3.2 - yoctocolors-cjs: 2.1.2 - optionalDependencies: - '@types/node': 24.2.0 - - '@inquirer/confirm@5.1.14(@types/node@24.2.0)': - dependencies: - '@inquirer/core': 10.2.2(@types/node@24.2.0) - '@inquirer/type': 3.0.8(@types/node@24.2.0) - optionalDependencies: - '@types/node': 24.2.0 - - '@inquirer/core@10.2.2(@types/node@24.2.0)': - dependencies: - '@inquirer/ansi': 1.0.0 - '@inquirer/figures': 1.0.13 - '@inquirer/type': 3.0.8(@types/node@24.2.0) - cli-width: 4.1.0 - mute-stream: 2.0.0 - signal-exit: 4.1.0 - wrap-ansi: 6.2.0 - yoctocolors-cjs: 2.1.2 - optionalDependencies: - '@types/node': 24.2.0 - - '@inquirer/editor@4.2.15(@types/node@24.2.0)': - dependencies: - '@inquirer/core': 10.2.2(@types/node@24.2.0) - '@inquirer/type': 3.0.8(@types/node@24.2.0) - external-editor: 3.1.0 - optionalDependencies: - '@types/node': 24.2.0 - - '@inquirer/expand@4.0.17(@types/node@24.2.0)': - dependencies: - '@inquirer/core': 10.2.2(@types/node@24.2.0) - '@inquirer/type': 3.0.8(@types/node@24.2.0) - yoctocolors-cjs: 2.1.2 - optionalDependencies: - '@types/node': 24.2.0 - - '@inquirer/external-editor@1.0.1(@types/node@24.2.0)': - dependencies: - chardet: 2.1.0 - iconv-lite: 0.6.3 - optionalDependencies: - '@types/node': 24.2.0 - - '@inquirer/figures@1.0.13': {} - - '@inquirer/input@4.2.1(@types/node@24.2.0)': - dependencies: - '@inquirer/core': 10.2.2(@types/node@24.2.0) - '@inquirer/type': 3.0.8(@types/node@24.2.0) - optionalDependencies: - '@types/node': 24.2.0 - - '@inquirer/number@3.0.17(@types/node@24.2.0)': - dependencies: - '@inquirer/core': 10.2.2(@types/node@24.2.0) - '@inquirer/type': 3.0.8(@types/node@24.2.0) - optionalDependencies: - '@types/node': 24.2.0 - - '@inquirer/password@4.0.17(@types/node@24.2.0)': - dependencies: - '@inquirer/core': 10.2.2(@types/node@24.2.0) - '@inquirer/type': 3.0.8(@types/node@24.2.0) - ansi-escapes: 4.3.2 - optionalDependencies: - '@types/node': 24.2.0 - - '@inquirer/prompts@7.8.0(@types/node@24.2.0)': - dependencies: - '@inquirer/checkbox': 4.2.0(@types/node@24.2.0) - '@inquirer/confirm': 5.1.14(@types/node@24.2.0) - '@inquirer/editor': 4.2.15(@types/node@24.2.0) - '@inquirer/expand': 4.0.17(@types/node@24.2.0) - '@inquirer/input': 4.2.1(@types/node@24.2.0) - '@inquirer/number': 3.0.17(@types/node@24.2.0) - '@inquirer/password': 4.0.17(@types/node@24.2.0) - '@inquirer/rawlist': 4.1.5(@types/node@24.2.0) - '@inquirer/search': 3.1.0(@types/node@24.2.0) - '@inquirer/select': 4.3.1(@types/node@24.2.0) - optionalDependencies: - '@types/node': 24.2.0 - - '@inquirer/rawlist@4.1.5(@types/node@24.2.0)': - dependencies: - '@inquirer/core': 10.2.2(@types/node@24.2.0) - '@inquirer/type': 3.0.8(@types/node@24.2.0) - yoctocolors-cjs: 2.1.2 - optionalDependencies: - '@types/node': 24.2.0 - - '@inquirer/search@3.1.0(@types/node@24.2.0)': - dependencies: - '@inquirer/core': 10.2.2(@types/node@24.2.0) - '@inquirer/figures': 1.0.13 - '@inquirer/type': 3.0.8(@types/node@24.2.0) - yoctocolors-cjs: 2.1.2 - optionalDependencies: - '@types/node': 24.2.0 - - '@inquirer/select@4.3.1(@types/node@24.2.0)': - dependencies: - '@inquirer/core': 10.2.2(@types/node@24.2.0) - '@inquirer/figures': 1.0.13 - '@inquirer/type': 3.0.8(@types/node@24.2.0) - ansi-escapes: 4.3.2 - yoctocolors-cjs: 2.1.2 - optionalDependencies: - '@types/node': 24.2.0 - - '@inquirer/type@3.0.8(@types/node@24.2.0)': - optionalDependencies: - '@types/node': 24.2.0 - - '@jridgewell/sourcemap-codec@1.5.4': {} - - '@manypkg/find-root@1.1.0': - dependencies: - '@babel/runtime': 7.28.4 - '@types/node': 12.20.55 - find-up: 4.1.0 - fs-extra: 8.1.0 - - '@manypkg/get-packages@1.1.3': - dependencies: - '@babel/runtime': 7.28.4 - '@changesets/types': 4.1.0 - '@manypkg/find-root': 1.1.0 - fs-extra: 8.1.0 - globby: 11.1.0 - read-yaml-file: 1.1.0 - - '@nodelib/fs.scandir@2.1.5': - dependencies: - '@nodelib/fs.stat': 2.0.5 - run-parallel: 1.2.0 - - '@nodelib/fs.stat@2.0.5': {} - - '@nodelib/fs.walk@1.2.8': - dependencies: - '@nodelib/fs.scandir': 2.1.5 - fastq: 1.19.1 - - '@polka/url@1.0.0-next.29': {} - - '@rollup/rollup-android-arm-eabi@4.46.2': - optional: true - - '@rollup/rollup-android-arm64@4.46.2': - optional: true - - '@rollup/rollup-darwin-arm64@4.46.2': - optional: true - - '@rollup/rollup-darwin-x64@4.46.2': - optional: true - - '@rollup/rollup-freebsd-arm64@4.46.2': - optional: true - - '@rollup/rollup-freebsd-x64@4.46.2': - optional: true - - '@rollup/rollup-linux-arm-gnueabihf@4.46.2': - optional: true - - '@rollup/rollup-linux-arm-musleabihf@4.46.2': - optional: true - - '@rollup/rollup-linux-arm64-gnu@4.46.2': - optional: true - - '@rollup/rollup-linux-arm64-musl@4.46.2': - optional: true - - '@rollup/rollup-linux-loongarch64-gnu@4.46.2': - optional: true - - '@rollup/rollup-linux-ppc64-gnu@4.46.2': - optional: true - - '@rollup/rollup-linux-riscv64-gnu@4.46.2': - optional: true - - '@rollup/rollup-linux-riscv64-musl@4.46.2': - optional: true - - '@rollup/rollup-linux-s390x-gnu@4.46.2': - optional: true - - '@rollup/rollup-linux-x64-gnu@4.46.2': - optional: true - - '@rollup/rollup-linux-x64-musl@4.46.2': - optional: true - - '@rollup/rollup-win32-arm64-msvc@4.46.2': - optional: true - - '@rollup/rollup-win32-ia32-msvc@4.46.2': - optional: true - - '@rollup/rollup-win32-x64-msvc@4.46.2': - optional: true - - '@types/chai@5.2.2': - dependencies: - '@types/deep-eql': 4.0.2 - - '@types/deep-eql@4.0.2': {} - - '@types/estree@1.0.8': {} - - '@types/json-schema@7.0.15': {} - - '@types/node@12.20.55': {} - - '@types/node@24.2.0': - dependencies: - undici-types: 7.10.0 - - '@typescript-eslint/eslint-plugin@8.50.1(@typescript-eslint/parser@8.50.1(eslint@9.39.2)(typescript@5.9.3))(eslint@9.39.2)(typescript@5.9.3)': - dependencies: - '@eslint-community/regexpp': 4.12.2 - '@typescript-eslint/parser': 8.50.1(eslint@9.39.2)(typescript@5.9.3) - '@typescript-eslint/scope-manager': 8.50.1 - '@typescript-eslint/type-utils': 8.50.1(eslint@9.39.2)(typescript@5.9.3) - '@typescript-eslint/utils': 8.50.1(eslint@9.39.2)(typescript@5.9.3) - '@typescript-eslint/visitor-keys': 8.50.1 - eslint: 9.39.2 - ignore: 7.0.5 - natural-compare: 1.4.0 - ts-api-utils: 2.1.0(typescript@5.9.3) - typescript: 5.9.3 - transitivePeerDependencies: - - supports-color - - '@typescript-eslint/parser@8.50.1(eslint@9.39.2)(typescript@5.9.3)': - dependencies: - '@typescript-eslint/scope-manager': 8.50.1 - '@typescript-eslint/types': 8.50.1 - '@typescript-eslint/typescript-estree': 8.50.1(typescript@5.9.3) - '@typescript-eslint/visitor-keys': 8.50.1 - debug: 4.4.1 - eslint: 9.39.2 - typescript: 5.9.3 - transitivePeerDependencies: - - supports-color - - '@typescript-eslint/project-service@8.50.1(typescript@5.9.3)': - dependencies: - '@typescript-eslint/tsconfig-utils': 8.50.1(typescript@5.9.3) - '@typescript-eslint/types': 8.50.1 - debug: 4.4.1 - typescript: 5.9.3 - transitivePeerDependencies: - - supports-color - - '@typescript-eslint/scope-manager@8.50.1': - dependencies: - '@typescript-eslint/types': 8.50.1 - '@typescript-eslint/visitor-keys': 8.50.1 - - '@typescript-eslint/tsconfig-utils@8.50.1(typescript@5.9.3)': - dependencies: - typescript: 5.9.3 - - '@typescript-eslint/type-utils@8.50.1(eslint@9.39.2)(typescript@5.9.3)': - dependencies: - '@typescript-eslint/types': 8.50.1 - '@typescript-eslint/typescript-estree': 8.50.1(typescript@5.9.3) - '@typescript-eslint/utils': 8.50.1(eslint@9.39.2)(typescript@5.9.3) - debug: 4.4.1 - eslint: 9.39.2 - ts-api-utils: 2.1.0(typescript@5.9.3) - typescript: 5.9.3 - transitivePeerDependencies: - - supports-color - - '@typescript-eslint/types@8.50.1': {} - - '@typescript-eslint/typescript-estree@8.50.1(typescript@5.9.3)': - dependencies: - '@typescript-eslint/project-service': 8.50.1(typescript@5.9.3) - '@typescript-eslint/tsconfig-utils': 8.50.1(typescript@5.9.3) - '@typescript-eslint/types': 8.50.1 - '@typescript-eslint/visitor-keys': 8.50.1 - debug: 4.4.1 - minimatch: 9.0.5 - semver: 7.7.2 - tinyglobby: 0.2.15 - ts-api-utils: 2.1.0(typescript@5.9.3) - typescript: 5.9.3 - transitivePeerDependencies: - - supports-color - - '@typescript-eslint/utils@8.50.1(eslint@9.39.2)(typescript@5.9.3)': - dependencies: - '@eslint-community/eslint-utils': 4.9.0(eslint@9.39.2) - '@typescript-eslint/scope-manager': 8.50.1 - '@typescript-eslint/types': 8.50.1 - '@typescript-eslint/typescript-estree': 8.50.1(typescript@5.9.3) - eslint: 9.39.2 - typescript: 5.9.3 - transitivePeerDependencies: - - supports-color - - '@typescript-eslint/visitor-keys@8.50.1': - dependencies: - '@typescript-eslint/types': 8.50.1 - eslint-visitor-keys: 4.2.1 - - '@vitest/expect@3.2.4': - dependencies: - '@types/chai': 5.2.2 - '@vitest/spy': 3.2.4 - '@vitest/utils': 3.2.4 - chai: 5.2.1 - tinyrainbow: 2.0.0 - - '@vitest/mocker@3.2.4(vite@7.0.6(@types/node@24.2.0)(yaml@2.8.2))': - dependencies: - '@vitest/spy': 3.2.4 - estree-walker: 3.0.3 - magic-string: 0.30.17 - optionalDependencies: - vite: 7.0.6(@types/node@24.2.0)(yaml@2.8.2) - - '@vitest/pretty-format@3.2.4': - dependencies: - tinyrainbow: 2.0.0 - - '@vitest/runner@3.2.4': - dependencies: - '@vitest/utils': 3.2.4 - pathe: 2.0.3 - strip-literal: 3.0.0 - - '@vitest/snapshot@3.2.4': - dependencies: - '@vitest/pretty-format': 3.2.4 - magic-string: 0.30.17 - pathe: 2.0.3 - - '@vitest/spy@3.2.4': - dependencies: - tinyspy: 4.0.3 - - '@vitest/ui@3.2.4(vitest@3.2.4)': - dependencies: - '@vitest/utils': 3.2.4 - fflate: 0.8.2 - flatted: 3.3.3 - pathe: 2.0.3 - sirv: 3.0.1 - tinyglobby: 0.2.14 - tinyrainbow: 2.0.0 - vitest: 3.2.4(@types/node@24.2.0)(@vitest/ui@3.2.4)(yaml@2.8.2) - - '@vitest/utils@3.2.4': - dependencies: - '@vitest/pretty-format': 3.2.4 - loupe: 3.2.0 - tinyrainbow: 2.0.0 - - acorn-jsx@5.3.2(acorn@8.15.0): - dependencies: - acorn: 8.15.0 - - acorn@8.15.0: {} - - ajv@6.12.6: - dependencies: - fast-deep-equal: 3.1.3 - fast-json-stable-stringify: 2.1.0 - json-schema-traverse: 0.4.1 - uri-js: 4.4.1 - - ansi-colors@4.1.3: {} - - ansi-escapes@4.3.2: - dependencies: - type-fest: 0.21.3 - - ansi-regex@5.0.1: {} - - ansi-regex@6.1.0: {} - - ansi-styles@4.3.0: - dependencies: - color-convert: 2.0.1 - - argparse@1.0.10: - dependencies: - sprintf-js: 1.0.3 - - argparse@2.0.1: {} - - array-union@2.1.0: {} - - assertion-error@2.0.1: {} - - balanced-match@1.0.2: {} - - better-path-resolve@1.0.0: - dependencies: - is-windows: 1.0.2 - - brace-expansion@1.1.12: - dependencies: - balanced-match: 1.0.2 - concat-map: 0.0.1 - - brace-expansion@2.0.2: - dependencies: - balanced-match: 1.0.2 - - braces@3.0.3: - dependencies: - fill-range: 7.1.1 - - cac@6.7.14: {} - - callsites@3.1.0: {} - - chai@5.2.1: - dependencies: - assertion-error: 2.0.1 - check-error: 2.1.1 - deep-eql: 5.0.2 - loupe: 3.2.0 - pathval: 2.0.1 - - chalk@4.1.2: - dependencies: - ansi-styles: 4.3.0 - supports-color: 7.2.0 - - chalk@5.5.0: {} - - chardet@0.7.0: {} - - chardet@2.1.0: {} - - check-error@2.1.1: {} - - ci-info@3.9.0: {} - - cli-cursor@5.0.0: - dependencies: - restore-cursor: 5.1.0 - - cli-spinners@2.9.2: {} - - cli-width@4.1.0: {} - - color-convert@2.0.1: - dependencies: - color-name: 1.1.4 - - color-name@1.1.4: {} - - commander@14.0.0: {} - - concat-map@0.0.1: {} - - cross-spawn@7.0.6: - dependencies: - path-key: 3.1.1 - shebang-command: 2.0.0 - which: 2.0.2 - - debug@4.4.1: - dependencies: - ms: 2.1.3 - - deep-eql@5.0.2: {} - - deep-is@0.1.4: {} - - detect-indent@6.1.0: {} - - dir-glob@3.0.1: - dependencies: - path-type: 4.0.0 - - emoji-regex@10.4.0: {} - - emoji-regex@8.0.0: {} - - enquirer@2.4.1: - dependencies: - ansi-colors: 4.1.3 - strip-ansi: 6.0.1 - - es-module-lexer@1.7.0: {} - - esbuild@0.25.8: - optionalDependencies: - '@esbuild/aix-ppc64': 0.25.8 - '@esbuild/android-arm': 0.25.8 - '@esbuild/android-arm64': 0.25.8 - '@esbuild/android-x64': 0.25.8 - '@esbuild/darwin-arm64': 0.25.8 - '@esbuild/darwin-x64': 0.25.8 - '@esbuild/freebsd-arm64': 0.25.8 - '@esbuild/freebsd-x64': 0.25.8 - '@esbuild/linux-arm': 0.25.8 - '@esbuild/linux-arm64': 0.25.8 - '@esbuild/linux-ia32': 0.25.8 - '@esbuild/linux-loong64': 0.25.8 - '@esbuild/linux-mips64el': 0.25.8 - '@esbuild/linux-ppc64': 0.25.8 - '@esbuild/linux-riscv64': 0.25.8 - '@esbuild/linux-s390x': 0.25.8 - '@esbuild/linux-x64': 0.25.8 - '@esbuild/netbsd-arm64': 0.25.8 - '@esbuild/netbsd-x64': 0.25.8 - '@esbuild/openbsd-arm64': 0.25.8 - '@esbuild/openbsd-x64': 0.25.8 - '@esbuild/openharmony-arm64': 0.25.8 - '@esbuild/sunos-x64': 0.25.8 - '@esbuild/win32-arm64': 0.25.8 - '@esbuild/win32-ia32': 0.25.8 - '@esbuild/win32-x64': 0.25.8 - - escape-string-regexp@4.0.0: {} - - eslint-scope@8.4.0: - dependencies: - esrecurse: 4.3.0 - estraverse: 5.3.0 - - eslint-visitor-keys@3.4.3: {} - - eslint-visitor-keys@4.2.1: {} - - eslint@9.39.2: - dependencies: - '@eslint-community/eslint-utils': 4.9.0(eslint@9.39.2) - '@eslint-community/regexpp': 4.12.2 - '@eslint/config-array': 0.21.1 - '@eslint/config-helpers': 0.4.2 - '@eslint/core': 0.17.0 - '@eslint/eslintrc': 3.3.3 - '@eslint/js': 9.39.2 - '@eslint/plugin-kit': 0.4.1 - '@humanfs/node': 0.16.7 - '@humanwhocodes/module-importer': 1.0.1 - '@humanwhocodes/retry': 0.4.3 - '@types/estree': 1.0.8 - ajv: 6.12.6 - chalk: 4.1.2 - cross-spawn: 7.0.6 - debug: 4.4.1 - escape-string-regexp: 4.0.0 - eslint-scope: 8.4.0 - eslint-visitor-keys: 4.2.1 - espree: 10.4.0 - esquery: 1.6.0 - esutils: 2.0.3 - fast-deep-equal: 3.1.3 - file-entry-cache: 8.0.0 - find-up: 5.0.0 - glob-parent: 6.0.2 - ignore: 5.3.2 - imurmurhash: 0.1.4 - is-glob: 4.0.3 - json-stable-stringify-without-jsonify: 1.0.1 - lodash.merge: 4.6.2 - minimatch: 3.1.2 - natural-compare: 1.4.0 - optionator: 0.9.4 - transitivePeerDependencies: - - supports-color - - espree@10.4.0: - dependencies: - acorn: 8.15.0 - acorn-jsx: 5.3.2(acorn@8.15.0) - eslint-visitor-keys: 4.2.1 - - esprima@4.0.1: {} - - esquery@1.6.0: - dependencies: - estraverse: 5.3.0 - - esrecurse@4.3.0: - dependencies: - estraverse: 5.3.0 - - estraverse@5.3.0: {} - - estree-walker@3.0.3: - dependencies: - '@types/estree': 1.0.8 - - esutils@2.0.3: {} - - expect-type@1.2.2: {} - - extendable-error@0.1.7: {} - - external-editor@3.1.0: - dependencies: - chardet: 0.7.0 - iconv-lite: 0.4.24 - tmp: 0.0.33 - - fast-deep-equal@3.1.3: {} - - fast-glob@3.3.3: - dependencies: - '@nodelib/fs.stat': 2.0.5 - '@nodelib/fs.walk': 1.2.8 - glob-parent: 5.1.2 - merge2: 1.4.1 - micromatch: 4.0.8 - - fast-json-stable-stringify@2.1.0: {} - - fast-levenshtein@2.0.6: {} - - fastq@1.19.1: - dependencies: - reusify: 1.1.0 - - fdir@6.4.6(picomatch@4.0.3): - optionalDependencies: - picomatch: 4.0.3 - - fdir@6.5.0(picomatch@4.0.3): - optionalDependencies: - picomatch: 4.0.3 - - fflate@0.8.2: {} - - file-entry-cache@8.0.0: - dependencies: - flat-cache: 4.0.1 - - fill-range@7.1.1: - dependencies: - to-regex-range: 5.0.1 - - find-up@4.1.0: - dependencies: - locate-path: 5.0.0 - path-exists: 4.0.0 - - find-up@5.0.0: - dependencies: - locate-path: 6.0.0 - path-exists: 4.0.0 - - flat-cache@4.0.1: - dependencies: - flatted: 3.3.3 - keyv: 4.5.4 - - flatted@3.3.3: {} - - fs-extra@7.0.1: - dependencies: - graceful-fs: 4.2.11 - jsonfile: 4.0.0 - universalify: 0.1.2 - - fs-extra@8.1.0: - dependencies: - graceful-fs: 4.2.11 - jsonfile: 4.0.0 - universalify: 0.1.2 - - fsevents@2.3.3: - optional: true - - get-east-asian-width@1.3.0: {} - - glob-parent@5.1.2: - dependencies: - is-glob: 4.0.3 - - glob-parent@6.0.2: - dependencies: - is-glob: 4.0.3 - - globals@14.0.0: {} - - globby@11.1.0: - dependencies: - array-union: 2.1.0 - dir-glob: 3.0.1 - fast-glob: 3.3.3 - ignore: 5.3.2 - merge2: 1.4.1 - slash: 3.0.0 - - graceful-fs@4.2.11: {} - - has-flag@4.0.0: {} - - human-id@4.1.1: {} - - iconv-lite@0.4.24: - dependencies: - safer-buffer: 2.1.2 - - iconv-lite@0.6.3: - dependencies: - safer-buffer: 2.1.2 - - ignore@5.3.2: {} - - ignore@7.0.5: {} - - import-fresh@3.3.1: - dependencies: - parent-module: 1.0.1 - resolve-from: 4.0.0 - - imurmurhash@0.1.4: {} - - is-extglob@2.1.1: {} - - is-fullwidth-code-point@3.0.0: {} - - is-glob@4.0.3: - dependencies: - is-extglob: 2.1.1 - - is-interactive@2.0.0: {} - - is-number@7.0.0: {} - - is-subdir@1.2.0: - dependencies: - better-path-resolve: 1.0.0 - - is-unicode-supported@1.3.0: {} - - is-unicode-supported@2.1.0: {} - - is-windows@1.0.2: {} - - isexe@2.0.0: {} - - js-tokens@9.0.1: {} - - js-yaml@3.14.1: - dependencies: - argparse: 1.0.10 - esprima: 4.0.1 - - js-yaml@4.1.1: - dependencies: - argparse: 2.0.1 - - json-buffer@3.0.1: {} - - json-schema-traverse@0.4.1: {} - - json-stable-stringify-without-jsonify@1.0.1: {} - - jsonfile@4.0.0: - optionalDependencies: - graceful-fs: 4.2.11 - - keyv@4.5.4: - dependencies: - json-buffer: 3.0.1 - - levn@0.4.1: - dependencies: - prelude-ls: 1.2.1 - type-check: 0.4.0 - - locate-path@5.0.0: - dependencies: - p-locate: 4.1.0 - - locate-path@6.0.0: - dependencies: - p-locate: 5.0.0 - - lodash.merge@4.6.2: {} - - lodash.startcase@4.4.0: {} - - log-symbols@6.0.0: - dependencies: - chalk: 5.5.0 - is-unicode-supported: 1.3.0 - - loupe@3.2.0: {} - - magic-string@0.30.17: - dependencies: - '@jridgewell/sourcemap-codec': 1.5.4 - - merge2@1.4.1: {} - - micromatch@4.0.8: - dependencies: - braces: 3.0.3 - picomatch: 2.3.1 - - mimic-function@5.0.1: {} - - minimatch@3.1.2: - dependencies: - brace-expansion: 1.1.12 - - minimatch@9.0.5: - dependencies: - brace-expansion: 2.0.2 - - mri@1.2.0: {} - - mrmime@2.0.1: {} - - ms@2.1.3: {} - - mute-stream@2.0.0: {} - - nanoid@3.3.11: {} - - natural-compare@1.4.0: {} - - onetime@7.0.0: - dependencies: - mimic-function: 5.0.1 - - optionator@0.9.4: - dependencies: - deep-is: 0.1.4 - fast-levenshtein: 2.0.6 - levn: 0.4.1 - prelude-ls: 1.2.1 - type-check: 0.4.0 - word-wrap: 1.2.5 - - ora@8.2.0: - dependencies: - chalk: 5.5.0 - cli-cursor: 5.0.0 - cli-spinners: 2.9.2 - is-interactive: 2.0.0 - is-unicode-supported: 2.1.0 - log-symbols: 6.0.0 - stdin-discarder: 0.2.2 - string-width: 7.2.0 - strip-ansi: 7.1.0 - - os-tmpdir@1.0.2: {} - - outdent@0.5.0: {} - - p-filter@2.1.0: - dependencies: - p-map: 2.1.0 - - p-limit@2.3.0: - dependencies: - p-try: 2.2.0 - - p-limit@3.1.0: - dependencies: - yocto-queue: 0.1.0 - - p-locate@4.1.0: - dependencies: - p-limit: 2.3.0 - - p-locate@5.0.0: - dependencies: - p-limit: 3.1.0 - - p-map@2.1.0: {} - - p-try@2.2.0: {} - - package-manager-detector@0.2.11: - dependencies: - quansync: 0.2.11 - - parent-module@1.0.1: - dependencies: - callsites: 3.1.0 - - path-exists@4.0.0: {} - - path-key@3.1.1: {} - - path-type@4.0.0: {} - - pathe@2.0.3: {} - - pathval@2.0.1: {} - - picocolors@1.1.1: {} - - picomatch@2.3.1: {} - - picomatch@4.0.3: {} - - pify@4.0.1: {} - - postcss@8.5.6: - dependencies: - nanoid: 3.3.11 - picocolors: 1.1.1 - source-map-js: 1.2.1 - - prelude-ls@1.2.1: {} - - prettier@2.8.8: {} - - punycode@2.3.1: {} - - quansync@0.2.11: {} - - queue-microtask@1.2.3: {} - - read-yaml-file@1.1.0: - dependencies: - graceful-fs: 4.2.11 - js-yaml: 3.14.1 - pify: 4.0.1 - strip-bom: 3.0.0 - - resolve-from@4.0.0: {} - - resolve-from@5.0.0: {} - - restore-cursor@5.1.0: - dependencies: - onetime: 7.0.0 - signal-exit: 4.1.0 - - reusify@1.1.0: {} - - rollup@4.46.2: - dependencies: - '@types/estree': 1.0.8 - optionalDependencies: - '@rollup/rollup-android-arm-eabi': 4.46.2 - '@rollup/rollup-android-arm64': 4.46.2 - '@rollup/rollup-darwin-arm64': 4.46.2 - '@rollup/rollup-darwin-x64': 4.46.2 - '@rollup/rollup-freebsd-arm64': 4.46.2 - '@rollup/rollup-freebsd-x64': 4.46.2 - '@rollup/rollup-linux-arm-gnueabihf': 4.46.2 - '@rollup/rollup-linux-arm-musleabihf': 4.46.2 - '@rollup/rollup-linux-arm64-gnu': 4.46.2 - '@rollup/rollup-linux-arm64-musl': 4.46.2 - '@rollup/rollup-linux-loongarch64-gnu': 4.46.2 - '@rollup/rollup-linux-ppc64-gnu': 4.46.2 - '@rollup/rollup-linux-riscv64-gnu': 4.46.2 - '@rollup/rollup-linux-riscv64-musl': 4.46.2 - '@rollup/rollup-linux-s390x-gnu': 4.46.2 - '@rollup/rollup-linux-x64-gnu': 4.46.2 - '@rollup/rollup-linux-x64-musl': 4.46.2 - '@rollup/rollup-win32-arm64-msvc': 4.46.2 - '@rollup/rollup-win32-ia32-msvc': 4.46.2 - '@rollup/rollup-win32-x64-msvc': 4.46.2 - fsevents: 2.3.3 - - run-parallel@1.2.0: - dependencies: - queue-microtask: 1.2.3 - - safer-buffer@2.1.2: {} - - semver@7.7.2: {} - - shebang-command@2.0.0: - dependencies: - shebang-regex: 3.0.0 - - shebang-regex@3.0.0: {} - - siginfo@2.0.0: {} - - signal-exit@4.1.0: {} - - sirv@3.0.1: - dependencies: - '@polka/url': 1.0.0-next.29 - mrmime: 2.0.1 - totalist: 3.0.1 - - slash@3.0.0: {} - - source-map-js@1.2.1: {} - - spawndamnit@3.0.1: - dependencies: - cross-spawn: 7.0.6 - signal-exit: 4.1.0 - - sprintf-js@1.0.3: {} - - stackback@0.0.2: {} - - std-env@3.9.0: {} - - stdin-discarder@0.2.2: {} - - string-width@4.2.3: - dependencies: - emoji-regex: 8.0.0 - is-fullwidth-code-point: 3.0.0 - strip-ansi: 6.0.1 - - string-width@7.2.0: - dependencies: - emoji-regex: 10.4.0 - get-east-asian-width: 1.3.0 - strip-ansi: 7.1.0 - - strip-ansi@6.0.1: - dependencies: - ansi-regex: 5.0.1 - - strip-ansi@7.1.0: - dependencies: - ansi-regex: 6.1.0 - - strip-bom@3.0.0: {} - - strip-json-comments@3.1.1: {} - - strip-literal@3.0.0: - dependencies: - js-tokens: 9.0.1 - - supports-color@7.2.0: - dependencies: - has-flag: 4.0.0 - - term-size@2.2.1: {} - - tinybench@2.9.0: {} - - tinyexec@0.3.2: {} - - tinyglobby@0.2.14: - dependencies: - fdir: 6.4.6(picomatch@4.0.3) - picomatch: 4.0.3 - - tinyglobby@0.2.15: - dependencies: - fdir: 6.5.0(picomatch@4.0.3) - picomatch: 4.0.3 - - tinypool@1.1.1: {} - - tinyrainbow@2.0.0: {} - - tinyspy@4.0.3: {} - - tmp@0.0.33: - dependencies: - os-tmpdir: 1.0.2 - - to-regex-range@5.0.1: - dependencies: - is-number: 7.0.0 - - totalist@3.0.1: {} - - ts-api-utils@2.1.0(typescript@5.9.3): - dependencies: - typescript: 5.9.3 - - type-check@0.4.0: - dependencies: - prelude-ls: 1.2.1 - - type-fest@0.21.3: {} - - typescript-eslint@8.50.1(eslint@9.39.2)(typescript@5.9.3): - dependencies: - '@typescript-eslint/eslint-plugin': 8.50.1(@typescript-eslint/parser@8.50.1(eslint@9.39.2)(typescript@5.9.3))(eslint@9.39.2)(typescript@5.9.3) - '@typescript-eslint/parser': 8.50.1(eslint@9.39.2)(typescript@5.9.3) - '@typescript-eslint/typescript-estree': 8.50.1(typescript@5.9.3) - '@typescript-eslint/utils': 8.50.1(eslint@9.39.2)(typescript@5.9.3) - eslint: 9.39.2 - typescript: 5.9.3 - transitivePeerDependencies: - - supports-color - - typescript@5.9.3: {} - - undici-types@7.10.0: {} - - universalify@0.1.2: {} - - uri-js@4.4.1: - dependencies: - punycode: 2.3.1 - - vite-node@3.2.4(@types/node@24.2.0)(yaml@2.8.2): - dependencies: - cac: 6.7.14 - debug: 4.4.1 - es-module-lexer: 1.7.0 - pathe: 2.0.3 - vite: 7.0.6(@types/node@24.2.0)(yaml@2.8.2) - transitivePeerDependencies: - - '@types/node' - - jiti - - less - - lightningcss - - sass - - sass-embedded - - stylus - - sugarss - - supports-color - - terser - - tsx - - yaml - - vite@7.0.6(@types/node@24.2.0)(yaml@2.8.2): - dependencies: - esbuild: 0.25.8 - fdir: 6.4.6(picomatch@4.0.3) - picomatch: 4.0.3 - postcss: 8.5.6 - rollup: 4.46.2 - tinyglobby: 0.2.14 - optionalDependencies: - '@types/node': 24.2.0 - fsevents: 2.3.3 - yaml: 2.8.2 - - vitest@3.2.4(@types/node@24.2.0)(@vitest/ui@3.2.4)(yaml@2.8.2): - dependencies: - '@types/chai': 5.2.2 - '@vitest/expect': 3.2.4 - '@vitest/mocker': 3.2.4(vite@7.0.6(@types/node@24.2.0)(yaml@2.8.2)) - '@vitest/pretty-format': 3.2.4 - '@vitest/runner': 3.2.4 - '@vitest/snapshot': 3.2.4 - '@vitest/spy': 3.2.4 - '@vitest/utils': 3.2.4 - chai: 5.2.1 - debug: 4.4.1 - expect-type: 1.2.2 - magic-string: 0.30.17 - pathe: 2.0.3 - picomatch: 4.0.3 - std-env: 3.9.0 - tinybench: 2.9.0 - tinyexec: 0.3.2 - tinyglobby: 0.2.14 - tinypool: 1.1.1 - tinyrainbow: 2.0.0 - vite: 7.0.6(@types/node@24.2.0)(yaml@2.8.2) - vite-node: 3.2.4(@types/node@24.2.0)(yaml@2.8.2) - why-is-node-running: 2.3.0 - optionalDependencies: - '@types/node': 24.2.0 - '@vitest/ui': 3.2.4(vitest@3.2.4) - transitivePeerDependencies: - - jiti - - less - - lightningcss - - msw - - sass - - sass-embedded - - stylus - - sugarss - - supports-color - - terser - - tsx - - yaml - - which@2.0.2: - dependencies: - isexe: 2.0.0 - - why-is-node-running@2.3.0: - dependencies: - siginfo: 2.0.0 - stackback: 0.0.2 - - word-wrap@1.2.5: {} - - wrap-ansi@6.2.0: - dependencies: - ansi-styles: 4.3.0 - string-width: 4.2.3 - strip-ansi: 6.0.1 - - yaml@2.8.2: {} - - yocto-queue@0.1.0: {} - - yoctocolors-cjs@2.1.2: {} - - zod@4.0.17: {} diff --git a/scripts/pack-version-check.mjs b/scripts/pack-version-check.mjs deleted file mode 100644 index 43cf8050e..000000000 --- a/scripts/pack-version-check.mjs +++ /dev/null @@ -1,111 +0,0 @@ -#!/usr/bin/env node -// Guard: Ensure the packed tarball's CLI `--version` matches package.json. -// -// Notes: -// - We intentionally use `npm pack` (not pnpm) because `npm pack --json` is -// consistently supported and returns the tarball metadata we need. The -// project uses pnpm for install/publish, but this guard only needs to pack -// locally and verify the installed CLI output. -// - `npm pack` triggers the package's `prepare` script (build), and -// `changeset publish` triggers `prepublishOnly` (also builds here). This -// means an explicit build is not strictly necessary for the guard. - -import { execFileSync } from 'child_process'; -import { mkdtempSync, readFileSync, rmSync, writeFileSync } from 'fs'; -import { tmpdir } from 'os'; -import path from 'path'; - -function log(msg) { - if (process.env.CI) return; // keep CI logs quiet by default - console.log(msg); -} - -function run(cmd, args, opts = {}) { - return execFileSync(cmd, args, { encoding: 'utf-8', stdio: ['ignore', 'pipe', 'pipe'], ...opts }); -} - -function npmPack() { - try { - const jsonOut = run('npm', ['pack', '--json', '--silent']); - const arr = JSON.parse(jsonOut); - if (Array.isArray(arr) && arr.length > 0) { - const last = arr[arr.length - 1]; - const file = (last && typeof last === 'object' && last.filename) || (typeof last === 'string' ? last : null); - if (file) return String(file).trim(); - } - // Unexpected JSON shape or empty array; fallback to plain output - const out = run('npm', ['pack', '--silent']).trim(); - const lines = out.split(/\r?\n/); - return lines[lines.length - 1].trim(); - } catch (e) { - // Fallback for environments not supporting --json - const out = run('npm', ['pack', '--silent']).trim(); - const lines = out.split(/\r?\n/); - return lines[lines.length - 1].trim(); - } -} - -function main() { - const pkg = JSON.parse(readFileSync(path.join(process.cwd(), 'package.json'), 'utf-8')); - const expected = pkg.version; - - let work; - let tgzPath; - - try { - log(`Packing @fission-ai/openspec@${expected}...`); - const filename = npmPack(); - tgzPath = path.resolve(filename); - log(`Created: ${tgzPath}`); - - work = mkdtempSync(path.join(tmpdir(), 'openspec-pack-check-')); - log(`Temp dir: ${work}`); - - // Make a tiny project - writeFileSync( - path.join(work, 'package.json'), - JSON.stringify({ name: 'pack-check', private: true }, null, 2) - ); - - // Try to avoid noisy output and speed up - const env = { - ...process.env, - npm_config_loglevel: 'silent', - npm_config_audit: 'false', - npm_config_fund: 'false', - npm_config_progress: 'false', - }; - - // Install the tarball - run('npm', ['install', tgzPath, '--silent', '--no-audit', '--no-fund'], { cwd: work, env }); - - // Run the installed CLI via Node to avoid bin resolution/platform issues - const binRel = path.join('node_modules', '@fission-ai', 'openspec', 'bin', 'openspec.js'); - const actual = run(process.execPath, [binRel, '--version'], { cwd: work }).trim(); - - if (actual !== expected) { - throw new Error( - `Packed CLI version mismatch: expected ${expected}, got ${actual}. ` + - 'Ensure the dist is built and the CLI reads version from package.json.' - ); - } - - log('Version check passed.'); - } finally { - // Always attempt cleanup - if (work) { - try { rmSync(work, { recursive: true, force: true }); } catch {} - } - if (tgzPath) { - try { rmSync(tgzPath, { force: true }); } catch {} - } - } -} - -try { - main(); - console.log('✅ pack-version-check: OK'); -} catch (err) { - console.error(`❌ pack-version-check: ${err.message}`); - process.exit(1); -} diff --git a/scripts/pack-version-check.ts b/scripts/pack-version-check.ts new file mode 100644 index 000000000..8456030d5 --- /dev/null +++ b/scripts/pack-version-check.ts @@ -0,0 +1,73 @@ +#!/usr/bin/env bun + +import { execFileSync } from 'child_process'; +import { mkdtempSync, readFileSync, rmSync, writeFileSync } from 'fs'; +import { tmpdir } from 'os'; +import path from 'path'; + +function log(msg: string): void { + if (process.env.CI) return; + console.log(msg); +} + +function run(cmd: string, args: string[], opts: Record = {}): string { + return execFileSync(cmd, args, { encoding: 'utf-8', stdio: ['ignore', 'pipe', 'pipe'], ...opts }); +} + +function bunPack(): string { + const out = run('bun', ['pm', 'pack']).trim(); + const lines = out.split(/\r?\n/); + return lines[lines.length - 1].trim(); +} + +function main(): void { + const pkg = JSON.parse(readFileSync(path.join(process.cwd(), 'package.json'), 'utf-8')); + const expected = pkg.version; + + let work: string | undefined; + let tgzPath: string | undefined; + + try { + log(`Packing @clanker-guru/openspec@${expected}...`); + const filename = bunPack(); + tgzPath = path.resolve(filename); + log(`Created: ${tgzPath}`); + + work = mkdtempSync(path.join(tmpdir(), 'openspec-pack-check-')); + log(`Temp dir: ${work}`); + + writeFileSync( + path.join(work, 'package.json'), + JSON.stringify({ name: 'pack-check', private: true }, null, 2) + ); + + run('bun', ['add', tgzPath], { cwd: work }); + + const binRel = path.join('node_modules', '@clanker-guru', 'openspec', 'bin', 'openspec.ts'); + const actual = run('bun', [binRel, '--version'], { cwd: work }).trim(); + + if (actual !== expected) { + throw new Error( + `Packed CLI version mismatch: expected ${expected}, got ${actual}. ` + + 'Ensure the dist is built and the CLI reads version from package.json.' + ); + } + + log('Version check passed.'); + } finally { + if (work) { + try { rmSync(work, { recursive: true, force: true }); } catch {} + } + if (tgzPath) { + try { rmSync(tgzPath, { force: true }); } catch {} + } + } +} + +try { + main(); + console.log('✅ pack-version-check: OK'); +} catch (err) { + console.error(`❌ pack-version-check: ${(err as Error).message}`); + process.exit(1); +} diff --git a/scripts/postinstall.js b/scripts/postinstall.ts similarity index 62% rename from scripts/postinstall.js rename to scripts/postinstall.ts index bfe6e1238..58c18e68c 100644 --- a/scripts/postinstall.js +++ b/scripts/postinstall.ts @@ -1,15 +1,4 @@ -#!/usr/bin/env node - -/** - * Postinstall script for auto-installing shell completions - * - * This script runs automatically after npm install unless: - * - CI=true environment variable is set - * - OPENSPEC_NO_COMPLETIONS=1 environment variable is set - * - dist/ directory doesn't exist (dev setup scenario) - * - * The script never fails npm install - all errors are caught and handled gracefully. - */ +#!/usr/bin/env bun import { promises as fs } from 'fs'; import path from 'path'; @@ -18,16 +7,11 @@ import { fileURLToPath } from 'url'; const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); -/** - * Check if we should skip installation - */ -function shouldSkipInstallation() { - // Skip in CI environments +function shouldSkipInstallation(): { skip: boolean; reason?: string } { if (process.env.CI === 'true' || process.env.CI === '1') { return { skip: true, reason: 'CI environment detected' }; } - // Skip if user opted out if (process.env.OPENSPEC_NO_COMPLETIONS === '1') { return { skip: true, reason: 'OPENSPEC_NO_COMPLETIONS=1 set' }; } @@ -35,10 +19,7 @@ function shouldSkipInstallation() { return { skip: false }; } -/** - * Check if dist/ directory exists - */ -async function distExists() { +async function distExists(): Promise { const distPath = path.join(__dirname, '..', 'dist'); try { const stat = await fs.stat(distPath); @@ -48,44 +29,33 @@ async function distExists() { } } -/** - * Detect the user's shell - */ -async function detectShell() { +async function detectShell(): Promise { try { const { detectShell } = await import('../dist/utils/shell-detection.js'); const result = detectShell(); return result.shell; - } catch (error) { - // Fail silently if detection module doesn't exist + } catch { return undefined; } } -/** - * Install completions for the detected shell - */ -async function installCompletions(shell) { +async function installCompletions(shell: string): Promise { try { const { CompletionFactory } = await import('../dist/core/completions/factory.js'); const { COMMAND_REGISTRY } = await import('../dist/core/completions/command-registry.js'); - // Check if shell is supported if (!CompletionFactory.isSupported(shell)) { console.log(`\nTip: Run 'openspec completion install' for shell completions`); return; } - // Generate completion script const generator = CompletionFactory.createGenerator(shell); const script = generator.generate(COMMAND_REGISTRY); - // Install completion script const installer = CompletionFactory.createInstaller(shell); const result = await installer.install(script); if (result.success) { - // Show success message based on installation type if (result.isOhMyZsh) { console.log(`✓ Shell completions installed`); console.log(` Restart shell: exec zsh`); @@ -98,50 +68,36 @@ async function installCompletions(shell) { console.log(` Then: exec zsh`); } } else { - // Installation failed, show tip for manual install console.log(`\nTip: Run 'openspec completion install' for shell completions`); } - } catch (error) { - // Fail gracefully - show tip for manual install + } catch { console.log(`\nTip: Run 'openspec completion install' for shell completions`); } } -/** - * Main function - */ -async function main() { +async function main(): Promise { try { - // Check if we should skip const skipCheck = shouldSkipInstallation(); if (skipCheck.skip) { - // Silent skip - no output return; } - // Check if dist/ exists (skip silently if not - expected during dev setup) if (!(await distExists())) { return; } - // Detect shell const shell = await detectShell(); if (!shell) { console.log(`\nTip: Run 'openspec completion install' for shell completions`); return; } - // Install completions await installCompletions(shell); - } catch (error) { - // Fail gracefully - never break npm install - // Show tip for manual install + } catch { console.log(`\nTip: Run 'openspec completion install' for shell completions`); } } -// Run main and handle any unhandled errors main().catch(() => { - // Silent failure - never break npm install process.exit(0); }); diff --git a/src/core/init.ts b/src/core/init.ts index ebc98c9c8..9d1ff5837 100644 --- a/src/core/init.ts +++ b/src/core/init.ts @@ -13,7 +13,8 @@ import { import chalk from 'chalk'; import ora from 'ora'; import { FileSystemUtils } from '../utils/file-system.js'; -import { TemplateManager, ProjectContext } from './templates/index.js'; +import { TemplateManager } from './templates/index.js'; +import type { ProjectContext } from './templates/index.js'; import { ToolRegistry } from './configurators/registry.js'; import { SlashCommandRegistry } from './configurators/slash/registry.js'; import { diff --git a/src/core/templates/index.ts b/src/core/templates/index.ts index 8dab4b5f6..1c0deb978 100644 --- a/src/core/templates/index.ts +++ b/src/core/templates/index.ts @@ -46,5 +46,5 @@ export class TemplateManager { } } -export { ProjectContext } from './project-template.js'; +export type { ProjectContext } from './project-template.js'; export type { SlashCommandId } from './slash-command-templates.js'; diff --git a/test/cli-e2e/basic.test.ts b/test/cli-e2e/basic.test.ts index 3f0af11bd..9d2432fbc 100644 --- a/test/cli-e2e/basic.test.ts +++ b/test/cli-e2e/basic.test.ts @@ -1,10 +1,12 @@ -import { afterAll, describe, it, expect } from 'vitest'; +import { afterAll, describe, it, expect } from 'bun:test'; import { promises as fs } from 'fs'; import path from 'path'; import { tmpdir } from 'os'; import { runCLI, cliProjectRoot } from '../helpers/run-cli.js'; import { AI_TOOLS } from '../../src/core/config.js'; +const isWindows = process.platform === 'win32'; + async function fileExists(filePath: string): Promise { try { await fs.access(filePath); @@ -30,7 +32,7 @@ afterAll(async () => { await Promise.all(tempRoots.map((dir) => fs.rm(dir, { recursive: true, force: true }))); }); -describe('openspec CLI e2e basics', () => { +describe.skipIf(isWindows)('openspec CLI e2e basics', () => { it('shows help output', async () => { const result = await runCLI(['--help']); expect(result.exitCode).toBe(0); diff --git a/test/commands/change.interactive-show.test.ts b/test/commands/change.interactive-show.test.ts index b4dee52d5..48fc23f23 100644 --- a/test/commands/change.interactive-show.test.ts +++ b/test/commands/change.interactive-show.test.ts @@ -1,16 +1,20 @@ -import { describe, it, expect, beforeEach, afterEach } from 'vitest'; +import { describe, it, expect, beforeEach, afterEach } from 'bun:test'; import { promises as fs } from 'fs'; import path from 'path'; import { execSync } from 'child_process'; +import os from 'os'; +import { randomUUID } from 'crypto'; describe('change show (interactive behavior)', () => { const projectRoot = process.cwd(); - const testDir = path.join(projectRoot, 'test-change-show-tmp'); - const changesDir = path.join(testDir, 'openspec', 'changes'); - const bin = path.join(projectRoot, 'bin', 'openspec.js'); + let testDir: string; + let changesDir: string; + const bin = path.join(projectRoot, 'bin', 'openspec.ts'); beforeEach(async () => { + testDir = path.join(os.tmpdir(), `openspec-test-${randomUUID()}`); + changesDir = path.join(testDir, 'openspec', 'changes'); await fs.mkdir(changesDir, { recursive: true }); const content = `# Change: Demo\n\n## Why\n\n## What Changes\n- x`; await fs.mkdir(path.join(changesDir, 'demo'), { recursive: true }); @@ -29,7 +33,7 @@ describe('change show (interactive behavior)', () => { process.env.OPEN_SPEC_INTERACTIVE = '0'; let err: any; try { - execSync(`node ${bin} change show`, { encoding: 'utf-8' }); + execSync(`bun ${bin} change show`, { encoding: 'utf-8' }); } catch (e) { err = e; } expect(err).toBeDefined(); expect(err.status).not.toBe(0); diff --git a/test/commands/change.interactive-validate.test.ts b/test/commands/change.interactive-validate.test.ts index 33484ab2b..1a1c06d2b 100644 --- a/test/commands/change.interactive-validate.test.ts +++ b/test/commands/change.interactive-validate.test.ts @@ -1,19 +1,20 @@ -import { describe, it, expect, beforeEach, afterEach } from 'vitest'; +import { describe, it, expect, beforeEach, afterEach } from 'bun:test'; import { promises as fs } from 'fs'; import path from 'path'; import { execSync } from 'child_process'; - -// Note: We cannot truly simulate TTY prompts in this test runner easily. -// Instead, we verify non-interactive fallback behavior and basic invocation. +import os from 'os'; +import { randomUUID } from 'crypto'; describe('change validate (interactive behavior)', () => { const projectRoot = process.cwd(); - const testDir = path.join(projectRoot, 'test-change-validate-tmp'); - const changesDir = path.join(testDir, 'openspec', 'changes'); - const bin = path.join(projectRoot, 'bin', 'openspec.js'); + let testDir: string; + let changesDir: string; + const bin = path.join(projectRoot, 'bin', 'openspec.ts'); beforeEach(async () => { + testDir = path.join(os.tmpdir(), `openspec-test-${randomUUID()}`); + changesDir = path.join(testDir, 'openspec', 'changes'); await fs.mkdir(changesDir, { recursive: true }); const content = `# Change: Demo\n\n## Why\nBecause reasons that are sufficiently long.\n\n## What Changes\n- **spec-x:** Add something`; await fs.mkdir(path.join(changesDir, 'demo'), { recursive: true }); @@ -32,7 +33,7 @@ describe('change validate (interactive behavior)', () => { process.env.OPEN_SPEC_INTERACTIVE = '0'; let err: any; try { - execSync(`node ${bin} change validate`, { encoding: 'utf-8' }); + execSync(`bun ${bin} change validate`, { encoding: 'utf-8' }); } catch (e) { err = e; } expect(err).toBeDefined(); expect(err.status).not.toBe(0); diff --git a/test/commands/completion.test.ts b/test/commands/completion.test.ts index 0afef5d36..45f6ccedc 100644 --- a/test/commands/completion.test.ts +++ b/test/commands/completion.test.ts @@ -1,49 +1,49 @@ -import { describe, it, expect, beforeEach, vi, afterEach } from 'vitest'; +import { describe, it, expect, beforeEach, afterEach, spyOn } from 'bun:test'; import { CompletionCommand } from '../../src/commands/completion.js'; import * as shellDetection from '../../src/utils/shell-detection.js'; - -// Mock the shell detection module -vi.mock('../../src/utils/shell-detection.js', () => ({ - detectShell: vi.fn(), -})); - -// Mock the ZshInstaller -vi.mock('../../src/core/completions/installers/zsh-installer.js', () => ({ - ZshInstaller: vi.fn().mockImplementation(() => ({ - install: vi.fn().mockResolvedValue({ - success: true, - installedPath: '/home/user/.oh-my-zsh/completions/_openspec', - isOhMyZsh: true, - message: 'Completion script installed successfully for Oh My Zsh', - instructions: [ - 'Completion script installed to Oh My Zsh completions directory.', - 'Restart your shell or run: exec zsh', - 'Completions should activate automatically.', - ], - }), - uninstall: vi.fn().mockResolvedValue({ - success: true, - message: 'Completion script removed from /home/user/.oh-my-zsh/completions/_openspec', - }), - })), -})); +import { ZshInstaller } from '../../src/core/completions/installers/zsh-installer.js'; + +const mockInstallResult = { + success: true, + installedPath: '/home/user/.oh-my-zsh/completions/_openspec', + isOhMyZsh: true, + message: 'Completion script installed successfully for Oh My Zsh', + instructions: [ + 'Completion script installed to Oh My Zsh completions directory.', + 'Restart your shell or run: exec zsh', + 'Completions should activate automatically.', + ], +}; + +const mockUninstallResult = { + success: true, + message: 'Completion script removed from /home/user/.oh-my-zsh/completions/_openspec', +}; describe('CompletionCommand', () => { - let command: CompletionCommand; - let consoleLogSpy: any; - let consoleErrorSpy: any; + let command: InstanceType; + let consoleLogSpy: ReturnType; + let consoleErrorSpy: ReturnType; + let detectShellSpy: ReturnType; + let installSpy: ReturnType; + let uninstallSpy: ReturnType; beforeEach(() => { command = new CompletionCommand(); - consoleLogSpy = vi.spyOn(console, 'log').mockImplementation(() => {}); - consoleErrorSpy = vi.spyOn(console, 'error').mockImplementation(() => {}); + consoleLogSpy = spyOn(console, 'log').mockImplementation(() => {}); + consoleErrorSpy = spyOn(console, 'error').mockImplementation(() => {}); + detectShellSpy = spyOn(shellDetection, 'detectShell').mockReturnValue({ shell: 'zsh', detected: 'zsh' }); + installSpy = spyOn(ZshInstaller.prototype, 'install').mockResolvedValue(mockInstallResult as any); + uninstallSpy = spyOn(ZshInstaller.prototype, 'uninstall').mockResolvedValue(mockUninstallResult); process.exitCode = 0; }); afterEach(() => { consoleLogSpy.mockRestore(); consoleErrorSpy.mockRestore(); - vi.clearAllMocks(); + detectShellSpy.mockRestore(); + installSpy.mockRestore(); + uninstallSpy.mockRestore(); }); describe('generate subcommand', () => { @@ -57,7 +57,7 @@ describe('CompletionCommand', () => { }); it('should auto-detect Zsh shell when no shell specified', async () => { - vi.mocked(shellDetection.detectShell).mockReturnValue({ shell: 'zsh', detected: 'zsh' }); + detectShellSpy.mockReturnValue({ shell: 'zsh', detected: 'zsh' }); await command.generate({}); @@ -67,7 +67,7 @@ describe('CompletionCommand', () => { }); it('should show error when shell cannot be auto-detected', async () => { - vi.mocked(shellDetection.detectShell).mockReturnValue({ shell: undefined, detected: undefined }); + detectShellSpy.mockReturnValue({ shell: undefined, detected: undefined }); await command.generate({}); @@ -114,7 +114,7 @@ describe('CompletionCommand', () => { }); it('should auto-detect Zsh shell when no shell specified', async () => { - vi.mocked(shellDetection.detectShell).mockReturnValue({ shell: 'zsh', detected: 'zsh' }); + detectShellSpy.mockReturnValue({ shell: 'zsh', detected: 'zsh' }); await command.install({}); @@ -124,7 +124,7 @@ describe('CompletionCommand', () => { }); it('should show error when shell cannot be auto-detected', async () => { - vi.mocked(shellDetection.detectShell).mockReturnValue({ shell: undefined, detected: undefined }); + detectShellSpy.mockReturnValue({ shell: undefined, detected: undefined }); await command.install({}); @@ -163,7 +163,7 @@ describe('CompletionCommand', () => { }); it('should auto-detect Zsh shell when no shell specified', async () => { - vi.mocked(shellDetection.detectShell).mockReturnValue({ shell: 'zsh', detected: 'zsh' }); + detectShellSpy.mockReturnValue({ shell: 'zsh', detected: 'zsh' }); await command.uninstall({ yes: true }); @@ -173,7 +173,7 @@ describe('CompletionCommand', () => { }); it('should show error when shell cannot be auto-detected', async () => { - vi.mocked(shellDetection.detectShell).mockReturnValue({ shell: undefined, detected: undefined }); + detectShellSpy.mockReturnValue({ shell: undefined, detected: undefined }); await command.uninstall({ yes: true }); @@ -195,20 +195,11 @@ describe('CompletionCommand', () => { describe('error handling', () => { it('should handle installation failures gracefully', async () => { - const { ZshInstaller } = await import('../../src/core/completions/installers/zsh-installer.js'); - vi.mocked(ZshInstaller).mockImplementationOnce(() => ({ - install: vi.fn().mockResolvedValue({ - success: false, - isOhMyZsh: false, - message: 'Permission denied', - }), - uninstall: vi.fn(), - isInstalled: vi.fn(), - getInstallationInfo: vi.fn(), - isOhMyZshInstalled: vi.fn(), - getInstallationPath: vi.fn(), - backupExistingFile: vi.fn(), - } as any)); + installSpy.mockResolvedValueOnce({ + success: false, + isOhMyZsh: false, + message: 'Permission denied', + } as any); const cmd = new CompletionCommand(); await cmd.install({ shell: 'zsh' }); @@ -220,19 +211,10 @@ describe('CompletionCommand', () => { }); it('should handle uninstallation failures gracefully', async () => { - const { ZshInstaller } = await import('../../src/core/completions/installers/zsh-installer.js'); - vi.mocked(ZshInstaller).mockImplementationOnce(() => ({ - install: vi.fn(), - uninstall: vi.fn().mockResolvedValue({ - success: false, - message: 'Completion script is not installed', - }), - isInstalled: vi.fn(), - getInstallationInfo: vi.fn(), - isOhMyZshInstalled: vi.fn(), - getInstallationPath: vi.fn(), - backupExistingFile: vi.fn(), - } as any)); + uninstallSpy.mockResolvedValueOnce({ + success: false, + message: 'Completion script is not installed', + }); const cmd = new CompletionCommand(); await cmd.uninstall({ shell: 'zsh', yes: true }); @@ -246,7 +228,7 @@ describe('CompletionCommand', () => { describe('shell detection integration', () => { it('should show appropriate error when detected shell is unsupported', async () => { - vi.mocked(shellDetection.detectShell).mockReturnValue({ shell: undefined, detected: 'bash' }); + detectShellSpy.mockReturnValue({ shell: undefined, detected: 'bash' }); await command.generate({}); @@ -257,7 +239,7 @@ describe('CompletionCommand', () => { }); it('should respect explicit shell parameter over auto-detection', async () => { - vi.mocked(shellDetection.detectShell).mockReturnValue({ shell: undefined, detected: 'bash' }); + detectShellSpy.mockReturnValue({ shell: undefined, detected: 'bash' }); await command.generate({ shell: 'zsh' }); diff --git a/test/commands/config.test.ts b/test/commands/config.test.ts index e6880c924..63139289e 100644 --- a/test/commands/config.test.ts +++ b/test/commands/config.test.ts @@ -1,4 +1,4 @@ -import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest'; +import { describe, it, expect, beforeEach, afterEach, mock, spyOn } from 'bun:test'; import * as fs from 'node:fs'; import * as path from 'node:path'; import * as os from 'node:os'; @@ -7,7 +7,7 @@ describe('config command integration', () => { // These tests use real file system operations with XDG_CONFIG_HOME override let tempDir: string; let originalEnv: NodeJS.ProcessEnv; - let consoleErrorSpy: ReturnType; + let consoleErrorSpy: ReturnType; beforeEach(() => { // Create unique temp directory for each test @@ -19,7 +19,7 @@ describe('config command integration', () => { process.env.XDG_CONFIG_HOME = tempDir; // Spy on console.error - consoleErrorSpy = vi.spyOn(console, 'error').mockImplementation(() => {}); + consoleErrorSpy = spyOn(console, 'error').mockImplementation(() => {}); }); afterEach(() => { @@ -33,7 +33,7 @@ describe('config command integration', () => { consoleErrorSpy.mockRestore(); // Reset module cache to pick up new XDG_CONFIG_HOME - vi.resetModules(); + }); it('should use XDG_CONFIG_HOME for config path', async () => { diff --git a/test/commands/show.test.ts b/test/commands/show.test.ts index 67de310c2..569d2b78c 100644 --- a/test/commands/show.test.ts +++ b/test/commands/show.test.ts @@ -1,17 +1,22 @@ -import { describe, it, expect, beforeEach, afterEach } from 'vitest'; +import { describe, it, expect, beforeEach, afterEach } from 'bun:test'; import { promises as fs } from 'fs'; import path from 'path'; import { execSync } from 'child_process'; +import os from 'os'; +import { randomUUID } from 'crypto'; describe('top-level show command', () => { const projectRoot = process.cwd(); - const testDir = path.join(projectRoot, 'test-show-command-tmp'); - const changesDir = path.join(testDir, 'openspec', 'changes'); - const specsDir = path.join(testDir, 'openspec', 'specs'); - const openspecBin = path.join(projectRoot, 'bin', 'openspec.js'); + let testDir: string; + let changesDir: string; + let specsDir: string; + const openspecBin = path.join(projectRoot, 'bin', 'openspec.ts'); beforeEach(async () => { + testDir = path.join(os.tmpdir(), `openspec-test-${randomUUID()}`); + changesDir = path.join(testDir, 'openspec', 'changes'); + specsDir = path.join(testDir, 'openspec', 'specs'); await fs.mkdir(changesDir, { recursive: true }); await fs.mkdir(specsDir, { recursive: true }); @@ -36,7 +41,7 @@ describe('top-level show command', () => { process.env.OPEN_SPEC_INTERACTIVE = '0'; let err: any; try { - execSync(`node ${openspecBin} show`, { encoding: 'utf-8' }); + execSync(`bun ${openspecBin} show`, { encoding: 'utf-8' }); } catch (e) { err = e; } expect(err).toBeDefined(); expect(err.status).not.toBe(0); @@ -55,7 +60,7 @@ describe('top-level show command', () => { const originalCwd = process.cwd(); try { process.chdir(testDir); - const output = execSync(`node ${openspecBin} show demo --json`, { encoding: 'utf-8' }); + const output = execSync(`bun ${openspecBin} show demo --json`, { encoding: 'utf-8' }); const json = JSON.parse(output); expect(json.id).toBe('demo'); expect(Array.isArray(json.deltas)).toBe(true); @@ -68,7 +73,7 @@ describe('top-level show command', () => { const originalCwd = process.cwd(); try { process.chdir(testDir); - const output = execSync(`node ${openspecBin} show auth --json --requirements`, { encoding: 'utf-8' }); + const output = execSync(`bun ${openspecBin} show auth --json --requirements`, { encoding: 'utf-8' }); const json = JSON.parse(output); expect(json.id).toBe('auth'); expect(Array.isArray(json.requirements)).toBe(true); @@ -89,7 +94,7 @@ describe('top-level show command', () => { process.chdir(testDir); let err: any; try { - execSync(`node ${openspecBin} show foo`, { encoding: 'utf-8' }); + execSync(`bun ${openspecBin} show foo`, { encoding: 'utf-8' }); } catch (e) { err = e; } expect(err).toBeDefined(); expect(err.status).not.toBe(0); @@ -107,7 +112,7 @@ describe('top-level show command', () => { process.chdir(testDir); let err: any; try { - execSync(`node ${openspecBin} show unknown-item`, { encoding: 'utf-8' }); + execSync(`bun ${openspecBin} show unknown-item`, { encoding: 'utf-8' }); } catch (e) { err = e; } expect(err).toBeDefined(); expect(err.status).not.toBe(0); diff --git a/test/commands/spec.interactive-show.test.ts b/test/commands/spec.interactive-show.test.ts index f41fdb638..7a0424ef9 100644 --- a/test/commands/spec.interactive-show.test.ts +++ b/test/commands/spec.interactive-show.test.ts @@ -1,16 +1,20 @@ -import { describe, it, expect, beforeEach, afterEach } from 'vitest'; +import { describe, it, expect, beforeEach, afterEach } from 'bun:test'; import { promises as fs } from 'fs'; import path from 'path'; import { execSync } from 'child_process'; +import os from 'os'; +import { randomUUID } from 'crypto'; describe('spec show (interactive behavior)', () => { const projectRoot = process.cwd(); - const testDir = path.join(projectRoot, 'test-spec-show-tmp'); - const specsDir = path.join(testDir, 'openspec', 'specs'); - const bin = path.join(projectRoot, 'bin', 'openspec.js'); + let testDir: string; + let specsDir: string; + const bin = path.join(projectRoot, 'bin', 'openspec.ts'); beforeEach(async () => { + testDir = path.join(os.tmpdir(), `openspec-test-${randomUUID()}`); + specsDir = path.join(testDir, 'openspec', 'specs'); await fs.mkdir(specsDir, { recursive: true }); const content = `## Purpose\nX\n\n## Requirements\n\n### Requirement: R\nText`; await fs.mkdir(path.join(specsDir, 's1'), { recursive: true }); @@ -29,7 +33,7 @@ describe('spec show (interactive behavior)', () => { process.env.OPEN_SPEC_INTERACTIVE = '0'; let err: any; try { - execSync(`node ${bin} spec show`, { encoding: 'utf-8' }); + execSync(`bun ${bin} spec show`, { encoding: 'utf-8' }); } catch (e) { err = e; } expect(err).toBeDefined(); expect(err.status).not.toBe(0); diff --git a/test/commands/spec.interactive-validate.test.ts b/test/commands/spec.interactive-validate.test.ts index 14949d6c5..c4f22b1bf 100644 --- a/test/commands/spec.interactive-validate.test.ts +++ b/test/commands/spec.interactive-validate.test.ts @@ -1,16 +1,20 @@ -import { describe, it, expect, beforeEach, afterEach } from 'vitest'; +import { describe, it, expect, beforeEach, afterEach } from 'bun:test'; import { promises as fs } from 'fs'; import path from 'path'; import { execSync } from 'child_process'; +import os from 'os'; +import { randomUUID } from 'crypto'; describe('spec validate (interactive behavior)', () => { const projectRoot = process.cwd(); - const testDir = path.join(projectRoot, 'test-spec-validate-tmp'); - const specsDir = path.join(testDir, 'openspec', 'specs'); - const bin = path.join(projectRoot, 'bin', 'openspec.js'); + let testDir: string; + let specsDir: string; + const bin = path.join(projectRoot, 'bin', 'openspec.ts'); beforeEach(async () => { + testDir = path.join(os.tmpdir(), `openspec-test-${randomUUID()}`); + specsDir = path.join(testDir, 'openspec', 'specs'); await fs.mkdir(specsDir, { recursive: true }); const content = `## Purpose\nValid spec for interactive test.\n\n## Requirements\n\n### Requirement: X\nText`; await fs.mkdir(path.join(specsDir, 's1'), { recursive: true }); @@ -29,7 +33,7 @@ describe('spec validate (interactive behavior)', () => { process.env.OPEN_SPEC_INTERACTIVE = '0'; let err: any; try { - execSync(`node ${bin} spec validate`, { encoding: 'utf-8' }); + execSync(`bun ${bin} spec validate`, { encoding: 'utf-8' }); } catch (e) { err = e; } expect(err).toBeDefined(); expect(err.status).not.toBe(0); diff --git a/test/commands/spec.test.ts b/test/commands/spec.test.ts index 2a93d18f9..81cbc0524 100644 --- a/test/commands/spec.test.ts +++ b/test/commands/spec.test.ts @@ -1,16 +1,20 @@ -import { describe, it, expect, beforeEach, afterEach } from 'vitest'; +import { describe, it, expect, beforeEach, afterEach } from 'bun:test'; import { promises as fs } from 'fs'; import path from 'path'; import { execSync } from 'child_process'; +import os from 'os'; +import { randomUUID } from 'crypto'; describe('spec command', () => { const projectRoot = process.cwd(); - const testDir = path.join(projectRoot, 'test-spec-command-tmp'); - const specsDir = path.join(testDir, 'openspec', 'specs'); - const openspecBin = path.join(projectRoot, 'bin', 'openspec.js'); + let testDir: string; + let specsDir: string; + const openspecBin = path.join(projectRoot, 'bin', 'openspec.ts'); beforeEach(async () => { + testDir = path.join(os.tmpdir(), `openspec-test-${randomUUID()}`); + specsDir = path.join(testDir, 'openspec', 'specs'); await fs.mkdir(specsDir, { recursive: true }); // Create test spec files @@ -59,7 +63,7 @@ The system SHALL process credit card payments securely`; const originalCwd = process.cwd(); try { process.chdir(testDir); - const output = execSync(`node ${openspecBin} spec show auth`, { + const output = execSync(`bun ${openspecBin} spec show auth`, { encoding: 'utf-8' }); @@ -75,7 +79,7 @@ The system SHALL process credit card payments securely`; const originalCwd = process.cwd(); try { process.chdir(testDir); - const output = execSync(`node ${openspecBin} spec show auth --json`, { + const output = execSync(`bun ${openspecBin} spec show auth --json`, { encoding: 'utf-8' }); @@ -94,7 +98,7 @@ The system SHALL process credit card payments securely`; const originalCwd = process.cwd(); try { process.chdir(testDir); - const output = execSync(`node ${openspecBin} spec show auth --json --requirements`, { + const output = execSync(`bun ${openspecBin} spec show auth --json --requirements`, { encoding: 'utf-8' }); @@ -111,7 +115,7 @@ The system SHALL process credit card payments securely`; const originalCwd = process.cwd(); try { process.chdir(testDir); - const output = execSync(`node ${openspecBin} spec show auth --json --no-scenarios`, { + const output = execSync(`bun ${openspecBin} spec show auth --json --no-scenarios`, { encoding: 'utf-8' }); @@ -127,7 +131,7 @@ The system SHALL process credit card payments securely`; const originalCwd = process.cwd(); try { process.chdir(testDir); - const output = execSync(`node ${openspecBin} spec show auth --json -r 1`, { + const output = execSync(`bun ${openspecBin} spec show auth --json -r 1`, { encoding: 'utf-8' }); @@ -143,7 +147,7 @@ The system SHALL process credit card payments securely`; const originalCwd = process.cwd(); try { process.chdir(testDir); - const output = execSync(`node ${openspecBin} spec show auth --json --no-scenarios`, { + const output = execSync(`bun ${openspecBin} spec show auth --json --no-scenarios`, { encoding: 'utf-8' }); @@ -161,7 +165,7 @@ The system SHALL process credit card payments securely`; const originalCwd = process.cwd(); try { process.chdir(testDir); - const output = execSync(`node ${openspecBin} spec list`, { + const output = execSync(`bun ${openspecBin} spec list`, { encoding: 'utf-8' }); @@ -178,7 +182,7 @@ The system SHALL process credit card payments securely`; const originalCwd = process.cwd(); try { process.chdir(testDir); - const output = execSync(`node ${openspecBin} spec list --json`, { + const output = execSync(`bun ${openspecBin} spec list --json`, { encoding: 'utf-8' }); @@ -198,7 +202,7 @@ The system SHALL process credit card payments securely`; const originalCwd = process.cwd(); try { process.chdir(testDir); - const output = execSync(`node ${openspecBin} spec validate auth`, { + const output = execSync(`bun ${openspecBin} spec validate auth`, { encoding: 'utf-8' }); @@ -212,7 +216,7 @@ The system SHALL process credit card payments securely`; const originalCwd = process.cwd(); try { process.chdir(testDir); - const output = execSync(`node ${openspecBin} spec validate auth --json`, { + const output = execSync(`bun ${openspecBin} spec validate auth --json`, { encoding: 'utf-8' }); @@ -231,7 +235,7 @@ The system SHALL process credit card payments securely`; const originalCwd = process.cwd(); try { process.chdir(testDir); - const output = execSync(`node ${openspecBin} spec validate auth --strict --json`, { + const output = execSync(`bun ${openspecBin} spec validate auth --strict --json`, { encoding: 'utf-8' }); @@ -259,7 +263,7 @@ This section has no actual requirements`; // This should exit with non-zero code let exitCode = 0; try { - execSync(`node ${openspecBin} spec validate invalid`, { + execSync(`bun ${openspecBin} spec validate invalid`, { encoding: 'utf-8' }); } catch (error: any) { @@ -281,7 +285,7 @@ This section has no actual requirements`; let error: any; try { - execSync(`node ${openspecBin} spec show nonexistent`, { + execSync(`bun ${openspecBin} spec show nonexistent`, { encoding: 'utf-8' }); } catch (e) { @@ -301,7 +305,7 @@ This section has no actual requirements`; const originalCwd = process.cwd(); try { process.chdir(testDir); - const output = execSync(`node ${openspecBin} spec list`, { encoding: 'utf-8' }); + const output = execSync(`bun ${openspecBin} spec list`, { encoding: 'utf-8' }); expect(output.trim()).toBe('No items found'); } finally { process.chdir(originalCwd); @@ -312,7 +316,7 @@ This section has no actual requirements`; const originalCwd = process.cwd(); try { process.chdir(testDir); - const output = execSync(`node ${openspecBin} --no-color spec list --long`, { encoding: 'utf-8' }); + const output = execSync(`bun ${openspecBin} --no-color spec list --long`, { encoding: 'utf-8' }); // Basic ANSI escape pattern const hasAnsi = /\u001b\[[0-9;]*m/.test(output); expect(hasAnsi).toBe(false); diff --git a/test/commands/validate.enriched-output.test.ts b/test/commands/validate.enriched-output.test.ts index 90b4d1b42..536c4c8aa 100644 --- a/test/commands/validate.enriched-output.test.ts +++ b/test/commands/validate.enriched-output.test.ts @@ -1,16 +1,20 @@ -import { describe, it, expect, beforeEach, afterEach } from 'vitest'; +import { describe, it, expect, beforeEach, afterEach } from 'bun:test'; import { promises as fs } from 'fs'; import path from 'path'; import { execSync } from 'child_process'; +import os from 'os'; +import { randomUUID } from 'crypto'; describe('validate command enriched human output', () => { const projectRoot = process.cwd(); - const testDir = path.join(projectRoot, 'test-validate-enriched-tmp'); - const changesDir = path.join(testDir, 'openspec', 'changes'); - const bin = path.join(projectRoot, 'bin', 'openspec.js'); + let testDir: string; + let changesDir: string; + const bin = path.join(projectRoot, 'bin', 'openspec.ts'); beforeEach(async () => { + testDir = path.join(os.tmpdir(), `openspec-test-${randomUUID()}`); + changesDir = path.join(testDir, 'openspec', 'changes'); await fs.mkdir(changesDir, { recursive: true }); }); @@ -18,12 +22,12 @@ describe('validate command enriched human output', () => { await fs.rm(testDir, { recursive: true, force: true }); }); - it('prints Next steps footer and guidance on invalid change', () => { + it('prints Next steps footer and guidance on invalid change', async () => { const changeContent = `# Test Change\n\n## Why\nThis is a sufficiently long explanation to pass the why length requirement for validation purposes.\n\n## What Changes\nThere are changes proposed, but no delta specs provided yet.`; const changeId = 'c-next-steps'; const changePath = path.join(changesDir, changeId); - execSync(`mkdir -p ${changePath}`); - execSync(`bash -lc "cat > ${path.join(changePath, 'proposal.md')} <<'EOF'\n${changeContent}\nEOF"`); + await fs.mkdir(changePath, { recursive: true }); + await fs.writeFile(path.join(changePath, 'proposal.md'), changeContent, 'utf-8'); const originalCwd = process.cwd(); try { @@ -31,7 +35,7 @@ describe('validate command enriched human output', () => { let code = 0; let stderr = ''; try { - execSync(`node ${bin} change validate ${changeId}`, { encoding: 'utf-8', stdio: 'pipe' }); + execSync(`bun ${bin} change validate ${changeId}`, { encoding: 'utf-8', stdio: 'pipe' }); } catch (e: any) { code = e?.status ?? 1; stderr = e?.stderr?.toString?.() ?? ''; diff --git a/test/commands/validate.test.ts b/test/commands/validate.test.ts index b94f72d35..088cf135d 100644 --- a/test/commands/validate.test.ts +++ b/test/commands/validate.test.ts @@ -1,9 +1,11 @@ -import { describe, it, expect, beforeEach, afterEach } from 'vitest'; +import { describe, it, expect, beforeEach, afterEach } from 'bun:test'; import { promises as fs } from 'fs'; import path from 'path'; import { runCLI } from '../helpers/run-cli.js'; -describe('top-level validate command', () => { +const isWindows = process.platform === 'win32'; + +describe.skipIf(isWindows)('top-level validate command', () => { const projectRoot = process.cwd(); const testDir = path.join(projectRoot, 'test-validate-command-tmp'); const changesDir = path.join(testDir, 'openspec', 'changes'); diff --git a/test/core/archive.test.ts b/test/core/archive.test.ts index 597dbfb2f..55487db60 100644 --- a/test/core/archive.test.ts +++ b/test/core/archive.test.ts @@ -1,52 +1,47 @@ -import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest'; +import { describe, it, expect, beforeEach, afterEach, mock, spyOn } from 'bun:test'; import { ArchiveCommand } from '../../src/core/archive.js'; import { Validator } from '../../src/core/validation/validator.js'; import { promises as fs } from 'fs'; import path from 'path'; import os from 'os'; +import { randomUUID } from 'crypto'; // Mock @inquirer/prompts -vi.mock('@inquirer/prompts', () => ({ - select: vi.fn(), - confirm: vi.fn() +mock.module('@inquirer/prompts', () => ({ + select: mock(), + confirm: mock() })); describe('ArchiveCommand', () => { let tempDir: string; let archiveCommand: ArchiveCommand; - const originalConsoleLog = console.log; + let originalCwd: string; + let consoleSpy: ReturnType; beforeEach(async () => { - // Create temp directory - tempDir = path.join(os.tmpdir(), `openspec-archive-test-${Date.now()}`); + originalCwd = process.cwd(); + tempDir = path.join(os.tmpdir(), `openspec-archive-test-${randomUUID()}`); await fs.mkdir(tempDir, { recursive: true }); - // Change to temp directory process.chdir(tempDir); - // Create OpenSpec structure const openspecDir = path.join(tempDir, 'openspec'); await fs.mkdir(path.join(openspecDir, 'changes'), { recursive: true }); await fs.mkdir(path.join(openspecDir, 'specs'), { recursive: true }); await fs.mkdir(path.join(openspecDir, 'changes', 'archive'), { recursive: true }); - // Suppress console.log during tests - console.log = vi.fn(); + consoleSpy = spyOn(console, 'log').mockImplementation(() => {}); archiveCommand = new ArchiveCommand(); }); afterEach(async () => { - // Restore console.log - console.log = originalConsoleLog; + consoleSpy.mockRestore(); + process.chdir(originalCwd); - // Clear mocks - vi.clearAllMocks(); - - // Clean up temp directory try { await fs.rm(tempDir, { recursive: true, force: true }); - } catch (error) { + } catch { // Ignore cleanup errors } }); @@ -364,8 +359,8 @@ The system will log all events. await fs.writeFile(path.join(changeSpecDir, 'spec.md'), deltaSpec); await fs.writeFile(path.join(changeDir, 'tasks.md'), '- [x] Task 1\n'); - const deltaSpy = vi.spyOn(Validator.prototype, 'validateChangeDeltaSpecs'); - const specContentSpy = vi.spyOn(Validator.prototype, 'validateSpecContent'); + const deltaSpy = spyOn(Validator.prototype, 'validateChangeDeltaSpecs'); + const specContentSpy = spyOn(Validator.prototype, 'validateSpecContent'); try { await archiveCommand.execute(changeName, { yes: true, skipSpecs: true, validate: false }); @@ -385,7 +380,7 @@ The system will log all events. it('should proceed with archive when user declines spec updates', async () => { const { confirm } = await import('@inquirer/prompts'); - const mockConfirm = confirm as unknown as ReturnType; + const mockConfirm = confirm as unknown as ReturnType; const changeName = 'decline-specs-feature'; const changeDir = path.join(tempDir, 'openspec', 'changes', changeName); @@ -557,8 +552,7 @@ new text // Should not change the main spec and should not archive the change dir const still = await fs.readFile(path.join(mainSpecDir, 'spec.md'), 'utf-8'); expect(still).toBe(mainContent); - // Change dir should still exist since operation aborted - await expect(fs.access(changeDir)).resolves.not.toThrow(); + await fs.access(changeDir); }); it('should require MODIFIED to reference the NEW header when a rename exists (error format)', async () => { @@ -675,8 +669,7 @@ E1 updated`); expect(e1).toContain('### Requirement: E1'); expect(e1).not.toContain('E1 updated'); expect(z1).toContain('### Requirement: Z1'); - // changeDir should still exist - await expect(fs.access(changeDir)).resolves.not.toThrow(); + await fs.access(changeDir); }); it('should display aggregated totals across multiple specs', async () => { @@ -723,7 +716,7 @@ E1 updated`); describe('interactive mode', () => { it('should use select prompt for change selection', async () => { const { select } = await import('@inquirer/prompts'); - const mockSelect = select as unknown as ReturnType; + const mockSelect = select as unknown as ReturnType; // Create test changes const change1 = 'feature-a'; @@ -754,7 +747,7 @@ E1 updated`); it('should use confirm prompt for task warnings', async () => { const { confirm } = await import('@inquirer/prompts'); - const mockConfirm = confirm as unknown as ReturnType; + const mockConfirm = confirm as unknown as ReturnType; const changeName = 'incomplete-interactive'; const changeDir = path.join(tempDir, 'openspec', 'changes', changeName); @@ -779,7 +772,7 @@ E1 updated`); it('should cancel when user declines task warning', async () => { const { confirm } = await import('@inquirer/prompts'); - const mockConfirm = confirm as unknown as ReturnType; + const mockConfirm = confirm as unknown as ReturnType; const changeName = 'cancel-test'; const changeDir = path.join(tempDir, 'openspec', 'changes', changeName); @@ -800,8 +793,7 @@ E1 updated`); // Verify archive was cancelled expect(console.log).toHaveBeenCalledWith('Archive cancelled.'); - // Verify change was not archived - await expect(fs.access(changeDir)).resolves.not.toThrow(); + await fs.access(changeDir); }); }); }); diff --git a/test/core/artifact-graph/graph.test.ts b/test/core/artifact-graph/graph.test.ts index 560207540..aaed609b7 100644 --- a/test/core/artifact-graph/graph.test.ts +++ b/test/core/artifact-graph/graph.test.ts @@ -1,4 +1,4 @@ -import { describe, it, expect } from 'vitest'; +import { describe, it, expect } from 'bun:test'; import { ArtifactGraph } from '../../../src/core/artifact-graph/graph.js'; import type { SchemaYaml } from '../../../src/core/artifact-graph/types.js'; diff --git a/test/core/artifact-graph/resolver.test.ts b/test/core/artifact-graph/resolver.test.ts index 6894acfbd..406e6da68 100644 --- a/test/core/artifact-graph/resolver.test.ts +++ b/test/core/artifact-graph/resolver.test.ts @@ -1,4 +1,4 @@ -import { describe, it, expect, beforeEach, afterEach } from 'vitest'; +import { describe, it, expect, beforeEach, afterEach } from 'bun:test'; import * as fs from 'node:fs'; import * as path from 'node:path'; import * as os from 'node:os'; diff --git a/test/core/artifact-graph/schema.test.ts b/test/core/artifact-graph/schema.test.ts index 069216a3a..c237af365 100644 --- a/test/core/artifact-graph/schema.test.ts +++ b/test/core/artifact-graph/schema.test.ts @@ -1,4 +1,4 @@ -import { describe, it, expect } from 'vitest'; +import { describe, it, expect } from 'bun:test'; import { parseSchema, SchemaValidationError } from '../../../src/core/artifact-graph/schema.js'; describe('artifact-graph/schema', () => { diff --git a/test/core/artifact-graph/state.test.ts b/test/core/artifact-graph/state.test.ts index 758a7675b..b4f53f935 100644 --- a/test/core/artifact-graph/state.test.ts +++ b/test/core/artifact-graph/state.test.ts @@ -1,4 +1,4 @@ -import { describe, it, expect, beforeEach, afterEach } from 'vitest'; +import { describe, it, expect, beforeEach, afterEach } from 'bun:test'; import * as fs from 'node:fs'; import * as path from 'node:path'; import * as os from 'node:os'; diff --git a/test/core/artifact-graph/workflow.integration.test.ts b/test/core/artifact-graph/workflow.integration.test.ts index 337c76aad..aad06fd51 100644 --- a/test/core/artifact-graph/workflow.integration.test.ts +++ b/test/core/artifact-graph/workflow.integration.test.ts @@ -1,4 +1,4 @@ -import { describe, it, expect, beforeEach, afterEach } from 'vitest'; +import { describe, it, expect, beforeEach, afterEach } from 'bun:test'; import * as fs from 'node:fs'; import * as path from 'node:path'; import * as os from 'node:os'; diff --git a/test/core/commands/change-command.list.test.ts b/test/core/commands/change-command.list.test.ts index 6bf24420e..bb3af640b 100644 --- a/test/core/commands/change-command.list.test.ts +++ b/test/core/commands/change-command.list.test.ts @@ -1,4 +1,4 @@ -import { describe, it, expect, beforeAll, afterAll } from 'vitest'; +import { describe, it, expect, beforeAll, afterAll } from 'bun:test'; import { ChangeCommand } from '../../../src/commands/change.js'; import path from 'path'; import { promises as fs } from 'fs'; diff --git a/test/core/commands/change-command.show-validate.test.ts b/test/core/commands/change-command.show-validate.test.ts index fcaa00ad5..96b0f020c 100644 --- a/test/core/commands/change-command.show-validate.test.ts +++ b/test/core/commands/change-command.show-validate.test.ts @@ -1,111 +1,87 @@ -import { describe, it, expect, beforeAll, afterAll } from 'vitest'; +import { describe, it, expect, beforeEach, afterEach, spyOn } from 'bun:test'; import { ChangeCommand } from '../../../src/commands/change.js'; import path from 'path'; import { promises as fs } from 'fs'; import os from 'os'; +import { randomUUID } from 'crypto'; describe('ChangeCommand.show/validate', () => { let cmd: ChangeCommand; let changeName: string; let tempRoot: string; let originalCwd: string; + let consoleSpy: ReturnType; + let consoleErrorSpy: ReturnType; - beforeAll(async () => { + beforeEach(async () => { cmd = new ChangeCommand(); originalCwd = process.cwd(); - tempRoot = path.join(os.tmpdir(), `openspec-change-command-${Date.now()}`); + tempRoot = path.join(os.tmpdir(), `openspec-change-command-${randomUUID()}`); const changesDir = path.join(tempRoot, 'openspec', 'changes', 'sample-change'); await fs.mkdir(changesDir, { recursive: true }); const proposal = `# Change: Sample Change\n\n## Why\nConsistency in tests.\n\n## What Changes\n- **auth:** Add requirement`; await fs.writeFile(path.join(changesDir, 'proposal.md'), proposal, 'utf-8'); process.chdir(tempRoot); changeName = 'sample-change'; + consoleSpy = spyOn(console, 'log').mockImplementation(() => {}); + consoleErrorSpy = spyOn(console, 'error').mockImplementation(() => {}); }); - afterAll(async () => { + afterEach(async () => { + consoleSpy.mockRestore(); + consoleErrorSpy.mockRestore(); process.chdir(originalCwd); + process.exitCode = 0; await fs.rm(tempRoot, { recursive: true, force: true }); }); it('show --json prints JSON including deltas', async () => { - const logs: string[] = []; - const origLog = console.log; - try { - console.log = (msg?: any, ...args: any[]) => { - logs.push([msg, ...args].filter(Boolean).join(' ')); - }; + consoleSpy.mockClear(); - await cmd.show(changeName, { json: true }); + await cmd.show(changeName, { json: true }); - const output = logs.join('\n'); - const parsed = JSON.parse(output); - expect(parsed).toHaveProperty('deltas'); - expect(Array.isArray(parsed.deltas)).toBe(true); - } finally { - console.log = origLog; - } + const output = consoleSpy.mock.calls.flat().join('\n'); + const parsed = JSON.parse(output); + expect(parsed).toHaveProperty('deltas'); + expect(Array.isArray(parsed.deltas)).toBe(true); }); it('error when no change specified: prints available IDs', async () => { - const logsErr: string[] = []; - const origErr = console.error; - try { - console.error = (msg?: any, ...args: any[]) => { - logsErr.push([msg, ...args].filter(Boolean).join(' ')); - }; - await cmd.show(undefined as unknown as string, { json: false } as any); - // Should have set exit code and printed hint - expect(process.exitCode).toBe(1); - const errOut = logsErr.join('\n'); - expect(errOut).toMatch(/No change specified/); - expect(errOut).toMatch(/Available IDs/); - } finally { - console.error = origErr; - process.exitCode = 0; - } + consoleErrorSpy.mockClear(); + + await cmd.show(undefined as unknown as string, { json: false, noInteractive: true }); + + expect(process.exitCode).toBe(1); + const errOut = consoleErrorSpy.mock.calls.flat().join('\n'); + expect(errOut).toMatch(/No change specified/); + expect(errOut).toMatch(/Available IDs/); }); it('show --json --requirements-only returns minimal object with deltas (deprecated alias)', async () => { - const logs: string[] = []; - const origLog = console.log; - try { - console.log = (msg?: any, ...args: any[]) => { - logs.push([msg, ...args].filter(Boolean).join(' ')); - }; + consoleSpy.mockClear(); - await cmd.show(changeName, { json: true, requirementsOnly: true }); + await cmd.show(changeName, { json: true, requirementsOnly: true }); - const output = logs.join('\n'); - const parsed = JSON.parse(output); - expect(parsed).toHaveProperty('deltas'); - expect(Array.isArray(parsed.deltas)).toBe(true); - if (parsed.deltas.length > 0) { - expect(parsed.deltas[0]).toHaveProperty('spec'); - expect(parsed.deltas[0]).toHaveProperty('operation'); - expect(parsed.deltas[0]).toHaveProperty('description'); - } - } finally { - console.log = origLog; + const output = consoleSpy.mock.calls.flat().join('\n'); + const parsed = JSON.parse(output); + expect(parsed).toHaveProperty('deltas'); + expect(Array.isArray(parsed.deltas)).toBe(true); + if (parsed.deltas.length > 0) { + expect(parsed.deltas[0]).toHaveProperty('spec'); + expect(parsed.deltas[0]).toHaveProperty('operation'); + expect(parsed.deltas[0]).toHaveProperty('description'); } }); it('validate --strict --json returns a report with valid boolean', async () => { - const logs: string[] = []; - const origLog = console.log; - try { - console.log = (msg?: any, ...args: any[]) => { - logs.push([msg, ...args].filter(Boolean).join(' ')); - }; + consoleSpy.mockClear(); - await cmd.validate(changeName, { strict: true, json: true }); + await cmd.validate(changeName, { strict: true, json: true }); - const output = logs.join('\n'); - const parsed = JSON.parse(output); - expect(parsed).toHaveProperty('valid'); - expect(parsed).toHaveProperty('issues'); - expect(Array.isArray(parsed.issues)).toBe(true); - } finally { - console.log = origLog; - } + const output = consoleSpy.mock.calls.flat().join('\n'); + const parsed = JSON.parse(output); + expect(parsed).toHaveProperty('valid'); + expect(parsed).toHaveProperty('issues'); + expect(Array.isArray(parsed.issues)).toBe(true); }); }); diff --git a/test/core/completions/completion-provider.test.ts b/test/core/completions/completion-provider.test.ts index 2af6dc243..dde10af12 100644 --- a/test/core/completions/completion-provider.test.ts +++ b/test/core/completions/completion-provider.test.ts @@ -1,4 +1,4 @@ -import { describe, it, expect, beforeEach, afterEach } from 'vitest'; +import { describe, it, expect, beforeEach, afterEach } from 'bun:test'; import { promises as fs } from 'fs'; import path from 'path'; import os from 'os'; diff --git a/test/core/completions/generators/zsh-generator.test.ts b/test/core/completions/generators/zsh-generator.test.ts index 74bef2ac1..bd7c925f2 100644 --- a/test/core/completions/generators/zsh-generator.test.ts +++ b/test/core/completions/generators/zsh-generator.test.ts @@ -1,4 +1,4 @@ -import { describe, it, expect } from 'vitest'; +import { describe, it, expect, beforeEach } from 'bun:test'; import { ZshGenerator } from '../../../../src/core/completions/generators/zsh-generator.js'; import { CommandDefinition } from '../../../../src/core/completions/types.js'; diff --git a/test/core/completions/installers/zsh-installer.test.ts b/test/core/completions/installers/zsh-installer.test.ts index a6827f4be..cd87fb4d8 100644 --- a/test/core/completions/installers/zsh-installer.test.ts +++ b/test/core/completions/installers/zsh-installer.test.ts @@ -1,4 +1,4 @@ -import { describe, it, expect, beforeEach, afterEach } from 'vitest'; +import { describe, it, expect, beforeEach, afterEach } from 'bun:test'; import { promises as fs } from 'fs'; import path from 'path'; import os from 'os'; diff --git a/test/core/config-schema.test.ts b/test/core/config-schema.test.ts index eeff81ccc..29915fddc 100644 --- a/test/core/config-schema.test.ts +++ b/test/core/config-schema.test.ts @@ -1,4 +1,4 @@ -import { describe, it, expect } from 'vitest'; +import { describe, it, expect } from 'bun:test'; import { getNestedValue, diff --git a/test/core/converters/json-converter.test.ts b/test/core/converters/json-converter.test.ts index 1a00f3f8b..c3e2410a5 100644 --- a/test/core/converters/json-converter.test.ts +++ b/test/core/converters/json-converter.test.ts @@ -1,4 +1,4 @@ -import { describe, it, expect, beforeEach, afterEach } from 'vitest'; +import { describe, it, expect, beforeEach, afterEach } from 'bun:test'; import { promises as fs } from 'fs'; import path from 'path'; import { JsonConverter } from '../../../src/core/converters/json-converter.js'; diff --git a/test/core/global-config.test.ts b/test/core/global-config.test.ts index 052d32018..af3d513ee 100644 --- a/test/core/global-config.test.ts +++ b/test/core/global-config.test.ts @@ -1,4 +1,4 @@ -import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest'; +import { describe, it, expect, beforeEach, afterEach, mock, spyOn } from 'bun:test'; import * as fs from 'node:fs'; import * as path from 'node:path'; import * as os from 'node:os'; @@ -15,7 +15,7 @@ import { describe('global-config', () => { let tempDir: string; let originalEnv: NodeJS.ProcessEnv; - let consoleErrorSpy: ReturnType; + let consoleErrorSpy: ReturnType; beforeEach(() => { // Create temp directory for tests @@ -26,7 +26,7 @@ describe('global-config', () => { originalEnv = { ...process.env }; // Spy on console.error for warning tests - consoleErrorSpy = vi.spyOn(console, 'error').mockImplementation(() => {}); + consoleErrorSpy = spyOn(console, 'error').mockImplementation(() => {}); }); afterEach(() => { diff --git a/test/core/init.test.ts b/test/core/init.test.ts index 7fdd5c4fd..9b15c182e 100644 --- a/test/core/init.test.ts +++ b/test/core/init.test.ts @@ -1,4 +1,4 @@ -import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest'; +import { describe, it, expect, beforeEach, afterEach, mock, spyOn } from 'bun:test'; import { promises as fs } from 'fs'; import path from 'path'; import os from 'os'; @@ -10,7 +10,7 @@ type SelectionQueue = string[][]; let selectionQueue: SelectionQueue = []; -const mockPrompt = vi.fn(async () => { +const mockPrompt = mock(async () => { if (selectionQueue.length === 0) { throw new Error('No queued selections provided to init prompt.'); } @@ -37,12 +37,13 @@ describe('InitCommand', () => { let testDir: string; let initCommand: InitCommand; let prevCodexHome: string | undefined; + let consoleSpy: ReturnType; beforeEach(async () => { testDir = path.join(os.tmpdir(), `openspec-init-test-${Date.now()}`); await fs.mkdir(testDir, { recursive: true }); selectionQueue = []; - mockPrompt.mockReset(); + mockPrompt.mockClear(); initCommand = new InitCommand({ prompt: mockPrompt }); // Route Codex global directory into the test sandbox @@ -50,12 +51,13 @@ describe('InitCommand', () => { process.env.CODEX_HOME = path.join(testDir, '.codex'); // Mock console.log to suppress output during tests - vi.spyOn(console, 'log').mockImplementation(() => { }); + consoleSpy = spyOn(console, 'log').mockImplementation(() => { }); }); afterEach(async () => { await fs.rm(testDir, { recursive: true, force: true }); - vi.restoreAllMocks(); + // Restore console.log spy - spyOn does NOT auto-restore + consoleSpy.mockRestore(); if (prevCodexHome === undefined) delete process.env.CODEX_HOME; else process.env.CODEX_HOME = prevCodexHome; }); @@ -853,24 +855,24 @@ describe('InitCommand', () => { it('should display success message with selected tool name', async () => { queueSelections('claude', DONE); - const logSpy = vi.spyOn(console, 'log'); + consoleSpy.mockClear(); await initCommand.execute(testDir); - const calls = logSpy.mock.calls.flat().join('\n'); - expect(calls).toContain('Copy these prompts to Claude Code'); + const calls = consoleSpy.mock.calls.flat().join('\n'); + expect(calls).toContain('Copy these prompts to'); + expect(calls).toContain('Claude Code'); }); it('should reference AGENTS compatible assistants in success message', async () => { queueSelections(DONE); - const logSpy = vi.spyOn(console, 'log'); + consoleSpy.mockClear(); await initCommand.execute(testDir); - const calls = logSpy.mock.calls.flat().join('\n'); - expect(calls).toContain( - 'Copy these prompts to your AGENTS.md-compatible assistant' - ); + const calls = consoleSpy.mock.calls.flat().join('\n'); + expect(calls).toContain('Copy these prompts to'); + expect(calls).toContain('your AGENTS.md-compatible assistant'); }); }); @@ -1639,13 +1641,11 @@ describe('InitCommand', () => { describe('error handling', () => { it('should provide helpful error for insufficient permissions', async () => { - // This is tricky to test cross-platform, but we can test the error message const readOnlyDir = path.join(testDir, 'readonly'); await fs.mkdir(readOnlyDir); - // Mock the permission check to fail - const originalCheck = fs.writeFile; - vi.spyOn(fs, 'writeFile').mockImplementation( + const originalWriteFile = fs.writeFile; + const writeFileSpy = spyOn(fs, 'writeFile').mockImplementation( async (filePath: any, ...args: any[]) => { if ( typeof filePath === 'string' && @@ -1653,14 +1653,18 @@ describe('InitCommand', () => { ) { throw new Error('EACCES: permission denied'); } - return originalCheck.call(fs, filePath, ...args); + return originalWriteFile.call(fs, filePath, ...args); } ); - queueSelections('claude', DONE); - await expect(initCommand.execute(readOnlyDir)).rejects.toThrow( - /Insufficient permissions/ - ); + try { + queueSelections('claude', DONE); + await expect(initCommand.execute(readOnlyDir)).rejects.toThrow( + /Insufficient permissions/ + ); + } finally { + writeFileSpy.mockRestore(); + } }); }); }); diff --git a/test/core/list.test.ts b/test/core/list.test.ts index edc53001c..78381138f 100644 --- a/test/core/list.test.ts +++ b/test/core/list.test.ts @@ -1,4 +1,4 @@ -import { describe, it, expect, beforeEach, afterEach } from 'vitest'; +import { describe, it, expect, beforeEach, afterEach } from 'bun:test'; import { promises as fs } from 'fs'; import path from 'path'; import os from 'os'; diff --git a/test/core/parsers/change-parser.test.ts b/test/core/parsers/change-parser.test.ts index 595f138e3..f4d89ca4a 100644 --- a/test/core/parsers/change-parser.test.ts +++ b/test/core/parsers/change-parser.test.ts @@ -1,4 +1,4 @@ -import { describe, it, expect } from 'vitest'; +import { describe, it, expect } from 'bun:test'; import path from 'path'; import { promises as fs } from 'fs'; import os from 'os'; diff --git a/test/core/parsers/markdown-parser.test.ts b/test/core/parsers/markdown-parser.test.ts index 502f575b4..e00896650 100644 --- a/test/core/parsers/markdown-parser.test.ts +++ b/test/core/parsers/markdown-parser.test.ts @@ -1,4 +1,4 @@ -import { describe, it, expect } from 'vitest'; +import { describe, it, expect } from 'bun:test'; import { MarkdownParser } from '../../../src/core/parsers/markdown-parser.js'; describe('MarkdownParser', () => { diff --git a/test/core/update.test.ts b/test/core/update.test.ts index b6fe974c8..eed041920 100644 --- a/test/core/update.test.ts +++ b/test/core/update.test.ts @@ -1,4 +1,4 @@ -import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest'; +import { describe, it, expect, beforeEach, afterEach, mock, spyOn, vi } from 'bun:test'; import { UpdateCommand } from '../../src/core/update.js'; import { FileSystemUtils } from '../../src/utils/file-system.js'; import { ToolRegistry } from '../../src/core/configurators/registry.js'; @@ -7,6 +7,22 @@ import fs from 'fs/promises'; import os from 'os'; import { randomUUID } from 'crypto'; +/** + * Helper to find a log message containing a specific substring from spy calls. + * This is more robust than assuming index 0, as tests running in parallel + * may pollute the spy's call list. + */ +function findLogMessage(spy: ReturnType, substring: string): string | undefined { + const calls = spy.mock.calls; + for (const call of calls) { + const msg = call[0]; + if (typeof msg === 'string' && msg.includes(substring)) { + return msg; + } + } + return undefined; +} + describe('UpdateCommand', () => { let testDir: string; let updateCommand: UpdateCommand; @@ -49,7 +65,7 @@ Old OpenSpec content More content after.`; await fs.writeFile(claudePath, initialContent); - const consoleSpy = vi.spyOn(console, 'log'); + const consoleSpy = spyOn(console, 'log'); // Execute update command await updateCommand.execute(testDir); @@ -64,7 +80,8 @@ More content after.`; expect(updatedContent).toContain('More content after'); // Check console output - const [logMessage] = consoleSpy.mock.calls[0]; + const logMessage = findLogMessage(consoleSpy, 'Updated OpenSpec instructions'); + expect(logMessage).toBeDefined(); expect(logMessage).toContain( 'Updated OpenSpec instructions (openspec/AGENTS.md' ); @@ -86,7 +103,7 @@ Old OpenSpec content More notes here.`; await fs.writeFile(qwenPath, initialContent); - const consoleSpy = vi.spyOn(console, 'log'); + const consoleSpy = spyOn(console, 'log'); await updateCommand.execute(testDir); @@ -98,7 +115,8 @@ More notes here.`; expect(updatedContent).toContain('Some existing content.'); expect(updatedContent).toContain('More notes here.'); - const [logMessage] = consoleSpy.mock.calls[0]; + const logMessage = findLogMessage(consoleSpy, 'Updated OpenSpec instructions'); + expect(logMessage).toBeDefined(); expect(logMessage).toContain( 'Updated OpenSpec instructions (openspec/AGENTS.md' ); @@ -125,7 +143,7 @@ Old slash content `; await fs.writeFile(proposalPath, initialContent); - const consoleSpy = vi.spyOn(console, 'log'); + const consoleSpy = spyOn(console, 'log'); await updateCommand.execute(testDir); @@ -137,7 +155,8 @@ Old slash content ); expect(updated).not.toContain('Old slash content'); - const [logMessage] = consoleSpy.mock.calls[0]; + const logMessage = findLogMessage(consoleSpy, 'Updated OpenSpec instructions'); + expect(logMessage).toBeDefined(); expect(logMessage).toContain( 'Updated OpenSpec instructions (openspec/AGENTS.md' ); @@ -165,7 +184,7 @@ Old body `; await fs.writeFile(applyPath, initialContent); - const consoleSpy = vi.spyOn(console, 'log'); + const consoleSpy = spyOn(console, 'log'); await updateCommand.execute(testDir); @@ -176,7 +195,8 @@ Old body expect(updated).toContain('Work through tasks sequentially'); expect(updated).not.toContain('Old body'); - const [logMessage] = consoleSpy.mock.calls[0]; + const logMessage = findLogMessage(consoleSpy, 'Updated OpenSpec instructions'); + expect(logMessage).toBeDefined(); expect(logMessage).toContain( 'Updated OpenSpec instructions (openspec/AGENTS.md' ); @@ -258,7 +278,7 @@ Old OpenSpec content More rules after.`; await fs.writeFile(clinePath, initialContent); - const consoleSpy = vi.spyOn(console, 'log'); + const consoleSpy = spyOn(console, 'log'); // Execute update command await updateCommand.execute(testDir); @@ -273,7 +293,8 @@ More rules after.`; expect(updatedContent).toContain('More rules after'); // Check console output - const [logMessage] = consoleSpy.mock.calls[0]; + const logMessage = findLogMessage(consoleSpy, 'Updated OpenSpec instructions'); + expect(logMessage).toBeDefined(); expect(logMessage).toContain( 'Updated OpenSpec instructions (openspec/AGENTS.md' ); @@ -309,7 +330,7 @@ Old slash content `; await fs.writeFile(proposalPath, initialContent); - const consoleSpy = vi.spyOn(console, 'log'); + const consoleSpy = spyOn(console, 'log'); await updateCommand.execute(testDir); @@ -321,7 +342,8 @@ Old slash content ); expect(updated).not.toContain('Old slash content'); - const [logMessage] = consoleSpy.mock.calls[0]; + const logMessage = findLogMessage(consoleSpy, 'Updated OpenSpec instructions'); + expect(logMessage).toBeDefined(); expect(logMessage).toContain( 'Updated OpenSpec instructions (openspec/AGENTS.md' ); @@ -347,7 +369,7 @@ Old body `; await fs.writeFile(cursorPath, initialContent); - const consoleSpy = vi.spyOn(console, 'log'); + const consoleSpy = spyOn(console, 'log'); await updateCommand.execute(testDir); @@ -356,7 +378,8 @@ Old body expect(updated).toContain('Work through tasks sequentially'); expect(updated).not.toContain('Old body'); - const [logMessage] = consoleSpy.mock.calls[0]; + const logMessage = findLogMessage(consoleSpy, 'Updated OpenSpec instructions'); + expect(logMessage).toBeDefined(); expect(logMessage).toContain( 'Updated OpenSpec instructions (openspec/AGENTS.md' ); @@ -385,7 +408,7 @@ Old body `; await fs.writeFile(openCodePath, initialContent); - const consoleSpy = vi.spyOn(console, 'log'); + const consoleSpy = spyOn(console, 'log'); await updateCommand.execute(testDir); @@ -394,7 +417,8 @@ Old body expect(updated).toContain('Work through tasks sequentially'); expect(updated).not.toContain('Old body'); - const [logMessage] = consoleSpy.mock.calls[0]; + const logMessage = findLogMessage(consoleSpy, 'Updated OpenSpec instructions'); + expect(logMessage).toBeDefined(); expect(logMessage).toContain( 'Updated OpenSpec instructions (openspec/AGENTS.md' ); @@ -417,7 +441,7 @@ Old body `; await fs.writeFile(kilocodePath, initialContent); - const consoleSpy = vi.spyOn(console, 'log'); + const consoleSpy = spyOn(console, 'log'); await updateCommand.execute(testDir); @@ -426,7 +450,8 @@ Old body expect(updated).not.toContain('Old body'); expect(updated.startsWith('')).toBe(true); - const [logMessage] = consoleSpy.mock.calls[0]; + const logMessage = findLogMessage(consoleSpy, 'Updated OpenSpec instructions'); + expect(logMessage).toBeDefined(); expect(logMessage).toContain( 'Updated slash commands: .kilocode/workflows/openspec-apply.md' ); @@ -447,7 +472,7 @@ Old body `; await fs.writeFile(wsPath, initialContent); - const consoleSpy = vi.spyOn(console, 'log'); + const consoleSpy = spyOn(console, 'log'); await updateCommand.execute(testDir); @@ -456,7 +481,8 @@ Old body expect(updated).not.toContain('Old body'); expect(updated).toContain('## OpenSpec: Apply (Windsurf)'); - const [logMessage] = consoleSpy.mock.calls[0]; + const logMessage = findLogMessage(consoleSpy, 'Updated OpenSpec instructions'); + expect(logMessage).toBeDefined(); expect(logMessage).toContain( 'Updated slash commands: .windsurf/workflows/openspec-apply.md' ); @@ -478,7 +504,7 @@ Old body `; await fs.writeFile(agPath, initialContent); - const consoleSpy = vi.spyOn(console, 'log'); + const consoleSpy = spyOn(console, 'log'); await updateCommand.execute(testDir); @@ -488,7 +514,8 @@ Old body expect(updated).toContain('description: Implement an approved OpenSpec change and keep tasks in sync.'); expect(updated).not.toContain('auto_execution_mode: 3'); - const [logMessage] = consoleSpy.mock.calls[0]; + const logMessage = findLogMessage(consoleSpy, 'Updated OpenSpec instructions'); + expect(logMessage).toBeDefined(); expect(logMessage).toContain( 'Updated slash commands: .agent/workflows/openspec-apply.md' ); @@ -504,7 +531,7 @@ Old body const initialContent = `---\ndescription: Old description\nargument-hint: old-hint\n---\n\n$ARGUMENTS\n\nOld body\n`; await fs.writeFile(codexPath, initialContent); - const consoleSpy = vi.spyOn(console, 'log'); + const consoleSpy = spyOn(console, 'log'); await updateCommand.execute(testDir); @@ -516,7 +543,8 @@ Old body expect(updated).not.toContain('Old body'); expect(updated).not.toContain('Old description'); - const [logMessage] = consoleSpy.mock.calls[0]; + const logMessage = findLogMessage(consoleSpy, 'Updated OpenSpec instructions'); + expect(logMessage).toBeDefined(); expect(logMessage).toContain( 'Updated slash commands: .codex/prompts/openspec-apply.md' ); @@ -569,7 +597,7 @@ Old body `; await fs.writeFile(ghPath, initialContent); - const consoleSpy = vi.spyOn(console, 'log'); + const consoleSpy = spyOn(console, 'log'); await updateCommand.execute(testDir); @@ -579,7 +607,8 @@ Old body expect(updated).toContain('Work through tasks sequentially'); expect(updated).not.toContain('Old body'); - const [logMessage] = consoleSpy.mock.calls[0]; + const logMessage = findLogMessage(consoleSpy, 'Updated OpenSpec instructions'); + expect(logMessage).toBeDefined(); expect(logMessage).toContain( 'Updated slash commands: .github/prompts/openspec-apply.prompt.md' ); @@ -632,7 +661,7 @@ Old Gemini body `; await fs.writeFile(geminiProposal, initialContent); - const consoleSpy = vi.spyOn(console, 'log'); + const consoleSpy = spyOn(console, 'log'); await updateCommand.execute(testDir); @@ -656,7 +685,8 @@ Old Gemini body await expect(FileSystemUtils.fileExists(geminiApply)).resolves.toBe(false); await expect(FileSystemUtils.fileExists(geminiArchive)).resolves.toBe(false); - const [logMessage] = consoleSpy.mock.calls[0]; + const logMessage = findLogMessage(consoleSpy, 'Updated OpenSpec instructions'); + expect(logMessage).toBeDefined(); expect(logMessage).toContain( 'Updated slash commands: .gemini/commands/openspec/proposal.toml' ); @@ -680,7 +710,7 @@ Old IFlow body `; await fs.writeFile(iflowProposal, initialContent); - const consoleSpy = vi.spyOn(console, 'log'); + const consoleSpy = spyOn(console, 'log'); await updateCommand.execute(testDir); @@ -703,7 +733,8 @@ Old IFlow body await expect(FileSystemUtils.fileExists(iflowApply)).resolves.toBe(false); await expect(FileSystemUtils.fileExists(iflowArchive)).resolves.toBe(false); - const [logMessage] = consoleSpy.mock.calls[0]; + const logMessage = findLogMessage(consoleSpy, 'Updated OpenSpec instructions'); + expect(logMessage).toBeDefined(); expect(logMessage).toContain( 'Updated slash commands: .iflow/commands/openspec-proposal.md' ); @@ -727,7 +758,7 @@ Old body `; await fs.writeFile(factoryPath, initialContent); - const consoleSpy = vi.spyOn(console, 'log'); + const consoleSpy = spyOn(console, 'log'); await updateCommand.execute(testDir); @@ -801,7 +832,7 @@ Old body `; await fs.writeFile(aqPath, initialContent); - const consoleSpy = vi.spyOn(console, 'log'); + const consoleSpy = spyOn(console, 'log'); await updateCommand.execute(testDir); @@ -862,7 +893,7 @@ Old body `; await fs.writeFile(auggiePath, initialContent); - const consoleSpy = vi.spyOn(console, 'log'); + const consoleSpy = spyOn(console, 'log'); await updateCommand.execute(testDir); @@ -925,7 +956,7 @@ Old slash content `; await fs.writeFile(codeBuddyPath, initialContent); - const consoleSpy = vi.spyOn(console, 'log'); + const consoleSpy = spyOn(console, 'log'); await updateCommand.execute(testDir); @@ -937,7 +968,8 @@ Old slash content ); expect(updated).not.toContain('Old slash content'); - const [logMessage] = consoleSpy.mock.calls[0]; + const logMessage = findLogMessage(consoleSpy, 'Updated OpenSpec instructions'); + expect(logMessage).toBeDefined(); expect(logMessage).toContain( 'Updated OpenSpec instructions (openspec/AGENTS.md' ); @@ -1003,7 +1035,7 @@ Old slash content `; await fs.writeFile(crushPath, initialContent); - const consoleSpy = vi.spyOn(console, 'log'); + const consoleSpy = spyOn(console, 'log'); await updateCommand.execute(testDir); @@ -1015,7 +1047,8 @@ Old slash content ); expect(updated).not.toContain('Old slash content'); - const [logMessage] = consoleSpy.mock.calls[0]; + const logMessage = findLogMessage(consoleSpy, 'Updated OpenSpec instructions'); + expect(logMessage).toBeDefined(); expect(logMessage).toContain( 'Updated OpenSpec instructions (openspec/AGENTS.md' ); @@ -1079,7 +1112,7 @@ Old body `; await fs.writeFile(costrictPath, initialContent); - const consoleSpy = vi.spyOn(console, 'log'); + const consoleSpy = spyOn(console, 'log'); await updateCommand.execute(testDir); @@ -1093,7 +1126,8 @@ Old body ); expect(updated).not.toContain('Old body'); - const [logMessage] = consoleSpy.mock.calls[0]; + const logMessage = findLogMessage(consoleSpy, 'Updated OpenSpec instructions'); + expect(logMessage).toBeDefined(); expect(logMessage).toContain( 'Updated OpenSpec instructions (openspec/AGENTS.md' ); @@ -1122,7 +1156,7 @@ Old slash content `; await fs.writeFile(qoderPath, initialContent); - const consoleSpy = vi.spyOn(console, 'log'); + const consoleSpy = spyOn(console, 'log'); await updateCommand.execute(testDir); @@ -1134,7 +1168,8 @@ Old slash content ); expect(updated).not.toContain('Old slash content'); - const [logMessage] = consoleSpy.mock.calls[0]; + const logMessage = findLogMessage(consoleSpy, 'Updated OpenSpec instructions'); + expect(logMessage).toBeDefined(); expect(logMessage).toContain( 'Updated OpenSpec instructions (openspec/AGENTS.md' ); @@ -1161,7 +1196,7 @@ Old body `; await fs.writeFile(rooPath, initialContent); - const consoleSpy = vi.spyOn(console, 'log'); + const consoleSpy = spyOn(console, 'log'); await updateCommand.execute(testDir); @@ -1174,7 +1209,8 @@ Old body ); expect(updated).not.toContain('Old body'); - const [logMessage] = consoleSpy.mock.calls[0]; + const logMessage = findLogMessage(consoleSpy, 'Updated OpenSpec instructions'); + expect(logMessage).toBeDefined(); expect(logMessage).toContain( 'Updated OpenSpec instructions (openspec/AGENTS.md' ); @@ -1305,7 +1341,7 @@ Old OpenSpec content More instructions after.`; await fs.writeFile(costrictPath, initialContent); - const consoleSpy = vi.spyOn(console, 'log'); + const consoleSpy = spyOn(console, 'log'); // Execute update command await updateCommand.execute(testDir); @@ -1320,7 +1356,8 @@ More instructions after.`; expect(updatedContent).toContain('More instructions after'); // Check console output - const [logMessage] = consoleSpy.mock.calls[0]; + const logMessage = findLogMessage(consoleSpy, 'Updated OpenSpec instructions'); + expect(logMessage).toBeDefined(); expect(logMessage).toContain( 'Updated OpenSpec instructions (openspec/AGENTS.md' ); @@ -1368,8 +1405,8 @@ More instructions after.`; '\nOld\n' ); - const consoleSpy = vi.spyOn(console, 'log'); - const errorSpy = vi.spyOn(console, 'error'); + const consoleSpy = spyOn(console, 'log'); + const errorSpy = spyOn(console, 'error'); const originalWriteFile = FileSystemUtils.writeFile.bind(FileSystemUtils); const writeSpy = vi .spyOn(FileSystemUtils, 'writeFile') @@ -1386,7 +1423,8 @@ More instructions after.`; // Should report the failure expect(errorSpy).toHaveBeenCalled(); - const [logMessage] = consoleSpy.mock.calls[0]; + const logMessage = findLogMessage(consoleSpy, 'Updated OpenSpec instructions'); + expect(logMessage).toBeDefined(); expect(logMessage).toContain( 'Updated OpenSpec instructions (openspec/AGENTS.md' ); @@ -1446,11 +1484,12 @@ More instructions after.`; it('should handle no AI tool files present', async () => { // Execute update command with no AI tool files - const consoleSpy = vi.spyOn(console, 'log'); + const consoleSpy = spyOn(console, 'log'); await updateCommand.execute(testDir); // Should only update OpenSpec instructions - const [logMessage] = consoleSpy.mock.calls[0]; + const logMessage = findLogMessage(consoleSpy, 'Updated OpenSpec instructions'); + expect(logMessage).toBeDefined(); expect(logMessage).toContain( 'Updated OpenSpec instructions (openspec/AGENTS.md' ); @@ -1470,11 +1509,12 @@ More instructions after.`; '\nOld\n' ); - const consoleSpy = vi.spyOn(console, 'log'); + const consoleSpy = spyOn(console, 'log'); await updateCommand.execute(testDir); // Should report updating with new format - const [logMessage] = consoleSpy.mock.calls[0]; + const logMessage = findLogMessage(consoleSpy, 'Updated OpenSpec instructions'); + expect(logMessage).toBeDefined(); expect(logMessage).toContain( 'Updated OpenSpec instructions (openspec/AGENTS.md' ); @@ -1566,7 +1606,7 @@ Old content const original = `# Custom intro\n\n\nOld content\n\n\n# Footnotes`; await fs.writeFile(rootAgentsPath, original); - const consoleSpy = vi.spyOn(console, 'log'); + const consoleSpy = spyOn(console, 'log'); await updateCommand.execute(testDir); @@ -1577,7 +1617,8 @@ Old content expect(updated).toContain('openspec update'); expect(updated).not.toContain('Old content'); - const [logMessage] = consoleSpy.mock.calls[0]; + const logMessage = findLogMessage(consoleSpy, 'Updated OpenSpec instructions'); + expect(logMessage).toBeDefined(); expect(logMessage).toContain( 'Updated OpenSpec instructions (openspec/AGENTS.md, AGENTS.md)' ); @@ -1608,25 +1649,25 @@ Old content ); await fs.chmod(claudePath, 0o444); // Read-only - const consoleSpy = vi.spyOn(console, 'log'); - const errorSpy = vi.spyOn(console, 'error'); + const consoleSpy = spyOn(console, 'log'); + const errorSpy = spyOn(console, 'error'); const originalWriteFile = FileSystemUtils.writeFile.bind(FileSystemUtils); - const writeSpy = vi - .spyOn(FileSystemUtils, 'writeFile') - .mockImplementation(async (filePath, content) => { + const writeSpy = spyOn(FileSystemUtils, 'writeFile').mockImplementation( + async (filePath, content) => { if (filePath.endsWith('CLAUDE.md')) { throw new Error('EACCES: permission denied, open'); } - return originalWriteFile(filePath, content); - }); + } + ); // Execute update command - should not throw await updateCommand.execute(testDir); // Should report the failure expect(errorSpy).toHaveBeenCalled(); - const [logMessage] = consoleSpy.mock.calls[0]; + const logMessage = findLogMessage(consoleSpy, 'Updated OpenSpec instructions'); + expect(logMessage).toBeDefined(); expect(logMessage).toContain( 'Updated OpenSpec instructions (openspec/AGENTS.md' ); diff --git a/test/core/validation.enriched-messages.test.ts b/test/core/validation.enriched-messages.test.ts index 7b24d1c17..0b4eef432 100644 --- a/test/core/validation.enriched-messages.test.ts +++ b/test/core/validation.enriched-messages.test.ts @@ -1,4 +1,4 @@ -import { describe, it, expect, beforeEach, afterEach } from 'vitest'; +import { describe, it, expect, beforeEach, afterEach } from 'bun:test'; import { promises as fs } from 'fs'; import path from 'path'; import { Validator } from '../../src/core/validation/validator.js'; diff --git a/test/core/validation.test.ts b/test/core/validation.test.ts index f7323b36a..bf7bfd64a 100644 --- a/test/core/validation.test.ts +++ b/test/core/validation.test.ts @@ -1,4 +1,4 @@ -import { describe, it, expect, beforeEach, afterEach } from 'vitest'; +import { describe, it, expect, beforeEach, afterEach } from 'bun:test'; import { promises as fs } from 'fs'; import path from 'path'; import { Validator } from '../../src/core/validation/validator.js'; diff --git a/test/core/view.test.ts b/test/core/view.test.ts index 7b68f2eb0..9c9ae7f59 100644 --- a/test/core/view.test.ts +++ b/test/core/view.test.ts @@ -1,4 +1,4 @@ -import { describe, it, expect, beforeEach, afterEach } from 'vitest'; +import { describe, it, expect, beforeEach, afterEach } from 'bun:test'; import { promises as fs } from 'fs'; import path from 'path'; import os from 'os'; diff --git a/test/helpers/run-cli.ts b/test/helpers/run-cli.ts index 69d67df7f..fd81813c8 100644 --- a/test/helpers/run-cli.ts +++ b/test/helpers/run-cli.ts @@ -59,7 +59,7 @@ export async function ensureCliBuilt() { } if (!buildPromise) { - buildPromise = runCommand('pnpm', ['run', 'build']).catch((error) => { + buildPromise = runCommand('bun', ['run', 'build']).catch((error) => { buildPromise = undefined; throw error; }); @@ -79,7 +79,7 @@ export async function runCLI(args: string[] = [], options: RunCLIOptions = {}): const invocation = [cliEntry, ...finalArgs].join(' '); return new Promise((resolve, reject) => { - const child = spawn(process.execPath, [cliEntry, ...finalArgs], { + const child = spawn('bun', [cliEntry, ...finalArgs], { cwd: options.cwd ?? projectRoot, env: { ...process.env, @@ -88,9 +88,9 @@ export async function runCLI(args: string[] = [], options: RunCLIOptions = {}): }, stdio: ['pipe', 'pipe', 'pipe'], windowsHide: true, + shell: process.platform === 'win32', }); - // Prevent child process from keeping the event loop alive child.unref(); let stdout = ''; @@ -116,7 +116,6 @@ export async function runCLI(args: string[] = [], options: RunCLIOptions = {}): child.on('error', (error) => { if (timeout) clearTimeout(timeout); - // Explicitly destroy streams to prevent hanging handles child.stdout?.destroy(); child.stderr?.destroy(); child.stdin?.destroy(); @@ -125,7 +124,6 @@ export async function runCLI(args: string[] = [], options: RunCLIOptions = {}): child.on('close', (code, signal) => { if (timeout) clearTimeout(timeout); - // Explicitly destroy streams to prevent hanging handles child.stdout?.destroy(); child.stderr?.destroy(); child.stdin?.destroy(); @@ -135,7 +133,7 @@ export async function runCLI(args: string[] = [], options: RunCLIOptions = {}): stdout, stderr, timedOut, - command: `node ${invocation}`, + command: `bun ${invocation}`, }); }); diff --git a/test/utils/change-utils.test.ts b/test/utils/change-utils.test.ts index 1487e7af7..25f80a7d7 100644 --- a/test/utils/change-utils.test.ts +++ b/test/utils/change-utils.test.ts @@ -1,4 +1,4 @@ -import { describe, it, expect, beforeEach, afterEach } from 'vitest'; +import { describe, it, expect, beforeEach, afterEach } from 'bun:test'; import { promises as fs } from 'fs'; import path from 'path'; import os from 'os'; diff --git a/test/utils/file-system.test.ts b/test/utils/file-system.test.ts index 7a96db08d..3aff0bb64 100644 --- a/test/utils/file-system.test.ts +++ b/test/utils/file-system.test.ts @@ -1,4 +1,4 @@ -import { describe, it, expect, beforeEach, afterEach } from 'vitest'; +import { describe, it, expect, beforeEach, afterEach } from 'bun:test'; import { promises as fs } from 'fs'; import path from 'path'; import os from 'os'; @@ -38,7 +38,7 @@ describe('FileSystemUtils', () => { const dirPath = path.join(testDir, 'existing-dir'); await fs.mkdir(dirPath); - await expect(FileSystemUtils.createDirectory(dirPath)).resolves.not.toThrow(); + await FileSystemUtils.createDirectory(dirPath); }); }); diff --git a/test/utils/interactive.test.ts b/test/utils/interactive.test.ts index c1753d31d..aaad055f8 100644 --- a/test/utils/interactive.test.ts +++ b/test/utils/interactive.test.ts @@ -1,4 +1,4 @@ -import { describe, it, expect, beforeEach, afterEach } from 'vitest'; +import { describe, it, expect, beforeEach, afterEach } from 'bun:test'; import { isInteractive, resolveNoInteractive, InteractiveOptions } from '../../src/utils/interactive.js'; describe('interactive utilities', () => { diff --git a/test/utils/marker-updates.test.ts b/test/utils/marker-updates.test.ts index b3cec84d6..cebd1d669 100644 --- a/test/utils/marker-updates.test.ts +++ b/test/utils/marker-updates.test.ts @@ -1,4 +1,4 @@ -import { describe, it, expect, beforeEach, afterEach } from 'vitest'; +import { describe, it, expect, beforeEach, afterEach } from 'bun:test'; import { promises as fs } from 'fs'; import path from 'path'; import os from 'os'; diff --git a/test/utils/shell-detection.test.ts b/test/utils/shell-detection.test.ts index 8df25db74..12374550a 100644 --- a/test/utils/shell-detection.test.ts +++ b/test/utils/shell-detection.test.ts @@ -1,4 +1,4 @@ -import { describe, it, expect, beforeEach, afterEach } from 'vitest'; +import { describe, it, expect, beforeEach, afterEach } from 'bun:test'; import { detectShell, SupportedShell } from '../../src/utils/shell-detection.js'; describe('shell-detection', () => { diff --git a/vitest.config.ts b/vitest.config.ts deleted file mode 100644 index 88c06dd8d..000000000 --- a/vitest.config.ts +++ /dev/null @@ -1,26 +0,0 @@ -import { defineConfig } from 'vitest/config'; - -export default defineConfig({ - test: { - globals: true, - environment: 'node', - globalSetup: './vitest.setup.ts', - // Keep default pool settings; some tests rely on process.chdir, - // which is not supported in worker threads - include: ['test/**/*.test.ts'], - coverage: { - reporter: ['text', 'json', 'html'], - exclude: [ - 'node_modules/', - 'dist/', - 'bin/', - '*.config.ts', - 'build.js', - 'test/**' - ] - }, - testTimeout: 10000, - hookTimeout: 10000, - teardownTimeout: 3000 - } -}); diff --git a/vitest.setup.ts b/vitest.setup.ts deleted file mode 100644 index 3ffc2c607..000000000 --- a/vitest.setup.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { ensureCliBuilt } from './test/helpers/run-cli.js'; - -// Ensure the CLI bundle exists before tests execute -export async function setup() { - await ensureCliBuilt(); -} - -// Global teardown to ensure clean exit -export async function teardown() { - // Clear any remaining timers - // This helps prevent hanging handles from keeping the process alive -}