Structured controls on the left, your real shell config — live — on the right. Nothing ever touches disk until you've seen the diff. Built for developers who trust their tools.
┌──────────────────────────────────────────────────────────────────────┐
│ ◉ ◉ ◉ ~/.zshrc ● 172 lines ⌘K Backups Review & Save…│
├───────────────────────────────────┬────────────────────────────────────┤
│ Filter blocks… [All|Aliases|…] │ source Live ▾ │
│ ▾ ALIASES 11 + │ 1 #!/usr/bin/env zsh │
│ cc = claude --dangerously… ● │ 2 │
│ sz = source ~/.zshrc ● │ 3 # aliases │
│ ▾ PATH + │ 4 alias cc="claude --danger…" │
│ $HOME/.local/bin │ 5 alias sz="source ~/.zshrc" │
│ 🔒 $path[@] · inherited │ … │
├───────────────────────────────────┴────────────────────────────────────┤
│ ● Saved · ~/.zshrc · 61 blocks · backup 4m ago Discard │
└──────────────────────────────────────────────────────────────────────┘
💡 Live at seashell.cuzeacflorin.fr. The source is in
landing/— a small Vite + React app (minimalist, all‑lowercase, Geist Pixel Square). Run it withcd landing && pnpm install && pnpm dev, orpnpm buildfor static output inlanding/dist/.
Your ~/.zshrc boots your entire shell. Editing it by hand is fiddly and a single
unbalanced quote can break every new terminal. seashell gives you friendly,
structured controls for the things that map cleanly (aliases, exports, PATH,
options, keybindings) and honest code editing for the things that don't
(functions, eval inits, plugin blocks) — while keeping the real file visible
at all times and guaranteeing it never gets corrupted.
- 🪟 Two‑pane editor — structured controls on the left, the live, syntax‑highlighted file on the right. Click a control and watch the exact lines settle into the source.
- 🧩 The right editor per kind — opaque inline fields for aliases & exports (pipes and quotes kept literal, never re‑escaped), removable chips for
setopt, chord + widget forbindkey, a reorderable PATH editor with a locked$path[@]sentinel, and a dignified summary‑row + scoped code editor for functions /eval/ plugin blocks. - 🔍 Mandatory diff before save — a real diff of on‑disk bytes vs. your edits, hunks labelled by your file's own section comments. Nothing is written until you confirm.
- ✅
zsh -nsyntax check — every save is validated byzshitself first, so you can't write a config that breaks your shell. - 🕒 Automatic backups & restore — every save snapshots your file to
~/.zshrc.backups/first. Browse, diff and restore any backup — and restore is itself reversible. - 🔀 Enable / disable as a comment toggle — flip any block on/off; disabling comments its exact lines (and re‑enabling is byte‑identical).
- ⌘K command palette — fuzzy jump to any block, add aliases/exports, restore backups, open in your editor, and more.
- 📋 Copy diff / copy file, Open in Zed, Reveal in Finder.
- 🐚 Menu‑bar tray + global shortcut — summon or hide the window from anywhere with
⌘⌥Z; the app lives quietly in your menu bar. - 👀 Live external‑change detection — if
~/.zshrcchanges on disk under you, seashell tells you. - 🎨 Calm, native‑mac design — one restrained green accent, hairline borders, Geist for UI + mono, Phosphor icons, first‑class dark and light.
Safety isn't a feature here, it's the architecture:
- Byte‑exact round‑trip. The parser captures every original line into exactly one block. Untouched blocks are re‑emitted verbatim — only the blocks you actually edit are regenerated.
serialize(parse(file)) === file, byte for byte. This is enforced by a test suite that runs against a real 172‑line.zshrc. - Atomic, symlink‑aware writes. Saves go to a temp file, get
fsync'd, preserve the original file mode, thenrename()over the target — a crash can never leave a half‑written config. If~/.zshrcis a symlink (stow / chezmoi / yadm…), seashell writes through to the real target instead of clobbering the link. - Automatic backups. The current file is copied to
~/.zshrc.backups/before every write, so any change is reversible. - Graceful fallback. If the parser ever encounters something it can't safely model, it drops to whole‑file (source‑only) editing — your bytes are preserved, no exceptions.
Grab the latest .dmg from the Releases page, open it, and drag seashell to Applications.
On first launch, right‑click the app → Open (it isn't notarized yet, so Gatekeeper will ask).
Prerequisites: Rust (stable), Node ≥ 22.13, and pnpm ≥ 11.
git clone https://github.com/envindavsorg/seashell.git
cd seashell
pnpm install
pnpm tauri dev # run the app in development
pnpm tauri build # produce a .dmg / .app in src-tauri/target/release/bundle/| Shortcut | Action |
|---|---|
⌘S |
Review & Save (open the diff) |
⌘K |
Command palette |
⌘D |
Toggle source view: Live ↔ On disk |
⌘Z |
Undo |
⌘F |
Focus the block filter |
⌘⌥Z |
Global: summon / hide the window |
↩ |
Edit the focused block |
The window's close button hides seashell to the menu bar (it's a resident app).
⌘Q or the tray's Quit exits for real.
seashell is a Tauri 2 app — a Rust core and a React webview talking over an IPC bridge, with a strict division of labour:
- Rust (
src-tauri/) does only the safety‑critical I/O: read, atomic write + backup, restore, and thezsh -nvalidation. It holds no parsing logic. - TypeScript (
src/lib/zshrc/) owns the round‑trip‑safe parser, serializer and diff — a single, unit‑tested source of truth for the data model. - React (
src/components/zshrc/) is the two‑pane UI, styled with Tailwind v4 + shadcn/ui.
Tauri 2 · Rust · React 19 · TypeScript · Vite · Tailwind v4 · shadcn/ui · Geist · Phosphor Icons · pnpm
pnpm tauri dev # the real desktop app (Rust + webview)
pnpm dev # frontend only, in a browser at :1420 (invoke() will fail)
pnpm build # typecheck + bundle the frontend
pnpm check # Biome: lint + format (writes fixes)
pnpm test # parser round-trip suite (uses ~/.zshrc, else a checked-in fixture)
# from src-tauri/
cargo clippy # lint the Rust backend
cargo fmt # formatpnpm test reads your real ~/.zshrc when present, otherwise scripts/fixtures/sample.zshrc
(override with ZSHRC_FIXTURE=path or a CLI arg). Lint, typecheck, the test, clippy and fmt
all run in CI (.github/workflows/ci.yml).
If you touch src/lib/zshrc/parser.ts, always re‑run pnpm test — it's the guardrail for
the cardinal rule (byte‑exact round‑trip, reversible toggles, isolated edits).
MIT © Cuzeac Florin