diff --git a/.github/dependabot.yml b/.github/dependabot.yml
new file mode 100644
index 0000000..85c26b2
--- /dev/null
+++ b/.github/dependabot.yml
@@ -0,0 +1,11 @@
+version: 2
+updates:
+ - package-ecosystem: npm
+ directory: /
+ schedule:
+ interval: weekly
+
+ - package-ecosystem: github-actions
+ directory: /
+ schedule:
+ interval: weekly
diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml
index b80cffb..0fe090d 100644
--- a/.github/workflows/ci.yaml
+++ b/.github/workflows/ci.yaml
@@ -12,16 +12,22 @@ jobs:
runs-on: ubuntu-latest
steps:
- - name: Install Nodejs
- uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
- with:
- node-version: 24
-
- name: Checkout repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
fetch-depth: 0
+ - name: Install Nodejs
+ uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
+ with:
+ node-version-file: .nvmrc
+ cache: npm
+
+ - name: Install Pixi
+ run: |
+ curl -fsSL https://pixi.sh/install.sh | sh
+ echo "$HOME/.pixi/bin" >> "$GITHUB_PATH"
+
- name: Install dependencies
run: npm ci
@@ -37,6 +43,9 @@ jobs:
- name: Build extension
run: npm run compile
+ - name: Run tests
+ run: xvfb-run -a npm test
+
- name: Package extension
run: npx vsce package
@@ -46,16 +55,17 @@ jobs:
needs: test
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
steps:
- - name: Install Nodejs
- uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
- with:
- node-version: 24
-
- name: Checkout repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
fetch-depth: 0
+ - name: Install Nodejs
+ uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
+ with:
+ node-version-file: .nvmrc
+ cache: npm
+
- run: npm ci
- name: Set pre-release version
@@ -72,16 +82,17 @@ jobs:
needs: test
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
steps:
- - name: Install Nodejs
- uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
- with:
- node-version: 24
-
- name: Checkout repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
fetch-depth: 0
+ - name: Install Nodejs
+ uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
+ with:
+ node-version-file: .nvmrc
+ cache: npm
+
- run: npm ci
- name: Set pre-release version
diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml
index b6ef8c4..2098808 100644
--- a/.github/workflows/release.yaml
+++ b/.github/workflows/release.yaml
@@ -10,16 +10,17 @@ jobs:
name: 'Check version'
runs-on: ubuntu-latest
steps:
- - name: Install Nodejs
- uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
- with:
- node-version: 24
-
- name: Checkout repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
fetch-depth: ${{ env.FETCH_DEPTH }}
+ - name: Install Nodejs
+ uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
+ with:
+ node-version-file: .nvmrc
+ cache: npm
+
- name: Validate package version matches git tag
run: |
TAG_VERSION=${GITHUB_REF#refs/tags/v}
@@ -34,16 +35,17 @@ jobs:
runs-on: ubuntu-latest
needs: check-version
steps:
- - name: Install Nodejs
- uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
- with:
- node-version: 24
-
- name: Checkout repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
fetch-depth: 0
+ - name: Install Nodejs
+ uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
+ with:
+ node-version-file: .nvmrc
+ cache: npm
+
# Install Node dependencies.
- run: npm ci
@@ -56,16 +58,17 @@ jobs:
runs-on: ubuntu-latest
needs: check-version
steps:
- - name: Install Nodejs
- uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
- with:
- node-version: 24
-
- name: Checkout repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
fetch-depth: 0
+ - name: Install Nodejs
+ uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
+ with:
+ node-version-file: .nvmrc
+ cache: npm
+
# Install Node dependencies.
- run: npm ci
diff --git a/.github/workflows/security-audit.yaml b/.github/workflows/security-audit.yaml
new file mode 100644
index 0000000..31b3a4d
--- /dev/null
+++ b/.github/workflows/security-audit.yaml
@@ -0,0 +1,24 @@
+name: Dependency security audit
+
+on:
+ schedule:
+ - cron: '23 4 * * 1'
+ workflow_dispatch:
+
+permissions:
+ contents: read
+
+jobs:
+ audit:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
+
+ - name: Install Node.js
+ uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
+ with:
+ node-version-file: .nvmrc
+ cache: npm
+
+ - run: npm ci
+ - run: npm audit --audit-level=high
diff --git a/.gitignore b/.gitignore
index 0b60dfa..8466251 100644
--- a/.gitignore
+++ b/.gitignore
@@ -3,3 +3,7 @@ dist
node_modules
.vscode-test/
*.vsix
+
+# Pixi environments in test fixtures and projects
+**/.pixi/*
+!**/.pixi/config.toml
diff --git a/.husky/pre-commit b/.husky/pre-commit
new file mode 100644
index 0000000..3c15019
--- /dev/null
+++ b/.husky/pre-commit
@@ -0,0 +1 @@
+npx lint-staged --concurrent false
diff --git a/.nvmrc b/.nvmrc
new file mode 100644
index 0000000..df6ae33
--- /dev/null
+++ b/.nvmrc
@@ -0,0 +1 @@
+24.21.0
diff --git a/.prettierignore b/.prettierignore
new file mode 100644
index 0000000..678d79a
--- /dev/null
+++ b/.prettierignore
@@ -0,0 +1 @@
+**/pixi.lock
diff --git a/.prettierrc b/.prettierrc
index 397eb7e..844605c 100644
--- a/.prettierrc
+++ b/.prettierrc
@@ -5,6 +5,7 @@
"printWidth": 120,
"tabWidth": 4,
"useTabs": false,
+ "endOfLine": "auto",
"overrides": [
{
"files": ["*.yml", "*.yaml"],
diff --git a/.vscode-test.mjs b/.vscode-test.mjs
new file mode 100644
index 0000000..ddc06ce
--- /dev/null
+++ b/.vscode-test.mjs
@@ -0,0 +1,12 @@
+import { defineConfig } from '@vscode/test-cli';
+import { fileURLToPath } from 'node:url';
+
+export default defineConfig({
+ files: 'out/test/**/*.vscode.test.js',
+ version: 'stable',
+ workspaceFolder: fileURLToPath(new URL('./test/fixtures/pixi-project/', import.meta.url)),
+ mocha: {
+ ui: 'tdd',
+ timeout: 20_000,
+ },
+});
diff --git a/.vscode/launch.json b/.vscode/launch.json
index 0fed5b9..1968b8d 100644
--- a/.vscode/launch.json
+++ b/.vscode/launch.json
@@ -5,7 +5,7 @@
"name": "Run Extension",
"type": "extensionHost",
"request": "launch",
- "args": ["--extensionDevelopmentPath=${workspaceFolder}"],
+ "args": ["${workspaceFolder}/test/fixtures/pixi-project", "--extensionDevelopmentPath=${workspaceFolder}"],
"outFiles": ["${workspaceFolder}/dist/**/*.js"],
"preLaunchTask": "${defaultBuildTask}"
}
diff --git a/.vscode/tasks.json b/.vscode/tasks.json
index 45c4565..2095f60 100644
--- a/.vscode/tasks.json
+++ b/.vscode/tasks.json
@@ -1,6 +1,15 @@
{
"version": "2.0.0",
"tasks": [
+ {
+ "type": "npm",
+ "script": "compile",
+ "problemMatcher": [],
+ "group": {
+ "kind": "build",
+ "isDefault": true
+ }
+ },
{
"type": "npm",
"script": "watch",
@@ -11,8 +20,7 @@
"group": "watchers"
},
"group": {
- "kind": "build",
- "isDefault": true
+ "kind": "build"
}
},
{
diff --git a/.vscodeignore b/.vscodeignore
index 98449b5..d1108c6 100644
--- a/.vscodeignore
+++ b/.vscodeignore
@@ -1,6 +1,8 @@
**/.github/
.vscode/**
.vscode-test/**
+test/**
+**/.pixi/**
out/**
node_modules/**
src/**
diff --git a/CHANGELOG.md b/CHANGELOG.md
index c8a9de4..99eb6ed 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -5,6 +5,17 @@ All notable changes to the "pixi-code" extension will be documented in this file
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
+## [0.2.1]
+
+- Publish as `kaiserls.pixi-code` and fix Pixi manager registration with Python Environments
+- Keep valid Python environments visible when a Pixi environment targets an unsupported platform
+- Handle package refresh failures and use Pixi environment names for package queries
+- Support relative paths and `${workspaceFolder}` in `pixi-code.pixiExecutable`
+- Use the first workspace folder as the default working directory for Pixi commands
+- Improve activation diagnostics in the Pixi output channel
+- Exclude test fixtures and local Pixi environments from the extension package
+- Add automated tests and dependency security checks, and update vulnerable test dependencies
+
## [0.2.0]
- Use published @vscode/python-environments API package
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 5a84c4c..533c30c 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -8,39 +8,43 @@ Code extension that integrates Pixi environments with the Python Environments ex
1. **Prerequisites**
- Node.js 20+
- VS Code with the Python Environments extension installed
- - Pixi installed on your system
+ - [Pixi](https://pixi.prefix.dev/latest/installation/) installed on your system
2. **Clone and setup**
```bash
- git clone https://github.com/renan-r-santos/pixi-code.git
+ git clone https://github.com/kaiserls/pixi-code.git
cd pixi-code
npm install
```
3. **Development workflow**
+
```bash
- npm run compile # Build the extension
- npm run watch # Watch for changes during development
+ npm run watch # Rebuild while you edit
+ npm test # Run the full validation suite before submitting
```
+ Press `F5` in VS Code to launch an Extension Development Host, then open a project containing `pixi.toml` or a
+ `pyproject.toml` with a `[tool.pixi]` table.
+
## Code style and quality
-This project maintains strict code quality standards using TypeScript, ESLint, and Prettier. All code must pass these
-quality checks before being merged.
+This project uses TypeScript, ESLint, and Prettier. `npm test` runs the required checks before its unit and extension
+tests. Husky formats and fixes staged files at commit time.
-```bash
-npm run lint # Check for linting issues
-npm run format:check # Check code formatting
-npm run compile # Build and verify compilation
-```
+### Tests
-Fixing issues:
+Use unit tests for pure TypeScript logic, such as Pixi command construction and parsing. They run directly in Node.js and
+must not import the `vscode` runtime module.
-```bash
-npm run format # Auto-fix formatting issues
-npm run lint -- --fix # Auto-fix linting issues where possible
-```
+Use VS Code extension-host tests for interactions with the `vscode` API, extension activation, and extension
+contributions. The first run downloads an isolated VS Code instance into `.vscode-test/`; later runs reuse it.
+
+For focused work, run `npm run test:unit` or `npm run test:vscode` individually. `npm run typecheck` is available when
+you only need TypeScript validation.
+
+The CI `test` job runs `npm test` before either pre-release publishing job is allowed to start.
## Making a contribution
@@ -60,16 +64,7 @@ git checkout -b feature/your-feature-name
- **Code formatting**: Use Prettier to format your code
- **Logging**: Use the provided logging utilities in `src/common/logging.ts`
-### 3. Extension testing
-
-Test the extension functionality:
-
-1. Press `F5` in launch VS Code in debug mode
-2. Open a project containing `pixi.toml` or `pyproject.toml`
-3. Verify Pixi environments are discovered and functional
-4. Test environment switching and terminal activation
-
-### 4. Commit and submit
+### 3. Commit and submit
- Reference any related issues
- Submit a pull request with detailed description
diff --git a/README.md b/README.md
index f5ba625..9007a02 100644
--- a/README.md
+++ b/README.md
@@ -3,7 +3,7 @@
[](https://marketplace.visualstudio.com/items?itemName=renan-r-santos.pixi-code)
+Version](https://img.shields.io/visual-studio-marketplace/v/kaiserls.pixi-code)](https://marketplace.visualstudio.com/items?itemName=kaiserls.pixi-code)
@@ -35,7 +35,7 @@ conda, venv, and other Python environments in VS Code.
## Installation
1. Install Pixi on your system
-2. Install [this extension](https://marketplace.visualstudio.com/items?itemName=renan-r-santos.pixi-code) from the VS
+2. Install [this extension](https://marketplace.visualstudio.com/items?itemName=kaiserls.pixi-code) from the VS
Code Marketplace
3. Open a project with a `pixi.toml` or `pyproject.toml` file
@@ -43,7 +43,7 @@ The extension will automatically discover Pixi environments and register them wi
## Extension Settings
-- `pixi-code.pixiExecutable`: Path to the Pixi executable. Leave empty to use auto-discovery (default).
+- `pixi-code.pixiExecutable`: Path to the Pixi executable. Supports `${workspaceFolder}` and paths relative to a workspace folder. Leave empty to use auto-discovery (default).
## Limitations
@@ -74,6 +74,10 @@ Check the "Pixi Environment Manager" output channel:
- Verify `pixi.toml` or `pyproject.toml` exists in project root
- Run `pixi install` to ensure environments are set up
+## Contributing
+
+See [CONTRIBUTING.md](CONTRIBUTING.md) for development setup and workflow details.
+
## License
MIT
diff --git a/package-lock.json b/package-lock.json
index da1720b..2efd663 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,12 +1,12 @@
{
"name": "pixi-code",
- "version": "0.2.0",
+ "version": "0.2.1",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "pixi-code",
- "version": "0.2.0",
+ "version": "0.2.1",
"license": "MIT",
"dependencies": {
"@types/semver": "^7.7.1",
@@ -18,14 +18,19 @@
},
"devDependencies": {
"@types/fs-extra": "^11.0.4",
+ "@types/mocha": "^10.0.10",
"@types/node": "24.x",
"@types/vscode": "^1.118.0",
"@types/which": "^3.0.4",
"@typescript-eslint/eslint-plugin": "^8.59.1",
"@typescript-eslint/parser": "^8.59.1",
+ "@vscode/test-cli": "^0.0.15",
+ "@vscode/test-electron": "^2.5.2",
"eslint": "^10.2.1",
"eslint-plugin-simple-import-sort": "^13.0.0",
"eslint-plugin-unused-imports": "^4.4.1",
+ "husky": "^9.1.7",
+ "lint-staged": "^15.5.2",
"prettier": "^3.8.3",
"ts-loader": "^9.5.7",
"typescript": "^6.0.3",
@@ -36,6 +41,16 @@
"vscode": "^1.118.0"
}
},
+ "node_modules/@bcoe/v8-coverage": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-1.0.2.tgz",
+ "integrity": "sha512-6zABk/ECA/QYSCQ1NGiVwwbQerUCZ+TQbp64Q3AgmfNvurHH0j8TtXa1qbShXA6qqkpAj4V5W8pP6mLe1mcMqA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ }
+ },
"node_modules/@discoveryjs/json-ext": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-1.0.0.tgz",
@@ -206,6 +221,16 @@
"url": "https://github.com/sponsors/nzakas"
}
},
+ "node_modules/@istanbuljs/schema": {
+ "version": "0.1.6",
+ "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.6.tgz",
+ "integrity": "sha512-+Sg6GCR/wy1oSmQDFq4LQDAhm3ETKnorxN+y5nbLULOR3P0c14f2Wurzj3/xqPXtasLFfHd5iRFQ7AJt4KH2cw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
"node_modules/@jridgewell/gen-mapping": {
"version": "0.3.13",
"resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz",
@@ -338,6 +363,13 @@
"@types/node": "*"
}
},
+ "node_modules/@types/istanbul-lib-coverage": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz",
+ "integrity": "sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/@types/json-schema": {
"version": "7.0.15",
"resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz",
@@ -355,6 +387,13 @@
"@types/node": "*"
}
},
+ "node_modules/@types/mocha": {
+ "version": "10.0.10",
+ "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-10.0.10.tgz",
+ "integrity": "sha512-xPyYSz1cMPnJQhl0CLMH68j3gprKZaTjG3s5Vi+fDgx+uhG9NOXwbVt52eFS8ECyXhyKcjDLCBEqBExKuiZb7Q==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/@types/node": {
"version": "24.12.2",
"resolved": "https://registry.npmjs.org/@types/node/-/node-24.12.2.tgz",
@@ -628,6 +667,120 @@
"vscode": "^1.110.0"
}
},
+ "node_modules/@vscode/test-cli": {
+ "version": "0.0.15",
+ "resolved": "https://registry.npmjs.org/@vscode/test-cli/-/test-cli-0.0.15.tgz",
+ "integrity": "sha512-nAxk2X79wuXS7aOhyFFhFcCqd7EBUoMesu7ZgsYE/4eFjyBMuyIweVE94BxdKH1RieN8eOz2SIrljrZt6Lk9fQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/mocha": "^10.0.10",
+ "c8": "^11.0.0",
+ "chokidar": "^5.0.0",
+ "enhanced-resolve": "^5.24.0",
+ "glob": "^13.0.6",
+ "minimatch": "^10.2.5",
+ "mocha": "^11.7.6",
+ "supports-color": "^10.2.2",
+ "yargs": "^18.0.0"
+ },
+ "bin": {
+ "vscode-test": "out/bin.mjs"
+ },
+ "engines": {
+ "node": ">=22"
+ }
+ },
+ "node_modules/@vscode/test-cli/node_modules/cliui": {
+ "version": "9.0.1",
+ "resolved": "https://registry.npmjs.org/cliui/-/cliui-9.0.1.tgz",
+ "integrity": "sha512-k7ndgKhwoQveBL+/1tqGJYNz097I7WOvwbmmU2AR5+magtbjPWQTS1C5vzGkBC8Ym8UWRzfKUzUUqFLypY4Q+w==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "string-width": "^7.2.0",
+ "strip-ansi": "^7.1.0",
+ "wrap-ansi": "^9.0.0"
+ },
+ "engines": {
+ "node": ">=20"
+ }
+ },
+ "node_modules/@vscode/test-cli/node_modules/supports-color": {
+ "version": "10.2.2",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-10.2.2.tgz",
+ "integrity": "sha512-SS+jx45GF1QjgEXQx4NJZV9ImqmO2NPz5FNsIHrsDjh2YsHnawpan7SNQ1o8NuhrbHZy9AZhIoCUiCeaW/C80g==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/supports-color?sponsor=1"
+ }
+ },
+ "node_modules/@vscode/test-cli/node_modules/yargs": {
+ "version": "18.2.0",
+ "resolved": "https://registry.npmjs.org/yargs/-/yargs-18.2.0.tgz",
+ "integrity": "sha512-9OpKOLeaoNFecEp7P6iYbzze/5CqWoH7N3SMs/6y1XF4nMvFMspEGZzJ6uFi9MmQwXhyzqYoSEKO3tvA3Z/o2w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "cliui": "^9.0.1",
+ "escalade": "^3.1.1",
+ "get-caller-file": "^2.0.5",
+ "string-width": "^8.2.1",
+ "y18n": "^5.0.5",
+ "yargs-parser": "^22.0.0"
+ },
+ "engines": {
+ "node": "^20.19.0 || ^22.12.0 || >=23"
+ }
+ },
+ "node_modules/@vscode/test-cli/node_modules/yargs-parser": {
+ "version": "22.0.0",
+ "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-22.0.0.tgz",
+ "integrity": "sha512-rwu/ClNdSMpkSrUb+d6BRsSkLUq1fmfsY6TOpYzTwvwkg1/NRG85KBy3kq++A8LKQwX6lsu+aWad+2khvuXrqw==",
+ "dev": true,
+ "license": "ISC",
+ "engines": {
+ "node": "^20.19.0 || ^22.12.0 || >=23"
+ }
+ },
+ "node_modules/@vscode/test-cli/node_modules/yargs/node_modules/string-width": {
+ "version": "8.3.0",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-8.3.0.tgz",
+ "integrity": "sha512-ZbmZM0JCihQN91dWnxoipT2KOEyHqEyfRXUyjuRhW8b/xnqPDoq4gWEVApTVa9db2wN8mmoikgFBbjh71+cGeQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "get-east-asian-width": "^1.5.0",
+ "strip-ansi": "^7.1.2"
+ },
+ "engines": {
+ "node": ">=20"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/@vscode/test-electron": {
+ "version": "2.5.2",
+ "resolved": "https://registry.npmjs.org/@vscode/test-electron/-/test-electron-2.5.2.tgz",
+ "integrity": "sha512-8ukpxv4wYe0iWMRQU18jhzJOHkeGKbnw7xWRX3Zw1WJA4cEKbHcmmLPdPrPtL6rhDcrlCZN+xKRpv09n4gRHYg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "http-proxy-agent": "^7.0.2",
+ "https-proxy-agent": "^7.0.5",
+ "jszip": "^3.10.1",
+ "ora": "^8.1.0",
+ "semver": "^7.6.2"
+ },
+ "engines": {
+ "node": ">=16"
+ }
+ },
"node_modules/@webassemblyjs/ast": {
"version": "1.14.1",
"resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.14.1.tgz",
@@ -839,6 +992,16 @@
"acorn": "^6.0.0 || ^7.0.0 || ^8.0.0"
}
},
+ "node_modules/agent-base": {
+ "version": "7.1.4",
+ "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.4.tgz",
+ "integrity": "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 14"
+ }
+ },
"node_modules/ajv": {
"version": "6.15.0",
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.15.0.tgz",
@@ -898,6 +1061,35 @@
"dev": true,
"license": "MIT"
},
+ "node_modules/ansi-escapes": {
+ "version": "7.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-7.3.0.tgz",
+ "integrity": "sha512-BvU8nYgGQBxcmMuEeUEmNTvrMVjJNSH7RgW24vXexN4Ven6qCvy4TntnvlnwnMLTVlcRQQdbRY8NKnaIoeWDNg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "environment": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/ansi-regex": {
+ "version": "6.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.3.0.tgz",
+ "integrity": "sha512-WpDfL7NO6j7tH88IDBNVdUJxDh9nmCteAVW9dsep846XdwF4naCBK+/tGLX3KJgcpgMRXCFlTM2hKGoK9FsdrQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-regex?sponsor=1"
+ }
+ },
"node_modules/ansi-styles": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
@@ -914,6 +1106,13 @@
"url": "https://github.com/chalk/ansi-styles?sponsor=1"
}
},
+ "node_modules/argparse": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
+ "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
+ "dev": true,
+ "license": "Python-2.0"
+ },
"node_modules/balanced-match": {
"version": "4.0.4",
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz",
@@ -925,9 +1124,9 @@
}
},
"node_modules/baseline-browser-mapping": {
- "version": "2.10.24",
- "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.10.24.tgz",
- "integrity": "sha512-I2NkZOOrj2XuguvWCK6OVh9GavsNjZjK908Rq3mIBK25+GD8vPX5w2WdxVqnQ7xx3SrZJiCiZFu+/Oz50oSYSA==",
+ "version": "2.11.26",
+ "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.11.26.tgz",
+ "integrity": "sha512-GLQdD3y6UF8iVuMJl5fHgE4jdn/ua7n+toKfLgNlg3BqQtOZjpy68T8Tup8/wGWZCDlm7KMg7tPb4MPn7oN0TQ==",
"dev": true,
"license": "Apache-2.0",
"bin": {
@@ -938,16 +1137,16 @@
}
},
"node_modules/brace-expansion": {
- "version": "5.0.5",
- "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.5.tgz",
- "integrity": "sha512-VZznLgtwhn+Mact9tfiwx64fA9erHH/MCXEUfB/0bX/6Fz6ny5EGTXYltMocqg4xFAQZtnO3DHWWXi8RiuN7cQ==",
+ "version": "5.0.12",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.12.tgz",
+ "integrity": "sha512-YovQ3rzhaLMIrDjNDMkNS01tea93qhEhG5xy8f6+R0l+dw3Ki+5sCoIoI942iuLZTHWogWktgwVDhU09iNEimQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"balanced-match": "^4.0.2"
},
"engines": {
- "node": "18 || 20 || >=22"
+ "node": "20 || >=22"
}
},
"node_modules/braces": {
@@ -962,10 +1161,17 @@
"node": ">=8"
}
},
+ "node_modules/browser-stdout": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz",
+ "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==",
+ "dev": true,
+ "license": "ISC"
+ },
"node_modules/browserslist": {
- "version": "4.28.2",
- "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.2.tgz",
- "integrity": "sha512-48xSriZYYg+8qXna9kwqjIVzuQxi+KYWp2+5nCYnYKPTr0LvD89Jqk2Or5ogxz0NUMfIjhh2lIUX/LyX9B4oIg==",
+ "version": "4.29.1",
+ "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.29.1.tgz",
+ "integrity": "sha512-AUdjuRyCNGUYtqpqfTmWyM4fXay8yIQhmLnvYe/THMGfT9B/34X7xQd3ifKxwyNPPpowVBjLb+64BN9Rn1mizw==",
"dev": true,
"funding": [
{
@@ -983,11 +1189,11 @@
],
"license": "MIT",
"dependencies": {
- "baseline-browser-mapping": "^2.10.12",
- "caniuse-lite": "^1.0.30001782",
- "electron-to-chromium": "^1.5.328",
- "node-releases": "^2.0.36",
- "update-browserslist-db": "^1.2.3"
+ "baseline-browser-mapping": "^2.11.25",
+ "caniuse-lite": "^1.0.30001810",
+ "electron-to-chromium": "^1.5.438",
+ "node-releases": "^2.0.57",
+ "update-browserslist-db": "^1.3.3"
},
"bin": {
"browserslist": "cli.js"
@@ -1003,10 +1209,44 @@
"dev": true,
"license": "MIT"
},
+ "node_modules/c8": {
+ "version": "11.0.0",
+ "resolved": "https://registry.npmjs.org/c8/-/c8-11.0.0.tgz",
+ "integrity": "sha512-e/uRViGHSVIJv7zsaDKM7VRn2390TgHXqUSvYwPHBQaU6L7E9L0n9JbdkwdYPvshDT0KymBmmlwSpms3yBaMNg==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "@bcoe/v8-coverage": "^1.0.1",
+ "@istanbuljs/schema": "^0.1.3",
+ "find-up": "^5.0.0",
+ "foreground-child": "^3.1.1",
+ "istanbul-lib-coverage": "^3.2.0",
+ "istanbul-lib-report": "^3.0.1",
+ "istanbul-reports": "^3.1.6",
+ "test-exclude": "^8.0.0",
+ "v8-to-istanbul": "^9.0.0",
+ "yargs": "^17.7.2",
+ "yargs-parser": "^21.1.1"
+ },
+ "bin": {
+ "c8": "bin/c8.js"
+ },
+ "engines": {
+ "node": "20 || >=22"
+ },
+ "peerDependencies": {
+ "monocart-coverage-reports": "^2"
+ },
+ "peerDependenciesMeta": {
+ "monocart-coverage-reports": {
+ "optional": true
+ }
+ }
+ },
"node_modules/caniuse-lite": {
- "version": "1.0.30001791",
- "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001791.tgz",
- "integrity": "sha512-yk0l/YSrOnFZk3UROpDLQD9+kC1l4meK/wed583AXrzoarMGJcbRi2Q4RaUYbKxYAsZ8sWmaSa/DsLmdBeI1vQ==",
+ "version": "1.0.30001812",
+ "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001812.tgz",
+ "integrity": "sha512-qN+QNNBr93TCmFrmte0bBCjSDMuRvt78VlHT99qIGPszm4QsqCX8lnyWUFkHi8B7ZBAPq8SH+UqyXNy/odMdng==",
"dev": true,
"funding": [
{
@@ -1041,6 +1281,22 @@
"url": "https://github.com/chalk/chalk?sponsor=1"
}
},
+ "node_modules/chokidar": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-5.0.0.tgz",
+ "integrity": "sha512-TQMmc3w+5AxjpL8iIiwebF73dRDF4fBIieAqGn9RGCWaEVwQ6Fb2cGe31Yns0RRIzii5goJ1Y7xbMwo1TxMplw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "readdirp": "^5.0.0"
+ },
+ "engines": {
+ "node": ">= 20.19.0"
+ },
+ "funding": {
+ "url": "https://paulmillr.com/funding/"
+ }
+ },
"node_modules/chrome-trace-event": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.4.tgz",
@@ -1051,6 +1307,140 @@
"node": ">=6.0"
}
},
+ "node_modules/cli-cursor": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-5.0.0.tgz",
+ "integrity": "sha512-aCj4O5wKyszjMmDT4tZj93kxyydN/K5zPWSCe6/0AV/AA1pqe5ZBIw0a2ZfPQV7lL5/yb5HsUreJ6UFAF1tEQw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "restore-cursor": "^5.0.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/cli-spinners": {
+ "version": "2.9.2",
+ "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.9.2.tgz",
+ "integrity": "sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/cli-truncate": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-4.0.0.tgz",
+ "integrity": "sha512-nPdaFdQ0h/GEigbPClz11D0v/ZJEwxmeVZGeMo3Z5StPtUTkA9o1lD6QwoirYiSDzbcwn2XcjwmCp68W1IS4TA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "slice-ansi": "^5.0.0",
+ "string-width": "^7.0.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/cliui": {
+ "version": "8.0.1",
+ "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz",
+ "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "string-width": "^4.2.0",
+ "strip-ansi": "^6.0.1",
+ "wrap-ansi": "^7.0.0"
+ },
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/cliui/node_modules/ansi-regex": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
+ "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/cliui/node_modules/emoji-regex": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
+ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/cliui/node_modules/is-fullwidth-code-point": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
+ "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/cliui/node_modules/string-width": {
+ "version": "4.2.3",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
+ "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "emoji-regex": "^8.0.0",
+ "is-fullwidth-code-point": "^3.0.0",
+ "strip-ansi": "^6.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/cliui/node_modules/strip-ansi": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
+ "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-regex": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/cliui/node_modules/wrap-ansi": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
+ "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-styles": "^4.0.0",
+ "string-width": "^4.1.0",
+ "strip-ansi": "^6.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
+ }
+ },
"node_modules/clone-deep": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz",
@@ -1086,6 +1476,13 @@
"dev": true,
"license": "MIT"
},
+ "node_modules/colorette": {
+ "version": "2.0.20",
+ "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz",
+ "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/commander": {
"version": "2.20.3",
"resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
@@ -1093,6 +1490,20 @@
"dev": true,
"license": "MIT"
},
+ "node_modules/convert-source-map": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz",
+ "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/core-util-is": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz",
+ "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/cross-spawn": {
"version": "7.0.6",
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
@@ -1156,17 +1567,34 @@
"dev": true,
"license": "MIT"
},
+ "node_modules/diff": {
+ "version": "9.0.0",
+ "resolved": "https://registry.npmjs.org/diff/-/diff-9.0.0.tgz",
+ "integrity": "sha512-svtcdpS8CgJyqAjEQIXdb3OjhFVVYjzGAPO8WGCmRbrml64SPw/jJD4GoE98aR7r25A0XcgrK3F02yw9R/vhQw==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "engines": {
+ "node": ">=0.3.1"
+ }
+ },
"node_modules/electron-to-chromium": {
- "version": "1.5.345",
- "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.345.tgz",
- "integrity": "sha512-F9JXQGiMrz6yVNPI2qOVPvB9HzjH5cGzhs8oJ6A28V5L/YnzN/0KsuiibqF+F1Fd9qxFzD1BUnYSd8JfULxTwg==",
+ "version": "1.5.439",
+ "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.439.tgz",
+ "integrity": "sha512-qu6QIPXhsb+CRcAiTMNjR4A1y/7tCYKkKjr5CZXRVih6qkDf79peZ2BpEU3qoDBNCRrcy3Mra3X9nG5oruuA7Q==",
"dev": true,
"license": "ISC"
},
+ "node_modules/emoji-regex": {
+ "version": "10.6.0",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.6.0.tgz",
+ "integrity": "sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/enhanced-resolve": {
- "version": "5.21.0",
- "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.21.0.tgz",
- "integrity": "sha512-otxSQPw4lkOZWkHpB3zaEQs6gWYEsmX4xQF68ElXC/TWvGxGMSGOvoNbaLXm6/cS/fSfHtsEdw90y20PCd+sCA==",
+ "version": "5.25.1",
+ "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.25.1.tgz",
+ "integrity": "sha512-nGXts5znJzmWPu+mIE9izCOzdg63oJca2mDzGWWTth7sr4aCToKcoyFVBQwN75Ij5Pf6p510EwkTqViTRzDV+w==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -1190,6 +1618,19 @@
"node": ">=4"
}
},
+ "node_modules/environment": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/environment/-/environment-1.1.0.tgz",
+ "integrity": "sha512-xUtoPkMggbz0MPyPiIWr1Kp4aeWJjDZ6SMvURhimjdZgsRuDplF5/s9hcgGhyXMhs+6vpnuoiZ2kFiu3FMnS8Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
"node_modules/es-errors": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz",
@@ -1444,6 +1885,13 @@
"node": ">=0.10.0"
}
},
+ "node_modules/eventemitter3": {
+ "version": "5.0.4",
+ "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.4.tgz",
+ "integrity": "sha512-mlsTRyGaPBjPedk6Bvw+aqbsXDtoAyAzm5MO7JgU+yVRyMQ5O8bD4Kcci7BS85f93veegeCPkL8R4GLClnjLFw==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/events": {
"version": "3.3.0",
"resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz",
@@ -1454,6 +1902,30 @@
"node": ">=0.8.x"
}
},
+ "node_modules/execa": {
+ "version": "8.0.1",
+ "resolved": "https://registry.npmjs.org/execa/-/execa-8.0.1.tgz",
+ "integrity": "sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "cross-spawn": "^7.0.3",
+ "get-stream": "^8.0.1",
+ "human-signals": "^5.0.0",
+ "is-stream": "^3.0.0",
+ "merge-stream": "^2.0.0",
+ "npm-run-path": "^5.1.0",
+ "onetime": "^6.0.0",
+ "signal-exit": "^4.1.0",
+ "strip-final-newline": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=16.17"
+ },
+ "funding": {
+ "url": "https://github.com/sindresorhus/execa?sponsor=1"
+ }
+ },
"node_modules/fast-deep-equal": {
"version": "3.1.3",
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
@@ -1504,9 +1976,9 @@
"license": "MIT"
},
"node_modules/fast-uri": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.0.tgz",
- "integrity": "sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA==",
+ "version": "3.1.8",
+ "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.8.tgz",
+ "integrity": "sha512-GZMtZUTNRpOVIECoXwLNZS5xUGE+mVNbTB8h/7Rwh2TFWcBQiPzTgyZi05BF9UMZKkLJv8XBRJTlU7zg8+ZfMg==",
"dev": true,
"funding": [
{
@@ -1581,6 +2053,19 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
+ "node_modules/find-up-simple": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/find-up-simple/-/find-up-simple-1.0.1.tgz",
+ "integrity": "sha512-afd4O7zpqHeRyg4PfDQsXmlDe2PfdHtJt6Akt8jOWaApLOZk5JXs6VMR29lz03pRe9mpykrRCYIYxaJYcfpncQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
"node_modules/flat": {
"version": "5.0.2",
"resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz",
@@ -1612,6 +2097,23 @@
"dev": true,
"license": "ISC"
},
+ "node_modules/foreground-child": {
+ "version": "3.3.1",
+ "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.1.tgz",
+ "integrity": "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "cross-spawn": "^7.0.6",
+ "signal-exit": "^4.0.1"
+ },
+ "engines": {
+ "node": ">=14"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
"node_modules/fs-extra": {
"version": "11.3.4",
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.3.4.tgz",
@@ -1636,6 +2138,60 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/get-caller-file": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
+ "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",
+ "dev": true,
+ "license": "ISC",
+ "engines": {
+ "node": "6.* || 8.* || >= 10.*"
+ }
+ },
+ "node_modules/get-east-asian-width": {
+ "version": "1.7.0",
+ "resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.7.0.tgz",
+ "integrity": "sha512-XjH1AECxf0giL2V1aU8vKyRR2ppRUb5c0EvT7zuJTokQ74bNo52zOtghqdWIqrhUD79fo3x0WfKZdOqxF6LG1Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/get-stream": {
+ "version": "8.0.1",
+ "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-8.0.1.tgz",
+ "integrity": "sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=16"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/glob": {
+ "version": "13.0.6",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-13.0.6.tgz",
+ "integrity": "sha512-Wjlyrolmm8uDpm/ogGyXZXb1Z+Ca2B8NbJwqBVg0axK9GbBeoS7yGV6vjXnYdGm6X53iehEuxxbyiKp8QmN4Vw==",
+ "dev": true,
+ "license": "BlueOak-1.0.0",
+ "dependencies": {
+ "minimatch": "^10.2.2",
+ "minipass": "^7.1.3",
+ "path-scurry": "^2.0.2"
+ },
+ "engines": {
+ "node": "18 || 20 || >=22"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
"node_modules/glob-parent": {
"version": "6.0.2",
"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz",
@@ -1685,6 +2241,67 @@
"node": ">= 0.4"
}
},
+ "node_modules/html-escaper": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz",
+ "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/http-proxy-agent": {
+ "version": "7.0.2",
+ "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz",
+ "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "agent-base": "^7.1.0",
+ "debug": "^4.3.4"
+ },
+ "engines": {
+ "node": ">= 14"
+ }
+ },
+ "node_modules/https-proxy-agent": {
+ "version": "7.0.6",
+ "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz",
+ "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "agent-base": "^7.1.2",
+ "debug": "4"
+ },
+ "engines": {
+ "node": ">= 14"
+ }
+ },
+ "node_modules/human-signals": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-5.0.0.tgz",
+ "integrity": "sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">=16.17.0"
+ }
+ },
+ "node_modules/husky": {
+ "version": "9.1.7",
+ "resolved": "https://registry.npmjs.org/husky/-/husky-9.1.7.tgz",
+ "integrity": "sha512-5gs5ytaNjBrh5Ow3zrvdUUY+0VxIuWVL4i9irt6friV+BqdCfmV11CQTWMiBYWHbXhco+J1kHfTOUkePhCDvMA==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "husky": "bin.js"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/typicode"
+ }
+ },
"node_modules/ignore": {
"version": "7.0.5",
"resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.5.tgz",
@@ -1695,6 +2312,13 @@
"node": ">= 4"
}
},
+ "node_modules/immediate": {
+ "version": "3.0.6",
+ "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz",
+ "integrity": "sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/import-local": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/import-local/-/import-local-3.2.0.tgz",
@@ -1725,6 +2349,13 @@
"node": ">=0.8.19"
}
},
+ "node_modules/inherits": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
+ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
+ "dev": true,
+ "license": "ISC"
+ },
"node_modules/interpret": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/interpret/-/interpret-3.1.1.tgz",
@@ -1760,6 +2391,19 @@
"node": ">=0.10.0"
}
},
+ "node_modules/is-fullwidth-code-point": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-4.0.0.tgz",
+ "integrity": "sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
"node_modules/is-glob": {
"version": "4.0.3",
"resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
@@ -1772,6 +2416,19 @@
"node": ">=0.10.0"
}
},
+ "node_modules/is-interactive": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-2.0.0.tgz",
+ "integrity": "sha512-qP1vozQRI+BMOPcjFzrjXuQvdak2pHNUMZoeG2eRbiSqyvbEf/wQtEOTOX1guk6E3t36RkaqiSt8A/6YElNxLQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
"node_modules/is-number": {
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
@@ -1781,6 +2438,19 @@
"node": ">=0.12.0"
}
},
+ "node_modules/is-path-inside": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-4.0.0.tgz",
+ "integrity": "sha512-lJJV/5dYS+RcL8uQdBDW9c9uWFLLBNRyFhnAKXw5tVqLlKZ4RMGZKv+YQ/IA3OhD+RpbJa1LLFM1FQPGyIXvOA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
"node_modules/is-plain-object": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz",
@@ -1794,6 +2464,39 @@
"node": ">=0.10.0"
}
},
+ "node_modules/is-stream": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz",
+ "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/is-unicode-supported": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz",
+ "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/isarray": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
+ "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/isexe": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/isexe/-/isexe-4.0.0.tgz",
@@ -1813,6 +2516,45 @@
"node": ">=0.10.0"
}
},
+ "node_modules/istanbul-lib-coverage": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz",
+ "integrity": "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/istanbul-lib-report": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz",
+ "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "istanbul-lib-coverage": "^3.0.0",
+ "make-dir": "^4.0.0",
+ "supports-color": "^7.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/istanbul-reports": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.2.0.tgz",
+ "integrity": "sha512-HGYWWS/ehqTV3xN10i23tkPkpH46MLCIMFNCaaKNavAXTF1RkqxawEPtnjnGZ6XKSInBKkiOA5BKS+aZiY3AvA==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "html-escaper": "^2.0.0",
+ "istanbul-lib-report": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
"node_modules/jest-worker": {
"version": "27.5.1",
"resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz",
@@ -1844,6 +2586,29 @@
"url": "https://github.com/chalk/supports-color?sponsor=1"
}
},
+ "node_modules/js-yaml": {
+ "version": "5.4.2",
+ "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-5.4.2.tgz",
+ "integrity": "sha512-m+aqu+LwO1O6sIopafj8HUVl5aawITwZQe/yHpMCKjaWBaA/d07B/QdMb3529REftiU+RMMHL3Vlsw3hON7vWg==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/puzrin"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/nodeca"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "argparse": "^2.0.1"
+ },
+ "bin": {
+ "js-yaml": "bin/js-yaml.mjs"
+ }
+ },
"node_modules/json-buffer": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz",
@@ -1877,6 +2642,19 @@
"graceful-fs": "^4.1.6"
}
},
+ "node_modules/jszip": {
+ "version": "3.10.2",
+ "resolved": "https://registry.npmjs.org/jszip/-/jszip-3.10.2.tgz",
+ "integrity": "sha512-3l+rb15IOWtUhU0H5MFqES/T6Kh7abYwjosBey/vD6hDt8zoEffkSC5Ws5SGtgVw3gBx2NEbhTeSW1+kWkpyTQ==",
+ "dev": true,
+ "license": "(MIT OR GPL-3.0-or-later)",
+ "dependencies": {
+ "lie": "~3.3.0",
+ "pako": "~1.0.2",
+ "readable-stream": "~2.3.6",
+ "setimmediate": "^1.0.5"
+ }
+ },
"node_modules/keyv": {
"version": "4.5.4",
"resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz",
@@ -1911,6 +2689,98 @@
"node": ">= 0.8.0"
}
},
+ "node_modules/lie": {
+ "version": "3.3.0",
+ "resolved": "https://registry.npmjs.org/lie/-/lie-3.3.0.tgz",
+ "integrity": "sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "immediate": "~3.0.5"
+ }
+ },
+ "node_modules/lilconfig": {
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.3.tgz",
+ "integrity": "sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=14"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/antonk52"
+ }
+ },
+ "node_modules/lint-staged": {
+ "version": "15.5.2",
+ "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-15.5.2.tgz",
+ "integrity": "sha512-YUSOLq9VeRNAo/CTaVmhGDKG+LBtA8KF1X4K5+ykMSwWST1vDxJRB2kv2COgLb1fvpCo+A/y9A0G0znNVmdx4w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "chalk": "^5.4.1",
+ "commander": "^13.1.0",
+ "debug": "^4.4.0",
+ "execa": "^8.0.1",
+ "lilconfig": "^3.1.3",
+ "listr2": "^8.2.5",
+ "micromatch": "^4.0.8",
+ "pidtree": "^0.6.0",
+ "string-argv": "^0.3.2",
+ "yaml": "^2.7.0"
+ },
+ "bin": {
+ "lint-staged": "bin/lint-staged.js"
+ },
+ "engines": {
+ "node": ">=18.12.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/lint-staged"
+ }
+ },
+ "node_modules/lint-staged/node_modules/chalk": {
+ "version": "5.6.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.6.2.tgz",
+ "integrity": "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^12.17.0 || ^14.13 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/chalk?sponsor=1"
+ }
+ },
+ "node_modules/lint-staged/node_modules/commander": {
+ "version": "13.1.0",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-13.1.0.tgz",
+ "integrity": "sha512-/rFeCpNJQbhSZjGVwO9RFV3xPqbnERS8MmIQzCtD/zl6gpJuV/bMLuN92oG3F7d8oDEHHRrujSXNUr8fpjntKw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/listr2": {
+ "version": "8.3.3",
+ "resolved": "https://registry.npmjs.org/listr2/-/listr2-8.3.3.tgz",
+ "integrity": "sha512-LWzX2KsqcB1wqQ4AHgYb4RsDXauQiqhjLk+6hjbaeHG4zpjjVAB6wC/gz6X0l+Du1cN3pUB5ZlrvTbhGSNnUQQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "cli-truncate": "^4.0.0",
+ "colorette": "^2.0.20",
+ "eventemitter3": "^5.0.1",
+ "log-update": "^6.1.0",
+ "rfdc": "^1.4.1",
+ "wrap-ansi": "^9.0.0"
+ },
+ "engines": {
+ "node": ">=18.0.0"
+ }
+ },
"node_modules/loader-runner": {
"version": "4.3.2",
"resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.2.tgz",
@@ -1941,6 +2811,98 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
+ "node_modules/log-update": {
+ "version": "6.1.0",
+ "resolved": "https://registry.npmjs.org/log-update/-/log-update-6.1.0.tgz",
+ "integrity": "sha512-9ie8ItPR6tjY5uYJh8K/Zrv/RMZ5VOlOWvtZdEHYSTFKZfIBPQa9tOAEeAWhd+AnIneLJ22w5fjOYtoutpWq5w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-escapes": "^7.0.0",
+ "cli-cursor": "^5.0.0",
+ "slice-ansi": "^7.1.0",
+ "strip-ansi": "^7.1.0",
+ "wrap-ansi": "^9.0.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/log-update/node_modules/ansi-styles": {
+ "version": "6.2.3",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz",
+ "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/log-update/node_modules/is-fullwidth-code-point": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-5.1.0.tgz",
+ "integrity": "sha512-5XHYaSyiqADb4RnZ1Bdad6cPp8Toise4TzEjcOYDHZkTCbKgiUl7WTUCpNWHuxmDt91wnsZBc9xinNzopv3JMQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "get-east-asian-width": "^1.3.1"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/log-update/node_modules/slice-ansi": {
+ "version": "7.1.2",
+ "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-7.1.2.tgz",
+ "integrity": "sha512-iOBWFgUX7caIZiuutICxVgX1SdxwAVFFKwt1EvMYYec/NWO5meOJ6K5uQxhrYBdQJne4KxiqZc+KptFOWFSI9w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-styles": "^6.2.1",
+ "is-fullwidth-code-point": "^5.0.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/slice-ansi?sponsor=1"
+ }
+ },
+ "node_modules/lru-cache": {
+ "version": "11.5.3",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.5.3.tgz",
+ "integrity": "sha512-U4N8FgzmWxc8k1VH8Kr6lQg18U7Fjvby6wXHVRX/ZZ7IwWbRMgrRbP0Wrb5q5NVinryp4SQampHKdvtecItxUg==",
+ "dev": true,
+ "license": "BlueOak-1.0.0",
+ "engines": {
+ "node": "20 || >=22"
+ }
+ },
+ "node_modules/make-dir": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz",
+ "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "semver": "^7.5.3"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
"node_modules/merge-stream": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz",
@@ -1980,6 +2942,32 @@
"node": ">= 0.6"
}
},
+ "node_modules/mimic-fn": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz",
+ "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/mimic-function": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/mimic-function/-/mimic-function-5.0.1.tgz",
+ "integrity": "sha512-VP79XUPxV2CigYP3jWwAUFSku2aKqBH7uTAapFWCBqutsbmDo96KY5o8uh6U+/YSIn5OxJnXp73beVkpqMIGhA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
"node_modules/minimatch": {
"version": "10.2.5",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.5.tgz",
@@ -1996,6 +2984,63 @@
"url": "https://github.com/sponsors/isaacs"
}
},
+ "node_modules/minipass": {
+ "version": "7.1.3",
+ "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.3.tgz",
+ "integrity": "sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==",
+ "dev": true,
+ "license": "BlueOak-1.0.0",
+ "engines": {
+ "node": ">=16 || 14 >=14.17"
+ }
+ },
+ "node_modules/mocha": {
+ "version": "12.0.2",
+ "resolved": "https://registry.npmjs.org/mocha/-/mocha-12.0.2.tgz",
+ "integrity": "sha512-SjAulGHxlMJLCD1bhvJBAiYwYxglydRzA9PDQ5MALq1oLRMMtIhxSQJ0olCFgA7c9YbTdxC0KOV0wl8JEDYVhA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "browser-stdout": "^1.3.1",
+ "chokidar": "^5.0.0",
+ "debug": "^4.3.5",
+ "diff": "^9.0.0",
+ "find-up-simple": "^1.0.1",
+ "glob": "^13.0.0",
+ "is-path-inside": "^4.0.0",
+ "is-unicode-supported": "^0.1.0",
+ "js-yaml": "^5.0.0",
+ "minimatch": "^10.2.2",
+ "ms": "^2.1.3",
+ "picocolors": "^1.1.1",
+ "serialize-javascript": "^7.1.1",
+ "strip-json-comments": "^5.0.3",
+ "supports-color": "^8.1.1",
+ "workerpool": "^10.0.0"
+ },
+ "bin": {
+ "mocha": "bin/mocha.js"
+ },
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/mocha/node_modules/supports-color": {
+ "version": "8.1.1",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz",
+ "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "has-flag": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/supports-color?sponsor=1"
+ }
+ },
"node_modules/ms": {
"version": "2.1.3",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
@@ -2018,11 +3063,59 @@
"license": "MIT"
},
"node_modules/node-releases": {
- "version": "2.0.38",
- "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.38.tgz",
- "integrity": "sha512-3qT/88Y3FbH/Kx4szpQQ4HzUbVrHPKTLVpVocKiLfoYvw9XSGOX2FmD2d6DrXbVYyAQTF2HeF6My8jmzx7/CRw==",
+ "version": "2.0.57",
+ "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.57.tgz",
+ "integrity": "sha512-kQK9LGGFiHtrWiNhZtA7Qbw17AQz+dmsEKODRIVTXA9+e5MS/2gZEBhYJt13GrAz5/IOZKddH/0Z3TP/Zgo+yw==",
"dev": true,
- "license": "MIT"
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/npm-run-path": {
+ "version": "5.3.0",
+ "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.3.0.tgz",
+ "integrity": "sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "path-key": "^4.0.0"
+ },
+ "engines": {
+ "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/npm-run-path/node_modules/path-key": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz",
+ "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/onetime": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz",
+ "integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "mimic-fn": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
},
"node_modules/optionator": {
"version": "0.9.4",
@@ -2042,6 +3135,86 @@
"node": ">= 0.8.0"
}
},
+ "node_modules/ora": {
+ "version": "8.2.0",
+ "resolved": "https://registry.npmjs.org/ora/-/ora-8.2.0.tgz",
+ "integrity": "sha512-weP+BZ8MVNnlCm8c0Qdc1WSWq4Qn7I+9CJGm7Qali6g44e/PUzbjNqJX5NJ9ljlNMosfJvg1fKEGILklK9cwnw==",
+ "dev": true,
+ "license": "MIT",
+ "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"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/ora/node_modules/chalk": {
+ "version": "5.6.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.6.2.tgz",
+ "integrity": "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^12.17.0 || ^14.13 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/chalk?sponsor=1"
+ }
+ },
+ "node_modules/ora/node_modules/is-unicode-supported": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-2.1.0.tgz",
+ "integrity": "sha512-mE00Gnza5EEB3Ds0HfMyllZzbBrmLOX3vfWoj9A9PEnTfratQ/BcaJOuMhnkhjXvb2+FkY3VuHqtAGpTPmglFQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/ora/node_modules/log-symbols": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-6.0.0.tgz",
+ "integrity": "sha512-i24m8rpwhmPIS4zscNzK6MSEhk0DUWa/8iYQWxhffV8jkI4Phvs3F+quL5xvS0gdQR0FyTCMMH33Y78dDTzzIw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "chalk": "^5.3.0",
+ "is-unicode-supported": "^1.3.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/ora/node_modules/log-symbols/node_modules/is-unicode-supported": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-1.3.0.tgz",
+ "integrity": "sha512-43r2mRvz+8JRIKnWJ+3j8JtjRKZ6GmjzfaE/qiBJnikNnYv/6bagRJ1kUhNk8R5EX/GkobD+r+sfxCPJsiKBLQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
"node_modules/p-limit": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz",
@@ -2084,6 +3257,13 @@
"node": ">=6"
}
},
+ "node_modules/pako": {
+ "version": "1.0.11",
+ "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz",
+ "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==",
+ "dev": true,
+ "license": "(MIT AND Zlib)"
+ },
"node_modules/path-exists": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
@@ -2111,6 +3291,23 @@
"dev": true,
"license": "MIT"
},
+ "node_modules/path-scurry": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.2.tgz",
+ "integrity": "sha512-3O/iVVsJAPsOnpwWIeD+d6z/7PmqApyQePUtCndjatj/9I5LylHvt5qluFaBT3I5h3r1ejfR056c+FCv+NnNXg==",
+ "dev": true,
+ "license": "BlueOak-1.0.0",
+ "dependencies": {
+ "lru-cache": "^11.0.0",
+ "minipass": "^7.1.2"
+ },
+ "engines": {
+ "node": "18 || 20 || >=22"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
"node_modules/picocolors": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
@@ -2130,6 +3327,19 @@
"url": "https://github.com/sponsors/jonschlinkert"
}
},
+ "node_modules/pidtree": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/pidtree/-/pidtree-0.6.1.tgz",
+ "integrity": "sha512-e0F9AOF1JMrCfBsyJOwU9lNvQ0WtXTq0j/4jk0BQ5JSI9VAybPXmDpPRw/2FQ3e5d3ZFN1mLh7jW99m/jjaptw==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "pidtree": "bin/pidtree.js"
+ },
+ "engines": {
+ "node": ">=0.10"
+ }
+ },
"node_modules/pkg-dir": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz",
@@ -2225,6 +3435,13 @@
"url": "https://github.com/prettier/prettier?sponsor=1"
}
},
+ "node_modules/process-nextick-args": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
+ "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/punycode": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz",
@@ -2255,6 +3472,36 @@
],
"license": "MIT"
},
+ "node_modules/readable-stream": {
+ "version": "2.3.8",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz",
+ "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "core-util-is": "~1.0.0",
+ "inherits": "~2.0.3",
+ "isarray": "~1.0.0",
+ "process-nextick-args": "~2.0.0",
+ "safe-buffer": "~5.1.1",
+ "string_decoder": "~1.1.1",
+ "util-deprecate": "~1.0.1"
+ }
+ },
+ "node_modules/readdirp": {
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-5.1.1.tgz",
+ "integrity": "sha512-Kko+Y5XQ6fM+Ce3dq3m9YGxnacYZYl9cA1wZjaF3Vbry2L3i1qVg8+CAgNPsXRArPMUMCaOR7oa9Nqntc43JKA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 20.19.0"
+ },
+ "funding": {
+ "type": "individual",
+ "url": "https://paulmillr.com/funding/"
+ }
+ },
"node_modules/rechoir": {
"version": "0.8.0",
"resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.8.0.tgz",
@@ -2268,6 +3515,16 @@
"node": ">= 10.13.0"
}
},
+ "node_modules/require-directory": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
+ "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
"node_modules/require-from-string": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz",
@@ -2323,6 +3580,39 @@
"node": ">=8"
}
},
+ "node_modules/restore-cursor": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-5.1.0.tgz",
+ "integrity": "sha512-oMA2dcrw6u0YfxJQXm342bFKX/E4sG9rbTzO9ptUcR/e8A33cHuvStiYOwH7fszkZlZ1z/ta9AAoPk2F4qIOHA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "onetime": "^7.0.0",
+ "signal-exit": "^4.1.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/restore-cursor/node_modules/onetime": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/onetime/-/onetime-7.0.0.tgz",
+ "integrity": "sha512-VXJjc87FScF88uafS3JllDgvAm+c/Slfz06lorj2uAY34rlUu0Nt+v8wreiImcrgAjjIHp1rXpTDlLOGw29WwQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "mimic-function": "^5.0.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
"node_modules/reusify": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz",
@@ -2333,6 +3623,13 @@
"node": ">=0.10.0"
}
},
+ "node_modules/rfdc": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.4.1.tgz",
+ "integrity": "sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/run-parallel": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz",
@@ -2356,6 +3653,13 @@
"queue-microtask": "^1.2.2"
}
},
+ "node_modules/safe-buffer": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
+ "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/schema-utils": {
"version": "4.3.3",
"resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.3.3.tgz",
@@ -2425,6 +3729,23 @@
"node": ">=10"
}
},
+ "node_modules/serialize-javascript": {
+ "version": "7.1.2",
+ "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-7.1.2.tgz",
+ "integrity": "sha512-GL2BWwVa6JydKO6l/ljVgjAZF4QJ3S7dWDWi53s5GZT8PJzD2fNxi67HANQGKAqPrwEpL5ba7gUBGi0Ls/sEoQ==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "engines": {
+ "node": ">=20.0.0"
+ }
+ },
+ "node_modules/setimmediate": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz",
+ "integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/shallow-clone": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz",
@@ -2461,6 +3782,49 @@
"node": ">=8"
}
},
+ "node_modules/signal-exit": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz",
+ "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==",
+ "dev": true,
+ "license": "ISC",
+ "engines": {
+ "node": ">=14"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/slice-ansi": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-5.0.0.tgz",
+ "integrity": "sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-styles": "^6.0.0",
+ "is-fullwidth-code-point": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/slice-ansi?sponsor=1"
+ }
+ },
+ "node_modules/slice-ansi/node_modules/ansi-styles": {
+ "version": "6.2.3",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz",
+ "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
"node_modules/source-map": {
"version": "0.7.6",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.6.tgz",
@@ -2492,6 +3856,99 @@
"node": ">=0.10.0"
}
},
+ "node_modules/stdin-discarder": {
+ "version": "0.2.2",
+ "resolved": "https://registry.npmjs.org/stdin-discarder/-/stdin-discarder-0.2.2.tgz",
+ "integrity": "sha512-UhDfHmA92YAlNnCfhmq0VeNL5bDbiZGg7sZ2IvPsXubGkiNa9EC+tUTsjBRsYUAz87btI6/1wf4XoVvQ3uRnmQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/string_decoder": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
+ "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "safe-buffer": "~5.1.0"
+ }
+ },
+ "node_modules/string-argv": {
+ "version": "0.3.2",
+ "resolved": "https://registry.npmjs.org/string-argv/-/string-argv-0.3.2.tgz",
+ "integrity": "sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.6.19"
+ }
+ },
+ "node_modules/string-width": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz",
+ "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "emoji-regex": "^10.3.0",
+ "get-east-asian-width": "^1.0.0",
+ "strip-ansi": "^7.1.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/strip-ansi": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.2.0.tgz",
+ "integrity": "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-regex": "^6.2.2"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/strip-ansi?sponsor=1"
+ }
+ },
+ "node_modules/strip-final-newline": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz",
+ "integrity": "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/strip-json-comments": {
+ "version": "5.0.3",
+ "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-5.0.3.tgz",
+ "integrity": "sha512-1tB5mhVo7U+ETBKNf92xT4hrQa3pm0MZ0PQvuDnWgAAGHDsfp4lPSpiS6psrSiet87wyGPh9ft6wmhOMQ0hDiw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=14.16"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
"node_modules/supports-color": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
@@ -2585,6 +4042,21 @@
}
}
},
+ "node_modules/test-exclude": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-8.0.0.tgz",
+ "integrity": "sha512-ZOffsNrXYggvU1mDGHk54I96r26P8SyMjO5slMKSc7+IWmtB/MQKnEC2fP51imB3/pT6YK5cT5E8f+Dd9KdyOQ==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "@istanbuljs/schema": "^0.1.2",
+ "glob": "^13.0.6",
+ "minimatch": "^10.2.2"
+ },
+ "engines": {
+ "node": "20 || >=22"
+ }
+ },
"node_modules/tinyglobby": {
"version": "0.2.16",
"resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.16.tgz",
@@ -2723,9 +4195,9 @@
}
},
"node_modules/update-browserslist-db": {
- "version": "1.2.3",
- "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz",
- "integrity": "sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==",
+ "version": "1.3.3",
+ "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.3.3.tgz",
+ "integrity": "sha512-pJ2sYawQS0R/WI928Gj5GlPhTGzbMelq0+4INtSYNDV9ErKJcX6xjGWkoG/VnB3dpUm00zALaqkrUD77pO5TDQ==",
"dev": true,
"funding": [
{
@@ -2763,6 +4235,28 @@
"punycode": "^2.1.0"
}
},
+ "node_modules/util-deprecate": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
+ "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/v8-to-istanbul": {
+ "version": "9.3.0",
+ "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.3.0.tgz",
+ "integrity": "sha512-kiGUalWN+rgBJ/1OHZsBtU4rXZOfj/7rKQxULKlIzwzQSvMJUUNgPwJEEh7gU6xEVxC0ahoOBvN2YI8GH6FNgA==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "@jridgewell/trace-mapping": "^0.3.12",
+ "@types/istanbul-lib-coverage": "^2.0.1",
+ "convert-source-map": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=10.12.0"
+ }
+ },
"node_modules/watchpack": {
"version": "2.5.1",
"resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.5.1.tgz",
@@ -2957,6 +4451,154 @@
"node": ">=0.10.0"
}
},
+ "node_modules/workerpool": {
+ "version": "10.0.3",
+ "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-10.0.3.tgz",
+ "integrity": "sha512-6z2Iis68Wqth93/G/wJP9u+R3O+d2XTlgWChGCwuT1qLbBsOYueGRZuJ++v3mtDP5KjYdy+WzvWC+VWETSVXJA==",
+ "dev": true,
+ "license": "Apache-2.0"
+ },
+ "node_modules/wrap-ansi": {
+ "version": "9.0.2",
+ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.2.tgz",
+ "integrity": "sha512-42AtmgqjV+X1VpdOfyTGOYRi0/zsoLqtXQckTmqTeybT+BDIbM/Guxo7x3pE2vtpr1ok6xRqM9OpBe+Jyoqyww==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-styles": "^6.2.1",
+ "string-width": "^7.0.0",
+ "strip-ansi": "^7.1.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
+ }
+ },
+ "node_modules/wrap-ansi/node_modules/ansi-styles": {
+ "version": "6.2.3",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz",
+ "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/y18n": {
+ "version": "5.0.8",
+ "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",
+ "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==",
+ "dev": true,
+ "license": "ISC",
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/yaml": {
+ "version": "2.9.1",
+ "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.9.1.tgz",
+ "integrity": "sha512-3NxN8+78OdzbT7C/WjGsyfPAtJaN3FNDsWxv7Y7mcDsT/oOmgW8BpyQQFFBnvZE3j9Y2Sdz1ULFLezL7Eb2yFw==",
+ "dev": true,
+ "license": "ISC",
+ "bin": {
+ "yaml": "bin.mjs"
+ },
+ "engines": {
+ "node": ">= 14.6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/eemeli"
+ }
+ },
+ "node_modules/yargs": {
+ "version": "17.7.3",
+ "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.3.tgz",
+ "integrity": "sha512-GZtjxm/J/4TSxuL3FNYjCmLktBTnIw/rVmKSIyKeYAZpmJB2ig9VauCC5xsa82GNKVKDAqpOn3KVzNt0zmrU0g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "cliui": "^8.0.1",
+ "escalade": "^3.1.1",
+ "get-caller-file": "^2.0.5",
+ "require-directory": "^2.1.1",
+ "string-width": "^4.2.3",
+ "y18n": "^5.0.5",
+ "yargs-parser": "^21.1.1"
+ },
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/yargs-parser": {
+ "version": "21.1.1",
+ "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz",
+ "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==",
+ "dev": true,
+ "license": "ISC",
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/yargs/node_modules/ansi-regex": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
+ "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/yargs/node_modules/emoji-regex": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
+ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/yargs/node_modules/is-fullwidth-code-point": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
+ "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/yargs/node_modules/string-width": {
+ "version": "4.2.3",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
+ "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "emoji-regex": "^8.0.0",
+ "is-fullwidth-code-point": "^3.0.0",
+ "strip-ansi": "^6.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/yargs/node_modules/strip-ansi": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
+ "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-regex": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
"node_modules/yocto-queue": {
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",
diff --git a/package.json b/package.json
index 0c59232..2c5da3e 100644
--- a/package.json
+++ b/package.json
@@ -4,14 +4,14 @@
"description": "Pixi support for the Python Environments extension",
"icon": "assets/icon.png",
"license": "MIT",
- "version": "0.2.0",
- "homepage": "https://github.com/renan-r-santos/pixi-code",
+ "version": "0.2.1",
+ "homepage": "https://github.com/kaiserls/pixi-code",
"repository": {
"type": "git",
- "url": "https://github.com/renan-r-santos/pixi-code"
+ "url": "https://github.com/kaiserls/pixi-code"
},
"bugs": {
- "url": "https://github.com/renan-r-santos/pixi-code/issues"
+ "url": "https://github.com/kaiserls/pixi-code/issues"
},
"keywords": [
"pixi",
@@ -31,7 +31,7 @@
"workspaceContains:**/pixi.toml",
"workspaceContains:**/pyproject.toml"
],
- "publisher": "renan-r-santos",
+ "publisher": "kaiserls",
"extensionDependencies": [
"ms-python.vscode-python-envs"
],
@@ -51,7 +51,7 @@
"pixi-code.pixiExecutable": {
"type": "string",
"default": "",
- "description": "Path to the Pixi executable. Leave empty to use auto-discovery.",
+ "description": "Path to the Pixi executable. Supports ${workspaceFolder} and paths relative to a workspace folder. Leave empty to use auto-discovery.",
"scope": "machine-overridable"
}
}
@@ -71,29 +71,48 @@
"compile": "webpack",
"watch": "webpack --watch",
"package": "webpack --mode production --devtool hidden-source-map",
- "compile-tests": "tsc -p . --outDir out",
+ "typecheck": "tsc -p . --noEmit",
+ "compile-tests": "node -e \"require('fs').rmSync('out', { recursive: true, force: true })\" && tsc -p . --outDir out",
+ "test:unit": "npm run compile-tests && node --test out/test/**/*.unit.test.js",
+ "test:vscode": "npm run compile-tests && npm run compile && pixi install --locked --manifest-path test/fixtures/pixi-project/pixi.toml && vscode-test",
+ "test": "npm run typecheck && npm run test:unit && npm run test:vscode",
"watch-tests": "tsc -p . -w --outDir out",
- "pretest": "npm run compile-tests && npm run compile && npm run lint",
+ "pretest": "npm run lint && npm run format:check",
+ "prepare": "husky",
"lint": "eslint src",
"format": "prettier --write .",
"format:check": "prettier --check ."
},
+ "lint-staged": {
+ "src/**/*.ts": "eslint --fix",
+ "*": "prettier --write --ignore-unknown"
+ },
"devDependencies": {
"@types/fs-extra": "^11.0.4",
+ "@types/mocha": "^10.0.10",
"@types/node": "24.x",
"@types/vscode": "^1.118.0",
"@types/which": "^3.0.4",
"@typescript-eslint/eslint-plugin": "^8.59.1",
"@typescript-eslint/parser": "^8.59.1",
+ "@vscode/test-cli": "^0.0.15",
+ "@vscode/test-electron": "^2.5.2",
"eslint": "^10.2.1",
"eslint-plugin-simple-import-sort": "^13.0.0",
"eslint-plugin-unused-imports": "^4.4.1",
+ "husky": "^9.1.7",
+ "lint-staged": "^15.5.2",
"prettier": "^3.8.3",
"ts-loader": "^9.5.7",
"typescript": "^6.0.3",
"webpack": "^5.106.2",
"webpack-cli": "^7.0.2"
},
+ "overrides": {
+ "@vscode/test-cli": {
+ "mocha": "^12.0.2"
+ }
+ },
"dependencies": {
"@types/semver": "^7.7.1",
"@vscode/python-environments": "^1.0.0",
diff --git a/src/common/utils.ts b/src/common/utils.ts
index 0397f59..55e1b4a 100644
--- a/src/common/utils.ts
+++ b/src/common/utils.ts
@@ -1,6 +1,6 @@
import * as os from 'os';
-export const EXTENSION_ID = 'renan-r-santos.pixi-code';
+export const EXTENSION_ID = 'kaiserls.pixi-code';
export const PIXI_MANAGER_ID = `${EXTENSION_ID}:pixi`;
export function untildify(path: string): string {
diff --git a/src/extension.ts b/src/extension.ts
index 4144613..154bef4 100644
--- a/src/extension.ts
+++ b/src/extension.ts
@@ -3,6 +3,7 @@ import { ExtensionContext, window } from 'vscode';
import { registerLogger } from './common/logging';
import { setPersistentState } from './common/persistentState';
+import { EXTENSION_ID } from './common/utils';
import { PixiEnvManager } from './pixi/envManager';
import { PixiPackageManager } from './pixi/projectManager';
import { getPixi, runPixi } from './pixi/utils';
@@ -11,38 +12,48 @@ import { getEnvExtApi } from './pythonEnvsApi';
const MINIMUM_PIXI_VERSION = '0.53.0';
export async function activate(context: ExtensionContext) {
- const api = await getEnvExtApi();
-
const log = window.createOutputChannel('Pixi Environment Manager', { log: true });
context.subscriptions.push(log, registerLogger(log));
- // Validate Pixi installation
- const stdout = await runPixi(['--version']);
- const versionMatch = stdout.trim().match(/^pixi (\d+\.\d+\.\d+)/);
- if (!versionMatch) {
- const errorMsg = `Found invalid Pixi binary at ${await getPixi()}.`;
- window.showErrorMessage(errorMsg);
- throw new Error(errorMsg);
- }
-
- const currentVersion = versionMatch[1];
-
- // Check if the current version meets the minimum requirement using semver
- if (!semver.gte(currentVersion, MINIMUM_PIXI_VERSION)) {
- const errorMsg =
- `Pixi version ${currentVersion} is too old. ` +
- `This extension requires Pixi version ${MINIMUM_PIXI_VERSION} or newer. ` +
- `Please update Pixi by running: pixi self-update`;
- window.showErrorMessage(errorMsg);
- throw new Error(errorMsg);
+ try {
+ log.info('Activating Pixi Code');
+ const api = await getEnvExtApi();
+
+ // Validate Pixi installation
+ const stdout = await runPixi(['--version']);
+ const versionMatch = stdout.trim().match(/^pixi (\d+\.\d+\.\d+)/);
+ if (!versionMatch) {
+ const errorMsg = `Found invalid Pixi binary at ${await getPixi()}.`;
+ window.showErrorMessage(errorMsg);
+ throw new Error(errorMsg);
+ }
+
+ const currentVersion = versionMatch[1];
+
+ // Check if the current version meets the minimum requirement using semver
+ if (!semver.gte(currentVersion, MINIMUM_PIXI_VERSION)) {
+ const errorMsg =
+ `Pixi version ${currentVersion} is too old. ` +
+ `This extension requires Pixi version ${MINIMUM_PIXI_VERSION} or newer. ` +
+ `Please update Pixi by running: pixi self-update`;
+ window.showErrorMessage(errorMsg);
+ throw new Error(errorMsg);
+ }
+
+ log.info(`Using Pixi ${currentVersion}`);
+
+ // Setup the persistent state for the extension.
+ setPersistentState(context);
+
+ const manager = new PixiEnvManager(api, log);
+ context.subscriptions.push(api.registerEnvironmentManager(manager, { extensionId: EXTENSION_ID }));
+ log.info('Registered Pixi environment manager');
+
+ const packageManager = new PixiPackageManager(api, log);
+ context.subscriptions.push(api.registerPackageManager(packageManager, { extensionId: EXTENSION_ID }));
+ log.info('Registered Pixi package manager');
+ } catch (error) {
+ log.error('Pixi Code activation failed', error);
+ throw error;
}
-
- // Setup the persistent state for the extension.
- setPersistentState(context);
-
- const manager = new PixiEnvManager(api, log);
- context.subscriptions.push(api.registerEnvironmentManager(manager));
-
- const packageManager = new PixiPackageManager(api, log);
- context.subscriptions.push(api.registerPackageManager(packageManager));
}
diff --git a/src/pixi/envManager.ts b/src/pixi/envManager.ts
index 1cff735..04a6c9d 100644
--- a/src/pixi/envManager.ts
+++ b/src/pixi/envManager.ts
@@ -15,7 +15,7 @@ import {
import { EventEmitter, LogOutputChannel, MarkdownString, ProgressLocation, ThemeIcon, Uri, window } from 'vscode';
import { createDeferred, Deferred } from '../common/deferred';
-import { traceVerbose } from '../common/logging';
+import { traceInfo, traceVerbose } from '../common/logging';
import { resolvePixiProjectPaths } from '../common/searchPaths';
import { PIXI_MANAGER_ID } from '../common/utils';
import { PixiEnvironment } from './types';
@@ -122,12 +122,14 @@ export class PixiEnvManager implements EnvironmentManager {
}
async set(scope: SetEnvironmentScope, environment?: PythonEnvironment) {
- traceVerbose(`Called set with scope: ${scope}, environment: ${JSON.stringify(environment)}`);
+ const environmentName = environment?.displayName ?? environment?.envId.id ?? 'none';
+ traceVerbose(`Setting ${scope === undefined ? 'global' : 'project'} Pixi environment to '${environmentName}'`);
if (scope === undefined) {
await setGlobalEnvId(environment?.envId.id);
this.triggerDidChangeEnvironment(undefined, this.globalEnv, environment);
this.globalEnv = environment;
+ traceInfo(`Activated global environment '${environmentName}'`);
return;
}
@@ -150,6 +152,10 @@ export class PixiEnvManager implements EnvironmentManager {
await setProjectEnvId(projectPath, environment?.envId.id);
this.triggerDidChangeEnvironment(project.uri, oldEnv, environment);
+ const projectName = project.name ?? projectPath;
+ traceInfo(
+ `${environment ? 'Activated' : 'Cleared'} environment '${environmentName}' for project '${projectName}'`,
+ );
}
}
@@ -187,6 +193,7 @@ export class PixiEnvManager implements EnvironmentManager {
}
private async refreshAll(): Promise {
+ traceInfo('Discovering Pixi environments across registered projects and search paths');
await window.withProgress(
{
location: ProgressLocation.Window,
@@ -202,6 +209,7 @@ export class PixiEnvManager implements EnvironmentManager {
const searchPathRoots = await resolvePixiProjectPaths();
const projectPaths = new Set([...projectMap.keys(), ...searchPathRoots]);
+ traceVerbose(`Refreshing Pixi environments for ${projectPaths.size} project path(s)`);
const changes: DidChangeEnvironmentsEventArgs = [];
@@ -216,6 +224,13 @@ export class PixiEnvManager implements EnvironmentManager {
);
this._onDidChangeEnvironments.fire(changes);
+ const environmentCount = [...this.projectToEnvs.values()].reduce(
+ (count, envs) => count + envs.length,
+ 0,
+ );
+ traceInfo(
+ `Discovered ${environmentCount} Pixi environment(s); ${changes.length} environment change(s)`,
+ );
const envLookup = this.buildEnvLookup();
@@ -254,8 +269,10 @@ export class PixiEnvManager implements EnvironmentManager {
}
const projectPath = project.uri.fsPath;
+ traceInfo(`Refreshing Pixi environments for project '${project.name ?? projectPath}'`);
const oldEnvs = this.projectToEnvs.get(projectPath) || [];
const newEnvs = await refreshPixi(projectPath);
+ traceInfo(`Found ${newEnvs.length} Pixi environment(s) for project '${project.name ?? projectPath}'`);
this.projectToEnvs.set(projectPath, newEnvs);
this._onDidChangeEnvironments.fire(this.diffEnvironments(oldEnvs, newEnvs));
diff --git a/src/pixi/projectManager.ts b/src/pixi/projectManager.ts
index b76b4a1..1129c52 100644
--- a/src/pixi/projectManager.ts
+++ b/src/pixi/projectManager.ts
@@ -20,7 +20,7 @@ import {
window,
} from 'vscode';
-import { traceVerbose } from '../common/logging';
+import { traceError, traceInfo, traceVerbose } from '../common/logging';
import { PixiEnvironment } from './types';
import { listPixiPackages, pixiPkgsToPackages } from './utils';
@@ -72,13 +72,32 @@ export class PixiPackageManager implements PackageManager, Disposable {
}
const projectPath = path.dirname(environment.pixiInfo.project_info.manifest_path);
- const pixiPackages = await listPixiPackages(environment.name, projectPath);
-
- const before = environment.packages;
- const after = pixiPkgsToPackages(pixiPackages, environment.envId.id);
+ const pixiEnvironment = environment.pixiInfo.environments_info.find(
+ (info) => info.prefix === environment.envId.id,
+ );
+ if (!pixiEnvironment) {
+ traceInfo(
+ `Failed to refresh packages: Pixi environment '${environment.name}' is missing from project info`,
+ );
+ return;
+ }
- environment.packages = after;
- this.triggerOnDidChangePackages(environment, before, after);
+ try {
+ const pixiPackages = await listPixiPackages(pixiEnvironment.name, projectPath);
+
+ const before = environment.packages;
+ const after = pixiPkgsToPackages(pixiPackages, environment.envId.id);
+
+ environment.packages = after;
+ this.triggerOnDidChangePackages(environment, before, after);
+ traceInfo(
+ `Refreshed packages for '${environment.name}' in '${projectPath}': ${after.length} package(s)`,
+ );
+ } catch (error) {
+ traceError(
+ `Failed to refresh packages for environment '${environment.name}' in '${projectPath}': ${error}`,
+ );
+ }
},
);
}
diff --git a/src/pixi/utils.ts b/src/pixi/utils.ts
index f49d12e..8728c5c 100644
--- a/src/pixi/utils.ts
+++ b/src/pixi/utils.ts
@@ -1,12 +1,14 @@
import { Package } from '@vscode/python-environments';
import * as ch from 'child_process';
+import * as fs from 'fs';
+import * as path from 'path';
import { CancellationError, CancellationToken, ThemeIcon, Uri, window, workspace } from 'vscode';
import which from 'which';
import { createDeferred } from '../common/deferred';
-import { quoteArgs } from '../common/execUtils';
+import { quoteArgs, quoteStringIfNecessary } from '../common/execUtils';
import { findPythonExecutable } from '../common/findPython';
-import { traceError, traceInfo, traceVerbose } from '../common/logging';
+import { traceError, traceVerbose } from '../common/logging';
import { getWorkspacePersistentState } from '../common/persistentState';
import { PIXI_MANAGER_ID, untildify } from '../common/utils';
import { PixiEnvironment, PixiInfo, PixiPackage } from './types';
@@ -27,7 +29,21 @@ export async function getPixi(): Promise {
const value = config.get('pixiExecutable');
if (value) {
- return untildify(value);
+ let resolved = untildify(value);
+ if (workspace.workspaceFolders && workspace.workspaceFolders.length > 0) {
+ const firstFolder = workspace.workspaceFolders[0].uri.fsPath;
+ resolved = path.normalize(resolved.replace(/\$\{workspaceFolder\}/g, firstFolder));
+ if (!path.isAbsolute(resolved)) {
+ for (const folder of workspace.workspaceFolders) {
+ const candidate = path.resolve(folder.uri.fsPath, resolved);
+ if (fs.existsSync(candidate)) {
+ resolved = candidate;
+ break;
+ }
+ }
+ }
+ }
+ return resolved;
}
const pixiPath = await findPixi();
@@ -48,7 +64,9 @@ async function _runPixi(
): Promise {
const deferred = createDeferred();
args = quoteArgs(args);
- const proc = ch.spawn(pixi, args, { shell: true, ...options });
+ const command = `${quoteStringIfNecessary(pixi)} ${args.join(' ')}`;
+ traceVerbose(`Running '${command}'${options?.cwd ? ` in '${options.cwd}'` : ''}`);
+ const proc = ch.spawn(quoteStringIfNecessary(pixi), args, { shell: true, ...options });
const cancelDisposable = token?.onCancellationRequested(() => {
proc.kill();
@@ -65,7 +83,6 @@ async function _runPixi(
proc.stderr?.on('data', (data) => {
const d = data.toString('utf-8');
stderr += d;
- traceError(d.trim());
});
proc.on('error', (err) => {
deferred.reject(err);
@@ -76,7 +93,9 @@ async function _runPixi(
proc.on('close', () => {
cancelDisposable?.dispose();
if (exitCode !== 0) {
- deferred.reject(new Error(`Failed to run "pixi ${args.join(' ')}":\n ${stderr}`));
+ const message = `Pixi command '${command}' failed with exit code ${exitCode ?? 'unknown'}${stderr.trim() ? `:\n${stderr.trim()}` : ''}`;
+ traceError(message);
+ deferred.reject(new Error(message));
} else {
deferred.resolve(stdout);
}
@@ -87,7 +106,12 @@ async function _runPixi(
export async function runPixi(args: string[], options?: ch.SpawnOptions, token?: CancellationToken): Promise {
const pixi = await getPixi();
- return _runPixi(pixi, args, options, token);
+ const defaultCwd = workspace.workspaceFolders?.[0]?.uri.fsPath;
+ const spawnOptions: ch.SpawnOptions = {
+ ...(defaultCwd ? { cwd: defaultCwd } : {}),
+ ...options,
+ };
+ return _runPixi(pixi, args, spawnOptions, token);
}
export async function listPixiPackages(envName: string, projectPath: string): Promise {
@@ -113,7 +137,16 @@ export async function refreshPixi(projectPath: string): Promise {
- const pixiPackages = await listPixiPackages(pixiEnv.name, projectPath);
+ let pixiPackages: PixiPackage[];
+ try {
+ pixiPackages = await listPixiPackages(pixiEnv.name, projectPath);
+ } catch (error) {
+ traceError(
+ `Could not list packages for Pixi environment '${projectName}:${pixiEnv.name}' in '${projectPath}': ${error}`,
+ );
+ return null;
+ }
+
const pythonPackage = pixiPackages.find((pkg) => pkg.name === 'python');
if (!pythonPackage) {
@@ -162,7 +195,7 @@ export async function refreshPixi(projectPath: string): Promise env !== null);
} catch (error) {
- traceInfo(`Failed to get pixi environments: ${error}`);
+ traceError(`Failed to discover Pixi environments in '${projectPath}': ${error}`);
return [];
}
}
diff --git a/src/test/extension.vscode.test.ts b/src/test/extension.vscode.test.ts
new file mode 100644
index 0000000..5455959
--- /dev/null
+++ b/src/test/extension.vscode.test.ts
@@ -0,0 +1,68 @@
+import * as assert from 'node:assert/strict';
+import { readFile, rm, writeFile } from 'node:fs/promises';
+import * as path from 'node:path';
+
+import { PythonEnvironmentApi } from '@vscode/python-environments';
+import * as vscode from 'vscode';
+
+import { EXTENSION_ID, PIXI_MANAGER_ID } from '../common/utils';
+
+suite('Pixi Code extension', () => {
+ test('contributes an empty default Pixi executable setting', () => {
+ const setting = vscode.workspace.getConfiguration('pixi-code').inspect('pixiExecutable');
+
+ assert.equal(setting?.defaultValue, '');
+ });
+
+ test('selects the Pixi default environment through Python Environments', async function () {
+ this.timeout(120_000);
+
+ const pixiExtension = vscode.extensions.getExtension(EXTENSION_ID);
+ const pythonEnvsExtension =
+ vscode.extensions.getExtension('ms-python.vscode-python-envs');
+ assert.ok(pixiExtension, 'Pixi Code must be loaded in the extension test host');
+ assert.ok(pythonEnvsExtension, 'Python Environments must be installed in the extension test host');
+
+ const api = await pythonEnvsExtension.activate();
+ await pixiExtension.activate();
+
+ const environments = await api.getEnvironments('all');
+ const pixiEnvironment = environments.find(
+ (environment) =>
+ environment.envId.managerId === PIXI_MANAGER_ID && environment.name.startsWith('pixi-project:default'),
+ );
+ assert.ok(pixiEnvironment, 'The Pixi fixture default environment must be discoverable');
+
+ const workspaceFolder = vscode.workspace.workspaceFolders?.[0];
+ assert.ok(workspaceFolder, 'The Pixi fixture must be open as the test workspace');
+ const scope = workspaceFolder.uri;
+ const settingsPath = path.join(scope.fsPath, '.vscode', 'settings.json');
+ const originalSettings = await readFile(settingsPath).catch((error: NodeJS.ErrnoException) => {
+ if (error.code === 'ENOENT') {
+ return undefined;
+ }
+ throw error;
+ });
+ const previousEnvironment = await api.getEnvironment(scope);
+ try {
+ await api.setEnvironment(scope, pixiEnvironment);
+ const selectedEnvironment = await api.getEnvironment(scope);
+
+ assert.equal(
+ selectedEnvironment?.envId.id,
+ pixiEnvironment.envId.id,
+ 'Python Environments did not select the Pixi interpreter; check its output for a missing manager',
+ );
+ } finally {
+ try {
+ await api.setEnvironment(scope, previousEnvironment);
+ } finally {
+ if (originalSettings) {
+ await writeFile(settingsPath, originalSettings);
+ } else {
+ await rm(settingsPath, { force: true });
+ }
+ }
+ }
+ });
+});
diff --git a/src/test/hello-world.unit.test.ts b/src/test/hello-world.unit.test.ts
new file mode 100644
index 0000000..25aa4bf
--- /dev/null
+++ b/src/test/hello-world.unit.test.ts
@@ -0,0 +1,6 @@
+import * as assert from 'node:assert/strict';
+import { test } from 'node:test';
+
+test('runs unit tests', () => {
+ assert.equal(1 + 1, 2);
+});
diff --git a/src/test/pixi.unit.test.ts b/src/test/pixi.unit.test.ts
new file mode 100644
index 0000000..9a1f4e2
--- /dev/null
+++ b/src/test/pixi.unit.test.ts
@@ -0,0 +1,244 @@
+import * as assert from 'node:assert/strict';
+import { spawn as realSpawn, SpawnOptions } from 'node:child_process';
+import { EventEmitter as NodeEventEmitter } from 'node:events';
+import { chmod, mkdir, mkdtemp, rm, writeFile } from 'node:fs/promises';
+import * as os from 'node:os';
+import * as path from 'node:path';
+import { test } from 'node:test';
+
+import { PixiEnvironment } from '../pixi/types';
+
+type SpawnCall = { executable: string; args: string[]; options: SpawnOptions };
+type SpawnResult = { stdout?: string; stderr?: string; exitCode?: number };
+
+const calls: SpawnCall[] = [];
+const infoMessages: string[] = [];
+const errorMessages: string[] = [];
+let configuredExecutable = 'pixi';
+let workspaceFolders: { uri: { fsPath: string } }[] = [];
+let respond: (call: SpawnCall) => SpawnResult = () => ({ exitCode: 0 });
+let useRealSpawn = false;
+
+class TestEventEmitter {
+ event = () => undefined;
+ fire(_value: T) {}
+ dispose() {}
+}
+
+const vscode = {
+ CancellationError: class extends Error {},
+ EventEmitter: TestEventEmitter,
+ ProgressLocation: { Window: 1 },
+ ThemeIcon: class {
+ constructor(readonly id: string) {}
+ },
+ Uri: { file: (fsPath: string) => ({ fsPath }) },
+ window: {
+ showErrorMessage: () => undefined,
+ withProgress: async (_options: unknown, task: () => Promise) => task(),
+ },
+ workspace: {
+ getConfiguration: () => ({ get: () => configuredExecutable }),
+ get workspaceFolders() {
+ return workspaceFolders;
+ },
+ },
+};
+
+const childProcess = {
+ spawn(executable: string, args: string[], options: SpawnOptions) {
+ const call = { executable, args, options };
+ calls.push(call);
+ if (useRealSpawn) {
+ return realSpawn(executable, args, options);
+ }
+ const proc = new NodeEventEmitter() as NodeEventEmitter & {
+ stdout: NodeEventEmitter;
+ stderr: NodeEventEmitter;
+ kill: () => void;
+ };
+ proc.stdout = new NodeEventEmitter();
+ proc.stderr = new NodeEventEmitter();
+ proc.kill = () => undefined;
+ queueMicrotask(() => {
+ const result = respond(call);
+ if (result.stdout) {
+ proc.stdout.emit('data', result.stdout);
+ }
+ if (result.stderr) {
+ proc.stderr.emit('data', result.stderr);
+ }
+ proc.emit('exit', result.exitCode ?? 0);
+ proc.emit('close');
+ });
+ return proc;
+ },
+};
+
+// VS Code is unavailable in Node's unit-test process. Load the production modules
+// with only their host APIs replaced; the discovery and command logic remains real.
+const loader = require('node:module') as {
+ _load: (request: string, parent?: NodeModule, isMain?: boolean) => unknown;
+};
+const originalLoad = loader._load;
+loader._load = function (request, parent, isMain) {
+ if (request === 'vscode') {
+ return vscode;
+ }
+ if (request === 'child_process') {
+ return childProcess;
+ }
+ if (request === '@vscode/python-environments') {
+ return { PackageChangeKind: { add: 1, remove: 2 } };
+ }
+ return originalLoad.call(this, request, parent, isMain);
+};
+const { getPixi, refreshPixi, runPixi } = require('../pixi/utils') as typeof import('../pixi/utils');
+const { PixiPackageManager } = require('../pixi/projectManager') as typeof import('../pixi/projectManager');
+const { registerLogger } = require('../common/logging') as typeof import('../common/logging');
+loader._load = originalLoad;
+
+registerLogger({
+ info: (message: string) => void infoMessages.push(message),
+ error: (message: string) => void errorMessages.push(message),
+ debug: () => undefined,
+} as unknown as Parameters[0]);
+
+test('an unsupported Pixi environment does not hide valid Python environments', async () => {
+ calls.length = 0;
+ infoMessages.length = 0;
+ errorMessages.length = 0;
+ workspaceFolders = [{ uri: { fsPath: path.resolve('workspace') } }];
+ const projectPath = path.resolve('workspace', 'project');
+ respond = ({ args }) => {
+ if (args[0] === 'info') {
+ return {
+ stdout: JSON.stringify({
+ project_info: { name: 'project', manifest_path: path.join(projectPath, 'pixi.toml') },
+ environments_info: [
+ { name: 'default', prefix: path.join(projectPath, '.pixi', 'envs', 'default') },
+ { name: 'foreign', prefix: path.join(projectPath, '.pixi', 'envs', 'foreign') },
+ { name: 'test', prefix: path.join(projectPath, '.pixi', 'envs', 'test') },
+ ],
+ }),
+ };
+ }
+ const envName = args.at(-1);
+ if (envName === 'foreign') {
+ return { stderr: "No packages found in 'foreign' environment for this platform", exitCode: 1 };
+ }
+ return { stdout: JSON.stringify([{ name: 'python', version: '3.12.1', is_explicit: true }]) };
+ };
+
+ const environments = await refreshPixi(projectPath);
+
+ assert.deepEqual(
+ environments.map((environment) => environment.name),
+ ['project:default (3.12.1)', 'project:test (3.12.1)'],
+ );
+ assert.equal(calls.length, 4);
+ assert.ok(calls.every((call) => call.options.cwd === projectPath));
+ assert.ok(
+ errorMessages.some(
+ (message) =>
+ message.includes("Could not list packages for Pixi environment 'project:foreign'") &&
+ message.includes(projectPath),
+ ),
+ );
+});
+
+test('package refresh uses the Pixi environment name and keeps existing packages on failure', async () => {
+ calls.length = 0;
+ infoMessages.length = 0;
+ errorMessages.length = 0;
+ const projectPath = path.resolve('workspace', 'project');
+ const prefix = path.join(projectPath, '.pixi', 'envs', 'default');
+ const packages = [{ name: 'python', version: '3.12.1' }];
+ const environment = {
+ name: 'project:default (3.12.1)',
+ envId: { id: prefix },
+ packages,
+ pixiInfo: {
+ project_info: { name: 'project', manifest_path: path.join(projectPath, 'pixi.toml') },
+ environments_info: [{ name: 'default', prefix }],
+ },
+ } as unknown as PixiEnvironment;
+ const manager = new PixiPackageManager(
+ {} as ConstructorParameters[0],
+ {} as ConstructorParameters[1],
+ );
+
+ respond = () => ({ stderr: 'Pixi list failed', exitCode: 1 });
+ await manager.refresh(environment);
+ assert.equal(environment.packages, packages);
+ assert.equal(calls[0].args.at(-1), 'default');
+ assert.equal(calls[0].options.cwd, projectPath);
+ assert.ok(
+ errorMessages.some((message) => message.includes('Pixi command') && message.includes('Pixi list failed')),
+ );
+ assert.ok(
+ errorMessages.some(
+ (message) => message.includes('Failed to refresh packages') && message.includes(projectPath),
+ ),
+ );
+
+ respond = () => ({ stdout: JSON.stringify([{ name: 'python', version: '3.13.0', is_explicit: true }]) });
+ await manager.refresh(environment);
+ assert.equal(environment.packages[0].version, '3.13.0');
+});
+
+test('configured Pixi paths resolve from workspaces and commands use a workspace cwd', async () => {
+ calls.length = 0;
+ const root = await mkdtemp(path.join(os.tmpdir(), 'pixi code '));
+ const firstFolder = path.join(root, 'first');
+ const secondFolder = path.join(root, 'second');
+ const secondExecutable = path.join(secondFolder, 'bin', 'pixi');
+ try {
+ await mkdir(path.dirname(secondExecutable), { recursive: true });
+ await mkdir(firstFolder);
+ await writeFile(secondExecutable, '');
+ workspaceFolders = [{ uri: { fsPath: firstFolder } }, { uri: { fsPath: secondFolder } }];
+ configuredExecutable = path.join('bin', 'pixi');
+ assert.equal(await getPixi(), secondExecutable);
+
+ respond = () => ({ stdout: 'pixi 0.67.0' });
+ assert.equal(await runPixi(['--version']), 'pixi 0.67.0');
+ assert.equal(calls[0].executable, `"${secondExecutable}"`);
+ assert.equal(calls[0].options.cwd, firstFolder);
+
+ await runPixi(['--version'], { cwd: secondFolder });
+ assert.equal(calls[1].options.cwd, secondFolder);
+
+ configuredExecutable = '${workspaceFolder}/bin/pixi';
+ assert.equal(await getPixi(), path.join(firstFolder, 'bin', 'pixi'));
+ } finally {
+ configuredExecutable = 'pixi';
+ workspaceFolders = [];
+ await rm(root, { recursive: true, force: true });
+ }
+});
+
+test('a configured executable in a path with spaces can run through the shell', async () => {
+ const root = await mkdtemp(path.join(os.tmpdir(), 'pixi executable '));
+ const executable = path.join(root, process.platform === 'win32' ? 'pixi.cmd' : 'pixi');
+ try {
+ const script =
+ process.platform === 'win32'
+ ? '@echo off\r\necho pixi-test %1\r\n'
+ : '#!/bin/sh\nprintf "pixi-test %s\\n" "$1"\n';
+ await writeFile(executable, script);
+ if (process.platform !== 'win32') {
+ await chmod(executable, 0o755);
+ }
+ configuredExecutable = executable;
+ workspaceFolders = [{ uri: { fsPath: root } }];
+ useRealSpawn = true;
+
+ assert.equal((await runPixi(['--version'])).trim(), 'pixi-test --version');
+ } finally {
+ useRealSpawn = false;
+ configuredExecutable = 'pixi';
+ workspaceFolders = [];
+ await rm(root, { recursive: true, force: true });
+ }
+});
diff --git a/test/fixtures/pixi-project/.gitattributes b/test/fixtures/pixi-project/.gitattributes
new file mode 100644
index 0000000..997504b
--- /dev/null
+++ b/test/fixtures/pixi-project/.gitattributes
@@ -0,0 +1,2 @@
+# SCM syntax highlighting & preventing 3-way merges
+pixi.lock merge=binary linguist-language=YAML linguist-generated=true -diff
diff --git a/test/fixtures/pixi-project/hello_world.py b/test/fixtures/pixi-project/hello_world.py
new file mode 100644
index 0000000..cd6ecd9
--- /dev/null
+++ b/test/fixtures/pixi-project/hello_world.py
@@ -0,0 +1,2 @@
+if __name__ == "__main__":
+ print("Hello, World!")
diff --git a/test/fixtures/pixi-project/pixi.lock b/test/fixtures/pixi-project/pixi.lock
new file mode 100644
index 0000000..95355b5
--- /dev/null
+++ b/test/fixtures/pixi-project/pixi.lock
@@ -0,0 +1,604 @@
+version: 7
+platforms:
+- name: linux-64
+ virtual-packages:
+ - __unix=0=0
+ - __linux=4.18
+ - __glibc=2.28
+ - __archspec=0=x86_64
+- name: win-64
+ virtual-packages:
+ - __win=10.0
+ - __archspec=0=x86_64
+environments:
+ default:
+ channels:
+ - url: https://conda.anaconda.org/conda-forge/
+ packages:
+ linux-64:
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-20_gnu.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-hda65f42_10.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/icu-78.3-py310h44b86e0_2.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.46.1-default_hbd61a6d_102.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.8.5-hd2095e1_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/libffi-3.5.2-h3435931_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-16.2.0-ha9f2e26_7.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/libgomp-16.2.0-he0feb66_7.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.3-hb03c661_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/libmpdec-4.0.0-hb03c661_2.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.53.4-h13e7031_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-16.2.0-h934c35e_7.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.42.4-hcfc3c73_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.3.2-h25fd6f3_3.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.6-hdb14827_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/openssl-3.6.4-h781a0a9_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/python-3.14.0-h32b2ec7_103_cp314.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/readline-8.3-hd6e31c0_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_h1df4ec4_4.conda
+ - conda: https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.7-hb78ec9c_7.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.7.22-hbd8a1cb_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/python_abi-3.14-9_cp314.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2026c-h151e31d_0.conda
+ win-64:
+ - conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.7.22-h4c7d964_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/python_abi-3.14-9_cp314.conda
+ - conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2026c-h151e31d_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/bzip2-1.0.8-h0ad9c76_10.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/libexpat-2.8.5-hac47afa_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/libffi-3.5.2-h3d046cb_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/liblzma-5.8.3-hfd05255_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/libmpdec-4.0.0-hfd05255_2.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/libsqlite-3.53.4-hf5d6505_1.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/libzlib-1.3.2-hfd05255_3.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/openssl-3.6.4-hf411b9b_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/python-3.14.0-h4b44e0e_103_cp314.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/tk-8.6.13-h967ab96_4.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/ucrt-10.0.26100.0-h57928b3_0.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/vc-14.5-ha367084_41.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/vc14_runtime-14.51.36247-habf1de7_41.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/vcomp14-14.51.36247-habf1de7_41.conda
+ - conda: https://conda.anaconda.org/conda-forge/win-64/zstd-1.5.7-h534d264_7.conda
+packages:
+- conda: https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-20_gnu.conda
+ build_number: 20
+ sha256: 1dd3fffd892081df9726d7eb7e0dea6198962ba775bd88842135a4ddb4deb3c9
+ md5: a9f577daf3de00bca7c3c76c0ecbd1de
+ depends:
+ - __glibc >=2.17,<3.0.a0
+ - libgomp >=7.5.0
+ constrains:
+ - openmp_impl <0.0a0
+ license: BSD-3-Clause
+ license_family: BSD
+ run_exports:
+ strong:
+ - _openmp_mutex >=4.5
+ size: 28948
+ timestamp: 1770939786096
+- conda: https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-hda65f42_10.conda
+ sha256: 1a0d382c515ebf55f8ee1f38c8b81bc95af5c2acc42ad53b66bc5df932032f96
+ md5: e675fabcf81499adc7edf58124fb1e01
+ depends:
+ - __glibc >=2.17,<3.0.a0
+ - libgcc >=14
+ license: bzip2-1.0.6
+ license_family: BSD
+ run_exports:
+ weak:
+ - bzip2 >=1.0.8,<2.0a0
+ size: 257808
+ timestamp: 1785906269155
+- conda: https://conda.anaconda.org/conda-forge/linux-64/icu-78.3-py310h44b86e0_2.conda
+ sha256: 9f07834f0c546ab14d885ce0366285f61f44e326c0edd1fc63b8294e113ae432
+ md5: 72a381cbad04f24b1c2a43ef707f45b4
+ depends:
+ - __glibc >=2.17,<3.0.a0
+ - libstdcxx >=14
+ - libgcc >=14
+ license: MIT
+ license_family: MIT
+ run_exports:
+ weak:
+ - icu >=78.3,<79.0a0
+ size: 14459115
+ timestamp: 1786545741408
+- conda: https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.46.1-default_hbd61a6d_102.conda
+ sha256: 27d83f1188cd19bcb7754a078b3fa7f4cfb8527f8eb2fde54dd01fc529d1adec
+ md5: 449500f2c089da11c40f5c21312e3e07
+ depends:
+ - __glibc >=2.17,<3.0.a0
+ - zstd >=1.5.7,<1.6.0a0
+ constrains:
+ - binutils_impl_linux-64 2.46.1
+ license: GPL-3.0-only
+ license_family: GPL
+ run_exports: {}
+ size: 745303
+ timestamp: 1784214507189
+- conda: https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.8.5-hd2095e1_0.conda
+ sha256: 6de73033a7c5f712c9c5a54124e4581e025691029835e5bceaf10a333a7e7bc0
+ md5: 72cfd2b95b0540247220b42f58a148d7
+ depends:
+ - __glibc >=2.17,<3.0.a0
+ - libgcc >=15
+ constrains:
+ - expat 2.8.5.*
+ license: MIT
+ license_family: MIT
+ run_exports: {}
+ size: 77893
+ timestamp: 1790346247149
+- conda: https://conda.anaconda.org/conda-forge/linux-64/libffi-3.5.2-h3435931_0.conda
+ sha256: 31f19b6a88ce40ebc0d5a992c131f57d919f73c0b92cd1617a5bec83f6e961e6
+ md5: a360c33a5abe61c07959e449fa1453eb
+ depends:
+ - __glibc >=2.17,<3.0.a0
+ - libgcc >=14
+ license: MIT
+ license_family: MIT
+ run_exports:
+ weak:
+ - libffi >=3.5.2,<3.6.0a0
+ size: 58592
+ timestamp: 1769456073053
+- conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-16.2.0-ha9f2e26_7.conda
+ sha256: e031634c3a928f9594eba868bc46ef5230d6571a364a0c63215b06c4563bfcea
+ md5: 735629b400b70eeab21a2ba8f5b1c2ce
+ depends:
+ - __glibc >=2.17,<3.0.a0
+ - _openmp_mutex >=4.5
+ constrains:
+ - libgcc-ng ==16.2.0=*_7
+ - libgomp 16.2.0 he0feb66_7
+ license: GPL-3.0-only WITH GCC-exception-3.1
+ license_family: GPL
+ run_exports: {}
+ size: 1058444
+ timestamp: 1790303109576
+- conda: https://conda.anaconda.org/conda-forge/linux-64/libgomp-16.2.0-he0feb66_7.conda
+ sha256: 92a0bb350c7be6a4eedcb4e111c60aefd176018e6b1c009a6e025dbe9bbcd758
+ md5: d904c7ddd95e026254b4b80808ee9e12
+ depends:
+ - __glibc >=2.17,<3.0.a0
+ license: GPL-3.0-only WITH GCC-exception-3.1
+ license_family: GPL
+ run_exports:
+ strong:
+ - _openmp_mutex >=4.5
+ size: 640566
+ timestamp: 1790303046034
+- conda: https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.3-hb03c661_1.conda
+ sha256: 9787df8c22a59c9a70d3e5a10db9ad663485e75e9ccc3f09bd092cb7b95e0dab
+ md5: 1390b7c5ac0b1d8e447bc5efa6d3c8c2
+ depends:
+ - __glibc >=2.17,<3.0.a0
+ - libgcc >=14
+ constrains:
+ - xz 5.8.3.*
+ license: 0BSD
+ run_exports:
+ weak:
+ - liblzma >=5.8.3,<6.0a0
+ size: 112995
+ timestamp: 1786348617826
+- conda: https://conda.anaconda.org/conda-forge/linux-64/libmpdec-4.0.0-hb03c661_2.conda
+ sha256: 46820b4a835e175940ae20bec00fdddaff804cda27a1408ab1b95e77a2196437
+ md5: fcfed1dc5053eb1901b66e7b1fc32588
+ depends:
+ - __glibc >=2.17,<3.0.a0
+ - libgcc >=14
+ license: BSD-2-Clause
+ license_family: BSD
+ run_exports: {}
+ size: 92759
+ timestamp: 1786650399772
+- conda: https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.53.4-h13e7031_1.conda
+ sha256: f20d70da54e5b31dd4a51fb1efeaafafd5ab6dd8d7ac9d1438eaa2526ac4ed3d
+ md5: e72bbec309c2b0f37823ee7d4fabfcd3
+ depends:
+ - __glibc >=2.17,<3.0.a0
+ - icu >=78.3,<79.0a0
+ - libgcc >=15
+ - libzlib >=1.3.2,<2.0a0
+ license: blessing
+ run_exports:
+ weak:
+ - libsqlite >=3.53.4,<4.0a0
+ size: 974348
+ timestamp: 1787051145557
+- conda: https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-16.2.0-h934c35e_7.conda
+ sha256: fa7018298629fc429971fffd6ecba3d27a7b02e4e890d6a93ea01ffebe8cb745
+ md5: 9b6707e0caca917fa6ea9ee473f37a5d
+ depends:
+ - __glibc >=2.17,<3.0.a0
+ - libgcc 16.2.0 ha9f2e26_7
+ constrains:
+ - libstdcxx-ng ==16.2.0=*_7
+ license: GPL-3.0-only WITH GCC-exception-3.1
+ license_family: GPL
+ run_exports: {}
+ size: 6615436
+ timestamp: 1790303132935
+- conda: https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.42.4-hcfc3c73_0.conda
+ sha256: f34b8d1de9a2bf62476d8608057d9b8a918d97444236dc53a47128f2fae79041
+ md5: 54a948337e66706380ff24d6b5fde63f
+ depends:
+ - libgcc >=15
+ - __glibc >=2.17,<3.0.a0
+ license: BSD-3-Clause
+ license_family: BSD
+ run_exports:
+ weak:
+ - libuuid >=2.42.4,<3.0a0
+ size: 34442
+ timestamp: 1790121449161
+- conda: https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.3.2-h25fd6f3_3.conda
+ sha256: eb8a0db0aa570124f7d2a93d7c7f596e3390df5e047818d873baad32985fc736
+ md5: 0de0122d9570a8ab637c6b73db268389
+ depends:
+ - __glibc >=2.17,<3.0.a0
+ constrains:
+ - zlib 1.3.2 *_3
+ license: Zlib
+ license_family: Other
+ run_exports:
+ weak:
+ - libzlib >=1.3.2,<2.0a0
+ size: 63713
+ timestamp: 1785362952714
+- conda: https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.6-hdb14827_1.conda
+ sha256: 5d46557214ed184381dafe835b7c94a474a1c3b307a08a250b1ea4779b44ffb3
+ md5: ee6c0cd80a60961a1f48aa3e0b91f986
+ depends:
+ - __glibc >=2.17,<3.0.a0
+ - libgcc >=14
+ license: X11 AND BSD-3-Clause
+ run_exports:
+ weak:
+ - ncurses >=6.6,<7.0a0
+ size: 911196
+ timestamp: 1786355078102
+- conda: https://conda.anaconda.org/conda-forge/linux-64/openssl-3.6.4-h781a0a9_0.conda
+ sha256: 4747b2d6a8336f52343bceb8a1ebf41a9e6e665b9d2e3f989972de53a310599e
+ md5: 16e3034a330cc625f2c685edec60cf4e
+ depends:
+ - __glibc >=2.17,<3.0.a0
+ - ca-certificates
+ - libgcc >=15
+ license: Apache-2.0
+ license_family: Apache
+ run_exports:
+ weak:
+ - openssl >=3.6.4,<4.0a0
+ size: 3202955
+ timestamp: 1787698780103
+- conda: https://conda.anaconda.org/conda-forge/linux-64/python-3.14.0-h32b2ec7_103_cp314.conda
+ build_number: 103
+ sha256: 0b2b29d9de342b1a5fb4ef38dcce6e8d5edcd51f6f3dd29e62bca1f58a217d5d
+ md5: 945dbdc18b94a19ccb7638878da9d9b3
+ depends:
+ - __glibc >=2.17,<3.0.a0
+ - bzip2 >=1.0.8,<2.0a0
+ - ld_impl_linux-64 >=2.36.1
+ - libexpat >=2.7.3,<3.0a0
+ - libffi >=3.5.2,<3.6.0a0
+ - libgcc >=14
+ - liblzma >=5.8.1,<6.0a0
+ - libmpdec >=4.0.0,<5.0a0
+ - libsqlite >=3.51.1,<4.0a0
+ - libuuid >=2.41.2,<3.0a0
+ - libzlib >=1.3.1,<2.0a0
+ - ncurses >=6.5,<7.0a0
+ - openssl >=3.5.4,<4.0a0
+ - python_abi 3.14.* *_cp314
+ - readline >=8.2,<9.0a0
+ - tk >=8.6.13,<8.7.0a0
+ - tzdata
+ - zstd >=1.5.7,<1.6.0a0
+ license: Python-2.0
+ run_exports:
+ weak:
+ - python_abi 3.14.* *_cp314
+ noarch:
+ - python
+ size: 36634207
+ timestamp: 1764706943970
+ python_site_packages_path: lib/python3.14/site-packages
+- conda: https://conda.anaconda.org/conda-forge/linux-64/readline-8.3-hd6e31c0_1.conda
+ sha256: 01b3fe073a66e321970d09e04b388708f8cbdca5cdfbfcb7c9eeb470ad10383d
+ md5: 69c01c781e7c8190bbdaf79e3848c5ca
+ depends:
+ - __glibc >=2.17,<3.0.a0
+ - libgcc >=15
+ - ncurses >=6.6,<7.0a0
+ license: GPL-3.0-only
+ license_family: GPL
+ run_exports:
+ weak:
+ - readline >=8.3,<9.0a0
+ size: 348899
+ timestamp: 1787033801506
+- conda: https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_h1df4ec4_4.conda
+ build_number: 104
+ sha256: a1a241d172c1ccab067ba245206dd048bc3c2d1b84504b53c9468e99adfc16a1
+ md5: 676a2f9b1c4fcf57b70aa5c65f6c60d0
+ depends:
+ - libgcc >=15
+ - __glibc >=2.17,<3.0.a0
+ - libzlib >=1.3.2,<2.0a0
+ constrains:
+ - xorg-libx11 >=1.8.13,<2.0a0
+ license: TCL
+ run_exports:
+ weak:
+ - tk >=8.6.13,<8.7.0a0
+ size: 3566806
+ timestamp: 1787272857910
+- conda: https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.7-hb78ec9c_7.conda
+ sha256: 47d682b9f6d6ec9eb1a6e6c3e75ea6273e899e78fb7fc59f81d39745009fbc60
+ md5: aa459086047c0e5e27023ab19f8cb86a
+ depends:
+ - __glibc >=2.17,<3.0.a0
+ - libzlib >=1.3.2,<2.0a0
+ license: BSD-3-Clause
+ license_family: BSD
+ run_exports:
+ weak:
+ - zstd >=1.5.7,<1.6.0a0
+ size: 601301
+ timestamp: 1786599621503
+- conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.7.22-h4c7d964_0.conda
+ sha256: 95e8e74062a5fe5f870ac8c90302b6e89945165fdaed7810606e84ddee6aac12
+ md5: e27d2ac27b096dc51fedfcf775a53f9b
+ depends:
+ - __win
+ license: ISC
+ run_exports: {}
+ size: 132136
+ timestamp: 1784754918886
+- conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.7.22-hbd8a1cb_0.conda
+ sha256: 0a0544cf95f64394fe4959286f5c71f5444ad58feb0602e53becb27448d24da6
+ md5: 0f51e2391ade309db462a55611263e9c
+ depends:
+ - __unix
+ license: ISC
+ run_exports: {}
+ size: 131780
+ timestamp: 1784754889428
+- conda: https://conda.anaconda.org/conda-forge/noarch/python_abi-3.14-9_cp314.conda
+ build_number: 9
+ sha256: e7f8e965bbfb98e08feb2365cacdad8bb218fa5b5a0a2752f747287f425f213c
+ md5: 350d89b50d7de805abf2e63e29dee451
+ constrains:
+ - python 3.14.* *_cp314
+ license: BSD-3-Clause
+ license_family: BSD
+ run_exports: {}
+ size: 6791
+ timestamp: 1788302824440
+- conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2026c-h151e31d_0.conda
+ sha256: b928c30ddcb0e3f544c6eade8352737e6e610e263276b90232db6a578ef899d8
+ md5: fcb489df604d100968b737f2cb6076c6
+ license: LicenseRef-Public-Domain
+ run_exports: {}
+ size: 118849
+ timestamp: 1784250406640
+- conda: https://conda.anaconda.org/conda-forge/win-64/bzip2-1.0.8-h0ad9c76_10.conda
+ sha256: 04767466ee9227c9c57ab2c6503e0149177d34111c7418d2f420297acb1eb229
+ md5: c3301c058362f340100d91cd8be0393f
+ depends:
+ - ucrt >=10.0.20348.0
+ - vc >=14.3,<15
+ - vc14_runtime >=14.44.35208
+ license: bzip2-1.0.6
+ license_family: BSD
+ run_exports:
+ weak:
+ - bzip2 >=1.0.8,<2.0a0
+ size: 55919
+ timestamp: 1785906343696
+- conda: https://conda.anaconda.org/conda-forge/win-64/libexpat-2.8.5-hac47afa_0.conda
+ sha256: 70c73d9fd24ad996f2821d1501adae2ca70984b4e2d8faed76227f348ce86078
+ md5: 4969128c45f9e71adbb6a1696679ce7f
+ depends:
+ - ucrt >=10.0.20348.0
+ - vc >=14.3,<15
+ - vc14_runtime >=14.44.35208
+ constrains:
+ - expat 2.8.5.*
+ license: MIT
+ license_family: MIT
+ run_exports: {}
+ size: 72107
+ timestamp: 1790346254561
+- conda: https://conda.anaconda.org/conda-forge/win-64/libffi-3.5.2-h3d046cb_0.conda
+ sha256: 59d01f2dfa8b77491b5888a5ab88ff4e1574c9359f7e229da254cdfe27ddc190
+ md5: 720b39f5ec0610457b725eb3f396219a
+ depends:
+ - ucrt >=10.0.20348.0
+ - vc >=14.3,<15
+ - vc14_runtime >=14.44.35208
+ license: MIT
+ license_family: MIT
+ run_exports:
+ weak:
+ - libffi >=3.5.2,<3.6.0a0
+ size: 45831
+ timestamp: 1769456418774
+- conda: https://conda.anaconda.org/conda-forge/win-64/liblzma-5.8.3-hfd05255_1.conda
+ sha256: d36c4a1e1f80fd08e18a407e03622ff2f34dfdd022da6488ad19603dea19e6d5
+ md5: 880a0c8549479b198af21ba5dc49b109
+ depends:
+ - ucrt >=10.0.20348.0
+ - vc >=14.3,<15
+ - vc14_runtime >=14.44.35208
+ constrains:
+ - xz 5.8.3.*
+ license: 0BSD
+ run_exports:
+ weak:
+ - liblzma >=5.8.3,<6.0a0
+ size: 105809
+ timestamp: 1786348717883
+- conda: https://conda.anaconda.org/conda-forge/win-64/libmpdec-4.0.0-hfd05255_2.conda
+ sha256: f07e451de3db1836b87f7aedf95c8e65cdb06c0e6105329ba24bb5f7b5c75e2a
+ md5: 5ae92fd6614edd024576e14069d7ad4c
+ depends:
+ - ucrt >=10.0.20348.0
+ - vc >=14.3,<15
+ - vc14_runtime >=14.44.35208
+ license: BSD-2-Clause
+ license_family: BSD
+ run_exports: {}
+ size: 89109
+ timestamp: 1786650384519
+- conda: https://conda.anaconda.org/conda-forge/win-64/libsqlite-3.53.4-hf5d6505_1.conda
+ sha256: 0a45d7c0f20146fff787a106f8fa187872e309c70975ff8f0936e188914c26ad
+ md5: a72d495965b144bb7da033642d389047
+ depends:
+ - ucrt >=10.0.20348.0
+ - vc >=14.3,<15
+ - vc14_runtime >=14.44.35208
+ license: blessing
+ run_exports:
+ weak:
+ - libsqlite >=3.53.4,<4.0a0
+ size: 1314919
+ timestamp: 1787051140039
+- conda: https://conda.anaconda.org/conda-forge/win-64/libzlib-1.3.2-hfd05255_3.conda
+ sha256: 0629c2cc0404d3bb29d6baa7b4ba62da80797015e86de050db81ea5a07050527
+ md5: 5d2ff29d465097458cc3ff6569151991
+ depends:
+ - ucrt >=10.0.20348.0
+ - vc >=14.3,<15
+ - vc14_runtime >=14.44.35208
+ constrains:
+ - zlib 1.3.2 *_3
+ license: Zlib
+ license_family: Other
+ run_exports:
+ weak:
+ - libzlib >=1.3.2,<2.0a0
+ size: 58529
+ timestamp: 1785276664143
+- conda: https://conda.anaconda.org/conda-forge/win-64/openssl-3.6.4-hf411b9b_0.conda
+ sha256: 9dddb559ba49744d5d94092d8d13cb0567f5c3b3f439f3acf28433d1f4256acc
+ md5: 73cb1783f47c452be4c309430fbef89f
+ depends:
+ - ca-certificates
+ - ucrt >=10.0.20348.0
+ - vc >=14.3,<15
+ - vc14_runtime >=14.44.35208
+ license: Apache-2.0
+ license_family: Apache
+ run_exports:
+ weak:
+ - openssl >=3.6.4,<4.0a0
+ size: 9474879
+ timestamp: 1787699876495
+- conda: https://conda.anaconda.org/conda-forge/win-64/python-3.14.0-h4b44e0e_103_cp314.conda
+ build_number: 103
+ sha256: bb956b898a0602c5353b98239b154f7628da36d38e07b2381b08dd7553ce8e56
+ md5: 112140e1dcc25c5680a48bcfafbbe31a
+ depends:
+ - bzip2 >=1.0.8,<2.0a0
+ - libexpat >=2.7.3,<3.0a0
+ - libffi >=3.5.2,<3.6.0a0
+ - liblzma >=5.8.1,<6.0a0
+ - libmpdec >=4.0.0,<5.0a0
+ - libsqlite >=3.51.1,<4.0a0
+ - libzlib >=1.3.1,<2.0a0
+ - openssl >=3.5.4,<4.0a0
+ - python_abi 3.14.* *_cp314
+ - tk >=8.6.13,<8.7.0a0
+ - tzdata
+ - ucrt >=10.0.20348.0
+ - vc >=14.3,<15
+ - vc14_runtime >=14.44.35208
+ - zstd >=1.5.7,<1.6.0a0
+ license: Python-2.0
+ run_exports:
+ weak:
+ - python_abi 3.14.* *_cp314
+ noarch:
+ - python
+ size: 16959731
+ timestamp: 1764705373632
+ python_site_packages_path: Lib/site-packages
+- conda: https://conda.anaconda.org/conda-forge/win-64/tk-8.6.13-h967ab96_4.conda
+ sha256: f19618a3a82cc483dacf1c70a30367ee7b0c7e71b90f1f80e14feff44fbd3688
+ md5: dd9eb33c99d352b6356f86964d6040f7
+ depends:
+ - vc >=14.3,<15
+ - vc14_runtime >=14.44.35208
+ - ucrt >=10.0.20348.0
+ license: TCL
+ run_exports:
+ weak:
+ - tk >=8.6.13,<8.7.0a0
+ size: 3782376
+ timestamp: 1787272860855
+- conda: https://conda.anaconda.org/conda-forge/win-64/ucrt-10.0.26100.0-h57928b3_0.conda
+ sha256: 3005729dce6f3d3f5ec91dfc49fc75a0095f9cd23bab49efb899657297ac91a5
+ md5: 71b24316859acd00bdb8b38f5e2ce328
+ constrains:
+ - vc14_runtime >=14.29.30037
+ - vs2015_runtime >=14.29.30037
+ license: LicenseRef-MicrosoftWindowsSDK10
+ run_exports: {}
+ size: 694692
+ timestamp: 1756385147981
+- conda: https://conda.anaconda.org/conda-forge/win-64/vc-14.5-ha367084_41.conda
+ sha256: 35444c55a92e2f7f7ba26bc70f81e56e52344f7d064c0fd4b40a46a58517b79c
+ md5: aa805b5522c2a98fa286e551a1f48546
+ depends:
+ - vc14_runtime >=14.51.36247
+ track_features:
+ - vc14
+ license: BSD-3-Clause
+ license_family: BSD
+ run_exports: {}
+ size: 21383
+ timestamp: 1785359368566
+- conda: https://conda.anaconda.org/conda-forge/win-64/vc14_runtime-14.51.36247-habf1de7_41.conda
+ sha256: 4e4cb599cdc41bf2109d1464c127b5bcbddf548ce3e322e612afb691338b48f8
+ md5: ac5333bb3d429361f23adf704cc49a78
+ depends:
+ - ucrt >=10.0.20348.0
+ - vcomp14 14.51.36247 habf1de7_41
+ constrains:
+ - vs2015_runtime 14.51.36247.* *_41
+ license: LicenseRef-MicrosoftVisualCpp2015-2022Runtime
+ license_family: Proprietary
+ run_exports: {}
+ size: 767955
+ timestamp: 1785359364369
+- conda: https://conda.anaconda.org/conda-forge/win-64/vcomp14-14.51.36247-habf1de7_41.conda
+ sha256: 731e043390c9457299484d39e427221fc868a9249540a498a5a4f6456c7744d1
+ md5: 350bb67a5c8e5f1c53347ac544ab6600
+ depends:
+ - ucrt >=10.0.20348.0
+ constrains:
+ - vs2015_runtime 14.51.36247.* *_41
+ license: LicenseRef-MicrosoftVisualCpp2015-2022Runtime
+ license_family: Proprietary
+ run_exports:
+ strong:
+ - vcomp14 >=14.51.36247
+ size: 155910
+ timestamp: 1785359349999
+- conda: https://conda.anaconda.org/conda-forge/win-64/zstd-1.5.7-h534d264_7.conda
+ sha256: ca7daae4f218a11fab82cc2857f0ea518ec3f46acec60490485347a4c22c6b3e
+ md5: e4ac308c39d6d0e131154976da67cf3b
+ depends:
+ - vc >=14.3,<15
+ - vc14_runtime >=14.44.35208
+ - ucrt >=10.0.20348.0
+ - libzlib >=1.3.2,<2.0a0
+ license: BSD-3-Clause
+ license_family: BSD
+ run_exports:
+ weak:
+ - zstd >=1.5.7,<1.6.0a0
+ size: 387535
+ timestamp: 1786599623274
diff --git a/test/fixtures/pixi-project/pixi.toml b/test/fixtures/pixi-project/pixi.toml
new file mode 100644
index 0000000..e6e5aad
--- /dev/null
+++ b/test/fixtures/pixi-project/pixi.toml
@@ -0,0 +1,12 @@
+[workspace]
+authors = ["Lars Kaiser "]
+channels = ["conda-forge"]
+name = "pixi-project"
+platforms = ["win-64", "linux-64"]
+version = "0.1.0"
+
+[tasks]
+hello_world = { cmd = "python hello_world.py", description = "Hello World Command" }
+
+[dependencies]
+python = "3.14.*"
diff --git a/tsconfig.json b/tsconfig.json
index 4fb4b92..cb2003a 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -3,6 +3,7 @@
"module": "Node16",
"target": "ES2022",
"lib": ["ES2022"],
+ "types": ["node", "vscode", "mocha"],
"sourceMap": true,
"rootDir": "src",
"strict": true,