Lab note #1

stock-tui: building a stock market heatmap for the terminal

A mouse-first Rust TUI inspired by StockTouch, shaped through 75 rounds of prompts, screenshots, tests, and corrections, then shipped through package managers.

View on GitHub Watch the build video
A 14.6-second v0.3.0 walkthrough from the nine-sector overview to sector and ticker views; the interface remains representative of v0.3.2.

The seed was simple: what if the old StockTouch market map lived inside a terminal? Not a trading app, and not a spreadsheet with ANSI colors – a dense, mouse-friendly view you could scan, open, and explore without leaving the shell.

The idea

A favorite old interface, moved sideways

StockTouch arranged the market as a wall of red and green tiles. stock-tui keeps that visual model but changes the medium: a 3×3 overview of nine economic sectors, up to 100 companies inside each sector, then a ticker screen with price, volume, statistics, and news.

“Represent stocks as color-coded rectangles, moving from bright red through dark red and neutral gray to dark green and bright green.”

From the first prompt to Codex

The opening prompt was broad, but it was not vague. It named the interaction model, screen hierarchy, visual scale, cache, likely data provider, mouse support, and the shape of a future backend. That gave Codex room to make implementation choices without asking it to invent the product.

The build loop

The first prompt made a program. Feedback made the product.

The first commit already contained the end-to-end skeleton. The useful work happened afterward: run it, notice something odd, describe the evidence, let the agent inspect it, and keep the correction small enough to verify. The repository now records 75 prompt notes through the v0.3.2 package-manager release, including trusted crates.io publishing and first-party Homebrew delivery.

  1. 1

    Choose the medium

    A follow-up challenged the initial language choice: Rust or Go instead of Python? Rust won because Ratatui offered precise cell and canvas rendering, Tokio handled background sync, and bundled SQLite kept distribution to one native binary.

  2. 2

    Replace obvious fakes

    The first demo exposed synthetic ticker IDs and suspicious alternating gains and losses. The next pass kept simulated values but paired them with real SEC-catalog issuer identities and independent seeded returns. Demo data became useful without pretending to be live.

  3. 3

    Debug the terminal, not an abstraction

    Mouse reports, Braille chart guides, font fallback, and delayed input all behaved differently inside a browser terminal. Screenshots and exact symptoms led to SGR mouse support, terminal-stable guide glyphs, contrast tests, and a shutdown sequence that drains input before returning to the shell.

  4. 4

    Let constraints change the architecture

    A shared no-key market-data proxy sounded convenient. Provider terms made public redistribution unsafe, so the live path stayed bring-your-own Alpaca credentials. Cloudflare R2 serves only the independently derived SEC issuer catalog; prices and news stay behind the user's chosen provider.

  5. 5

    Make background work earn its requests

    A traffic audit found that an idle client refreshed far more than its visible screen required. Version 0.3.1 limits the five-minute cadence to current sector members, benchmark proxies, and favorites, and pauses it when the terminal forwards lost focus. Startup, catalog reconciliation, and explicit refreshes retain the broader discovery path.

  6. 6

    Treat installation as part of the release

    Version 0.3.2 added crates.io, a maintained Homebrew tap, and native Debian packages. The work included clean installation checks, Intel and Apple Silicon validation, pinned artifact digests, and publishing paths that stop before their own publication when release identity or provenance does not match.

Under the hood

One native client, several deliberately narrow boundaries

Interface

  • Rust 2024 for the client
  • Ratatui for layout and cell rendering
  • Crossterm for mouse, keyboard, resize, and terminal cleanup

Runtime & storage

  • Tokio for background provider work
  • SQLite via bundled rusqlite
  • Reqwest + rustls for provider and catalog requests

Data & delivery

  • Alpaca for BYO-key prices, bars, assets, and news
  • SEC JSON/XBRL for issuer, classification, and share-estimate data
  • Wikidata for conservatively matched CC0 company context
  • Cloudflare R2 for the small public catalog
  • GitHub Actions for five native archives, two Debian packages, crates.io, and Homebrew delivery
Shipping it

The install path became part of the product

The v0.3.2 release has five checksummed platform archives and local amd64 and arm64 Debian packages. The macOS binaries cover Intel and Apple Silicon, use the hardened runtime, and are signed and accepted by Apple's notary service.

Install routes

  • A maintained Homebrew tap for macOS and Linux
  • A published crates.io package for Rust users
  • GitHub release downloads for standalone and local Debian installs

Platform coverage

  • Signed and notarized Intel and Apple Silicon macOS archives
  • Static x86_64 and ARM64 Linux archives plus two Debian packages
  • A Windows x86_64 archive

Release gates

  • Checksums plus installation or executable smoke tests across every package format
  • Short-lived GitHub OIDC credentials for crates.io publishing
  • Verified Homebrew assets and three-platform validation before formula updates
Working with Codex

Specific observations beat impressive prompts

The sessions ran through chatcode.dev, but the platform was mostly the workbench: a persistent browser terminal where Codex could inspect the repository, run tests, and continue after the laptop closed. More interestingly, that environment surfaced real xterm and browser-font behavior that a local mock would have missed.

  • Point at evidence. “The cursor drifts farther to the right” was more actionable than “the chart looks wrong.”
  • Ask for the trade-off. The Rust-or-Go question produced a decision the repository could explain, not just a language switch.
  • Keep judgment human. Licensing, visual taste, security boundaries, and what counts as honest demo data still needed explicit choices.
  • Turn a fix into a guardrail. Rendering bugs became tests; ambiguous SEC share structures became fail-closed catalog rules.

You do not need to arrive with a perfect specification. A concrete first picture and the confidence to say “that is not what I meant” are enough to start. The project became precise one observation at a time.

Try the experiment

Install it, then choose demo or live data

The quickest route on macOS or Linux is Homebrew. The deterministic offline demo needs no account or market-data key, generates simulated prices for 900 real SEC-catalog issuer identities, and labels the screen SIMULATED.

shell
brew install chatcode-lab/tap/stock-tui
stock-tui --demo

With Rust 1.95 or newer, stock-tui can also be built from crates.io:

shell
cargo install --locked stock-tui
stock-tui --demo

Checksum-verified Linux and Windows archives, signed and notarized Intel and Apple Silicon macOS archives, and local Debian packages are attached to the release. The public live-data path remains bring-your-own Alpaca credentials. This is early, pre-1.0 software and not investment advice.

A closer look

The same idea at two depths

See it in motion

Watch the stock-tui build session

The recorded session follows Codex from the first StockTouch-inspired prompt through implementation, visual review, and the finished terminal app.

Source, releases, documentation, and the full prompt-to-commit history are in github.com/chatcode-lab/stock-tui.

Share this note