The ChatGPT, Grok, Gemini and Phind rows in the sidebar AI picker now
pull each site's own favicon through the same fetch-and-cache path
custom engines already use. The old placeholder color-letter tiles I
shipped in 0.3.106 are removed; the engine's sym emoji is the pre-fetch
fallback until the real favicon lands (cached per profile after that).
Change: fall back from bundledIcon(id) to customFavicon(https://<fav>/)
for built-in engines when no bundled file exists. Perplexity keeps its
existing bundled perplexity.png.
Three home-page tweaks:
- Removed the YOUR LINKS and SILENT MODE section headings; the two
panels now stand on their own without labels.
- The + Add card cell now matches the real cards' size and shape so
it reads as a peer of the grid rather than a short dashed strip.
- Empty slot cells in the left grid are invisible by default and
only reveal their dashed outline when you hover the strip or drag
a link over them. The + add-link cell stays visible as the
discoverable entry.
AI engine picker:
- The chevron badge on the AI button is now a plain span with the
button role, not a nested <button> inside the main AI button.
Chromium flattened the invalid nesting so the chevron's own click
handler never fired; the picker now opens from the chevron and
from keyboard Enter / Space as well as right-click.
Performance (Settings > Performance > Startup):
- Pithos ships with activation: on-demand; its control server for
s3d no longer boots at launch. Wakes on first panel open or a
pithos.sia navigation.
- Hermes relay auto-restore (1.5 s after launch) is now gated by a
new setting hermesAutoRestore (default on). Turn it off to skip
background Nostr relay connections for users who don't live in
Hermes.
- New setting pithosAtLaunch (default off) mirrors the existing
walletAtLaunch so users who do want Pithos ready at launch can
opt back in.
- The Lightest preset now also turns off pithosAtLaunch and
hermesAutoRestore.
First click of the toolbar's address bar or the home page's search field
now selects the current text so the next keystroke replaces it — the
long-standing Chrome / Firefox behaviour the two inputs were missing.
A second click (while already focused) falls through to native cursor
placement, so inline editing still works.
Silent Mode cards switch from a vertical icon-above-title-above-sub
layout to a horizontal one: a left stack holds the icon and the title,
the description sits on the right with left-aligned text and up to
three lines. Backgrounds move from the solid --card tone to a 55%
rgba with a 10 px backdrop blur so the wallpaper reads through.
Home tagline updated: 'Names that live on the Bitcoin Cash chain'
becomes 'Names that live on decentralized blockchain'. The address-bar
tip now points at hello.bch by name so the first step is obvious.
Right-click on a tab now shows a Save page as submenu with PDF and
Image (PNG) items. PDF uses webContents.printToPDF (A4, prefers CSS
page size, prints backgrounds); PNG uses webContents.capturePage of
the visible viewport. Both open a save dialog with a filename derived
from the tab title or hostname, write to the chosen path, and register
the result in the downloads list.
The Claude connector's design doc now ships at
theseus.x/dev/claude-connector/DESIGN-claude-connector.md so readers
on the site do not have to leave for the forge; the Developers page
links the local copy first and the forge mirror alongside it.
Hero mark now sits in front of the "Theseus Navigator" wordmark inside a
translucent rounded panel, so the identity reads on any wallpaper. The
tag line and the hint got their own matching pill backings for the same
reason.
Left-column slots grew from a fixed 3-column grid in a 240–280 px panel
to an auto-fill grid in a 360–440 px panel — about 5 columns of 72 px
tiles instead of 3, so more quick-launch icons fit without the panel
feeling cramped. No change to the icons themselves.
Home page splits into two self-contained panels so the left-column
links no longer scale with the Silent Mode cards. The slot grid is
narrower, the icons default closer to Windows desktop-shortcut size,
and each section carries its own subtle panel background and heading.
Claude connector hardening (the opt-in MCP add-on from 0.3.106):
- Pin the approved origin to the TabDriver on every Controller.use()
and re-check the tab's current URL before each CDP read / input
(isolated, snapshot, screenshot, clickAt, insertText, press,
setFiles, evaluate). A meta-refresh or soft-nav to an unapproved
origin between approval and the call now throws instead of leaking
content or steering input to the new site.
- Rotate the bearer token on every stop() so toggling the connector
off (toolbar chip, panel switch, deactivate) invalidates existing
credentials. Re-enabling issues a fresh token; the panel's install
strings update on the next start. Matches the mental model where
"off" means "the keys change" instead of "the server stops".
- click without a ref now resolves the element at (x, y) through
DOM.getNodeForLocation and refuses if it's a password / one-time-
code field. Previously only ref-based click ran isSecretField; raw
coordinates let focus land on a password field before FOCUS_GUARD
kicked in to block typing.
Right-click or chevron-click on the sidebar strip's AI button now opens
a borderless overlay instead of a plain native menu: enabled engines
are listed with their bundled icons, the current engine is highlighted
with the acid accent + check, and a settings row at the bottom jumps
to Search settings. Clicking an engine selects it as the default and
opens it in the left panel in one click.
Bundled engine icons gained an svg-first fallback: engine-icons/<id>.svg
is picked up before <id>.png so plain color-coded letter tiles ship
alongside the existing bitmap favicons. Added tiles for ChatGPT, Grok,
Gemini and Phind — each a simple initial-on-color mark.
Left column slot grid grows to a visible 3-column fixed cell layout.
Each link can be pinned to a specific slot by dropping onto an empty
cell; unpinned links flow top-to-bottom through the remaining cells.
Dropping an item onto another slot swaps the two positions, so the
grid never collapses underneath the user.
The Ariadne.X home card now uses the brand kit's "ivory on dark"
mark (variant-ivory-glow) instead of the terracotta pottery sketch.
The ivory bust reads cleanly against the navy card surface — the
pottery version was designed for cream backgrounds and got lost
against the dark card.
A wiz:// link that opens a new window with rel="noreferrer" (Potidaea's "Open in wallet", and many other dapps) was dropped before it reached the wallet; a click on one in the page now opens Aegis's pairing approval. Links inside iframes are still refused.
Right-click on a sidebar panel (WhatsApp, Telegram, LLMs, add-on panels
like Hermes) now opens a native menu with Copy image / Save image as /
Open link in new tab / Copy / Back / Forward / Reload. Previously the
sidebar views had no context-menu listener attached, so sites like
WhatsApp Web that intercept right-click left the user with no way to
copy an image.
Hermes mark in the sidebar strip now zooms to the V-fold and wings;
envelope body partially visible. The original viewBox had ~43% empty
space top-and-bottom, so the glyph rendered at ~15 px inside the 26 px
icon frame.
The slot grid on the left of the home page switches from `repeat(3, 1fr)`
to `repeat(3, 100px)` with `justify-content: start`. Cells no longer
stretch to fill the column, so icons sit in a tight desktop-style grid
anchored to the left edge instead of drifting inside wide 1fr cells.
The 900px breakpoint keeps 100px cells and left-anchors them too.
Also carries the Hermes brand kit updates that landed on master between
0.3.101 and now — the Hermes.X Silent Mode card now renders the new
blue envelope mark from home-brand/hermes-mark.svg instead of the old
inline red envelope. The sidebar strip icon size for Hermes was bumped
to 26px in the same cycle to balance the new mark's negative space.
Three more LLM engines land in the catalog and in DEFAULT_ENABLED, so the
sparkle button's picker lists five AI engines out of the box: Perplexity,
Phind, ChatGPT, Grok, Gemini. The first two answer a URL query without any
login, the latter three need a free-tier account; all three accept the
chat URL as the "open the home" target, which is what the sidebar button
needs. A one-time offer migration adds them to any existing profile's
enabledEngines (users who disable one keep it off across restarts via a
new `enginesOffered` field).
Sidebar strip polish. The gear button now opens Settings › Sidebar on a
single click instead of popping a one-item native menu first. The "+"
add button under the gear is removed — adding a web app goes through
Settings › Sidebar anyway, which the gear opens. The quicklinks-add IPC
is kept but repointed to Settings › Sidebar (it used to open General,
which was the wrong page for the add-a-web-app flow).
0.3.99 installed users hit "Cannot find package 'nostr-tools' imported from
resources/lib/hermes.mjs" the first time they tried the Create account /
Open existing account button on the Hermes panel. The module was extracted
to resources/lib/ via extraResources (so the same .mjs/.js pattern as the
other lib files), but every other extracted .mjs happens to only pull
node:* builtins — hermes.mjs is the first one that needs real npm deps.
Node's resolver walks up from resources/lib/hermes.mjs looking for a
node_modules sibling and finds nothing: node_modules lives inside app.asar,
unreachable from an extracted file.
Fix: extraResources the nostr-tools dir + its three dep namespaces + the
one WASM dep so the walk finds them.
The gear popover at the bottom of the left strip is reduced to a single
"Open sidebar settings" item; the overlay/push radio and "Reset panel
widths" controls move to Settings › Sidebar permanently, so there's one
source of truth for the sidebar's own options.
A new sparkle button is added below the icon stack: it opens the user's
default AI engine (any search engine with kind=llm — Perplexity ships
on by default now; Phind is in the catalog). Click opens the engine in
the left panel like the existing web-app quick-links; right-click (or
the small chevron in the button's corner) pops a native menu of every
enabled LLM, each one-click to switch default + open. The button hides
itself when no LLM engine is enabled.
Hermes consolidation. The hermes.x web quick-link added in 0.3.99 is
retracted — the bundled Hermes extension already registers a left-strip
panel (side: "left"), so the web link was duplicating it. Any profile
that caught 0.3.99 gets the stray entry yanked on first load.
Ctrl+Shift+E now opens the Hermes panel in the active window's left
sidebar instead of the standalone Messages BrowserWindow; the window
is still reachable via the ⧉ pop-out button in the panel header for
users who want a free-floating client. The home-page Silent Mode card
for Hermes.X comes back (it's a link to the web page, not a shortcut
to the panel — different purpose).
Two more resolvers under Settings › Names & Certificates. SNS — .sol names
resolve through Bonfida's public SDK proxy, preferring an explicit URL
record over an IPFS record (served via a configurable IPFS gateway).
Unstoppable Domains — the full UD TLD roster (.crypto, .nft, .wallet,
.bitcoin, .blockchain, .dao, …) through resolve.unstoppabledomains.com;
browser.redirect_url takes precedence over an ipfs record. .x stays with
BNS — the UD adapter explicitly skips it so a Sirius registration can
never be shadowed by an Unstoppable one.
Both proxies are Cloudflare-fronted; users on blocked IPs can swap the
endpoint in Advanced. The handshake adapter's skip-list grows to cover
.sol and every UD TLD so a user with HNS + UD + SNS all enabled gets the
specific adapter, never the generic hns.to gateway, for those names.
Hermes.X moves from the home page's Silent Mode card grid to the Theseus
left-sidebar quick-link strip, slotting in right after Proton Mail. The
default list grows to 6 entries; existing profiles pick it up through the
LATER_DEFAULTS one-time offer (same mechanism Proton used in 0.3.88).
Users who still have Hermes on their custom home page can remove it manually.
Two more adapters under Settings › Names & Certificates:
Namecoin — .bit names resolve by calling name_show "d/<name>" on the
configured JSON-RPC endpoint and following `translate` or `alias` records
to a clearnet host. Pure IP records aren't followed yet (that needs
in-browser DNS override + TLS pinning, which comes later). Namecoin has
no free public RPC, so the toggle is off by default and the row carries a
"Needs an RPC URL" note instead of a "Not wired yet" one; set yours in
Advanced.
Handshake — non-ICANN hostnames resolve through the public hns.to web
gateway (user-overridable in Advanced). hns.to proxies the request to a
Handshake node and serves the on-chain content. A bundled list of common
ICANN TLDs (original gTLDs + popular new gTLDs + every ccTLD) keeps the
default collision policy ("icann-wins") from hijacking clearnet names.
Setting the policy to "hns-wins" removes that gate.
Both adapters follow the ENS adapter's shape — tryExtraResolvers in main.js
calls each in turn after the BNS lookup; the first one that returns a URL
loads it. Settings copy on both rows updated.
First real resolver behind the Names & Certificates toggles. When the ENS
switch is on, typing a .eth name in the address bar runs:
1. namehash(name) (EIP-137 keccak256 recursion)
2. eth_call resolver(bytes32) on the ENS registry
3. eth_call contenthash(bytes32) on the returned resolver address
4. decode EIP-1577 (varint protocol + CID) → ipfs|ipns|swarm
5. navigate to <gateway>/ipfs/<cid> (or /ipns/<cid>)
The adapter lives in lib/resolvers/ens.cjs; main.js's navigateTab calls it
through tryExtraResolvers after the BNS check and before the clearnet
fallback. Defaults: publicnode's free Ethereum RPC (Cloudflare's eth-RPC
returns "Internal error" for ENS calls in testing) and ipfs.io as the
gateway (Cloudflare retired their IPFS gateway in 2024). Both are
user-overridable in Settings › Names & Certificates › Advanced.
CIDv0 (Qm… base58) and CIDv1 (bafy… base32) both encode; swarm names
cache a "not yet supported" negative result for one minute until we add a
swarm gateway option. Positive answers cache for 10 min, negatives for 1 min.
The left-column icons return to a fixed 3-column grid, each icon in its own
cell. Drag reorders which cell holds which icon, with before/after indicators
matching the right-side cards. Drops out of x,y positioning: no more free-
floating icons sticking against the card grid; defaults flow left-to-right
across the three cells. The "+" add button sits in the next free cell at
the end of the slot grid.
Homepage max-width widens to 1680px (from 1400) so on wide screens the left
column doesn't crowd the cards. Legacy x,y values on stored icons are
ignored by the renderer (array order is what shows).
New top-level settings page lets the user pre-configure which non-BNS name
systems Theseus will resolve (ENS, Namecoin, Handshake, SNS, Unstoppable)
and which extra TLS roots it will trust (Russian National CA, scoped by TLD).
BNS is always on; everything else is off by default. Each resolver row has
its own Advanced disclosure for RPC URL, gateway, endpoint and collision
policy. The Russian CA row's Advanced holds the comma-separated TLD scope
list that limits what the CA can sign for (default .ru/.рф/.gov.ru/.online.ru).
State persists to %APPDATA%\Theseus\extra-resolvers.json via settings-only
IPC (extra-resolvers-get / extra-resolvers-set / extra-resolvers-reset,
origin-gated to the settings page). The adapters and setCertificateVerifyProc
hook that read this file land in 0.3.96 (ENS) → 0.3.99 (Russian CA); each
row's "Not wired yet — coming in 0.3.9X" caption goes away as its adapter
ships. No home.html change in this release.
The left column goes back to free positioning: each icon stores its own
x,y and snaps to a 20px grid; a faint grid shows underneath while dragging
so placement feels OS-desktop. Live-move via pointer events (clicks still
navigate thanks to a 4px move threshold). Dropping a left icon over the
right card grid re-parents it as a card; dropping a card onto the left
area turns it into a free-positioned icon.
Silent Mode cards get their one-line description back under the title.
Add/edit modal gains a Description field. Defaults seed sub-text on every
Silent Mode card and x,y on every Your-links icon.
The left column grows from a single narrow stack to a 3-wide grid of slots
so added icons flow sideways instead of pushing the page tall. The "+" add
button sits in the next free cell of that same grid. Drag-reorder on the
left column switches from above/below to before/after indicators to match
the right-side cards; both sections are 2D grids now.
Pulls the Theseus Navigator hero (compass + title + search + .bch tip) back
to the top so identity + search stay the first thing on the page. Underneath,
the two-column desktop keeps the shape from 0.3.91 but drops the second
search bar: a narrow left column of stackable slot tiles (hello.bch,
sia.coin, Pithos.sia, Bergamot.X, + add) and a 3-column grid of nine Silent
Mode cards on the right. Right-click opens context menus — background edits
(change bg, icon size, add link/card, reset) on empty space, and copy image
/ copy link / open / edit / remove on any icon or card. Copy image renders
the brand mark to a 256px PNG and writes it with navigator.clipboard.write.
Slot order is HTML5 drag-and-drop between either column; schema is v5 and
passes through migrateCards unchanged.
Three changes to the desktop home that landed in 0.3.90:
- Hero header is back. The compass mark, Theseus Navigator title, tagline
and search sit centered at the top of the page, same shape as the home
before the desktop redesign. The Edit button moves to the top-right
corner so the hero reads as identity, not chrome.
- Silent Mode on the right is CARDS again, not just tiles. Each card
carries the brand icon on the left, title + one-line description
stacked, and a muted acid-colored badge on the right (Navigator /
Registrar / Code host / ...). Cards sit in a center-right column that
stops before the right edge, giving the left column breathing room.
- Your-links on the left is free-drag, OS-desktop style. Each icon
stores x,y and snaps to a 20px grid; dragging an icon moves it live
while the grid faintly shows underneath. The schema gains x,y on
Your-links items — unchanged for Silent Mode cards. Legacy icons
without x,y auto-layout in a tidy 2-column grid near the top.
Compass mark replaces the chain emoji in the hero. The on-disk schema
nudges to v4; v3 and v1 reads still migrate (missing x,y get an
auto-layout fallback at render time).
The new-tab page is now a two-column desktop. The right column holds the
curated Silent Mode X-family (Theseus.X, SilentMode.X, Sirius.X,
Hephaestus.X, Prometheus.X, Hermes.X, Helios.X, Ariadne.X, Aegis.X) with
real brand marks pulled from each product's own favicon or add-on manifest.
The left column is yours — hello.bch, sia.coin, Pithos.sia, Bergamot.X by
default, plus whatever you add. Icons pick up and move within and across
columns in edit mode.
Edit mode also carries per-column default-size pickers (S / M / L / XL),
six background presets + a custom colour + an image upload, and + slots
in each column. The Ariadne.X mark uses the real face/thread illustration
in ancient-Greek-pottery colours (terracotta rings on cream). The Aegis.X
tile matches the one the add-on itself ships.
The on-disk format moves from a bare array of cards (v1) to a v3 object:
{ version:3, iconSize, quickSize, background, sections:{ sm, q } }
On first read, a v1 array lands as sections.q and the Silent Mode column
stays at the code default. The remote home-cards.json URL is still
accepted as either shape; migrateCards() normalises before use.
The web app rows in Settings showed a letter where the strip shows the
app's icon. The icons now live in strip-icons.js, shared by both. Typing
the start of a well-known app's name or address in the add row shows the
rest in grey, the address field offers that app's address, and the right
arrow takes it.
An open sidebar panel (a web app or an extension panel) now has a bar on
top with its name, Maximize/Restore (it covers the page, up to the right
sidebar) and Close. How panels sit next to the page is a choice, in the
new gear above + on the strip and in Settings > Sidebar: over the page,
where it floats on the left of a page that keeps its width and a click in
the page closes it; or pushing the page aside, where it stays open until
closed. That choice replaces the pin, which only existed to keep a panel
open on a page click.
Also: a window laid out while minimized reads a zero-size area, so every
view was left at 0x0 and the window came back blank until resized.
Layout now skips a minimized window and runs again on restore.
Any site could call navigator.setAppBadge(n) and Electron drew n over the
app's taskbar icon. Every site wrote the same single number, so the icon
showed a count with no way to tell whose it was. A session-wide preload now
removes the Badging API in pages and service workers, so sites fall back to
their own title or favicon counters.
Logins typed in a quick link (X, Telegram, WhatsApp, …) are offered for saving, saved ones are offered and filled there, and sites that accept Theseus ID can use it from the sidebar.
- The password manager offers to save, and fills, logins in sign-in forms
embedded in iframes (payment providers, single sign-on widgets), keyed to
the frame's own site.
- PIN pads: Unlock (or Enter) beside Cancel instead of submitting on the
last digit; a new PIN is any 6 to 8 digits with Next; larger keys; calmer
hover so the pad no longer seems to flash as you type.
0.3.80 shipped with the Settings left menu squeezed into a short centred
box (a .app class clash from the Apps list, fixed in 882b6fb). This is
0.3.80 plus that fix.
- Theseus ID: window.theseusId.signIn lets Silent Mode projects (and sites
whose own origin list allows it) sign the user in with an ID derived from
the vault: private per project by default, or one shared ID. Settings ›
Theseus ID lists the projects, changes or renews an ID, revokes, and shows
the recovery key. The login service is https://id.theseus.x.
- BNS sites on an ip record get the page's own POSTs, headers and cookies,
so forms and sign-ins on hephaestus.x and id.theseus.x work.
- Vault: PINs of 6 to 8 digits set up step by step on a keypad; the unlock
prompt is centred and its keypad no longer jumps under the cursor.
- Logins: after a sign-in or sign-up, Theseus offers to save the password
(optionally behind a PIN check), offers saved logins on login forms, and
keeps sign-ins for vault sites when cookies are cleared on quit.
Ships 0279b91 (the left panel resizes from its edge, per app, and hides
when a new tab or the right sidebar opens), d113c6d (a page click closes it
unless the app is pinned) and 6a2f6fe (an installed web app can be closed
and removed; Settings lists apps).
Web apps in the left panel were a fixed 380 px, too narrow for WhatsApp,
and add-on panels a fixed 400. A grip on the panel's right edge now
resizes it, each app keeps its own width (settings.leftPanelWidths), a
double-click resets it, and the page always keeps at least 320 px. The
grip is a small view of Theseus's own laid over the edge, since the panel
may be a third-party page; while dragging it covers the window so the drag
keeps its events.
Like Opera's sidebar, the left panel now hides when a new tab is opened or
the right sidebar opens. It is only hidden, so reopening lands where the
user left off.
Add-on panels on the left used to get the right sidebar's grip on their
left edge, where dragging resized the right sidebar; that grip is hidden
there and its drags are ignored.
Pages of Silent Mode projects can now sign the user in with their Theseus
ID instead of a wallet phrase typed into the page. Theseus writes the
sign-in message itself, takes the origin from the committed top frame, and
signs as a project only on an origin that project's list includes, so a
phishing page cannot get another project's signature and no page can use
the ID key to sign anything else.
- lib/theseus-id.cjs: the policy (first sign-in always asks and lets the
user pick a private or One ID; Silent Mode projects are silent after
that while the vault is open; per-site "always"; 10 silent signatures per
minute per origin), the per-project record encrypted under a key derived
from the vault, origin-list fetching with a 1 h cache and a 7-day stale
fallback, and ID moves that send a proof signed by both keys and only
finish once the project confirms.
- A locked vault is unlocked only for a page the user just clicked or typed
in: navigator.userActivation alone is true on load for pages opened with
loadURL, which would let a page pop the vault prompt by itself.
- Settings › Theseus ID: default mode, One ID, automatic sign-in toggle,
signed-in projects (always, change ID, new ID, revoke) and a recovery key
behind a fresh PIN / password check.
- TheseusID/registry/projects.json is the first-party list (Hephaestus,
Sirius, Pithos); it and TheseusID/lib ship as extraResources.
- Token-aware cashaddrs (BNS owners) now decode for owner-signed lists.
Verified on a scratch profile against a local test project whose server
checks signatures with TheseusID/lib/verify.mjs: locked vault on load gives
"locked" with no prompt, first sign-in prompt, silent second sign-in, a
claimed foreign project refused without a prompt, an ID move that keeps the
project's account, and the recovery key behind the confirm prompt.
Settings > Plug-Ins > Ariadne's Thread now switches the daemon on and off
on every install scheme. The toggle used to look for a scheduled task
named 'BNS Resolver Daemon' (and 'BNS Sia Bridge') -- the compat names
from before Ariadne 0.2.0. A fresh 0.2.0 install under the Just-me scope
registers the daemon as 'Ariadne BNS Resolver (<user>)' instead, so the
toggle silently did nothing. The handler now walks every scheduled task
whose name matches the Ariadne pattern -- the pre-0.2 compat names,
the 0.2.0 All-users names and the Just-me scoped names -- and starts or
stops each one. Unrelated 'BNS Indexer'-style tasks on the box are left
alone.
The blocklist consumer existed in the resolver library and the gateway, but
the browser opened a flagged name without comment. Now the indexer process
reads the subscribed lists from the chain every ten minutes and hands the
flags to main. A flagged name loads a warning page naming the reason, the
list and the report; the user may continue, and that is remembered per name.
Two gates, because content is reached two ways. loadBns shows the real
interstitial. serveBns refuses with an inline page on every path that skips
it: reload, back and forward, bns:// links, web app windows. The inline page
has no button, since a page at the site's own origin must not be able to
approve itself; only blocked.html may ask to continue, checked by file URL.
Settings › Naming has the policy: warn (default), never open, or ignore the
lists. The csam reason is never offered a way through. A list that cannot be
read keeps the last known flags and never stops a name from resolving.
The gateway put its own warning in front of flagged sites, which this
browser could not get past: it fetches files itself, with no cookie jar. It
now sends x-bns-policy: client and the gateway stays out of the way for a
client that says it decides for itself.
dev/blocklist-selftest.js runs the real protocol handler and decision
functions against a scratch profile.
- Settings → Language gets a Translator engine radio: pick between
LibreTranslate (hosted — current default) and Bergamot (on-device —
WASM engine, bundled in a later release; falls back to LibreTranslate
for now with a one-time notice). See bergamot.x for the plan.
- Bundles Pithos 0.3.13: menu reflows in setup order with the account on
top, files waiting to upload are shown and go up on their own, s3d
one-shot commands never open the database at once.
- Error page handles Cloudflare Bot Fight 503s: branded page explains the
Electron TLS fingerprint and offers a one-click retry to a .bch mirror
when one is published (path preserved).
- Fixes did-fail-load suppression: a cert error during the HTTPS fallback
now surfaces the branded error page instead of being swallowed.
Built-in extensions can answer paths under a name they ship with, so
Pithos opens at pithos.sia/<user>/<drive>/<folder> instead of a
loopback address, signed in only while the vault is unlocked. A tab
playing sound is no longer frozen in the background, so music keeps
playing when you switch tabs. A widened left panel covers the page
instead of squeezing it and the right sidebar. The tab that was open
at close loads on launch. Bundles Pithos 0.3.10 (views, compact sidebar
layout, music player, updater footer, Account page) and Aegis 0.31.0
(the audit fixes).
Ships 2437506 (the restore setting was a no-op with the default quit
clear), the first-use loader for extensions with Aegis 0.29.0 bundled
(~0.7 s less main-thread work at launch, ETH/SOL bridge fixed), the
language picker as an overlay, Pithos 0.3.4 and the Ariadne status row.
The globe-chip menu was a native Electron menu — square corners, system
font, no theming beyond the OS's own context-menu paint. Replaces it with
a floating overlay WebContentsView (lang-picker.html + preload),
following the same pattern the engine picker and the popover already
use: rounded 12px surface, acid-tint accents on the current pin, soft
shadow, dark + light scheme, flush under the chip's bottom-right.
The content is organised around the user's intent — translate first,
pick a language second. The "Translate this page" row sits at the top
when it is actionable (web tab + supported source + supported target),
with the detected source and the target under the label so the user can
tell what the backend will do before they click. Once a page is
translated, that row flips to "Show original (<source>)". Below the
action strip is Automatic + the six supported languages, each with a
two-letter code chip in the left slot and a ✓ on the current pin.
Unsupported languages are hidden by default inside a collapsible "More
languages (translator coming later)" group — click to expand, click to
collapse; a pinned-unsupported auto-expands so its ✓ stays visible.
Plumbing matches engine-picker: deferred-load WebContentsView,
closeOnClickAway, setBounds anchored under the chip, picker renderer
reports its own content height after each render so the overlay
contracts and expands with the "More languages" toggle. State pushes
come from emitTranslateState (so the Translate / Show-original row
updates when a page finishes auto-translating with the picker open)
and from broadcastSettings (so a Settings-side language change
re-paints the ✓).
Verified end-to-end: picker loads, shows Automatic + 6 supported in the
default list and 18 greyed in the "More" group, repaints to "⟲ Show
original (Spanish)" after an auto-translate completes.
Ships 08b101f (a quick-unlock PIN for the vault, shared with extensions
through api.vault.requestUnlock), 3fd0fe3 (extensions can open from the
left edge, beside the quick links), Pithos 0.3.0 bundled (c2df6e3: guided
setup, PIN gate, recovery phrase from the vault, on the left) and e1c5d91
(one language chip with "Translate this page" and automatic translation).
The vault re-locks on every restart and only the master password opened
it, so every extension that needs it (Aegis, now Pithos) either asked for
the master password itself or grew its own PIN. Theseus now owns one:
- Settings > Passwords sets, changes or removes a 6-digit PIN. The PIN
wraps the master password (PBKDF2-SHA256, 600k iterations, AES-256-GCM)
and the result is sealed with the OS keystore (safeStorage: DPAPI /
Keychain / libsecret), so a copied vault-pin.json cannot be brute-forced
elsewhere. Every unlock still ends at the master password.
- Three wrong PINs in a row require the master password. The strike count
lives in the same file, so a restart does not reset it; a successful
master-password unlock does. A PIN whose password no longer opens the
vault (password changed) is dropped.
- unlock.html is Theseus's own prompt, over the whole window: PIN pad, or
the master password. Extensions call api.vault.requestUnlock({ reason })
(vault-derive capability) and get { ok } back; what the user typed never
reaches them. Settings' locked screen offers "Unlock with PIN" through
the same prompt.