theseus/messages-preload.js

44 lines
2 KiB
JavaScript
Raw Normal View History

// Renderer bridge for the Messages panel.
// All hermes-* IPC returns { ok, ... } | { ok: false, err }.
const { contextBridge, ipcRenderer } = require("electron");
contextBridge.exposeInMainWorld("hermes", {
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
// Identity + relay state
status: () => ipcRenderer.invoke("hermes-status"),
canUseVault: () => ipcRenderer.invoke("hermes-can-use-vault"),
init: (mnemonic) => ipcRenderer.invoke("hermes-init", { mnemonic }),
initFromVault: () => ipcRenderer.invoke("hermes-init", { useVault: true }),
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
close: () => ipcRenderer.invoke("hermes-close"),
// Messages
inbox: () => ipcRenderer.invoke("hermes-inbox"),
send: (to, text) => ipcRenderer.invoke("hermes-send", { to, text }),
markThreadRead: (peerPkHex, upToCreatedAt) =>
ipcRenderer.invoke("hermes-thread-mark-read", { peerPkHex, upToCreatedAt }),
// Contacts (address book)
contacts: {
list: () => ipcRenderer.invoke("hermes-contacts-list"),
add: (name, nickname) => ipcRenderer.invoke("hermes-contacts-add", { name, nickname }),
update: (pkHex, patch) => ipcRenderer.invoke("hermes-contacts-update", { pkHex, patch }),
remove: (pkHex) => ipcRenderer.invoke("hermes-contacts-remove", { pkHex }),
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
// Opt-in import: opens an OS file-picker for a .vcf. Returns parsed
// candidates for the renderer to preview; nothing is added without a
// follow-up add() call per contact. Convenience only — the full add
// flow (manual +) is never gated behind this.
importPick: () => ipcRenderer.invoke("hermes-contacts-import-pick"),
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
},
// Pushes: new decrypted message / relay status change.
onMessage: (cb) => {
const wrapped = (_e, msg) => cb(msg);
ipcRenderer.on("hermes-message", wrapped);
return () => ipcRenderer.removeListener("hermes-message", wrapped);
},
onStatus: (cb) => {
const wrapped = (_e, s) => cb(s);
ipcRenderer.on("hermes-status-update", wrapped);
return () => ipcRenderer.removeListener("hermes-status-update", wrapped);
},
});