Commit graph

660 commits

Author SHA1 Message Date
Local Dev
ffc4d4d79e Theseus 0.3.123: error page's Did-you-mean row gains a Search chip
The "Did you mean" row on name-unreachable / name-not-registered used to
show only URL suggestions (BCNR warm-index matches + ICANN TLD swaps).
It now also carries a trailing "🔎 Search '<host>'" chip that defers to
the user's default search engine, so a DNS failure where none of the URL
alternatives look right still gives a one-click recovery path.

When no URL alternative surfaces at all — just the search chip is enough
on its own — the row's label softens from "Did you mean" to "Not sure
what you were after?" so a bare search chip reads naturally.
2026-10-27 20:55:11 +02:00
Local Dev
aea158ab05 Theseus 0.3.122 followups: AI engines page, Pick-AI edit button, Pithos panel, Did-you-mean on DNS failures, LLM picker UI polish, real-brand icon preference
Shipped on top of the 0.3.122 Settings restructure commit.

AI engines settings page. New top-level nav entry "AI engines" with its own
Default picker, Enabled list, catalog, discover filter and + Add AI engine
form. The Search page is now LLM-free — ENGINE_KINDS is `["search"]`, the
Search catalog filters out kind="llm" entries, and the Search custom-URL
form only adds kind="search" engines. add-engine IPC now accepts a kind:
"llm" field (sets defaultLlmId instead of searchEngine for LLM customs).

Pick-AI picker. Borders removed, corners rounded (16px), heavier shadow;
"Pick AI engines…" footer row dropped. Edit button (pencil icon) added to
the header; opens the new AI engines settings page via `llm-picker-settings`,
which now routes to the "ai-engines" slug (openSettingsTab falls through to
"search" for legacy profiles that lack the section).

