-
v1.3.0
Stablereleased this
2026-07-13 09:11:37 -05:00 | 28 commits to main since this releaseAdds Docker/Swarm secret-file support so credentials can be delivered as mounted files instead of plain environment variables. Local docker-compose deployment is unchanged; the Swarm migration itself remains future work (
docs/DOCKER_SWARM_SETUP.md).Added
*_FILEsecret convention. Every secret the bot reads now also accepts a<NAME>_FILEvariant pointing at a file whose contents are the secret (the Docker/Swarm/run/secrets/*convention), read through a newreadSecret()helper (src/utils/readSecret.ts).<NAME>_FILEtakes precedence over an inline<NAME>(a warning is logged if both are set); an unreadable file is logged and treated as unset so the normal "<NAME>is required" validation still fires. CoversDISCORD_TOKEN,CLAUDE_API_KEY,DATABASE_URL,BRAVE_SEARCH_API_KEY,RIOT_API_KEY,LOL_PREDICTION_API_KEY,D2EMU_API_USERNAME, andD2EMU_API_TOKEN. Plain env vars (and.env-based local runs) are byte-for-byte unchanged.
Downloads
-
Source code (ZIP)
0 downloads
-
Source code (TAR.GZ)
0 downloads
-
v1.2.6
Stablereleased this
2026-07-12 22:42:38 -05:00 | 32 commits to main since this releaseBug-fix release: unbreaks LoL live-game predictions and the
/aufhockerchat command against Sonnet 5, records prediction outcomes again, and paces Riot API calls more conservatively.Fixed
- Stop sending
temperatureto Claude. The current Claude families (Sonnet 5 and newer) rejecttemperaturewith a400(temperature is deprecated for this model), which was failing live-game predictions, lane detection, and — whenever invoked — the/aufhockerchat command itself. Dropped the parameter from all three call sites and removed the now-deadCLAUDE_TEMPERATUREconfig field, its validation, and the env templates. - Record prediction outcomes again. The
recordResultUPDATE bound$3to both avarcharassignment (actual_winner) and avarcharcomparison (predicted_winner); with node-pg's untyped parameter, Postgres deduced two conflicting types and rejected the query (42P08: inconsistent types deduced for parameter $3 — text versus character varying). Every result write failed, so accuracy stats stayed empty. Cast$3::varcharin both spots.
Changed
- More conservative Riot API pacing. A game detection fans out ~80 Riot calls (rank + mastery + up to 60 match-v5); the shared client throttle sat at 90 req/2min — barely under a personal key's ~100/2min ceiling, which is also shared with the lol-companion project — so the match-v5 burst tripped 429s (absorbed by retry, logged as warnings). Lowered the throttle and made it env-tunable via
LOL_RIOT_MAX_REQUESTS_PER_2MIN(75),LOL_RIOT_MAX_REQUESTS_PER_SEC(15), andLOL_RIOT_MIN_SPACING_MS(350).
Downloads
-
Source code (ZIP)
0 downloads
-
Source code (TAR.GZ)
0 downloads
- Stop sending
-
v1.2.5
Stablereleased this
2026-07-12 22:30:10 -05:00 | 33 commits to main since this releaseDocs only — no change to the bot's runtime, image, or command surface.
Changed
- Consolidated docs under
docs/. MovedDOCKER_SETUP.md,DOCKER_SWARM_SETUP.md, andWHATS_LEFT.mdout of the repo root intodocs/(alongsideDEPLOYMENT.md, the admin guides, etc.); fixed the now-sibling relative links.README.md,CHANGELOG.md, andCLAUDE.mdstay at root by convention. WHATS_LEFT.mdis now open-work-only. Dropped the "what landed" and completed-item history (that lives inCHANGELOG.md+ git); it now lists just the remaining items.- Refreshed
docs/DOCKER_SWARM_SETUP.md. Its "runner needs Docker access" step is marked done (shipped in v1.2.3 via the repo-scopedaufhocker-dockerrunner), and the example publish job now targetsruns-on: aufhocker-docker— targeting the sharedubuntu-latestrunner would fail now that it no longer exposes the Docker socket to jobs.
Downloads
-
Source code (ZIP)
0 downloads
-
Source code (TAR.GZ)
0 downloads
- Consolidated docs under
-
v1.2.4
Stablereleased this
2026-07-12 22:19:22 -05:00 | 34 commits to main since this releaseDocs only — no change to the bot's runtime, image, or command surface.
Added
docs/PLUGIN_DECOMPOSITION_PLAN.md— a design + staged-migration plan for P4-1 (fuller plugin decomposition). Adopts making the corequeryfeature the third plugin as the "rule of three" trigger: define a realPlugincontract soquery/lol/d2all implement it and the bot core becomes a thin host. Sequenced D2 → LoL → query (riskiest last, behind a proven interface).WHATS_LEFT.md's P4-1 item now points at it.
Downloads
-
Source code (ZIP)
0 downloads
-
Source code (TAR.GZ)
0 downloads
-
v1.2.3
Stablereleased this
2026-07-12 21:56:07 -05:00 | 35 commits to main since this releaseCI infrastructure only — no change to the bot's runtime, image, or command surface.
Changed
docker-buildCI moves to a repo-scoped runner. The job now runs on a dedicatedaufhocker-dockerrunner (registered scoped to just this repo) that mounts the host Docker socket into its job containers, instead of the sharedubuntu-latestrunner. The shared runner no longer passes the socket into any job, so other repos' workflows can no longer reach the host Docker daemon — only this repo's (trusted)docker-buildjob gets host-daemon access. Closes the socket-isolation item; the second runner service lives in theforgejo-runner.yamlSwarm stack.
Downloads
-
Source code (ZIP)
0 downloads
-
Source code (TAR.GZ)
0 downloads
-
v1.2.2
Stablereleased this
2026-07-12 21:03:01 -05:00 | 37 commits to main since this releaseChanged
LOL_PREDICTION_MODEL:.env.configmoves fromclaude-opus-4-8(priciest model, polled per active game) toclaude-sonnet-5— a deliberate quality/cost tradeoff, still above the code default (claude-haiku-4-5-20251001) thatCLAUDE.mdcalls for.
Downloads
-
Source code (ZIP)
0 downloads
-
Source code (TAR.GZ)
0 downloads
-
v1.2.1
Stablereleased this
2026-07-12 20:45:06 -05:00 | 39 commits to main since this releaseCI and test hygiene that restores a fully green pipeline. No change to the bot's runtime, built image, or command surface.
Fixed
build-and-testCI is green again. The config-validation tests built their "valid base config" withoutBRAVE_SEARCH_API_KEY, then depended on it being present in the ambient environment —config.tsloads dotenv over['.env', '.env.config'], and the committed.env.configsetsENABLE_ADMIN_TOOLS=true, sovalidate()requires the key forweb_search. It was present locally (from.env) but absent in CI, so two "should validate successfully" cases threw only there. The base config now pins the key and is self-contained. Separately, files that were not Prettier-clean (CHANGELOG.md, four__tests__files,WHATS_LEFT.md) were formatted soformat:check— the job's first step — stops aborting the run.docker-buildCI is green. The Forgejo Actions runner now mounts the host Docker socket into job containers, so the image build reaches the daemon (previously it failed with "cannot connect to the Docker daemon"). This needs bothcontainer.options(with-v /var/run/docker.sock:/var/run/docker.sock) andcontainer.valid_volumes: [/var/run/docker.sock]— the runner validates-vmounts againstvalid_volumes, which defaults to deny-all. Set in theforgejo-runner.yamlSwarm stack; theci.ymlcomment is corrected to match.
Changed
WHATS_LEFT.md: removed the closed SECURITY.md (A3) item and dropped P5-1 (CIdocker-build) now that it is done.
Downloads
-
Source code (ZIP)
0 downloads
-
Source code (TAR.GZ)
0 downloads
-
v1.2.0
Stablereleased this
2026-07-12 11:55:23 -05:00 | 44 commits to main since this releaseOpen-sourcing, a Riot rate-limit fix, and a secrets/config split, plus a sweep of documentation and compose drift. No change to the bot's command surface.
Changed
- Relicensed from proprietary to MIT.
LICENSEis now the MIT text,package.jsonlicenseisMIT(wasUNLICENSED), and the README — which already claimed MIT — is now consistent with both. The "Contributing" (fork + PR) section is valid again. - Secrets are now split from non-secret config. Credentials and deployment identity live in
.env(git-ignored); non-secret tuning (models, intervals, feature flags, pool sizes) lives in.env.config, which is committed. Both load together — docker-compose viaenv_file: [.env.config, .env], local runs viadotenv.config({ path: ['.env', '.env.config'] })— with disjoint keys so order is immaterial (and.envwins on any overlap). - Corrected drifted
docker-compose.yml(dev) defaults. Model ids that matched the retired-family guard and an aggressive LoL poll interval (30000) / rate-limit threshold (10) are gone, replaced by the committed.env.configvalues (claude-sonnet-5,300000,50). Dead env varsLOL_EMBED_LAYOUTandDEPLOYMENT_ENVIRONMENTwere removed. The dev healthcheck now hits the real/healthendpoint (parity with production), anduser-mappings.jsonis mounted so its absence no longer warns on every boot.
Added
- Client-side Riot API pacing (
RiotRateLimiter). A single limiter shared across every Riot client spreads calls to stay under a personal key's budget (~20 req/s, ~100 req/2 min) so bursty game-detection enrichment avoids 429s rather than merely backing off after hitting them. Combined with the saner 5-minute poll interval, this ends the recurringspectator-v5rate-limit warnings. Unit-tested (spacing, rolling windows, concurrent serialization) and wired as an optional collaborator so existing client tests are unaffected.
Fixed
- Documentation drift: the README "Project Structure" now matches the actual tree and
CLAUDE.md, and the stale Dockerfile "health endpoint requires implementation" comment (it is implemented) is gone. - Minor code smells: removed the dead
stripHtml()inToolExecutor, switched its numeric HTML-entity decode toString.fromCodePoint(astral-safe), and replaced the deprecatedString.prototype.substrinAufhockerBotwithslice.npm ci --only=production→npm ci --omit=devin the Dockerfile. - Tooling: an ESLint
no-consoleoverride for the migration CLI keeps the warning meaningful elsewhere, and Prettier now setsendOfLine: autosoformat:checkstops false-flagging a Windows (CRLF) checkout.
Downloads
-
Source code (ZIP)
0 downloads
-
Source code (TAR.GZ)
0 downloads
- Relicensed from proprietary to MIT.
-
v1.1.0 Stable
released this
2026-07-08 23:04:02 -05:00 | 108 commits to main since this releaseToolchain and dependency modernization — every dependency to latest stable, zero deprecation warnings and zero
npm auditfindings on a fresh install (down from 17 vulnerabilities including 1 critical). No user-facing behavior change, but the supported Node floor moves from 18 to 22.Changed
- ESLint 8 (end-of-life) → 10.6 with typescript-eslint 8.63, migrating
.eslintrc.jsto flateslint.config.js. This alone removed the deprecatedrimraf@3/glob@7/inflight/@humanwhocodes/*install warnings. Two rules no longer exist upstream:interface-name-prefix(dropped) andno-var-requires(nowno-require-importsin the test overrides). - Jest 29 → 30 (with
@types/jest30, ts-jest 29.4.11); ts-jest's deprecated transform-levelisolatedModulesoption moved intotsconfig.test.json. - fast-check 3 → 4: removed APIs migrated (
fc.stringOf(unit, opts)→fc.string({ unit, ...opts }),fc.char()-based strings → defaultfc.string()), and allfc.date()arbitraries now passnoInvalidDate: truesince v4 generatesInvalid Dateby default — Discord/DB timestamps are always valid dates. @anthropic-ai/sdk0.78 → 0.110 (its improved types made two manual casts inClaudeClientredundant), dotenv 16 → 17, discord.js 14.26.4, pg 8.22, winston 3.19.- TypeScript 5.9 → 6.0.3, deliberately capped
~6.0.x: typescript-eslint's peer range is<6.1.0, so TS 7 has to wait for upstream support.tsconfigmoved off the TS7-removednode10module resolution tomodule/moduleResolution: nodenext(output is still CommonJS). - Node floor 18 → 22 (
engines,.nvmrc, Dockerfilenode:22-alpine, CI containernode:22-bookworm) — Node 20 went end-of-life in April 2026.@types/nodetracks the runtime major (^22), not npm's latest. - Added a package.json
overridesblock for upstream pins:undici@^6.27(discord.js pins a 6.24.1 with several CVEs — this cleared most of the 17 audit findings), andbabel-plugin-istanbul@8/test-exclude@8/glob@13to lift Jest's own deprecated-glob chain.
Fixed
- Four re-thrown errors (
ToolExecutorfetch timeout/network wrappers,ShutdownHandlercancellation,UserMapperdatabase-sync failure) now attach the original error ascause— previously the root cause was discarded when the wrapper error was thrown (surfaced by ESLint 10's newpreserve-caught-errorrule).
Downloads
-
Source code (ZIP)
0 downloads
-
Source code (TAR.GZ)
0 downloads
- ESLint 8 (end-of-life) → 10.6 with typescript-eslint 8.63, migrating
-
v1.0.1 Stable
released this
2026-07-08 21:44:54 -05:00 | 110 commits to main since this releaseFull lint cleanup following the config fix in 1.0.0 -- no user-facing behavior change, but a few real bugs turned up along the way and got fixed.
Changed
- Fixed all ~1270 lint violations the corrected
.eslintrc.jssurfaced. Production code is now fully lint-clean (typed DB rows, narrowedunknownerror handling, missing return types, floating/misused promises). A targeted ESLint override relaxes the unsafe-any family for test files, since Jest mocks are inherently loosely typed. npm run lintnow runs in CI, after format check and before type-check.
Fixed
MessageStoreandServerConfigManagercleanup methods loggeddeletedCount: 0on every call -- read.rowCountoff a value that never had it. AddedRETURNINGclauses and countresult.lengthinstead.DiscordClient's rate-limit handler logged fields (timeout/url) that don't exist on the real payload type -- alwaysundefined. Now logs the real fields.DiscordClient.disconnect()never awaitedclient.destroy(), so shutdown could complete before the gateway connection actually closed.
Downloads
-
Source code (ZIP)
1 download
-
Source code (TAR.GZ)
1 download
- Fixed all ~1270 lint violations the corrected