• v3.0.0 89878b7119

    v3.0.0
    All checks were successful
    CI / build-and-test (push) Successful in 1m4s
    Stable

    joeyr released this 2026-07-07 09:15:48 -05:00 | 100 commits to main since this release

    Added

    • Real installers. The app now packages into a proper Windows installer
      (NSIS — per-user, no admin prompt) and a standalone portable .exe via
      npm run dist, instead of being launched from npm start. The native pieces
      are bundled and verified to run from the packaged build: the koffi FFI addon
      (global hotkey + screen capture) and the tesseract OCR worker with its
      language model.
    • Riot API key in Settings. A new field in the Settings panel stores your
      personal Riot API key locally in settings.json. It enables the scouting
      report and benchmark harvesting, and a status line shows whether a key is set.

    Changed

    • BREAKING — the Riot API key now comes only from the Settings panel. The
      app no longer reads RIOT_API_KEY from the environment or a .env file.
      After updating, enter your key in Settings once (it applies on the next
      launch); an existing .env key will be ignored by the app. The standalone
      npm run harvest:benchmarks CLI is unaffected and still reads RIOT_API_KEY
      from the environment.
    • The packaged app writes debug.log into your user-data folder
      (%APPDATA%\champ-select-assistant\) instead of next to the executable. Dev
      runs are unchanged (current working directory).

    Downloads: LoL Companion-3.0.0-setup.exe (installer) or
    LoL Companion-3.0.0-portable.exe (no install). The build is unsigned, so
    Windows SmartScreen warns on first run — choose More info → Run anyway.
    After installing, open Settings and enter your Riot API key to enable the
    scouting report and benchmark harvesting.

    Downloads
  • v2.1.2 ed00a34c5e

    v2.1.2
    All checks were successful
    CI / build-and-test (push) Successful in 1m10s
    Stable

    joeyr released this 2026-07-06 12:18:28 -05:00 | 106 commits to main since this release

    Added

    • Continuous integration. A Forgejo Actions workflow runs the full gate — type-check, tests, and build — on every push and pull request to main, so a broken build can no longer land unnoticed. It runs on Node 24 to match the shipped Electron runtime and skips the unused Electron binary download.

    Fixed

    • Tests are now timezone-independent. A renderer snapshot rendered a timestamp through toLocaleTimeString, so it only matched in the recording machine's local timezone and failed under CI (UTC); the test scripts now pin TZ=UTC. No change to app behavior.
    Downloads
  • v2.1.1 52f86f25e0

    v2.1.1 Stable

    joeyr released this 2026-07-04 23:06:01 -05:00 | 115 commits to main since this release

    Changed

    • A player the game never identifies now shows a muted amber ? instead of a red ✕. When Riot's local Live Client API exposes a player with no Riot ID at all (a bare # / champion-name placeholder — typically someone still on the loading screen or reconnecting), there is no name to look up. That is different from a name that was looked up and genuinely not found, and the red ✕ read as if the report had failed to load the player. The badge now distinguishes the two — amber ? ("no Riot ID in the game data") vs. red ✕ ("player not found") — with a tooltip explaining the amber case.

    Added

    • Diagnostics for unresolved scouting rows. Real games surfaced players the live feed left unidentifiable all game (the champion name as a placeholder, no tag), even across the 1- and 5-minute re-harvests. The app now logs the raw live-feed identity fields for any tag-less player, and on every scout run probes the LCU /lol-gameflow/v1/session and logs whether it exposes puuids for both teams — read-only groundwork for a fallback identity source that would not depend on the live feed's Riot IDs.
    Downloads
  • v2.1.0 ac36f73a82

    v2.1.0 Stable

    joeyr released this 2026-07-04 16:03:29 -05:00 | 117 commits to main since this release

    Added

    • The scouting report now calls each lane. Between every head-to-head pair a small verdict chip points to the favored side (green toward your team, red toward the enemy, grey = for even), combining the ranked-ladder gap with recent on-champ form. A thin on-champ sample is discounted quadratically, so a 1-2 game hot streak can't fake an edge, and the chip stays blank whenever either side's data hasn't loaded — it never shows a confident-but-guessed call.
    • Biggest-threat and weakest-link callouts. Exactly one enemy card is tagged ⚠ threat (highest combined rank + on-champ score) and one ally card weak link (lowest), so the two players who most shape the game are obvious at a glance.
    • "first time?" hint. When a player has no mastery and no recent games on the champion they locked, the on-champ line reads first time? instead of a blank —.

    Changed

    • The report is laid out as head-to-head lane pairs (your player directly across from their opposite, TOP → SUP) instead of two independent columns.
    • On-champ stats from a small sample (< 5 games) are dimmed and marked * so a coinflip sample isn't read as a trend.
    • Clarified the stat labels with tooltips — "Record" notes it's overall ranked, not on this champ.

    Notes

    • The in-game overlays' on-screen render has not yet been verified in a live match.
    Downloads
  • v2.0.1 fa285e38e2

    v2.0.1 Stable

    joeyr released this 2026-07-01 08:46:00 -05:00 | 118 commits to main since this release

    Fixed

    • A player whose Riot ID is missing from the live feed no longer drops out of the scouting report. Riot's local Live Client API occasionally exposes a player with no Riot ID (a bare #, empty game name, summonerName defaulted to the champion name) — typically a teammate still on the loading screen. That player's game-name split to an empty string and the whole card was silently filtered out, leaving a gap in the lane. The card is now always kept: the champion and role render, and the identity badge shows a red ✕ ("couldn't identify this account") instead of the lane vanishing.
    • The scouting report now re-harvests when a player's identity didn't resolve. Previously the live feed was sampled exactly once per game (at game start), so a player whose Riot ID hadn't populated yet stayed blank all game no matter how many times the overlay was toggled — toggling only re-shows the cached snapshot. When any identity fails to resolve, the report now re-harvests at the 1-minute and 5-minute game-clock marks; a later snapshot usually carries the now-populated Riot ID, and the card fills in automatically. Re-runs are cheap (already-resolved players are served from the scout cache), bounded to those two marks per game, and cleared at game end. A genuinely hidden account that the feed never surfaces stays a ✕ — the read-only-against-the-LCU contract is unchanged.
    Downloads
  • v2.0.0 4d90185687

    v2.0.0 Stable

    joeyr released this 2026-06-30 22:19:07 -05:00 | 119 commits to main since this release

    The full-stack modernization milestone: every dependency is now on its latest release, with zero security advisories, zero deprecated packages, and zero deprecated APIs in our own code. Nothing about how the app is used changes — this is a foundation release. The major-version bump signals the scale of the under-the-hood jump (Electron, React, and zod all crossed a major), not a change to the read-only-against-the-LCU contract, which is unchanged.

    Fixed

    • The scouting report now routes Riot API calls to the correct region. Platform detection read the LCU's LoginDataPacket platform-config namespace, which is frequently empty and returned a 404, so region resolution silently fell back to na1 for everyone regardless of their actual server. It now reads the client's crash-reporting environment (/riotclient/v1/crash-reporting/environment), set at client startup, which returns the Riot platform id (e.g. na1) directly. NA players were unaffected (the fallback happened to match); other regions were mis-routed.

    Internal

    • Every dependency upgraded to latest, in gated phases. Runtime/framework majors: Electron 33 -> 43 (bundled Node 20 -> 24), React 18 -> 19, zod 3 -> 4, undici 7 -> 8, koffi 3.0 -> 3.1. Toolchain: TypeScript 5 -> 6, Vite 5 -> 8, Vitest 2 -> 4, @types/node -> 24 (pinned to match Electron 43's Node 24 runtime). Plus pino 9 -> 10, selfsigned 2 -> 5, jsdom 25 -> 29, fast-check 3 -> 4, and the React 19 / zod 4 type packages.
    • Deprecated APIs removed at the source, not silenced. zod 4: .passthrough() -> .loose() and z.string().datetime() -> z.iso.datetime(); enum-keyed z.record -> z.partialRecord where the data is partial (a real behavior fix — v4 enum records are exhaustive). React 19: the removed global JSX namespace is now imported explicitly. Vitest 4: vitest.workspace.ts folded into test.projects. TypeScript 6: tsconfig.main.json moduleResolution migrated off the deprecated node10.
    • Result: npm audit reports 0 vulnerabilities and the tree carries no deprecated packages. All 482 tests pass; the build is warning-free.
    Downloads
  • v1.9.0 83d3360e08

    v1.9.0 Stable

    joeyr released this 2026-06-30 10:24:36 -05:00 | 133 commits to main since this release

    Added

    • Your champion pool is now pre-harvested. Adding champions to your pool in the settings panel queues a background benchmark harvest for each one at your own rank tier (the same data the in-game overlay compares against), and the saved pool is also backfilled at startup. Harvests run one at a time and skip any champion whose data is already fresh, so editing the pool is cheap.

    Fixed

    • The scouting report's "on champ" and "role" rows no longer come back blank during a harvest. The benchmark harvester and the scouting report each had their own rate limiter but shared one Riot API key, so when a harvest was running as a game went live their combined traffic blew past the key's 100-requests-per-2-minutes cap — and the scout's deep tier (recent-match stats) was the casualty, leaving those rows as "—". The harvester now runs in-process behind the same rate limiter as the scout, and pauses entirely while a game is live so the scouting report gets the full budget; it resumes from a checkpoint when the game ends.

    Internal

    • The benchmark harvester moved from a spawned scripts/harvest-benchmarks.mjs child process to an in-process module (src/main/live/harvester.ts) sharing the scout's RiotClient. The script remains as a thin CLI shim for manual npm run harvest:benchmarks runs (now requires npm run build:main first).
    Downloads
  • v1.8.0 fbeb36c044

    v1.8.0 Stable

    joeyr released this 2026-06-29 23:18:07 -05:00 | 134 commits to main since this release

    Added

    • The scouting report now shows whether each player was found. A small indicator next to every riot ID pulses as a dot while the row-1 identity lookup (account → puuid) is in flight, then resolves to a green ✓ when the player is found or a red ✕ when they can't be (no tag exposed, or Riot has no such account). This makes the first pull visibly populate, and — more usefully — tells a genuinely not-found player apart from a found one who is merely unranked or has no recent games, which until now both showed "—" across the board.
    Downloads
  • v1.7.2 1cc1a4323b

    v1.7.2 Stable

    joeyr released this 2026-06-29 22:47:10 -05:00 | 135 commits to main since this release

    Internal

    • Integration tests no longer make real loopback patch GETs. The test harness now stubs the patch resolver's fetch in-memory by default (resolving the mock server's game version without a socket); the single test that exercises the real LCU patch wiring opts in explicitly. This removes the per-test network churn and the ECONNRESET log noise at teardown, and with it a source of rare waitFor timeouts under parallel test forks. Harness wait budgets were also raised to 10 s, and the patch resolver no longer logs a warning for a fetch that fails after it has been stopped (an expected shutdown-time connection reset).
    Downloads
  • v1.7.1 79cab74ff9

    v1.7.1 Stable

    joeyr released this 2026-06-29 22:24:05 -05:00 | 136 commits to main since this release

    Fixed

    • The scouting report no longer flashes when you first open it. Pressing the hotkey before the first snapshot existed showed an empty, see-through window for a beat and then popped the report in — a visible flicker on the first open of a session. The panel now paints its frame immediately with a "Gathering report…" line, and the team columns fill into that frame in place, so there is no empty-window-then-pop-in jump.
    • Opening the report with no live game now gives feedback. Previously the hotkey showed a blank, invisible overlay with no sign it had worked; it now shows the report frame and the gathering message, so you always get confirmation the hotkey fired and a reminder of how to close it.
    Downloads