Icon priority flipped. allEngines() now prefers a fetched favicon (the
site's own brand mark, cached per profile) over the bundled generic tile.
Bundled tiles still carry the first paint while the fetch runs, and the
emit after fetch swaps in the real brand. Offline profiles see the tile
indefinitely — same reliability as before.

Pithos sidebar panel. bundled-addons/pithos/addon.json declares a `panels`
block so sidebarLeftPanels() returns Pithos's panel BEFORE the add-on's
on-demand activation. Previously, the Sidebar settings' Theseus native
apps card was missing Pithos: it only appeared after first launch, when
the add-on's own registerSidebarPanel call ran. Hermes already did this.

Did-you-mean on DNS failures. The error page's "Did you mean" row now
merges BCNR warm-index matches with ICANN alternative-TLD swaps + history
base-name matches. For my.mynymbox.com the suggestions are my.mynymbox.io,
mynymbox.io, my.mynymbox.net, mynymbox.net — the subdomain-strip is
interleaved so a mistake like typing my.mynymbox.com when the real site
is client.mynymbox.io still surfaces mynymbox.io near the top. Both paths
are local-only; no network, no leak of what the user is browsing.

Sidebar settings tightened. "How panels open" collapsed to one row with
two side-by-side option cards; "Reset panel widths" and "AI engine in the
sidebar" are one-liners now.
2026-10-27 20:50:40 +02:00
Local Dev
1a31ac0393 Theseus 0.3.122: Settings restructure — General first-rows, top-level Ariadne & Aegis, Sidebar native-apps card
Settings page UX restructure.

- Nav bar: reordered to General, Language, Search, Passwords, Performance,
  Privacy, Names & Certificates, Plug-ins, Ariadne's Thread, Aegis,
  Extensions, Sidebar, Apps. Dropped the top-level Theseus ID entry;
  Theseus ID is reachable from General now. Added two new top-level
  entries — Ariadne's Thread and Aegis — each a small landing section
  that chevrons into the existing plug-in sub-page (Ariadne) or opens the
  wallet panel via openPanel("aegis:main") (Aegis).

- General section: first four rows are now Make-Theseus-default, Theseus
  Shield (chevron + on/off toggle), Startup (restore tabs), Updates
  (version + Check button), followed by a Theseus ID chevron row.
  Appearance / Developer tools / Registries / About stay below in the
  same order. Removed the "Default handling" sub-head; the default-
  browser and file-associations rows moved to the top. The Shield row
  uses listAddons() + setAddonEnabled("blocker", on) for state; the
  chevron falls back to openPanel("blocker:main").

- Names & Certificates: dropped the always-on BNS row at the top.

- Plug-ins main page: Ariadne's Thread and Aegis rows removed — they
  moved to top-level. The page now links into the new landing sections.
  Hidden placeholders keep the DOM ids (ariadneStatusMain, aegisCheckMain
  …) so the shared refresh code keeps working. Sub-pages (plugins-
  ariadne, plugins-aegis) untouched.

- Extensions list: Hermes and Pithos hidden from the list (they live in
  the Sidebar card now). docx-editor and pdf-editor sort last within
  each group so smaller utilities stay near the top.

- Toolbar add-on strip (chrome.html): same last-sort rule for docx-editor
  and pdf-editor, applied to the rank() ordering so unknown keys without
  a saved dockOrder keep registration order and the editors land past
  them.

- Sidebar section: added two cards at the top. "Theseus native apps"
  (Hermes + Pithos) and "Third-party apps" (the sidebar quick-links /
  Web apps). Native apps appear first. The Extension panels section
  still lists everything else that opens from the strip; Hermes and
  Pithos are filtered out of it so they don't appear twice.

- Version bumped to 0.3.122. No new IPCs — reuses listAddons,
  setAddonEnabled, openPanel, sidebarLeftPanels, addonInvoke.
2026-10-27 18:04:49 +02:00
Local Dev
41eb0acec9 Theseus 0.3.121: default-browser toggle + "Open with Theseus" in file menus
New Settings › General › Default handling section (Windows only, hidden on
other platforms until there is a backing path for them). Two toggles:

  * "Make Theseus the default browser" registers Theseus for http and https
    via app.setAsDefaultProtocolClient and lands the user on Windows
    Settings › Default apps so they can confirm the switch — Windows does
    not let an app assert itself as default, so we do what we can and point
    them at the UI that owns the final decision.
  * "Show Open with Theseus in file menus" writes HKCU\Software\Classes
    entries for .html, .htm, .pdf, .svg and .xhtml so Theseus appears in
    the Open-with dropdown for those files. Everything lands under HKCU
    (no admin). A matching RegisteredApplications\Theseus Navigator entry
    makes Theseus visible by name in Settings › Default apps.

Also handles file paths and URL arguments on the command line — this is
what Windows passes when the user picks Theseus from an Open-with menu, or
clicks a link in another app once Theseus is the default. argv[0] is the
exe; the first entry that is a recognised scheme (http/https/file/bns) or
an existing local file wins and opens as a new tab. Second-instance was
already wired to handleLaunch via requestSingleInstanceLock, so a running
Theseus just picks up the file.
2026-10-27 17:28:32 +02:00
Local Dev
fa2d2f89da Theseus 0.3.120: Pick-AI button opens its list again; "DuckDuckGo AI" renamed to "Duck AI"
The 0.3.106 switch from a native menu to an HTML overlay for Pick AI gave the
overlay a client-side window.blur handler that called api.close(). In the
engine picker (same pattern) the close-on-click-away is driven from main
with a `win.isFocused()` guard, so a focus flicker between the strip view
and the pop does not count as a click-away; the LLM overlay missed that
guard, so Electron's own view-to-view focus flicker on open was enough to
close the picker the moment it opened. From 0.3.106 through 0.3.119 the
Pick-AI button looked like a no-op: it rendered the pop internally (the DOM
was there, 7 rows) but setVisible flipped back off before paint. Users saw
a blank click.

Fix is the same contract the engine, language, downloads and site-info
pickers use: closeOnClickAway on main, no blur handler on the client.
`llmPickerVisible` is tracked alongside setVisible so the gate can read it.
The focus() call on open now runs only when the window is actually focused
(same guard the other overlays use). The raise() call also passed
`primaryW?.win` where a window record was expected, so the view never
re-parented when a secondary window became primary — fixed to pass the
record.

Also renames DuckDuckGo AI → Duck AI in the engine catalog. duck.ai is
Duck's own branded entry for the chat UI and matches what the host lands
on; the longer name was ambiguous next to the DuckDuckGo search entry.
2026-10-27 17:08:33 +02:00
Local Dev
47a739ad72 Theseus 0.3.119: LLMs out of the search dropdown; reorder by popularity; add DuckAI, Alisa, Qwen
The toolbar magnifier dropdown mixed search engines and AI chat engines in one
list, which left the Pick-AI button on the sidebar strip looking redundant and
cluttered the thing people reach for when they want to find something on the
web. The dropdown is now search-only; LLMs are picked through the strip's own
AI picker overlay (which already lists them with real icons).

LLM order follows rough global popularity so a fresh profile defaults to the
one most people reach for: ChatGPT, Gemini, Grok, Perplexity, DuckAI, Alisa,
Qwen. Three additions along with it:

  * DuckAI (duck.ai) — anonymous, no sign-up, serves GPT-4o mini + Claude 3
    Haiku + Llama 3 + Mistral behind one URL. Also wired as a toolbar search
    target with pre-filled answer via &ia=chat.
  * Alisa (ya.ru/alisa) — Russian-language assistant from Yandex.
  * Qwen (chat.qwen.ai) — Alibaba's Tongyi chat; email sign-up, the strongest
    non-mainland-phone access to a Chinese model.

Phind stays frozen (Vercel 404 at the root). A saved defaultLlmId pointing at
a frozen engine is cleared so the fallback resolves to the new list[0] rather
than silently flipping to whatever was second.

Engine home URLs can now opt into an override via a `home` field — needed by
DuckAI (its chat lives at the apex of duck.ai but prefers that URL over the
duckduckgo.com stem) and Alisa (chat UI lives at /alisa, not the apex of
ya.ru).
2026-10-27 16:47:22 +02:00
Local Dev
61c605a97f Theseus 0.3.118: drop Phind (Vercel 404), re-bundle AI picker icons
Phind's web UI returns a Vercel 404 at the root as of 2026-10-27, so
users who clicked Open AI with Phind as the default got a dark error
page. The engine is now marked frozen with a reason, which keeps the
Settings row visible with an explanation but takes it out of the
enabled list; anyone whose defaultLlmId was phind automatically falls
back to the next enabled engine (Perplexity).

AI picker icons move from runtime favicon fetch back to bundled files
(ChatGPT, Grok, Gemini return as engine-icons/*.svg — initial-on-color
tiles). The fetch path still runs as a fallback for custom engines and
anything else that lacks a bundle.
2026-10-27 16:01:36 +02:00
Local Dev
34989f94b3 Theseus 0.3.117: ICANN hosts that fail DNS show a DNS error, not a BCNR-register pitch
When a navigation hits ERR_NAME_NOT_RESOLVED and the TLD is a well-known
ICANN one (.com/.net/.io/country codes/…), Theseus now shows the DNS-
flavoured 'This name didn't resolve' page instead of the BCNR-flavoured
'That name isn't registered' page. The BCNR page framed the failure as
'nobody has claimed this on-chain name, want to register it on Sirius?'
— confusing when the user typed a real .com whose DNS is temporarily
broken (hostile Wi-Fi AAAA mangling is the usual cause). The DNS page
leads with retry and search instead, and still mentions BCNR was tried.

Non-ICANN TLDs (.bch, .x, …) keep the register-first framing. The
TLD set is a static whitelist of the common ones — covers the long
tail of real sites without being exhaustive. Add more as needed.
2026-10-27 15:35:03 +02:00
Local Dev
33a84e70b0 Theseus 0.3.116: Pick AI is its own strip button; Claude chip no longer crowds the search box
The AI picker is now a sibling of the AI launch button in the sidebar
strip, not a chevron badge glued to its corner. Launch button still
opens the current engine in the left panel on click (right-click still
opens the picker, kept as a power-user shortcut). The new pick button
is a full-size strip icon with a three-row list glyph and its own
tooltip; keyboard Enter / Space activates it.

The Claude connector chip in the toolbar gained max-width + ellipsis
on its label, plus flex-shrink wiring, so the Claude 3 tabs string
never grows past 160 px and the search box keeps its text visible
even when the connector is actively streaming.
2026-10-27 14:31:26 +02:00
Local Dev
f87173fde4 Theseus 0.3.115: AI picker chevron now visible; strip + picker refresh after favicon fetch
The sidebar AI button's chevron badge grows from a 10 px grey ghost in
the corner to a 14 px acid-coloured circle that reads at a glance, so
Pick AI engine is actually discoverable. Click or Enter still opens
the picker overlay; right-click on the AI button still works too.

Also wires emitQuickLinksState() into the icon-fetch completion path.
Before 0.3.115 the sidebar strip and the picker overlay kept showing
the engine sym emoji until some other state change re-emitted the
quicklinks payload. Now a freshly-fetched favicon lights up in the
strip and the picker on the same tick it finishes caching.
2026-10-26 10:50:47 +02:00
Local Dev
8bb5b3d26a Theseus 0.3.114: add-on update poller fires after chrome, not during tab restore
Moved the 30-second boot poll from whenReady+30s into onChromeReady so
restoreTabs' network fetches aren't competing with the add-on manifest
fetches for the first few seconds. The 4 h interval stays where it was.

Preload audit (no change needed): theseus-id-preload.js already short-
circuits in subframes (window.top === window guard), addon-inject-
preload.js keeps page scripts top-frame only by design, and
no-badge-preload.js intentionally covers service workers.
2026-10-25 12:51:27 +02:00
Local Dev
bd55e75536 Theseus 0.3.113: AI picker shows the real brand favicons
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.
2026-10-25 10:47:40 +02:00
Local Dev
9095a5ecf9 Theseus 0.3.112: AI picker chevron fixed, home polish, performance toggles
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.
2026-10-24 14:20:20 +03:00
Local Dev
5829d43482 Theseus 0.3.111: address bar + home search select-on-click
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.
2026-10-24 14:05:04 +03:00
Dev
a920737c3c Claude connector 0.2.0: connect Claude Code and Claude Desktop from the panel
Setting the connector up meant copying a command with a token into a
terminal, and since 0.3.107 the token rotates whenever the connector
stops, so a configured client silently lost access after any extension
toggle and had to be set up again.

The panel now has a Connect button per app. Claude Code is registered
through its own CLI (claude mcp add-json, user scope), so its config is
written by Claude Code itself; Claude Desktop gets only the theseus entry
in claude_desktop_config.json, with a backup and no write to a file that
does not parse. Apps connected this way are re-registered after every
start and every Revoke when the address or token no longer matches. The
panel opens by itself the first time the extension is turned on. The
copy-a-command route stays under "Set up by hand".
2026-10-24 00:32:06 +03:00
Local Dev
17c434dcee Theseus 0.3.110: horizontal cards, semi-transparent backgrounds, refreshed tagline
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.
2026-10-23 23:34:25 +03:00
Local Dev
3ab3f77594 Theseus 0.3.109: Save page as PDF or PNG; connector design doc hosted on theseus.x
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.
2026-10-23 23:00:42 +03:00
Local Dev
a639f7a80d Theseus 0.3.108: hero wordmark in a readable pill, left slots widened
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.
2026-10-23 21:09:48 +03:00
Local Dev
7f70779f1c Theseus 0.3.107: two-section home + Claude connector hardening
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.
2026-10-23 19:12:52 +03:00
Dev
c06557e957 Theseus: Claude connector, an opt-in MCP server for the signed-in profile
Claude sessions could not work inside the user's own profile: the desktop
app's browser lost synthetic pastes and typing in Medium's editor, and a
browser-wide --remote-debugging-port would hand every session to any local
process. The connector is a built-in extension, off until turned on in
Settings > Extensions, that serves MCP on 127.0.0.1 behind a per-install
token and drives one tab at a time through that tab's webContents.debugger.

- Host: a "tab-control" capability (built-in add-ons only) for listing,
  opening, navigating, closing and focusing tabs, handing out web tabs'
  webContents (never Settings, extension or home tabs), and a toolbar chip
  plus tab outline while a client is connected; the chip's X stops it.
  Built-in add-ons can ship "defaultEnabled": false.
- Tools: list_tabs, open_tab, navigate, activate_tab, close_tab, screenshot,
  read_page_text, snapshot (accessibility tree with refs), click, type
  (insertText + real Enter), press_key, paste_html / paste_text (system
  clipboard + webContents.paste, clipboard restored), upload_file
  (DOM.setFileInputFiles), wait_for, and evaluate behind its own switch.
- Safety: first use of each site asks the user; password and one-time-code
  fields are refused; uploads only from folders the user added; requests
  from web pages or foreign Host headers are refused; every action is
  logged with a timestamp in the panel and actions.log.
- Claude Desktop runs stdio-shim.cjs through the Theseus executable in Node
  mode.
- Tests: unit (protocol, auth, policy, shim) and an end-to-end run on a
  throwaway profile that types, pastes HTML with a heading and a link, and
  uploads a PNG on a local page.
2026-10-23 17:45:02 +03:00
Dev
08cc113371 Theseus: plan for an opt-in Claude connector (MCP over loopback, per-tab CDP)
Claude sessions need to act inside the signed-in profile (a Medium draft
failed from the desktop app's own browser), and a browser-wide debugging
port would expose every session to any local process.
2026-10-23 17:45:02 +03:00
Local Dev
fde510eece Theseus 0.3.106: AI engine picker as a styled overlay with real icons
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.
2026-10-22 22:06:37 +03:00
Local Dev
964536b5c8 Theseus 0.3.105: fixed-slot left grid + Ariadne dark-bg icon
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.
2026-10-22 21:31:45 +03:00
Local Dev
82c9408cdf Theseus 0.3.104: WizardConnect "Open in wallet" links reach Aegis
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.
2026-10-22 19:35:34 +03:00
Local Dev
727fa27ebd WizardConnect "Open in wallet" links that open a new window reach Aegis
Potidaea's "Open in wallet" is <a href="wiz://…" target="_blank"
rel="noopener noreferrer">, a shape many dapps use. A new-window wiz:// link
goes through the window-open handler, which credits a pairing to the page
only through the request's referrer, so it can tell the page's own link
from one in a frame. noreferrer strips the referrer, so the link was
dropped and the wallet never heard of it.

The inject preload, which runs in a tab's top document only, now hands a
trusted click on a wiz:// link straight to main, and main accepts it only
from the tab's main frame before routing it like any pairing link. Links
inside iframes still go the old way and are still refused without a
referrer.
2026-10-22 19:15:05 +03:00
Local Dev
2da64a5600 PENDING: retire the translate entry now that 0.1.7 has landed
The file tracks working-tree state that is not yet committed or shipped;
0.1.7 is both, so leaving the block would misdescribe the tree to the next
session reading it.
2026-10-22 15:59:49 +03:00
Local Dev
93e54ca348 translate 0.1.6 -> 0.1.7: translate as you type, and say what was detected
Typing never triggered a translation. The input handler was wired only to the
language detector, so nothing happened until Enter, the Translate button or a
language change -- the panel looked broken to anyone who simply typed and
waited. Translation now runs 500 ms after the text settles.

Each request carries a sequence number. Typing outruns the network, and
without that guard a slower earlier response paints its stale text over a
newer one.

Detection already worked, but wrote its answer only into the text of the
collapsed "Auto-detect" option, which a closed select hides -- so it read as
"detection is broken" when it had in fact succeeded. Name the language in a
row under the selects, and lower the 12-character floor to 5, since short
phrases never cleared it. With translate-as-you-type on, skip the standalone
detect call: the translation response already carries the detected language,
so asking twice only doubled the load on a public mirror.

Two of the three fallback mirrors were dead, checked by posting to both
endpoints: translate.plausibility.cloud answers 405, and lingva.ml serves an
HTML page because it is not a LibreTranslate API at all, so it could only ever
produce the "HTML instead of JSON" failure. Drop both and add
silentmode.st/libre, which stays a fallback rather than the default because it
covers six languages against disroot's fifty.

Auto-translate sends text to a translation server as it is typed, so it is a
visible toggle rather than silent behaviour. Default on.
2026-10-22 15:59:09 +03:00
Local Dev
3b2cad491d hermes: ship the browser side of the Theseus feature set
Fixes the "unknown invoke: fetchCloudBackup" dead-end on mobile sign-in
and the empty hooks the Settings UI depended on. The shim now implements:

- Local wrap: on signup it generates a BIP-39 mnemonic (@scure/bip39),
  derives the Nostr sk via PBKDF2+HKDF with purpose "messenger/0" (same
  chain Theseus runs), scrypt+AES-GCM wraps the mnemonic (@noble/hashes
  scrypt matching HERMES_SCRYPT N=2^15 r=8 p=1), stores it in
  localStorage.hermes.wrap. hasBackup/getBackup use that wrap, so a
  password sign-in now works on the same device.

- Cloud backup: publishCloudBackup / fetchCloudBackup / removeCloudBackup
  / hasCloudBackup matching Theseus's dtag format
  (hermes.backup.v1/<sha256(bareName)[:32]>). Password unlocks the local
  wrap, re-wraps for the cloud copy with a fresh salt, publishes a
  kind:30078 to every relay, remembers the event id for later retract
  via NIP-09.

- Phone discovery: setPhone / clearPhone / findByPhones with the same
  hermes.phone/<base64url(sha256(E.164))[:32]> d-tag Theseus uses, so a
  vCard import on the browser surfaces the same matches a Theseus user
  would see.

- contactsUpdate / contactsRemove rounded out so the panel's contacts
  menu is fully wired.

Also:

- Default relay list bumped to [wss://hermes.x, wss://relay.silentmode.st,
  wss://nos.lol] in both the Theseus host and the web shim, so every
  publish/fetch hits our own strfry on the VPS and the cloud backup lives
  somewhere we control.

- Theseus host: addons-host.js + main.js now understand a `width` field
  on sidebar panels, so the Hermes panel declares width:500 and opens at
  a Telegram-ish width by default (user can still drag; saved per-panel).

- Panel + web messenger: forced color-scheme:dark (the brand mark has
  hard navy cutouts that stand out as "black inside the envelope" on a
  light background; dark everywhere is cheaper than theme-aware marks).

- Password fields: 👁 toggle appears on every <input type="password">
  via a tiny JS enhancer in both the panel and the web messenger.

- Settings/signin tabs: Sign in / Sign up persistent pill, drag-to-resize
  contacts/thread splitter (persisted per device), 2-column always.
2026-10-22 15:33:07 +03:00
Local Dev
b2fef43607 Theseus 0.3.103: sidebar panel context menu + Hermes icon framing
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.
2026-10-22 13:48:09 +03:00
Local Dev
c944952f04 hermes panel: mirror the Sign in / Sign up tab bar from the web
Theseus's sidebar panel.html had the pre-redesign flow (two primary buttons
+ Create a new account toggle + Name+password/Seed-phrase chip switcher).
Replaced with the same persistent pill tab bar the web messenger uses:
Sign in / Sign up visible together, active one filled, inactive outlined;
tapping an inactive tab swaps the form below with no back step. "Recover
with seed phrase" is a quiet link that opens its own form (with ← Back).

The Theseus-only "Open with Theseus ID" quick path now lives inside the
Sign in tab's form and hides entirely when the vault is locked — no more
disabled button + hint about unlocking the vault cluttering the signin
screen. Bumped the bundled addon to 0.2.9.
2026-10-22 13:28:47 +03:00
Local Dev
4b3fd4be42 hermes: mobile mockup collapse + two-user integration test
The /overview page's UI mockup used a fixed 220px/1fr grid that overflowed on
375px viewports. Added a @media (<=640px) rule that drops the contacts pane,
expands the thread to the full width, breaks out to the screen edges, and
tightens the window-bar + compose padding so the mockup reads cleanly on a
phone.

Added tests/hermes-two-users.test.mjs — a Node integration suite that drives
two personas (alice, bob) through the full flow against the live nos.lol
relay: BIP-39 key derivation, phone-claim publish, phone→pubkey discovery
both directions, bidirectional NIP-17 gift-wrap DM delivery, vCard parse +
findByPhones. Eight assertions, all pass. Run with:
  node TheseusNavigator/tests/hermes-two-users.test.mjs
2026-10-22 11:55:06 +03:00
Local Dev
bbe5d3d298 hermes: cloud-wrapped backup (opt-in B) + mobile site polish
Users can now sign in with name + password on a device that has never seen the
account by opting into a cloud backup at account creation. The seed phrase is
locally re-wrapped with scrypt + AES-GCM keyed by the password and published
as a NIP-78 kind:30078 event under d-tag `hermes.backup.v1/<sha256(name)>`.
Relays only ever see opaque ciphertext; the password is the only decryption
key, so backup strength is password strength.

Signin tries the local wrap first (fast, no network) and falls back to the
cloud copy if the device hasn't been used before. Settings → Backup now has
"Back up to cloud" / "Re-upload" / "Remove cloud backup" controls that reuse
the Reveal-seed password field as the key.

Site: added @media breakpoints to shared.css so the header collapses cleanly
on narrow screens (icon-only brand under 380px, hidden "Sign in" label under
640px), the hero mark drops to 84px, h1 scales down, and buttons shrink to
touch sizes. Also fixed a stale reference to the removed `mnemonicBox` id in
the Create-account toggle that was throwing a TypeError on mobile.
2026-10-22 03:46:45 +03:00
Local Dev
6b4654231b hermes settings: scrollable modal + Address book vCard import
Two Settings-pane fixes:

1. .modal was clipped on short viewports (mobile landscape, small
   laptop screens): place-items:center + fixed max-width with no
   max-height meant the content below Phone discovery / Backup fell
   off the bottom. Add max-height: calc(100vh - 24px) + overflow-y:
   auto so the whole thing scrolls inside the backdrop. This is why
   the user couldn't see Phone discovery on mobile.
2. Address book section between Phone discovery and Backup: 'Import
   contacts from vCard' triggers a hidden file picker (<input
   type=file accept=.vcf>) that reads the file client-side, extracts
   FN + TEL per VCARD block, hands the phone list to findByPhones,
   and auto-adds the matched Hermes identities as contacts with the
   vCard name as nickname.

Lives in both the Theseus addon panel and the hermes.x web messenger.
Phone discovery was already in Settings — the modal clipping just hid
it on smaller viewports.
2026-10-22 03:12:28 +03:00
Local Dev
5984d39253 hermes signin: one Sign in button + two chips, nav + mobile dark bg
Signin screen (both the Theseus addon panel and hermes.x/messenger):
- Open with Theseus ID and Create a new account stay as top-level
  actions (unchanged).
- Beneath them, a 'Sign in' divider + two chips [Name + password]
  [Seed phrase] drive one unified Sign in button. Toggle swaps the
  input area between the password form and the mnemonic textarea.
  The old 'Sign in with name + password' and 'Open an existing
  account' secondary buttons are gone.

Site nav restructure (site-hermes-x/):
- Header now: Hermes.X brand + Overview + Sign in icon (opens
  /messenger). Messenger tab, Branding tab, and Get Theseus pill are
  all removed from the header.
- Footer carries Branding + Open Messenger + Get Theseus links as
  secondary nav. Branding is 'here' on the brand kit page.

Mobile dark bg fix (shared.css):
- color-scheme: dark on :root so mobile browsers don't flip the
  page into a light theme that makes the sky-blue mark unreadable.
- html { background: var(--bg) } so the pre-body paint is dark too
  (Safari / Firefox mobile briefly show the html bg before body css
  loads).
2026-10-22 03:08:40 +03:00
Local Dev
975edba88f hermes signin: hide the hermes: scheme + add name+password sign-in
Scheme form "hermes:alice" was leaking into the UI (default display
mode + hero copy + placeholders). Drop it as a visible option: the
display-mode picker now offers bare / dotted / email and defaults to
bare so users just see "alice" in chat lists and settings. The
hermes: URI scheme stays available as an input form (parseHandle
still accepts it) — just not surfaced in the UI.

New sign-in path: a "Sign in with name + password" button on the
signin screen opens a two-field form that calls getBackup({password})
to unwrap the locally-saved mnemonic, then init({mnemonic, handle})
in one shot. This covers the "come back to the same device" case
without typing the full seed every time. From a new device the seed
phrase path is still there — the form hint says so.

Applied to both the desktop addon panel (TheseusNavigator/bundled-
addons/hermes/panel.html) and the hermes.x web messenger
(site-hermes-x/messenger/index.html) so they stay in step.
2026-10-22 02:27:23 +03:00
Local Dev
88b5f2473b hermes: monkey-patch scryptSync maxmem from the extracted lib
The main.js scrypt call also carries its own maxmem option now (commit
00286f76), but main.js lives inside app.asar and can't be hot-patched
onto an installed Theseus. lib/hermes.js lives at
resources/lib/hermes.mjs OUTSIDE the asar — patching it with the
module-level crypto.scryptSync override means a plain file-write onto
an installed Theseus fixes Create account without rebuilding and
reinstalling.

The patch guards itself with __hermesScryptPatched so repeated
loads of hermes.mjs (dev reload, test harnesses) don't re-wrap and
blow up the function reference chain.
2026-10-22 02:02:25 +03:00
Local Dev
47af393f22 hermes brand kit: inner V-fold now reads on every surface
Before: the on-sky lockup had a dark mark with dark cutouts — the fold
V-shape disappeared because the cutouts matched the mark colour instead
of the sky backdrop. Same on cream.

Now three per-surface mark variants, cutouts coloured to match the
expected background so it shows through:
  mark.svg          sky body  + navy cutouts   → dark panel
  mark-on-sky.svg   navy body + sky cutouts    → sky-blue surface
  mark-on-light.svg navy body + cream cutouts  → light surface

Logo lockups rebuilt the same way: logo-horizontal-on-sky.svg uses the
dark+sky mark variant, logo-horizontal-light.svg uses the dark+cream
mark variant, same for stacked.

Branding page's on-sky / on-light preview cells repointed at the new
variants. addon.json bumped to 0.2.6 (same mark, re-emitted from
pipeline for byte parity with the sites).
2026-10-22 00:14:54 +03:00
Local Dev
4c10e3e724 hermes: lift scrypt maxmem so Create account doesn't throw
N=2^15 r=8 p=1 needs 128 * N * r = ~32 MiB. Node's default maxmem for
scryptSync is exactly 32 MiB, so the derive call throws
MEMORY_LIMIT_EXCEEDED on the first create-account click. Pass maxmem:
128 MiB explicitly so the ceiling is above the KDF's working set with
headroom.

Applies to both wrap and unwrap paths; wrap params carry the KDF cost
inline so changing the N here would invalidate existing backups, but
unwrap already reads N from the blob — the maxmem lift is the only
needed change.
2026-10-22 00:10:19 +03:00
Local Dev
8171ea99d6 Theseus 0.3.102: home — Hermes brand mark catches up, slot grid tightened
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.
2026-10-22 00:02:57 +03:00
Local Dev
df994c2bdf hermes: tighter viewBox + bump sidebar strip icon size 20→26
Two tweaks so the mark reads at sidebar size.

- addon.json/mark.svg (and every mirror of mark.svg across the sites):
  rebuild with ZERO padding around the content bbox so the icon fills
  the slot vertically — before it was centred in a square viewBox that
  wasted ~45% of pixels. Version bumped to 0.2.5 so Theseus re-seeds.
- quicklinks.html: .icon svg, .icon img goes from 20×20 to 26×26
  (container stays 34×34; same breathing room, bigger glyph). Ships
  with the next Theseus release — can't be hot-patched into the asar.

Deploy state: site-hermes-x is live on the VPS and in bns/hermes.x/ via
the silentmode-sia-sync systemd timer, which was extended to include
hermes-x alongside sirius-x and bergamot. Future rsyncs of site-hermes-x/
to the VPS auto-sync to Sia within 5 minutes.
2026-10-21 23:02:32 +03:00
Local Dev
b013eebd5c hermes: use the vector mark everywhere, retire the raster paths
User supplied the real vector source at Hermes/Icons/file.svg. Dropped the
background rectangle, kept the sky-blue foreground + dark inner detail
cutouts, squared the viewBox around the content bbox with a small margin.
Result: ~6.6 KB SVG, pixel-perfect at every size — no more 60x downscale
blur.

- bundled-addons/hermes/assets/mark.svg: tight-cropped vector
  (viewBox centres the icon in a square so 1:1 slots don't crop).
- bundled-addons/hermes/assets/mark-64.svg: same, pre-normalised to a
  0..64 viewBox for legacy consumers that assume that range.
- bundled-addons/hermes/addon.json: version 0.2.4; manifest icon is now
  the SVG as a data:image/svg+xml;base64 URI (8.8 KB vs the previous
  16 KB PNG data URI).
- bundled-addons/hermes/panel.html: both img tags point at mark.svg at
  24 and 72 px.
- home.html / home-brand/hermes-mark.svg: Hermes.X tile uses the vector.
- site/hermes/{favicon,branding/mark}.svg: both now the user's artwork.
- site-hermes-x/assets/{favicon,mark}.svg: same.
- All /hermes site HTML img tags swapped from mark.webp to mark.svg.

Installed bundle + user-data cache hot-patched to 0.2.4 so this takes
effect on the running Theseus without a reinstall.
2026-10-21 22:52:18 +03:00
Local Dev
2abd4d9616 hermes: crop the mark to the icon area, ship 128/256 px PNGs
The 1461x720 webp downscales badly to 24 px (sidebar strip) and 72 px (signin
header) — browser is doing a ~60x reduction and the thin wing lines turn to
mush. Pre-crop around the icon's content bbox, make it square with a small
breathing margin, resize to 128 px and 256 px, drop transparency on the dark
backdrop. Addon manifest icon is the 128 PNG as a data URI (16 KB vs the
26 KB uncropped webp), and the panel pulls mark-128.png / mark-256.png at
the two sizes it needs. Also home.html's Hermes.X tile now points at the
cropped PNG so the home card isn't blurry.

Version bumped to 0.2.3 so seedBundledAddons picks it up on a release
bundle swap. The installed bundle + user-data cache were hot-patched
too so the fix is visible immediately in the running app.
2026-10-21 22:14:00 +03:00
Local Dev
bee4fd50dc theseus home: Hermes.X brand tile uses the webp mark
Was still rendering the red fill-in SVG left over from before Hermes had
a proper brand. Switch to the {src: "home-brand/hermes-mark.webp"} form so
the home tile matches what the sidebar icon + the hermes.x hero already
show. Lands next time home.html ships (part of a packaged Theseus release;
can't be hot-patched into the installed app.asar without rebuilding).
2026-10-21 22:11:27 +03:00
Local Dev
13d4ab76b3 Theseus 0.3.101: Grok + Gemini + ChatGPT, sidebar polish
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).
2026-10-21 21:55:10 +03:00
Local Dev
8c4572e329 hermes: use the user's own mark.webp as the icon, drop the SVG attempts
User-authored artwork wins. mark.webp is the main icon; two sibling variants
(mark-wings-both.webp, mark-variant.webp) ship alongside for brand uses.

- bundled-addons/hermes/addon.json: version 0.2.2, icon/panels[0].icon are
  now data:image/webp;base64,... from the main mark.
- bundled-addons/hermes/assets/mark.webp: served by the host via the panel
  page's relative path (seedBundledAddons' fs.cpSync recursive carries it).
- bundled-addons/hermes/panel.html: both top-bar and signin inline SVGs
  become <img src="assets/mark.webp"> at 24 and 72 px.
- site/hermes/index.html: hero SVG → <img> at 120 px.
- site/hermes/branding/{index.html,mark.webp,mark-wings-both.webp,mark-variant.webp}:
  branding kit now carries the three webp files; the inline hero SVG uses
  the main one.
- site-hermes-x/{index,branding,messenger}/index.html: same SVG → <img>
  swap with the appropriate assets/ relative path.
- site-hermes-x/assets/mark{,-wings-both,-variant}.webp: sibling of the
  existing favicon.svg and mark SVGs (kept for backward refs that still
  point at them).

Legacy mark.svg + mark-stroke.svg + favicon.svg stay in place for any
external references; nothing in-repo points at them for the primary icon
slots anymore. favicons still point at the SVG files — safe to leave;
flipping those to webp is a one-liner if you want it.
2026-10-21 21:32:14 +03:00
Local Dev
21310e600b theseus: ship nostr-tools alongside hermes.mjs in packaged builds
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.
2026-10-21 20:51:28 +03:00
Local Dev
22e2b3f75e Theseus 0.3.100: LLM sidebar button, Hermes consolidation, Settings polish
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).
2026-10-21 20:10:11 +03:00
Local Dev
208a192fc9 Theseus 0.3.99: SNS + Unstoppable adapters, Hermes moves to the sidebar
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.
2026-10-21 19:12:19 +03:00
Local Dev
e4a9a2cea9 hermes: addon 0.2.1 — bump so Theseus re-seeds today's user-data cache
The seedBundledAddons() version check is strict less-than: a cached v0.2.0
in %APPDATA%\Theseus\extensions\hermes\ wouldn't be overwritten by a bundle
also at v0.2.0, even if the files inside changed. Bumping to 0.2.1 forces
a reseed on the next restart so all of today's panel + API work (three-form
parser, Settings panel, kind:0 profiles, phone discovery) ships without a
manual cache wipe.
2026-10-21 19:06:56 +03:00
Local Dev
dd754c030b hermes: "on-chain registered name", not ".bch name"
Hermes handles are not tied to the .bch TLD — the user's names live on .x
today and the planned Hermes TLDs are .erm/.tel — so the hermes.x site,
the silentmode.st Hermes page and the add-on's description and panel now
say "on-chain registered name" and use alice.x / bob.x as examples.
Add-on wording ships on its own OTA; no version bump here.
2026-10-21 18:39:37 +03:00