Chrome keeps treating an input that was ever type=password as a password
field, so after tapping the eye the selection menu still hid Copy. Key
fields are now plain text inputs masked with -webkit-text-security, and
the eye toggles the mask instead of the type.
Also fixes the eye icon never switching: lucide swaps <i> for <svg>, so
querySelector('i') was null and the handler threw.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The provider is Anthropic; Claude is its model family. Models now take
the ant: prefix (e.g. ant:claude-opus-5-5), the provider value sent to
the proxy is "anthropic", and the key lives in anthropic_api_key /
USER.apiKeyAnthropic. No fallback for the old names.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Every page load fetched whatever these resolved to, so a bad or
compromised release would ship to all users with access to their keys.
Each pin serves byte-identical content to what the unpinned URL served.
- lucide@latest -> lucide@1.60.0
- cdn.tailwindcss.com -> 3.4.17
- cash-dom -> 8.1.5
- alpinejs -> 3.17.5
- markdown-it-mathjax3 (esm.sh) -> 5.2.0
- medv.io/codejar -> codejar@4.3.0 on jsDelivr (same file)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Thread Sync now shows Upload to GitHub / Download from GitHub in a popover,
like sunes sync, so it can be dismissed instead of forcing a choice. It
closes on an outside click, resize, the sidebar overlay, or picking an
option. The push and pull code is unchanged, and the readme's sync steps
now name the popover options.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Assistant messages now carry ts, a plain ms timestamp, instead of the time
riding at the start of the id. Reply ids, which double as the proxy's run
id, are just 128 random bits as unpadded base64url (22 chars). SECURITY.md
now says ntfy pings carry a short hash of the run id.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Reply ids, which double as the proxy's run id, are now the same base36 ms
timestamp followed by a dash and 128 random bits from crypto.getRandomValues,
so a run can't be found by guessing. Saved replies keep their fields and the
timestamp prefix. The id is sent inside begin, resume and stop instead of the
URL, and SECURITY.md now says ntfy pings carry only the timestamp half.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Each reply owns its socket and keeps streaming and saving into its own
thread when you switch threads or sunes, so other threads aren't blocked.
Drops reconnect with backoff and resume from the last chunk; a socket that
stays open but goes silent is caught by a ping when the app returns to the
foreground (and every 20s while visible). Streaming messages carry
stream:{seq}, and replies in flight are listed in localStorage so a reload
picks them up even before their thread is opened. This replaces the 1.5s
HTTP polling, the threads_cache store and the DOM-based last-message lookup.
Stop now always reaches the proxy: after a reload, after switching apps and
while the socket is still connecting. Deleting a streaming message or its
thread stops the run. Also fixes:
- the send lock is taken before any await, so a double tap can't send twice
- a tap on the button right after it flips from Stop to Send is ignored
- Stop no longer swallows the next manual empty-composer send
- a thread opened while another was still loading can't take its messages
- deleting a local thread now removes it from the list
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Both are converted to WebP in the browser like other non-WebP images, so
providers never see them. Browsers that can't decode JXL now get a readable
error instead of [object Event].
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Oversized WebPs are now scaled to a 2048px longest edge at 0.94 quality
instead of being sent at full size.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Videos are compressed with Mediabunny to 360p at 4 fps (HEVC when the
device can encode it, H.264 otherwise) with mono 32 kbps AAC, then
stored as video_url data URLs. Frames are resized after the frame-rate
drop, and rotation is baked in during that same step, so phone videos
stay on the fast path.
The attach badge shows compression progress, sending waits for pending
compressions, and "Clear all attachments" cancels them. Messages show
video thumbnails that open a fullscreen player.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Clicking the attach button or pasting files now appends instead of
resetting. Long-press (touch) or right-click opens a popover with
"Clear all attachments".
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Bubblewrap TWA config for chat.sune, plus a manually dispatched workflow
that builds, signs, verifies against assetlinks.json, attests provenance
and publishes the release for the tag given as input.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Keep the legacy com.planetrenox.sune entry so the old app stays
fullscreen, and add the new chat.sune package with its new key.
Ignore keystore files so signing keys can never be committed.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>