Commit graph

643 commits

Author SHA1 Message Date
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
Local Dev
5e27a1b53d hermes: phone discovery (opt-in), lookup contacts by number
Users can link one or more phone numbers to their Hermes identity by
publishing a kind:30078 claim event whose d-tag is a SHA-256 hash of the
E.164 number. The number itself never leaves the device. Add-contact and
message-send now also accept a +phone input directly — the client hashes it
and queries relays for the matching Hermes identity.

- lib/hermes.js: normalisePhone(str) strips separators + a leading 00
  into E.164, rejects anything that doesn't fit +[country][7-15 digits].
  hashPhone(str) → base64url-truncated-to-32 SHA-256 digest, used as the
  d-tag suffix under PHONE_DTAG_PREFIX. buildPhoneClaimEvent /
  buildPhoneRetractEvent emit the signed kind:30078 / NIP-09 kind:5.
- main.js: _hermesAPI.getPhone / setPhone / clearPhone / findByPhones.
  Plaintext phone persists in the identity meta (locally only) so the
  user can see what's linked and retract it; event ids are kept so a
  retract can reference the exact wire event. hermesResolveTo takes a
  phone-shaped input and does the discovery lookup transparently, so
  contactsAdd and send accept phones without a new entry point.
- panel.html: Settings → Phone discovery (link / unlink + privacy note),
  add-contact placeholder now lists +phone alongside the other forms.

Privacy stance stated in the UI: "anyone who already knows your number
can find you — same tradeoff as number-based messengers." No PSI tricks
yet; plain hash. Users who don't want it just don't link, which is the
default. Future slice can add a pepper if operators want to narrow the
brute-force window.
2026-10-21 17:21:16 +03:00
Local Dev
b5b3e5c1b2 hermes: Nostr kind:0 profiles — display name, picture, about
Peers' chat-list labels now cascade: contact nickname → kind:0 display name →
BNS handle → pk preview. Avatars render as a URL picture when kind:0 carries
one, with initials as fallback. Profiles are fetched on demand (background,
non-blocking) when a new peer pk shows up in the inbox or contact list, and
cached on disk so a cold start renders instantly.

- lib/hermes.js: buildProfileEvent({sk, displayName, picture, about}) emits
  a signed kind:0 with `name` + `display_name` set together (clients vary
  on which they prefer). parseProfileContent(content) handles both.
- main.js: profile cache at <userData>/hermes/profiles.json; auto-fetch
  from HERMES_DEFAULT_RELAYS with a 4 s per-relay cap. hermesPublishEvent
  centralises relay publish (used by profile save; send() retains its
  inlined copy for the DRY-up later). hermesRecord() kicks off a background
  profile fetch the first time a peer is seen; result fires on the
  hermes-profile bus event.
- main.js: _hermesAPI.updateProfile / getProfile. Addon proxies both.
- panel.html: Settings → Profile editor (display name, picture URL, about);
  publishes on save, pre-fills from the cache. Picture validated as http(s).
  labelFor() + avatarFor() centralise the display cascade. Profile state
  lives in state.profiles.
2026-10-21 17:18:07 +03:00
Local Dev
cee34c47e5 hermes: name+password signup, Settings panel, seed backup gated by password
Third signin option on the panel: enter a bare name + password, Hermes mints
a 12-word BIP-39 mnemonic locally, derives the Nostr key, password-wraps the
mnemonic for later Settings → Backup, and persists the sealed sk the same
way the other paths do. Save-forever still handles routine signin — the
password is only used to reveal the seed phrase and only from Settings.

- main.js: hermesWrapMnemonic / hermesUnwrapMnemonic via scrypt (N=2^15) +
  aes-256-gcm. Wrapped blob at <userData>/hermes-identity/mnemonic.wrapped.json,
  plaintext JSON — the wrap itself is the protection. On sign-out the blob
  is nuked alongside the sealed sk.
- main.js: init() now takes { create: true, handle, password }. Handle is
  validated (1-32 chars, kebab-friendly) and stored as `<name>.erm` so a
  mainnet free-manifest reservation lands on the same canonical form later.
  Mnemonic-path init optionally takes a password too — "promote this
  seed-phrase session to a password-protected backup" in one step.
