Commit graph

32 commits

Author SHA1 Message Date
d629ccf496
perf(frontend): drop the motion library for CSS keyframes and small FLIP/presence hooks 2026-09-30 16:26:36 +02:00
7172652ac3
perf(frontend): defer landing lower sections and voxel backdrop, skip guest refresh 401, fix hud a11y 2026-09-30 16:24:28 +02:00
b170227adf
perf(frontend): route-level code splitting, main chunk 538 -> 491 KB
Lighthouse (production, default mobile 4x-CPU profile) scored
Performance 33/100, dominated by one ~536-538 KB entry chunk that
bundled every route's code regardless of which page a visitor landed
on -- the "chunks are larger than 500 kB" Vite warning on every build
this session.

Converted every route except / and the 404 catch-all to React Router
8's native route.lazy (blocks navigation until the chunk is ready --
no separate Suspense fallback needed). AppShell/HomePage/NotFoundPage/
RequireAuth stay eager since they're needed on every load regardless.

Result: main chunk 490.84 KB, no >500kB warning, one small chunk per
route (LoginPage 1.4 KB, ThemesPage 15.5 KB, AccountPage 11 KB, etc.)
loaded only when actually visited.

Fixed a real race the lazy boundary exposed: /login and /register
share an "Почта" field label, and during the chunk swap between them
the old page can stay mounted a beat longer than before -- a test
grabbing the field by label could land on the about-to-unmount one.
Also bumped RTL's asyncUtilTimeout and vitest's testTimeout, since the
route-transition + findBy chain didn't always land inside the old
1000/5000ms defaults under full parallel test-suite load.

Claude-Session: https://claude.ai/code/session_01F1M1Jic1wTSn4igUENynmZ
2026-09-30 16:06:45 +02:00
6b0633034d
feat(frontend): SEO — sitemap, canonical link, structured data
- robots.txt now also points at a real sitemap.xml (public pages
  only: /, /download, /themes, /showcase) and disallows the
  auth-gated routes (/account, /configs, /link) that have nothing
  useful to a crawler
- canonical <link> on the root page
- SoftwareApplication JSON-LD so Google can render a rich result
  (name, free price, icon) instead of a plain blue link

Claude-Session: https://claude.ai/code/session_01F1M1Jic1wTSn4igUENynmZ
2026-09-30 15:48:44 +02:00
9744dc7f24
fix(frontend): add a real robots.txt, cache hashed assets forever
Lighthouse audit findings:
- No robots.txt existed, so nginx's SPA fallback (try_files -> index.html)
  served the React app's HTML at /robots.txt -- crawlers got 44 "syntax
  not understood" lines instead of directives.
