| cmd | ||
| doc | ||
| internal | ||
| scripts | ||
| .envrc | ||
| .fast-commit.toml | ||
| .gitignore | ||
| AGENTS.md | ||
| ARCHITECTURE.md | ||
| CODE_STYLE.md | ||
| devenv.lock | ||
| devenv.nix | ||
| devenv.yaml | ||
| flake.lock | ||
| flake.nix | ||
| go.mod | ||
| go.sum | ||
| LICENSE.txt | ||
| main.go | ||
| README.md | ||
Taplands
Local-first CLI/TUI app for Magic: The Gathering card browsing, deck building, and collection management.
Taplands is built with:
- Go + Cobra (CLI)
- Bubble Tea + Bubbles + Lip Gloss (TUI)
- SQLite (MTGJSON source DBs + user data DB)
Current Status
Implemented right now:
- First-run initialization flow with confirmation + installer TUI
- Concurrent MTGJSON DB download/extract
- Main menu + full-screen alt-screen TUI
- Cards view with side-by-side list/detail, search modes (standard/fuzzy/syntax), scrolling
- Multi-select card workflow in Cards (
space, quantity withh/l) - Add selected cards to collections/decks from Cards (
a/d) - Quick add to last-used collection/deck (
A/D) - Collections and Decks two-step flow:
- enter on list
- left pane card list + right pane card detail
- CLI deck/collection create + import flow from text files
Install and Run
Nix (recommended)
Run directly:
nix run .
Install into profile:
nix profile add .
From remote repo:
nix run github:<owner>/<repo>
nix profile add github:<owner>/<repo>
Go
go run .
First Run Initialization
On first taplands start, Taplands checks local card DBs and (if missing) asks for confirmation, then downloads and extracts:
https://mtgjson.com/api/v5/AllPrintings.sqlite.xzhttps://mtgjson.com/api/v5/AllPricesToday.sqlite.xz
You can also run init explicitly:
taplands init
Data Paths
- Linux:
~/.local/share/taplands - macOS:
~/Library/Application Support/taplands
Layout:
taplands/
cards/
AllPrintings.sqlite
AllPricesToday.sqlite
cache/
user/
user-data.sqlite
state/
init-state.json
CLI Commands
Top-level:
taplands inittaplands db updatetaplands import ...taplands export ...taplands deck create <name>taplands collection create <name>
Import to Deck/Collection
taplands import deck <id-or-name> -i file.txt
taplands import collection <id-or-name> -i file.txt
Non-interactive mode:
taplands import deck <id-or-name> -i file.txt --yes
taplands import collection <id-or-name> -i file.txt --yes
Import behavior:
- If target deck/collection does not exist, Taplands asks to create it first.
- Prints summary (
x out of x cards found, not found list, planned import count). - Asks confirmation unless
--yesis provided. - Uses strict matching when set/collector/foil details are present.
- Falls back to best name match when details are omitted.
Import File Format
Format:
[qty][x] CardName [(set)] [cardnumber] [foil identifier]
Notes:
qtyoptional, defaults to1xoptional (4xor4are both valid)- foil identifier is
*F* - set is written like
(BLB)
Examples:
Example Card
1 Example Card *F*
4x Example Card
4x Example Card (BLB)
4 Example Card 543 *F*
1x Example Card (set) 123 *F*
1 Example Card 123
Export
taplands export deck <deck-id-or-name> --format deck
TUI Key Highlights
Global/common:
qquitescback- arrows +
j/knavigate
Cards view:
/searchtabcycle search mode forward (fuzzy -> standard -> syntax)shift+tabcycle search mode backwardspaceselect/unselect cardh/ldecrease/increase quantity for selected cardcclear selected cardsaadd selected/current card(s) to collectiondadd selected/current card(s) to deckAquick add to last-used collectionDquick add to last-used deck
Syntax Search
Taplands syntax mode is inspired by Scryfall's search language:
- Reference: https://scryfall.com/docs/syntax
Supported right now (phase 1 subset):
- Boolean logic: implicit
AND,or, parentheses, negation with- - Exact names:
!nameand!"quoted name" - Keywords:
c:/color:,id:/identity:,t:/type:,o:/oracle:,kw:/keyword:,m:/mana:,mv:/manavalue: - Stats:
pow:/power:,tou:/toughness:,loy:/loyalty:,pt:/powtou: - Print metadata:
r:/rarity:,s:/set:/e:/edition:,cn:/number: - Legality:
f:/format:,banned:,restricted: - Extras:
a:/artist:,ft:/flavor:,wm:/watermark:,produces: - Flags:
is:andnot:for common flags likereprint,reserved,funny,promo,full,foil,nonfoil,digital,commander,hybrid,phyrexian
Not supported yet:
- Regex search syntax (
/.../) - Price filters (
usd:,eur:,tix:and numeric price comparisons) - Cube/tagger/search-display operators (
cube:,art:,function:,display:,order:,unique:,prefer:) - Full Scryfall historical/reprint operators (
new:,in:,prints=,sets=and related variants) - Date/year operators (
date:,year:) - Full advanced mana semantics (
devotion:, completem>cost superset semantics)
Development
Devenv
Enter dev shell:
devenv shell
Useful scripts:
generate-jet-> regenerates Jet code from local SQLite DB filescheck-flake-hash-> runsnix build .#taplands --no-link
Flake Vendor Hash Hook
Devenv git hook checks flake vendor hash only when staged files include:
flake.nixflake.lockgo.modgo.sum
This keeps commit-time checks fast while still guarding Nix package integrity when dependencies change.
Roadmap (Short)
- Better import throughput and optional benchmark output
- Deck/collection card edit/remove operations
- Richer card detail rendering and prices/legalities polish
- More export/import formats