streamsnow 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (78) hide show
  1. streamsnow-0.1.0/.claude-plugin/marketplace.json +12 -0
  2. streamsnow-0.1.0/.claude-plugin/plugin.json +12 -0
  3. streamsnow-0.1.0/.github/workflows/ci.yml +73 -0
  4. streamsnow-0.1.0/.github/workflows/publish.yml +38 -0
  5. streamsnow-0.1.0/.gitignore +31 -0
  6. streamsnow-0.1.0/CHANGELOG.md +32 -0
  7. streamsnow-0.1.0/CONTRIBUTING.md +40 -0
  8. streamsnow-0.1.0/LICENSE +21 -0
  9. streamsnow-0.1.0/PKG-INFO +149 -0
  10. streamsnow-0.1.0/README.md +120 -0
  11. streamsnow-0.1.0/RELEASING.md +52 -0
  12. streamsnow-0.1.0/agents/.gitkeep +0 -0
  13. streamsnow-0.1.0/docs/deploy-setup.md +49 -0
  14. streamsnow-0.1.0/examples/README.md +26 -0
  15. streamsnow-0.1.0/hooks/hooks.json +15 -0
  16. streamsnow-0.1.0/hooks/session_start.sh +5 -0
  17. streamsnow-0.1.0/pyproject.toml +60 -0
  18. streamsnow-0.1.0/scaffold/branding/.gitkeep +0 -0
  19. streamsnow-0.1.0/scaffold/github-workflows/.gitkeep +0 -0
  20. streamsnow-0.1.0/skills/_shared/cross-agent-review.md +67 -0
  21. streamsnow-0.1.0/skills/_shared/deploy-error-translator.md +48 -0
  22. streamsnow-0.1.0/skills/_shared/playwright-walkthrough.md +43 -0
  23. streamsnow-0.1.0/skills/_shared/sync-with-main.md +28 -0
  24. streamsnow-0.1.0/skills/add-page/SKILL.md +22 -0
  25. streamsnow-0.1.0/skills/apply-review/SKILL.md +35 -0
  26. streamsnow-0.1.0/skills/auto-review-app/SKILL.md +29 -0
  27. streamsnow-0.1.0/skills/deep-dive-data/SKILL.md +31 -0
  28. streamsnow-0.1.0/skills/migrate-app/SKILL.md +38 -0
  29. streamsnow-0.1.0/skills/new-app/SKILL.md +25 -0
  30. streamsnow-0.1.0/skills/onboard/SKILL.md +26 -0
  31. streamsnow-0.1.0/skills/preview-app/SKILL.md +24 -0
  32. streamsnow-0.1.0/skills/refine-requirements/SKILL.md +20 -0
  33. streamsnow-0.1.0/skills/review-app/SKILL.md +37 -0
  34. streamsnow-0.1.0/skills/ship-app/SKILL.md +25 -0
  35. streamsnow-0.1.0/skills/sql-review/SKILL.md +44 -0
  36. streamsnow-0.1.0/skills/start-app/SKILL.md +26 -0
  37. streamsnow-0.1.0/skills/validate-app/SKILL.md +32 -0
  38. streamsnow-0.1.0/streamsnow/__init__.py +19 -0
  39. streamsnow-0.1.0/streamsnow/_templates/app/AGENTS.md.j2 +15 -0
  40. streamsnow-0.1.0/streamsnow/_templates/app/branding.py.j2 +51 -0
  41. streamsnow-0.1.0/streamsnow/_templates/app/config.toml.j2 +8 -0
  42. streamsnow-0.1.0/streamsnow/_templates/app/environment.yml.j2 +11 -0
  43. streamsnow-0.1.0/streamsnow/_templates/app/example_metric.sql.j2 +12 -0
  44. streamsnow-0.1.0/streamsnow/_templates/app/overview.py.j2 +48 -0
  45. streamsnow-0.1.0/streamsnow/_templates/app/pyproject.toml.j2 +12 -0
  46. streamsnow-0.1.0/streamsnow/_templates/app/secrets.toml.example.j2 +10 -0
  47. streamsnow-0.1.0/streamsnow/_templates/app/snowflake.yml.j2 +29 -0
  48. streamsnow-0.1.0/streamsnow/_templates/app/sql_loader.py.j2 +21 -0
  49. streamsnow-0.1.0/streamsnow/_templates/app/streamlit_app.py.j2 +16 -0
  50. streamsnow-0.1.0/streamsnow/_templates/repo/AGENTS.md.j2 +52 -0
  51. streamsnow-0.1.0/streamsnow/_templates/repo/CLAUDE.md.j2 +1 -0
  52. streamsnow-0.1.0/streamsnow/_templates/repo/README.md.j2 +33 -0
  53. streamsnow-0.1.0/streamsnow/_templates/repo/ci.yml.j2 +35 -0
  54. streamsnow-0.1.0/streamsnow/_templates/repo/deploy.git.yml.j2 +66 -0
  55. streamsnow-0.1.0/streamsnow/_templates/repo/deploy.yml.j2 +68 -0
  56. streamsnow-0.1.0/streamsnow/_templates/repo/gitignore.j2 +21 -0
  57. streamsnow-0.1.0/streamsnow/_templates/repo/pre-commit-config.yaml.j2 +42 -0
  58. streamsnow-0.1.0/streamsnow/cli.py +594 -0
  59. streamsnow-0.1.0/streamsnow/config.py +401 -0
  60. streamsnow-0.1.0/streamsnow/deploy.py +152 -0
  61. streamsnow-0.1.0/streamsnow/policy.py +48 -0
  62. streamsnow-0.1.0/streamsnow/scaffolder.py +188 -0
  63. streamsnow-0.1.0/streamsnow/tools/__init__.py +8 -0
  64. streamsnow-0.1.0/streamsnow/tools/check_app_security.py +643 -0
  65. streamsnow-0.1.0/streamsnow/tools/check_bind_predicates.py +66 -0
  66. streamsnow-0.1.0/streamsnow/tools/check_caching.py +186 -0
  67. streamsnow-0.1.0/streamsnow/tools/check_export_clean.py +123 -0
  68. streamsnow-0.1.0/streamsnow/tools/check_schema_refs.py +272 -0
  69. streamsnow-0.1.0/streamsnow/tools/validate_app.py +281 -0
  70. streamsnow-0.1.0/streamsnow.config.example.yaml +57 -0
  71. streamsnow-0.1.0/templates/default/.gitkeep +0 -0
  72. streamsnow-0.1.0/tests/test_config.py +194 -0
  73. streamsnow-0.1.0/tests/test_deploy.py +100 -0
  74. streamsnow-0.1.0/tests/test_export_clean.py +32 -0
  75. streamsnow-0.1.0/tests/test_init.py +217 -0
  76. streamsnow-0.1.0/tests/test_smoke.py +45 -0
  77. streamsnow-0.1.0/tests/test_validate.py +581 -0
  78. streamsnow-0.1.0/uv.lock +425 -0
