v0.1.0
Changelog
Features
- e407e72 feat(browse): fold unpriced into a three-table watches screen
- c12930a feat(browse): re-read on a neighbour's writes, and make r keep its place
- d2923d5 feat(browse): scroll the detail overlay with the wheel
- 02f498f feat(browse): the collection pane filters views
- 57ab37e feat(deck): add --dry-run to deck add
- d77488e feat(detail): bid history, spread-over-time, and per-card comps
- 59c2b31 feat(export): add --format text so a deck can come home
- f2541c3 feat(ios): let any tier be silent
- f8d2f31 feat(json): binders, guessed, and the percentage movers already showed
- 5c17301 feat(json): carry card facts, and set the schema baseline at 1.0.0
- b1bb072 feat(market): the comp sheet as a fourth table
- b35d7ac feat(prices): refuse a market price its own asks contradict
- 4eee266 feat(scan): port the phone link into Go
- 1eaeb58 feat(ui): WUBRG identity bubbles up from the data
- 04f5b3e feat(ui): WUBRG identity palette; NO_COLOR
- 6669598 feat(ui): card images on by default
- 0a59396 feat(ui): identity treatment
- ac139cf feat(ui): trim help to the command tables
- e6e3ad5 feat(ui): vocabulary
- 75a6c9d feat(watch): alert on a percentage move, anchored to a trailing high
- 1e5bd68 feat(watch): read import from stdin, and allow a band on add
- 4713c91 feat(watch): watch the printing you own, and make standing watches readable
- 146d04d feat: --json documents with schema
- 4d2c086 feat: MARKET palette and container filters
- 3ce76ed feat: TCGplayer CSV ingest for price history
- fbca0d5 feat: TLS with TOFU pinning for the scan link
- 5ee672c feat: add-flow command palette
- 6d6a136 feat: add-flow destination picker
- 6fade8b feat: add-session exit and pending scan queue (#9)
- 2ff7ed5 feat: all-cards list, guarded add exits, palette
- 891c823 feat: anchor the marker search on the copyright
- 85116cf feat: arbitrage command surfacing vendor prices
- dee48e6 feat: art index with pHash and a footprint cache
- 4fc5215 feat: browse by set, held-row editing
- 52d1ab2 feat: browse interop help and operation state
- 1c7c7dc feat: bulk paste entry — add --file, stdin, and --binder
- 62803e3 feat: bulk watch list import
- 0c4ba93 feat: buylist view as an inverted market table
- 86d4687 feat: card detail pane and browse view polish
- 1aa49ae feat: card image aspect and detail layout
- 5eb1e38 feat: carry a condition through import and export
- c1970a4 feat: chime per processed card; view-ranked palette
- c2864c3 feat: command palette and a single registry for browser actions
- ee0fa85 feat: deck containers and bulk import
- bf481fc feat: edit a holding's condition
- bf707aa feat: edit and delete cards from the set view
- 615b161 feat: embed the add cascade
- 3d57a17 feat: etched gets its own price
- 574bac5 feat: gradient theming for movers and comps
- 89bb6d0 feat: handheld scan view driven from the phone
- b40e59a feat: hands-free scanning
- b45582b feat: held-row editing and market table trims
- 61d225a feat: hoard export (canonical CSV, Moxfield, Archidekt)
- 53b803c feat: hoard import (ManaBox, Moxfield, Delver Lens, hoard CSV)
- 3877745 feat: hoard list sorting; mtgjson storage design doc
- d9b26b1 feat: hoard report; dated valuation formats
- 5884b35 feat: hoard watch — price alerts that fire
- 912d3d8 feat: iPhone capture app with CardKit, ScanLink, and ScanWire
- 1eea727 feat: import ledger and a round-trippable CSV
- 47dde52 feat: in-TUI add, interop, and operation confirmations
- 470b154 feat: initial CLI for cataloging a collection
- 379c5b7 feat: know a new card from a second look at the old one
- cb8817c feat: land summary impact coloring
- 59ea0d4 feat: let the capture receipt scroll back through the session
- d45fa7e feat: list the collection one row per finish
- 4b7b987 feat: long-running operations run inside the tui
- f640c13 feat: market comps in browse
- 30d2f27 feat: market settings and TCG price plumbing
- 9eadabf feat: market table sorting and browse row editing
- 8fec3e9 feat: merge command (#10)
- 4aff813 feat: movers report from price history
- 8779bed feat: multi-card scanning
- 692ecd2 feat: multiple named binders
- aaf8d03 feat: old-frame title/number arbitration; new scan fixtures
- e30f141 feat: open card detail from unpriced
- bcdaefa feat: pHash art index
- 24f8be7 feat: palette curation, gradients, pane updates
- d04db35 feat: per-finish foil pricing
- dcb7832 feat: per-tier scan sounds and a settings screen
- 634f93d feat: persistent add mode and per-user db location
- 5837947 feat: price fallbacks, schema migrations, and collector-number scanning
- 397ec18 feat: price history schema migration
- 95f1753 feat: printings, pricing, and browse fixes from a feedback session
- 1c0439e feat: progress contract, CLI renderer, and graceful interrupts
- d935e57 feat: raise the capture ceiling to 1920x1440, pin Vision's revision
- 55da04d feat: read old-frame white borders
- f9b554d feat: read pre-collector-number frames
- d379a88 feat: read the old-frame foil marker
- 4f3d03a feat: read the printed language
- 9a1282b feat: renameable default binder
- 1fcf893 feat: risers and sinkers in collection
- de5efa8 feat: scan cards with an iPhone camera
- 32ea50b feat: scanner trigger tuning and a rules-quote title fixture
- feec096 feat: scene signature and trigger tuning for the phone
- c895933 feat: search TUI
- ce914b2 feat: sparkle foil detection and schema v24
- 078db6f feat: trim the CLI surface and polish the scanner
- 278b330 feat: two-pane browser TUI and a local Scryfall card catalog
- 03f2e92 feat: ui table and formatting layer behind summary
- 8e647de feat: update the all-cards list; first-run catalog
- 5bc2fd2 feat: value snapshots and a hoard-value sparkline
- 8176927 feat: watch-this-card everywhere
- b7fcc4b feat: watches view, fired banner
Fixes
- 178df10 fix(browse): make / filter the market view
- 65788cf fix(browse): make / filter the movers view
- 2d83f53 fix(browse): report the deck lines the browser could not read
- fe56903 fix(browse): report the losses update-prices and backfill were hiding
- 1117d90 fix(ci): stop pinning oras in the shared toolchain
- 892e16a fix(cli): keep help inside a narrow terminal
- e84ac14 fix(cli): refuse a repeated export scope, and an unknown import format
- 527b061 fix(cli): show global flags in help, and ship the schema
- 29fd302 fix(cli): stop deck restores from looking clean when lines were skipped
- d82961c fix(decksource): read Archidekt and Deckstats text exports as exported
- 5fd41c1 fix(import): check the binder before resolving
- a06c562 fix(import): refuse a CSV row longer than its header
- 8cbe12e fix(install): anchor the checksum lookup to the whole filename
- 887cf4b fix(ios): drop the pairing code from the waiting status
- ad04f0d fix(ios): keep advertising when a session ends
- ff5a62d fix(ios): read the team identifier from the certificate OU
- 1b2bb4f fix(ios): restart the listener when the advertisement dies
- 80eb760 fix(json): stop reporting colorless cards as -
- 3855cc8 fix(json): stop three types claiming a card's colour is unknown
- eb92db6 fix(market): stop inventing an etched sheet for printings without one
- 16c7fba fix(movers): a window is a range, not a precondition
- d9a0123 fix(scan): delete the pairing guess, route on the sentinel instead
- 90e78cd fix(scan): keep a phone-offered second-copy slot past the next card
- e77f96c fix(scan): keep the error sentinel that friendly() was throwing away
- 6639e9f fix(scan): pin the collector-block rescue at compile time
- ad32ac4 fix(store): repair two comments gofmt had corrupted, and guard the rest
- 534d581 fix(ui): agree the count
- 9b0d25d fix: All Cards view and help text
- 2957934 fix: MARKET consistency + holdings cursor; lock in scanner HUD sounds
- b2301ea fix: a stalled MTGJSON download fails
- 998cf1d fix: allow bottom location to be read
- 04791ad fix: browse status line text
- e242a2a fix: clear the pre-launch audit red list
- 545e60b fix: container filtering and holdings counts in browse
- b0a4519 fix: count a sliver growing back into the whole card as stillness
- 383c34d fix: filters on MARKET view
- 07ee8a9 fix: name the cards pane when the collection is empty
- 7c4c681 fix: network edge resilience and clear output
- d4cce89 fix: only comp vendor prices we can tie to the held product
- cf80b40 fix: pin the card signature's sampling window to the shutter's geometry
- e1e44ec fix: price aggregation blips
- 2009ef1 fix: reject flavor-text attributions
- d82750f fix: release fix syft
- 4b7ecb2 fix: say what movers counted, and let the guess queue reach zero
- 43ff841 fix: scan drain race, cache fallback, quote order; dedupe shared rules
- e7b0fa0 fix: scanner HUD and capture presentation
- a393ba4 fix: scanner drops lingering re-sightings
- 4296be9 fix: sort every browse view by its own columns, S reverses
- f0d695b fix: stacked-card trigger and wire framing
- 4280a02 fix: store forward-compat, backup ordering, atomic import writes
- 08e36fe fix: tie opportunity rows to the held product
- feb2e5d fix: update make and Taskfile
Other changes
- 432d81c build(scan): publish fixture frames to ghcr, pinned by digest
- 53ce775 build: binny, Taskfile, goreleaser, and install.sh
- 6ee1c4b chore(deps): Bump github.com/santhosh-tekuri/jsonschema/v6
- 5fdf5cd chore(deps): update Go modules and GitHub Actions
- 700b8de ci: codeql, lint, and release workflow fixes
- 446b5be ci: disable macOS scan workflow until runner budget allows
- 49a23ac ci: fix the main workflows
- a96b38a ci: rename the default branch to main
- 00a2c3c ci: scan fixtures path-filtered macOS workflow
- b9a0e7b ci: workflows
- fc43c39 demo: demo and docs
- 2175647 perf(scan): end discovery at the answer, not the deadline
- 91084d7 perf: serve same-day arbitrage quotes from a filtered day-cache
- 2cd6192 refactor!: rename arbitrage to market
- d85f4bb refactor!: rename finish 'normal' to 'nonfoil'
- e55bfee refactor(catalog): drop the image_uri column
- ca584c7 refactor(cli): finish the cobra migration and move to cmd/hoard
- 978df2b refactor(json): one CardDetail, and Enriched as the only presence signal
- 436c5b5 refactor(scan): delete the macOS scan helper
- 87ada24 refactor(watch): drop the ID column from watch list
- 06e057b refactor: add fast reads to action layer
- 22772de refactor: backfill joins the action layer
- 64b03bc refactor: browse input dispatch derives from enum
- 51d0766 refactor: collapse repeated patterns and shrink interfaces
- 0cf8e5e refactor: delete the art-identification index
- bda8de2 refactor: demo and image icons
- d5a29be refactor: extract card resolution; stderr and exit-code discipline
- 25b6b18 refactor: move arbitrage to action layer
- 7c6edce refactor: move catalog operations into the action layer
- 6fd83c2 refactor: move every add path into the action layer
- dd74bb3 refactor: move import into the action layer
- cbd165c refactor: move repair-finishes to the action layer
- 9f3b2c8 refactor: move update-prices into the action layer
- 493c1ed refactor: rename module to hoard
- 93fc1c8 refactor: retire ScanKit; CardKit becomes the sole reader
- b87d0d3 refactor: split store.go and main.go; extract internal/report
- 162c977 refactor: split the scanner into ScanKit with tests
Verification:
cosign verify-blob \
--bundle checksums.txt.sigstore.json \
--certificate-identity-regexp "^https://github.com/spiffcs/hoard/.*" \
--certificate-oidc-issuer "https://token.actions.githubusercontent.com" \
checksums.txt