- Add improve command to all command tables and usage sections
- Add normalized_config field to BestCarRecord struct documentation
- Update CarCounts.by_rid type from String to (String, String)
- Update CarCounts.guid_to_rid type to HashMap<String, HashSet<(String, String)>>
- Add owned_configs field to MyCarsData and CarCounts docs
- Add normalize_to_final_build() to API docs
- Update CSV format examples to include FinalBuild column
- Update my_cars.json structure with engineMajor/weightMajor/chassisMajor
- Update timing file example with v2c_ version prefix
- Add version prefix stripping to data transformation docs
- Update CHANGELOG.md with Unreleased section
- Fix compare_records description to include normalized config sorting
- Add normalize_to_final_build() to map tune configs to final builds (323/233/332)
- Add normalized_config field to BestCarRecord
- Change CarCounts.by_rid key from String to (String, String) for per-config tracking
- Change CarCounts.guid_to_rid to HashMap<String, HashSet<(String, String)>>
- Extract owned tune configs from my_cars.json (engineMajor/weightMajor/chassisMajor)
- Add improve command: owned cars not yet at final build, sorted by track count
- Strip version prefixes (v2c_/v1c_) from config keys at parse time
- Update dedup check in update_best_car to consider normalized_config
- Add atomic_write helper for safe CSV output
- Delete completed plans/code-review-v2.md
- Apply rustfmt formatting across codebase
- Replace stdout output with structured CSV file generation
- Add wishlist, all commands with --min-count and --max-wishlist flags
- Introduce CarCounts struct for shared analysis computation
- Improve error handling: return Result instead of unwrap/panic
- Add prize field to BestCarRecord
- Remove TODO.md
- Add clap dependency with derive feature for structured CLI argument parsing
- Replace env::args() manual matching with clap subcommands (fetch, best, missing, wishlist, trash, details, track)
- Change print_best_car() signature from (&String, &String, &String) to (&str, &str, u8) for idiomatic Rust
- Add TODO.md tracking known tech debt and planned features
- Update CHANGELOG.md with clap migration details and set v0.2.0 release date
- Extract shared types (Car, BestCarRecord, AnalysisContext) into src/lib.rs
- Replace global static BEST_CARS with injected AnalysisContext for testability
- Add semaphore-bounded concurrency (limit 20) in parse_all_times()
- Replace hardcoded track name match with track_names.json loaded via include_str!
- Replace magic number 115 with const MAX_RQ: u8 = 113
- Improve floating-point tie comparison with TIME_TOLERANCE (5ms) constant
- Remove src/club.rs binary (topdrives.club no longer maintained)
- Remove scraper dependency from Cargo.toml
- Remove tracks.txt (replaced by track_names.json)
- Remove empty/placeholder test bodies
- Improve error handling in get_file() for response body read
- Add load_my_cars_data() combining owned + wishlist extraction in one I/O
- Update CHANGELOG, README, and all docs to reflect changes
- Remove once_cell and serde dependencies; use std::sync::LazyLock
and manual serde_json::Value parsing instead
- Add wishlist support: load wishlist from my_cars.json, prefix
missing cars with '+' in missing mode, add 'wishlist' command
to show stale wishlist entries (prefixed with '-')
- Replace unwrap()/expect() with graceful eprintln warnings and
early returns throughout (get_car_list, parse_car_times, etc.)
- Scope all Mutex locks tightly to avoid holding during I/O
(print_best_times, print_best_cars, print_trash, print_wishlist_stale)
- Replace custom split_prefix_postfix with str::split_once
- Pass owned-car set into parse_all_times/parse_car_times via
Arc<HashSet> instead of reading file per task
- Consolidate my_cars.json loading into single load_my_cars_data()
returning both owned and wishlist sets
- Add .gitignore and Cargo.lock to version control
- Report task failures in parse_all_times join loop