agentleFS
kyle-chalmerskyle-chalmers/streamsnow/skills/migrate-app/SKILL.md

migrate-app

Skill17 starsChanged 32 days agoMITView on GitHub

Port an external Streamlit app into the repo in two reviewable steps — lift-and-shift into apps/<slug>/, then conform to repo conventions until validation passes. Use when the user says "migrate a streamlit app", "port this dashboard into the repo", "bring an external app in", or "modernize this dashboard".

The file

We split this skill into the rules it gives an agent

4 rules. About 0 are common, 1 is distinctive, and 3 are very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈1

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 3

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Distinctive:

    Commit the lift as one changeset.

    line 49
  2. Very specific:

    Spec it: follow build-app spec.md in backfill mode for apps/<slug>/REQUIREMENTS.md (pages, their questions, sources, TTLs, the runtime from …

    line 53
  3. Very specific:

    Keep imports app-local (from branding import ...): deployed, a repo-level shared/ is gone.

    line 59
  4. Very specific:

    Check snowflake.yml fits the runtime.

    line 68

≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

/migrate-app

Repo overlay: if .streamsnow/overlays/migrate-app.md exists in this repo, read it first — committed, repo-specific additions/overrides (_shared/overlays.md). Outside Claude Code, also read _shared/other-agents.md.

Bring an external Streamlit app into the repo, then conform it until the gates pass. Two commits — the lift (files relocated, only ship blockers scrubbed), then the conform diff — because mixing the move and the rewrite makes review impossible and kills your ability to bisect a misbehaving conform against the known-good lift.

This skill gets the app in; /build-app's phases make it good, so a migrated app meets the same bar as a new one; the gates (streamsnow validate-app, streamsnow sql-review check) decide "done".

Detection is streamsnow migrate <verb> — JSON out, deterministic, AST-only (never executes source). You read the JSON and make the judgment calls. Read engine.md before Step 1 — it documents every verb: when to run it, what its JSON says, the judgment call that follows.

Step 1 — lift-and-shift (get it in the tree)

  1. streamsnow doctor first; failures → /onboard before continuing.
  2. Settle <slug> (<domain>-<function>, kebab-case), then streamsnow migrate preflight <source> --target-slug <slug>. Exit 1 → stop and resolve with the user (abort_reason names it: target exists, not a Streamlit app, multiple entrypoints, or catastrophic deps that force a runtime conversation).
  3. streamsnow migrate graft-plan <source> and streamsnow migrate scan-imports <source> — the first says where the UI lands (pages/*, pages/overview.py, or streamlit_app.py, with the reason), the second names the subpackages that must be grafted whole so relative imports survive. Copy the source in accordingly; the one structural change is renaming the entrypoint to streamlit_app.py (not configurable). No refactoring yet.
  4. streamsnow migrate scan-hardfails <source> and clear every block before committing: denied-schema references re-pointed to governed equivalents (with the user — the mapping can't be guessed), hardcoded secrets out of .py (the user copies values by hand into gitignored secrets.toml; never read or commit a source secrets file — the scanner itself only presence-checks them). Re-run until exit 0.
  5. Dependencies: decide the runtime with the user per _shared/runtime-decision.md — it drives the manifest, connection pattern, and which packages even exist. Warehouse → streamsnow migrate translate-deps <source> --out apps/<slug>/environment.yml writes the conda manifest (walk dropped/unmapped/inferred_suggestions with the user — nothing is auto-added). Container → declare PyPI deps in pyproject.toml, using the same JSON as inventory.
  6. Commit the lift as one changeset.

Step 2 — conform (make it a StreamSnow app, the /build-app way)

  1. Spec it: follow build-app spec.md in backfill mode for apps/<slug>/REQUIREMENTS.md (pages, their questions, sources, TTLs, the runtime from step 5).
  2. Foundation: streamsnow new the same slug and runtime in a scratch repo; copy in every file the lift lacks (snowflake.yml, branding.py, sql_loader.py, review.py, pages/_*.py, pages/about.py, sql_review/), never over a source file; drop its starter page and query (pages.md). Then scaffold.md § Foundation. Keep imports app-local (from branding import ...): deployed, a repo-level shared/ is gone.
  3. Conform the pages: pages.md § Parallel build with each page-builder in mode: conform (keep the visuals and behavior, apply the conventions). Its worklist is the JSON of streamsnow migrate scan-conformance apps/<slug> and streamsnow migrate scan-inline-sql apps/<slug>, split by file. Migrate-only items (engine.md): pin columns for each SELECT *, swap altair_imports to the repo chart standard, rebuild navigation with st.navigation if legacy_pages_only, and put the required_grants needing a DBA in the PR. Walk each query's Feeds/Schemas with the user; plumbing SQL stays inline with # noqa: inline-sql.
  4. Check snowflake.yml fits the runtime; scrub personal absolute paths. As /build-app does, rewrite the app AGENTS.md starter Pages and Queries lines (with non-default TTLs and the runtime) and add the README Apps row (title, apps/<slug>/), or starter-text warns.
  5. Verify: build-app verify.md, then the user clicks through every page in /preview-app; a warehouse app failing locally on get_active_session is not a bug.
  6. Gate: streamsnow validate-app <slug> PASS, streamsnow sql-review check <slug> clean, and both conform scans' fix-lists empty. Then commit the conform as its own changeset. A deploy error you can't place → _shared/deploy-error-translator.md.

Hand-offs

PASS → /ship-app opens the PR (first-time accounts may need one-time streamsnow deploy-setup DDL); deeper quality → /review-app + /sql-review; an app already in the repo → Step 2 only; later changes → /build-app <slug> or /build-app <slug> --feedback "...".

Done when

streamsnow validate-app <slug> passes, streamsnow sql-review check <slug> is clean, the two conform scans report nothing to fix, REQUIREMENTS.md describes the app, and the lift and conform are two separate commits.

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.