-
v0.2.0
StableSome checks failedcheck-secrets / Nosey parker (push) Successful in 3sPublish release artifacts / Build + publish lets-chat-desktop binaries (push) Failing after 3scheck-secrets / Kingfisher (push) Successful in 9scheck-secrets / TruffleHog (push) Successful in 16sBuild desktop (Windows) / Build desktop (Windows x86_64) (release) Successful in 3m36sBuild desktop (Linux) / Build desktop (Linux x86_64) (release) Successful in 4m55sCheck / clippy + fmt + tests (push) Successful in 5m56sBuild desktop (Windows) / Build desktop (Windows x86_64) (push) Successful in 8m36sBuild OCI container / Build and push lets-chat (push) Successful in 12m5sBuild desktop (Linux) / Build desktop (Linux x86_64) (push) Successful in 15m16sreleased this
2026-07-23 05:41:48 +02:00 | 190 commits to main since this releaseChangelog
8bb8b6ddMerge pull request 'Release v0.2.0' (#581) from release/v0.2.0 into main
aa755a55Release v0.2.0
db192d53Merge pull request 'Reactions on thread replies, in their own id namespace (LC-595)' (#580) from feat/lc595-thread-reactions into main
120c7096feat(reactions): reactions on thread replies, in their own id namespace (LC-595)
c0960d00Merge pull request 'STT cost/load control: bounded concurrency, rate limits, scope gating (LC-592)' (#579) from feat/lc592-stt-load-control into main
a4b430f6feat(stt): bound STT concurrency, rate, and scope (LC-592)
5ca2d38dMerge pull request 'STT reliability: timeout, retry, and surfaced failure state (LC-590)' (#578) from feat/lc590-stt-reliability into main
57f5b364feat(stt): timeout, retry, and surfaced transcription failures (LC-590)
a456a957Merge pull request 'STT provider seam with native Deepgram support (LC-593)' (#577) from feat/lc593-stt-providers into main
f6207c32feat(stt): provider seam with native Deepgram support (LC-593)
31e3b434Merge pull request 'STT language + prompt hinting and real segment timestamps (LC-591)' (#576) from feat/lc591-stt-accuracy into main
c9d41fb0feat(stt): language + prompt hinting and real segment timestamps (LC-591)
299efaa5Merge pull request 'Extract the shared bus-drain and control-dispatch machinery (LC-616)' (#575) from refactor/lc616-rtc-machinery into main
5dfa68farefactor(rtc): extract the shared bus-drain and control-dispatch machinery (LC-616)
2b651922Merge pull request 'Unify the call/huddle session lifecycle across the clients (LC-613)' (#574) from refactor/lc613-converge-rtc-clients into main
2035f1b7refactor(rtc): unify the call/huddle session lifecycle across the clients (LC-613)
4788c6b0Merge pull request 'Cover the 1:1 ring and huddle WS handlers (LC-614)' (#573) from test/lc614-call-huddle-coverage into main
82b46e08test(call): cover the 1:1 ring and huddle WS handlers (LC-614)
b1181b7fMerge pull request 'Show an in-call indicator when a room has an active huddle (LC-612)' (#572) from feat/lc612-sidebar-incall into main
47c40a40feat(sidebar): show an in-call indicator when a room has an active huddle (LC-612)
cb0a98e4Merge pull request 'Carry huddle media over the SFU when LiveKit is configured (LC-610)' (#571) from feat/lc610-sfu-huddle-media into main
efb81bfffeat(huddle): carry huddle media over the SFU when LiveKit is configured (LC-610)
2aa94c7cMerge pull request 'Ring room members when a huddle starts (LC-611)' (#570) from feat/lc611-huddle-ring into main
396bee65feat(huddle): ring room members when a huddle starts (LC-611)
0694c301Merge pull request 'Mint SFU tokens for huddles, and stop stages colliding with them (LC-596)' (#569) from feat/lc596-sfu-huddle-tokens into main
ccd9649bfeat(huddle): mint SFU tokens for huddles, and stop stages colliding with them (LC-596)
aef25047Merge pull request 'Transcribe a Stage, gated to whoever holds the floor (LC-597)' (#568) from feat/lc597-stage-transcription into main
5a82f556feat(stage): transcribe a Stage, gated to whoever holds the floor (LC-597)
9e2f8b1dMerge pull request 'Tell an unkeyed build why it cannot self-update (LC-607)' (#567) from fix/lc607-updater-fails-before-network into main
08b4f0e9fix(desktop): tell an unkeyed build why it cannot self-update (LC-607)
b2456479Merge pull request 'Drop the DELETE FROM rooms crutch from the onboarding fixture (LC-603)' (#566) from test/lc603-onboarding-reachability into main
ddec0a54test(home): drop the DELETE FROM rooms crutch from the onboarding fixture (LC-603)
81f651ddMerge pull request 'Make the login-approval attempt cap atomic (LC-608)' (#565) from fix/lc587-atomic-attempt-cap into main
cc3f5835fix(auth): make the login-approval attempt cap atomic (LC-608)
3a050333Merge pull request 'Fail fast on missing psa-systems org secrets, and stop shipping the old org's update URL (LC-594)' (#564) from chore/lc594-psa-systems-ci-secrets into main
0abe6bbffix(ci): correct the package owner to psa-systems-private
ded73692chore(ci): fail fast on missing psa-systems org secrets, fix stale update URL
f602242eMerge pull request 'Gate DM Delete on the effective room role, not the org role (LC-599)' (#563) from fix/lc599-dm-delete-uses-effective-role into main
fb812cfffix(dm): gate Delete on the effective room role, not the org role
e612bb6cMerge pull request 'Scope the remaining room-visibility queries to the viewer's enclaves (LC-606)' (#562) from fix/lc606-scope-remaining-room-queries into main
cc851be1fix(db): scope the remaining room-visibility queries to the viewer's enclaves
c4c64938Merge pull request 'Run the integration tests in CI, and make the fixture check real (LC-605)' (#561) from fix/lc605-ci-runs-integration-tests into main
b242f179ci: run the integration tests, and make the fixture check real
9590fceeMerge pull request 'Scope unread inbox + dashboard queries to the viewer's enclaves (LC-604)' (#560) from fix/lc604-inbox-enclave-scoping into main
550069c2fix(inbox): scope unread queries to the viewer's enclaves
98a05c65Merge pull request 'Cover both branches of / after the LC-575 dashboard (LC-600)' (#558) from fix/lc600-home-branch-tests into main
9bbadc1cMerge pull request 'fix(auth): make login-approval consume atomic to close a TOCTOU (LC-601)' (#557) from fix/LC-601-login-approval-consume-toctou into main
dfae0903test(home): cover both branches of / after the LC-575 dashboard
b1ce19e7fix(auth): make login-approval consume atomic to close a TOCTOU (LC-601)
28352522Merge pull request 'Group the message overflow menu into scannable sections (LC-598)' (#556) from feat/lc-message-menu-grouping into main
744bfc08feat(room): group the message overflow menu into scannable sections
4018da48Merge pull request 'fix(ci): use the psa-systems package vars after the org move' (#554) from fix/ci-psa-systems-package-vars into main
67d45da6Merge pull request 'feat(auth): notify-and-approve gate for suspicious logins (LC-587)' (#555) from feat/LC-587-suspicious-login-approval into main
add21bb0feat(auth): notify-and-approve gate for suspicious logins (LC-587)
770f3cbefix(ci): use the psa-systems package vars after the org move
526b6e49Merge pull request 'Reactions that actually work, sidebar expand ribbon, huddle transcription' (#553) from feat/sidebar-collapse-ribbon into main
15edf7d6style(reactions): rustfmt the toggle_reaction insert
0b05fbccfeat(transcription): support transcription in huddles
03c8cd4ffeat(sidebar): expand the collapsed sidebar from a ribbon on the rail seam
0f34bf5cfix(reactions): atomic toggle + populate the one-tap quick-react bar
0a153a1ffeat(reactions): working emoji picker from the hover bar; conditional add-more
1b61c3ccfeat(settings): dismiss the settings page by clicking outside it or Escape
e1c66b23fix(thread): make typed text visible in the thread reply box
25557987Merge pull request 'Redesign chat UI to the prototype: rail, sidebar, panels, composer, settings' (#552) from fix/lc-576-active-row-invert into main
3d57cb17fix(composer): stop clipping the paperclip attachment icon
a8a7db56feat(thread): emoji picker for thread replies; fix attachment clipping
28cdbe33style(header): space between the # and the room name
822ec4destyle(timeline): merge adjacent mentioned messages into one accent block
9b8c5044style(composer): shrink the attachment icon so it doesn't clip
06913c8ffix(sidebar): draft indicator is an SVG pencil, not a tofu dingbat
963188bdstyle(settings): full-bleed palette preview cards
1bc3da09fix(rail): hide the profile hovercard while the account menu is open
c59ee614feat(room): close Details/Thread with an X; info toggles Details
cab27504style(composer): stopwatch glyph for the self-destruct timer
54afdc4dfeat(sidebar): render the @-mention badge on DM rows
64e5662fstyle(composer): rework the self-destruct timer into a clock popover
9624a579feat(room): header member avatar stack and correct public-room member count
49efc47estyle(settings,sidebar): 4-up palette cards; shorter search placeholder
c36ce47ffeat(dev): mock OIDC can authenticate multiple identities
5a0f29ccfeat(room,sidebar): right-column collapse, platform-aware ⌘K, search icon
df04002astyle(settings): mini-window palette preview cards
8d233a68style(thread): accent-color the replied-to name in the thread header
ed26a2fbfeat(rail): curated settings dropdown and avatar hovercard
8dd411ebstyle(details,rail): notifications dropdown chevron; accent unread badge
99ae64c7style(settings,timeline): comp-style Appearance controls; bare day divider
fb72feb0style(sidebar): add ⌘K search hint chip and focus binding
4f8c5effMerge remote-tracking branch 'origin/main' into fix/lc-576-active-row-invert
06df7325Merge pull request 'fix(auth): link bunyip_sub onto an existing verified-email account on SSO (LC-588)' (#551) from fix/LC-588-sso-email-link into main
27b1df29fix(auth): link bunyip_sub onto an existing verified-email account on SSO (LC-588)
cf67ebcdMerge pull request 'feat(auth): alert users on a new-country login (LC-580)' (#550) from feat/lc580-login-location-alerts into main
f4072213fix(auth): show the full country name in the login-location alert (LC-580)
11ee2e0afeat(auth): alert users on a new-country login (LC-580)
d498e740Merge pull request 'feat(dev): mock OIDC OP can authenticate for the local dev stack (LC-577)' (#549) from feat/lc577-mock-oidc-auth into main
1135afd6feat(dev): make the mock OIDC OP able to actually authenticate
cb0080ecMerge pull request 'feat(enclave): surface configurable enclave icon on the settings page (LC-542)' (#548) from feat/lc542-enclave-icon-settings into main
9b1b5344feat(enclave): surface configurable enclave icon on the settings page (LC-542)
fc3917cdMerge pull request 'fix(sidebar): invert glyph, draft pencil, and DM status on active row (LC-576)' (#547) from fix/lc576-active-row-invert into main
d11c96b6fix(sidebar): invert glyph, draft pencil, and DM status on active row (LC-576)
a84a1481Merge pull request 'feat(home): Home dashboard (catch-up) + "Open on" landing preference (LC-575)' (#546) from feat/lc575-home-dashboard into main
359e8f73feat(home): Home dashboard (catch-up) + "Open on" landing preference (LC-575)
6db89f97Merge pull request 'fix(i18n): correct Spanish room-details-pinned-yes to «Sí» (LC-579)' (#545) from fix/lc-579-es-pinned-yes-accent into main
6839c2ecfix(i18n): correct Spanish room-details-pinned-yes to «Sí» (LC-579)
689a055fMerge pull request 'chore(css): remove dead .lc-empty-wrap helper (LC-578)' (#544) from chore/lc-578-remove-dead-lc-empty-wrap into main
5d470673chore(css): remove dead .lc-empty-wrap helper (LC-578)
bdee3bc3feat(ui): one profile control in the rail, and rail ordering
7a83cd96feat(ui): one right column of subcards, and rail cleanup
079ad180feat(ui): restructure the sidebar and room header to the prototype
8f736f21feat(dev): make the mock OIDC OP able to actually authenticate
a270f720fix(ui): invert active-row glyphs and align thread/details/header to the prototype
5e327d68Merge pull request 'Apply the prototype new look across Let's Chat (phased)' (#539) from feat/lc-ui-port into main
850a3f5dMerge branch 'main' into feat/lc-ui-port
cee7ac0cMerge remote-tracking branch 'origin/main' into feat/lc-ui-port
1b9c193eMerge pull request 'Rewrite Phase 3 plan with verified literal pixel-match gaps' (#538) from docs/pixel-match-phase3-literal-gaps into main
0aec7dc4test(chat): regenerate message fixtures for the new row geometry
43eef075Merge branch 'main' into docs/pixel-match-phase3-literal-gaps
3bc4a417style(room): give the room-info page the prototype hero
03740847test(dev): mirror the chat surface into the theme gallery
5917e452Merge pull request 'feat(composer): one-row restructure (LC-574)' (#543) from feat/lc574-composer-onerow into main
3211d38fstyle(chat): reconcile the chat surface to the prototype
d2204602feat(composer): one-row restructure (LC-574)
c8f075f9feat(theme): server-persisted UI scaling (compact/default/large/xl)
e7dddbffMerge pull request 'feat(timeline): polish room message hierarchy (LC-558)' (#542) from feat/lc558-timeline-polish into main
33486feffeat(timeline): polish room message hierarchy (LC-558)
b120661fMerge pull request 'fix(a11y): call-button 44x44 tap targets on touch (LC-573)' (#541) from feat/lc573-call-button-tap-targets into main
a5f51a64fix(a11y): call-button 44x44 tap targets on touch (LC-573)
49acefb3Merge pull request 'feat(admin): shared page-header component (LC-572)' (#540) from feat/lc572-admin-page-header into main
385a81c2feat(admin): shared page-header component (LC-572)
07eeeb97style(theme): contrast + surface-separation fixes across all palettes
4da139eedocs(plan): rewrite Phase 3 with verified literal pixel-match gaps
4bfca656Merge pull request 'Mockup pixel-match: amethyst palette + room Details panel' (#537) from docs/lets-chat-mockup-pixel-match into main
133e242eMerge branch 'main' into docs/lets-chat-mockup-pixel-match
a770e987Merge pull request 'docs: redesign completion roadmap + LC-UI tail reconcile' (#536) from docs/LC-553-redesign-tail-roadmap into main
e6cb452ffeat(dev): mock OIDC OP so dev-web-local boots without bunyip
d2e30e67docs(lets-chat): note SSO env requirement for local boot
aeea958adocs(lets-chat): overnight progress log + morning screenshot checklist
b6cc3b99style(connection): theme the connection-status banner via tokens
5d832fe7feat(room): mount Details panel in the room right column
88b81b9afeat(room): add Details panel partial
510a3fd7feat(room): add Details panel locale keys
142c90ffrefactor(room): expose member count and pinned flag to the room page view
6ef017f1fix(theme): render amethyst on load and tint its hc-dark accent surface
9edd1d01feat(theme): show amethyst in dev theme gallery
bc94a7fffeat(theme): add amethyst swatch to settings picker
682df62efeat(theme): allow amethyst palette in backend validation
df605acctest(theme): cover amethyst palette in contrast checker
2f0e88ddfeat(theme): add amethyst violet palette tokens
c54dba37docs(lets-chat): plan the mockup pixel-match overhaul
84cf107edocs(redesign): completion roadmap + tail reconcile
14103395Merge pull request '44px touch targets on the redesign icon controls (coarse pointer)' (#535) from feat/mobile-tap-targets into main
b20f16f2feat(a11y): 44px touch targets on the redesign icon controls (coarse pointer)
a19f294bMerge pull request 'Migrate hand-rolled callout boxes to the .alert component (redesign follow-up)' (#534) from refactor/alert-component-migration into main
1491843arefactor(ui): migrate hand-rolled callout boxes to the .alert component
19e2f028Merge pull request 'LC-565: a11y regression pass - composer focus ring + phantom danger token (redesign P5)' (#533) from fix/LC-565-a11y-regression-pass into main
eda0b36ffix(a11y): composer focus ring + fix phantom danger-surface-content token (LC-565 / LC-UI-12)
350966a2Merge pull request 'LC-564: route login + welcome errors through the shared alert (redesign P5)' (#532) from feat/LC-564-entry-surface-alignment into main
046fa0dcfeat(entry): route login + welcome errors through the shared alert (LC-564 / LC-UI-11)
79a5a4c2Merge pull request 'LC-561: unify admin status indicators onto one chip vocabulary (redesign P3)' (#531) from feat/LC-561-admin-status-chips into main
82b7251efeat(admin): unify status indicators onto one status-chip vocabulary (LC-561 / LC-UI-08)
7b177512Merge pull request 'LC-557: tokenize empty-state color residuals (redesign P3)' (#530) from fix/LC-557-empty-state-residuals into main
bfbf2ebbfix(ui): tokenize empty-state color residuals (LC-557 / LC-UI-04)
b860c6d9Merge pull request 'LC-559: lift the composer onto an elevated card (redesign P2)' (#529) from feat/LC-559-composer-polish into main
0e99d2b0feat(composer): lift the composer onto an elevated card (LC-559 / LC-UI-06)
9dd20357Merge pull request 'LC-566: six-palette theme system foundation (redesign P1)' (#528) from docs/LC-541-redesign-p1-foundation into main
e0fd465cfix(theme): persist palette on select; darkMode hc-dark
8f5101a2fix(theme): repoint JS data-theme reads to data-mode
8641ce03feat(theme): add .lc-table; retune radii/shadow
b29d7d25fix(theme): HC accent AAA + max-contrast ring
1d1202d2feat(theme): dev theme/component gallery
388dcd63fix(i18n): add es keys for palette picker
b7e12fe4feat(theme): appearance picker with palette swatches
6c5f4cb9feat(theme): two-axis no-flash bootstrap (palette + mode)
ceff72f2feat(theme): add 5 palettes across light/dark/hc
fc0ee383refactor(theme): split tokens into constant + palette layers
8591825bfeat(theme): key Tailwind dark: on data-mode
4d6247d2feat(theme): sync lc-mode + lc-palette cookies cross-device
ad4ff3dafeat(theme): persist palette; rename mode cookie to lc-mode
142fefabfeat(theme): db setters for mode + palette
f8d78a35feat(theme): mode + palette accessors on User
c02de9d5feat(theme): split theme pref into mode + palette
39cb409fdocs(redesign): P1 foundation implementation plan
5c9c1b12docs(redesign): P1 foundation design spec
12da86bbMerge pull request 'fix(room): tokenize the inline edit form (LC-558)' (#527) from feat/LC-558-timeline-polish into main
bb733f94fix(room): tokenize the inline edit form so it themes correctly (LC-558 / LC-UI-05)
183d9e81Merge pull request 'feat(sidebar): dark-navy Blue Harbor sidebar + rail (LC-560)' (#526) from feat/LC-560-navy-sidebar into main
9811b614Merge pull request 'feat(css): add .alert* + layout-helper component classes (LC-555)' (#524) from feat/LC-555-alert-classes into main
08b3718bMerge remote-tracking branch 'origin/feat/LC-555-alert-classes' into feat/LC-555-alert-classes
a5ff2636Merge remote-tracking branch 'origin/main' into feat/LC-555-alert-classes
f604320efeat(sidebar): dark-navy Blue Harbor sidebar + rail in all themes (LC-560 / LC-UI-07)
21e202b1Merge pull request 'feat(css): add .lc-page-* width + layout utilities (LC-562)' (#525) from feat/LC-562-page-width-utils into main
0ef4bb19feat(css): add .lc-page-* width + layout utilities (LC-562 / LC-UI-09)
1ee70a70Merge branch 'main' into feat/LC-555-alert-classes
4c65e961feat(css): add .alert* + layout-helper component classes (LC-555 / LC-UI-02)
e5a7dcb9Merge pull request 'feat(css): add --sidebar-* chrome tokens (LC-554 phase 1b)' (#523) from feat/LC-554-sidebar-tokens into main
73a15b8efeat(css): add --sidebar-* chrome tokens for all four themes (LC-554 phase 1b)
c2d94d36Merge pull request 'feat(css): Blue Harbor semantic-token retune (LC-554 phase 1a)' (#522) from feat/LC-554-blue-harbor-tokens into main
ea4326f0feat(css): retune semantic tokens to Blue Harbor (LC-554 phase 1a)
8fcc6da4Merge pull request 'feat(enclave): graduated member trust + posting gate (LC-551)' (#521) from feat/LC-551-trust-levels into main
bb017eedtest(routes): graduated member trust coverage (LC-551)
1591c009feat(enclave): trust pill + manual promote in the member list (LC-551)
37014a60feat(room): gate new-member posting rate and auto-graduate on send (LC-551)
8a05b362feat(db): enclave member trust column + graduation helpers (LC-551)
dacdab02Merge pull request 'feat(markdown): mermaid diagram rendering (LC-550)' (#520) from feat/LC-550-mermaid-diagrams into main
e1269660feat(assets): vendored mermaid + lazy-loading diagram enhancement (LC-550)
0d28e860feat(markdown): render ```mermaid fences as diagram containers (LC-550)
209014bbMerge pull request 'feat(search): semantic / related-message search (LC-549)' (#519) from feat/LC-549-semantic-search into main
0fdb724ftest(routes): related + semantic search integration coverage (LC-549)
cf447c29i18n: related-search and semantic-toggle strings (LC-549)
9baa892cfeat(search): opt-in semantic search mode that degrades to FTS (LC-549)
f0a8a4f8feat(search): "Find related" messages backed by embeddings (LC-549)
8533adb2feat(state): wire embeddings client into AppState + config (LC-549)
52135426feat(db): message_embeddings sidecar table + storage and by-ids fetch (LC-549)
de5254acfeat(embeddings): operator embeddings client with cosine + serde helpers (LC-549)
d8afed98Merge pull request 'feat(messages): AI suggested replies (LC-548)' (#518) from feat/LC-548-suggest-reply into main
69142aa2test(routes): integration coverage for suggested replies (LC-548)
5edc37b5i18n(room): suggested-reply menu label and panel heading (LC-548)
0d7318d3feat(ui): suggest-reply chips in the message menu, applied via the composer panel (LC-548)
b8cc9c14feat(routes): AI suggested-reply endpoint with chip parser (LC-548)
5984b9a8Merge pull request 'feat(error): friendlier generic error page (LC-552)' (#517) from feat/LC-552-friendly-error-page into main
a89fc0c0feat(error): redesign the generic error page, hide only internal detail (LC-552)
2edec3c3i18n(error): friendly per-status error-page descriptions (LC-552)
2778e292Merge pull request 'feat(messages): ephemeral / self-destruct messages (LC-547)' (#516) from feat/LC-547-ephemeral-messages into main
e3f5e06ftest(messages): sweep + composer coverage for ephemeral messages (LC-547)
1361417bfeat(composer): self-destruct timer select wired into post_message (LC-547)
53bf6731feat(messages): schedule the unconditional ephemeral sweeper (LC-547)
61c3fb87feat(retention): unconditional sweep for expired ephemeral messages (LC-547)
fba7631cfeat(messages): expires_at column + TTL parsing for self-destruct (LC-547)
361ba0bcMerge pull request 'feat(threads): per-thread mute (LC-546)' (#515) from feat/LC-546-per-thread-mute into main
48c10000test(threads): db + route coverage for per-thread mute (LC-546)
296e9102feat(threads): mute toggle route, button, and thread-panel wiring (LC-546)
ef610ee2feat(threads): suppress muted followers from thread reply fan-out (LC-546)
e9b81d91feat(threads): thread_muters table + data layer (LC-546)
e15e58b9Merge pull request 'chore(repo): publish-readiness sanitization sweep (LC-521)' (#514) from chore/LC-521-publish-sanitization into main
f009947cchore(ci): drop trufflehog --exclude-paths and the empty exclude file (LC-521)
c2d89992chore(repo): publish-readiness sanitization sweep (LC-521)
0c607396Merge pull request 'fix(enclave): friendly redirect for invalid/revoked invite code (LC-544)' (#513) from fix/LC-544-friendly-invalid-invite-code into main
fa92f0aetest(enclave): assert discover renders the invalid-invite-code banner (LC-544)
28ef74f6fix(enclave): friendly redirect for invalid/revoked invite code (LC-544)
627935c8Merge pull request 'feat(uploads): accessible image alt text (LC-537)' (#512) from feat/LC-537-image-alt-text into main
ab1090b6test(uploads): alt-text round-trip + author-gated editor route (LC-537)
31a0ce0cfeat(uploads): author alt-text editor with live re-render (LC-537)
4c12202bfeat(uploads): store image alt text (LC-537)
14772e09Merge pull request 'feat(stats): personal member-stats recap page (LC-536)' (#511) from feat/LC-536-member-stats into main
8a10f798test(stats): member_stats aggregation + /stats page render (LC-536)
2d747528feat(stats): personal stats recap page at /stats (LC-536)
6c7a0e5bfeat(stats): personal member-stats aggregation (LC-536)
ead0527dMerge pull request 'feat(profile): pronouns, links & local time on profiles (LC-533)' (#510) from feat/LC-533-profile-extras into main
ff965166test(profile): profile-extras round-trip + hovercard privacy gate (LC-533)
7939228afeat(profile): show pronouns, links, local time on the hovercard (LC-533)
61bff2c6feat(profile): edit pronouns, links, timezone in settings (LC-533)
b1e1315afeat(profile): pronouns, links, timezone columns + model plumbing (LC-533)
2184b50aMerge pull request 'feat(mute): auto-expiring timed mutes (LC-535)' (#509) from feat/LC-535-timed-mutes into main
f71dee54test(mute): expiry sweep lifts past mutes, spares permanent and future (LC-535)
d6492bbbfeat(mute): timed-mute duration picker in the admin user table (LC-535)
4e0c9d60feat(mute): honour mute expiry at every posting gate (LC-535)
0189ef34feat(mute): auto-expiring timed-mute core (LC-535)
7c46cabfMerge pull request 'feat(branding): standardize "Let's Chat" display name; guard tab title (LC-538)' (#508) from feat/LC-538-standardize-name-casing into main
2de2c5d3feat(branding): standardize "Let's Chat" display name; guard tab title (LC-538)
e4e25189Merge pull request 'feat(room): per-channel slowmode (LC-534)' (#507) from feat/LC-534-slowmode into main
d6662ee9test(slowmode): end-to-end enforcement, off, and mod-exempt (LC-534)
8d3e2a64feat(slowmode): room-manage control to set the cooldown (LC-534)
0f11e577feat(slowmode): enforce per-channel slowmode in post_message (LC-534)
077ccbbafeat(slowmode): rooms.slowmode_seconds column + cooldown limiter (LC-534)
5629c7ebMerge pull request 'feat(compose): AI writing assistant in the composer (LC-532)' (#506) from feat/LC-532-composer-ai-assist into main
07089ce9test(compose): end-to-end AI-assist happy path + gates (LC-532)
30f0e596feat(compose): wire the AI-assist button, panel slot, and apply/dismiss (LC-532)
168597f0feat(compose): AI writing-assistant endpoint + result panel (LC-532)
885c33e9Merge pull request 'feat(kudos): per-user opt-out of the leaderboard (LC-526 follow-up)' (#505) from feat/LC-526-kudos-optout into main
5fdc4387test(kudos): cover leaderboard exclusion of opted-out users (LC-526)
81f25c0afeat(kudos): settings toggle to opt out of the leaderboard (LC-526)
844858f4feat(kudos): exclude opted-out users from the leaderboard (LC-526)
03d5d5f6feat(kudos): users.kudos_leaderboard_opt_out column + accessors (LC-526)
ab1df775Merge pull request 'feat(kudos): /kudos recognition command + leaderboard (LC-526)' (#504) from feat/LC-526-kudos into main
566f1aa9test(kudos): cover leaderboard ranking, enclave scoping, window (LC-526)
2702495afeat(kudos): leaderboard page + sidebar nav entry (LC-526)
8372010cfeat(kudos): /kudos slash command that records + posts recognition (LC-526)
0f924184feat(kudos): kudos table + leaderboard aggregate db layer (LC-526)
dc46e5dcMerge pull request 'feat(search): has:file / has:link / in:thread operators (LC-530)' (#503) from feat/LC-530-search-filters into main
aad0af9ftest(search): cover has:file / has:link / in:thread filters (LC-530)
3ae1ca4cfeat(search): parse and wire has:file / has:link / in:thread operators (LC-530)
24827e97feat(search): add has:file / has:link / in:thread filter columns (LC-530)
2719e326Merge pull request 'feat(room): reaction highlights recap page (LC-529)' (#502) from longjacksonle/feat/LC-529-reaction-highlights into main
748e74f1feat(room): reaction highlights recap page (LC-529)
966a8b61Merge pull request 'feat(transcripts): trackable follow-up tasks from call action items (LC-527)' (#501) from longjacksonle/feat/LC-527-followup-tasks into main
82c47fb4feat(transcripts): trackable follow-up tasks from call action items (LC-527)
1362110bMerge pull request 'feat(room): read a message aloud via browser speech synthesis (LC-528)' (#500) from longjacksonle/feat/LC-528-read-aloud-messages into main
0189663cfeat(room): read a message aloud via browser speech synthesis (LC-528)
0d5ea0baMerge pull request 'feat(enclave): remove default enclave, prompt to create when none (LC-516)' (#499) from feat/LC-516-remove-default-enclave into main
7031e2eefix(enclave): guard disabled bots, cap name, drop redundant home query
630f4112feat(enclave): remove default enclave, prompt to create when none
369afb83Merge pull request 'ci: guard migration immutability against sqlx checksum drift' (#498) from feat/LC-515-migration-immutability-guard into main
d3705be8ci: guard migration immutability against sqlx checksum drift
44c766cdMerge pull request 'test(auth): reconcile db_sessions with LC-514 hashed session id' (#497) from fix/LC-520-db-sessions-hashed-id-tests into main
5a6a8a04test(auth): reconcile db_sessions with LC-514 hashed session id
b271392dMerge pull request 'fix(auth): [operator-action] hash session tokens at rest' (#496) from fix/LC-514-sessions-hash-at-rest into main
18967022fix(auth): [operator-action] hash session tokens at rest
79baa64fMerge pull request 'feat(wiki): live wiki-editing presence banner (LC-498)' (#495) from feat/LC-498-wiki-editing-presence into main
fdf001fefeat(wiki): live "X is editing the wiki" banner on the About page (LC-498)
4a66642cfeat(wiki): WS frame + render fragments for editing presence (LC-498)
5106f731feat(wiki): ephemeral wiki-editing presence in the hub (LC-498)
05969ccfMerge pull request 'feat(clips): async video clips with transcription [operator-action] (LC-496)' (#494) from feat/LC-496-video-clips into main
7c045e95test+docs(clips): clip transcription coverage + STT env note (LC-496)
592e5eedi18n(clips): en + es strings for the clip recorder (LC-496)
981364f5feat(clips): in-composer camera/screen recorder (LC-496)
68138e38feat(clips): transcribe video clips via the STT endpoint [operator-action] (LC-496)
804e6865feat(clips): inlineDownloads
-
Source code (ZIP)
0 downloads
-
Source code (TAR.GZ)
0 downloads
-
Source code (ZIP)
-
v0.1.0
StableSome checks failedcheck-secrets / Nosey parker (push) Successful in 7scheck-secrets / Kingfisher (push) Successful in 8scheck-secrets / TruffleHog (push) Successful in 10sBuild desktop (Windows) / Build desktop (Windows x86_64) (push) Successful in 2m17sBuild desktop (Windows) / Build desktop (Windows x86_64) (release) Successful in 2m18sBuild OCI container / Build and push lets-chat (push) Successful in 2m43sBuild desktop (Linux) / Build desktop (Linux x86_64) (release) Successful in 3m36sPublish release artifacts / Build + publish lets-chat-desktop binaries (push) Failing after 4m50sCheck / clippy + fmt + tests (push) Successful in 7m59sBuild desktop (Linux) / Build desktop (Linux x86_64) (push) Successful in 12m13sreleased this
2026-06-24 17:31:16 +02:00 | 700 commits to main since this releaseChangelog
7d56e2bMerge pull request 'Release v0.1.0' (#440) from release/v0.1.0 into main
2dcfd05Release v0.1.0
f33f41eMerge pull request 'fix(ci): derive desktop publish version from trigger to kill twin-publish race' (#391) from fix/desktop-twin-trigger-publish into main
bf76d8aMerge branch 'main' into fix/desktop-twin-trigger-publish
51a2156Merge pull request 'feat(transcripts): delete, bulk-clean, row polish, live search (LC-440)' (#439) from feat/transcripts-list-delete into main
c4e382dfeat(transcripts): delete + bulk-clean empty + row polish + live search (LC-440)
e43b948Merge pull request 'fix(settings): never-silent avatar upload errors (LC-439)' (#438) from fix/avatar-upload-error-feedback into main
2834e25fix(settings): never-silent avatar upload - client validation + raised body limit + htmx error net (LC-439)
dc8bee3Merge pull request 'feat(dm): system-event rows, grouping window, header icons, call end-state feedback (LC-433)' (#437) from feat/dm-view-call-feedback into main
8dc799efeat(dm): system-event rows, 5-min grouping, header icons, call end-state feedback (LC-433)
f86c69fMerge pull request 'fix(settings): single avatar preview, status placement, file-input tooltip (LC-432)' (#436) from fix/settings-profile-polish into main
b067834fix(settings): single avatar preview, status placement, file-input tooltip (LC-432)
09b19aaMerge pull request 'feat(settings): tabbed redesign + per-action HTMX feedback (LC-426)' (#435) from feat/settings-redesign-feedback into main
fb0ca33feat(settings): tabbed redesign + per-action HTMX feedback (LC-426)
5952c5dMerge pull request 'feat(calls): balanced participant grid + pre-join lobby (LC-416)' (#434) from feat/lc-416-voice-grid-lobby into main
7c2d5f5feat(calls): balance the participant grid + redesign the pre-join lobby (LC-416)
0f122a5Merge pull request 'fix(calls): affirmative recording state + control-bar tooltips (LC-416)' (#433) from feat/lc-416-recording-state-tooltips into main
3d5bf40fix(calls): make recording state affirmative + add control tooltips (LC-416)
0f8b57fMerge pull request 'feat(calls): redesign voice control bar + call view (LC-416)' (#432) from feat/lc-416-voice-callbar-redesign into main
cc1f8b7feat(calls): redesign voice control bar + call view (LC-416)
49e7aceMerge pull request 'fix(sidebar): explicit current-enclave header for sidebar re-renders + membership gate (LC-415)' (#431) from fix/sidebar-enclave-context-hardening into main
f89b907fix(sidebar): send viewer's current enclave as an explicit header for sidebar re-renders (LC-415)
2c78f78Merge pull request 'fix(sidebar): keep enclave context when re-rendering after a category mutation (LC-415)' (#430) from fix/sidebar-category-create-enclave-context into main
67541fffix(sidebar): keep enclave context when re-rendering after a category mutation (LC-415)
970d6a9Merge pull request 'fix(auth): drop lets-chat session on Bunyip identity swap (LC-414)' (#429) from fix/LC-414-session-bunyip-sub-reconcile into main
4ca6292fix(auth): drop lets-chat session on Bunyip identity swap (LC-414)
58272acMerge pull request 'feat(auth): mirror Bunyip admin role onto lets-chat users.role (LC-413)' (#428) from feat/LC-413-mirror-bunyip-admin-role into main
a109866feat(auth): mirror Bunyip admin role onto lets-chat users.role (LC-413)
579175bMerge pull request 'feat(calls): in-call transcript open/copy/download (LC-411)' (#427) from feat/lc-411-transcript-export into main
1d7be5cfeat(calls): in-call transcript open/copy/download from the drawer (LC-411)
724a18dMerge pull request 'feat(calls): bring the 1:1 DM call control bar to parity (LC-412)' (#426) from feat/lc-412-dm-modal-parity into main
1ca5aeffeat(calls): bring the 1:1 DM call control bar to parity (LC-412)
25124afMerge pull request 'fix(calls): screen-share stage never engaged on the receiver (LC-408)' (#425) from fix/lc-408-screenshare-receiver-pin into main
50f3e10fix(calls): screen-share stage never engaged on the receiver (LC-408)
41da0ccMerge pull request 'feat(calls): per-peer connection-quality indicator (LC-410)' (#424) from feat/lc-410-connection-quality into main
d48c506feat(calls): per-peer connection-quality indicator (LC-410)
aff111dMerge pull request 'fix(calls): screen-share stage never applied + could stick on peers (LC-408)' (#423) from fix/lc-408-screenshare-stage into main
fe07580fix(calls): screen-share stage never applied + could stick on peers (LC-408)
84a61f0Merge pull request 'feat(calls): mobile/responsive pass for the in-call UI (LC-409)' (#422) from feat/lc-409-call-mobile into main
e33e28dfeat(calls): mobile/responsive pass for the in-call UI (LC-409)
4655328Merge pull request 'feat(calls): pin screen-share to a stage tile (LC-408)' (#421) from feat/lc-408-screenshare-pinned-tile into main
b209329feat(calls): pin screen-share to a stage tile (LC-408)
0f9db73Merge pull request 'feat(calls): propagate voice mute state over WS so peers see it (LC-407)' (#420) from feat/lc-402-remote-mute into main
142bb80feat(calls): propagate voice mute state over WS so peers see it (LC-407)
580f838Merge pull request 'feat(calls): redesign the in-call voice UI (LC-402)' (#419) from feat/lc-402-voice-call-redesign into main
4f3a37ffeat(calls): redesign the in-call voice UI (LC-402)
bf0f48aMerge pull request 'fix(room): restore the delete-room affordance on the room info page (LC-400)' (#418) from fix/lc-400-room-delete-ui into main
6eeadfffix(room): restore the delete-room affordance on the room info page (LC-400)
13acb35Merge pull request 'fix(enclave): land the creator in the newly created room (LC-400)' (#417) from fix/lc-400-post-create-redirect into main
7a781b5fix(enclave): land the creator in the newly created room (LC-400)
c283749Merge pull request 'fix(sidebar): move add-room form to a modal so live swaps can't clobber it (LC-400)' (#416) from fix/lc-400-addroom-modal into main
8ef08c7fix(sidebar): move add-room form to a modal so live swaps can't clobber it (LC-400)
f10a1acMerge pull request 'fix(composer): clear the live markdown overlay after send (LC-399)' (#415) from fix/lc-399-overlay-stale-after-send into main
904fb0dfix(composer): clear the live markdown overlay after send (LC-399)
27db813Merge pull request 'feat(composer): live markdown highlight overlay (LC-399)' (#414) from feat/lc-399-composer-live-markdown-overlay into main
f5e7eaefeat(composer): live markdown highlight overlay (LC-399)
a340391Merge pull request 'docs: document call transcription STT/LLM env vars for operators (LC-398)' (#413) from docs/lc-398-transcription-env-docs into main
6002b83docs: document call transcription STT/LLM env vars for operators (LC-398)
78c884cMerge pull request 'fix(ws): always echo a message to its author, even when unsubscribed (LC-397)' (#412) from fix/lc-397-author-echo-unconditional into main
ea228b7fix(ws): always echo a message to its author, even when unsubscribed (LC-397)
036d063Merge pull request 'fix(calls): drive 1:1 transcription UI from the start response (LC-396)' (#411) from fix/lc-396-1on1-transcribe-response-driven into main
1921239fix(calls): drive 1:1 transcription UI from the start response (LC-396)
1201436Merge pull request 'feat(calls): optional LLM transcript summaries (LC-396)' (#410) from feat/lc-396-transcript-llm-summary into main
a410751feat(calls): optional LLM transcript summaries [operator-action] (LC-396)
6e7caa9Merge pull request 'feat(calls): transcript export (txt/vtt) + archive search (LC-393 Phase 4)' (#409) from feat/lc-395-transcript-export-search into main
f27914dfeat(calls): transcript export (txt/vtt) + archive search (LC-393 Phase 4)
f21bc8bMerge pull request 'feat(calls): transcripts archive page + harden 1:1 toggle (LC-394)' (#408) from feat/lc-394-transcript-archive into main
ebbc73bfeat(calls): transcripts archive page + harden 1:1 toggle (LC-394)
9f75902Merge pull request 'feat(calls): Phase 3 - self-hosted server-side STT provider (LC-393)' (#407) from feat/lc-393-phase3-server-stt into main
0e2f7adfeat(calls): Phase 3 - self-hosted server-side STT provider [operator-action] (LC-393)
8ffb297Merge pull request 'feat(calls): Phase 2 - transcription for enclave voice channels (LC-393)' (#406) from feat/lc-393-phase2-voice-transcription into main
5ea34bafeat(calls): Phase 2 - transcription for enclave voice channels (LC-393)
7f5b745Merge pull request 'feat(calls): meeting transcription - live captions + saved transcript (LC-393)' (#405) from feat/lc-393-call-transcription into main
563f082feat(calls): meeting transcription - live captions + saved transcript (LC-393)
d6479f7Merge pull request 'fix(search): make the sidebar People tab actually query /users/search (LC-392)' (#404) from fix/lc-392-people-search into main
db65327fix(search): make the sidebar People tab actually query /users/search (LC-392)
b94a389Merge pull request 'fix(reactions): make the picker filter actually hide cells (LC-391)' (#403) from feat/lc-389-full-emoji-picker into main
dcbca36fix(reactions): make the picker filter actually hide cells (LC-391)
2deef73Merge pull request 'fix(reactions): self-heal the Recent emoji row after a react (LC-390)' (#402) from fix/lc-390-recent-emoji-refresh into main
61a1b55fix(reactions): self-heal the Recent emoji row after a react (LC-390)
eb7eb21Merge pull request 'feat(composer): full categorized emoji picker, shared catalog (LC-389)' (#401) from feat/lc-389-full-emoji-picker into main
5a931fcfeat(composer): full categorized emoji picker, shared catalog (LC-389)
1c6cf31Merge pull request 'feat(reactions): full categorized, searchable emoji picker (LC-389)' (#400) from feat/lc-389-full-emoji-picker into main
e075476feat(reactions): full categorized, searchable emoji picker (LC-389)
d0f61bbMerge pull request 'feat(ui): align the room header action cluster (LC-388)' (#399) from feat/lc-388-header-spacing into main
94c8949feat(ui): align the room header action cluster (LC-388)
2edbd63Merge pull request 'feat(ui): widen same-author message grouping to 15 min + day-break (LC-387)' (#398) from feat/lc-387-grouping-pills into main
9d17e71feat(ui): widen same-author message grouping to 15 min + day-break (LC-387)
4b2caf5Merge pull request 'fix(ui): show-more visibility + reaction-picker dismissal regressions' (#397) from fix/room-polish-regressions into main
7df2e4bMerge remote-tracking branch 'origin/main' into fix/room-polish-regressions
07aa0bdfix(ui): show-more visibility + reaction-picker dismissal regressions
6d2d5daMerge pull request 'feat(ui): replace the jump-to-date native picker with a custom calendar (LC-386)' (#396) from feat/lc-386-jumpdate into main
b29c1befeat(ui): replace the jump-to-date native picker with a custom calendar (LC-386)
113da67Merge pull request 'feat(ui): intentional long-message truncation (LC-385)' (#395) from feat/lc-385-truncation into main
11eb7a7feat(ui): intentional long-message truncation (LC-385)
5f281e0Merge pull request 'feat(ui): float the reaction emoji picker as an anchored popover (LC-384)' (#394) from feat/lc-384-reaction-popover into main
981e646feat(ui): float the reaction emoji picker as an anchored popover (LC-384)
4bd5f79Merge pull request 'feat(ui): align + lighten the sidebar room/DM list (LC-381)' (#393) from feat/lc-381-room-list-polish into main
f250373feat(ui): align + lighten the sidebar room/DM list (LC-381)
6df2314Merge pull request 'fix(composer): reconcile a stuck send in place, not by reloading #messages (LC-382)' (#392) from fix/lc-382-inplace-reconcile into main
88209b9fix(composer): reconcile a stuck send in place, not by reloading #messages (LC-382)
40db0defix(ci): derive desktop publish version from trigger, not git describe
f14535eMerge pull request 'fix(composer): self-heal a stuck "Sending..." optimistic placeholder (LC-382)' (#390) from fix/lc-382-sending-stuck-watchdog into main
17673f2Merge pull request 'feat(ui): tidy the two-tier composer (LC-380)' (#389) from feat/lc-380-composer-cleanup into main
af38a89fix(composer): self-heal a stuck "Sending..." optimistic placeholder (LC-382)
4b04860feat(ui): tidy the two-tier composer (LC-380)
31fb16dMerge pull request 'feat(ui): refine the day / unread divider styling (LC-379)' (#388) from feat/lc-379-day-divider into main
bb86b82feat(ui): refine the day / unread divider styling (LC-379)
1a069b2Merge pull request 'feat(ui): room header notify pill + title polish (LC-378)' (#387) from feat/lc-378-room-header-notify into main
aebbe5efeat(ui): room header notify pill + title polish (LC-378)
fd9c529Merge pull request 'feat(ui): message grouping rhythm + add-reaction affordance (LC-377)' (#386) from feat/lc-377-message-grouping into main
6b550fefeat(ui): message grouping rhythm + add-reaction affordance (LC-377)
f31c3c4Merge pull request 'feat(ui): message action bar -> icon toolbar + overflow menu (LC-376)' (#385) from feat/lc-376-message-action-menu into main
3120075feat(ui): message action bar -> icon toolbar + overflow menu (LC-376)
4537810Merge pull request 'feat(ui): polish message rows, reactions, and the composer (LC-374)' (#384) from feat/lc-374-message-composer-polish into main
47ecc59feat(ui): polish message rows, reactions, and the composer (LC-374)
0987e5bMerge pull request 'feat(ui): unify the room / DM / home headers (LC-373)' (#383) from feat/lc-373-room-header into main
4c4eee2feat(ui): unify the room / DM / home headers (LC-373)
a27446cMerge pull request 'feat(ui): redesign the welcome empty state (LC-372)' (#382) from feat/lc-372-welcome-empty-state into main
cc4d55bfeat(ui): redesign the welcome empty state (LC-372)
b4e4cccMerge pull request 'feat(ui): group and polish the sidebar room/DM list (LC-371)' (#381) from feat/lc-371-room-list-sections into main
f555856feat(ui): group and polish the sidebar room/DM list (LC-371)
8adac0cMerge pull request 'feat(ui): unify the two sidebar search boxes (LC-369)' (#380) from feat/lc-369-search-consolidation into main
c6fff78feat(ui): unify the two sidebar search boxes (LC-369)
f7d764aMerge pull request 'feat(ui): turn the sidebar profile header into an account menu (LC-368)' (#379) from feat/lc-368-account-menu into main
dc27ebffeat(ui): turn the sidebar profile header into an account menu (LC-368)
2869aa1Merge pull request 'feat(ui): group the sidebar nav into icon sections (LC-367)' (#378) from feat/lc-367-sidebar-grouping into main
7c55c10feat(ui): group the sidebar nav into icon sections (LC-367)
cac1b08Merge pull request 'feat(ui): redesign the enclave rail with semantic tokens (LC-366)' (#377) from feat/lc-366-enclave-rail into main
020bd2dfeat(ui): redesign the enclave rail with semantic tokens (LC-366)
a760003Merge pull request 'feat(ui): styled app-wide tooltip component (LC-370)' (#376) from feat/lc-370-tooltip-component into main
090e7b9feat(ui): styled app-wide tooltip component (LC-370)
64d6feeMerge pull request 'feat(ui): semantic typography scale + spacing rhythm (LC-365)' (#375) from feat/lc-365-design-tokens into main
29fcd5cfeat(ui): add a semantic typography scale + spacing rhythm (LC-365)
c8fb5e5Merge pull request 'fix(tests): remove SMTP-env race behind the email-notification flake (LC-363)' (#374) from fix/lc-363-email-notification-flake into main
9e34c97fix(tests): stop the email-notification flake from racing on SMTP env vars (LC-363)
b8920d3Merge pull request 'feat(i18n): localize client-side JS strings via window.__lcI18n catalog (LC-361)' (#373) from fix/lc-361-js-i18n into main
f6f8991feat(i18n): localize the remaining outbox/devices/recorder JS strings (LC-361)
56f0d91feat(i18n): localize client-side JS strings via a window._lcI18n catalog (LC-361)
19ecc00Merge pull request 'feat(ci): cap native check.yml parallelism at nproc/2' (#372) from feat/GOV-10-native-check-nproc-cap into main
2d92967feat(ci): cap native check.yml parallelism at nproc/2
795133cMerge pull request 'fix(a11y): accessible names for search inputs + settings selects; reaction OOB label (LC-362)' (#371) from fix/lc-362-a11y-labels into main
425d90dMerge pull request 'fix: webhook/email avatar fallback + inline settings form errors (LC-356, LC-360)' (#370) from fix/lc-356-360-audit-ux into main
ce57fc4fix(a11y): give search inputs and settings selects accessible names; fix reaction OOB drift (LC-362)
f95c68dfix(settings): flash profile/delete-account errors inline instead of a full-page error (LC-356)
b749c08fix(room): fall back to initials when a webhook/email avatar fails to load (LC-360)
6fda0c3Merge pull request 'fix: four validation/correctness audit findings (LC-355, LC-357, LC-358, LC-359)' (#369) from fix/lc-355-357-358-359-audit-med into main
3883d50fix(admin): validate bridge/webhook targets and bound rate-limit/quota (LC-357, LC-358)
6fafefcfix(room): use a textarea for inline message edit so multiline is editable (LC-359)
f3c22acfix(branding): cap login heading/body length on the write path (LC-355)
5c10f82Merge pull request 'fix: remaining HIGH audit findings - dead 2FA cleanup + <html lang> (LC-353, LC-354)' (#368) from fix/lc-353-354-audit-high-cleanup into main
8786932fix(i18n): drive <html lang> from the resolved request locale (LC-354)
26421ebchore: remove dead 2FA UI cruft left by the LC-22 Bunyip SSO cutover (LC-353)
952ace8Merge pull request 'fix: four HIGH correctness/security fixes from the UI audit (LC-349..352)' (#367) from fix/lc-349-352-audit-high-correctness into main
7c4bdddfix(admin): block removing the last active admin (LC-352)
4d26c85fix(enclave): refuse role changes that would demote the Owner (LC-351)
3701e9efix(polls): clamp poll closes_in to avoid Duration overflow panic (LC-350)
ede91bcfix(scheduled): cap scheduled-message body length on the write path (LC-349)
4e3497cMerge pull request 'fix(avatar): revalidate /avatars with ETag so changes appear promptly (LC-348)' (#366) from fix/lc-348-avatar-etag-revalidation into main
bdc8977fix(avatar): revalidate /avatars with ETag so changes appear promptly (LC-348)
1d41ca8Merge pull request 'fix(settings): confirm profile-picture upload and refresh the preview (LC-347)' (#365) from fix/lc-347-avatar-upload-feedback into main
797916bMerge remote-tracking branch 'origin/main' into fix/lc-347-avatar-upload-feedback
7beca2achore: drop accidental .claude/scheduled_tasks.lock change from LC-347
e573216fix(settings): confirm profile-picture upload and refresh the preview (LC-347)
ccda09aMerge pull request 'docs: refresh auth docs for Bunyip-SSO-only (LC-22) + document dev-web SSO setup' (#364) from docs/dev-web-bunyip-sso-setup into main
7e57e54docs: refresh auth docs for Bunyip-SSO-only (LC-22) + document dev-web SSO setup
2214053Merge pull request 'fix(dev): serve dev-web on the nebula-secure entrypoint too' (#363) from fix/dev-web-nebula-entrypoint into main
c23d097fix(dev): serve dev-web on the nebula-secure entrypoint too
9fa846cMerge pull request '[operator-action] fix(dev): make dev-web bootable against the Bunyip OP (LC-22 fallout)' (#362) from fix/dev-web-bunyip-sso-startup into main
72fba3d[operator-action] fix(dev): make dev-web bootable against the Bunyip OP (LC-22 fallout)
c07fc39Merge pull request 'fix(composer): preserve in-progress message across reconnect soft-refresh (LC-346)' (#361) from fix/lc-346-composer-refresh-preserve into main
daab33bfix(composer): preserve in-progress message across reconnect soft-refresh
1eed22bMerge pull request 'feat(settings): section off the user settings page with a sticky nav (LC-345)' (#360) from feat/lc-345-settings-sections into main
2d516bafeat(settings): section off the user settings page with a sticky nav (LC-345)
7812fbbMerge pull request 'feat(moderation): shame-tag community moderation prototype (LC-342)' (#359) from feat/lc-342-shame-tags into main
866539ffeat(moderation): shame-tag community moderation prototype (LC-342)
33352dbMerge pull request 'docs(test): correct enclave_rooms helper comment (LC-341)' (#358) from test/lc-341-coyote-trigger into main
d813d7fdocs(test): correct enclave_rooms helper comment (LC-341)
100e7a1Merge pull request 'test(enclave): assert Coyote Mode auto-ban trigger deterministically (LC-341)' (#357) from test/lc-341-coyote-trigger into main
78a87cbtest(enclave): assert Coyote Mode auto-ban trigger deterministically (LC-341)
c34e4a4Merge pull request 'feat(enclave): banned-list UI with per-user unban (LC-340)' (#356) from feat/lc-340-enclave-banlist into main
c2f510dfeat(enclave): banned-list UI with per-user unban
10b114fMerge pull request 'feat(enclave): Coyote Mode anti-spam (cross-room burst -> enclave ban + 24h soft-purge) (LC-339)' (#355) from feat/lc-339-coyote-mode into main
d4f990etest(enclave): HTTP coverage for Coyote Mode gate + ban enforcement; clarify exemption copy
c7b3ceafeat(enclave): Coyote Mode anti-spam (cross-room burst -> enclave ban + 24h soft-purge)
65f14abMerge pull request 'fix(composer): do not wipe in-progress text on draft-autosave (LC-338)' (#354) from fix/lc-338-composer-draft-wipe into main
8b9277cfix(composer): do not wipe in-progress text on draft-autosave (LC-338)
db8df9eMerge pull request 'fix(ws): render_sidebar uses recipient's current enclave, not None (LC-337)' (#353) from fix/lc-337-render-sidebar-enclave-aware into main
0917b76fix(ws): render_sidebar uses the recipient's current enclave, not None
d03fd53Merge pull request 'feat(enclave): remove landing menu; sidebar + create-chat, invite-search to settings' (#352) from feat/lc-336-remove-enclave-landing-menu into main
927ea7cfeat(enclave): remove landing menu; sidebar + create-chat, invite-search to settings
6fb0404Merge pull request 'fix(oidc): pass raw 32-byte Ed25519 key, not SPKI-wrapped DER (LC-22)' (#351) from fix/lc-22-ed25519-spki-verify into main
c6065f3fix(oidc): pass raw 32-byte Ed25519 key, not SPKI-wrapped DER (LC-22)
db87b28Merge pull request 'style: cargo fmt the report.rs use ordering' (#350) from fix/lc-22-routes-reports-appstate-drift into main
d0ddb7estyle: cargo fmt the report.rs use ordering
811e535Merge pull request 'fix(report): gate admin-queue helpers behind standalone (LC-22 / LC-334)' (#349) from fix/lc-22-routes-reports-appstate-drift into main
e22c95afix(report): gate admin-queue helpers behind standalone (LC-22 / LC-334)
f4f513dMerge pull request 'fix(tests): AppState drift in routes_reports - add bunyip_sso None (LC-22)' (#348) from fix/lc-22-routes-reports-appstate-drift into main
1fee553fix(tests): AppState drift in routes_reports - add bunyip_sso None (LC-22)
efd5c6bMerge pull request 'style: cargo fmt run on LC-22 cutover additions' (#347) from feat/lc-22-bunyip-rp-cutover into main
6d1b912fix(tests): drop unused send_with_ip helpers in routes_anti_spam (LC-22)
900a7b4style: cargo fmt run on LC-22 cutover additions
194f12eMerge pull request 'feat/lc-22-bunyip-rp-cutover' (#346) from feat/lc-22-bunyip-rp-cutover into main
99d9745Merge pull request 'feat(moderation): report a message to moderators with a site-admin review queue (LC-334)' (#345) from feat/lc-334-message-reports into main
d0602f0test(sso): adapt fixtures for users.bunyip_sub UNIQUE constraint (LC-22)
6080041feat(moderation): report a message to moderators with a site-admin review queue
6a960b2fix(sso): retire 2FA-enrollment middleware + stale anti-spam knobs (LC-22)
a1df3a2[operator-action] feat(sso): pure-RP Bunyip cutover; retire local auth (LC-22)
01a1169Merge pull request 'feat(composer): live character counter near the message-length cap (LC-332)' (#344) from feat/lc-332-composer-char-counter into main
9f35028feat(composer): live character counter near the message-length cap
7b75d98Merge pull request 'fix(ws): delay reconnect banner so page nav does not flash it (LC-318)' (#343) from fix/lc-318-reconnect-banner-grace into main
128ff46fix(ws): keep missed-content recovery on short real outages
7cfae7dfix(ws): delay reconnect banner so page nav does not flash it
7787976Merge pull request 'fix(sidebar): live category change uses enclave-keyed nav fragment (LC-331)' (#342) from fix/lc-331-sidebar-categories-live into main
f5b7b4dfix(sidebar): live category change uses enclave-keyed nav fragment
95a0d9cMerge pull request 'feat(markdown): copy button on fenced code blocks (LC-329)' (#341) from feat/lc-329-code-block-copy into main
98f9f99feat(markdown): copy button on fenced code blocks (LC-329)
d8f9385Merge pull request 'feat(settings): per-user message text size (LC-327)' (#340) from feat/lc-327-message-text-size into main
cd9e2dbfeat(settings): per-user message text size (LC-327)
5d72760Merge pull request 'feat(room): jump-to-date navigation (LC-325)' (#339) from feat/lc-325-jump-to-date into main
a67eec8feat(room): jump-to-date navigation (LC-325)
5c0c01bMerge pull request 'feat(composer): #channel-link autocomplete and clickable links (LC-323)' (#338) from feat/lc-323-channel-link-autocomplete into main
0df7d1ffeat(composer): #channel-link autocomplete and clickable links (LC-323)
cfcd40cMerge pull request 'feat(room): per-room nickname (LC-321)' (#337) from feat/lc-321-per-room-nickname into main
a04f947feat(room): per-room nickname (LC-321)
67f529dMerge pull request 'feat(status): auto-expiring custom status (LC-319)' (#336) from feat/lc-319-auto-expiring-status into main
86bc5cffeat(status): auto-expiring custom status (LC-319)
f723490Merge pull request 'feat(composer): emoji picker button (LC-316)' (#335) from feat/lc-316-composer-emoji-picker into main
a548784feat(composer): emoji picker button (LC-316)
658c35aMerge pull request 'feat(ui): relative message timestamps (LC-314)' (#334) from feat/lc-314-relative-timestamps into main
825a9d3feat(ui): relative message timestamps (LC-314)
4981851Merge pull request 'feat(search): saved searches (LC-312)' (#333) from feat/lc-312-saved-searches into main
17a32a1feat(search): saved searches (LC-312)
8ba5805Merge pull request 'feat(threads): thread following / subscribe (LC-310)' (#332) from feat/lc-310-thread-following into main
a1746eefeat(threads): thread following / subscribe (LC-310)
f6e435bMerge pull request 'feat(ui): unread-only sidebar filter (LC-308)' (#331) from feat/lc-308-unread-only-sidebar into main
32f26a4feat(ui): unread-only sidebar filter (LC-308)
03551bbMerge pull request 'feat(notifications): keyword / highlight-word notifications (LC-304)' (#330) from feat/lc-304-keyword-notifications into main
0008406feat(notifications): keyword / highlight-word notifications (LC-304)
ff09979Merge pull request 'feat(ui): quick-reaction hover bar on messages (LC-302)' (#329) from feat/lc-302-quick-reaction-bar into main
188869cfeat(ui): quick-reaction hover bar on messages (LC-302)
4117eb8Merge pull request 'feat(composer): list, quote, and strikethrough toolbar buttons (LC-300)' (#328) from feat/lc-300-composer-toolbar-blocks into main
3b2f5cefeat(composer): list, quote, and strikethrough toolbar buttons (LC-300)
4a5ec67Merge pull request 'feat(ui): user profile hovercard on username hover (LC-298)' (#327) from feat/lc-298-profile-hovercard into main
c08f3fafeat(ui): user profile hovercard on username hover (LC-298)
e0294e3Merge pull request 'feat(composer): emoji :shortcode: autocomplete (LC-296)' (#326) from feat/lc-296-emoji-autocomplete into main
efbd24efeat(composer): emoji :shortcode: autocomplete (LC-296)
ea79458Merge pull request 'feat(ui): jump to first unread - floating pill returns to the unread divider (LC-294)' (#325) from feat/lc-294-jump-to-first-unread into main
4466325feat(ui): jump to first unread - floating pill returns to the unread divider (LC-294)
d36a25eMerge pull request 'feat(ui): theme quick-toggle in the sidebar footer (LC-292)' (#324) from feat/lc-292-theme-quick-toggle into main
b67fad9feat(ui): theme quick-toggle in the sidebar footer (LC-292)
843d4a7Merge pull request 'feat(markdown): spoiler text - ||text|| renders click-to-reveal (LC-290)' (#323) from feat/lc-290-spoiler-markdown into main
a88e50efeat(markdown): spoiler text - ||text|| renders click-to-reveal (LC-290)
7d07c94Merge pull request 'feat(ui): recently-used emoji row in the reaction picker (LC-288)' (#322) from feat/lc-288-recent-emoji into main
c973ef3feat(ui): recently-used emoji row in the reaction picker (LC-288)
1963680Merge pull request 'feat(ui): mark a conversation unread from a message (LC-286)' (#321) from feat/lc-286-mark-unread into main
7570383feat(ui): mark a conversation unread from a message (LC-286)
2f6a324Merge pull request 'feat(ui): highlight messages that @-mention the viewer (LC-284)' (#320) from feat/lc-284-self-mention-highlight into main
e767434feat(ui): highlight messages that @-mention the viewer (LC-284)
fbf1d71Merge pull request 'feat(ui): copy a message's text from the hover menu (LC-282)' (#319) from feat/lc-282-copy-message-text into main
ccd6825feat(ui): copy a message's text from the hover menu (LC-282)
42d2da0Merge pull request 'feat(ui): search operators from: and before:/after: (LC-280)' (#318) from feat/lc-280-search-operators into main
ac257f3feat(ui): search operators from: and before:/after: (LC-280)
c36762cMerge pull request 'feat(ui): forward a message to another room or DM (LC-278)' (#317) from feat/lc-278-message-forwarding into main
c0d9864feat(ui): forward a message to another room or DM (LC-278)
1c3d268Merge pull request 'feat(ui): markdown preview toggle in the composer (LC-276)' (#316) from feat/lc-276-markdown-preview into main
08f3dbbfeat(ui): markdown preview toggle in the composer (LC-276)
55a858eMerge pull request 'feat(ui): filter field on the reaction emoji picker (LC-274)' (#315) from feat/lc-274-reaction-picker-filter into main
6b7bf70feat(ui): filter field on the reaction emoji picker (LC-274)
88a0000Merge pull request 'feat(ui): copy button on code blocks (LC-272)' (#314) from feat/lc-272-code-copy-button into main
cfd0d0ffeat(ui): copy button on code blocks (LC-272)
75277d5Merge pull request 'feat(ui): collapse the room sidebar to the enclave rail (LC-270)' (#313) from feat/lc-270-sidebar-collapse-rail into main
d6c8c87feat(ui): collapse the room sidebar to the enclave rail (LC-270)
c820970Merge pull request 'feat(ui): per-room scoped search from the room header (LC-268)' (#312) from feat/lc-268-per-room-search into main
dce7e88feat(ui): per-room scoped search from the room header (LC-268)
bcc5fb4Merge pull request 'feat(ui): who-reacted tooltip on reaction pills (LC-266)' (#311) from feat/lc-266-who-reacted-tooltip into main
d495540feat(ui): who-reacted tooltip on reaction pills (LC-266)
0b4ec6dMerge pull request 'feat(ui): collapsible pinned-messages strip (LC-264)' (#310) from feat/lc-264-pinned-strip-collapse into main
24725a1feat(ui): collapsible pinned-messages strip (LC-264)
ad8dad5Merge pull request 'feat(ui): image lightbox - click an inline image to view it enlarged (LC-262)' (#309) from feat/lc-262-image-lightbox into main
47a81c1feat(ui): image lightbox - click an inline image to view it enlarged (LC-262)
8c9b351Merge pull request 'feat(ui): quick switcher - Ctrl/Cmd+K palette to jump anywhere (LC-260)' (#308) from feat/lc-260-quick-switcher into main
7b2b7c6Merge remote-tracking branch 'origin/main' into feat/lc-260-quick-switcher
efc0956feat(ui): quick switcher - Ctrl/Cmd+K palette to jump anywhere (LC-260)
638dee6Merge pull request 'feat(ui): per-room mark-as-read from the sidebar (LC-258)' (#307) from feat/lc-258-per-room-mark-read into main
397239efeat(ui): per-room mark-as-read from the sidebar (LC-258)
526fccaMerge pull request 'feat(ui): collapse long messages with Show more / Show less (LC-256)' (#306) from feat/lc-256-collapse-long-messages into main
4d919f8feat(ui): collapse long messages with Show more / Show less (LC-256)
8b96dbfMerge pull request 'feat(ui): composer formatting toolbar - bold/italic/code/link (LC-254)' (#305) from feat/lc-254-composer-format-toolbar into main
a4498dffeat(ui): composer formatting toolbar - bold/italic/code/link (LC-254)
4abe5e8Merge pull request 'feat(ui): keyboard shortcuts overlay - '?' opens a cheat-sheet (LC-252)' (#304) from feat/lc-252-shortcuts-overlay into main
c83de4efeat(ui): keyboard shortcuts overlay - '?' opens a cheat-sheet (LC-252)
d275c60Merge pull request 'feat(justfile): add dev-clean / dev-clean-all teardown recipes' (#303) from feat/dev-clean-recipes into main
76d55b1feat(justfile): add dev-clean / dev-clean-all teardown recipes
74efa83Merge pull request 'feat(ui): mark all as read - clear unread across every conversation (LC-250)' (#302) from feat/lc-250-mark-all-read into main
8c452f2feat(ui): mark all as read - clear unread across every conversation (LC-250)
0822d90Merge pull request 'feat(ui): Arrow-Up in an empty composer edits your last message (LC-248)' (#301) from feat/lc-248-arrowup-edit-last into main
8fa338cfeat(ui): Arrow-Up in an empty composer edits your last message (LC-248)
90f2378Merge pull request 'feat(ui): copy message link permalink that scrolls to + highlights the message (LC-246)' (#300) from feat/lc-246-message-permalink into main
6b7ea81feat(ui): copy message link permalink that scrolls to + highlights the message (LC-246)
bd217dcMerge pull request 'feat(ui): message-list date separators (Today / Yesterday / date) (LC-244)' (#299) from feat/lc-244-date-separators into main
ed7ec4bfeat(ui): message-list date separators (Today / Yesterday / date) (LC-244)
edf1f63Merge pull request 'feat(ui): jump-to-latest pill with new-message count in the message list (LC-242)' (#298) from feat/lc-242-jump-to-latest-pill into main
c4e87a1feat(ui): jump-to-latest pill with new-message count in the message list (LC-242)
2236657Merge pull request 'feat(ui): per-conversation draft sidebar indicators + caret restore (LC-237)' (#297) from feat/lc-237-draft-sidebar-indicators into main
b42ccf7feat(ui): per-conversation draft sidebar indicators + caret restore (LC-237)
e6f67beMerge pull request 'chore(build): bump rust-builder-glibc to v1.0.1' (#296) from chore/bump-rust-builder-glibc-v1.0.1 into main
cdc2150chore(build): bump rust-builder-glibc to v1.0.1
1e5df9dMerge pull request 'chore: Sync .gitignore' (#295) from chore/sync-gitignore into main
72b61c7chore: Sync .gitignore
e789968Merge pull request 'feat(ui): optimistic local echo for composer sends (LC-230)' (#294) from feat/lc-230-optimistic-echo into main
c78d54bfix(ui): address LC-230 review findings - quarantine ghost, retry data loss, debounced failure flip
ddfc493feat(ui): optimistic local echo for composer sends (LC-230)
4dcd642Merge pull request 'perf(ui): cut composer per-keystroke costs (LC-229)' (#293) from perf/lc-229-composer-keystroke-costs into main
3e8acc8perf(ui): consolidate send-button writers, fix review findings (LC-229)
0ce36bcperf(ui): cut composer per-keystroke costs (LC-229)
1b1b2e4Merge pull request 'perf(server): return 204 from post_message (LC-228)' (#292) from feat/lc-228-post-message-no-content into main
5e586e0perf(server): return 204 from slash dispatch too (LC-228)
e48269cperf(server): return 204 from post_message instead of unused composer fragment (LC-228)
ff650e9Merge pull request 'fix(ci): generate release notes from commits since previous tag' (#291) from fix/release-notes-since-prev-tag into main
8cb79a1fix(ci): generate release notes from commits since previous tag
031952bMerge pull request 'fix(http): remove dead auto-redirect SSRF footgun; prove the rebind window is closed at connect (LC-152-TOCTOU)' (#290) from fix/lc-152-pin-validated-ip into main
9230df3fix(http): remove dead auto-redirect SSRF footgun; prove + document the rebind window is closed at connect (LC-152-TOCTOU, #286)
bcac695Merge pull request 'test(desktop): net_guard grep-ban matches allow-list by full path + recursive src walk (LC-210-GREPBAN-FULLPATH)' (#289) from fix/lc-210-grepban-fullpath into main
9a9da4etest(desktop): match net_guard ureq grep-ban allow-list by full path, walk src recursively (LC-210-GREPBAN-FULLPATH, #285)
3e7a557Merge pull request 'fix(uploads): bound image decode with explicit Limits, closing the unbounded GIF path [operator-action] (LC-206-IMAGE-LIMITS)' (#288) from fix/lc-206-image-limits into main
ede3a2dfix(uploads): bound image decode with explicit Limits, closing the unbounded GIF path [operator-action] (LC-206-IMAGE-LIMITS, #284)
0dc6858Merge pull request 'fix(rooms): cap room description + wiki body length like chat messages (LC-153-WIKI-DESC-CAP)' (#287) from fix/lc-153-wiki-desc-cap into main
235de2bfix(rooms): cap room description + wiki body length like chat messages (LC-153-WIKI-DESC-CAP, #283)
332a320Merge pull request 'docs: reconcile email-ingress/bridge docs + env tables with shipped behavior (LC-209-DOC-DRIFT)' (#282) from docs/lc-279-doc-drift into main
9a0e1e4docs: reconcile email-ingress/bridge docs + env tables with shipped behavior (LC-209-DOC-DRIFT, #279)
bdf0a88Merge pull request 'feat(admin): surface email-ingress / IMAP-poll / retention-sweep health on /admin/settings (LC-207-OBSERVABILITY)' (#281) from feat/lc-207-observability-ingress-sweep-imap into main
e5cbca2feat(admin): surface email-ingress, IMAP-poll, and retention-sweep health on /admin/settings (LC-207-OBSERVABILITY, #278)
882bda9Merge pull request 'feat(desktop): verify signed update manifest + binary hash before self-replace [operator-action] (LC-210-BINARY-INTEGRITY)' (#280) from feat/lc-210-binary-integrity-manifest-signing into main
54c1fcafeat(desktop): verify signed update manifest + binary hash before self-replace [operator-action] (LC-210-BINARY-INTEGRITY, #277)
8e8feafMerge pull request 'fix(desktop): SSRF-guard the self-updater with per-hop redirect validation (LC-210)' (#276) from fix/lc-210-desktop-updater-ssrf-guard into main
52266b9fix(desktop): SSRF-guard the self-updater with per-hop redirect validation (LC-210)
4e3ee62Merge pull request 'docs(release): CHANGELOG + operator-visible-change convention (LC-209)' (#275) from docs/lc-209-changelog-convention into main
5110788docs(release): CHANGELOG + operator-visible-change convention (LC-209)
a46233aMerge pull request 'fix(uploads): unique write_atomic staging name to end routes_uploads flake (LC-208)' (#274) from fix/lc-208-write-atomic-unique-staging into main
17c53a3fix(uploads): unique write_atomic staging name to end routes_uploads flake (LC-208)
222a95eMerge pull request 'feat(admin): bridge-avatar cache diagnostic page (LC-207)' (#273) from feat/lc-207-bridge-avatar-admin-diagnostics into main
9ba932afeat(admin): bridge-avatar cache diagnostic page (LC-207)
a8454a7Merge pull request 'refactor(uploads): centralize image decode behind safe helpers + grep-ban (LC-206)' (#272) from refactor/lc-206-image-decode-safe-helper into main
b0b81adrefactor(uploads): centralize image decode behind safe helpers + grep-ban (LC-206)
3b90293Merge pull request 'perf(ui): debounce mention popover refresh 200ms (LC-227)' (#271) from feat/lc-227-mention-popover-debounce into main
af46d8dperf(ui): debounce mention popover refresh 200ms (LC-227)
3eaf910Merge pull request 'fix(ui): tokenize remaining .lc-md + .lc-quote-bar slate/blue (LC-226)' (#270) from feat/lc-226-lc-md-quote-bar-tokenize into main
0bb6d21Merge pull request 'feat(ui): tokenize message actor badges (webhook/email/bridge) (LC-225)' (#269) from feat/lc-225-actor-badge-tokenize into main
0be2446fix(ui): tokenize remaining .lc-md + .lc-quote-bar hardcoded slate/blue (LC-226)
93d3238feat(ui): tokenize message actor badges (webhook/email/bridge) (LC-225)
2039991Merge pull request 'fix(email-ingress): enqueue message.posted for LC-75 subscribers (LC-205)' (#268) from fix/lc-205-email-ingress-message-posted into main
9096478Merge pull request 'feat(ui): tokenize soft-success + soft-warning callouts (LC-224)' (#267) from feat/lc-224-success-warning-tokenize into main
9a9f85ffix(ui): code-review fixes for LC-224 success/warning sweep
04f034ffix(email-ingress): enqueue message.posted so LC-75 subscribers see it (LC-205)
cdbf759feat(ui): tokenize soft-success + soft-warning callouts (LC-224)
1f4e406Merge pull request 'feat(ui): tokenize accent / focus-ring drift (LC-222)' (#265) from feat/lc-222-accent-focus-tokenize into main
8488a19fix(ui): code-review fixes for LC-222 accent / focus-ring sweep
e2382a0Merge pull request 'test: retire hand-rolled migration lists, grep-ban drift (LC-204)' (#266) from fix/lc-204-retire-handrolled-migration-lists into main
d42ad50Merge branch 'main' into fix/lc-204-retire-handrolled-migration-lists
37b5066test: grep-ban hand-rolled migration lists + pin migration_enclaves (LC-204)
9118c35test: convert 34 hand-rolled migration lists to common::pool() (LC-204)
eecea87feat(ui): tokenize accent / focus-ring drift (LC-222)
a79a6d9Merge pull request 'fix(ui): tokenize .lc-md + swap 4 prose-slate no-ops onto lc-md (LC-221)' (#264) from feat/lc-221-markdown-tokenize into main
8ec1b7ffix(ui): tokenize .lc-md + swap 4 prose-slate no-ops onto lc-md (LC-221)
d37cc36Merge pull request 'feat(error): styled themed error page for AppError::IntoResponse (LC-220)' (#263) from feat/lc-220-styled-error-page into main
2f8e419fix(error): code-review fixes for LC-220 styled error page
ac538f4feat(error): styled themed error page for AppError::IntoResponse (LC-220)
83bd838Merge pull request 'fix(ui): admin top nav scrolls horizontally instead of wrapping (LC-219)' (#262) from feat/lc-219-admin-nav-scroll into main
8db5ba0fix(ui): reserve right padding for the version chip on admin nav (LC-219)
6a3f140fix(ui): admin top nav scrolls horizontally instead of wrapping (LC-219)
c16d02fMerge pull request 'fix(test): add 0057 migration to 18 hand-rolled test pools (LC-217 follow-up)' (#261) from fix/lc-217-migration-drift-test-pools into main
f20b025Merge pull request 'feat(ui): expand compact density to sidebar / header / composer (LC-218)' (#260) from feat/lc-218-density-compact-expanded into main
3e91c70fix(ui): split densityrowandrow-densefor proportional compression (LC-218)
7208b0bfix(test): add 0057 migration to 18 hand-rolled test pools (LC-217 follow-up)
377660dfeat(ui): expand compact density to sidebar / header / composer (LC-218)
4daa202Merge pull request 'feat(enclave): per-enclave message send rate-limit override (LC-217)' (#259) from feat/lc-217-enclave-msg-rate-limit into main
3334651docs(claude-md): polish LC-217 anti-spam section
3a3ecc8fix(test): tighten missed assertion in limits_are_per_enclave (LC-217)
f50b0edfix(enclave): code-review fixes for LC-217
b0fa47afeat(enclave): per-enclave message send rate-limit override (LC-217)
2cbb5fdMerge pull request 'fix(ui): debounce composer "Could not send" banner (LC-216)' (#258) from fix/lc-216-composer-error-debounce into main
4551adffix(ui): cancel pending composer error timer on form teardown (LC-216)
436bd5afix(ui): debounce composer "Could not send" banner (LC-216)
a1c830eMerge pull request 'feat(ui): tokenize soft-danger callouts for dark themes (LC-215)' (#257) from feat/lc-215-danger-surface-tokens into main
6de86d7fix(ui): tokenize outbox.js failed-send label (LC-215)
6d2acfefix(ui): code-review fixes for LC-215 danger-surface sweep
bd262a4feat(ui): tokenize soft-danger callouts for dark themes (LC-215)
728aeb1Merge pull request 'fix(ci): inject git_hash / git_version / build_date as build args (LC-214)' (#256) from fix/lc-214-ci-build-provenance into main
9429dccfix(ci): inject git_hash / git_version / build_date as build args (LC-214)
3f8258cMerge pull request 'fix(migrations): revert migration 6 comment edit + pin immutability rule (LC-212)' (#255) from fix/LC-212-migration-6-revert-comment-edit into main
c844bc8fix(migrations): revert migration 6 comment edit + pin immutability rule (LC-212)
64e4185Merge pull request 'chore(security): redact SMTP credentials from compose.dev.yml.1 template (LC-211)' (#253) from chore/lc-211b-redact-smtp-creds-template into main
875b743chore(security): redact SMTP credentials from compose.dev.yml.1 template (LC-211)
a27d152Merge pull request 'fix(ci): clippy clean on rust 1.94 (LC-187)' (#254) from fix/lc-187-clippy-resolve-msg-author into main
5b28d95fix(ci): clippy clean on rust 1.94 (LC-187)
cb23c60Merge pull request 'fix(compose): SMTP_TLS template value "implicit" -> "tls" (LC-211)' (#252) from fix/lc-211-smtp-tls-template-value into main
877cd3afix(compose): SMTP_TLS template value "implicit" -> "tls" (LC-211)
f75aca1Merge pull request 'feat(ui): viewport-fit, safe-area helpers, smoother nav drawer (LC-199)' (#251) from feat/lc-199-responsive into main
2d44ff2fix(ui): #main uses 100dvh so iOS URL bar doesn't eat content (LC-199)
77df44ffeat(ui): viewport-fit, safe-area helpers, smoother nav drawer (LC-199)
b882769Merge pull request 'style: rustfmt the LC-78/LC-152 bridge files (LC-187)' (#250) from fix/lc-187-fmt-bridge-files into main
428c548Merge pull request 'feat(ui): tokenize presence dots + status/bot badges (LC-198)' (#249) from feat/lc-198-icons-avatars into main
73f6b06style: rustfmt the LC-78 / LC-152 bridge files (LC-187)
f1426affix(ui): bot badge stays visible on row hover (LC-198)
53cfb33feat(ui): tokenize presence dots + status/bot badges (LC-198)
7457186Merge pull request 'feat(a11y): skip link, message-list live region, composer + popup labels (LC-197)' (#248) from feat/lc-197-a11y into main
8711c62fix(a11y): honest semantics for status picker + reaction trigger (LC-197)
7610726feat(a11y): skip link, message-list live region, composer + popup labels (LC-197)
b10c8a5Merge pull request 'feat(ui): motion & micro-interactions, prefers-reduced-motion aware (LC-196)' (#247) from feat/lc-196-motion into main
f04e662fix(ui): .lc-anim-swap fade uses transition, not animation (LC-196)
7d4aeb3feat(ui): motion & micro-interactions, prefers-reduced-motion aware (LC-196)
1c426d2Merge pull request 'feat(ui): shared component vocabulary (LC-195)' (#241) from feat/lc-195-components into main
4074068Merge pull request 'fix(security): close Web Push SSRF + LC-152 TOCTOU via shared http_client' (#246) from feat/lc-152-shared-http-client-no-bypass into main
80fdda1killer pair + grep-ban + per-site error propagation
aabe4cdelper + migrated sites for revie
bd6887bmigrate 5 outbound sites
6753093Merge pull request 'chore: rename SMTP env vars to LETS_CHAT_SMTP (LC-201)' (#244) from chore/lc-201-prefix-smtp-env-vars into main
0cc10bbMerge branch 'main' into chore/lc-201-prefix-smtp-env-vars
503055bhelper + custom Resolve + OnceLock client
a843a3aMerge pull request 'feat(bridges): foreign-avatar proxy (LC-78-AVATAR-PROXY, on by default)' (#245) from feat/lc-78-avatar-proxy into main
40c4fdcdocs: name the proxied-avatar threat model in v2
fce69ebtests across the 6 surfaces
446e326flip POST endpoint + new GET proxy + render template
504cd82flip POST endpoint + new GET proxy + render template
e77490aLC-152 audit + image-decoder spike + fetch module
37f86a9schema migration + db helpers
66801a8chore: rename SMTP env vars to LETS_CHAT_SMTP* (LC-201)
36cf5f3Merge pull request 'docs: bring README current with shipped features (LC-145)' (#242) from docs/lc-145-update-docs into main
936cc35Merge branch 'main' into docs/lc-145-update-docs
2adb12bMerge pull request 'feat(bridges): per-message synthetic actor + admin UI (LC-78 v1)' (#243) from feat/lc-78-bridge-registration-surface into main
65038eaoperator docs + migration-list drift fix in tests
ebafe43admin UI for bridge registration + health + plain remove
9f1460floop-break actor field across all LC-75 events
1e575c4bridge role tier + isolation test
e4ec15dbridges CRUD + heartbeat + sealed config
4e3633blist_messages_paginated fork
899a4afbridge-messages endpoint + bridge:post scope
f71a6c5schema + MessageActor::Bridge arm
fa69adddocs: bring README current with shipped features (LC-145)
876d281feat(ui): shared component vocabulary (buttons/inputs/cards/modals) (LC-195)
28e9a36Merge pull request 'feat(ui): density toggle + readability/compact polish (LC-194)' (#240) from feat/lc-194-density-polish into main
b4f0e8cfeat(ui): density toggle + readability/compact polish (LC-194)
531af8dMerge pull request 'feat(ui): migrate templates to semantic color tokens (LC-193)' (#239) from feat/lc-193-token-migration into main
bbcff9afeat(ui): migrate templates to semantic color tokens (LC-193)
a24d3f6Merge pull request 'feat(ui): high-contrast theme variants, WCAG AA/AAA (LC-192)' (#238) from feat/lc-192-high-contrast into main
fad8d14feat(ui): high-contrast theme variants, WCAG AA/AAA (LC-192)
6cc252fMerge pull request 'feat(ui): light/dark/system theme switching + per-user pref (LC-191)' (#237) from feat/lc-191-theme-switching into main
745a33efeat(ui): light/dark/system theme switching + per-user pref (LC-191)
873cce2Merge pull request 'feat(ui): design-token foundation + Tailwind theme wiring (LC-190)' (#236) from feat/lc-190-design-tokens into main
07b3a94feat(ui): semantic design-token foundation + Tailwind theme wiring (LC-190)
5e2a33dMerge pull request 'i18n: externalize UI chrome + Spanish catalog (LC-188)' (#235) from feat/lc-188-i18n-externalize into main
464a1e0i18n: externalize UI chrome across templates + Spanish catalog (LC-188)
b1c674dMerge pull request 'test(i18n): silence clippy single_element_loop in catalog coverage check' (#234) from feat/lc-100-i18n into main
22c2771test(i18n): silence clippy single_element_loop in catalog coverage check
808a5ccMerge pull request 'feat(i18n): Fluent + Askama localization framework (LC-100)' (#233) from feat/lc-100-i18n into main
30efeb8feat(i18n): Fluent + Askama framework, locale middleware, settings picker (LC-100)
3b93507Merge pull request 'feat(client): per-room RSS/Atom + iCal feeds, token-gated (LC-102)' (#232) from feat/lc-102-room-feeds into main
6cfc333feat(client): per-room RSS/Atom + iCal feeds, token-gated (LC-102)
f198ac2Merge pull request 'style: rustfmt the LC-186 remote-control audit files (LC-187)' (#231) from fix/lc-187-fmt into main
346cfb1style: rustfmt the LC-186 remote-control audit files
d117ef1Merge pull request 'feat(realtime,desktop): remote-control safety envelope (LC-186)' (#230) from feat/lc-186-remote-control-safety into main
381cd67feat(realtime,desktop): remote-control safety envelope (LC-186)
129fe1aMerge pull request 'feat(desktop): native OS input injection for remote control (LC-185, Windows first)' (#229) from feat/lc-185-native-input-injection into main
3ffb3e9fix(desktop): clear held input when arming a remote-control session
c6201a5feat(desktop): native OS input injection for remote control (LC-185, Windows first)
dc4a6c1Merge pull request 'feat(realtime): remote-control input capture + data-channel transport (LC-184, controller)' (#228) from feat/lc-184-remote-control-input-capture into main
b255670feat(realtime): remote-control input capture + data-channel transport (LC-184, controller)
f63f686Merge pull request 'feat(realtime): remote-control consent signaling + verified-email gate (LC-183 server)' (#227) from feat/lc-183-remote-control-handshake into main
847152cfeat(realtime): remote-control consent signaling + verified-email gate (LC-183, server)
333a519Merge pull request 'docs: remote-control design + threat model (LC-182)' (#226) from docs/lc-182-remote-control-design into main
6413497docs: address LC-182 design review - de-risk the subtask handoffs
b4c8820docs: remote-control design + threat model (LC-182)
f165833Merge pull request 'spike(LC-131): Windows installer from Linux via NSIS' (#225) from spike/lc-131-nsis-from-linux into main
1732bfffeat(desktop): build + publish the Windows installer from Linux (LC-131)
05bf94bspike(LC-131): build the Windows installer from Linux with NSIS
3914ebeMerge pull request 'feat(realtime): live refresh affordance for /inbox and /activity (LC-179)' (#224) from feat/lc-179-live-inbox-activity into main
c73b4f6docs: bring live-updates documentation current with the LC-156 epic (LC-179)
44c8b15feat(realtime): live refresh affordance for /inbox and /activity (LC-179)
d749be0Merge pull request 'feat(realtime): live /saved list on bookmark/unbookmark (LC-178, saved surface)' (#223) from feat/lc-178-live-saved into main
e8e366dfeat(realtime): live /saved list on bookmark/unbookmark (LC-178, saved surface)
305b6d9Merge pull request 'feat(realtime): live admin room list (LC-177)' (#222) from feat/lc-177-live-admin-rooms into main
e7ece06feat(realtime): live admin room list (archive/edit/invite/regenerate) (LC-177)
bd0de88Merge pull request 'feat(realtime): drop a user's enclave topic subscription on access loss (LC-176)' (#221) from feat/lc-176-topic-unsubscribe into main
9e3457bfeat(realtime): drop a user's enclave topic subscription on access loss (LC-176)
9259fd4Merge pull request 'feat(realtime): live admin user list (LC-175, admin-user surface)' (#220) from feat/lc-175-live-admin-lists into main
d5a6a9ffeat(realtime): live admin user list (ban/mute/role/quota/delete) (LC-175, admin-user surface)
1a49795Merge pull request 'feat(realtime): live sidebar room list on enclave room add/remove (LC-174)' (#219) from feat/lc-174-live-sidebar-rooms into main
dddc6f3feat(realtime): live sidebar room list on enclave room add/remove (LC-174)
f335a59Merge pull request 'feat(realtime): live own-profile refresh in the sidebar self block (LC-173 phases 1-2)' (#218) from feat/lc-173-live-own-profile into main
3c52b03feat(realtime): live own-profile refresh in the sidebar self block (LC-173 phases 1-2)
d569cd1Merge pull request 'feat(realtime): live enclave settings-page member list (LC-172)' (#217) from feat/lc-172-live-settings-members into main
efd9037feat(realtime): live enclave settings-page member list (LC-172)
cd1b01dMerge pull request 'fix(composer): Enter defers to an open mention/slash combobox (LC-171)' (#216) from fix/lc-171-composer-enter-guard into main
786b6e6test(composer): make the LC-171 Enter-guard assertion reformat-tolerant
1ca0806fix(composer): Enter defers to an open mention/slash combobox (LC-171)
559222cMerge pull request 'feat(realtime): live enclave member + room lists on the landing page (LC-170)' (#215) from feat/lc-170-live-enclave-lists into main
4374071fix(realtime): let non-member site admins subscribe to the enclave topic (LC-170 review)
fa12548feat(realtime): live enclave member + room lists on the landing page (LC-170)
a3adcbbMerge pull request 'chore(ui): consolidate avatar renderer, auth form-errors, confirm-dialog guideline (LC-169)' (#214) from chore/lc-169-ui-consolidation into main
0893fd0chore(ui): consolidate avatar renderer, auth form-errors, confirm-dialog guideline (LC-169)
6ac3409Merge pull request 'feat(a11y): keyboard navigation for the slash-command popover (LC-168)' (#213) from feat/lc-168-slash-keyboard-nav into main
bcf39e6feat(a11y): keyboard navigation for the slash-command popover (LC-168)
ca043a4Merge pull request 'feat(realtime): live invitations page (LC-161, first surface)' (#212) from feat/lc-161-live-invitations into main
d3fbd2afeat(realtime): live invitations page (LC-161, first surface)
ec7c226Merge pull request 'feat(realtime): typed WS topics (enclave/user/admin) + subscribe-time auth (LC-160)' (#211) from feat/lc-160-typed-ws-topics into main
beb9728feat(realtime): typed WS topics (enclave/user/admin) + subscribe-time auth (LC-160)
90a66fbMerge pull request 'fix(a11y): reminder picker modal focus-trap parity (LC-158)' (#210) from chore/lc-158-reminder-modal-a11y into main
5ea4113refactor(a11y): dispose the reminder-picker trap on every path (LC-158)
8eb46befix(a11y): bring the reminder picker modal to focus-trap parity (LC-158)
311fcd8Merge pull request 'feat(search): shared keyboard navigation + ARIA for search bars (LC-157 phase 1)' (#209) from feat/lc-157-search-keyboard-nav into main
d75cdc1fix(search): namespace option ids so they are document-unique (LC-157)
ddf8906feat(search): shared keyboard navigation + ARIA for search bars (LC-157 phase 1)
628a27bMerge pull request 'feat(email-ingress): optional dead-letter folder for dropped messages (LC-77-DEAD-LETTER)' (#208) from feat/lc-77-dead-letter into main
556f8a1feat(email-ingress): optional dead-letter IMAP folder for dropped messages (LC-77-DEAD-LETTER)
653cd97Merge pull request 'feat(email-ingress): exactly-once dedup via Message-ID hash (LC-77-MID-DEDUP)' (#207) from feat/lc-77-mid-dedup into main
5bd6f87feat(email-ingress): wire processed-Message-ID dedup into poll loop (LC-77-MID-DEDUP commit 2)
2d0a21ffeat(email-ingress): processed_message_ids dedup schema + db primitives (LC-77-MID-DEDUP commit 1)
cd583bbMerge pull request 'feat(email-ingress): reply-by-email ingress (LC-77-REPLY stage 2)' (#206) from feat/lc-77-reply-stage2 into main
6250aebtest(email-ingress): threat-model tests + docs for reply-by-email (LC-77-REPLY commit 2d)
12cde6bfeat(email-ingress): poll loop dispatches ReplyMatch to reply_actor (LC-77-REPLY commit 2c)
2e61571feat(email-ingress): reply-by-email actor + quote/signature strip (LC-77-REPLY commit 2b)
1a3747afeat(email-ingress): namespace-forked resolver + reply-token primitives (LC-77-REPLY commit 2a)
503f0abMerge pull request 'feat(notify): per-mention/DM notification emails (LC-77-REPLY stage 1)' (#205) from feat/lc-77-reply-stage1 into main
9646eb2test(notify): end-to-end mention/DM dispatch tests + docs touch-up (LC-77-REPLY commit 1d)
773a06cfeat(notify): wire mention/DM email dispatch into the post path (LC-77-REPLY commit 1c)
cee7699feat(email): per-message mention/DM notification dispatcher + Reply-To (LC-77-REPLY commit 1b)
47f51eafeat(db): reply_tokens schema + per-user notify_email_activity opt-in (LC-77-REPLY commit 1a)
ecb892bMerge pull request 'refactor(admin): remove dead SMTP admin form + clean up stale rows (LC-77-SMTP-SEAL, #200)' (#204) from feat/lc-77-smtp-seal into main
7d071e8refactor(admin): remove dead SMTP admin form + clean up stale settings rows (LC-77-SMTP-SEAL)
3c83c9cMerge pull request 'docs(email-ingress): operator guide + threat-model integration tests (LC-77)' (#199) from feat/lc-77-docs into main
d242a9edocs(email-ingress): operator guide + threat-model integration tests (LC-77)
bc94365Merge pull request 'feat(email-ingress): MIME body + attachment upload pipeline (LC-77)' (#198) from feat/lc-77-mime-attachments into main
b080653feat(email-ingress): MIME body + attachment upload pipeline (LC-77)
2fd425eMerge pull request 'feat(email-ingress): admin lifecycle UI (LC-77)' (#197) from feat/lc-77-admin-ui into main
70a133ffeat(email-ingress): admin settings UI for IMAP config (LC-77)
f185a89feat(email-ingress): per-room admin UI for email inboxes (LC-77)
b2b24b0Merge pull request 'feat(email-ingress): IMAP poll + resolution + synthetic-actor send (LC-77)' (#196) from feat/lc-77-imap-poll into main
8891bbdstyle: cargo fmt sweep across the LC-77 surface + LC-59 carryover
d2d2409test(email-ingress): per-message pipeline integration tests (LC-77)
71095abfeat(email-ingress): IMAP poll loop + spawn_email_poll (LC-77)
eecbdf9feat(email-ingress): email_ingress module core + finalize send path (LC-77)
f3a0d4cfeat(email-ingress): db layer + rate-limit kind (LC-77)
2832602refactor(messages): add EmailInbox actor variant + AuthorMeta.actor (LC-77)
0de27ccMerge pull request 'feat(email-ingress): schema for IMAP config + email inboxes (LC-77)' (#195) from feat/lc-77-schema into main
b590185feat(email-ingress): schema for IMAP config + email inboxes (LC-77)
b23e010Merge pull request 'refactor(messages): MessageActor enum for render-time actor identity (LC-77)' (#194) from feat/lc-77-message-actor-enum into main
1d9b210refactor(messages): MessageActor enum for render-time actor identity (LC-77)
0182bbctest(messages): pin webhook render output as pre-refactor fixture (LC-77)
6eaaa1aMerge pull request 'feat/lc-59-math' (#193) from feat/lc-59-math into main
469dbd8feat(messages): wire LaTeX math into markdown pipeline + round-trip tests (LC-59)
081543cfeat(messages): server-side LaTeX -> MathML rendering module (LC-59)
f305aa5Merge pull request 'feat(realtime): declarative live-update subscription module (LC-156 phase 1)' (#192) from feat/lc-156-live-subscribe-foundation into main
7b2605dfix(realtime): also re-subscribe on htmx:afterSettle, not just htmx:load (LC-156)
ec3615cfeat(realtime): declarative live-update subscription module (LC-156 phase 1)
b4ff9ccMerge pull request 'fix(security): token CSPRNG + proxy-trust + og:image hardening (LC-155)' (#191) from feat/lc-155-token-csprng-hardening into main
9b35a25fix(unfurl): re-sanitize cached og:image on the cache-hit path (LC-155)
b6735ebfix(security): token CSPRNG + proxy-header trust + og:image scheme hardening (LC-155)
925b319Merge pull request 'fix(security): allowlist markdown link/image schemes (LC-154)' (#189) from feat/lc-154-markdown-link-scheme into main
3497de9fix(security): also scheme-allowlist the login-body markdown renderer (LC-154)
cd3d54efix(security): allowlist markdown link/image schemes (LC-154)
bf58ae3Merge pull request 'fix(security): cap message body length (LC-153)' (#188) from feat/lc-153-message-length-cap into main
f60c738fix(security): cap message length on the JSON API v1 POST too (LC-153)
bc48c01fix(security): cap message body length (LC-153)
c564162Merge pull request 'fix(security): SSRF guard at webhook delivery time + shared predicate (LC-152)' (#186) from feat/lc-152-webhook-delivery-ssrf into main
46aa6dcfix(security): SSRF guard at webhook delivery time + shared predicate (LC-152)
0f930d6Merge pull request 'fix(security): rate-limit login + 2FA challenge endpoints (LC-151)' (#184) from feat/lc-151-login-rate-limit into main
ebdc879fix(security): rate-limit login + 2FA challenge endpoints (LC-151)
4aa8119Merge pull request 'fix(security): re-validate every redirect hop in unfurl against SSRF guard (LC-150)' (#183) from feat/lc-150-unfurl-redirect-ssrf into main
ed8e9fdfix(unfurl): bail on empty redirect Location instead of re-fetching self (LC-150)
02f73c1fix(security): re-validate every redirect hop in unfurl against SSRF guard (LC-150)
fe03449Merge pull request 'fix(security): enforce room access on reaction handlers (LC-149)' (#182) from feat/lc-149-reactions-authz into main
d2473affix(security): enforce room access on reaction handlers (LC-149)
76513b2Merge pull request 'docs(audit): codebase-wide review + live-update and search designs (LC-148)' (#181) from chore/lc-148-codebase-audit into main
a38d55fdocs(audit): codebase-wide review report + live-update and search design docs (LC-148)
9fa401fMerge pull request 'feat(notifications): cap push subscriptions per user across channels (LC-147)' (#180) from feat/lc-147-cap-push-subscriptions into main
995716ffeat(notifications): cap push subscriptions per user across channels (LC-147)
623d131Merge pull request 'feat(notifications): mobile push foundation (APNs + FCM channels) (LC-91)' (#179) from feat/lc-91-mobile-push-foundation into main
477370afeat(notifications): mobile push foundation (APNs + FCM channels) (LC-91)
5c6cda5Merge pull request 'test(notifications): close per-room notification-level audit gaps (LC-90)' (#178) from feat/lc-90-per-room-notify-audit into main
0de703ftest(notifications): assert private-room dropdown for a non-admin member (LC-90)
b4c8315test(notifications): close per-room notification-level audit gaps (LC-90)
15ecf9cMerge pull request 'feat(notifications): per-user Do Not Disturb / quiet hours (LC-88)' (#177) from feat/lc-88-dnd-quiet-hours into main
8eced21feat(notifications): per-user Do Not Disturb / quiet hours (LC-88)
6985228Merge pull request 'workflow/check-secrets.yml' (#176) from workflow/check-secrets.yml into main
57392b7add .noseyparker-ignore.txt
9720335add .trufflehog-exclude.txt
ef18903add check-secrets.yml
bdff2b1Merge pull request 'feat/lc-64-message-drafts' (#175) from feat/lc-64-message-drafts into main
89041e1test(drafts): integration tests + query-plan pin (LC-64)
a2fabdcfeat(drafts): composer wiring + render-on-load with lazy cleanup (LC-64)
5227ba4feat(drafts): PUT handler + race guard + clear-on-send/schedule + purge (LC-64)
1cf7a5ffeat(drafts): scaffold message_drafts schema + db module (LC-64)
21f6d27Merge pull request 'feat/room-retention' (#174) from feat/room-retention into main
c125d9bMerge branch 'main' into feat/room-retention
3d6bdf8Merge pull request 'docs: refresh README, FUTURE, and API docs for shipped features (LC-145)' (#173) from chore/lc-145-update-docs into main
7f47cc5docs: refresh README, FUTURE, and API docs for shipped features (LC-145)
fd02934feat(retention): admin UI + audit + env-var docs
13a9bb7feat(retention): wire spawn + MessagePurged broadcast
efd2c5afeat(retention): sweep logic + FTS trigger guard (0046)
98dcbc3test(retention): verify cascade fires for every message FK
e3cb693docs(test-maintenance): correct stale migration-drift note
8e98332feat(retention): scaffold room retention schema and fix cascade gaps
41681a4Merge pull request 'feat(calls): select mic/camera/speaker instead of system default (LC-144)' (#172) from feat/lc-144-call-device-select into main
eff7928fix(calls): guard device picker against stale refresh + idle speaker re-route (LC-144)
1dca2f1feat(calls): select mic/camera/speaker instead of system default (LC-144)
89084a1Merge pull request 'feat(integration): outgoing webhooks / event subscriptions (LC-75)' (#171) from feat/lc-75-outgoing-webhooks into main
69d5d62fix(webhooks): SSRF guard + replay-resistant signature for outgoing webhooks (LC-75)
a1dd501feat(integration): outgoing webhooks / event subscriptions (LC-75)
66da262Merge pull request 'feat(integration): incoming webhooks (post-as URL) (LC-74)' (#170) from feat/lc-74-incoming-webhooks into main
f229545fix(webhooks): cap incoming webhook message length (LC-74)
0837c39feat(integration): incoming webhooks (post-as URL) (LC-74)
cd894d7Merge pull request 'feat(justfile): scaffold fj-driven create-release + group attrs (DEV-331)' (#169) from feat/justfile-fj-pr-create-DEV-331 into main
a2f1b79feat(justfile): scaffold fj-driven create-release + group attrs (DEV-331)
ebd2d39Merge pull request 'feat(integration): first-class bot identity (LC-73)' (#168) from feat/lc-73-bots into main
9468118fix(bots): roll back orphan bot row if token minting fails (LC-73)
2c1e3c3feat(integration): first-class bot identity (LC-73)
67a3a36Merge pull request 'feat(integration): scoped bearer API tokens + JSON API v1 (LC-72)' (#167) from feat/lc-72-api-tokens into main
f5b2d21fix(api): case-insensitive Bearer scheme; document maintenance bypass (LC-72)
ff11216feat(integration): scoped bearer API tokens + JSON API v1 (LC-72)
89e5088Merge pull request 'feat(navigation): clicking an enclave opens last/default room + settings gear (LC-143)' (#166) from feat/lc-143-enclave-last-room into main
0a63c6cfix(navigation): pick enclave default room from the openable set (LC-143)
21d0d88feat(navigation): clicking an enclave opens last/default room; settings gear (LC-143)
50a8c94Merge pull request 'feat(integration): slash commands framework (LC-76)' (#165) from feat/lc-76-slash-commands into main
cd181a3fix(slash): SSRF guard on webhook command URLs; overflow-safe duration (LC-76)
1d837f4feat(integration): slash commands framework (LC-76)
5a35d5bMerge pull request 'feat(messaging): polls / voting (LC-66)' (#164) from feat/lc-66-polls into main
727a368perf(polls): skip build_poll_view for non-poll messages; test non-member vote (LC-66)
4f9fa6bfeat(messaging): polls / voting (LC-66)
cada393Merge pull request 'feat(messaging): message reminders - remind me about this (LC-63)' (#163) from feat/lc-63-reminders into main
8dcae88fix(reminders): re-check room access at fire time (LC-63)
53ab287feat(messaging): "remind me about this message" reminders (LC-63)
c26efe9Merge pull request 'feat(branding): per-scope favicon, global-only v1 (LC-142)' (#162) from feat/lc-142-branding-favicon into main
7c67283fix(branding): sandbox served favicon SVG; consistent cache-bust (LC-142)
7a50a65feat(branding): per-scope favicon, global-only v1 (LC-142)
b1267b5Merge pull request 'feat(branding): render custom logo in the enclave switcher (LC-141)' (#161) from feat/lc-141-sidebar-logo into main
efbac56fix(branding): cache-bust switcher logo URLs with asset_version (LC-141)
d082734feat(branding): render custom logo in the enclave switcher (LC-141)
3b90483Merge pull request 'feat(pwa): installable PWA + offline message outbox (LC-98)' (#160) from feat/lc-98-pwa-offline-outbox into main
2fdd311feat(pwa): installable PWA + offline message outbox (LC-98)
d25fe18Merge pull request 'feat(admin): analytics dashboard (DAU/MAU/messages/rooms/signups) (LC-97)' (#159) from feat/lc-97-admin-analytics into main
d6d3922feat(admin): analytics dashboard with DAU/MAU/messages/rooms/signups + retention (LC-97)
b24bb18Merge pull request 'feat(admin): branding - custom logo, colors, login text (LC-96)' (#158) from feat/lc-96-branding into main
7ed437bMerge remote-tracking branch 'origin/main' into feat/lc-96-branding
1ae0221fix(branding): code-review follow-ups (LC-96)
27dfce2feat(branding): custom logo, colors, login text (LC-96)
6ae9e20Merge pull request 'feat/lc-62-scheduled-send-pr-b' (#157) from feat/lc-62-scheduled-send-pr-b into main
59ae590fix(scheduled): label /scheduled timestamps as UTC (LC-62)
61d2089docs: README Features entry for scheduled-send (LC-62)
817c0ecfeat(scheduled): purge scheduled rows on account delete (LC-62)
07a4d16feat(scheduled): composer modal UI reusing Phase 25 dialog focus-trap (LC-62)
aed7284feat(scheduled): /scheduled routes + management view + shared validation (LC-62)
1320497feat(scheduled): background dispatcher with atomic claim + re-validation (LC-62)
0449081Merge pull request 'feat/lc-62-scheduled-send' (#156) from feat/lc-62-scheduled-send into main
7c4d808feat(scheduled): schema + db module + orphan-sweep guard (LC-62)
f271353refactor(routes): extract finalize_message_send from post_message (LC-62)
e8c763fMerge pull request 'feat(admin): backup + restore archive (LC-95)' (#155) from feat/lc-95-backup-restore into main
2f8e7c7fix(backup): code-review follow-ups (LC-95)
e0df85afeat(admin): backup + restore archive (LC-95)
2f831a1Merge pull request 'feat(anti-spam): rate limits + link filter + honeypot (LC-94)' (#154) from feat/lc-94-anti-spam into main
017996efix(anti-spam): code-review follow-ups (LC-94)
b33e4adfeat(anti-spam): admin pages + integration tests (LC-94)
228be41feat(anti-spam): wire enforcement at messages, register, forgot (LC-94)
cbf18fcfeat(anti-spam): schema, rate-limit module, link helpers (LC-94)
70f3713Merge pull request 'feat(admin): per-user + per-enclave storage quotas (LC-93)' (#153) from feat/lc-93-storage-quotas into main
9a2b3f3fix(quotas): code-review follow-ups (LC-93)
e4cb63cfeat(admin): per-user + per-enclave storage quotas (LC-93)
f689b78Merge pull request 'feat(admin): maintenance-mode UI toggle + 503 gate (LC-92)' (#152) from feat/lc-92-maintenance-mode into main
f63e929fix(admin): exempt password-reset surface from maintenance gate
2ba923cfeat(admin): maintenance-mode UI toggle + 503 gate (LC-92)
50b89d8Merge pull request 'feat(rooms): per-room Files tab in room info (LC-87)' (#151) from feat/lc-87-room-files-tab into main
319f250feat(rooms): per-room Files tab in room info page (LC-87)
7bb7adcMerge pull request 'feat(rooms): room info page with description + wiki (LC-86)' (#150) from feat/lc-86-room-docs-wiki into main
712a472feat(rooms): room info page with description + wiki (LC-86)
2c9baf6Merge pull request 'feat(rooms): read-only / moderators-only posting policy (LC-85)' (#149) from feat/lc-85-readonly-rooms into main
02ba040feat(rooms): read-only / moderators-only posting policy (LC-85)
0c9a4deMerge pull request 'feat(rbac): per-room moderator overrides (LC-84)' (#148) from feat/lc-84-per-room-role-overrides into main
e81d19ffeat(rbac): room-header link to per-room moderators page
82eaf80feat(rbac): per-room moderator overrides (LC-84)
98614bfMerge pull request 'fix(autoscroll): re-anchor on composer resize' (#147) from fix/mention-autocomplete-breaks-autoscroll into main
807aae9Merge pull request 'feat(mentions): user groups in @ autocomplete' (#146) from feat/lc-83-group-mention-popover into main
e9a3b5aMerge pull request 'feat(enclave): typeahead UX for group Add member' (#145) from feat/lc-83-add-member-typeahead into main
8911207fix(autoscroll): scope teardown to #messages, not bubbling ancestor
8e157a8fix(autoscroll): drivewasAtBottomfrom scroll events only
5724193fix(autoscroll): re-anchor on composer resize, not just on htmx swap
31e2dbafeat(mentions): include user groups in @ autocomplete
8e6cc6dfeat(enclave): typeahead UX for group "Add member"
6a816c0Merge pull request 'feat(enclave): user-groups CRUD UI' (#144) from feat/lc-83-user-groups-ui into main
a312908Merge pull request 'feat(mentions): per-enclave user groups @group-name (LC-83)' (#143) from feat/lc-83-user-groups into main
6497b02feat(enclave): user-groups CRUD UI in enclave settings
09979bdfeat(mentions): per-enclave user groups (@group-name) - LC-83
bcda3eeMerge pull request 'feat(activity): activity center at /activity (LC-82)' (#142) from feat/lc-82-activity into main
b883ca4feat(activity): per-user activity feed at /activity (LC-82)
67ef16aMerge pull request 'fix(dm): send WS subscribe when page mounts on an already-open socket' (#141) from fix/dm-subscribe-on-open-socket into main
204fe68fix(dm): send WS subscribe when page mounts on an already-open socket
922fe5aMerge pull request 'feat(sidebar): jump-to-unread + /inbox (LC-81) [stacked]' (#140) from feat/lc-81-jump-and-inbox into main
250eb24feat(sidebar): jump-to-unread keybind + /inbox view (LC-81)
0c89bdcMerge pull request 'feat(sidebar): per-user starred rooms + DMs (LC-80) [stacked]' (#139) from feat/lc-80-starred-rooms into main
40c6ecafeat(sidebar): per-user starred rooms + DMs (LC-80)
f01bc68Merge pull request 'fix(sidebar): active-room highlight + drag-to-uncategorize (LC-79 follow-up)' (#138) from fix/sidebar-active-room-and-uncategorize into main
740f8f9fix(sidebar): active-room highlight + drag-to-uncategorize after LC-79 redesign
483c4dcMerge pull request 'refactor(sidebar): per-enclave admin-managed room categories (LC-79 redesign)' (#137) from refactor/lc-79-enclave-scoped-categories into main
7daad44refactor(sidebar): make room categories per-enclave, admin-managed (LC-79 redesign)
7929ca1Merge pull request 'fix(sidebar): show room count on collapsed-category header' (#136) from fix/sidebar-collapsed-room-count into main
67f664dfix(sidebar): show room count on collapsed-category header
dcf7fbeMerge pull request 'fix(sidebar): make uncategorized rooms draggable into categories' (#135) from fix/sidebar-uncategorized-draggable into main
f60a7edfix(sidebar): make uncategorized room rows draggable into categories
eae8471Merge pull request 'fix(sidebar): keep room list visible when category mutations fire from an enclave page' (#134) from fix/sidebar-categories-respect-current-enclave into main
92bbb91fix(sidebar): derive current enclave from HX-Current-URL on category mutations
684171aMerge pull request 'fix(sidebar): scrub categorization on room leave (LC-79 AC #5)' (#133) from fix/lc-79-ac5-forget-room-on-leave into main
ce535a3fix(sidebar): scrub category assignments when user leaves a room (LC-79 AC #5)
15c626bMerge pull request 'feat(sidebar): collapsed aggregate + mobile tap target (LC-79 phase 3)' (#132) from feat/lc-79-phase3-collapsed-aggregate-mobile into main
e55b912feat(sidebar): collapsed-category aggregate badges + mobile tap target (LC-79 phase 3)
d9fdddcMerge pull request 'feat(sidebar): drag-and-drop category + room reorder (LC-79 phase 2)' (#131) from feat/lc-79-phase2-drag-and-drop into main
ba4a506feat(sidebar): drag-and-drop category + room reorder (LC-79 phase 2)
7a7bfd9Merge pull request 'feat(sidebar): grouped category render + UI (LC-79 phase 1b)' (#130) from feat/lc-79-sidebar-categories-phase1b into main
53e6012feat(sidebar): grouped category render + UI affordances (LC-79 phase 1b)
1857f8bMerge pull request 'feat(sidebar): per-user channel-category schema + CRUD (LC-79 phase 1a)' (#129) from feat/lc-79-sidebar-categories-phase1 into main
9e2fa0cfeat(sidebar): per-user channel-category schema + CRUD endpoints
0d437d4Merge pull request 'ci(desktop): publish Linux .deb + .AppImage bundles' (#128) from feat/lc-132-publish-linux-bundles into main
dbf2c9aci(desktop): publish Linux .deb + .AppImage bundles
ba3364cMerge pull request 'feat(desktop): auto-grant getUserMedia on Linux + Windows' (#127) from feat/lc-129-getusermedia-permission-hooks into main
231f106feat(desktop): auto-grant getUserMedia on Linux + Windows
3773c2bMerge pull request 'feat/screen-share' (#126) from feat/screen-share into main
4f99a8aMerge remote-tracking branch 'origin/main' into feat/screen-share
c31262cfeat(voice): add screen share to enclave voice channels
dd3e9d0Merge pull request 'plan/phase26-edit-history' (#125) from plan/phase26-edit-history into main
dad6052style: cargo fmt cleanup across phase 26 work
2732926docs(claude): document test-harness 2FA and admin-promotion gotchas
67caf27feat(room): make (edited) label in thread reply open history drawer
fb30860test(message_editing): add edit-history db and route integration tests
3c3a1e3feat(room): add edit-history drawer for edited messages
00d7b36feat(db): add MessageEdit type and transactional edit history writes
7fb5fc9docs(plans): add phase 26 edit history implementation plan
c09b6fcfeat(db): add message_edits table for per-message edit history
f8fb7baMerge pull request 'feat(desktop): URL editor, tray, Linux bundles, cookie fix (LC-123)' (#124) from feat/desktop-clients into main
0f8e400feat(desktop): URL editor, tray, Linux bundles, cookie fix (LC-123)
7f75065Merge pull request 'chrone/accessibility-audit' (#123) from chrone/accessibility-audit into main
6562809feat(a11y): record axe baseline JSON and document Task 8 findings
c174398feat(a11y): implement combobox ARIA pattern for mention popover
8376b2ffeat(a11y): add focus trap and ARIA roles to call dialogs
fa0675cfeat(a11y): add HTMX afterSwap focus restoration with opt-out support
24c1635feat(a11y): add aria-expanded toggle to mobile nav button and update deferred list
c8b1139feat(a11y): add aria-labels and harden screen reader announcement text
6fe1c08feat(a11y): add aria-live regions and screen reader announcements
6112b0dfeat(a11y): add phase 25 accessibility plan and global :focus-visible rule
dcb5ce9fix(call): make screen share actually reach the peer
5a06be9feat(call): add screen share to 1:1 calls
cf58930Merge pull request 'feat(presence): add sticky manual "away" status distinct from auto-idle' (#122) from feat/sticky-away into main
e7143c3Merge pull request 'feat(presence): relabel statuses Online/Away, add aria-label and offline color' (#121) from feat/presence-polish into main
bbb75aafeat(presence): add sticky manual "away" status distinct from auto-idle
3d1ef08feat(presence): relabel statuses Online/Away, add aria-label and offline color
f6e254dMerge pull request 'feat/tauri2-desktop-migration' (#120) from feat/tauri2-desktop-migration into main
26ee755fix(dev-desktop): mount XAUTHORITY and grant xhost so the Tauri 2 window can open the X display
c5bd8b6ci(desktop): wire Tauri 2 build files into the workflow paths and Windows cross-compile
3daba48feat(desktop): migrate from Tao+Wry to Tauri 2
d4cf6bdMerge pull request 'fix(auth): defer account creation until 2FA enrollment completes' (#119) from fix/2fa-before-registration into main
bb78d41fix(auth): defer account creation until 2FA enrollment completes
1ebbfb4Merge pull request 'fix(voice): self-video, DM-call takeover, and live participants preview' (#118) from fix/voice-call-bugs into main
52ab2c9fix(voice): self-video, DM-call takeover, and live participants preview
7a2ff88Merge pull request 'fix(call): deliver incoming-call popup from any page and resolve glare server-side' (#117) from fix/global-call-popup-and-glare into main
3be65e4fix(call): deliver incoming-call popup from any page and resolve glare server-side
44eb986Merge pull request 'refactor(dev): convert dev-* recipes to Docker Compose' (#115) from feat/dev-recipes-to-compose into main
39a579brefactor(dev): convert dev-* recipes to Docker Compose
f1526a9Merge pull request 'feat(desktop): show a welcome page when the server is unreachable' (#114) from feat/desktop-welcome-page into main
f96fc35feat(desktop): show a welcome page when the server is unreachable
c9c37afMerge pull request 'fix(ci): move FORGEJO_TOKEN to step-env so the secret reaches nu' (#113) from fix/forgejo-token-step-env-v2 into main
f1ccc2bfix(ci): move FORGEJO_TOKEN to step-env so the secret reaches nu
99352b4Merge pull request 'fix(ci): use nu http delete/put for generic-packages uploads (yotun pattern)' (#112) from fix/generic-packages-use-nu-http into main
76cb3fcfix(ci): use nu http delete/put for generic-packages uploads (yotun pattern)
5f1a0a9Merge pull request 'fix(ci): switch generic-packages upload auth to HTTP Basic with owner:token' (#111) from fix/generic-packages-basic-auth into main
bff7fb4fix(ci): switch generic-packages upload auth to HTTP Basic with owner:token
71968bfMerge pull request 'fix(ci): publish desktop binaries to the private package registry' (#110) from fix/desktop-workflows-publish-to-packages into main
9100e59Merge branch 'main' into fix/desktop-workflows-publish-to-packages
1602316fix(ci): publish desktop binaries to the private package registry
62371dbMerge pull request 'fix(ci): build-oci-image pushes to the private org registry' (#109) from fix/build-oci-image-private-package-org into main
820942ffix(ci): build-oci-image pushes to the private org registry
455efe7Merge pull request 'chore(dev): point dev/cargo wrappers at the shared org builder image' (#108) from chore/use-rust-builder-glibc-image into main
04d58b9chore(dev): point dev/cargo wrappers at the shared org builder image
725535bMerge pull request 'chore(dev): align local clippy with CI (Rust 1.94 + -D warnings)' (#106) from chore/sync-local-clippy-with-ci into main
5ee6ebeMerge branch 'main' into chore/sync-local-clippy-with-ci
531591fMerge pull request 'fix(ci): publish lets-chat-desktop releases to the private package org' (#107) from fix/publish-release-private-package-org into main
0b94fadMerge branch 'main' into fix/publish-release-private-package-org
4cbbe26Merge branch 'main' into chore/sync-local-clippy-with-ci
12c6bd6fix(ci): publish lets-chat-desktop releases to the private package org
1af0380chore(dev): align local clippy with CI (Rust 1.94 + -D warnings)
d4f42abMerge pull request 'chore: silence clippy 1.94 errors so CI -D warnings stays green' (#105) from chore/clippy-1.94-cleanup into main
4c25156Merge branch 'main' into chore/clippy-1.94-cleanup
9f2f02fchore: silence clippy 1.94 errors so CI -D warnings stays green
c07b5a9Merge pull request 'fix(ci): drop save --force from publish-release manifest write' (#104) from fix/publish-release-no-save-force into main
01c7daefix(ci): drop save --force from publish-release manifest write
3ba793eMerge pull request 'feat(desktop): self-update for the lets-chat-desktop binary' (#103) from feat/desktop-self-update into main
c646927feat(desktop): self-update for the lets-chat-desktop binary
af963acMerge pull request 'feat(ci): cross-compile lets-chat-desktop for Windows x86_64' (#102) from feat/desktop-windows-build into main
e53038eMerge branch 'main' into feat/desktop-windows-build
65dad3dMerge pull request 'chore(ci): drop redundant apt install from Dockerfile.desktop-linux' (#101) from chore/desktop-linux-dockerfile-dedupe into main
aa3da4bMerge branch 'main' into chore/desktop-linux-dockerfile-dedupe
ff485b0Merge pull request 'style: apply cargo fmt to fix drifted formatting' (#100) from style/cargo-fmt-drift into main
618b873Merge branch 'main' into style/cargo-fmt-drift
8f573b5Merge pull request 'fix(dev): chown cargo volumes on first run so check works without root' (#99) from fix/dev-cargo-volume-perms into main
dea41abMerge branch 'main' into fix/dev-cargo-volume-perms
0782818Merge pull request 'chore: group just recipes for clearer --list output' (#98) from chore/group-just-recipes into main
cb79c5ffeat(ci): cross-compile lets-chat-desktop for Windows x86_64
580c2cechore(ci): drop redundant apt install from Dockerfile.desktop-linux
27d7c55style: apply cargo fmt to fix drifted formatting
d389c29fix(dev): chown cargo volumes on first run so check works without root
35e05b7chore: group just recipes for clearer --list output
336b3a5Merge pull request 'feat: Lets Chat screenshot' (#97) from feat/lets-chat-screenshot into main
76dc89efeat: Lets Chat screenshot
be627caMerge pull request 'chore/test-debt-cleanup' (#95) from chore/test-debt-cleanup into main
463e4aaMerge pull request 'feat(calls): WebRTC voice/video calls and enclave voice channels' (#96) from feat/voice-and-video-calls into main
c7b6da5feat(calls): WebRTC voice/video calls and enclave voice channels
1e13caechore(tests): remove duplicate migrations from db_dm setup_pools
6aa1b0ddocs(claude): document test-drift categories and add curl permission
f1a3bd2test(enclave): fix invite_then_accept_creates_membership contract drift
2a9d4a3chore(tests): fix migration drift and feature-gate drift across test suite
91a2f4fMerge pull request 'fix(tests): make just test pass again' (#94) from fix/just-test-stale-migrations into main
2e24b00fix(tests): make just test pass again
92743a5Merge pull request 'feat(messaging): press Enter anywhere to send a message' (#93) from feat/enter-anywhere-send into main
320e09efeat(messaging): press Enter anywhere to send a message
2228e9bMerge pull request 'feat(messaging): voice messages with record + waveform' (#92) from feat/voice-messages into main
bff8741feat(messaging): voice messages with record + waveform
f671240Merge pull request 'feat/upload-hygiene' (#91) from feat/upload-hygiene into main
b959eeechore(uploads): clippy + cargo fmt fixes for phase 23
c95fb70test(uploads): pipeline, sweep, dedup-GC, admin, preview round-trip
65f9403docs(uploads): admin help text + plan note on preview-only regen
06990bdfeat(uploads): admin regenerate-thumbnails, purge-orphans-now, disk-usage panel
2eef769feat(uploads): hourly orphan sweeper with dedup-aware file delete
c09c3d2feat(uploads): serve ?size=preview from /api/files/:id
a05a24dfeat(uploads): pipeline runs on image uploads (strip + thumbnail)
00bbb81docs(uploads): fix plan typo (GIF original preserves animation)
e516bf9feat(uploads): image pipeline (re-encode strips EXIF, 360px preview)
478d27bfeat(uploads): add image crate + uploads module skeleton
122c09edocs(uploads): add Phase 23 upload hygiene implementation plan
725468fMerge pull request 'fix(enclave): live typeahead for invite member' (#90) from fix/invite-member-search into main
5b6c0c8fix(enclave): enforce visibility/block/ban gate on invite POST
1fb2c3bfix(enclave): replace invite-by-username form with live typeahead
d4b1f91Merge pull request 'feat(messaging): quote-reply with inline chip' (#89) from feat/quote-reply into main
3db7928feat(messaging): rename hover actions Quote/Reply to Reply/Thread
c376369feat(messaging): quote-reply with inline chip above body
56e0fa6Merge pull request 'fix(reconnect): wire WS manual-reconnect helper now that htmx is actually loaded' (#88) from fix/ws-reconnect-after-restart into main
5ada89dfix(reconnect): wire WS manual-reconnect helper now that htmx is actually loaded
dac7329Merge pull request 'fix(mail): send verification + reset emails as multipart/alternative' (#87) from fix/email-spam-multipart into main
4ef2489fix(mail): send verification + reset emails as multipart/alternative
cf37553Merge pull request 'feat/login-alerts' (#86) from feat/login-alerts into main
b55d2a5chore(login-alerts): demote send and suppression logs to debug
f73f15afeat(account): log every login-alert suppression and success
8178e52feat(account): email user on sign-in from a new device
bbb5452Merge pull request 'feat(account-delete): refuse when caller is sole admin' (#85) from feat/account-deletion into main
4531575feat(account-delete): refuse when caller is sole admin
d0bb0afMerge pull request 'feat(account): add self-serve account deletion' (#84) from feat/account-deletion into main
2334446feat(account): add self-serve account deletion
ef5663dMerge pull request 'feat/account-data-export' (#83) from feat/account-data-export into main
14db568fix(account-export): hash session ids instead of exporting raw tokens
5ffe42ffeat(account): add GDPR-style data export
841e6ffMerge pull request 'fix/db-write-contention' (#82) from fix/db-write-contention into main
72be514chore: remove diagnostic instrumentation now that the deadlock is fixed
630f585fix(auth): drop DashMap Ref before re-acquiring shard write lock
d76ab51diag(auth): add outer watchdog and post-lookup tracing in inject_user
279ab19diag(auth): trace every entry, branch, and exit in enforce_2fa
8f14709diag: per-step tracing in get_settings and ws_handler
775b8b7fix(main): bump tokio worker pool to 32 to survive CPU bursts
8f3d8b6fix(ws): wrap message renders with render_template so block_in_place applies
928b73cfix(views): cache markdown render to stop tokio worker pinning under broadcast load
eee6a4bfix(views): render templates with block_in_place to free the tokio worker
7b4fd8ddiag(auth): tighten phase watchdog to 1s and log on completion
d6f5c00diag(auth): use tokio::select! for phase watchdogs (reliable fire on timeout)
868d7dddiag(routes): distinguish stuck requests from cancelled requests
5d8abe2Merge pull request 'chore: remove smtp migration from vapid test setup, add cargo clean permission' (#81) from feat/email-digest into main
73970b1chore: remove smtp migration from vapid test setup, add cargo clean permission
d9ce8fdMerge pull request 'feat/email-digest' (#80) from feat/email-digest into main
654c0a6Merge main into feat/email-digest
0bba1d3diag: log every entry to log_slow_requests and inject_user
24ed994diag(auth): per-phase watchdogs in inject_user
cd83f1cdiag(auth): time session lookup and downstream handler separately
8c4cc85diag(routes): watchdog log fires while a request is still in-flight
11f0de1fix(views): warm syntect at startup to stop tokio-worker starvation
4e53006fix(db): prewarm pool, log slow requests, sample pool stats
f80bc11fix(db): batch high-frequency touches through a single background writer
7def438Merge pull request 'feat/multi-device-sessions' (#79) from feat/multi-device-sessions into main
6d63775fix(auth): drop transaction and add debounce on touch_user_activity
1ca7dfcfix(db): enable WAL + busy_timeout to stop SQLITE_BUSY under write contention
9045f47docs(readme): document email-digest setup, semantics, and upgrade path
8ca8a1ffeat(digest): user-facing email + opt-in UI + admin default-for-new-users toggle
f6af786feat(auth): broaden OS detection in session-list device labels
5ae0aa9test(digest): pin the "new offline session re-fires" half of the gate
d58536bfeat(digest): ship the digest tick - eligibility, dispatch, scheduler, base URL
75f3b3cfeat(auth): per-session device list with revoke in settings
04171b9feat(digest): add content primitives - snippet helper + Askama templates
749495aMerge pull request 'feat(auth): email verification on registration' (#78) from feat/email-verification into main
7955ddffix(admin): clarify the SMTP "not active" banner leads with the restart case
117a00fchore: remove SaaS mode docs from CLAUDE.md and reformat Rust sources
46839b6feat(auth): email verification on registration
5af5c74feat(digest): wire admin SMTP form to typed config + add test-email button
408c7d1feat(digest): add migration and DB helpers for email digest tracking
c28f8fdMerge pull request 'feat(auth): email-based password reset + in-settings password change' (#77) from feat/password-reset into main
d4c84a6feat(digest): track WS-receive activity in users.last_ws_seen_at
06ddf62feat(auth): email-based password reset + in-settings password change
4b283f4docs(plans): add phase 22 email digest plan
2bfeac8Merge pull request 'feat/broadcast-mentions' (#76) from feat/broadcast-mentions into main
9c7047arefactor(mentions): move push concurrency cap to per-send level in dispatch
768f674feat(mentions): show broadcast-count hint in composer as user types @here/@channel
95ea09bfeat(mentions): add broadcast-count probe endpoint for composer preview
49fcdf0feat(mentions): surface @here/@channel in mention autocomplete popover
b85c3a0feat(mentions): cap push fan-out concurrency with a semaphore
270933efeat(mentions): wire broadcast tokens into post/patch_message resolution
5486d42feat(mentions): add @here/@channel resolver helpers and broadcast chip rendering
f1a04a1Merge pull request 'chore(todo): remove TODO.md after tickets created' (#75) from chore/remove-todo into main
642be5fchore(todo): remove TODO.md after tickets created
07c1d42Merge pull request 'feat(messages): per-user saved-messages list' (#74) from feat/saved-messages into main
c7814cafeat(messages): per-user saved-messages list
85fbe2bMerge pull request 'feat(messages): render bodies as markdown with syntax-highlighted code' (#73) from feat/markdown-rendering into main
289d86afeat(messages): render bodies as markdown with syntax-highlighted code
082b0fbMerge pull request 'docs(todo): refresh TODO.md with feature backlog' (#72) from docs/todo-feature-backlog into main
14912cadocs(todo): refresh TODO.md with feature backlog
241a334Merge pull request 'fix(reactions): cancel button collapses entire emoji picker' (#71) from fix/reaction-picker-cancel into main
b2847a7fix(reactions): cancel button collapses entire emoji picker
0adc72bMerge pull request 'feat(emojis): enclave-scoped custom emojis with optional global sharing' (#70) from feat/custom-emojis into main
f1ddb15Merge branch 'main' into feat/custom-emojis
f897b36feat(emojis): enclave-scoped custom emojis with optional global sharing
7de3864Merge pull request 'fix/listener-accumulation' (#69) from fix/listener-accumulation into main
ae5911bchore: allow echo exit-code command in settings and tidy test assertion
8c968ecdocs(CLAUDE.md): document inline script teardown pattern and persistent-shell exception
d2b6afbfix(blocked): tear down document click listener and debounce timer on HTMX cleanup
07aa8b1docs(layout): add comment explaining persistent-shell script lifetime rationale
db0a013docs(layout): clarify persistent-shell script lifetime to explain no teardown needed
3f72269fix(ws): tear down wsOpen listener on room page cleanup to prevent accumulation
ad49914fix(notify): tear down document click listener on HTMX cleanup to prevent accumulation
c28db9efix(composer): tear down htmx:afterSwap body listener on HTMX cleanup
9ca0dacfix(ws): tear down body event listeners on HTMX cleanup to prevent accumulation across soft-refreshes
fc45ea2docs(superpowers): expand phase 20 smoke test and rationale detail
78779e3docs(superpowers): add phase 20 plan for listener accumulation fix
fedc130Merge pull request 'feat(pinned): re-render bubble on pin/unpin so hover menu flips immediately' (#68) from feat/pin-message into main
a1aa74eMerge branch 'main' into feat/pin-message
e83827cfeat(pinned): re-render bubble on pin/unpin so hover menu flips immediately
ccc4c99Merge pull request 'chore: add install-hooks + pre-commit recipes' (#67) from chore/pre-commit-hook into main
6d89711Merge branch 'main' into chore/pre-commit-hook
42f2572Merge pull request 'feat/pin-message' (#66) from feat/pin-message into main
bda082dchore(settings): add allowed commands for check, verify, server-down, and gh auth
53ed844chore(pinned): apply rustfmt and add migration 0016 to test fixtures
a8a5ae4Merge pull request 'Fix: replace nonexistentserverfeature flag in check.yml' (#65) from fix/check-yml-features-flag into main
0a7a3fbfix: replace nonexistentserverfeature flag in check.yml
1fd02b7chore: add install-hooks + pre-commit recipes
f53671ctest(pinned): add route integration tests for pin/unpin feature
293e696feat(pinned): add pin/unpin routes, strip UI, and pins list page
2a81cf6Merge pull request 'chore/rust-builder-1.94' (#64) from chore/rust-builder-1.94 into main
0d8aedfMerge branch 'main' into chore/rust-builder-1.94
e17ff86feat(pinned): add MessagePinned and MessageUnpinned WebSocket events
74b0426feat(pinned): add DB layer for pinned messages
4b986bcMerge pull request 'ci: drop rustup component add now that opensuse-base ships them' (#63) from chore/drop-rust-toolchain-install into main
09cf4bbdocs(pinned): add Phase 19 pinned messages implementation plan
9a2986aci: drop rustup component add now that opensuse-base ships them
c83dca6Merge pull request 'feat(reconnect): visible reconnect indicator with backoff and soft-refresh' (#62) from feat/reconnect-ui into main
cbfee49chore(reconnect): apply rustfmt to routes_reconnect test file
55503a0test(reconnect): cover banner partial rendering and soft-refresh target
8cde6e5feat(reconnect): add WS reconnect/banner state machine
7845ebefeat(reconnect): mount connection-status banner and reserve hx-ext slot
52bf149feat(reconnect): add connection-status banner partial
f7982c7docs(reconnect): add phase 18 plan for connection-lost UI
7857a9bdocs(reconnect): add Phase 18 WebSocket reconnect UI implementation plan
a705252ci: bump runtime stage from bookworm-slim to trixie-slim
5936556ci: build from rust-builder-* (rust 1.94)
a4fc2a6Merge pull request 'chore/sync-from-yotun' (#61) from chore/sync-from-yotun into main
7d37f40Merge from main and resolve conflicts
9cd9ab2chore: Sync .gitignore with other repos
159aabcMerge pull request 'feat/dm-mute' (#60) from feat/dm-mute into main
9fd5fd5chore(settings): allowjust --listin Claude Code permissions
175b4eerefactor(notifications): remove redundant.into()calls on Protocol errors
ab92d1ftest(notifications): add integration tests for POST /dm/{peer_id}/mute route
f5b26aefeat(notifications): add POST /dm/{peer_id}/mute route handler
ba77c71feat(notifications): implement DM mute toggle UI and remove DM-kind bypass
2490c75feat(notifications): expose mute_mode on SidebarPeer for DM sidebar rendering
3c8787bfeat(notifications): add set_dm_mute and enforce DM/non-DM room kind checks
e073f84docs(plans): add phase 17 per-DM mute implementation plan
7614ff4ci: bump actions/checkout to v5
310ba22Merge pull request 'feat/web-push' (#59) from feat/web-push into main
bbbf74bdocs(readme): expand LETS_CHAT_SECRET_KEY documentation and add crates.io/GitHub API fetch permissions
830fd71refactor(push): drop_pem_infix from VAPID keypair columns and clarify LETS_CHAT_SECRET_KEY docs
1831796ci: build from rust-builder base images
5ebac41ci: pin dioxus-cli to 0.7.7 in builders
7679b5bci: cache cargo registry + git via BuildKit cache mounts
da919b0ci: switch OCI cache to registry mode=max
fe41c5aci(check): cache Rust build artifacts via Swatinem/rust-cache
5570e9eci: add Check workflow (fmt + clippy + build + tests)
d5aadd9ci: cap cargo build jobs at nproc/2 per pipeline
f75f9a2chore(deps): bump dioxus to 0.7.7
9e10eddMerge pull request 'feat/web-push' (#58) from feat/web-push into main
400f621test(push): wire new AppState fields into remaining test harnesses
d65aaectest(push): add dispatch and VAPID keypair integration tests
7e8e673test(push): add integration tests for push_subscriptions DB layer
7e50661test(push): apply migration 0009 in all in-memory test pool setups
5cc87fafeat(push): wire service-worker registration into the browser notification flow
800128cfeat(push): add HTTP routes, payload builder, and settings UI for push notifications
a0cf752feat(push): add DB layer, dispatch logic, and production push client
22fe853feat(push): add notify_push_enabled field to user queries and prefs
f07e485feat(push): wire VAPID keypair and push client into AppState
678c628feat(push): add migrations for push subscriptions and VAPID keypair
97ee3cffeat(push): add service worker and notification icon assets
a97c253feat(push): add web-push-native dependency and p256/base64 support
72fda45docs(plans): add Phase 16 web push notifications plan
dc0b8c1Merge pull request 'feat/room-mute' (#57) from feat/room-mute into main
2a79a6dFeature: Per-room mute / notification preferences
ff5d774docs(plans): add Phase 15 per-room mute implementation plan
2c26430Merge pull request 'chore/display-version' (#56) from chore/display-version into main
b9d0b12chore(version): show build metadata in admin nav
dac9f16chore(version): show build metadata on settings page
9428f0achore(version): bake build metadata into all binaries
1395aaeMerge pull request 'feat(build): split standalone vs saas build modes' (#55) from feat/split-build-saas-standalone into main
b221e45feat(build): split standalone vs saas build modes
d78f6c6Merge pull request 'feat(auth): require password confirmation on registration' (#54) from feat/confirm-password into main
d46785dfeat(auth): require password confirmation on registration
35b4c8dMerge pull request 'feat/two-factor-auth' (#53) from feat/two-factor-auth into main
c925c91feat(auth): TOTP two-factor authentication (squashed)
b579003Merge pull request 'feat/mentions-notifications' (#52) from feat/mentions-notifications into main
28219eetest(mentions): add integration tests for mention routes
b74580dtest(mentions): apply migrations 0007 and 0014 to all in-memory test pools
38c6e0dfeat(mentions): add client-side mention notifications and @mention autocomplete
8ff99d1feat(mentions): render @mention chips in messages and push live mention events
c5e9ec6feat(mentions): wire up mention extraction, persistence, and fan-out
65ee8edfeat(db): add mentions table and notification settings migrations
ead085bfeat(assets): add favicon SVGs and notification sound
edb3c6cdocs: add Phase 14 mentions/notifications plan and mark Phase 13 done
a6c7267chore: gitignore local Claude settings and add regex dependency
21fa4daMerge pull request 'fix/search-preview' (#51) from fix/search-preview into main
027c631fix(blocked): drive block popover with plain fetch, not HTMX
2962ed6fix(blocked): send q param to /users/search from block popover
549a7c9feat(blocked): live people-search popover under "Block by username"
ec62695fix(search): render search as sidebar popover instead of full page
c2a7dabMerge pull request 'feat/user-blocking' (#50) from feat/user-blocking into main
4542d1cfix(users): gate username block lookup behind shared-enclave membership
e00cbddfeat(users): block by username so private profiles can be blocked too
0d1220bfix(users): hide blocked users' messages in rooms, threads, search, and ws
559619bfeat(users): block other users to hide them and prevent DMs
f54d18fMerge pull request 'feat/profile-privacy' (#49) from feat/profile-privacy into main
535d382fix(dm): show inline error bubble instead of 404 when peer is private
42847d8feat(users): profile privacy toggle hides users from search and new DMs
785559eMerge pull request 'feat(users): profile search by username and display name' (#48) from feat/profile-search into main
2060c4efeat(users): profile search by username and display name
5c7b980Merge pull request 'fix(layout): wrap static-page sections in a full-width scroll container' (#47) from fix/scroll-wrapper-not-section into main
4d44524Merge pull request 'fix(layout): scroll body content on static pages so long lists are reachable' (#46) from fix/scrollable-static-pages into main
174e8bafix(layout): wrap static-page sections in a full-width scroll container
587a1d9merge
c3a03a9Merge branch 'long-fix'
320c1b8fix(uploads): move file input outside form to prevent HTMX multipart
e03612bfix(layout): scroll body content on static pages so long lists are reachable
947b0bfMerge pull request 'feat(composer): paste, drag/drop, and inline image preview for uploads' (#44) from feat/composer-paste-drop-preview into main
76240d3Merge pull request 'fix(layout): collapse sidebar to a drawer below the md breakpoint' (#43) from fix/mobile-drawer into main
2a160ddMerge pull request 'feat(search): broaden Home search beyond DMs to include accessible rooms' (#42) from fix/search-include-rooms into main
ae3448dMerge pull request 'feat(composer): textarea + send button + retry on failure' (#41) from feat/composer-multiline into main
6a4d548Merge pull request 'feat(routes): render unknown routes inside the app shell as a 404 page' (#40) from fix/404-shell into main
5a65144Merge pull request 'feat(sidebar): active DM/room highlight + resolved enclave member names' (#39) from fix/sidebar-active-and-member-names into main
bee12c9Merge pull request 'fix(status): close picker on save + Esc/click-outside dismiss + counter' (#38) from fix/status-auto-close into main
d98d0d0feat(composer): paste, drag/drop, and inline image preview for uploads
da93cc3fix(layout): collapse sidebar to a drawer below the md breakpoint
24b02bafeat(search): broaden Home search beyond DMs to include accessible rooms
0104acbfeat(composer): textarea + send button + retry on failure
7384e63feat(routes): render unknown routes inside the app shell as a 404 page
3975cb0Merge branch 'feat/uploads'
da14de9feat(sidebar): active DM/room highlight + resolved enclave member names
0dd5e46fix(status): close picker on save + Esc/click-outside dismiss + counter
5812131style(uploads): apply rustfmt to phase 13 sources and tests
b4ea90bfeat(uploads): integration tests for upload, serve, and send-with-attachment
0c9c338Merge pull request 'feat(threads): Slack-style thread panel for rooms and DMs' (#36) from feat/threads into main
206b266feat(previews): SSRF-hardened /api/unfurl + lazy preview cards
3a5dbd0feat(uploads): render attachments inline in message fragment
6ebfa9cfeat(uploads): composer paperclip + staged-attachment chip
ccb94c7feat(uploads): link uploaded files to messages on send
d1111ecfeat(uploads): POST /api/upload + GET /api/files/:id endpoints
bb7efe9feat(uploads): Attachment model + db layer + MessageView wiring
eea89f4feat(threads): Slack-style thread panel for rooms and DMs
a3f6347feat(uploads): chat schema for file_uploads + link_previews
28dfef8feat(deps): add dependencies for file uploads and link previews
7877bcddocs(uploads): add Phase 13 implementation plan for file uploads and link previews
12f6748Merge pull request 'feat(typing): wire client typing frames + clear on send' (#35) from feat/typing-indicator into main
99508d1feat(typing): wire client typing frames + clear on send
5081351Merge pull request 'feat/user-status' (#34) from feat/user-status into main
adfc992feat(status): render custom status text inline + live-update via WS
d740688fix(status): wrap WS status script in OOB swap target so HTMX runs it
a866ea5feat(status): live cross-user status updates over WebSocket
7c2127bfeat(status): derive offline status from hub presence
a9651c7feat(status): user availability (active/idle/dnd) + custom status text
a12eb53Merge pull request 'feat(profiles): editable display name, bio, and avatar' (#33) from feat/profiles into main
644342bfeat(profiles): editable display name, bio, and avatar
7cd16acMerge pull request 'feat/enclaves' (#32) from feat/enclaves into main
3c43be6feat(enclaves): /admin/enclaves shows every enclave on the server
6ce978dfix(enclaves): scope rooms.name uniqueness per enclave
5f12743fix(enclaves): flash banner shows the conflicting name
5c1813ffix(enclaves): flash error uses opaque code, never user-controlled text
9feaed6fix(enclaves): show duplicate-name error as inline banner instead of error page
92a91f7fix(enclaves): clean 400 on duplicate name instead of 500
edbe6aefix(enclaves): Home switcher button bypasses last_visited redirect
12e6c41fix(enclaves): sidebar scopes by current_enclave (DMs in Home, rooms in enclave)
377d7e1feat(enclaves): remove legacy POST /admin/rooms; admin listing read-only
856fa26feat(enclaves): broadcast member/room/invitation events from handlers
e337f8bfeat(enclaves): add ChatEvent variants for membership, rooms, invitations
10e8809chore(enclaves): rebuild Tailwind output + sync test-file fmt
725508efeat(enclaves): updated welcome copy and link to invitations
24f3590feat(enclaves): expanded discover page with three sections
cd6a86ffeat(enclaves): full settings template with role/kick/transfer controls
2ad888dfeat(enclaves): expand enclave landing with inline manage forms
e34de30feat(enclaves): two-column chrome with enclave switcher partial
7f82512feat(enclaves): switcher entries on every page struct
319ea35fix(enclaves): tighten post_message access + DM redirect + idempotent join
5634287feat(enclaves): /search scopes to enclave or DMs
89f3f93feat(enclaves): route guards use is_room_accessible
cbeb3affeat(enclaves): last_visited cookie redirect on /
d29f77efeat(enclaves): per-enclave room CRUD + private-room member management
399e35afeat(enclaves): settings page + edit/transfer/delete/leave/role/kick handlers
68f8d62feat(enclaves): direct invite + accept/decline + /invitations page
c846192feat(enclaves): discovery, visibility toggle, invite-code endpoints
38fc637feat(enclaves): GET /enclave/{id} landing with member-only access
fba7448feat(enclaves): POST /enclaves creates and redirects to landing
f5f824bfeat(enclaves): minimal view models + templates for enclave routes
fa96cc3fix(enclaves): gate backfill on actual promotion + repair created_by sentinel
89bc116feat(enclaves): permission helpers with site-admin godmode
6a50ec3feat(enclaves): list_rooms_in_enclave honors enclave + private-membership rule
b17ff2efeat(enclaves): is_room_accessible covers DM, public, private + site admin godmode
3552908feat(enclaves): create_room takes enclave_id; admin room create uses General
ba9e4cffeat(enclaves): run backfill at startup and after first-user promotion
de6aaa2feat(enclaves): backfill_general_membership reads auth users
58f5375feat(enclaves): metadata, visibility, invite-code, cascade delete
c29b74dfeat(enclaves): invitations CRUD + atomic accept
cc6c7a9feat(enclaves): transfer_ownership (atomic demote+promote)
b55687bfeat(enclaves): add_member, remove_member, update_role
4bce800feat(enclaves): list_enclaves_for_user, list_public_enclaves, list_members
2021484feat(enclaves): get_enclave, get_enclave_by_invite_code, get_membership
a60f10cfeat(enclaves): add db::enclave::create_enclave with owner-membership tx
63aa376feat(enclaves): add Enclave, EnclaveRole, EnclaveMembership, EnclaveInvitation models
2a37fc2feat(enclaves): add chat-DB schema migration
1411df0docs(enclaves): add phase 3 (UI) and phase 4 (realtime + cleanup) plans
e9c4d12docs(enclaves): add phase 2 plan (routes)
62f5e76docs(enclaves): add master plan index and phase 1 (DB foundation)
da38a04docs(enclaves): split migration data step from startup backfill
bc2e8a4docs(enclaves): add design spec
01f8639Merge pull request 'chore(docker): apply app-prefixed container name convention to compose files' (#31) from long-convention-name into main
9b3d732chore(docker): apply app-prefixed container name convention to compose files
fe8859bMerge pull request 'feat/message-grouping' (#30) from feat/message-grouping into main
66cd2b6fix(composer): clear input synchronously on submit so rapid typing isn't lost
d6155c9feat(unread): render an unread-messages divider above the first new message
469842cfeat(scroll): sticky-bottom auto-scroll for rooms and DMs
f68ab93fix(ws): advance last-read watermark when receiving a message in a subscribed room
49182e9fix(grouping): tighten vertical spacing between follow-up messages
01848b5docs(plan): add message-grouping plan; apply rustfmt to tests
6dd66d3feat(grouping): promote next message to header when deleting a grouped header
3b156b9feat(grouping): compute is_follow_up on WS new-message and edit broadcasts
cbf1384feat(grouping): hide header and tighten spacing on follow-up messages
ef562c6feat(grouping): compute is_follow_up on page load and add prior/next helpers
519a6d6feat(grouping): add is_follow_up field to MessageView (defaulted to false)
9400d7efeat(grouping): add MESSAGE_GROUPING_WINDOW_SECONDS const and is_follow_up_of predicate
ba1a956docs(spec): add design for grouping consecutive messages
0461f46Merge pull request 'fix(ws): restore "Seen" caption and live sidebar unread badges' (#29) from fix/read-receipts-and-realtime-notifications into main
d756eb0fix(ws): restore "Seen" caption and live sidebar unread badges
62b8760Merge pull request 'fix(ci): repair Forgejo workflows after the axum rewrite' (#28) from fix/forgejo-workflows into main
f5a83d7fix(ci): repair Forgejo workflows after the axum rewrite
14647b8Merge pull request 'fix(desktop): forward DISPLAY/Wayland and use host network in cargo-desktop' (#27) from fix/desktop-display-forwarding into main
2049214fix(desktop): forward DISPLAY/Wayland and use host network in cargo-desktop
346edd7Merge pull request 'fix/axum-rewrite-gaps' (#26) from fix/axum-rewrite-gaps into main
bf98767feat(admin): port mute, role, delete, room create/edit/invite/regenerate
046e99dfix(ws): live updates for edited messages, new messages, and DM creation
99678c6fix(ui): always show message actions, fix CSS cache busting, clearer DM link
181ca42fix(ui): restore missing features lost in axum rewrite
8f12ba1Merge pull request 'fix(dev): unbreak Docker dev environment' (#25) from fix/dev-docker-env into main
d168460fix(dev): unbreak Docker dev environment
003cc2cMerge pull request 'feat/axum-htmx-rewrite' (#24) from feat/axum-htmx-rewrite into main
864865cchore: drop dx, desktop docker, obsolete plans, update CLAUDE.md
caa7d92feat(desktop): native webview wrapper using tao + wry
ee97633feat(read-receipts): unread badges and mark-as-read on view
90d50b9feat(admin): port admin pages to Askama+HTMX
a912e47docs(plan): update resume notes for tasks 14-17
b830011feat(search): full-text message search via /search?q=...
c79910afeat(routes): direct messages render via /dm/:peer_id
b9b95fefeat(reactions): add and remove reactions with HTMX picker
0741d24feat(routes): edit and delete message endpoints
eb1ea0afeat(routes): send messages via POST /room/:id/messages
b72e7f1fix(ws): use OptionalUser extractor and gate typing on subscribed rooms
5061d23feat(ws): port /ws upgrade and broadcast pre-rendered HTML fragments
08b5d99feat(routes): render room view with message history (read-only)
bd1edb9refactor(models): impl From for User to deduplicate projection
522ddc2feat(views): render rooms list and DM peers in sidebar
512b109fix(auth): render correct form on register failure; transactional admin promote
2f4b5d5feat(auth): wire login, register, and logout routes
2c8375dfeat(auth): add cookie middleware and AuthUser/AdminUser extractors
266e226docs(plan): add resume notes for tasks 4-17
38fa3edrefactor(views): introduce Html wrapper helper; drop dead asset_url
f313ceafeat(views): add Askama base layout, sidebar shell, and welcome page
7111716docs(plan): note Hub-instance unification as pre-step in Task 8
6d4f4a0feat(server): replace Dioxus with empty Axum app
7ec92f6chore: move Cargo.lock to workspace root and update gitignore path
d7ddac1chore: convert to cargo workspace and vendor htmx assets
db74bc1chore(dev): add Docker-based cargo and bun wrappers
e425157docs(plan): implementation plan for Axum + HTMX rewrite
4a483d3docs(spec): add Axum + HTMX rewrite design
417c521Merge pull request 'fix(auth): show "Username taken" instead of generic "Registration failed"' (#23) from fix/register-username-taken-error into main
95dcc1cfix(auth): show "Username taken" instead of generic "Registration failed"
5adc3c6Merge pull request 'fix(reactions): broadcast reaction updates to all room viewers' (#22) from fix/reactions-broadcast-to-peers into main
fcfd3a3fix(reactions): broadcast reaction updates to all room viewers
0ae3d25Merge pull request 'fix/dm-stable-state-on-send' (#21) from fix/dm-stable-state-on-send into main
a6d9d20fix(sidebar): switch reactive futures to use_resource so refetches don't suspend the root
4015774fix(ws): guard signal writes from forget()'d closures to avoid panic
8dc7040fix(dm): stabilize component state across re-renders to stop refresh on send
99fa68fMerge pull request 'feat(chat): allow users to delete their own messages' (#20) from feat/user-delete-own-messages into main
66bb7f1feat(chat): allow users to delete their own messages
36381efAdd LICENSE
ab0f1b3Merge pull request 'long-lc-5' (#19) from long-lc-5 into main
26eba88docs(search): add Phase 11 message search implementation plan
8caf2c1feat(search): add SearchResult model, search_messages server fn, and db tests
e6ca857docs(todo): mark Phase 11 — Message Search as Done
29065b0chore(test): add db_search to test suite
0061708feat(search): add message search UI and FTS5 query backend
f1d32befeat(search): add FTS5 virtual table and sync triggers for message search
4359d67Merge pull request 'long-lc-5' (#18) from long-lc-5 into main
85176ecchore(settings): add cargo build and test permissions to local config
4350627feat(reactions): load room reactions on mount with single bulk query
84640e5docs(todo): mark Phase 10 reactions as done, update migration numbers
d44962bfeat(reactions): add db_reactions integration test to just test recipe
0d184a6feat(reactions): wire ReactionBar into room and DM views with WS sync
634ee58fix(reactions): rename migration to 0007_reactions.sql
2078bb1feat(reactions): wire toggle_reaction server fn and WS events
68f9382feat(reactions): add ReactionBar component and reactions server fn module
9b2f1c7feat(reactions): add toggle_reaction and list_reactions db functions
5dc0444feat(reactions): add message_reactions table and Reaction model
75ce266docs(plan): add phase 10 emoji reactions implementation plan
383cb7dMerge pull request 'feat/auto-scroll' (#17) from feat/auto-scroll into main
b8f2222fix(chat): always sticky-scroll for own messages
2336d70fix(chat): sticky-bottom scroll + guard stale signal in visibilitychange
b2a34defix(chat): use Signal.read() for struct-field access and wrap message group for keying
3a96d37feat(chat): integrate auto-scroll into DM view
3ce27a7feat(chat): integrate auto-scroll into room view
a808741feat(chat): auto-dismiss pill and advance last-seen on manual scroll
8b2020dfeat(chat): implement auto-scroll open + sticky-bottom logic
0c7e2acfeat(chat): add DOM scroll primitives for auto-scroll hook
7442b7dfeat(chat): add localStorage last-seen helpers
71eee96feat(chat): scaffold use_auto_scroll hook
d3ab596docs(auto-scroll): implementation plan for chat auto-scroll
09769b5docs(auto-scroll): spec for chat auto-scroll behavior
2295119Merge pull request 'fix(docker): persist SQLite data across restarts in compose.yml' (#16) from fix/persist-messages into main
40c7ea7fix(docker): persist SQLite data across restarts in compose.yml
c344701Merge pull request 'fix(ui): strip ServerFnError wrapper from all user-facing error messages' (#15) from feat/short-user-errors into main
f13c9ebfix(ui): strip ServerFnError wrapper from all user-facing error messages
aa9676dMerge pull request 'fix(auth): scope blank-input grace window to page mount, not server boot' (#14) from fix/register-grace-per-page into main
d0daf39fix(auth): scope blank-input grace window to page mount, not server boot
b8a5e3bMerge pull request 'fix/websocket-messages' (#13) from fix/websocket-messages into main
2a3c422fix(chat): update message list via WebSocket events instead of refetching
2a92f17Merge pull request 'fix(db): use sqlx migrator so migrations don't re-run on every startup' (#12) from fix/oneshot-cancelled into main
ad299b9fix(db): use sqlx migrator so migrations don't re-run on every startup
0aba125Merge pull request 'feat(auth): blank-input grace window + generic register/login errors' (#11) from fix/register-error-window into main
8ee6218fix(auth): strip ServerFnError wrapper from user-facing messages
d4e5de3docs: spec and plan for register/login blank-input grace window
b4b735ffeat(auth): generic login errors + blank-input grace window
fd348aafeat(auth): generic register errors + blank-input grace window
2fd3a21fix(auth): eagerly initialize server uptime clock at boot
1fa44a4feat(auth): add startup grace window helpers
170f078Merge pull request 'feat/stack-rework' (#10) from feat/stack-rework into main
bfa9f46chore(docker): pass --features client explicitly for desktop build
c9661b4chore(justfile): add check-client, update dev-desktop for client feature
91856f8refactor(main): split server and client entry points
049beb7refactor: gate server-only modules on feature = server
a4f851dchore: rename desktop feature to client and gate server deps
001bc15docs: add server/client build split design
1ea1880Merge pull request 'fix/register-delay' (#9) from fix/register-delay into main
cb9a66fstyle: cargo fmt
f4e2c95chore(auth): remove diagnostic console logs
2d1b701diag(auth): remove hydrated gate, inline form to test hydration path
2fcae65debug(auth): use_future+yield to flip hydrated, with console logging
50b5decfix(auth): use onmounted to trigger post-hydration form render
1cfd09ffix(auth): flip hydrated via use_effect instead of use_hook+spawn
b63461dfeat(auth): render login form only after hydration
6bc08a7feat(auth): render register form only after hydration
4e25c77revert(web): restore SSR router
8facb6drefactor(auth): drop hydration guards from login page
e73c732refactor(auth): drop hydration guards from register page
4d5ae8frefactor(web): serve CSR shell + server fns instead of SSR
4a104badocs(plan): record Dioxus CSR research findings
6a646f3docs(plan): add CSR migration plan for auth hydration bugs
041ce6ffix(auth): apply locked styles unconditionally and guard handlers pre-hydration
e36bad9feat(auth): disable login/register submit until WASM hydration finishes
9d5b073fix(auth): read login/register inputs from DOM to survive SSR hydration race
47c6ecefix(components): remove spawn wrapper from oninput handlers
f99358bMerge pull request 'feat/read-receipts' (#8) from feat/read-receipts into main
9910a4ffix(dm): persist Seen label across refresh
c71d70afix(dm): ignore own DmRead events in peer read tracker
e5792f5fix(dm): notify recipient sidebar of new messages
c74ba95feat(sidebar): add read-receipts toggle in user menu
3bc45aafeat(sidebar): show DM unread count badges
d2c1ec4feat(dm): mark read on visibility and render Seen label
0c481e2feat(server_fns): add set_read_receipts_enabled
32d6d80feat(server_fns): add mark_dm_read, peer read state, and unread counts
7926f98feat(ws): add DmRead event
a982fe1feat(db): add dm read-state upsert and unread counts
632a58afeat(auth): add read_receipts_enabled user column
e421e16feat(migrations): add dm_read_state for read receipts
04f058edocs(plan): add read-receipts implementation plan
ba22f22docs(spec): add read-receipts design and update TODO
280af8aMerge pull request 'feat: Phase 8 — Typing Indicators & Phase 9 — Private Rooms' (#7) from long-branch into main
b514399fix(components): wrap oninput handlers in spawn for login, register, and dm_view
2765685fix(components): wrap signal mutations in spawn for Dioxus 0.7 compatibility
2273293feat(components): fix room navigation reactivity and auto-add creator on room creation
efd86f3chore: mark phase 9 complete and update dev/test config
9dce497feat(server_fns): add join/leave room server fns and fix invite_code migration
da70a9efeat(components): migrate user context to Signal<Option> and replace form submit with explicit handlers
b92ffb7feat(tests): add private rooms test suite and migrate existing tests to new signatures
ae0951efeat(server_fns): register rooms module in mod.rs
bbe7f60feat(components): add room type selector and invite controls to admin rooms UI
18f901ffeat(server_fns): add room type, invite user, and regenerate invite code endpoints
ce8945bfeat(db): add room membership queries and private room visibility
f57eefbfeat(components): add InvitePage component for joining rooms via invite code
a501086feat(routes): wire Invite component to InvitePage
a649a2cfeat(routes): add /invite/:code route for private room invites
14f7b9efeat(migrations): add invite_code column and index for private rooms
fc2be19feat(db): run migration 005 for private rooms on startup
c6b5035feat(server_fns): enforce private room access control on chat endpoints
8ef9eb4feat(models): add invite_code field to Room struct
e3a4aacfeat(ws): add RoomMemberAdded and RoomMemberRemoved chat events
01c016ddocs(plan): add phase 9 private rooms implementation plan
57bcf95docs(readme): rewrite with features, tech stack, and docker quickstart
0f8a9e0Merge pull request 'feat: message editing and typing indicators (Phase 7 & 8)' (#6) from long-branch into main
0d27f83chore(settings): expand allowed bash permissions for git and docker
e295621docs(plan): mark phase 8 heading as Done
04a929ddocs(plan): mark all phase 8 typing indicator tasks complete
551805cfeat(dm): add typing indicator UI to DM view
029b949feat(room): add typing indicator UI to room view
9580a90feat(ws): add send_typing helper to WsHandle
1e59d54feat(ws): add UserTyping events and Typing client control
52cbf33feat(ws): add typing indicator support to Hub
ce5c174docs(plans): add Phase 8 typing indicators implementation plan
95a7420docs(todo): mark Phase 7 Message Editing as done
ef14e83fix(ui): use peek() instead of read() for messages_version counter
f2738a0chore(claude): allow docker run in local permissions
d2bf8f7test(db): add message editing integration tests
4920689test(db): apply message editing migration in DM and moderation test setups
d017fa2feat(ws): add MessageEdited variant to ChatEvent enum
db80f6bfeat(server): implement edit_message server function with auth and WS broadcast
d1b0627feat(ui): add inline message editing to room and DM views
2536a68feat(db): add edited_at column to messages table
e5a2f90docs: add Phase 7 message editing implementation plan
15c6c6edocs: add phased development roadmap for Phases 7–13
2b7aba5init
529cabfMerge pull request 'fix(docker): add Bun and Tailwind CSS build to dev Dockerfile, remove TODO.md' (#5) from feat/css into main
56b2bfafix(docker): add Bun and Tailwind CSS build to dev Dockerfile, remove TODO.md
f760d87Merge pull request 'fix(auth): set session cookie client-side for Dioxus 0.7.5 compat' (#4) from fix/login into main
b929710fix(auth): set session cookie client-side for Dioxus 0.7.5 compat
3476318Merge pull request 'feat/just-dev-web-traefik' (#3) from feat/just-dev-web-traefik into main
fc174adfix: bind dx serve to 0.0.0.0:8080, rename domain to chat.a8n.run, fix HeaderValue parse
4818b73fix: update to dioxus-fullstack 0.7.5 API and fix compilation errors
69f457efeat(dev): add dev-web-down and dev-web-clean just recipes
160e73ffix(docker): mount migrations directory in dev compose files
e8c43c5fix(docker): update dx to 0.7.5 and set platform web in dev Dockerfile
e146f66feat(dev): add Traefik-based dev-web and split local into dev-web-local
0291afcMerge pull request 'feat/admin-users-mods-chat' (#2) from feat/admin-users-mods-chat into main
dd7614fchore: update Cargo.lock
1f493dbfix(ws): add is_dm field to filter sidebar refresh, add 30s ping for stale connection detection
9545be6docs: mark Phase 6 WebSockets complete, update TODO.md and add plan
3447c51fix(ws): handle broadcast lag gracefully, verify DM room membership on subscribe
41ae3bcfeat(ws): refresh sidebar DM list on WebSocket events
c18c27cfeat(ws): wire up WebSocket in auth layout, room view, and DM view
c00bcc2feat(ws): add use_websocket client hook with auto-reconnect
dd9feaefeat(ws): broadcast events from send_message, send_dm_message, and moderation actions
c0585b8feat(ws): register /ws route on Axum router
23896a6feat(ws): add /ws endpoint handler with auth and subscribe/unsubscribe
86de2f0feat(ws): add connection hub with room subscriptions and broadcast
973377ffeat(ws): add ChatEvent enum and ws module structure
80f982dMerge pull request 'feat/admin-users-mods-chat' (#1) from feat/admin-users-mods-chat into main
f8bb49bchore: update .gitignore and remove stale data files from tracking
6bb6728docs: expand TODO.md with project structure, patterns, and agent-friendly guidance
2ad8531docs: add TODO.md with project status and remaining work
884d428docs: add Phase 5 DM implementation plan
72087fbfeat: add DM view, route, sidebar DM section, and username DM links
aeba5a5test: add DM integration tests
da80872feat: add DM server functions (get_or_create_dm, list_my_dms, send_dm_message)
a854bf1feat: add DM migration, room_type field, and DM DB functions
6956643docs: add Phase 2 and Phase 4 implementation plans
7f352ecfeat: add message delete button and mute banner in room view
9070d89feat: add moderation actions UI on admin users page
f257ba4feat: add Mod Log page, moderator access to admin panel
2ba161ftest: add moderation DB tests (ban, mute, suspend, soft-delete, audit log)
85f29d1feat: add moderation server functions (ban, mute, suspend, kick, delete_message)
f7e646afeat: add moderation migration, models, and DB functions
1eb65b2feat: add admin rooms page with create, edit, and delete
0f891cbfeat: add admin invite codes page with generation and revocation
b1246dafeat: add admin users page with role management and deletion
c68631bfeat: add admin settings page with grouped form cards
59e667bfeat: add admin layout with tabbed navigation and nested routes
ea216f3test: add settings and invite code DB tests
d84268ffeat: add admin server functions for Phase 3 admin panel
10e7fb9feat: add room management DB functions for admin panel
c52c3dffeat: add admin user management and invite code DB functions
d88d8d9feat: add settings database, pool, and SiteSettings model
d495d41test: add RBAC role hierarchy tests
b2e971cfeat: admin link in sidebar, visible only to admin users
472762arefactor: use require_auth helper in chat server functions
d5a614bfeat: add require_auth and require_role server-side helpers
b9a9bd3feat: sidebar user info, chat uses authenticated user identity
48cc30afeat: auth server functions, login/register pages, AuthLayout, route protection
69a643efeat: auth DB layer with user CRUD, sessions, and tests
b9c00a0db: add auth pool initialization alongside chat pool
d64dc4fmodels: add User, UserRecord, and Session structs
15f66c1db: add auth migration for users, sessions, invite_codes
85a4b3ddeps: add argon2, rand, axum-extra, time for auth
9d121f6docs: add Phase 1 (Auth) implementation plan
16a111edocs: add Let's Chat application design spec and FUTURE.md
ff64fecfeat: Initial applicationDownloads
-
Source code (ZIP)
0 downloads
-
Source code (TAR.GZ)
0 downloads
-
Source code (ZIP)