Skip to main content

StreamSnow ❄️

CI PyPI Python License: MIT Claude Code plugin

An open-source toolkit for building, governing, and shipping Streamlit-in-Snowflake apps with Claude Code.

Scaffold a governed monorepo, build dashboards inside enforced data-governance guardrails, and deploy them to Snowflake — without learning the rules by hand.


Status: beta, functional. The CLI (configure / init / new / doctor / validate-app / preview / check / sql-review / review-gate / review-loop / migrate / nav / deploy-sql / deploy-setup / verify-deploy / update / agent-skills) and the Claude Code plugin (8 skills + shared recipes, with deprecated aliases for the pre-0.3 names) are implemented and CI-green for both runtimes and both deploy sources. Published on PyPI (uvx streamsnow / pip install streamsnow); APIs may still evolve toward 1.0.

Mission

StreamSnow aims to let a data team build and ship Streamlit-in-Snowflake apps quickly and safely, by turning production lessons into scaffolding and checks that people and AI sessions can follow without having to remember them.

Vision

A data professional, with or without an AI assistant, can take a dashboard from idea to a governed, verified deployment in Snowflake without learning the platform's traps the hard way, and a reviewer with Snowsight can re-run the SQL behind the numbers it shows.

This is for you if:

  • ✅ you run, or will run, more than one Streamlit app in Snowflake with more than one author
  • ✅ you want Claude Code sessions and humans held to the same governance rules
  • ✅ you want a reviewer to re-run a dashboard's SQL in Snowsight without reading Python
  • ❌ you host Streamlit outside Snowflake, or you need a scheduler or a data catalog (StreamSnow does neither)
  • ❌ your dashboards are for people without Snowflake logins, out of the box (possible with customization; see below)

Where it fits next to a BI tool. For internal analytics, meaning dashboards your own Snowflake users open inside Snowsight, StreamSnow can replace a BI tool: the apps are Python you review like any other code, they run where the data lives, and access is managed with Snowflake roles. External or customer-facing analytics is a different job. Viewers without Snowflake logins, embedding a dashboard in another product, and pixel-perfect scheduled reports are all possible, but they take additional customization beyond what StreamSnow ships today.

Who can use this. You need a Snowflake account (any edition runs Streamlit in Snowflake; masking and row access policies, which StreamSnow does not require, need Enterprise) and either a role with CREATE STREAMLIT on one schema, or a Snowflake admin willing to run the one-time bootstrap that streamsnow deploy-setup --admin prints (database, schema, warehouse, roles, a CI service user and grants; see Deploy setup). Building and previewing locally needs only a login that can read your data.

Principles every change is judged against (the rules were already in the repo; collecting them here is what keeps future edits aligned):

  1. One implementation, many consumers. CLI, plugin, pre-commit, and CI call the same code.
  2. Detection is automated and total; destruction requires explicit committed consent.
  3. The backstop asks; it never decides. The gates are validate-app and CI, not the review nudge.
  4. Org knowledge lives in streamsnow.config.yaml and .streamsnow/overlays/, never in skills.
  5. Every rule names the incident that created it and the mechanism that enforces it.
  6. Degrade, don't die. A missing enabler is named, not refused.
  7. Faithful to a real fleet. A check that fails a well-run production app is a defect in the check until proven otherwise; tests/fixtures/fleet/ is the regression net.
  8. Leaving should be cheap. Everything StreamSnow writes into a repo is a plain file the repo keeps; the checks are the only dependency, and the exit path is documented as it actually is (Distribution → Ownership and exit).

What it is

StreamSnow is a hybrid of two things that work together:

  1. A streamsnow CLI (PyPI) — scaffolds a governed Streamlit-in-Snowflake monorepo, runs an interactive setup wizard, and vendors the validation tools, CI, pre-commit hooks, and branding your repo needs.
  2. A Claude Code plugin (marketplace) — ships the skills and hooks that turn Claude Code into a domain expert for this stack: /start-app (the front door), /preview-app, /validate-app, /review-app, /ship-app, and more.

Think a Claude Code skill pack fused with an installable system + setup. The CLI gives you the substrate; the plugin gives Claude the playbook. A single streamsnow.config.yaml is the source of truth both read from.

Why