- main.js: new _hermesAPI.getBackup({password}) and .hasBackup. status() now
  returns handle + source so the panel can label the restored session.
- panel.html: "Create a new account" button on signin reveals handle +
  password + confirm. ⋯ menu adds Settings… showing account info, display
  mode picker (hermes:alice / alice.erm / alice@hermes.tel — persisted via
  silentmode.storage), and the gated seed-phrase reveal. Reveal lays words
  out 12-across with 1-indexed numbering so a user copying to paper doesn't
  miscount. Backup section hides for vault / mnemonic sessions.

Still off-chain only — handles created this way are local labels until the
mainnet mint of the free manifest lets us register them against the
`hermes.erm` signed-records store (see [[hermes-name-scheme-plan]]).
2026-10-21 17:14:26 +03:00
Local Dev
4133153f32 hermes: three-form handle parser, hermes: scheme display, save-forever signin
Panel + standalone window now accept all three handle forms as synonyms, and
the UI defaults to the hermes:alice scheme form. Signin is persistent across
restarts via safeStorage-sealed identity; the ⋯ menu adds Sign out.

- lib/hermes.js: parseHandle(input) → {kind, value} canonicalises any of
  hermes:alice, alice.erm, alice.bch, alice@parent.tld, npub1…, or raw hex.
  renderHandle(name, mode) formats a .erm name as hermes:alice (default),
  alice.erm (dotted), or alice@hermes.tel (email). Non-.erm names always
  render dotted so a .bch handle can't masquerade as a sub-identity.
- main.js: hermesResolveTo() unifies contacts-add + send + their panel-API
  twins behind one path. Sub-identity (alice@parent.tld) resolution returns
  a crisp "not available yet" until the mainnet mint of the parent name's
  signed-records manifest lands — the parser accepts the form today so UI
  copy and placeholders can show it.
- main.js: safeStorage-sealed identity at <userData>/hermes-identity/,
  auto-restored on app ready. New _hermesAPI.signOut wipes it. init() takes
  { remember: false } for a one-shot session (default: persist). A
  hermes-restored event fires on auto-restore so the panel skips the
  signin screen.
- panel.html: renderHandle() mirror client-side; ⋯ menu with "Signed in as
  hermes:alice" header + Sign out; placeholders show all three forms; the
  signin hint tells users they stay signed in.

On-chain `.erm` and `hermes.tel` mints are deliberately deferred to mainnet
per user direction — the parser and display paths are tld-agnostic, so a
mainnet switch is one constant change in lib/hermes.js (HERMES_TLD /
HERMES_EMAIL_PARENT) plus the panel's mirror of them.
2026-10-21 12:32:59 +03:00
Local Dev
8777b1fc56 hermes: in-panel messenger with Theseus ID signin, spread-wings mark
The sidebar panel used to be a launcher that opened the standalone Messages
window; now it IS the messenger — signin screen with "Open with Theseus ID"
(derives the Nostr key from the unlocked vault seed) or "Open an existing
account" (12/24-word mnemonic fallback), then a contacts + thread view with
a narrow-width single-column fallback. The ⧉ button still pops the standalone
window out, so the Ctrl+Shift+E flow keeps working.

- main.js: expose a global._hermesAPI with status/canUseVault/init/inbox/
  send/markThreadRead/contacts* so the addon can proxy panel calls without
  granting it ipcRenderer or crossing the HERMES_ONLY sender gate.
  hermesEmit also fans out on an in-process __hermes_bus so the panel gets
  live inbox/status pushes decoupled from hermesWin's lifetime.
- bundled-addons/hermes/index.js: proxies each allow-listed method onto
  global._hermesAPI, forwards bus events to api.emit for the panel.
- panel.html: signin + app screens, mobile-style single column under 540px.
- Mark updated to the spread-wings variant: envelope sized up (34×22),
  three tapered trails extending outside the viewBox so the wings don't
  bunch at the back of the envelope at any size. Applied to the addon
  icon (manifest base64), the panel header, both /hermes sites, and
  site-hermes-x's favicon + mark SVGs.