- No Cache-Control on /assets/*, so every visit re-fetched a hashed,
  content-addressed bundle that can never actually change under that
  URL. Lighthouse estimated 936 KiB/visit wasted on this alone.

Claude-Session: https://claude.ai/code/session_01F1M1Jic1wTSn4igUENynmZ
2026-09-30 15:40:04 +02:00
6fa36f8b32
perf(frontend): memoize ColorField/GradientField with stable callbacks
React.memo alone does nothing here: PaletteTabs built a fresh
`(hex) => setColor(slot, hex)` closure per field on every render, so
memo's prop comparison always saw a "changed" onChange and re-rendered
anyway. Stabilized it properly:

- setColor/setGradient read draft/onChange from a ref (updated in a
  useLayoutEffect, not during render -- oxlint's react(refs) rule
  correctly flags a ref write in the render body) so they keep a
  stable identity (useCallback, empty deps) across edits
- per-slot wrapper closures are built once in a useMemo keyed off
  those now-stable functions, not off `draft`

This doesn't change the preset-switch case measured earlier (every
field's value genuinely changes then, so memo correctly re-renders
all of them -- that cost is what startTransition already covers). It
does stop sibling fields re-rendering on interactions that don't
touch them: undo/redo, tab switching, hovering unrelated panel
elements.

Claude-Session: https://claude.ai/code/session_01F1M1Jic1wTSn4igUENynmZ
2026-09-30 10:58:34 +02:00
786fe1cc1d
perf(frontend): defer the theme editor's heavy preset/import re-render
Measured with Playwright (rAF frame deltas around a preset click, real
Chromium, production): even with every CSS transition disabled, a
single frame still spiked to ~133ms on preset switch -- proving the
worst offender wasn't CSS at all, but the synchronous React re-render
(reset() swaps the whole draft, re-rendering every ColorField/
GradientField and the ClickGui panel at once).

Wrapped the three call sites that replace the whole draft (preset
pick, reset-to-default, file import) in startTransition so React can
deprioritize that render instead of blocking the frame the click
lands on.

Result (same measurement, after fix): peak frame 133ms -> 83ms,
frames over 100ms: 1 -> 0. Not a full fix -- frames over 16ms actually
rose slightly (18 -> 21), so total render cost is roughly the same,
just spread out instead of landing in one blocking spike. A real fix
for the remaining cost needs memoizing ColorField/GradientField so a
preset switch doesn't re-render every field instance; noted as a
follow-up, not done here.

panel.test.tsx: import's name-box assertion now waits instead of
checking synchronously, since the state update is deferred.

Claude-Session: https://claude.ai/code/session_01F1M1Jic1wTSn4igUENynmZ
2026-09-30 10:51:13 +02:00
ab86078ca3
perf(frontend): stop theme switches from janking the whole page
Two inherited-custom-property transitions were forcing a full style
recalculation on every animation frame during a theme switch:

- html transitioned --color-ice/--page-accent-glow (inherits: true),
  both read by dozens of selectors site-wide (buttons, links, glows,
  color-mix() gradients) -- animating them recomputed style for every
  element that references them, across the whole page, not just the
  swatch that was clicked.
- .lv-gui (the ClickGui replica used in ThemeStrip, HudPlayground, the
  login backdrop and the theme editor panel) transitioned 21 inherited
  custom properties at once, including per-row/per-tab ones
  (--gui-row-*, --gui-tab-*, --gui-menu-*) -- with a long module list
  that's the same cost multiplied by every row/tab in the tree.

Both now snap instantly instead of transitioning; .lv-gui keeps a
300ms cross-fade but only on the ~8 properties that read as "the
theme" (window/header/stroke/text/accent/panel), not per-row state.

Claude-Session: https://claude.ai/code/session_01F1M1Jic1wTSn4igUENynmZ
2026-09-30 10:37:40 +02:00
756ebc6d86
feat(frontend): full redesign of login/register
Owner's complaint: the two-pane layout's decorative right-side panel
("Твои настройки LoVisual на любом компьютере...") made no sense next
to a login form. Dropped the whole two-pane concept, not just its
visuals.

Login/register now render as the mod's own in-game account screen:
night-lake backdrop (the same Backdrop the landing hero uses), a
clock + Вход/Регистрация tab switcher styled like the mod's own
ClickGui tabs, a single glass panel on the mod's own category
colours, and a real mod-style hint row ("X - Y") instead of marketing
copy. What an account actually gets you is stated as plain hints
(4 cloud slots, share a slot's code, the mod signs itself in by code,
no account required to just use the mod) instead of a sales pitch.

- AuthSplit.tsx removed; AuthScreen.tsx + auth.css replace it
- LoginForm/RegisterForm: dropped the redundant login<->register text
  link now that the tab switcher does that job; RegisterForm now
  honours the original `from` redirect (previously always went to
  /configs even when registration started from /link)
- Rewrote auth i18n copy to match the site's established voice

Claude-Session: https://claude.ai/code/session_01F1M1Jic1wTSn4igUENynmZ
2026-09-30 10:30:53 +02:00
c2c7e8fa91
feat(frontend): redesign the theme editor page
The editor's control panel is now a second ClickGui window skinned
live with the theme being edited, so every change shows in the tool
itself, not just the preview -- same "the section is a ClickGui
window" move the landing's ThemeStrip already uses, applied to a
working tool this time.

- Removed the three uppercase eyebrow-style section labels (the same
  generic-tell pattern already fixed on the landing page); colour
  slots are grouped into named fieldsets (Window/Modules/Text) instead
- Panel split into panel/{PanelHeader,PresetPicker,PaletteTabs,
  ExportActions}.tsx to stay under the file-size limit
- Preset chips got a real swatch (accent dot over a mini card
  gradient) -- previously same-hued presets like Classic/Blue/Azure
  all read as identical blue dots
- Copy/share buttons confirm inline ("Скопировано"/"Ссылка
  скопирована"); import/clipboard failures now surface a message
  instead of failing silently
- Rewrote themes copy to match the landing's voice

Claude-Session: https://claude.ai/code/session_01F1M1Jic1wTSn4igUENynmZ
2026-09-30 10:28:59 +02:00
70e33f290f
fix(download): keep the GitHub label visible under the ribbon 2026-09-29 18:53:52 +02:00
fc440f0c91
feat(download): two-button page with the jar served by our backend 2026-09-29 18:39:40 +02:00
9d423456af
feat(frontend): landing redesign, mock/fake-data cleanup, Safari fix
Landing:
- Rewrote all landing copy (ru/en): removed the tracked-caps eyebrow
  chrome pattern everywhere, active-voice player-facing text
- ThemeStrip: full-bleed live-recolored ClickGui window instead of a
  boxed swatch panel; HudPlayground: full-size real HUD screen
- ShowcaseTeaser: dropped the fake "example" fallback cards, shows an
  honest empty state when there aren't 3 real configs yet
- Fixed VoxelScene parallax leaking outside the hero into the HUD
  section

Data accuracy: the module list/counts advertised InvisESP, BlockESP
and FakeLag — all three were removed from the mod earlier this
session as cheat modules. Corrected the catalogue and the 88/52
module-count claims to the real 86/50.

Design QOL pass: removed the same eyebrow-label chrome from the site
footer; replaced plausible-looking fake share codes (howItWorks demo
slots, the chat command typing demo) with an explicit placeholder
string so they read as illustration, not fabricated real data.

Perf: promoted .lv-lower-bg onto its own compositor layer
(will-change/translateZ) — a full-height, multi-gradient, masked,
continuously-animated background layer was repainting on every
scroll tick in Safari.

Claude-Session: https://claude.ai/code/session_01F1M1Jic1wTSn4igUENynmZ
2026-09-29 17:22:02 +02:00
3f679b83f6
feat(frontend): default site theme to Amber instead of Classic
New visitors (no saved lv_theme) now get the Amber accent; reconciled the
static CSS accent, demo scene colors and console greeting to match so there
is no blue/emerald flash before the theme provider applies. Updated the
default-theme assertions in the theme tests.
2026-09-29 10:55:18 +02:00
eb854c32da
feat(frontend): switch the default site accent from cyan to emerald
Recolor the site-level --color-ice default and glow from #5cc8e7 to #34d399
and align the decorative VoxelScene/ParticleField accent and the DevTools
greeting. ClickGui/mod theme accents (classic preset) are left untouched; the
avatar success notice now reads as positive green via tone=success.
2026-09-29 10:14:18 +02:00
e8b77fb0a5
fix(frontend): avatar history strip fills in without a reload
addAvatarHistory was fired off without awaiting, then the history tick was
bumped immediately, so the strip re-read IndexedDB before the write landed and
only populated after a remount. Await the write before bumping the tick.
2026-09-29 10:14:18 +02:00
fd2e29cede
feat(frontend): avatar upload QOL — feedback, re-crop, drop, progress, history
Task 12 batch around the existing crop/preview flow:
- Success Notice (auto-dismiss ~2.5s) after an avatar upload.
- "Reposition" re-crops the current avatar without re-picking a file.
- Drag & drop an image straight onto the profile avatar circle.
- Real upload progress via a new XHR-backed api.upload (fetch has none);
  refreshOnce now also stores the renewed token (reload-restore fix).
- Local avatar history (last 5, IndexedDB, this-device-only) strip that
  re-uploads a stored crop. Stored as ArrayBuffer (Blob is not cloneable
  under structuredClone); label makes the per-device scope explicit.
- Added a "success" tone to Notice.

Infra (same session): registered @shared/@features/@pages/@app/@test path
aliases in vite.config + tsconfigs and rewrote deep ../../../ imports;
moved avatar components into components/avatar/ to keep folders at <=4 files.

Tests: avatarHistory cap/order, recrop visibility, drop-opens-cropper,
client upload/progress/401-retry. bun test 103 pass, lint 0 errors, build ok.
2026-09-28 22:56:01 +02:00
e79b0aedd2
fix(download): serve lovisual.jar from our own origin, not GitHub
The download button pointed at a github.com releases redirect and the
changelog at the GitHub API — both unreachable if GitHub itself is
blocked for a visitor. The button now links to /downloads/lovisual.jar,
served directly from the site's own nginx. Release notes still read
the GitHub API (already degrades gracefully to an empty-state message
if that fails) since that's changelog content, not the actual download.

Claude-Session: https://claude.ai/code/session_01F1M1Jic1wTSn4igUENynmZ
2026-09-28 22:32:21 +02:00
f97f1a7117
feat(frontend): add a proper 1200x630 og:image for link previews
Square favicon.png was a weak og:image. Renders the same pixel-heart
mark next to the wordmark and tagline on the site's dark background.

Claude-Session: https://claude.ai/code/session_01F1M1Jic1wTSn4igUENynmZ
2026-09-28 22:26:38 +02:00
e0531eda5e
fix(frontend): session cookie path, browser-language default, avatar crop, EN link previews, topbar logo
- nginx: rewrite the refresh cookie's Path=/auth to /api/auth on the
  production proxy — without this the browser never sent the cookie
  back on POST /api/auth/refresh and the session was lost on reload
- i18n: fallbackLng ru -> en, so only an actual ru browser locale
  defaults to Russian, everything else defaults to English
- index.html: explicit English og:*/twitter:* tags so link previews
  in Discord/etc. don't fall back to the (Russian) meta description
