Nico Bellante d84e3344da Replace developing-with-streamlit with meta-skill for bundled skill discovery (#26)
## Summary

Replaces the old `developing-with-streamlit` skill (21 sub-skills + 17
templates) with a single lightweight **meta-skill** that discovers
Streamlit's bundled skills inside the pip package (>=1.57). One
user-level install works across every project; the discovered skills
always match each project's pinned Streamlit version.

Net diff: **+1,171 / −12,738** across 99 files.

## The contract

`developing-with-streamlit/scripts/discover.py` is the actual logic —
stdlib-only Python, cross-platform via `pathlib` + the `venv` module's
Windows/POSIX awareness. It detects the active Python interpreter
(`$VIRTUAL_ENV` → `./.venv` → `../.venv` → `<git-root>/.venv` →
`$CONDA_PREFIX` → `pipenv` if `Pipfile` → `poetry` if `poetry.lock` →
`pdm` if `pdm.lock` → `uv` if `uv.lock` → system), runs `import
streamlit; print(streamlit.__path__[0])`, and emits one of six exit
codes:

| Exit | Meaning | Agent action |
|---|---|---|
| 0 | Bundled SKILL.md found | Read printed path, follow its routing |
| 1 | Streamlit not installed | Confirm with user, then install with the
**single** package-manager-matched command in the error (`poetry add
streamlit` for poetry, `uv add streamlit` for uv, `<venv-python> -m pip
install streamlit` for venv, etc.) — no buffet |
| 2 | Streamlit < 1.57 | Suggest `pip install --upgrade streamlit` for
version-matched bundled skills; fall back to
`docs.streamlit.io/llms-full.txt` if user can't upgrade |
| 3 | No Python interpreter | Ask user to install Python 3.10+ (suggest
`uv` as the easy path) |
| 4 | Bundled skills exist but expected sub-path missing | Read listed
skills directly |
| 5 | Invalid argument | Fix invocation |

`SKILL.md` is a thin wrapper that documents this contract and tells the
agent to invoke `python <SKILL_DIR>/scripts/discover.py --project-dir
<USER_PROJECT_DIR>`. The `--project-dir` arg makes resolution
deterministic regardless of the agent's CWD at invocation time.

`detect_interpreter()` returns `(cmd, tag)` where `tag` identifies which
detection branch fired. `install_advice(cmd, tag)` maps the tag to one
matching install command, so a poetry project's exit-1 message points at
`poetry add streamlit` instead of dumping pip + uv + poetry + pipenv +
conda and asking the agent to guess.

Why a script instead of prose: same logic runs in production AND in
tests, so no parallel reference impl can drift. Pure-prose meta-skills
need LLM-in-the-loop evals to validate; this gets the bulk of realistic
failure modes from cheap pytest at zero LLM cost — modulo the
description-triggering question, which only LLM eval can answer.

## Tier 1 test matrix

19 pytest tests (26 cases including parametrized) in
`tests/discovery/test_discovery.py`. Each E2E test creates an isolated
`tmp_path` venv via the stdlib `venv` module, installs Streamlit fresh,
runs `discover.py`, and asserts the contract. Coverage:

- **Detection priority**: each interpreter source in our priority order,
including `<git-root>/.venv` (helpful for deep monorepo layouts)
- **Conflict**: `$VIRTUAL_ENV` wins over `./.venv`
- **Fallbacks**: missing-Streamlit (exit 1), pre-1.57 (exit 2),
upstream-restructured (exit 4)
- **Invocation contract**: `--project-dir` argument from outside the
project
- **Tool-marker detection**: `Pipfile` (pipenv), `poetry.lock` (poetry),
`pdm.lock` (pdm), `uv.lock` (uv)
- **uv branch isn't too eager**: doesn't fire on bare `pyproject.toml`
without `uv.lock`
- **Tool-aware install advice**: `install_advice` parametrized over all
10 tags (virtual-env, venv-local, venv-parent, venv-git-root, conda,
pipenv, poetry, pdm, uv, system) — guarantees the per-tag mapping
doesn't regress

Negative-test verified: temporarily reversing priority order in
`discover.py` causes `test_priority_venv_over_local` to fail with a
clear diagnostic; reverting the `uv.lock` marker causes
`test_uv_no_lockfile` to fail similarly. Both prove the tests catch the
regressions they're designed for.

CI runs on `ubuntu-latest` AND `windows-latest`, on PR + push to main +
weekly cron. Tests install whatever `streamlit` is currently latest on
PyPI — failures here are an honest signal that something broke, either
in our code or in upstream's bundled-skill layout.

### Latest passing run

[Run
25827312532](https://github.com/streamlit/agent-skills/actions/runs/25827312532)
on commit `7fd4fae`:

| Job | Result | Duration |
|---|---|---|
|
[`ubuntu-latest`](https://github.com/streamlit/agent-skills/actions/runs/25827312532/job/75883639893)
| 26 passed | 4m 33s |
|
[`windows-latest`](https://github.com/streamlit/agent-skills/actions/runs/25827312532/job/75883639903)
| 26 passed | 9m 13s |

All 26 cases pass on both runners — no skips. Every Windows-specific
concern (Scripts vs bin, `python.exe` vs `python`, path separators,
`Pipfile` / `poetry.lock` / `pdm.lock` / `uv.lock` markers) is
empirically validated. Each E2E test pins the resolved path to its own
venv via `assert_resolves_bundled(..., inside=...)`, so a
wrong-but-valid Streamlit install elsewhere on the runner can't silently
satisfy the assertion.

## End-to-end verification (LLM-in-the-loop)

Hands-on smoke test in a fresh Claude Code v2.1.128 session — done by me
before opening this for review, not by an automated script.

**Setup:** Built a `streamlit==1.57.0` venv at
`/tmp/test-streamlit-install-2/`, installed the skill at
`~/.claude/skills/developing-with-streamlit/`. Started Claude Code in
the project directory with no prior context, no `CLAUDE.md`, no skill
pre-selected.

**Prompt:**

> *I want to add a small KPI dashboard to a new app.py in this directory
— three metric cards showing total revenue, active users, and conversion
rate. Use placeholder values for now. Make it look polished.*

**Observed (full trajectory captured in the session JSONL — 14 tool
calls):**

1. Description match → `Skill(developing-with-streamlit)` fires
automatically. The prompt never names the skill or mentions `discover`.
2. `Bash` runs `discover.py --project-dir <project>` with **no
permission prompt** — the `allowed-tools` frontmatter pre-approves the
bundled script.
3. Stdout returns the bundled `SKILL.md` path inside the venv.
4. `Read` bundled SKILL.md, then `references/dashboards.md` and
`references/design.md`.
5. `ls` + `Read` of the `dashboard-metrics` template.
6. `Write` `app.py` using bundled patterns: `st.metric(border=True)`,
horizontal container, Material icons, sparkline trends.
7. Step 4 of the bundled SKILL.md respected — agent offered to run the
app rather than auto-running.

Whole chain held end-to-end. No skill misroutes, no silent fallthroughs,
no freelancing of Streamlit code without first reading the bundled refs.

## Acknowledged gaps

- **Multi-env disambiguation** — user with both conda + venv pinning
different Streamlit versions gets whichever the priority order picks.
Acceptable without a `cortex env detect`-style CLI.
- **Cross-agent `allowed-tools` support** — the pre-approval works in
Claude Code but is ignored by Cursor / Copilot / Gemini / Codex. They
fall back to their own permission prompts, which is the safe default —
just slightly more friction on first invocation in those agents.
- **Cross-agent end-to-end validation** — the smoke test above was
Claude Code only. Other agents follow the same Agent Skills spec and
should work via `npx skills add`, but individual agents haven't been
verified hands-on.

## Manual verification

All three confirmed by the cold-start hands-on test above:

- [x] Description's trigger phrases auto-fire the skill (no prompt
mentioned `developing-with-streamlit` or `discover`).
- [x] Agent invokes `scripts/discover.py` rather than winging it from
prose.
- [x] `allowed-tools` frontmatter pre-approves the bundled `discover.py`
(no bash permission prompt on first invocation in Claude Code).
2026-05-13 15:06:46 -07:00
2026-01-15 12:35:33 +01:00
2026-01-15 12:35:33 +01:00

Agent Skills for Streamlit Development

A lightweight meta-skill that teaches AI coding assistants (Claude Code, Cursor, and others) how to discover and load the Streamlit development skills bundled inside the Streamlit pip package (1.57+).

What are Agent Skills?

Agent Skills are specialized instruction sets that enhance AI coding assistants' capabilities for specific tasks. Each skill contains instructions, scripts, and resources that the AI loads dynamically to improve performance on Streamlit development workflows.

The actual skill content (dashboards, themes, layouts, session state, custom components, etc.) ships with Streamlit itself — this repo only contains the entry point that bootstraps discovery.

How it works

Starting with Streamlit 1.57, the full set of Streamlit development skills ships inside the Streamlit pip package itself. This repository provides a lightweight meta-skill that teaches agents how to discover and load those bundled skills.

The meta-skill (developing-with-streamlit/SKILL.md):

  1. Detects the active Python interpreter (virtualenv, conda, pipenv, poetry, pdm, uv, or system)
  2. Locates the installed Streamlit package path
  3. Points the agent to the bundled skills at <streamlit_path>/.agents/skills/
  4. Falls back to the online docs for older Streamlit versions

Install once, works with every project

Because discovery happens dynamically against whichever interpreter is active, a single user-level install of this meta-skill works across every project on your machine — regardless of which Streamlit version each project pins. Upgrade a project's Streamlit and the agent automatically picks up the newer bundled skills; no re-install needed.

Installation

This repository contains a single meta-skill (developing-with-streamlit). Install it once at the user level — the meta-skill resolves the bundled skills dynamically from whichever Python interpreter is active, so one global install works across every project and every Streamlit version you use.

skills (docs) is a Vercel-published cross-agent installer that supports Claude Code, Cursor, Copilot, Gemini CLI, Codex, and others — one command, all agents:

npx skills add streamlit/agent-skills -s developing-with-streamlit -g

-s picks the specific skill from this repo; -g installs at the user level (global) so it works across every project. Drop -g to install into the current project's .<agent>/skills/ directory instead. See npx skills add --help for the full flag list.

Claude Code

Anthropic's Claude Code does not yet ship an official skills install CLI. Clone this repo and drop the skill folder into your user-level Claude skills directory:

git clone https://github.com/streamlit/agent-skills.git
cp -r agent-skills/developing-with-streamlit ~/.claude/skills/

If you prefer project-scoped install, copy to .claude/skills/ in your repo root instead. See the Claude Code skills docs for the latest guidance.

GitHub Copilot

gh skill install streamlit/agent-skills developing-with-streamlit --scope user

Available via the GitHub CLI (gh) as of April 2026. Drop --scope user to install to the current repo only, or pin a version with developing-with-streamlit@v1.0.0. See the Copilot agent skills docs.

Cursor

The same GitHub CLI supports Cursor via --agent:

gh skill install streamlit/agent-skills developing-with-streamlit --agent cursor --scope user

See the Cursor skills docs for alternative install flows (Settings UI, manual placement in ~/.cursor/skills/).

Gemini CLI

gemini skills install https://github.com/streamlit/agent-skills.git

Defaults to ~/.gemini/skills/ (user scope). Add --scope workspace to install locally instead. See the Gemini CLI skills docs.

OpenAI Codex

Codex installs skills interactively. From inside a Codex session, run:

$skill-installer

Then point the installer at streamlit/agent-skills. Skills land in ~/.codex/skills/ (user). See the Codex skills docs.

Snowflake Cortex Code

Already installed — Cortex Code ships this skill by default; no manual step required.

Contributing

See CONTRIBUTING.md for guidelines on creating new skills.

License

This project is licensed under the Apache 2.0 License - see individual skills for their specific licenses.

S
Description
Use for ALL Streamlit tasks: creating, editing, debugging, beautifying, styling, theming, optimizing, or deploying Streamlit apps. Also custom components,…
Readme 3.6 MiB
Languages
Python 97.5%
Shell 2.5%