2026-10-21 03:00:17 +03:00
Local Dev
227d013013 Theseus 0.3.98: Namecoin + Handshake adapters
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.
2026-10-21 02:40:33 +03:00
Local Dev
6001686f09 hermes: propagate M v2 tapered-trails mark + sky-mid everywhere
Earlier iterations left the nested site/hermes/* on the superseded winged-
helmet design and the Theseus addon on acid-green despite the branding
tokens moving to sky-mid. This brings every surface to the same mark + colour:

- TheseusNavigator/bundled-addons/hermes/addon.json: both icon fields
  (toolbar + panel declared) swap from acid-green helmet to sky-mid
  (#38BDF8) tapered-trails envelope. Picks up on next addon re-copy.
- TheseusNavigator/bundled-addons/hermes/panel.html: inline SVG swapped
  from helmet dome paths to the tilted-envelope + 3 tapered trails. Uses
  currentColor so the panel's own colour token drives it.
- site/hermes/branding/mark.svg + mark-stroke.svg: standard (3 trails) +
  simplified 16-20px (1 trail) variants match site-hermes-x/assets/.
- site/hermes/branding/index.html: six inline mark cells (hero + 5 size
  cells) swapped in bulk.
- site/hermes/index.html: hero mark SVG swapped.

Grep confirms all seven surfaces now carry 'rotate(-22 32 32)' — the
tapered-trails signature. Nothing left on the old helmet.
2026-10-21 02:38:46 +03:00
Local Dev
3985772ba3 Theseus 0.3.97: ENS adapter — .eth names resolve to IPFS/IPNS
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.
2026-10-21 02:20:23 +03:00
Local Dev
4a7667c06e hermes.x: standalone site + sidebar addon side:left + mark v2 (tapered trails)
New site-hermes-x/ — standalone .x site (own nav, own assets, own OG tags),
sibling to site-theseus-x and site-sirius-x. Internal nav stays on hermes.x:
Overview, Messenger (preview + UI mockup), Branding (brand kit). The only
cross-link is 'Get Theseus' pointing at theseus.x where appropriate.

Mark redesigned: tilted winged envelope with three tapered speed-trails on
the back-left (top longest, bottom shortest). Default colour sky #38BDF8 —
swappable via --sky in site-hermes-x/assets/shared.css. Alternate orange
palette documented but not applied by default. Mark propagated to:
  - site-hermes-x/assets/mark.svg + mark-stroke.svg (16-20px variant)
  - site/hermes/{index.html, branding/{index.html, mark.svg, mark-stroke.svg}}
  - TheseusNavigator/bundled-addons/hermes/{addon.json, panel.html}

Theseus addon moves out of the top-right extensions dock and into the
left-strip sidebar: panels[].side = 'left' + registerSidebarPanel({side:'left'}).
Appears alongside Mail/Pithos/Telegram, excluded from rightPanels() so the
extensions dock no longer lists it. Verified via sidebarState() CDP query —
hermes:main is no longer in the right-panels list.

site/hermes/ (the nested silentmode.st/hermes page) also updated to the new
mark for consistency; both the sovereign hermes.x and the silentmode-nested
page now show the same winged envelope.
2026-10-21 02:19:58 +03:00
Local Dev
9450f5ec3a Theseus 0.3.96: home — left column back to grid cells, widened layout
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).
2026-10-21 01:31:21 +03:00
Local Dev
5d34fa18af Theseus 0.3.95: Names & Certificates settings — UI shell for extra resolvers
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.
2026-10-21 01:19:06 +03:00
Local Dev
8eae448dde Hermes: Ermis shortcut (Ctrl+Shift+E), sidebar add-on, vCard import, brand kit
Shortcut: Ctrl+Shift+M -> Ctrl+Shift+E. Chrome owns Ctrl+Shift+M as
'switch profile' and E matches the Greek spelling (Ermis).

Sidebar discoverability: new bundled add-on at bundled-addons/hermes/
registers a left-strip icon + launcher panel. The panel is a thin chrome
(mark + 'Open Messages' + shortcut hint) that forwards clicks through
api.onMessage -> ipcMain.emit('hermes-open-request') -> openHermesWindow.
All real messaging code stays in main.js — add-on is purely for discovery.

Address book: opt-in vCard (.vcf) import. Dialog in the Add Contact modal
lets the user pick a file; main.js parses BEGIN:VCARD blocks for X-BNS-NAME
/ X-NOSTR-NPUB / X-NOSTR-PUBKEY plus .bch names and npubs mentioned in
NOTE fields. Candidates are previewed per-contact with checkboxes; nothing
is added until the user confirms. Non-matching vCards are returned too (so
the user can still add manually) rather than silently dropped. Nothing is
uploaded; parsing is local.

site/hermes: status badge flipped from 'designed - not yet built' to
'MVP - desktop'. New 'What ships today' grid covers threaded chat, send by
name, address book, local history (all live) and mobile + Tor (next /
planned). Hero carries the new Ctrl+Shift+E shortcut and a link to
/hermes/branding.

site/hermes/branding: new page. Mark SVG (winged envelope, two variants
for 16-20px and 24-160px display sizes), palette (reuses Silent Mode
tokens + an amber accent that's distinctly warm-yellow, not Hermes-orange
— so it never collides with Hermès the fashion house), name explanation
(English Hermes / Greek Ermis), voice notes, do/don't table, MPL-2.0
attribution.

Hermes/MOBILE-RECOMMENDATION.md: analysis of three mobile paths (inside
Ariadne / standalone / hybrid). Recommendation is Option 1: ship as a
screen inside Ariadne. Reuses the wallet seed, aligns with the design
doc's 'one seed many purposes' architecture, lowest total cost.
2026-10-21 00:45:25 +03:00
Local Dev
2821453278 Theseus 0.3.94: home — free-drag left area, card sub-descriptions back
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.
2026-10-21 00:27:21 +03:00
Local Dev
a3b20a2446 Hermes MVP: threaded chat UI, contacts, persistent history, --messages flag
Builds on the previous Hermes sessions (NIP-17 crypto + chipnet hermes.bch
+ Theseus Messages window) to turn the flat inbox into something usable.

main.js (hermes block):
  - Persistent inbox per identity at
    <userData>/hermes/<pkHex>/inbox.jsonl (append-only JSONL, replayed on
    init). Read-state at <userData>/hermes/<pkHex>/read.json so unread
    badges survive restarts.
  - Address book at <userData>/hermes/contacts.json: list / add / update /
    remove. hermes-contacts-add resolves .bch name OR npub OR hex pk,
    canonicalises, writes.
  - Reverse-resolve consults contacts first, chain second: a user-curated
    nickname wins over the on-chain np lookup.
  - hermes-send also records the outgoing message to the inbox so thread
    view shows both sides (only when at least one relay accepted).
  - Inbox messages carry direction + peerPkHex + peerName so the renderer
    can group by thread without re-doing the pairing logic.
  - --messages CLI flag opens the panel at launch (first instance via
    whenReady, second-instance via handleLaunch) so the dev harness and
    power users don't need Ctrl+Shift+M.
  - Dev-only auto-init: THESEUS_HERMES_DEV_MNEMONIC env, gated on
    THESEUS_USER_DATA so it refuses to touch a production profile.
  - HERMES_INBOX_LIMIT raised 200 -> 2000 now that history actually sticks.

messages-preload.js:
  - Adds hermes.contacts.{list, add, update, remove} and
    hermes.markThreadRead; status + onMessage/onStatus unchanged.

messages.html:
  - Replaces the flat inbox with a two-column layout: contact list (search
    + unread badges + last-message preview) on the left, selected thread
    on the right with sender bubbles, timestamps, inline Enter-to-send
    compose, remove-contact affordance.
  - .bch suffix stripped from displayed names (TLD is noise in chat UI;
    other TLDs stay as disambiguation).
  - Mark-thread-read fires on open; vault-bind path kept intact.
2026-10-20 23:21:34 +03:00
Local Dev
4e865a6286 Theseus 0.3.93: home — slot area widened to a 3-column grid
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.
2026-10-20 23:04:43 +03:00
Local Dev
092a779a6a Theseus 0.3.92: home — hero returns above a slot column + 3-column card grid
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.
2026-10-13 20:48:20 +02:00
Silent Mode
8ac8b549b9 Theseus 0.3.91: home — hero back, Silent Mode cards, free-drag Your-links
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).
2026-10-12 09:38:09 +02:00