since17

module
v0.3.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 12, 2026 License: MIT

README

since17

     _                _ _____ 
 ___(_)_ __   ___ ___/ |___  |
/ __| | '_ \ / __/ _ \ |  / / 
\__ \ | | | | (_|  __/ | / /  
|___/_|_| |_|\___\___|_|/_/   v0.3.0

Your F1 Time Machine. Relive every Formula 1 season from 2017 onward, race by race, completely spoiler-free.

CI Go Version Go Report Card


Came late to F1? Watching your first season years later? since17 walks you through every round in calendar order using the official race highlight videos (the ~5-minute recaps on YouTube). For each round you get the standings and paddock context first, then the highlight link — and results only after you've confirmed you watched. No accidental spoilers. No discipline required.

Features

Spoiler-Safe Results and standings locked behind your current round — future data is never fetched
Expert Mode Toggle off spoiler protection for races you already know — unlocks standings, results, and AI post-race analysis
Bubble Tea TUI Full interactive race flow with keyboard navigation, spinner, and alt-screen
AI Historian Pre-race briefings or post-race expert analysis from any OpenAI-compatible LLM
Ergast + Cache Live data from the Ergast F1 API with file-based SHA-256 caching (permanent for past seasons)
Undo Single-level rewind with since17 undo if you advance by mistake
Track Database Pre-seeded pre-race context for every race 2017–2025 (no API key needed)
Colors Championship position deltas highlighted in green/red via Lip Gloss
Doctor Built-in diagnostics for state file and data integrity

Installation

Homebrew (macOS / Linux)
brew install eftekin/since17/since17
go install (always latest)
go install github.com/eftekin/since17/cmd/since17@latest
Build from source
git clone https://github.com/eftekin/since17.git
cd since17
make install

Quick Start

# Start tracking the 2021 season
since17 init 2021

# Check where you are + pre-race context
since17 status

# Watch flow: briefing → open highlights → reveal results → advance
since17 race

# Rewind if you advanced by mistake
since17 undo

Commands

Command Description
since17 init <year> Start or reset at round 1 of a season (2017–2025)
since17 status Current race, standings snapshot, and pre-race context
since17 race Full interactive watch flow (TUI)
since17 complete Mark current race highlights as watched and advance
since17 undo Rewind one race
since17 config View current settings
since17 config spoiler-safe <on|off> Toggle spoiler-safe / Expert Mode
since17 doctor Diagnostics for state file and data integrity

Expert Mode

Already know how the 2021 season ends? Toggle off spoiler protection and replay it with full context:

since17 config spoiler-safe off   # activate Expert Mode
since17 status                    # shows post-race standings + results + AI analysis
since17 config spoiler-safe on    # restore protection any time

In Expert Mode:

  • since17 status shows standings after the current round and the full race results table
  • The AI Historian delivers a post-race expert analysis instead of a pre-race briefing
  • The banner and dashboard indicate "Expert Mode · Spoilers Enabled"
  • since17 race fetches post-race standings in the TUI briefing view

Spoiler-safe mode is the default — new users are always protected.

AI Historian

since17 can generate race briefings using any OpenAI-compatible LLM. The behavior adapts to your mode.

Spoiler-safe mode: The system prompt locks the model's knowledge horizon to the race date. It cannot know the result, qualifying times, or any post-race event. Fires only when no local TSV context exists for the round.

Expert Mode: The temporal lock is removed. The AI delivers a post-race expert analysis: race winner, key incidents, championship standings impact, and historical significance. Runs on every status call, overriding the TSV blurb.

Setup:

export SINCE17_AI_KEY=sk-...
since17 status

Configuration:

Variable Default Description
SINCE17_AI_KEY (unset) API key — feature is disabled when absent
SINCE17_AI_BASE_URL https://api.openai.com/v1 Any OpenAI-compatible endpoint

Use a local model (e.g. Ollama):

export SINCE17_AI_KEY=ollama
export SINCE17_AI_BASE_URL=http://localhost:11434/v1
since17 status

Disable AI for a single run:

since17 status --no-ai

Data & Privacy

  • All watch progress is stored locally in ~/.since17/state.json
  • Pre-race context is compiled into the binary via go:embed (no external data files needed)
  • Race data is fetched from Ergast (with api.jolpi.ca as fallback) and cached in ~/.since17/cache/
  • No telemetry. No accounts. Nothing phoned home unless you set SINCE17_AI_KEY.

Architecture

cmd/since17/     # Binary entrypoint — version injected via ldflags
cmd/             # Cobra commands: status, race, complete, undo, init, config, doctor
internal/
  api/           # ErgastClient — REST client + SHA-256 file cache
  data/          # go:embed assets (highlights TSV, track database)
  historian/     # AI Historian — OpenAI-compatible HTTP client
  paths/         # App directory and state file paths (~/.since17/)
  state/         # StateManager — atomic JSON state, TrackerState model
  ui/            # Lip Gloss renderers + Bubble Tea race TUI
Formula/         # Homebrew tap formula

Development

# Build
make build

# Run tests
make test

# Vet
make vet

# Local GoReleaser snapshot (no publish)
make snapshot

Single test:

go test -run TestExtractStandings ./internal/api/

License

MIT — see LICENSE.

Directories

Path Synopsis
cmd
Package cmd wires Cobra commands to internal business logic.
Package cmd wires Cobra commands to internal business logic.
since17 command
internal
api
Package api wraps the Ergast F1 REST API with an optional file-based cache.
Package api wraps the Ergast F1 REST API with an optional file-based cache.
data
Package data bundles the race highlights TSV and the static circuit dataset into the binary via go:embed.
Package data bundles the race highlights TSV and the static circuit dataset into the binary via go:embed.
paths
Package paths centralises every filesystem location the tool reads or writes.
Package paths centralises every filesystem location the tool reads or writes.
state
Package state owns the TrackerState type and the only valid way to read or write it.
Package state owns the TrackerState type and the only valid way to read or write it.
ui
Package ui owns every visual rendering concern: Lip Gloss styles, constructor color mappings, and Bubble Tea model definitions.
Package ui owns every visual rendering concern: Lip Gloss styles, constructor color mappings, and Bubble Tea model definitions.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL