Handoff report: git-stash-browser-tui¶
Stage: handoff_report (fulfill, build path)
Item: git-stash-browser-tui — Git stash browser TUI
Date: 2026-06-26
Overview¶
stash-browser is a keyboard-driven terminal UI (TUI) for browsing git stashes across local repositories. It scans one or more directories, finds every git repository with stashes, and presents them in a unified two-pane interface. Users can preview, apply, pop, and drop stashes without leaving the terminal.
The project was triaged as an app MVP opportunity (score 80/100), approved by Moere, and built through a 6-stage fulfillment pipeline.
Pipeline history¶
| Stage | Status | Key output |
|---|---|---|
| Triage | ✅ Completed | Score 80/100, route to build path |
| Human proposal | ✅ Approved | Discord proposal approved by Moere |
| App scaffold | ✅ Completed | Full project skeleton with TUI, git wrappers, scanner, CLI, tests |
| Implementation pass | ✅ Completed | Polished TUI, modal drop confirmation, cancellable preview workers, persistent cache, expanded tests |
| Verification pass | ✅ Completed | All 19 tests pass, CLI smoke tests, scope rail compliance, secret/security scan |
What was built¶
Technology¶
- Language: Python 3.11+
- TUI framework: Textual ≥0.47.0
- Build system: Hatchling (editable install)
- Dev dependencies: pytest ≥7.4.0, pytest-asyncio ≥0.21.0
- External dependencies:
git(subprocess calls only — no API tokens, no accounts, no network)
Architecture¶
stash-browser/
├── pyproject.toml
├── README.md
├── src/stash_browser/
│ ├── __init__.py # Package init
│ ├── __main__.py # python -m entry point
│ ├── cli.py # Argument parsing, config loading, app launch
│ ├── git.py # Subprocess wrappers for git stash operations
│ ├── models.py # Stash dataclass with age formatting, branch parsing
│ ├── persistence.py # Scan result cache (~/.cache/stash-browser/)
│ ├── scanner.py # Directory walking, repo discovery, stash enumeration
│ └── tui.py # Textual two-pane TUI with full key bindings
└── tests/
├── conftest.py
├── test_cli.py # --version, --help, --root validation, config loading
├── test_git.py # Git subprocess wrappers
├── test_persistence.py # Cache save/load/clear
├── test_scanner.py # Repo discovery, depth limits, skip lists
└── test_tui.py # Pilot-based key binding tests (nav, apply, pop, drop)
Features¶
| Feature | Status |
|---|---|
| Two-pane TUI layout (DataTable sidebar + Static preview) | ✅ Verified |
| Stash list populated from scanned repos | ✅ Verified |
| Modal drop confirmation (ConfirmDropScreen) | ✅ Verified |
| Apply, pop, drop actions with status notifications | ✅ Verified |
| Cancellable preview worker with 200-line cap | ✅ Verified |
| Persistent cache in ~/.cache/stash-browser/last_scan.json | ✅ Verified |
| CLI --version and --help | ✅ Verified |
| CLI --root validation (missing root exits with error) | ✅ Verified |
| Config file loading (TOML with roots + max_depth) | ✅ Verified |
| Keyboard shortcuts: ↑/↓/k/j/Enter/a/p/d/r/?/Esc/q | ✅ Verified |
Filter by substring (press /, type, Esc to clear) |
✅ Verified |
Rescan roots in-app (r key) |
✅ Verified |
Keyboard shortcuts¶
| Key | Action |
|---|---|
| ↑ / ↓ or k / j | Move selection |
| Enter | Refresh preview |
| a | Apply selected stash |
| p | Pop selected stash |
| d | Drop selected stash (confirm with d) |
| r | Rescan roots |
| / | Filter list by substring |
| Esc | Clear filter / cancel drop |
| ? | Show help |
| q | Quit |
How to use¶
Install¶
Run¶
# Scan current directory
stash-browser
# Scan specific roots
stash-browser --root ~/projects --root ~/work
# Use config file
stash-browser --config ~/.config/stash-browser/config.toml
Config file (~/.config/stash-browser/config.toml)¶
Verification¶
All 19 tests pass across all modules. CLI entry points work correctly. All documented keyboard bindings match README shortcuts.
Test breakdown¶
test_git.py— git subprocess wrappers (stash list, show, apply, pop, drop)test_scanner.py— repo discovery, depth limits, skip liststest_persistence.py— cache save/load/cleartest_cli.py— --version, --help, --root validation, config loadingtest_tui.py— Pilot-based navigation, table population, apply/pop/drop, drop-confirmed, drop-cancelled
Scope rail compliance¶
- ✅ No payment flows, OAuth, accounts, or external API calls
- ✅ Single-process, local-only tool — shells out to
gitonly - ✅ No new accounts or keys needed
- ✅ No committed .env files, tokens, API keys, or credentials
- ✅ MIT licensed
Known issues / limitations¶
-
Branch parsing fallback (minor): The
%brbranch fallback relies on default git stash message format (WIP on <branch>:/On <branch>:). Custom stash messages may show-for branch on older git versions. This is documented in the implementation report. -
Textual/LSP import warnings (cosmetic): Some editor environments report missing
textual.*imports for LSP, but runtime imports and all tests pass. No actual issue at runtime. -
MVP scope limitations (intentional): No remote/cloud sync, no multi-user, no stash editing/renaming, no advanced search beyond substring, no worktrees/submodules as first-class entities, no index/untracked stash preview, no background file watching, no GUI/web interface. These are documented in
README.md.
Handoff to downstream stages¶
For discord_update_post¶
Post a ticket update to Discord channel 1519423506641584188 covering:
- What was built: stash-browser — a Python + Textual TUI for browsing git stashes across local repos
- Key features: Two-pane layout, keyboard-driven, apply/pop/drop/preview, modal drop confirmation, persistent scan cache, config file support
- How to access: The workspace at /root/hermes-multi-agent-workflow/work/builds/git-stash-browser-tui — cd there, source .venv/bin/activate, run stash-browser --root ~/projects
- Notes for Moere: MVP is complete with 19 passing tests. All scope rails respected (no secrets, no external APIs, no payment/auth). Ready for use on the workstation. See known issues section above for the branch parsing quirk.
For publish_output¶
Publish a summary to outputs.emilsturzenegger.ch (build category):
- Title: "stash-browser — Git stash browser TUI"
- Content source: this handoff report or a trimmed summary
- Category: build
- Command: bash /srv/outputs.emilsturzenegger.ch/add-output-page.sh build "stash-browser — Git stash browser TUI" /root/hermes-multi-agent-workflow/work/builds/git-stash-browser-tui/reports/handoff_report.md
Source information¶
- Sources: StackOverflow (400+ upvotes, 300k+ views), lazygit feature request (45 thumbs up), HN anecdote (3 months of buried stashes)
- Score: 80/100 (expected_value=18, feasibility=18, evidence=17, urgency=9, strategic_fit=18)
- Proposal: Approved by Moere on Discord at 2026-06-26T12:51:23Z
- Workspace:
/root/hermes-multi-agent-workflow/work/builds/git-stash-browser-tui - Full reports in workspace:
reports/app_scaffold.mdreports/implementation_pass.mdreports/verification_pass.mdreports/handoff_report.md(this file)