| name | sh-snippet-vault-architecture |
| description | Use this skill when working in the sh-snippet-vault repo and you need the correct mental model, file map, architectural boundaries, and safe validation workflow for the Rust TUI + CLI application. |
| metadata | {"skill_type":"architecture","framework":"rust","framework_version":"stable","scope":"repository","topics":["rust","ratatui","sqlite","nix","terminal-ui"]} |
sh-snippet-vault Architecture
Use this skill for tasks that change, review, or explain the sh-snippet-vault repository.
Start from this mental model:
- The repo is a Rust application with both a TUI and CLI surface.
- The TUI is for interactive browsing and editing; the CLI is for scripted import, export, search, and maintenance workflows.
- SQLite is the source of truth for snippet data.
- Nix provides the reproducible developer environment and standard quality commands.
Architectural goals
- Keep the code small, readable, and safe for agent-driven iteration.
- Preserve a clear split between domain logic, storage, TUI state, and CLI flows.
- Avoid coupling UI concerns directly to SQL or persistence details.
- Make it easy to add features without turning the app into a ball of stateful glue.
Default file map
Cargo.toml — workspace metadata and member wiring
crates/sh-snippet-vault/Cargo.toml — application crate dependencies and package metadata
flake.nix — Nix development environment and common repo commands
justfile — common validation and development shortcuts
crates/sh-snippet-vault/src/main.rs — startup and top-level app selection
crates/sh-snippet-vault/src/cli/ — non-interactive commands such as search, import, export, or maintenance
crates/sh-snippet-vault/src/app/ — TUI event loop, state, rendering, keybindings, and interaction flows
crates/sh-snippet-vault/src/domain/ — snippet types, validation, tags, shell metadata, and pure business rules
crates/sh-snippet-vault/src/storage/ — SQLite access, repositories, queries, and migrations integration
migrations/ — schema creation and forward-only database changes
examples/ or sample-data/ — realistic seed snippets for local testing
For deeper detail, read:
references/file-map.md
references/validation-workflow.md
Ownership boundaries
Keep in crates/sh-snippet-vault/src/domain/
Snippet and related entities
- validation rules
- shell-type enums or identifiers
- placeholder, note, and tag rules
- pure transformations that do not need I/O
Keep in crates/sh-snippet-vault/src/storage/
- schema access
- SQLite connection setup
- repository interfaces and concrete implementations
- query logic
- transactional behavior
Do not let raw SQL leak across the codebase. Prefer one storage boundary that the TUI and CLI both consume.
Keep in crates/sh-snippet-vault/src/app/
- screen/view state
- focus and selection state
- keyboard navigation
- modal and editor workflows
- rendering and event handling
Keep the TUI thin: it should orchestrate domain and storage behavior, not own business rules or duplicate validation.
Keep in crates/sh-snippet-vault/src/cli/
- import/export flows
- search/list output for scripting
- maintenance commands such as database setup or sample-data loading
The CLI should reuse the same domain and storage boundaries as the TUI instead of inventing a second logic path.
Data model expectations
The first version should keep the data model boring and explicit:
- snippet title
- shell target (
sh, bash, zsh)
- snippet body
- tags
- notes
- optional usage hints or explanation
- created/updated timestamps if useful
Do not over-design plugin systems, sync layers, cloud accounts, or multi-user abstractions in the MVP.
TUI design guardrails
- Prefer a few stable screens over many clever modes.
- Make the main list + detail flow fast and obvious.
- Keep keybindings discoverable.
- Treat editing flows as state machines, not ad hoc booleans spread across rendering code.
- Avoid
useEffect-style architecture drift in Rust equivalents: do not hide important state transitions behind unrelated rendering helpers.
SQLite guardrails
- Keep schema ownership explicit in
migrations/.
- Prefer parameterized queries and typed mapping over stringly-typed helpers.
- Keep write flows transactional where partial state would be dangerous.
- If search grows more complex, isolate the search strategy inside storage instead of scattering query logic into the TUI and CLI.
Nix and validation workflow
Use the least risky command that proves the change is correct:
nix develop
just fmt-check
just lint
just test
When packaging or repo wiring changes:
nix flake check
Working style for future agents
When touching this repo:
- Identify whether the change belongs in domain, storage, TUI, CLI, or Nix wiring.
- Preserve the single source of truth for snippet validation and persistence.
- Keep TUI and CLI behavior consistent by reusing the same core logic.
- Prefer adding small, testable boundaries over spreading ad hoc helpers across modules.
- Update docs or repo-local skills if the architecture becomes hard to rediscover.