@@ -0,0 +1,12 @@
1
+ {
2
+ "name": "streamsnow",
3
+ "owner": { "name": "Kyle Chalmers" },
4
+ "description": "StreamSnow — build, govern, and ship Streamlit-in-Snowflake apps with Claude Code.",
5
+ "plugins": [
6
+ {
7
+ "name": "streamsnow",
8
+ "source": "./",
9
+ "description": "Scaffolding, data-governance guardrails, local preview, validation, review, and deploy for Streamlit-in-Snowflake apps."
10
+ }
11
+ ]
12
+ }
@@ -0,0 +1,12 @@
1
+ {
2
+ "name": "streamsnow",
3
+ "displayName": "StreamSnow",
4
+ "version": "0.0.1",
5
+ "description": "Build, govern, and ship Streamlit-in-Snowflake apps with Claude Code: scaffolding, data-governance guardrails, local preview, validation, review, and deploy.",
6
+ "author": { "name": "Kyle Chalmers" },
7
+ "homepage": "https://github.com/kyle-chalmers/streamsnow",
8
+ "repository": "https://github.com/kyle-chalmers/streamsnow",
9
+ "license": "MIT",
10
+ "keywords": ["snowflake", "streamlit", "dashboards", "governance", "scaffolding"],
11
+ "hooks": "./hooks/hooks.json"
12
+ }
@@ -0,0 +1,73 @@
1
+ name: ci
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ pull_request:
7
+
8
+ permissions:
9
+ contents: read
10
+
11
+ concurrency:
12
+ group: ci-${{ github.ref }}
13
+ cancel-in-progress: true
14
+
15
+ jobs:
16
+ lint-and-test:
17
+ runs-on: ubuntu-latest
18
+ strategy:
19
+ fail-fast: false
20
+ matrix:
21
+ python-version: ["3.11", "3.12"]
22
+ steps:
23
+ - uses: actions/checkout@v4
24
+
25
+ - name: Install uv
26
+ uses: astral-sh/setup-uv@v5
27
+
28
+ - name: Sync project (creates .venv with dev extras)
29
+ run: uv sync --extra dev --python ${{ matrix.python-version }}
30
+
31
+ - name: Ruff lint
32
+ run: uv run ruff check .
33
+
34
+ - name: Ruff format check
35
+ run: uv run ruff format --check .
36
+
37
+ - name: Pytest
38
+ run: uv run pytest -q
39
+
40
+ privacy-gate:
41
+ # Pre-publish gate: fail if any proprietary/internal term or secret leaks
42
+ # into the OSS tree (the automated half; human review in RELEASING.md).
43
+ runs-on: ubuntu-latest
44
+ steps:
45
+ - uses: actions/checkout@v4
46
+ - uses: astral-sh/setup-uv@v5
47
+ - run: uv run --python 3.11 python -m streamsnow.tools.check_export_clean .
48
+
49
+ wheel-smoke:
50
+ # Build the wheel and run `streamsnow init` from the INSTALLED artifact, so
51
+ # a packaging regression (e.g. templates excluded from the wheel) fails CI
52
+ # rather than shipping a broken install.
53
+ runs-on: ubuntu-latest
54
+ steps:
55
+ - uses: actions/checkout@v4
56
+ - name: Install uv
57
+ uses: astral-sh/setup-uv@v5
58
+ - name: Build wheel
59
+ run: uv build --wheel
60
+ - name: Install wheel into a clean venv
61
+ run: |
62
+ uv venv --python 3.11 /tmp/wheelenv
63
+ uv pip install --python /tmp/wheelenv dist/*.whl
64
+ - name: Smoke — init from the built wheel ships templates
65
+ run: |
66
+ /tmp/wheelenv/bin/streamsnow --version
67
+ /tmp/wheelenv/bin/streamsnow init \
68
+ --config streamsnow.config.example.yaml --dir /tmp/wheel-init --app smoke-app
69
+ test -f /tmp/wheel-init/apps/smoke-app/streamlit_app.py
70
+ test -f /tmp/wheel-init/AGENTS.md
71
+ # Run the guardrail from inside the generated repo (config is discovered
72
+ # from cwd) — proves the wheel ships templates AND the check works.
73
+ cd /tmp/wheel-init && /tmp/wheelenv/bin/streamsnow check schema-refs apps
@@ -0,0 +1,38 @@
1
+ name: publish
2
+
3
+ # Tag a release (e.g. `git tag v0.1.0 && git push --tags`) to build and publish
4
+ # to PyPI via Trusted Publishing (OIDC — no stored token). One-time setup: add a
5
+ # PyPI trusted publisher for project `streamsnow`, repo kyle-chalmers/streamsnow,
6
+ # workflow `publish.yml`, environment `pypi`. See RELEASING.md.
7
+
8
+ on:
9
+ push:
10
+ tags: ["v*"]
11
+
12
+ permissions:
13
+ contents: read
14
+
15
+ jobs:
16
+ build-and-publish:
17
+ runs-on: ubuntu-latest
18
+ environment: pypi
19
+ permissions:
20
+ id-token: write # required for PyPI Trusted Publishing
21
+ steps:
22
+ - uses: actions/checkout@v4
23
+
24
+ - uses: astral-sh/setup-uv@v5
25
+
26
+ - name: Build sdist + wheel
27
+ run: uv build
28
+
29
+ - name: Verify the tag matches the package version
30
+ run: |
31
+ TAG="${GITHUB_REF_NAME#v}"
32
+ PKG="$(uv run --python 3.11 python -c 'import importlib.metadata as m; print(m.version("streamsnow"))' 2>/dev/null || true)"
33
+ echo "tag=$TAG pkg=$PKG"
34
+ # soft check — the wheel filename carries the authoritative version
35
+ ls dist/
36
+
37
+ - name: Publish to PyPI (Trusted Publishing)
38
+ uses: pypa/gh-action-pypi-publish@release/v1
@@ -0,0 +1,31 @@
1
+ # Python
2
+ __pycache__/
3
+ *.py[cod]
4
+ *.egg-info/
5
+ .eggs/
6
+ build/
7
+ dist/
8
+ .venv/
9
+ venv/
10
+
11
+ # Tooling
12
+ .ruff_cache/
13
+ .pytest_cache/
14
+ .mypy_cache/
15
+ .coverage
16
+ htmlcov/
17
+
18
+ # Secrets / local config (never commit)
19
+ .streamlit/secrets.toml
20
+ streamsnow.config.local.yaml
21
+ *.local.yaml
22
+
23
+ # OS / editor
24
+ .DS_Store
25
+ *.swp
26
+ .idea/
27
+ .vscode/
28
+
29
+ # Scratch
30
+ /tmp/
31
+ *.log
@@ -0,0 +1,32 @@
1
+ # Changelog
2
+
3
+ All notable changes to StreamSnow are recorded here. This project follows
4
+ [semantic versioning](https://semver.org/) once it reaches its first release.
5
+
6
+ ## [0.1.0] - 2026-06-27
7
+
8
+ Initial release.
9
+
10
+ ### CLI (`streamsnow`)
11
+ - `configure` / `init` / `new` — set up the Snowflake environment and scaffold a
12
+ governed monorepo + apps (container or warehouse runtime).
13
+ - `doctor` — machine + config prerequisite checks.
14
+ - `validate-app` — deterministic PASS/FAIL gate; `check schema-refs|security|caching|bind-predicates`.
15
+ - `preview` — run an app locally against live Snowflake.
16
+ - `deploy-setup` / `deploy-sql` / `stage-path` / `config-get` — deploy SQL + helpers
17
+ for stage-copy and git-repository sources.
18
+ - `update` — re-render governance files from the current config (dry-run by default).
19
+
20
+ ### Claude Code plugin
21
+ - 14 skills (onboard, refine-requirements, new-app, add-page, preview-app,
22
+ validate-app, ship-app, start-app, review-app, deep-dive-data, apply-review,
23
+ auto-review-app, sql-review, migrate-app) + 4 shared recipes.
24
+ - SessionStart hook, guarded to StreamSnow repos.
25
+
26
+ ### Governance & safety
27
+ - Typed, validated `streamsnow.config.yaml` with an injection-safe rendering gate.
28
+ - Config-driven schema allow/deny, app-security, caching-TTL, and bind-predicate checks.
29
+ - Pre-publish privacy/export gate; generated repos ship pre-commit + CI guardrails.
30
+
31
+ ### Packaging
32
+ - PyPI Trusted-Publishing release workflow; wheel-smoke + 3.11/3.12 CI matrix.
@@ -0,0 +1,40 @@
1
+ # Contributing to StreamSnow
2
+
3
+ Thanks for your interest! StreamSnow is in early, active development.
4
+
5
+ ## Ground rules
6
+
7
+ - **One implementation, many consumers.** Validation/scaffolding logic lives in
8
+ the `streamsnow` Python package. The CLI, the Claude Code plugin, pre-commit,
9
+ and CI all call that same code — never fork logic into a skill or a workflow.
10
+ - **Tools are CLI-first and structured.** Each tool is a small program with
11
+ `--format=md|json` output and meaningful exit codes (`0` pass, `1` finding,
12
+ `2` tool error). Skills shell out to them; they never embed prompt text.
13
+ - **No org-specific values in committed code.** Anything Snowflake-, company-,
14
+ or brand-specific belongs in `streamsnow.config.yaml`, not hardcoded.
15
+ - **Secrets never go in the repo.** Not in config, not in tests, not in docs.
16
+
17
+ ## Dev setup
18
+
19
+ ```bash
20
+ git clone https://github.com/kyle-chalmers/streamsnow.git
21
+ cd streamsnow
22
+ uv venv --python 3.11
23
+ uv pip install -e ".[dev]"
24
+ pre-commit install # once available
25
+ ```
26
+
27
+ ## Before you open a PR
28
+
29
+ ```bash
30
+ ruff check . && ruff format --check .
31
+ pytest
32
+ ```
33
+
34
+ CI runs the same checks. Keep changes focused; describe what tool/skill/template
35
+ you touched and why.
36
+
37
+ ## Reporting issues
38
+
39
+ Open a GitHub issue with the StreamSnow version (`streamsnow --version`), your
40
+ runtime/deploy-source config (redact secrets), and steps to reproduce.
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Kyle Chalmers
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,149 @@
1
+ Metadata-Version: 2.4
2
+ Name: streamsnow
3
+ Version: 0.1.0
4
+ Summary: Open-source toolkit for building, governing, and shipping Streamlit-in-Snowflake apps with Claude Code
5
+ Project-URL: Homepage, https://github.com/kyle-chalmers/streamsnow
6
+ Project-URL: Repository, https://github.com/kyle-chalmers/streamsnow
7
+ Project-URL: Issues, https://github.com/kyle-chalmers/streamsnow/issues
8
+ Author: Kyle Chalmers
9
+ License: MIT
10
+ License-File: LICENSE
11
+ Keywords: claude-code,dashboards,governance,scaffolding,snowflake,streamlit
12
+ Classifier: Development Status :: 3 - Alpha
13
+ Classifier: Environment :: Console
14
+ Classifier: Intended Audience :: Developers
15
+ Classifier: License :: OSI Approved :: MIT License
16
+ Classifier: Programming Language :: Python :: 3.11
17
+ Classifier: Programming Language :: Python :: 3.12
18
+ Classifier: Topic :: Software Development :: Code Generators
19
+ Requires-Python: >=3.11
20
+ Requires-Dist: jinja2>=3.1
21
+ Requires-Dist: pyyaml>=6
22
+ Requires-Dist: rich>=13
23
+ Requires-Dist: typer>=0.12
24
+ Provides-Extra: dev
25
+ Requires-Dist: pre-commit>=4; extra == 'dev'
26
+ Requires-Dist: pytest>=8; extra == 'dev'
27
+ Requires-Dist: ruff>=0.15; extra == 'dev'
28
+ Description-Content-Type: text/markdown
29
+
30
+ <!-- markdownlint-disable MD041 -->
31
+ <h1 align="center">StreamSnow ❄️</h1>
32
+
33
+ <p align="center">
34
+ <a href="https://github.com/kyle-chalmers/streamsnow/actions/workflows/ci.yml"><img alt="CI" src="https://github.com/kyle-chalmers/streamsnow/actions/workflows/ci.yml/badge.svg"></a>
35
+ <a href="https://pypi.org/project/streamsnow/"><img alt="PyPI" src="https://img.shields.io/pypi/v/streamsnow.svg"></a>
36
+ <img alt="Python" src="https://img.shields.io/badge/python-3.11%2B-blue">
37
+ <a href="LICENSE"><img alt="License: MIT" src="https://img.shields.io/badge/license-MIT-blue.svg"></a>
38
+ <img alt="Claude Code plugin" src="https://img.shields.io/badge/Claude%20Code-plugin-d97757">
39
+ </p>
40
+
41
+ <p align="center">
42
+ <strong>An open-source toolkit for building, governing, and shipping
43
+ Streamlit-in-Snowflake apps with Claude Code.</strong>
44
+ </p>
45
+
46
+ <p align="center">
47
+ <em>Scaffold a governed monorepo, build dashboards inside enforced
48
+ data-governance guardrails, and deploy them to Snowflake — without
49
+ learning the rules by hand.</em>
50
+ </p>
51
+
52
+ ---
53
+
54
+ > **Status: alpha, functional.** The CLI (configure / init / new / validate-app /
55
+ > preview / check / deploy-sql / deploy-setup) and the Claude Code plugin (14
56
+ > skills + shared recipes) are implemented and CI-green for both runtimes and
57
+ > both deploy sources. Not yet published to PyPI; APIs may still shift before the
58
+ > first tagged release.
59
+
60
+ ## What it is
61
+
62
+ StreamSnow is a **hybrid** of two things that work together:
63
+
64
+ 1. **A `streamsnow` CLI** (PyPI) — scaffolds a governed Streamlit-in-Snowflake
65
+ monorepo, runs an interactive setup wizard, and vendors the validation
66
+ tools, CI, pre-commit hooks, and branding your repo needs.
67
+ 2. **A Claude Code plugin** (marketplace) — ships the skills, subagents, and
68
+ hooks that turn Claude Code into a domain expert for this stack:
69
+ `/new-app`, `/preview-app`, `/validate-app`, `/ship-app`, `/start-app`, and
70
+ more.
71
+
72
+ Think **a Claude Code skill pack fused with an installable system + setup**.
73
+ The CLI gives you the substrate; the plugin gives Claude the playbook. A single
74
+ `streamsnow.config.yaml` is the source of truth both read from.
75
+
76
+ ## Why
77
+
78
+ Building Streamlit apps on Snowflake well means getting a hundred small things
79
+ right: caching with TTLs, parameterized SQL that survives the deployed Go
80
+ driver, runtime selection (container vs. warehouse), schema access guardrails,
81
+ a deploy pipeline, branding, and review discipline. StreamSnow encodes those as
82
+ **executable guardrails** — pre-commit + CI gates, scaffolding templates, and
83
+ Claude Code skills — so every developer (and every Claude session) follows the
84
+ same rules and ships safely.
85
+
86
+ ## Two things you choose
87
+
88
+ StreamSnow treats two axes as first-class, configurable options:
89
+
90
+ | Axis | Options |
91
+ |------|---------|
92
+ | **Runtime** | **Container** (default — cheaper, full PyPI, modern Streamlit) or **Warehouse** (legacy — instant start, Anaconda channel) |
93
+ | **Deploy source** | **Stage-copy** (default — CI uploads to an internal stage) or **Snowflake `GIT REPOSITORY`** (Snowflake pulls from your Git repo) |
94
+
95
+ ## Quickstart (target experience)
96
+
97
+ ```bash
98
+ # 0. Check your machine has the prerequisites (Python 3.11+, uv, git, snow CLI)
99
+ uvx streamsnow doctor
100
+
101
+ # 1. Configure your Snowflake environment + scaffold a governed repo with a starter app
102
+ uvx streamsnow init # runs the config wizard, then scaffolds
103
+ # (or split it: `streamsnow configure` to set up streamsnow.config.yaml first,
104
+ # then `streamsnow init` to scaffold)
105
+
106
+ # 2. Connect to Snowflake + create local preview secrets
107
+ snow connection add --connection-name <name> --account <locator> \
108
+ --user <you> --authenticator externalbrowser # init prints the exact command
109
+ cp apps/<slug>/.streamlit/secrets.toml.example apps/<slug>/.streamlit/secrets.toml
110
+
111
+ # 3. Add the Claude Code plugin (inside Claude Code)
112
+ /plugin marketplace add kyle-chalmers/streamsnow
113
+ /plugin install streamsnow@streamsnow
114
+
115
+ # 4. Build, preview, validate, ship
116
+ streamsnow new marketing campaign-dashboard # or /new-app
117
+ streamlit run apps/marketing-campaign-dashboard/streamlit_app.py
118
+ # /preview-app -> /validate-app -> /ship-app
119
+ ```
120
+
121
+ ## How it's organized
122
+
123
+ ```
124
+ streamsnow/ the PyPI package — CLI, config, policy, scaffolder, tools
125
+ ├── cli.py configure / init / new / doctor / check
126
+ ├── config.py typed + validated streamsnow.config.yaml model
127
+ ├── policy.py schema allow/deny single source of truth
128
+ ├── scaffolder.py renders a governed repo from config
129
+ ├── _templates/ the Jinja scaffold templates (repo/ + app/)
130
+ └── tools/ governance checks (e.g. check_schema_refs)
131
+ .claude-plugin/ Claude Code plugin manifest + marketplace
132
+ skills/ agents/ hooks/ Claude Code plugin surface (filled out in upcoming phases)
133
+ docs/ examples/ guides + reference app (in progress)
134
+ ```
135
+
136
+ > Active scaffolding lives in `streamsnow/` (templates under `streamsnow/_templates/`).
137
+ > The `skills/`, `agents/`, `hooks/`, `docs/`, and `examples/` directories are
138
+ > placeholders being populated phase by phase.
139
+
140
+ The `streamsnow` Python package is the **single source of truth** for tool
141
+ logic: the CLI, the Claude Code plugin, pre-commit, and CI all call the same
142
+ code — one implementation, many consumers.
143
+
144
+ ## License
145
+
146
+ [MIT](LICENSE) © Kyle Chalmers
147
+
148
+ > StreamSnow is an independent open-source project and is not affiliated with or
149
+ > endorsed by Snowflake Inc., Streamlit, or Anthropic.
@@ -0,0 +1,120 @@
1
+ <!-- markdownlint-disable MD041 -->
2
+ <h1 align="center">StreamSnow ❄️</h1>
3
+
4
+ <p align="center">
5
+ <a href="https://github.com/kyle-chalmers/streamsnow/actions/workflows/ci.yml"><img alt="CI" src="https://github.com/kyle-chalmers/streamsnow/actions/workflows/ci.yml/badge.svg"></a>
6
+ <a href="https://pypi.org/project/streamsnow/"><img alt="PyPI" src="https://img.shields.io/pypi/v/streamsnow.svg"></a>
7
+ <img alt="Python" src="https://img.shields.io/badge/python-3.11%2B-blue">
8
+ <a href="LICENSE"><img alt="License: MIT" src="https://img.shields.io/badge/license-MIT-blue.svg"></a>
9
+ <img alt="Claude Code plugin" src="https://img.shields.io/badge/Claude%20Code-plugin-d97757">
10
+ </p>
11
+
12
+ <p align="center">
13
+ <strong>An open-source toolkit for building, governing, and shipping
14
+ Streamlit-in-Snowflake apps with Claude Code.</strong>
15
+ </p>
16
+
17
+ <p align="center">
18
+ <em>Scaffold a governed monorepo, build dashboards inside enforced
19
+ data-governance guardrails, and deploy them to Snowflake — without
20
+ learning the rules by hand.</em>
21
+ </p>
22
+
23
+ ---
24
+
25
+ > **Status: alpha, functional.** The CLI (configure / init / new / validate-app /
26
+ > preview / check / deploy-sql / deploy-setup) and the Claude Code plugin (14
27
+ > skills + shared recipes) are implemented and CI-green for both runtimes and
28
+ > both deploy sources. Not yet published to PyPI; APIs may still shift before the
29
+ > first tagged release.
30
+
31
+ ## What it is
32
+
33
+ StreamSnow is a **hybrid** of two things that work together:
34
+
35
+ 1. **A `streamsnow` CLI** (PyPI) — scaffolds a governed Streamlit-in-Snowflake
36
+ monorepo, runs an interactive setup wizard, and vendors the validation
37
+ tools, CI, pre-commit hooks, and branding your repo needs.
38
+ 2. **A Claude Code plugin** (marketplace) — ships the skills, subagents, and
39
+ hooks that turn Claude Code into a domain expert for this stack:
40
+ `/new-app`, `/preview-app`, `/validate-app`, `/ship-app`, `/start-app`, and
41
+ more.
42
+
43
+ Think **a Claude Code skill pack fused with an installable system + setup**.
44
+ The CLI gives you the substrate; the plugin gives Claude the playbook. A single
45
+ `streamsnow.config.yaml` is the source of truth both read from.
46
+
47
+ ## Why
48
+
49
+ Building Streamlit apps on Snowflake well means getting a hundred small things
50
+ right: caching with TTLs, parameterized SQL that survives the deployed Go
51
+ driver, runtime selection (container vs. warehouse), schema access guardrails,
52
+ a deploy pipeline, branding, and review discipline. StreamSnow encodes those as
53
+ **executable guardrails** — pre-commit + CI gates, scaffolding templates, and
54
+ Claude Code skills — so every developer (and every Claude session) follows the
55
+ same rules and ships safely.
56
+
57
+ ## Two things you choose
58
+
59
+ StreamSnow treats two axes as first-class, configurable options:
60
+
61
+ | Axis | Options |
62
+ |------|---------|
63
+ | **Runtime** | **Container** (default — cheaper, full PyPI, modern Streamlit) or **Warehouse** (legacy — instant start, Anaconda channel) |
64
+ | **Deploy source** | **Stage-copy** (default — CI uploads to an internal stage) or **Snowflake `GIT REPOSITORY`** (Snowflake pulls from your Git repo) |
65
+
66
+ ## Quickstart (target experience)
67
+
68
+ ```bash
69
+ # 0. Check your machine has the prerequisites (Python 3.11+, uv, git, snow CLI)
70
+ uvx streamsnow doctor
71
+
72
+ # 1. Configure your Snowflake environment + scaffold a governed repo with a starter app
73
+ uvx streamsnow init # runs the config wizard, then scaffolds
74
+ # (or split it: `streamsnow configure` to set up streamsnow.config.yaml first,
75
+ # then `streamsnow init` to scaffold)
76
+
77
+ # 2. Connect to Snowflake + create local preview secrets
78
+ snow connection add --connection-name <name> --account <locator> \
79
+ --user <you> --authenticator externalbrowser # init prints the exact command
80
+ cp apps/<slug>/.streamlit/secrets.toml.example apps/<slug>/.streamlit/secrets.toml
81
+
82
+ # 3. Add the Claude Code plugin (inside Claude Code)
83
+ /plugin marketplace add kyle-chalmers/streamsnow
84
+ /plugin install streamsnow@streamsnow
85
+
86
+ # 4. Build, preview, validate, ship
87
+ streamsnow new marketing campaign-dashboard # or /new-app
88
+ streamlit run apps/marketing-campaign-dashboard/streamlit_app.py
89
+ # /preview-app -> /validate-app -> /ship-app
90
+ ```
91
+
92
+ ## How it's organized
93
+
94
+ ```
95
+ streamsnow/ the PyPI package — CLI, config, policy, scaffolder, tools
96
+ ├── cli.py configure / init / new / doctor / check
97
+ ├── config.py typed + validated streamsnow.config.yaml model
98
+ ├── policy.py schema allow/deny single source of truth
99
+ ├── scaffolder.py renders a governed repo from config
100
+ ├── _templates/ the Jinja scaffold templates (repo/ + app/)
101
+ └── tools/ governance checks (e.g. check_schema_refs)
102
+ .claude-plugin/ Claude Code plugin manifest + marketplace
103
+ skills/ agents/ hooks/ Claude Code plugin surface (filled out in upcoming phases)
104
+ docs/ examples/ guides + reference app (in progress)
105
+ ```
106
+
107
+ > Active scaffolding lives in `streamsnow/` (templates under `streamsnow/_templates/`).
108
+ > The `skills/`, `agents/`, `hooks/`, `docs/`, and `examples/` directories are
109
+ > placeholders being populated phase by phase.
110
+
111
+ The `streamsnow` Python package is the **single source of truth** for tool
112
+ logic: the CLI, the Claude Code plugin, pre-commit, and CI all call the same
113
+ code — one implementation, many consumers.
114
+
115
+ ## License
116
+
117
+ [MIT](LICENSE) © Kyle Chalmers
118
+
119
+ > StreamSnow is an independent open-source project and is not affiliated with or
120
+ > endorsed by Snowflake Inc., Streamlit, or Anthropic.
@@ -0,0 +1,52 @@
1
+ # Releasing StreamSnow
2
+
3
+ ## Pre-publish privacy gate (do this before the repo goes public)
4
+
5
+ StreamSnow was extracted from a private monorepo, so before flipping the repo
6
+ public or cutting the first PyPI release:
7
+
8
+ 1. **Automated scan** — must be clean:
9
+ ```bash
10
+ uv run python -m streamsnow.tools.check_export_clean .
11
+ ```
12
+ (Also runs as the `privacy-gate` CI job on every push.)
13
+ 2. **Human review** — skim for anything the scanner can't know is sensitive:
14
+ - real company/people/customer names, internal URLs, ticket IDs, account locators
15
+ - screenshots or example data derived from real systems
16
+ - anything in `git log` history (the scan only sees the working tree)
17
+ 3. Confirm `LICENSE`, `README`, and `CONTRIBUTING` say what you intend.
18
+
19
+ ## One-time PyPI setup (Trusted Publishing — no stored token)
20
+
21
+ 1. Create the `streamsnow` project on PyPI (or reserve the name).
22
+ 2. PyPI → project → **Publishing** → add a **Trusted Publisher**:
23
+ - Owner: `kyle-chalmers` · Repo: `streamsnow` · Workflow: `publish.yml` · Environment: `pypi`
24
+ 3. In GitHub repo settings, create an environment named `pypi`.
25
+
26
+ ## Cut a release
27
+
28
+ 1. Bump `version` in `pyproject.toml` (and note changes in `CHANGELOG.md`).
29
+ 2. Ensure `main` is green (lint-and-test, privacy-gate, wheel-smoke).
30
+ 3. Tag and push:
31
+ ```bash
32
+ git tag v0.1.0
33
+ git push origin v0.1.0
34
+ ```
35
+ The `publish` workflow builds the sdist + wheel and publishes to PyPI via OIDC.
36
+ 4. Create a GitHub Release from the tag with the changelog notes.
37
+
38
+ ## Flip the repo public (separate, deliberate step)
39
+
40
+ Only after the privacy gate passes and you've decided to open it:
41
+ ```bash
42
+ GH_TOKEN="$GITHUB_TOKEN_PERSONAL" gh repo edit kyle-chalmers/streamsnow --visibility public --accept-visibility-change-consequences
43
+ ```
44
+
45
+ ## Claude Code plugin marketplace
46
+
47
+ Once public, users add the plugin with:
48
+ ```
49
+ /plugin marketplace add kyle-chalmers/streamsnow
50
+ /plugin install streamsnow@streamsnow
51
+ ```
52
+ No publish step is required for the plugin — it's served from the public repo.
File without changes
@@ -0,0 +1,49 @@
1
+ # Deploy setup
2
+
3
+ StreamSnow scaffolds a `.github/workflows/deploy.yml` that ships your apps to
4
+ Snowflake on merge to `main`. It **skips automatically** until you set the
5
+ secrets below, so it never fails a normal merge before you're ready.
6
+
7
+ ## 1. One-time Snowflake objects
8
+
9
+ Generate and review the DDL for your configured deploy source, then run it once
10
+ with an admin (or the CI) role:
11
+
12
+ ```bash
13
+ streamsnow deploy-setup | less # review first
14
+ streamsnow deploy-setup | snow sql --stdin # or pipe to your admin session
15
+ ```
16
+
17
+ - **stage-copy** (default): creates the internal stage CI uploads to. Container
18
+ apps also need an account-level compute pool + external access integration
19
+ (admin, one-time — emitted as commented guidance).
20
+ - **git-repository**: creates the API integration, the secret holding a GitHub
21
+ token, and the `GIT REPOSITORY` object, and grants them to the CI role.
22
+
23
+ ## 2. CI auth (key-pair / JWT)
24
+
25
+ Create a key-pair for a dedicated CI user, register the public key on that
26
+ Snowflake user, and add these **repo secrets**:
27
+
28
+ | Secret | Value |
29
+ |---|---|
30
+ | `SNOWFLAKE_ACCOUNT` | account locator (e.g. `ab12345.us-east-1`) |
31
+ | `SNOWFLAKE_USER` | CI service user |
32
+ | `SNOWFLAKE_PRIVATE_KEY_RAW` | the PEM private key |
33
+ | `SNOWFLAKE_PRIVATE_KEY_PASSPHRASE` | (optional) key passphrase |
34
+ | `SNOWFLAKE_WAREHOUSE` | a warehouse the CI role can use |
35
+ | `SNOWFLAKE_ROLE` | your `ci_role` from `streamsnow.config.yaml` |
36
+
37
+ Once `SNOWFLAKE_ACCOUNT` is present, the deploy job runs on the next merge:
38
+ it uploads `apps/` to the SHA-versioned stage and runs `CREATE OR REPLACE
39
+ STREAMLIT` (via `streamsnow deploy-sql`) for each app.
40
+
41
+ ## git-repository note
42
+
43
+ The generated workflow targets the **stage-copy** path (CI pushes; Snowflake
44
+ never reaches out to GitHub — fewer moving parts, no network-policy dependency).
45
+ If you set `deploy.source: git-repository`, your CI must instead `snow git fetch`
46
+ the repository and Snowflake must be able to reach GitHub (or mint a GitHub-App
47
+ token into the secret). Use `streamsnow deploy-sql <slug>` for the create
48
+ statement and `streamsnow deploy-sql <slug> --refresh` for the
49
+ ABORT/PULL/COMMIT refresh of an existing app.
@@ -0,0 +1,26 @@
1
+ # Examples
2
+
3
+ StreamSnow doesn't check in a sample app — `streamsnow init` **generates** a
4
+ complete, working one for you (and the generated output is exercised in CI by
5
+ the `wheel-smoke` job, so it stays valid).
6
+
7
+ A freshly generated app looks like:
8
+
9
+ ```
10
+ apps/<slug>/
11
+ streamlit_app.py # st.navigation entrypoint, apply_branding()
12
+ pages/overview.py # branded metric + Plotly chart + a cached loader
13
+ queries/example_metric.sql
14
+ branding.py sql_loader.py
15
+ .streamlit/config.toml .streamlit/secrets.toml.example
16
+ snowflake.yml pyproject.toml (container) | environment.yml (warehouse)
17
+ AGENTS.md
18
+ ```
19
+
20
+ Generate and run one:
21
+
22
+ ```bash
23
+ uvx streamsnow init # setup wizard + scaffold
24
+ streamsnow validate-app <slug> # PASS/FAIL gate
25
+ streamsnow preview <slug> # run locally vs Snowflake
26
+ ```