2026-10-21 03:00:17 +03:00
|
|
|
// Hermes bundled add-on — thin proxy to the host's panel API.
|
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
|
|
|
//
|
2026-10-21 03:00:17 +03:00
|
|
|
// All the real messaging code (NIP-17 wrap/unwrap, relay subscriptions,
|
|
|
|
|
// persistent inbox, contacts) lives in Theseus main.js. Too much raw network
|
|
|
|
|
// + crypto to run under the add-on sandbox, and the vault seed must never
|
|
|
|
|
// cross the host/add-on boundary.
|
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
|
|
|
//
|
2026-10-21 03:00:17 +03:00
|
|
|
// This file does two things:
|
|
|
|
|
// 1. Register the left-strip sidebar entry (so Hermes is discoverable
|
|
|
|
|
// without pressing Ctrl+Shift+E).
|
|
|
|
|
// 2. Proxy a small, allow-listed set of panel operations between the
|
|
|
|
|
// panel's silentmode.invoke() calls and main.js's `global._hermesAPI`.
|
|
|
|
|
// The panel never sees ipcRenderer — only this named handler surface.
|
|
|
|
|
//
|
|
|
|
|
// Events coming the other way (inbox updates, relay status changes) are
|
|
|
|
|
// fanned out via a shared ipcMain event bus `__hermes_bus`: main.js's
|
|
|
|
|
// hermesBusEmit publishes, this file forwards each payload to the panel.
|
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
|
|
|
const { ipcMain } = require("electron");
|
|
|
|
|
|
2026-10-21 03:00:17 +03:00
|
|
|
const PANEL_METHODS = [
|
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
|
|
|
"status", "canUseVault", "close", "init", "signOut", "getBackup", "hasBackup",
|
2026-10-22 03:46:45 +03:00
|
|
|
"publishCloudBackup", "fetchCloudBackup", "hasCloudBackup", "removeCloudBackup",
|
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
|
|
|
"getProfile", "updateProfile",
|
2026-10-21 17:21:16 +03:00
|
|
|
"getPhone", "setPhone", "clearPhone", "findByPhones",
|
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
|
|
|
"inbox", "send", "markThreadRead",
|
|
|
|
|
"contactsList", "contactsAdd", "contactsUpdate", "contactsRemove",
|
2026-10-21 03:00:17 +03:00
|
|
|
];
|
|
|
|
|
|
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
|
|
|
module.exports = {
|
|
|
|
|
activate(api) {
|
|
|
|
|
api.registerSidebarPanel({
|
|
|
|
|
id: "main",
|
|
|
|
|
title: "Hermes",
|
|
|
|
|
page: "panel.html",
|
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
|
|
|
// Dock on the LEFT strip (alongside mail/pithos/telegram etc.), not
|
|
|
|
|
// the right-hand add-on dock. The host checks `side` on both the
|
|
|
|
|
// manifest's panels[] entry and the registerSidebarPanel call —
|
|
|
|
|
// declaring it in both keeps dormant vs active renders consistent.
|
|
|
|
|
side: "left",
|
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
|
|
|
});
|
2026-10-21 03:00:17 +03:00
|
|
|
|
|
|
|
|
// Legacy launcher behavior: panel.html can still ask to open the
|
|
|
|
|
// standalone Messages window. Kept because Ctrl+Shift+E users have
|
|
|
|
|
// muscle memory, and because a few flows (debug, multi-window)
|
|
|
|
|
// benefit from a free-floating window.
|
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
|
|
|
api.onMessage("open-messages", () => {
|
|
|
|
|
ipcMain.emit("hermes-open-request");
|
|
|
|
|
return { ok: true };
|
|
|
|
|
});
|
2026-10-21 03:00:17 +03:00
|
|
|
|
|
|
|
|
// Panel API proxies. Every method listed in PANEL_METHODS invokes the
|
|
|
|
|
// same-named function on global._hermesAPI. The main.js side defines
|
|
|
|
|
// that object once hermes is initialised; before that, status/canUseVault
|
|
|
|
|
// are the only safe methods and will return a stub-ok.
|
|
|
|
|
for (const name of PANEL_METHODS) {
|
|
|
|
|
api.onMessage(name, async (payload) => {
|
|
|
|
|
const hermes = global._hermesAPI;
|
|
|
|
|
if (!hermes || typeof hermes[name] !== "function") {
|
|
|
|
|
// Host not ready. Treat status/canUseVault as "no identity yet"
|
|
|
|
|
// so the panel can render its signin screen without a toast.
|
|
|
|
|
if (name === "status") return { ok: true, ready: false };
|
|
|
|
|
if (name === "canUseVault") return { ok: true, available: false };
|
|
|
|
|
return { ok: false, error: "hermes host not ready" };
|
|
|
|
|
}
|
|
|
|
|
return await hermes[name](payload);
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Main-side → panel event bus. hermesBusEmit in main.js fires events on
|
|
|
|
|
// ipcMain under __hermes_bus; forward each to the panel via api.emit so
|
|
|
|
|
// panel-side `silentmode.on("hermes-message", cb)` works identically to
|
|
|
|
|
// the ipcRenderer path used by the standalone window.
|
|
|
|
|
const busForward = (channel, payload) => {
|
|
|
|
|
try { api.emit(channel, payload); } catch {}
|
|
|
|
|
};
|
|
|
|
|
ipcMain.on("__hermes_bus", busForward);
|
|
|
|
|
|
|
|
|
|
api.onDeactivate && api.onDeactivate(() => {
|
|
|
|
|
try { ipcMain.off("__hermes_bus", busForward); } catch {}
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
api.log("hermes sidebar panel registered (proxy mode)");
|
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
|
|
|
},
|
|
|
|
|
};
|