Help us improve
Share bugs, ideas, or general feedback.
From probabl-skills
Detects which Python environment manager a project uses (pixi, uv, poetry, conda, pip+venv) and installs packages with the correct command. Bootstraps new projects with pixi by default.
npx claudepluginhub probabl-ai/skills --plugin probabl-skillsHow this skill is triggered — by the user, by Claude, or both
Slash command
/probabl-skills:python-env-managerThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Detect the env manager, install with the right command. Single
references/agent_feature_anatomy.mdreferences/ambient_detection.mdreferences/bootstrap.mdreferences/composition_model.mdreferences/editable_workspace.mdreferences/install_commands_anatomy.mdreferences/per_manager_footguns.mdreferences/preflight_evidence.mdreferences/skore_variant.mdscripts/install_agent_feature_conda.shscripts/install_agent_feature_hatch.shscripts/install_agent_feature_pip_venv.shscripts/install_agent_feature_pixi.shscripts/install_agent_feature_poetry.shscripts/install_agent_feature_uv.shscripts/verify_layout.shtemplates/pyrightconfig.jsonManages Python virtual environments using venv, Poetry, Pipenv, pyenv; handles dependencies, resolves conflicts, automates project setup, and troubleshoots issues.
Manages Python environments 10-100x faster using uv instead of pip. Covers project init, dependencies, virtual envs, and CLI tools via uv.
Opinionated Python data science/ML stack: one library per job organized by tier. Triggers on missing imports, library decisions, new projects, or substitute libraries.
Share bugs, ideas, or general feedback.
Detect the env manager, install with the right command. Single
authority for data-science-python-stack and the workflow skills
when they need a dependency added.
| Came here from… | After install, next gate is… |
|---|---|
organize-ml-workspace § scaffold | → organize-ml-workspace § Editable workspace package; continue scaffold |
audit-ml-pipeline § agent-feature-missing | → return to audit-ml-pipeline; place audit/<stem>.py |
build-ml-pipeline / evaluate-ml-pipeline § missing dep | → return to calling skill; continue at the failing pre-flight box |
data-science-python-stack § Missing dependency | → return to caller; the import that was missing should now succeed |
Always re-emit the Pre-flight checklist with evidence before declaring the turn done.
pip install. If it uses poetry, do not uv add. Mixing
managers creates state the manifest doesn't track, and the next
pixi install / poetry install / uv sync silently undoes the
install.default / dev / agent) is enforced. The agent does NOT ask
per-install. G-ENV-SCOPE fires only for ambiguous extras
(optuna, xgboost, mlflow, …).curl | sh is a system-level action.AskUserQuestion mandates. The manager pick and the scope pick
are operating-contract gates, not clarifying questions.Evidence: line. A
successful install command is not proof; the audit is.| Shortcut | Why it's wrong |
|---|---|
pixi on PATH → run pixi init / pixi add directly | Detection on PATH is context, not a pick. G-ENV-MGR still fires when no Workspace decisions row exists |
| User said "install ruff" → fire G-ENV-SCOPE | Routing is fixed: ruff / pytest / ipykernel / jupyterlab → dev. Scope ask is forbidden for the three known buckets |
User asked for xgboost → silently drop into default | Ambiguous extras require the binary default vs new-named-feature ask |
Calling skill writes its own pixi add --feature agent ... | Install commands are owned by this skill. Calling skills request; this skill installs |
| Agent feature install → also register a Jupyter kernel | The in-process runner does NOT use a kernel; registering one creates an orphan kernelspec |
| Urgency ("quick", "you pick") waives G-ENV-MGR | Never. Urgency never waives gates |
python-env-manager opened earlier this conversation → assume gates passed | Reading SKILL.md ≠ the gate firing. The AskUserQuestion (or JOURNAL.md lookup) is the gate pass |
Evidence format: see references/preflight_evidence.md.
Pre-flight (python-env-manager):
- [ ] Sibling SKILL.md files opened this turn:
data-science-python-stack, iterate-ml-experiment,
organize-ml-workspace
Evidence: Read .agents/skills/<each>/SKILL.md (this turn)
- [ ] `journal/JOURNAL.md` Status `Workspace decisions` block read
this turn for `env manager:` and `agent feature:` rows.
Evidence: lists each row's value or "not recorded yet" |
"n/a — JOURNAL.md does not exist yet"
- [ ] Detection done; manager identified: <pixi | uv | poetry | hatch
| conda | pip+venv | none>
Evidence: ls / Glob on project root + matched signal from § "Detection"
- [ ] G-ENV-MGR resolved: <pixi | uv | poetry | hatch | conda | pip+venv>
Evidence: AskUserQuestion id=<id> | JOURNAL.md Status (recorded YYYY-MM-DD) |
"detection returned a single manager; manifest commits the project"
- [ ] Dep category determined for each package:
runtime → default | dev → dev | agent → agent |
ambiguous → G-ENV-SCOPE binary ask
Evidence: explicit categorization in this turn's response
- [ ] G-ENV-SCOPE resolved ONLY for ambiguous extras
Evidence: AskUserQuestion id=<id> | user quote turn N |
"n/a — package routes automatically"
- [ ] (Agent-feature installs only) G-AGENT-FEATURE resolved: install | skipped
Evidence: AskUserQuestion id=<id> | JOURNAL.md Status (recorded YYYY-MM-DD) |
"n/a — not an agent-feature install"
- [ ] Install command syntax confirmed for that manager (see § "Install commands")
Evidence: cite the matching subsection
- [ ] Package list ready: <pkg-1, pkg-2, ...>
Evidence: explicit list in this turn's response
- [ ] (Agent-feature installs only) `pyrightconfig.json` drop step queued
Evidence: Read templates/pyrightconfig.json (this turn) + Write to project root
| "n/a — not an agent-feature install"
| "n/a — pyrightconfig.json already at project root"
- [ ] (Agent-feature installs only) Verification commands queued
Evidence: commands quoted in this turn's response | "n/a"
- [ ] Pre-flight re-emitted with evidence before final message.
Evidence: this same checklist appears in the end-of-turn summary.
| Signal at project root | Manager | Notes |
|---|---|---|
pixi.toml or pixi.lock | pixi | Default for this stack |
uv.lock, or pyproject.toml [tool.uv] | uv | Fast Rust-based |
poetry.lock, or pyproject.toml [tool.poetry] | poetry | Common in older projects |
hatch.toml, or pyproject.toml [tool.hatch] | hatch | Declarative; flow varies — ask |
environment.yml + conda/mamba on PATH | conda / mamba | Scientific stacks |
requirements.txt + .venv/ or venv/ | pip + venv | Least integrated |
| None of the above | (nothing detected) | Ask the user; default suggestion: pixi |
Notes:
pyproject.toml with only [build-system] / [project] and no
[tool.X] is ambiguous — ask, don't infer.pixi.toml + [tool.poetry]): surface the
ambiguity before picking.For ambient-manager edge cases (2+ managers on PATH, existing conda
envs that could be reused): → references/ambient_detection.md.
→ next: G-ENV-MGR (below).
G-ENV-MGR — which managerFires when: detection returned (nothing detected) AND project is
fresh; OR detection returned a single manager but no
Workspace decisions row for env manager exists yet.
AskUserQuestion: single pick — the manager. Options from the
detection table. Default recommendation on nothing-detected:
pixi. Free-text resolves only when it names a listed manager.
Persists: env manager: <pick> — recorded: <date> in
journal/JOURNAL.md Status Workspace decisions.
→ next: § "Install commands — by manager".
G-ENV-SCOPE — only for ambiguous extrasFires when: a requested dep doesn't match the § "Auto-routing
table" below (e.g. optuna, xgboost, mlflow).
AskUserQuestion (binary):
default — fold into runtime deps. Pick when the dep IS a
runtime concern.<X> — propose a name from the user's
wording (tracing for mlflow, tuning for optuna, dl for
torch). Pick when the dep is a tier-shift to feature-flag.Free-text resolution: explicit default or a feature name resolves;
"you pick" / "doesn't matter" does NOT.
default is pickedOne step: pixi add <pkg> (no --feature flag → lands in
default).
→ next: return to caller skill.
<X> is picked — 6 steps, all requiredThis is the load-bearing procedure smaller models forget. Step 3 specifically is the one that silently breaks LSP integration.
pixi add --feature <X> <pkg>
(manager-equivalents: uv add --group <X> <pkg>,
poetry add --group <X> <pkg>).<X> to the lsp env's features list —
per-manager:
pixi.toml [environments],
lsp = { features = [..., "<X>"], ... }.--all-groups / --with covers).pixi install -e lsp; uv →
uv sync --all-groups; poetry → poetry install --with <X>;
others → re-create.JOURNAL.md: append <X> to the
optional features: row.bash .agents/skills/python-env-manager/scripts/verify_layout.sh.
Exit 0 = consistent. Exit 1 = drift, with remediation lines.Skipping step 3 or 4 → the package installs into <X> but pyright
doesn't index it because lsp doesn't compose <X>. User sees
"unresolved import" on legitimate code.
→ next: return to caller skill.
G-AGENT-FEATURE — install ipython + pyrightFires when: an agent-only consumer (currently audit-ml-pipeline)
needs ipython / pyright and the manifest doesn't expose them.
AskUserQuestion (binary): install | skip.
install → run the bundled per-manager script (see § "Agent
feature install"). Recommended default for any workspace using
the audit flow.skip → block the calling skill; surface "audit step unavailable
until the agent feature is installed". No silent degradation.Persists: agent feature: <installed | skipped> — recorded: <date>.
There is no kernel registration. The audit runner is in-process.
The agent kernel: row in Workspace decisions is no longer
collected for new workspaces; legacy rows are informational.
→ next: § "Agent feature install" if install.
Read Workspace decisions first:
env manager: <pixi | uv | poetry | hatch | conda | pip+venv> — recorded: <date>agent feature: <installed | skipped> — recorded: <date>optional features: <name1, name2, ... | none> — recorded: <date>If a row is recorded, do not re-ask — cite
JOURNAL.md Status (Workspace decisions, recorded YYYY-MM-DD) as
the evidence for that row in the pre-flight.
If journal/JOURNAL.md doesn't exist yet (truly fresh project
before organize-ml-workspace), the gates fire fresh and answers
land in Workspace decisions once iterate-ml-experiment writes
the JOURNAL.
| Bucket | Contents | Composes with | Purpose |
|---|---|---|---|
default | scikit-learn, skrub, skore, tabular lib, editable <pkg> | (itself) | runtime |
dev | ruff, pytest, jupyterlab, ipykernel | default + dev | lint / test / interactive notebooks |
agent | ipython, pyright | default + agent | audit runner + pyright CLI |
lsp | (no own deps) | default + dev + agent + <all optional> | LSP integration |
Pixi composed-envs declaration:
[environments]
default = { features = ["default"], solve-group = "default" }
dev = { features = ["default", "dev"], solve-group = "default" }
agent = { features = ["default", "agent"], solve-group = "default" }
lsp = { features = ["default", "dev", "agent"], solve-group = "default" }
| Package | Routes to |
|---|---|
scikit-learn, skrub, skore (or skore[hub]) | default |
pandas + pyarrow OR polars | default |
ruff, pytest, jupyterlab, ipykernel | dev |
ipython, pyright | agent |
The editable workspace package (<pkg> @ .) | default |
Ambiguous → G-ENV-SCOPE fires.
Rationale (why lsp is separate, optional-feature growth model):
→ references/composition_model.md.
Once detected, use ONLY the matching commands. Per-manager
extended prose (the "why" + caveats per row) lives in
references/install_commands_anatomy.md.
| Action | Command |
|---|---|
| Add to default | pixi add <pkg> |
| Add to a feature | pixi add --feature <feature> <pkg> |
| Add to an env | pixi add -e <env> <pkg> |
| Remove | pixi remove <pkg> (or --feature <feature>) |
| Upgrade | pixi upgrade <pkg> |
| Run inside env | pixi run -e <env> <command> |
| Sync from manifest | pixi install |
default → [project] dependencies; dev → --group dev;
agent → --group agent; optional features → --group <name>.
| Action | Command |
|---|---|
| Add runtime | uv add <pkg> |
| Add dev | uv add --dev <pkg> |
| Add to group | uv add --optional <group> <pkg> |
| Remove | uv remove <pkg> |
| Upgrade | uv lock --upgrade-package <pkg> |
| Run inside env | uv run <command> |
| Sync | uv sync (use --all-groups to cover dev+agent+optional) |
default → [tool.poetry.dependencies]; dev → --group dev;
agent → --group agent; optional → --group <name>.
| Action | Command |
|---|---|
| Add runtime | poetry add <pkg> |
| Add dev | poetry add --group dev <pkg> |
| Add to group | poetry add --group <name> <pkg> |
| Remove | poetry remove <pkg> |
| Upgrade | poetry update <pkg> |
| Run | poetry run <command> |
| Sync | poetry install |
Declarative — no universal hatch add. Edit
pyproject.toml:[project] dependencies or
[tool.hatch.envs.<env>.dependencies], then any
hatch run -e <env> <command> re-creates the env. Caveat: hatch
envs do not compose; each non-default env duplicates runtime deps.
No native feature concept; map buckets to named envs
(<project>, <project>-dev, <project>-agent).
| Action | Command |
|---|---|
| Add (conda-forge) | conda install -n <env> -c conda-forge <pkg> |
| With mamba | mamba install -n <env> -c conda-forge <pkg> |
| Remove | conda remove -n <env> <pkg> |
| Sync from yml | conda env update -f environment.yml --prune |
Least-integrated. No manifest update — pip install mutates the
live env without tracking. Recommend migration to a managed
alternative.
Editable workspace install (src/<pkg>/) per manager:
→ references/editable_workspace.md.
The agent feature = project-scoped install of ipython + pyright
pyrightconfig.json (substituting <PYTHON_PATH>
for the lsp env's interpreter).| Manager | Invocation | Args |
|---|---|---|
| pixi | bash .agents/skills/python-env-manager/scripts/install_agent_feature_pixi.sh | none |
| uv | bash .agents/skills/python-env-manager/scripts/install_agent_feature_uv.sh | none |
| poetry | bash .agents/skills/python-env-manager/scripts/install_agent_feature_poetry.sh | none |
| hatch | bash .agents/skills/python-env-manager/scripts/install_agent_feature_hatch.sh | none (requires user-authored [tool.hatch.envs.agent] + [tool.hatch.envs.lsp]) |
| conda | bash .agents/skills/python-env-manager/scripts/install_agent_feature_conda.sh <project-name> | project name |
| pip+venv | bash .agents/skills/python-env-manager/scripts/install_agent_feature_pip_venv.sh <requirements-file> | requirements file |
Run the script, don't retype. Each script encodes per-manager
footguns (poetry's virtualenvs.in-project, hatch's no-composition,
conda's machine-local paths). Re-typing by hand is the named
forbidden shortcut.
Per-script anatomy (the 4 actions inside, post-install runner
invocation, cleanup, verification):
→ references/agent_feature_anatomy.md.
Per-manager footguns:
→ references/per_manager_footguns.md.
→ next: return to caller (typically audit-ml-pipeline).
Read skore mode: from journal/JOURNAL.md Status
Workspace decisions (set by organize-ml-workspace §
G-SKORE-MODE). The variant pulls in two orthogonal axes: mode
(local vs hub) and package source (conda-forge for pixi /
conda+mamba, PyPI for uv / poetry / hatch / pip+venv). PyPI
installs need an extra jupyter extra; conda-forge installs
already ship the jupyter integration.
skore mode: | conda-forge managers (pixi, conda / mamba) | PyPI managers (uv, poetry, hatch, pip+venv) |
|---|---|---|
local | pixi add skore / conda install -c conda-forge skore | uv add "skore[jupyter]" / poetry add "skore[jupyter]" / pip install "skore[jupyter]" |
hub | pixi add "skore[hub]" / conda install -c conda-forge "skore[hub]" | uv add "skore[hub,jupyter]" / poetry add "skore[hub,jupyter]" / pip install "skore[hub,jupyter]" |
If the row is absent (workspace not yet bootstrapped through
organize-ml-workspace), route back to that skill's G-SKORE-MODE.
Do not guess.
Forbidden:
skore[hub] "to be safe". The [hub] extra
costs ~20 MB of network deps + auth infra the local-mode user
didn't ask for.jupyter extra on PyPI installs because the
install line "looks shorter". The TableReport / report.*
widgets that the audit flow and evaluate-ml-pipeline rely on
fail to render without it on uv / poetry / hatch / pip+venv.jupyter extra on pixi / conda installs. Redundant
— conda-forge skore already pulls the jupyter integration in.Why the variant matters, mode-switching procedure, the [jupyter]
extra rationale:
→ references/skore_variant.md.
When skrub is being installed (or has just been installed) and
the platform is macOS, run dot -c in the project's env once the
install lands. This rebuilds graphviz's plugin / format cache;
skipping it leaves the first .skb.draw_graph() /
.skb.full_report() call printing format warnings or erroring out
on font lookup.
# right after the skrub install command lands, on macOS only:
[[ "$(uname)" == "Darwin" ]] && pixi run dot -c
Per manager, swap the env-run prefix: pixi run / uv run /
poetry run / hatch run / conda run -n <env> / activated
venv → bare dot -c. Linux + Windows: no-op, skip the call.
One-shot — no need to re-run on subsequent sessions unless graphviz
itself was reinstalled.
If detection found nothing AND the user picked pixi via G-ENV-MGR:
command -v pixi; surface install URL if missing.pixi init.pixi.toml: declare 3 features (default / dev /
agent) + 4 envs (default / dev / agent / lsp). dev
carries ruff, pytest, jupyterlab, ipykernel; agent
carries ipython, pyright.default (per G-SKORE-MODE table above —
pixi is conda-forge, so pixi add skore or pixi add "skore[hub]"; no [jupyter] extra on pixi).pandas pyarrow or polars).pixi add --pypi "<pkg> @ ." then edit to
<pkg> = { path = ".", editable = true }; then pixi install).pyrightconfig.json via sed-substitution of
<PYTHON_PATH> for .pixi/envs/lsp/bin/python.pixi install then pixi install -e dev /
-e agent / -e lsp.Full step-by-step with exact pixi.toml block, manager-equivalent
flows, pixi-version compatibility notes:
→ references/bootstrap.md.
→ next: return to organize-ml-workspace § scaffold.
| Skill | Relationship |
|---|---|
data-science-python-stack | Owns what to install; this skill turns it into a command |
organize-ml-workspace | Scaffold hands off here for editable install; G-TABULAR / G-SKORE-MODE feed this skill's bootstrap |
audit-ml-pipeline | G-AGENT-FEATURE fires from there |
build-ml-pipeline / evaluate-ml-pipeline | Missing-dep Stop conditions redirect here |
iterate-ml-experiment | Owns the Workspace decisions block this skill reads / writes |
--no-deps or version pins by default. Pin only on
user request or known incompatibility.