1.0.1 is the first desktop build that works on Linux at all. It also carries
the desktop.callsNotHere string these dictionaries now define for it — calls
are not available on the Linux desktop yet and the app says so rather than
failing.
src/app.jsx carries its own SB_DESKTOP_VERSION for the compact download
table; src/components/ui/DownloadApps.jsx carries DESKTOP_VERSION for the
grid. Bumping one leaves the other pointing at a tag whose filenames no
longer exist — the failure tests/desktop-download-links.test.mjs was written
for, and which it caught here.
The i18n scan also learns that these dictionaries feed two clients. The
desktop client is a separate repository, so its keys can never appear in a
scan of this src/ and were being reported as dead strings to delete.
Group calls are a new capability, and 6.6.6 only landed as a patch because the
version was bumped once per deploy while the feature was being tested. The
number is the release's, not the deploy's.
No code changes: version, badge, changelog heading, docs and build stamp.
Claude-Session: https://claude.ai/code/session_01XSxAkET3hQTkYDQfbjCQwZ
A group call is N-1 ordinary 1:1 calls, one to each other member, each riding
the pairwise session that member already has — a transport a human already
authenticated by comparing the safety code. No mixer, no SFU, no point at which
two people's media meets anywhere but on a device.
Call control is separate from call media, because the two reach different sets
of people. Who opened a call, who joined and who left travels as group frames
signed with the sender's group identity key, so it reaches members currently
reachable only through a relay — and a relaying member can drop one but cannot
write one. Media flows only where a direct link exists, so a member without one
shows as connecting rather than being omitted. Frames carry a per-sender
sequence checked before the action, so a captured leave cannot end a later call,
and simultaneous calls converge on the lower random call id.
One capture is shared across every leg rather than one getUserMedia per member,
and legs answer without prompting: the flag permitting that is set only locally,
only while this user is in the call, and cleared when they leave.
UI: a gallery that sizes itself from the space it has, a spotlight view, an
active-speaker indicator read from the waveform, and the call surface in the
same visual language as the 1:1 one.
Also in this commit, the v6.5.0 language-suggestion work that had not been
pushed yet; its notes are in the changelog. And two fixes: the safety-code input
asks for digits rather than text, and starting a new chat from inside a group no
longer creates it behind the group where it cannot be seen — which had made it
impossible to connect to anyone new, or to add anyone to a group, while a group
was open.
Claude-Session: https://claude.ai/code/session_01XSxAkET3hQTkYDQfbjCQwZ
Four right-to-left languages at /ar/, /he/, /fa/ and /ur/ — thirteen in all.
The layout no longer has a left and a right, it has a start and an end: the
margins, insets and corners are CSS logical properties now, so they follow
dir on <html>. Directional glyphs flip; keys, safety codes and session
descriptors are pinned left-to-right so bidi cannot reorder what two people
compare against each other's screens.
Also fixed: the Service Worker was registered as './sw.js', which 404s from
every locale subdirectory, so twelve of the thirteen pages had no worker at
all. And the bundler ran before the dictionaries were generated, so a newly
added language could reach the page ahead of the app that renders it.
The site now speaks German, French, Spanish, Ukrainian, Russian, Chinese,
Korean and Hindi alongside English — 623 strings per language, 5,607
translations, covering the landing page, the key exchange, the chat, group
calls and every error along the way.
Each locale is a real page at a real URL (/de/, /fr/, …), generated at build
time from locales/*.json. That is the whole point: the app is client-rendered,
so a language that only swaps strings at runtime has no address for a crawler
to index and no link anyone can share. Each page carries its own canonical, a
reciprocal hreflang cluster and translated schema.org.
The URL decides the language, always. A stored preference only applies where
the address does not say, and nothing ever redirects on Accept-Language —
that is how sites become invisible to search engines outside one country.
robots.txt and sitemap.xml did not exist before; both are generated now.
Bugs found on the way, each with a test that would have caught it:
- partner logos used page-relative paths and 404'd from any /xx/ page
- post-build stamped ?v= only into the root shell, leaving locales behind
- "Back online" appeared on every page load, not just after being offline
- update timestamps were hard-coded to US format for every reader
- t() threw on a partial window, taking whole components down with it