Building Streamlit apps on Snowflake well means getting a hundred small things right: caching with TTLs, parameterized SQL that survives the deployed Go driver, runtime selection (container vs. warehouse), schema access guardrails, a deploy pipeline, branding, and review discipline. StreamSnow encodes those as executable guardrails — pre-commit + CI gates, scaffolding templates, and Claude Code skills — so every developer (and every Claude session) follows the same rules and ships safely.

Two things you choose

StreamSnow treats two axes as first-class, configurable options:

Axis Options
Runtime Container (default — GA since March 2026, full PyPI, local preview matches deploy) or Warehouse (instant start, Anaconda channel, no compute-pool cost). Snowflake's own comparison: runtime environments
Deploy source Stage-copy (default — CI uploads to an internal stage) or Snowflake GIT REPOSITORY (Snowflake pulls from your Git repo)

Quickstart

Two lanes; pick the one that matches how you work. Both end at the same governed repo, and both need Python 3.11+, uv, and git (uvx streamsnow doctor tells you what is missing).

/plugin marketplace add kyle-chalmers/streamsnow
/plugin install streamsnow@streamsnow
/start-app --setup

/start-app --setup installs the streamsnow CLI if it is missing, runs the doctor, walks each missing prerequisite one confirmation at a time, runs streamsnow init --no-starter-app (the five-question wizard plus the governed repo files: AGENTS.md, pre-commit hooks, CI, .gitignore, README; no example app), and hands you to /start-app to build your first app. In a repo that already has Streamlit apps it switches to adopt mode (maps onto what exists, writes MIGRATION.md, never scaffolds over you).

CLI only

uv tool install streamsnow           # persistent `streamsnow` on your PATH
mkdir my-snowflake-apps && cd my-snowflake-apps
streamsnow init                      # 5-question wizard, then a governed scaffold
snow connection add --connection-name <name> --account <locator> \
  --user <you> --authenticator externalbrowser --default   # init prints the exact command
uv tool install pre-commit && pre-commit install
streamsnow validate-app example-dashboard                 # PASS proves the scaffold is whole
uv venv --python 3.11 && uv pip install -e apps/example-dashboard   # container runtime
streamsnow preview example-dashboard

On the warehouse runtime an app has environment.yml instead of pyproject.toml, so install its packages directly (init and streamsnow preview print the exact line).

One connection store: st.connection("snowflake") reads the snow CLI's default connection locally, so the per-app secrets.toml is an optional override, not a second place to type the same values.

Upgrading

The two halves upgrade separately, and the plugin half does not pick up hook or skill changes on its own — an installed copy stays at the version it was installed at until you reinstall it.

claude plugin list                       # shows the installed plugin version
/plugin uninstall streamsnow@streamsnow
/plugin install streamsnow@streamsnow    # then restart Claude Code
uv tool upgrade streamsnow               # the CLI
streamsnow update                        # dry-run: governance files the new templates would change
streamsnow update --apply                # re-render AGENTS.md, hooks, CI, deploy.yml

Generated CI pins streamsnow>=0.7,<0.8 (the deploy workflow >=0.7.1,<0.8); bump the pin with update --apply when you move majors. claude plugin details streamsnow@streamsnow lists 16 skills: 8 real ones plus 8 deprecated aliases for the pre-0.3 names.

The skills

One front door plus focused verbs — each skill's SKILL.md stays under 80 lines, with depth in per-skill reference files:

