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.
81 lines
3.4 KiB
JavaScript
81 lines
3.4 KiB
JavaScript
// Hermes bundled add-on — thin proxy to the host's panel API.
|
|
//
|
|
// 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.
|
|
//
|
|
// 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.
|
|
const { ipcMain } = require("electron");
|
|
|
|
const PANEL_METHODS = [
|
|
"status", "canUseVault", "close", "init", "inbox", "send",
|
|
"markThreadRead", "contactsList", "contactsAdd", "contactsUpdate",
|
|
"contactsRemove",
|
|
];
|
|
|
|
module.exports = {
|
|
activate(api) {
|
|
api.registerSidebarPanel({
|
|
id: "main",
|
|
title: "Hermes",
|
|
page: "panel.html",
|
|
// 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",
|
|
});
|
|
|
|
// 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.
|
|
api.onMessage("open-messages", () => {
|
|
ipcMain.emit("hermes-open-request");
|
|
return { ok: true };
|
|
});
|
|
|
|
// 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)");
|
|
},
|
|
};
|