- Avatar upload: pick -> circular crop/reposition/zoom preview ->
  confirm -> upload, instead of uploading the raw file blind
- Topbar: logo pill background removed, pixel-heart mark added next
  to the LoVisual wordmark
- Fixed two tests left stale by the earlier tagline copy change

Claude-Session: https://claude.ai/code/session_01F1M1Jic1wTSn4igUENynmZ
2026-09-28 22:23:28 +02:00
fc0e125e62
feat(brand): 3D pixel-heart icon and updated site tagline
- Site favicon/mod icon: aligned voxel heart mark with lightning-bolt
  side notches, crisp pixel edges, centered bounding box
- Landing hero + meta description updated to "visuals you'll fall in
  love with" (RU/EN), no em dashes
- fabric.mod.json now points at the new mod icon asset

Claude-Session: https://claude.ai/code/session_01F1M1Jic1wTSn4igUENynmZ
2026-09-28 22:14:14 +02:00
0ecb4635d1
docs: add a real root README and rewrite the frontend one
The repository had no root README at all, and frontend/README.md was
still the stock Vite template. Add a bilingual (EN/RU) overview covering
the mod, site, and backend plus how they connect (%link, %config
save/load), replace the frontend README with the actual stack, layout,
and scripts, and fix the mod README's broken DEVELOPMENT.md link to
point at DEV_GUIDE.md.
2026-09-28 17:28:41 +02:00
904c724c9f
feat(frontend): breakable grass block on the 404 page
Implements the last unbuilt easter egg (PLAN Task 11 #5, TODO «Пасхалки» #5): the
404 used to show static ASCII art; now a grass block drops into a dusk world,
cracks over three clicks, then bursts into square debris and respawns. Keyboard
accessible (a real button), and under prefers-reduced-motion the fall and burst
are skipped while the crack stages still work. Replaces the NOT_FOUND_ART pane;
i18n adds notFound.blockAria/blockHint (ru+en).
2026-09-28 13:51:00 +02:00
07b3f55bee
fix(frontend): localize avatar validation errors
checkAvatarFile returned hard-coded Russian strings, so an English user picking a
bad file got "Подойдёт PNG, JPG или WebP." with no translation. Route both
messages through the account namespace (validation.avatarType / avatarTooBig) the
same way the auth validators take a t function, keeping ru/en key parity enforced
by the satisfies clause.
2026-09-28 13:35:29 +02:00
fd0fe59fee
test(frontend): lock the style invariants a QA pass keeps re-finding
Two defects in this QA pass were pure CSS drift with no test surface at all:
100vw full-bleed sections panning the document by a scrollbar's width, and
controls sitting on three different corner radii. Assert both against the
sources, so the next person who hard-codes a radius or drops an overflow-x
guard fails CI instead of failing a screenshot review.

Tests now read files off disk, so they live in their own tsc project
(tsconfig.test.json, node types) excluded from the browser build.
2026-09-28 13:27:15 +02:00
1c94e0ebea
refactor(frontend): bring shared/ui and pages/public under the 4-file rule
Two directories had grown past the plan's ≤4 files per folder constraint:
shared/ui (5 primitives, and the kit keeps growing) and pages/public (5 pages,
counting auth/ as a subfolder).

Split shared/ui by concept — text-field/ and share-code/ each with their own
tests/ — and move PageTitle to shared/layout, where the rest of the page chrome
lives. Flat UI tests become per-component tests; the PageTitle test follows the
component. Move LoginPage and RegisterPage into the existing pages/public/auth/
beside the AuthSplit layout they both use.

No behaviour change: 83 tests, clean tsc build, 1 known oxlint warning.
2026-09-28 13:21:18 +02:00
456366006e
feat(frontend): unify control radius on one token
Buttons and inputs in the kit used rounded-md (6px) while the landing CTAs
hard-coded 0.6rem (9.6px), so a form row could mix three different corners.
Add --radius-ctl (10px, matching --radius-panel), point every interactive
control at it via rounded-ctl and make the CTAs consume the same variable.

Drop the unused ButtonAnchor helper.
2026-09-28 13:16:59 +02:00
7bb981b58e
feat(frontend): visual QA pass — unified page titles, CTAs, native controls, 404 fixes
- add PageTitle and apply it on /download, /themes, /configs, /showcase, /link, 404
- reset range-slider thumbs in the theme editor; fold color picker into the swatch
- hide horizontal scrollbars in the ClickGui mock; clip html to kill 100vw pan
- pin the footer under short pages via flex AppShell; split 404 art from caption
- one landing CTA geometry (lv-cta-lg / quiet); CLOUD eyebrow; auth caption scrim
- showcase error hides sort/pager; query retry limited to 1
2026-09-28 13:11:46 +02:00
ff2edc8eb6 chore(history): squash 16 commit(s) from 2026-09-26
- chore(backend): sync Cargo.lock with gateway dev-dependency
- feat(frontend): ClickGui replica matching the in-game GUI — category panels, Modules/Settings switch, theme cards
- feat(frontend): floating glass top bar in the mod's UI language
- fix(frontend): soft night backdrop for the ClickGui, editor that fits one screen
- chore(frontend): replace em dashes in UI copy with lighter separators
- refactor(frontend): split landing sections and theme editor into subfolders (4-files-per-folder rule)
- feat(frontend): login and registration in the mod's glass panel style
- feat(frontend): link the game with a device code
- feat(frontend): account page with avatar upload and linked games
- feat(frontend): my configs with share codes and publishing
- feat(frontend): public showcase listing and detail pages
- chore(frontend): drop em dashes from visible copy
- feat(frontend): atmospheric backdrop, glass download block and ClickGui-style FAQ on the landing
- feat(frontend): Konami code, DevTools console greeting and ASCII 404 block
- feat: public player profiles at /u/:id and author link in the showcase
- fix(frontend): stop the theme editor overflowing horizontally at 375px
2026-09-26 15:26:37 +02:00
7f4b532f99 chore(history): squash 67 commit(s) from 2026-09-25
- feat(accounts): persist device links with opaque hashed tokens, list and revoke endpoints
- feat(frontend): app shell, routing and landing page with the chat-command hero
- feat(frontend): Cyrillic-first fonts (Unbounded, Onest, JetBrains Mono); add i18next and motion
- docs: free mod, bilingual site, one-click download, theme editor, public profiles, rich landing in plans
- feat(accounts): internal gRPC AuthenticateDevice guarded by internal key
- feat(frontend): ru/en i18n with typed per-feature dictionaries and language switch
- feat(accounts): GET /me profile endpoint
- feat(gateway): scaffold crate with config validation and health check
- feat(gateway): reverse proxy to accounts and configs services
- feat(gateway): resolve identity once from access JWT or device token via gRPC
- feat(gateway): per-route and global rate limits with Retry-After
- feat(gateway): CORS for the site origin; docs for gateway and internal contract
- feat(configs): scaffold service with schema, config validation and health check
- feat(configs): four config slots per account with list, get and save
- feat(configs): permanent share codes with regenerate and public load-by-code
- feat(accounts): GetPublicProfiles gRPC for showcase author info
- style(accounts,common): apply rustfmt to existing sources
- feat(configs): public showcase with publish, browse, detail and copy-to-slot
- feat(backend): public profile endpoint and showcase author filter
- fix(gateway): silence clippy collapsible-if and needless-ref warnings
- docs(backend): configs-service implemented; Подсистема 1 backend complete
- feat(mod): add Optimize module skeleton with OptimizeState holder
- feat(mod): gate glass blur behind Optimize no_glass knob
- feat(mod): cut MotionBlur and DoF sample counts behind lite_post knob
- feat(mod): trim procedural sky noise behind lite_sky knob
- feat(mod): drop fade gradients and digit rolls behind lean_hud knob
- docs(todo): mark Optimize module phase 9.2 complete
- refactor(mod): drop dead Renderer2D compatibility shims
- refactor(mod): prune unreachable Renderer2D overload towers
- refactor(mod): remove unused Renderer2D overloads and imports
- docs(todo): mark Renderer2D giant-splitting done (2179 to 1597)
- refactor(mod): extract shader id constants from LoVisualRenderPipelines
- docs(todo): record registry wave 2026-09-25 (Renderer2D, pipelines)
- refactor(mod): move Renderer2D instance state into base class
- refactor(mod): extract Renderer2DRounded drawing family
- refactor(mod): extract Renderer2DPath connector and chamfer family
- refactor(mod): extract Renderer2DShapes circle line and texture primitives
- refactor(mod): extract Renderer2DGlass and Renderer2DItem families
- refactor(mod): prune Renderer2D imports after facade split
- docs(todo): record Renderer2D facade inheritance split (1597 to 475)
- docs: easter eggs — .env honeypot, konami troll mode, devtools banner, IDDQD config, breakable 404 block, 418 teapot
- feat(mod): introduce surface style system core (SurfaceStyle, StyleSpec, StyleConfig, SurfaceRenderer)
- refactor(mod): delegate HudRenderUtil liquid glass draws to SurfaceRenderer (dedupe glass constants)
- refactor(mod): route bespoke glass call sites through SurfaceRenderer.plateSpec
- feat(mod): add Auto option to HUD bg effects via shared HudBgStyles resolution
- feat(mod): flat fallback for no-glass optimize mode and persist global HUD config
- feat(mod): default HUD bg effects to Auto so the global surface style drives widgets
- feat(mod): add global cycle-style hotkey with surface style notification
- feat(mod): add surface style swatch strip under the global style picker
- feat(gateway): reject ambiguous paths and answer .env probes with a honeypot
- fix(gateway): charge failed credentials against the rate limit, allow stale ones on /auth
- feat(frontend): ClickGui theme pipeline generated from the mod, live site theming
- feat(frontend): landing v2 hero — voxel/particle backdrop, live ClickGui, theme strip
- docs(todo): drop the FPS A/B measurement from phase 9.3, close phase 9
- feat(gateway): answer /coffee with a 418 teapot
- feat(frontend): land the rest of landing v2 — HUD, module wall, showcase, FAQ, footer
- feat(frontend): one-click download from GitHub releases, changelog page, release CI
- feat(frontend): theme editor with live ClickGui preview, mod-compatible export and share links
- fix(frontend): landing HUD playground now shows real mod widgets (fps, coordinates, module list, keybinds, ping)
- style(frontend): apply ClickGui glass effect to landing HUD playground widgets
- fix(frontend): prevent color field row overflow in theme editor grid
- fix(frontend): never attach stale bearer token to /auth/* requests
- fix(configs): unpublish/publish can no longer bypass moderation
- refactor(accounts): shrink auth/handlers.rs under the 250-line cap
- fix(accounts): tolerate concurrent refresh without killing every session
- fix(gateway): minor hardening from the backend review
- feat(configs): IDDQD easter egg config
2026-09-25 20:22:13 +02:00
72bc4c7148 chore(history): squash 100 commit(s) from 2026-09-24
- fix(backend): case-insensitive unique email, revoke PUBLIC schema access, pin Argon2id params
- test(backend): assert password length cap boundary (256 ok, 257 rejected)
- docs(backend): plan — typed JWT token kinds so refresh/device tokens cannot pass as access tokens
- feat(backend): JWT access/refresh token issue and verify
- feat(backend): accounts repository (create/find_by_email/find_by_id)
- refactor(gui): LoVisualAddonManagerScreen 989→10 файлов addon/ (8.5.2)
- docs(backend): plan — fix sqlx::migrate! path in integration tests
- feat(backend): POST /auth/register and /auth/login
- refactor(settings): SettingsPanelComponent 715→81 + 6 helpers (8.5.2)
- docs(backend): plan — harden device flow (single-use codes, bounded store, 404/429)
- feat(backend): OAuth device authorization grant for mod login
- fix(backend): first confirm wins for device codes
- docs(backend): plan — split Task 8 (refactor) and Task 9 (avatars), harden avatar handling
- refactor(mixins): LocalPlayerMixin 691→111 + 4 handlers (8.5.2)
- refactor(visuals): Trails 687→130 (8.5.2)
- refactor(render): ItemBatchRenderer 677->100 (8.5.2)
- refactor(visuals): ReimaginedVisual 674→118 + 5 helpers (8.5.2)
- refactor(config): ConfigSerializer 668→91 + 4 helpers (8.5.2)
- refactor(hud): DynamicIsland 661→158 + 4 helpers (8.5.2)
- refactor(render): GlStencilFramebufferSupport 666→169 (8.5.2)
- refactor(gui): MenuScreen 669→128 + 4 helpers (8.5.2)
- refactor(render): UiStyle 644→170 + 3 helpers (8.5.2)
- refactor(gui): ModuleComponent 613→98 + 4 helpers (8.5.2)
- refactor(media): MediaSessionService 616→200 + 4 helpers (8.5.2)
- refactor(gui): RelationsComponent 661→59 + 4 helpers (8.5.2)
- chore(license): strip GPL file headers from all Java sources
- refactor(aiming): PointTracker 583→168 + 2 helpers (8.5.2)
- refactor(gui): LoVisualProxyManagerScreen 591→132 + 2 helpers (8.5.2)
- refactor(visuals): KillEffect 588→96 + 4 helpers (8.5.2)
- refactor(render): MeshBuilder +4 helpers (8.5.2)
- refactor(visuals): extract WorldParticlesRender helper (8.5.2)
- refactor(world): ExplosionDamageUtil 551→116 + 2 helpers (8.5.2)
- refactor(visuals): TazikHat 596->179 + Model + Palette in hats/tazik (8.5.2)
- chore(license): strip GPL header from remaining 30 files and make strip script variant-aware
- refactor(gui): ThemeComponent 561->166 + CardRenderer + ScrollState (8.5.2)
- refactor(hud): CustomHotbar 556→178 + Renderer + Selection + SelectionGradient (8.5.2)
- refactor(gui): ThemeCardRenderer perf + readability polish
- refactor(clickgui): CooldownRulesSetting 596->198 + Editor + DetailRenderer (8.5.2)
- refactor(hud): HudNotifier 561->200 + Painter + runtime/HudNotifierRuntime (8.5.2)
- refactor(theme): Themes 555->168 + impl/Transition + impl/Blending + impl/ProfileCodec (8.5.2)
- refactor(theme): EditableClickGuiTheme 205->185 + JavaDoc (8.5.2)
- refactor(theme): ThemeStore 491->128 + store/ThemeStoreJson + store/ThemeStoreIO (8.5.2)
- refactor(clickgui): ClickGuiRenderer 604->200 compacted one-line delegators + JavaDoc (8.5.2)
- refactor(mainmenu): LoVisualMainMenuScreen 551->161 + impl/Painter + impl/Renderer + impl/TextUtil (8.5.2)
- refactor(clickgui): ClickGuiTextEditorState 531->187 + impl/EditorCaret + impl/EditorPainter (8.5.2)
- refactor(tab): TabListModel 525->139 + model/Collector + model/Reader + model/Signature + model/TextSplitter (8.5.2)
- refactor(backend): shared bearer helper and test helpers, build_app takes Config, validate JWT secret strength
- refactor(module): ModuleManager 521->198 + impl/Registrar + impl/Dispatcher (8.5.2)
- feat(backend): avatar upload with decode, square crop, PNG re-encode and S3 storage
- refactor(clip): ClipFunction 512->146 + impl/Geometry + impl/Debug (8.5.2)
- docs(backend): implementation plans for gateway (auth hardening, gRPC, rate limits) and configs-service
- refactor(iris-patch): ShaderPatchEngine 499->146 + impl/Repo (8.5.2)
- chore(frontend): add router, react-query, fonts and vitest; dev proxy to gateway
- refactor(hud): ScriptedListHudPanel 499->158 + panel/Props + panel/Signature (8.5.2)
- refactor(hud): BaseHudElement 499->199 + impl/Registry + impl/Namer + impl/Prewarm (8.5.2)
- refactor(clickgui): Setting 498->170 + impl/Localization + impl/I18n (8.5.2)
- refact(viewmodel): split swing animations into camera/swing package
- refact(kineticlyrics): split module into stage, playback and modes
- rename(holeesp): module HoleESP -> CrystalHoles
- refact(crystalholes): split module into crystal scanner, renderer and safety
- refact(addonmanager): split manager into lifecycle, runtime, descriptors and profiles
- refact(accountconfig): split config into store, session and value helpers
- refactor(render): CustomTextRenderer 229->195, extract glyph-pass into GradientTexts helper
- docs(TODO): mark AddonManager split done; close 9.2 refactor gate
- refactor(media): LinuxMediaSession 441->148, split reader + track/seek state
- refactor(nametags): split NameTags into facade + impl helpers
- refactor(clickgui): split MainSettingsComponent into facade + scroll + model
- refactor(hud): split CustomBar into facade, model and BarSettings
- docs(frontend): implementation plan with design system from the mod theme
- feat(frontend): design tokens from the mod theme, fonts and shared UI kit
- fix(accounts): run migrations on startup, offload Argon2, validate register input, JSON error shape
- docs(gateway): plan note on splitting auth handlers before refresh endpoints
- feat(frontend): API client with silent refresh, error descriptions and test helpers
- style(mod): group compact one-line bulk query methods in ModuleManager
- feat(frontend): session restore, login and registration with client-side validation
- refactor(hud): split CustomHealthBar into facade + painter + script renderer
- docs(mod): record the 2026-09-24 HUD/settings split wave in TODO phase 8.5
- refactor(rhi): split GlStencilShapeClipBackend into facade + native-state + pass-lifecycle helpers
- refactor(rhi): split VulkanRenderStateBridge into facade + MSAA and stencil state helpers
- refactor(backtrack): split BacktrackController into facade + model + impl helpers
- refactor(svg): split SvgPathParser into facade + arc geometry + command/curve helpers
- refactor(mixin): split ClientPacketListenerMixin into hook-only mixin + handlers
- refactor(renderer3d): un-nest batch bindings + culling into sibling impl types
- refactor(renderwarp): extract static factories + geometry into impl helpers
- feat(backend): add common crate with shared JWT, internal gateway contract and accounts proto
- refactor(guimixin): move hook bodies into handlers, keep mixin as hooks + shadows
- feat(accounts): accept only gateway traffic, read identity from gateway header
- refactor(cacheduiscriptruntime): extract engine, hashing and frame stats into impl
- refactor(customskyboxrenderer): extract projection, shader passes and sun into impl
- refactor(betterchatstoremanager): extract persistence, key/path and hover helpers into impl
- feat(accounts): rotating opaque refresh tokens in httpOnly cookie, /auth/refresh and /auth/logout
- refactor(targetesp): extract crystal rendering subsystem into impl/TargetEspCrystalRenderer
- refactor(betterchathovercache): extract disk codec and lookup indexing into impl/ChatHoverCacheCodec
- refactor(microsoftauth): split HTTP transport, device-code and Xbox flows into impl/
- refactor(pvpcooldowns): extract local item-rule engine and defaults into impl/PvpCooldownRules
- refactor(lovisual): extract HUD/world render orchestration into HudRender helper
- refactor(statuseffectheuristics): extract palette/inference into ParticlePalette and color utils into ParticleColors
- refactor(dropesp): extract overlay/label render subsystem into impl/DropEspOverlayRenderer
- refactor(proxy): extract SOCKS handshake message builders into ProxyProtocolMessages
- refactor(eagleutil): promote EdgeRecovery controller and RecoveryMode to top-level class
2026-09-24 23:52:12 +02:00
9d08fa910a chore(history): squash 59 commit(s) from 2026-09-23
- refactor(hud/weather/render): Scoreboard 931→240 + Rain 903→159 + UiMeshGeometry 956→99 (8.5.2)
- refactor(chams): Chams 985 → 129 + 4×≤195 (8.5.2)
- refactor(module): Module 1031 → 139 + 4×≤134 (8.5.2)
- refactor(tooltips): BetterTooltips 960 → 181 + 4×≤199 (8.5.2)
- refactor(clickgui): ClickGuiPickerState 970→166 + ModulesMenuScreen 966→145 (8.5.2)
- refactor(clickgui): CombatProtocolHeuristicsEditorState 932→79 + 4×≤192 (8.5.2)
- refactor(hud): CompactHudStatModel 894 → 125 + 4×≤175 (8.5.2)
- refactor(iris): ShaderPatchCompiler 843→66 + 4×≤174 (8.5.2)
- refactor(tab): CustomTabList 834→136 + 4×≤166 (8.5.2)
- refactor(relations): OnlineRelationPlayerPickerComponent 837→74 + 4×≤192 (8.5.2)
- refactor(hits): HitEffect 770→120 + 4×≤176 (8.5.2)
- refactor(predict): Predictions 815→150 + 4×≤195 (8.5.2)
- refactor(config): ConfigProfilesComponent 799→125 + 4×≤195 (8.5.2)
- refactor(sim): PlayerMovementSimulation 757→157 + 4×≤194 (8.5.2)
- refactor(predict): ProjectilePuncher 747→104 + 3×≤134 (8.5.2)
- refactor(crosshair): Crosshair 743→143 + 4×≤167 (8.5.2)
- refactor(mediaplayer): MediaPlayer 743→174 + 4×≤196 (8.5.2)
- refactor(hud): Itemizer 699→193 + Cooldowns 707→151 (8.5.2)
- refactor(hud): Potions 617→176 + 4×≤166 (8.5.2)
- refactor(hud): Admins 702→118 + 4×≤138 (8.5.2)
- refactor(hud): Keybinds 611→157 + 4×≤160 (8.5.2)
- refactor(hud): ModuleList 499→181 + 3×≤150 (8.5.2)
- refactor(hud): Radar 392→161 + 2×≤124 (8.5.2)
- refactor(hud): Fps 309→168 + 3×≤107 (8.5.2)
- refactor(hud): Memory 304→151 + 3×≤144 (8.5.2)
- refactor(hud): Tps 339→154 + 3×≤143 (8.5.2)
- refactor(hud): Ping 309→145 + 3×≤125 (8.5.2)
- refactor(hud): SpeedBps 334→156 + 3×≤142 (8.5.2)
- refactor(hud): GameTime 314→150 + 3×≤127 (8.5.2)
- refactor(hud): SystemTime 300→136 + 3×≤130 (8.5.2)
- refactor(hud): Coordinates 337→174 + 2×≤172 (8.5.2)
- refactor(hud): Armor 324→162 + 2×≤148 (8.5.2)
- refactor(hud): Inventory 476→153 + 3×≤181 (8.5.2)
- docs(todo): обновлён 8.5.2 — отмечены готовые гиганты (BetterButtons/InventorySwap/Svg/Темы/WorldParticles/Module/Chams и хвост)
- docs(api): папка combatant-client-26.2/docs + addons.md (API можно ломать при рефакторе)
- refactor(visuals): BlockHighlight 692→271 + 4×≤200 (8.5.2)
- refactor(mixins): GameRendererMixin 830→344 (хуки) + 4 хелпера (8.5.2)
- refactor(visuals): WorldParticles 821→260 + 6×≤200, режимы добиты (8.5.2)
- docs(todo): 8.5.2 — WorldParticles/GameRendererMixin/BlockHighlight отмечены ГОТОВО
- refactor(render): MeshBuilder 738→447 (фасад write-API) + 3 хелпера, FrameStats снесён (8.5.2)
- docs(todo): Фаза 10 — дизайн платформы (аккаунты/конфиги/аватарки), backlog RPC-чата
- docs(todo): Подсистема 3 — Аддоны 2.0 (скрипты/версии) + витрина аддонов + админка
- docs(todo): Подсистема 2 — RPC-чат/друзья/виджеты-телеметрия + рейт-лимиты, доп. правки Подсистемы 3
- chore: переименование combatant-client-26.2 -> mod, добавлены backend/ и frontend/
- docs(backend): implementation plan for accounts-service (Подсистема 1, часть 1)
- chore: пересоздать backend/frontend через cargo new и bun create vite + tailwind; убрать таблицу компонентов из TODO.md
- docs(backend): edition 2024 в плане вместо 2021
- chore: обновить версии до реально актуальных (проверено компиляцией)
- docs: правила платформы (лимит 250 строк, антипаттерны backend/frontend по итогам ресёрча) + frontend/ARCHITECTURE.md
- docs: добавить правило ≤4 файла на папку в правила платформы (backend/frontend)
- docs: commit messages in English from now on
- chore: gitignore .superpowers/ scratch directory
- docs: commit messages in English from now on (mod)
- feat(backend): scaffold accounts-service with health check
- chore(backend): remove target/ build artifacts from git, add gitignore
- chore: track docs/ in git (was accidentally gitignored, never committed)
- chore(backend): convert to Cargo workspace, plan full microservice layout
- feat(backend): accounts/avatars/device_links schema + migration
- feat(backend): argon2id password hashing
2026-09-23 22:38:08 +02:00