Skill What it does
/start-app The front door: spec (incl. backfill from existing source) → scaffold → build pages → ship, with checkpoints. Also --setup (machine + repo) and adopt (existing repos — maps, doesn't scaffold, writes MIGRATION.md)
/preview-app Run an app locally against live Snowflake
/validate-app The pass/fail check that must be clean before shipping
/review-app Senior-reviewer-grade review; --fix applies findings, --auto loops to clean (executable loop primitives + per-change coverage stamping), --sql authors the audit-trail manifests
/audit-lineage Live-warehouse column + lineage verification (read-only, bounded)
/feedback-app Turn user feedback into classified, atomic-commit fixes
/ship-app Validate-gated stage → commit → push → PR → watch CI
/migrate-app Port an external Streamlit app in (lift, then conform)

Pre-0.3 names (/new-app, /refine-requirements, /add-page, /onboard, /auto-review-app, /sql-review, /apply-review, /deep-dive-data) still work as deprecated aliases and will be removed in the next major release.

Use with other agents

The skills are plain SKILL.md folders in the open Agent Skills format, so a coding agent other than Claude Code can follow them. OpenAI Codex CLI 0.157.1 is the only one tested. The CLI installs them where Codex looks:

streamsnow agent-skills install --agent codex               # <repo>/.agents/skills; commit it
streamsnow agent-skills install --agent codex --scope user  # ~/.agents/skills, every repo on this machine
streamsnow agent-skills list --agent codex                  # what is installed, and from which version

Then ask Codex for a skill by name ($start-app) or in plain words ("use the StreamSnow start-app skill to build..."). In a test with codex exec, Codex found the skills in .agents/skills, read the SKILL.md files and the recipes they link, and finished an offline app build that passed validate-app. The install is a copy: re-run it after uv tool upgrade streamsnow, and put repo-specific changes in .streamsnow/overlays/, because the command refuses to overwrite an edited skill without --force.

The same under any agent: the streamsnow CLI and its checks, validate-app, the pre-commit hooks and CI. They run outside the agent.

Different outside Claude Code (each skill points the agent at skills/_shared/other-agents.md):

  • Skill names. /ship-app is Claude Code's syntax; Codex uses $ship-app. The install marks ship-app and migrate-app explicit-only in Codex (allow_implicit_invocation: false), matching their disable-model-invocation in Claude Code.
  • Checkpoints. A checkpoint is a question the agent stops at. codex exec cannot ask you, so a non-interactive run stops at the first checkpoint its prompt does not answer. In the test it stopped at the spec checkpoint, and a second run whose prompt gave that answer resumed from REQUIREMENTS.md.
  • Reviewers. /review-app fans out reviewers as Claude Code subagents; the skill tells an agent without subagents to run the same briefs one after another.
  • Claude Code only: the plugin hooks in Hooks, in full have no Codex equivalent, so StreamSnow cannot pause a destructive snow command, nudge for a review, or print its session-start line there. The skills ask the agent to keep those guards by hand, and in the test Codex ran streamsnow review-gate classify itself. Those guards now rest on the agent following the skill; nothing enforces them.

The audit trail (new in 0.6)

Every query under apps/<slug>/queries/ gets a human-runnable proof: a fully-rendered, paste-runnable .review.sql under apps/<slug>/sql_review/, generated from a per-feature manifest and verified by an import-free freshness

  • coverage gate (streamsnow sql-review check). Coverage is keyed to the queries/ convention — the same place the validate gate pushes UI-feeding SQL — so SQL inlined in Python sits outside its reach. Drift, hand edits, unbound binds and write statements always fail the gate; whether an uncovered query fails or warns is your repo's call — sql_review: {coverage: warn | fail} in streamsnow.config.yaml (default warn, so an adopting fleet backfills on its own schedule; new in 0.7, replacing the 0.6 "warn now, FAIL later" promise). A person with nothing but Snowsight can trace a covered visual back to the data and confirm it — see Auditing a visual. For dashboards whose visuals aggregate differently than any single query, "mode": "metrics" manifests (0.6.1) render one authored block per visual.

Make it yours — repo overlays (new in 0.6.1)

The skills are generic procedures; your org's knowledge layers on top without forking them. Commit .streamsnow/overlays/<skill>.md files and every skill reads its overlay first — extra steps, local failure signatures, environment specifics, explicit overrides. Plugin upgrades never touch them; overlays may not skip mandatory gate invocations, and the coded gates (hooks, CI, pre-commit) run outside skill prose entirely. See skills/_shared/overlays.md.

Hooks, in full

Trust demands transparency: this plugin runs hooks, so here is every one of them. All are stdlib-only, make no network calls, never write outside the repo (plus one best-effort dedupe state file in $TMPDIR, so the review nudge fires once per state, not every turn), and fail open — a hook error never blocks your session; the guards only ever add a confirmation or a note.

Event Script What it does
PreToolUse (Bash) hooks/deploy_safety.py Pauses before destructive Streamlit/SQL commands (snow streamlit deploy/drop, CREATE OR REPLACE / DROP / ALTER STREAMLIT, stage REMOVE, destructive SQL incl. -f files / stdin) — /ship-app is the sanctioned deploy path
SessionStart hooks/session_start.sh One line inside a StreamSnow repo (plugin version, skills, which guards are active), a one-line /start-app --setup nudge in a repo that has Streamlit apps but no config, silence everywhere else
Stop hooks/review_gate_stop.py Warn-only nudge (a systemMessage, never a turn continuation) when a substantive app change ends with no review covering it — points at /review-app <slug> --auto. Off-switches: REVIEW_GATE_OFF=1, apps/<slug>/.review/SKIP, or review_gate: {enabled: false} in config

All hooks are repo-gated on streamsnow.config.yaml — zero cost in unrelated repos — and declare explicit timeouts so a hung hook can never stall a session. To turn them off, disable the plugin (claude plugin disable streamsnow). Hook additions do not reach installed copies automatically — see Upgrading.

How it's organized

streamsnow/            the PyPI package — CLI, config, policy, scaffolder, tools
  ├── cli.py           configure / init / new / doctor / check
  ├── config.py        typed + validated streamsnow.config.yaml model
  ├── policy.py        schema allow/deny single source of truth
  ├── scaffolder.py    renders a governed repo from config
  ├── _templates/      the Jinja scaffold templates (repo/ + app/)
  └── tools/           governance checks + engines (schema refs, security,
                       caching, dependency vulns, tombstones, path leaks,
                       sql_review generator, review gate/loop, migrate, doctor)
.claude-plugin/        Claude Code plugin manifest + marketplace
skills/  agents/  hooks/   Claude Code plugin surface (skills + SessionStart hook)
docs/  examples/            guides + a runnable no-Snowflake example app

Active scaffolding lives in streamsnow/ (templates under streamsnow/_templates/).

The streamsnow Python package is the single source of truth for tool logic: the CLI, the Claude Code plugin, pre-commit, and CI all call the same code — one implementation, many consumers.

Documentation

  • Getting started — run the example with no Snowflake, then scaffold and preview your own governed app.
  • Data discovery — find tables and wire queries inside the schema-access guardrails.
  • Deploying — ship apps to Snowflake on merge, for both deploy sources.
  • Deploy setup — the one-time Snowflake objects and CI secrets the pipeline needs.
  • Auditing a visual — the five-minute runbook for confirming any dashboard number against the warehouse, no code required.
  • Production lessons — the incidents behind the guardrails, genericized.
  • Troubleshooting — numbered symptom / cause / fix entries for the first-run and deploy failures people actually hit.
  • Official Snowflake docs, by topic — every external docs link the toolkit relies on, with scope, retrieved date, and where StreamSnow deliberately differs.
  • Distribution — how StreamSnow ships (PyPI CLI + plugin) and why there's no separate copy-paste kit.
  • Migrating a consumer repo — bring a repo with home-grown skills onto the plugin (skill map + incremental path).

License

MIT © Kyle Chalmers

StreamSnow is an independent open-source project and is not affiliated with or endorsed by Snowflake Inc., Streamlit, or Anthropic.

Metadata

Release files for streamsnow 0.7.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for streamsnow 0.7.1
File Size Uploaded
streamsnow-0.7.1.tar.gz 469.9 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for streamsnow 0.7.1
File Interpreter ABI Platform
streamsnow-0.7.1-py3-none-any.whl Python 3 none any Details

Total release size: 792.1 kB

Release files / streamsnow-0.7.1.tar.gz

Download URL streamsnow-0.7.1.tar.gz
Size 469.9 kB
Tags Source
SHA-256 checksum
How to use checksums
89572a60da13c192d2952de2a4c1b3873517956bd563f16bbd08ceba5ca1283c
BLAKE2b-256 checksum
How to use checksums
e63f98aa2fd7af9d8c8e38faf2c0b4a9f70f49ec243ee02c059729937864ae61
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 27, 2026.

Transparency log

Release files / streamsnow-0.7.1-py3-none-any.whl

Download URL streamsnow-0.7.1-py3-none-any.whl
Size 322.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
5c2aa52f44f65c10b4e8593bc4ddc7c19ec91566a8f84fc6084c0f61ed818a2a
BLAKE2b-256 checksum
How to use checksums
4db52eceb650fa58cc1a415f08eca30b97f19527c2e30dd532c355bd282008e9
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 27, 2026.

Transparency log

Release history Release notifications | RSS feed

0.7.5

2 release files

0.7.4

2 release files

0.7.3

2 release files

0.7.2

2 release files

This release

0.7.1 This release

2 release files

0.7.0

2 release files

0.6.3

2 release files

0.6.2

2 release files

0.6.1

2 release files

0.6.0

2 release files

0.5.0

2 release files

0.4.0

2 release files

0.3.0

2 release files

0.2.0

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page