The "Share a saved image" panel was wired to the automated exchange
engine, so an operator could only share an image right after an inbound
image request, limited to assets the auto-exchanger would itself pick.
Add a manual path that offers any enabled, unused library image at any
point (no request detection, tier, seller, or boundary gating) and sends
it with no reciprocal "your turn" text. Safety flags now surface as a
non-blocking warning instead of disabling the panel. The automated
auto-send path keeps all its guardrails; the shared image-delivery step
is extracted into a helper used by both paths.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Shared foundation:
- New Modal component on native <dialog>.showModal() (focus trap, inert
background, Escape, focus restore, scroll lock); all eight dialogs and
both globalThis.confirm calls migrated to it
- Design tokens for success/warning/danger surfaces; pill danger variant;
.sr-only utility; toast layering above dialog backdrops; not-allowed
cursor for validity-disabled buttons
Conversations/attention: auto-scroll with jump-to-latest, per-conversation
draft persistence, suggestion undo, 30s auto-refresh with refresh controls,
unread emphasis and counts, blur-consistent share dialog, empty-accounts
guidance, collapsed user lookup, relative timestamps, danger pills for
critical items
Media/library/outreach: click-blurred-to-reveal, lightbox with arrow
navigation and captions, dirty-form preservation across refetches, upload
validation with thumbnail preview, save feedback, result counts with
load-more and clear-filters, ticking countdowns from a single clock
Overview/performance/operations/settings: mutation errors inside the
confirm dialog, live sending-window countdown, offline-aware loading
states, per-panel loading/error with retry, 7/30/90-day range toggle,
console scroll yielding with shown/retained counts, risky-save matching
by subreddit name instead of index, useBlocker unsaved-changes guard,
single-pass validation with focus-to-first-error, access panel JSON
validation and input reset
Tests: 806 -> 844 passing; both typechecks clean.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Expired Matrix bearers no longer pause an account until a new extension
dump is uploaded. BrowserMatrixTokenRefresher loads chat.reddit.com in
the account's persistent browser profile (whose Reddit cookies stay
valid), lifts the fresh bearer off the first authenticated Matrix
request, verifies it via whoami, swaps it into the live MatrixClient
and persists it to the account row.
Wired into the per-account runtime at boot verification, the auth-gate
authenticator, and ChatService's 401 retry path. A dump is now only
needed when the Reddit cookies themselves no longer authenticate.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>