[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M69ANVY2ABDQCXJBQNBV587M":3,"skill-same:01M69ANVY2ABDQCXJBQNBV587M":68},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":16,"categories":17,"keywords":18,"publishedAt":38,"linkOnly":39,"markdownContent":40,"markdownBody":41,"frontMatter":42,"refName":44,"commitSha":45,"skillDirectory":46,"forksCount":47,"repositoryHtmlUrl":48,"repositoryHomepageUrl":49,"ownerHtmlUrl":50,"ownerBlogUrl":51,"ownerDescription":52,"updatedAt":53,"install":54,"resources":67},"01M69ANVY2ABDQCXJBQNBV587M","python-manager-discovery",null,"Environment manager-specific discovery patterns and known issues. Use when working on or reviewing environment discovery code for conda, poetry, pipenv, pyenv, or venv.","microsoft\u002Fvscode-python-environments","microsoft","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F6154722?v=4","01M698VYDXZ6JW5WH3CRV650R8","Microsoft","01M69ANKH8QP6PYCYYVP4340EX",147,"MIT","https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002Fvscode-python-environments\u002Fblob\u002Fmain\u002F.github\u002Fskills\u002Fpython-manager-discovery\u002FSKILL.md",[],[19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],"python manager discovery","python","discovery","manager","environment discovery","when","for","venv","pyenv","pipenv","name","false","conda","patterns","Poetry","use","environment","issues","code","2026-11-10 10:12:30",false,"---\nname: python-manager-discovery\ndescription: Environment manager-specific discovery patterns and known issues. Use when working on or reviewing environment discovery code for conda, poetry, pipenv, pyenv, or venv.\nargument-hint: 'manager name (e.g., poetry, conda, pyenv)'\nuser-invocable: false\n---\n\n# Environment Manager Discovery Patterns\n\nThis skill documents manager-specific discovery patterns, environment variable precedence, and known issues.\n\n## Manager Quick Reference\n\n| Manager | Config Files                                   | Cache Location           | Key Env Vars                                        |\n| ------- | ---------------------------------------------- | ------------------------ | --------------------------------------------------- |\n| Poetry  | `poetry.toml`, `pyproject.toml`, `config.toml` | Platform-specific        | `POETRY_VIRTUALENVS_IN_PROJECT`, `POETRY_CACHE_DIR` |\n| Pipenv  | `Pipfile`, `Pipfile.lock`                      | XDG or WORKON_HOME       | `WORKON_HOME`, `XDG_DATA_HOME`                      |\n| Pyenv   | `.python-version`, `versions\u002F`                 | `~\u002F.pyenv\u002F` or pyenv-win | `PYENV_ROOT`, `PYENV_VERSION`                       |\n| Conda   | `environment.yml`, `conda-meta\u002F`               | Registries + paths       | `CONDA_PREFIX`, `CONDA_DEFAULT_ENV`                 |\n| venv    | `pyvenv.cfg`                                   | In-project               | None                                                |\n\n---\n\n## Poetry\n\n### Discovery Locations\n\n**Virtualenvs cache (default):**\n\n- Windows: `%LOCALAPPDATA%\\pypoetry\\Cache\\virtualenvs`\n- macOS: `~\u002FLibrary\u002FCaches\u002Fpypoetry\u002Fvirtualenvs`\n- Linux: `~\u002F.cache\u002Fpypoetry\u002Fvirtualenvs`\n\n**In-project (when enabled):**\n\n- `.venv\u002F` in project root\n\n### Config Precedence (highest to lowest)\n\n1. Local config: `poetry.toml` in project root\n2. Environment variables: `POETRY_VIRTUALENVS_*`\n3. Global config: `~\u002F.config\u002Fpypoetry\u002Fconfig.toml`\n\n### Known Issues\n\n| Issue                     | Description                                     | Fix                              |\n| ------------------------- | ----------------------------------------------- | -------------------------------- |\n| `{cache-dir}` placeholder | Not resolved in paths from config               | Resolve placeholder before use   |\n| Wrong default path        | Windows\u002FmacOS differ from Linux                 | Use platform-specific defaults   |\n| In-project detection      | `POETRY_VIRTUALENVS_IN_PROJECT` must be checked | Check env var first, then config |\n\n### Code Pattern\n\n```typescript\nasync function getPoetryVirtualenvsPath(): Promise\u003Cstring> {\n    \u002F\u002F 1. Check environment variable first\n    const envVar = process.env.POETRY_VIRTUALENVS_PATH;\n    if (envVar) return envVar;\n\n    \u002F\u002F 2. Check local poetry.toml\n    const localConfig = await readPoetryToml(projectRoot);\n    if (localConfig?.virtualenvs?.path) {\n        return resolvePoetryPath(localConfig.virtualenvs.path);\n    }\n\n    \u002F\u002F 3. Use platform-specific default\n    return getDefaultPoetryCache();\n}\n\nfunction resolvePoetryPath(configPath: string): string {\n    \u002F\u002F Handle {cache-dir} placeholder\n    if (configPath.includes('{cache-dir}')) {\n        const cacheDir = getDefaultPoetryCache();\n        return configPath.replace('{cache-dir}', cacheDir);\n    }\n    return configPath;\n}\n```\n\n---\n\n## Pipenv\n\n### Discovery Locations\n\n**Default:**\n\n- Linux: `~\u002F.local\u002Fshare\u002Fvirtualenvs\u002F` (XDG_DATA_HOME)\n- macOS: `~\u002F.local\u002Fshare\u002Fvirtualenvs\u002F`\n- Windows: `~\\.virtualenvs\\`\n\n**When WORKON_HOME is set:**\n\n- Use `$WORKON_HOME\u002F` directly\n\n### Environment Variables\n\n| Var                      | Purpose                      |\n| ------------------------ | ---------------------------- |\n| `WORKON_HOME`            | Override virtualenv location |\n| `XDG_DATA_HOME`          | Base for Linux default       |\n| `PIPENV_VENV_IN_PROJECT` | Create `.venv\u002F` in project   |\n\n### Known Issues\n\n| Issue                         | Description         | Fix                          |\n| ----------------------------- | ------------------- | ---------------------------- |\n| Missing WORKON_HOME support   | Env var not checked | Read env var before defaults |\n| Missing XDG_DATA_HOME support | Not used on Linux   | Check XDG spec               |\n\n### Code Pattern\n\n```typescript\nfunction getPipenvVirtualenvsPath(): string {\n    \u002F\u002F Check WORKON_HOME first\n    if (process.env.WORKON_HOME) {\n        return process.env.WORKON_HOME;\n    }\n\n    \u002F\u002F Check XDG_DATA_HOME on Linux\n    if (process.platform === 'linux') {\n        const xdgData = process.env.XDG_DATA_HOME || path.join(os.homedir(), '.local', 'share');\n        return path.join(xdgData, 'virtualenvs');\n    }\n\n    \u002F\u002F Windows\u002FmacOS defaults\n    return path.join(os.homedir(), '.virtualenvs');\n}\n```\n\n---\n\n## PyEnv\n\n### Discovery Locations\n\n**Unix:**\n\n- `~\u002F.pyenv\u002Fversions\u002F` (default)\n- `$PYENV_ROOT\u002Fversions\u002F` (if PYENV_ROOT set)\n\n**Windows (pyenv-win):**\n\n- `%USERPROFILE%\\.pyenv\\pyenv-win\\versions\\`\n- Different directory structure than Unix!\n\n### Key Differences: Unix vs Windows\n\n| Aspect  | Unix              | Windows (pyenv-win)                     |\n| ------- | ----------------- | --------------------------------------- |\n| Command | `pyenv`           | `pyenv.bat`                             |\n| Root    | `~\u002F.pyenv\u002F`       | `%USERPROFILE%\\.pyenv\\pyenv-win\\`       |\n| Shims   | `~\u002F.pyenv\u002Fshims\u002F` | `%USERPROFILE%\\.pyenv\\pyenv-win\\shims\\` |\n\n### Known Issues\n\n| Issue                              | Description                                | Fix                                |\n| ---------------------------------- | ------------------------------------------ | ---------------------------------- |\n| path.normalize() vs path.resolve() | Windows drive letter missing               | Use `path.resolve()` on both sides |\n| Wrong command on Windows           | Looking for `pyenv` instead of `pyenv.bat` | Check for `.bat` extension         |\n\n### Code Pattern\n\n```typescript\nfunction getPyenvRoot(): string {\n    if (process.env.PYENV_ROOT) {\n        return process.env.PYENV_ROOT;\n    }\n\n    if (process.platform === 'win32') {\n        \u002F\u002F pyenv-win uses different structure\n        return path.join(os.homedir(), '.pyenv', 'pyenv-win');\n    }\n\n    return path.join(os.homedir(), '.pyenv');\n}\n\nfunction getPyenvVersionsPath(): string {\n    const root = getPyenvRoot();\n    return path.join(root, 'versions');\n}\n\n\u002F\u002F Use path.resolve() for comparisons!\nfunction comparePyenvPaths(pathA: string, pathB: string): boolean {\n    return path.resolve(pathA) === path.resolve(pathB);\n}\n```\n\n---\n\n## Conda\n\n### Discovery Locations\n\n**Environment locations:**\n\n- Base install `envs\u002F` directory\n- `~\u002F.conda\u002Fenvs\u002F`\n- Paths in `~\u002F.condarc` `envs_dirs`\n\n**Windows Registry:**\n\n- `HKCU\\Software\\Python\\ContinuumAnalytics\\`\n- `HKLM\\SOFTWARE\\Python\\ContinuumAnalytics\\`\n\n### Shell Activation\n\n| Shell      | Activation Command                     |\n| ---------- | -------------------------------------- |\n| bash, zsh  | `source activate envname`              |\n| fish       | `conda activate envname` (NOT source!) |\n| PowerShell | `conda activate envname`               |\n| cmd        | `activate.bat envname`                 |\n\n### Known Issues\n\n| Issue                 | Description             | Fix                        |\n| --------------------- | ----------------------- | -------------------------- |\n| Fish shell activation | Uses bash-style command | Use fish-compatible syntax |\n| Registry paths        | May be stale\u002Finvalid    | Verify paths exist         |\n| Base vs named envs    | Different activation    | Check if activating base   |\n\n### Code Pattern\n\n```typescript\nfunction getCondaActivationCommand(shell: ShellType, envName: string): string {\n    switch (shell) {\n        case 'fish':\n            \u002F\u002F Fish uses different syntax!\n            return `conda activate ${envName}`;\n        case 'cmd':\n            return `activate.bat ${envName}`;\n        case 'powershell':\n            return `conda activate ${envName}`;\n        default:\n            \u002F\u002F bash, zsh\n            return `source activate ${envName}`;\n    }\n}\n```\n\n---\n\n## venv\n\n### Discovery\n\n**Identification:**\n\n- Look for `pyvenv.cfg` file in directory\n- Contains `home` and optionally `version` keys\n\n### Version Extraction Priority\n\n1. `version` field in `pyvenv.cfg`\n2. Parse from `home` path (e.g., `Python311`)\n3. Spawn Python executable (last resort)\n\n### Code Pattern\n\n```typescript\nasync function getVenvVersion(venvPath: string): Promise\u003Cstring | undefined> {\n    const cfgPath = path.join(venvPath, 'pyvenv.cfg');\n\n    try {\n        const content = await fs.readFile(cfgPath, 'utf-8');\n        const lines = content.split('\\n');\n\n        for (const line of lines) {\n            const [key, value] = line.split('=').map((s) => s.trim());\n            if (key === 'version') {\n                return value;\n            }\n        }\n\n        \u002F\u002F Fall back to parsing home path\n        const homeLine = lines.find((l) => l.startsWith('home'));\n        if (homeLine) {\n            const home = homeLine.split('=')[1].trim();\n            const match = home.match(\u002F(\\d+)\\.(\\d+)\u002F);\n            if (match) {\n                return `${match[1]}.${match[2]}`;\n            }\n        }\n    } catch {\n        \u002F\u002F Config file not found or unreadable\n    }\n\n    return undefined;\n}\n```\n\n---\n\n## PET Server (Native Finder)\n\n### JSON-RPC Communication\n\nThe PET server is a Rust-based locator that communicates via JSON-RPC over stdio.\n\n### Known Issues\n\n| Issue               | Description                      | Fix                           |\n| ------------------- | -------------------------------- | ----------------------------- |\n| No timeout          | JSON-RPC can hang forever        | Add Promise.race with timeout |\n| Silent spawn errors | Extension continues without envs | Surface spawn errors to user  |\n| Resource leaks      | Worker pool not cleaned up       | Dispose on deactivation       |\n| Type guard missing  | Response types not validated     | Add runtime type checks       |\n| Cache key collision | Paths normalize to same key      | Use consistent normalization  |\n\n### Code Pattern\n\n```typescript\nasync function fetchFromPET\u003CT>(method: string, params: unknown): Promise\u003CT> {\n    const timeout = 30000; \u002F\u002F 30 seconds\n\n    const result = await Promise.race([\n        this.client.request(method, params),\n        new Promise\u003Cnever>((_, reject) => setTimeout(() => reject(new Error('PET server timeout')), timeout)),\n    ]);\n\n    \u002F\u002F Validate response type\n    if (!isValidResponse\u003CT>(result)) {\n        throw new Error(`Invalid response from PET: ${JSON.stringify(result)}`);\n    }\n\n    return result;\n}\n```\n","# Environment Manager Discovery Patterns\n\nThis skill documents manager-specific discovery patterns, environment variable precedence, and known issues.\n\n## Manager Quick Reference\n\n| Manager | Config Files                                   | Cache Location           | Key Env Vars                                        |\n| ------- | ---------------------------------------------- | ------------------------ | --------------------------------------------------- |\n| Poetry  | `poetry.toml`, `pyproject.toml`, `config.toml` | Platform-specific        | `POETRY_VIRTUALENVS_IN_PROJECT`, `POETRY_CACHE_DIR` |\n| Pipenv  | `Pipfile`, `Pipfile.lock`                      | XDG or WORKON_HOME       | `WORKON_HOME`, `XDG_DATA_HOME`                      |\n| Pyenv   | `.python-version`, `versions\u002F`                 | `~\u002F.pyenv\u002F` or pyenv-win | `PYENV_ROOT`, `PYENV_VERSION`                       |\n| Conda   | `environment.yml`, `conda-meta\u002F`               | Registries + paths       | `CONDA_PREFIX`, `CONDA_DEFAULT_ENV`                 |\n| venv    | `pyvenv.cfg`                                   | In-project               | None                                                |\n\n---\n\n## Poetry\n\n### Discovery Locations\n\n**Virtualenvs cache (default):**\n\n- Windows: `%LOCALAPPDATA%\\pypoetry\\Cache\\virtualenvs`\n- macOS: `~\u002FLibrary\u002FCaches\u002Fpypoetry\u002Fvirtualenvs`\n- Linux: `~\u002F.cache\u002Fpypoetry\u002Fvirtualenvs`\n\n**In-project (when enabled):**\n\n- `.venv\u002F` in project root\n\n### Config Precedence (highest to lowest)\n\n1. Local config: `poetry.toml` in project root\n2. Environment variables: `POETRY_VIRTUALENVS_*`\n3. Global config: `~\u002F.config\u002Fpypoetry\u002Fconfig.toml`\n\n### Known Issues\n\n| Issue                     | Description                                     | Fix                              |\n| ------------------------- | ----------------------------------------------- | -------------------------------- |\n| `{cache-dir}` placeholder | Not resolved in paths from config               | Resolve placeholder before use   |\n| Wrong default path        | Windows\u002FmacOS differ from Linux                 | Use platform-specific defaults   |\n| In-project detection      | `POETRY_VIRTUALENVS_IN_PROJECT` must be checked | Check env var first, then config |\n\n### Code Pattern\n\n```typescript\nasync function getPoetryVirtualenvsPath(): Promise\u003Cstring> {\n    \u002F\u002F 1. Check environment variable first\n    const envVar = process.env.POETRY_VIRTUALENVS_PATH;\n    if (envVar) return envVar;\n\n    \u002F\u002F 2. Check local poetry.toml\n    const localConfig = await readPoetryToml(projectRoot);\n    if (localConfig?.virtualenvs?.path) {\n        return resolvePoetryPath(localConfig.virtualenvs.path);\n    }\n\n    \u002F\u002F 3. Use platform-specific default\n    return getDefaultPoetryCache();\n}\n\nfunction resolvePoetryPath(configPath: string): string {\n    \u002F\u002F Handle {cache-dir} placeholder\n    if (configPath.includes('{cache-dir}')) {\n        const cacheDir = getDefaultPoetryCache();\n        return configPath.replace('{cache-dir}', cacheDir);\n    }\n    return configPath;\n}\n```\n\n---\n\n## Pipenv\n\n### Discovery Locations\n\n**Default:**\n\n- Linux: `~\u002F.local\u002Fshare\u002Fvirtualenvs\u002F` (XDG_DATA_HOME)\n- macOS: `~\u002F.local\u002Fshare\u002Fvirtualenvs\u002F`\n- Windows: `~\\.virtualenvs\\`\n\n**When WORKON_HOME is set:**\n\n- Use `$WORKON_HOME\u002F` directly\n\n### Environment Variables\n\n| Var                      | Purpose                      |\n| ------------------------ | ---------------------------- |\n| `WORKON_HOME`            | Override virtualenv location |\n| `XDG_DATA_HOME`          | Base for Linux default       |\n| `PIPENV_VENV_IN_PROJECT` | Create `.venv\u002F` in project   |\n\n### Known Issues\n\n| Issue                         | Description         | Fix                          |\n| ----------------------------- | ------------------- | ---------------------------- |\n| Missing WORKON_HOME support   | Env var not checked | Read env var before defaults |\n| Missing XDG_DATA_HOME support | Not used on Linux   | Check XDG spec               |\n\n### Code Pattern\n\n```typescript\nfunction getPipenvVirtualenvsPath(): string {\n    \u002F\u002F Check WORKON_HOME first\n    if (process.env.WORKON_HOME) {\n        return process.env.WORKON_HOME;\n    }\n\n    \u002F\u002F Check XDG_DATA_HOME on Linux\n    if (process.platform === 'linux') {\n        const xdgData = process.env.XDG_DATA_HOME || path.join(os.homedir(), '.local', 'share');\n        return path.join(xdgData, 'virtualenvs');\n    }\n\n    \u002F\u002F Windows\u002FmacOS defaults\n    return path.join(os.homedir(), '.virtualenvs');\n}\n```\n\n---\n\n## PyEnv\n\n### Discovery Locations\n\n**Unix:**\n\n- `~\u002F.pyenv\u002Fversions\u002F` (default)\n- `$PYENV_ROOT\u002Fversions\u002F` (if PYENV_ROOT set)\n\n**Windows (pyenv-win):**\n\n- `%USERPROFILE%\\.pyenv\\pyenv-win\\versions\\`\n- Different directory structure than Unix!\n\n### Key Differences: Unix vs Windows\n\n| Aspect  | Unix              | Windows (pyenv-win)                     |\n| ------- | ----------------- | --------------------------------------- |\n| Command | `pyenv`           | `pyenv.bat`                             |\n| Root    | `~\u002F.pyenv\u002F`       | `%USERPROFILE%\\.pyenv\\pyenv-win\\`       |\n| Shims   | `~\u002F.pyenv\u002Fshims\u002F` | `%USERPROFILE%\\.pyenv\\pyenv-win\\shims\\` |\n\n### Known Issues\n\n| Issue                              | Description                                | Fix                                |\n| ---------------------------------- | ------------------------------------------ | ---------------------------------- |\n| path.normalize() vs path.resolve() | Windows drive letter missing               | Use `path.resolve()` on both sides |\n| Wrong command on Windows           | Looking for `pyenv` instead of `pyenv.bat` | Check for `.bat` extension         |\n\n### Code Pattern\n\n```typescript\nfunction getPyenvRoot(): string {\n    if (process.env.PYENV_ROOT) {\n        return process.env.PYENV_ROOT;\n    }\n\n    if (process.platform === 'win32') {\n        \u002F\u002F pyenv-win uses different structure\n        return path.join(os.homedir(), '.pyenv', 'pyenv-win');\n    }\n\n    return path.join(os.homedir(), '.pyenv');\n}\n\nfunction getPyenvVersionsPath(): string {\n    const root = getPyenvRoot();\n    return path.join(root, 'versions');\n}\n\n\u002F\u002F Use path.resolve() for comparisons!\nfunction comparePyenvPaths(pathA: string, pathB: string): boolean {\n    return path.resolve(pathA) === path.resolve(pathB);\n}\n```\n\n---\n\n## Conda\n\n### Discovery Locations\n\n**Environment locations:**\n\n- Base install `envs\u002F` directory\n- `~\u002F.conda\u002Fenvs\u002F`\n- Paths in `~\u002F.condarc` `envs_dirs`\n\n**Windows Registry:**\n\n- `HKCU\\Software\\Python\\ContinuumAnalytics\\`\n- `HKLM\\SOFTWARE\\Python\\ContinuumAnalytics\\`\n\n### Shell Activation\n\n| Shell      | Activation Command                     |\n| ---------- | -------------------------------------- |\n| bash, zsh  | `source activate envname`              |\n| fish       | `conda activate envname` (NOT source!) |\n| PowerShell | `conda activate envname`               |\n| cmd        | `activate.bat envname`                 |\n\n### Known Issues\n\n| Issue                 | Description             | Fix                        |\n| --------------------- | ----------------------- | -------------------------- |\n| Fish shell activation | Uses bash-style command | Use fish-compatible syntax |\n| Registry paths        | May be stale\u002Finvalid    | Verify paths exist         |\n| Base vs named envs    | Different activation    | Check if activating base   |\n\n### Code Pattern\n\n```typescript\nfunction getCondaActivationCommand(shell: ShellType, envName: string): string {\n    switch (shell) {\n        case 'fish':\n            \u002F\u002F Fish uses different syntax!\n            return `conda activate ${envName}`;\n        case 'cmd':\n            return `activate.bat ${envName}`;\n        case 'powershell':\n            return `conda activate ${envName}`;\n        default:\n            \u002F\u002F bash, zsh\n            return `source activate ${envName}`;\n    }\n}\n```\n\n---\n\n## venv\n\n### Discovery\n\n**Identification:**\n\n- Look for `pyvenv.cfg` file in directory\n- Contains `home` and optionally `version` keys\n\n### Version Extraction Priority\n\n1. `version` field in `pyvenv.cfg`\n2. Parse from `home` path (e.g., `Python311`)\n3. Spawn Python executable (last resort)\n\n### Code Pattern\n\n```typescript\nasync function getVenvVersion(venvPath: string): Promise\u003Cstring | undefined> {\n    const cfgPath = path.join(venvPath, 'pyvenv.cfg');\n\n    try {\n        const content = await fs.readFile(cfgPath, 'utf-8');\n        const lines = content.split('\\n');\n\n        for (const line of lines) {\n            const [key, value] = line.split('=').map((s) => s.trim());\n            if (key === 'version') {\n                return value;\n            }\n        }\n\n        \u002F\u002F Fall back to parsing home path\n        const homeLine = lines.find((l) => l.startsWith('home'));\n        if (homeLine) {\n            const home = homeLine.split('=')[1].trim();\n            const match = home.match(\u002F(\\d+)\\.(\\d+)\u002F);\n            if (match) {\n                return `${match[1]}.${match[2]}`;\n            }\n        }\n    } catch {\n        \u002F\u002F Config file not found or unreadable\n    }\n\n    return undefined;\n}\n```\n\n---\n\n## PET Server (Native Finder)\n\n### JSON-RPC Communication\n\nThe PET server is a Rust-based locator that communicates via JSON-RPC over stdio.\n\n### Known Issues\n\n| Issue               | Description                      | Fix                           |\n| ------------------- | -------------------------------- | ----------------------------- |\n| No timeout          | JSON-RPC can hang forever        | Add Promise.race with timeout |\n| Silent spawn errors | Extension continues without envs | Surface spawn errors to user  |\n| Resource leaks      | Worker pool not cleaned up       | Dispose on deactivation       |\n| Type guard missing  | Response types not validated     | Add runtime type checks       |\n| Cache key collision | Paths normalize to same key      | Use consistent normalization  |\n\n### Code Pattern\n\n```typescript\nasync function fetchFromPET\u003CT>(method: string, params: unknown): Promise\u003CT> {\n    const timeout = 30000; \u002F\u002F 30 seconds\n\n    const result = await Promise.race([\n        this.client.request(method, params),\n        new Promise\u003Cnever>((_, reject) => setTimeout(() => reject(new Error('PET server timeout')), timeout)),\n    ]);\n\n    \u002F\u002F Validate response type\n    if (!isValidResponse\u003CT>(result)) {\n        throw new Error(`Invalid response from PET: ${JSON.stringify(result)}`);\n    }\n\n    return result;\n}\n```\n",{"name":5,"description":7,"argument-hint":43,"user-invocable":39},"manager name (e.g., poetry, conda, pyenv)","main","92c13e7942499b7608a22bf1cb86b881a90afc98",".github\u002Fskills\u002Fpython-manager-discovery",82,"https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002Fvscode-python-environments","https:\u002F\u002Fmarketplace.visualstudio.com\u002Fitems?itemName=ms-python.vscode-python-envs","https:\u002F\u002Fgithub.com\u002Fmicrosoft","https:\u002F\u002Fopensource.microsoft.com","Open source projects and samples from Microsoft","2026-11-11 07:16:10",{"source":8,"skillName":5,"commands":55,"prompt":65,"zipAvailable":66},[56,59,62],{"tool":57,"command":58},"npx","npx skills add microsoft\u002Fvscode-python-environments --skill python-manager-discovery",{"tool":60,"command":61},"bunx","bunx skills add microsoft\u002Fvscode-python-environments --skill python-manager-discovery",{"tool":63,"command":64},"pnpm","pnpm dlx skills add microsoft\u002Fvscode-python-environments --skill python-manager-discovery","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002Fvscode-python-environments\u002Fblob\u002Fmain\u002F.github\u002Fskills\u002Fpython-manager-discovery\u002FSKILL.md",true,[],[69,91,109,133,145,165],{"skillNo":70,"name":71,"nameZh":6,"description":72,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":73,"categories":74,"keywords":75,"publishedAt":38},"01M69AP5C8W366N8TDNBZA2YQ4","settings-precedence","VS Code settings precedence rules and common pitfalls. Essential for any code that reads or writes settings. Covers getConfiguration scope, inspect() vs get(), and multi-workspace handling.","https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002Fvscode-python-environments\u002Fblob\u002Fmain\u002F.github\u002Fskills\u002Fsettings-precedence\u002FSKILL.md",[],[76,77,78,30,79,80,81,82,83,84,25,85,86,87,37,88,89,90],"settings","settings precedence","essential","scope","multi","Rules","common pitfalls","pitfalls","inspect","file","review","component","get","workspace","common",{"skillNo":92,"name":93,"nameZh":6,"description":94,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":95,"categories":96,"keywords":97,"publishedAt":38},"01M69AP3CMT4CYDAZ6GQXCJN1D","run-smoke-tests","Run smoke tests to verify extension functionality in a real VS Code environment. Use this when checking if basic features work after changes.","https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002Fvscode-python-environments\u002Fblob\u002Fmain\u002F.github\u002Fskills\u002Frun-smoke-tests\u002FSKILL.md",[],[98,99,100,101,102,24,103,104,105,106,34,35,107,108,37],"tests","smoke","run","run smoke tests","smoke tests","features","changes","extension","basic","work","verify",{"skillNo":110,"name":111,"nameZh":6,"description":112,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":113,"categories":114,"keywords":120,"publishedAt":38},"01M69AP1H7465VYNYGZA7RSAMW","run-pre-commit-checks","Run the mandatory pre-commit checks before committing code. Includes lint, type checking, and unit tests. MUST be run before every commit.","https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002Fvscode-python-environments\u002Fblob\u002Fmain\u002F.github\u002Fskills\u002Frun-pre-commit-checks\u002FSKILL.md",[115],{"categoryNo":116,"categoryName":117,"taxonomyType":118,"taxonomyTypeDesc":119},"01JBSEEDCAT000000000000007","代码审查","SCENARIO","使用场景",[121,122,100,123,124,125,126,127,98,128,129,36,37,130,131,132],"commit","run pre commit checks","pre commit","pre commit checks","type","auto-fix","unit","auto","fix","lint","unit tests","pre-commit",{"skillNo":134,"name":135,"nameZh":6,"description":136,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":137,"categories":138,"keywords":139,"publishedAt":38},"01M69ANZK45PDMWHSTKZKZTS2V","run-integration-tests","Run integration tests to verify that extension components work together correctly. Use this after modifying component interactions or event handling.","https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002Fvscode-python-environments\u002Fblob\u002Fmain\u002F.github\u002Fskills\u002Frun-integration-tests\u002FSKILL.md",[],[100,140,141,142,98,87,143,105,34,107,108,144],"integration tests","run integration tests","integration","event","components",{"skillNo":146,"name":147,"nameZh":6,"description":148,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":149,"categories":150,"keywords":154,"publishedAt":38},"01M69ANXP7SBRDK7TK3C54V695","run-e2e-tests","Run E2E tests to verify complete user workflows like environment discovery, creation, and selection. Use this before releases or after major changes.","https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002Fvscode-python-environments\u002Fblob\u002Fmain\u002F.github\u002Fskills\u002Frun-e2e-tests\u002FSKILL.md",[151],{"categoryNo":152,"categoryName":153,"taxonomyType":118,"taxonomyTypeDesc":119},"01JBSEEDCAT000000000000008","测试与质量",[155,100,156,157,98,158,108,21,159,160,23,104,161,162,163,164,34,35],"e2e tests","run e2e","e2e","run e2e tests","workflows","user","complete","creation","selection","releases",{"skillNo":166,"name":167,"nameZh":6,"description":168,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":169,"categories":170,"keywords":171,"publishedAt":38},"01M69ANT39TYG676Q12DAWM182","generate-snapshot","Generate a codebase health snapshot for technical debt tracking and planning. Analyzes git history, code complexity, debt markers, and dependencies to identify hotspots and refactoring priorities.","https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002Fvscode-python-environments\u002Fblob\u002Fmain\u002F.github\u002Fskills\u002Fgenerate-snapshot\u002FSKILL.md",[],[172,173,174,175,176,25,177,178,179,180,181,182,183,184,185,186,187,188,189,37],"generate","generate snapshot","snapshot","code complexity","codebase","output","markers","technical debt","dependencies","priorities","complexity","codebase health","technical","history","refactoring","health","git","planning"]