Startpage layout reverted to the pre-0.3.131 shape. 0.3.131's full-page-
height sidebar was a mistake — slots in a short strip under a hero at
the top, cards and slots sharing one row of panels at the same height,
is what matches the design. .page/.main-col/.sidebar structure dropped,
hero back as a body sibling of .homepage, slots-list back to repeat(3,
72px) with minSlots=9. Two of the user's own tweaks baked into the
defaults: .section.chromeless on the left column so slot icons float
on the page background instead of sitting in a boxed panel, and
defaultState().iconSize = "large" (60 px tiles).
Game.X in the SM cards (replaces SilentMode.X in its slot, stub
description + a built-in gamepad brand mark until game.x goes live).
SilentMode.X moved to the quick-links strip as the 5th slot. moveItem
now strips the pinned-slot anchor when a q item moves to sm — a link
dragged onto the cards used to flip back on the next render because
its slot number was still set.
Nostr NIP-07 signer grows per-site identities (0.1.0 → 0.1.1). First
approval modal picks between the Hermes identity (one npub for DMs
and public notes, the one published as the np record on your BNS
name) and a site-specific HKDF-derived npub (unique per origin, so
Nostr clients can't cross-correlate your activity). The chooser shows
both npubs so the user sees what each button reveals. Grants without
a stored profileId (migrated from 0.3.131) default to the Hermes
identity so existing approvals keep behaving the same.
lib/hermes.js:nostrKeyFromRootForOrigin HKDFs with info
silentmode/nostr-origin/v1/<origin> over the existing 32-byte
messengerRoot. main.js _nostrAPI methods take {profileId, origin};
signer cache per profile.
Silent Mode Mail retired as an extension — now a Sidebar quicklink
(id: silentmail). Its 0.1.0 panel iframed mail.silentmode.st, which
sends X-Frame-Options: DENY; the browser rendered the block page and
STILL fired the iframe's load event, so the 5 s "did it embed?"
watchdog saw it as loaded and the panel stayed black. The whole
extension was just a landing page with an Open Mail button — exactly
what a sidebar quicklink does, without taking a panel slot or an
Extensions row. migrateAegisRename auto-retires any existing
extensions/mail/ to addons-backups/mail-migrated-<stamp>/ on first
boot of this Theseus; "mail" added to the first-party reserved-ids
list so a community add-on can't claim the id.
Claude connector 0.2.1 → 0.2.2: the bearer token no longer rotates on
every server stop. The old stop() generated a fresh token every time
Theseus quit, the panel toggled off, or a 0.3.X install replaced the
app — the Connect button wrote the new token to ~/.claude.json but
any already-running Claude Code or Claude Desktop process held the
previous token in memory and only re-reads config on launch, so /mcp
reconnect kept sending the stale bearer and the server rejected it
forever. Infinite loop: install Theseus upgrade, click Connect, MCP
still 401, close Claude, open Claude, install another upgrade a day
later, repeat. The explicit Revoke token button still rotates for
users who want fresh keys; everything else is persistent.
Sidebar panel apps blank to about:blank after 2 min of being closed to
free their render tree (iframes, media, listeners). Fast reopen within
the window still reuses the loaded page.
Light theme palette flip under body.light — the full set of
--ink / --mut / --card / --line tokens flip plus hero + card
translucent panels switch to light-glass, so hero titles, SM card
text, slot labels and the ".bch" tld read correctly on the light
background preset instead of as pale ghosts.
12 KiB
Pending — uncommitted Theseus changes
Working-tree state that hasn't been committed or shipped. Read this before touching the same files. Update when you land or add work.
Format: each group has a session: label so parallel sessions can see
what belongs to whom and coordinate. Naming convention:
YYYY-MM-DD:short-slug for date-bounded work, or parallel:<theme> for
work owned by a session that isn't the current one.
Last updated: 2026-10-29 (post-0.3.130 batch).
Releases are no longer recorded here: the live version and hashes are in
../site/releases-manifest.json and https://dl.silentmode.st/releases-manifest.json,
and each release commit is Theseus 0.3.x: ... in git history.
Staged for the next release (post-0.3.131)
-
LANDED: Startpage layout reverted to the pre-0.3.131 default, plus the user's two preferred tweaks baked into the defaults — the slot column is chromeless (floats on the page background, no panel box around it) and default
iconSizeis "large" (60 px tiles). Changes in home.html:- HTML:
<div class="hero">and<div class="homepage">back as body siblings (not nested in a.pagegrid with a sidebar aside)..homepageis the 2-col gridminmax(260, 300) 1fr, hero padded5vh 1rem 0as the top of the page again. - CSS:
.sidebarrenamed back to.left-column,.cards-wrapback to.right-column, the.page+.main-colgrid dropped..section.chromelesskept (brought back) — the left column uses it so slots float on the page background like the user had it; the SM cards keep the soft panel surface. defaultState().iconSizeis"large"(60 px slot tiles) — matches the sizing in the user's screenshot; existing profiles with their owniconSizekeep that choice..slots-list { grid-template-columns: repeat(3, 72px); width: max-content; margin: 0 auto }— fixed-cell 232 px grid, centered in its panel.layoutSlotsback tominSlots = 9(3 × 3 rows, matches the SM cards grid height).minSlotsForFill()and itsResizeObserverare gone..hero .ver-lineCSS + itsbody.lightoverride removed; the<p class="ver-line" id="verLine">markup gone; the init-script block that wiredgetVersion()→navigate("silentmode.st/releases")gone. The user asked for "What's new" to be dropped again after I restored it for 0.3.131;window.home.getVersionexposure in home-preload.js also removed since nothing calls it any more.moveItem()now strips theslotproperty when a q item moves to sm (link → card). Pin-to-slot is q-only, so leaving the anchor on an sm card re-pinned it back to a slot cell on the next revert. This fixes the user-reported "moving a link to card doesn't work" (actually it moved, but the stale slot anchor flipped it back on the next render).
- HTML:
-
Live user state reset. Backed up
%APPDATA%\Theseus\home-cards.jsonto.bak-before-reset, rewrote it to the restored defaults — SM cards list contains Game.X (replacing SilentMode.X in its slot), quicklinks strip holds hello.bch / sia.coin / Pithos.sia / Bergamot.X / SilentMode.X, plus any user-added extras preserved. Preserved:background(indigo preset) andiconSize(large). User must reload the open home tab (Ctrl+R or close/reopen) to pick up the new file. -
LANDED: Claude connector no longer rotates its bearer on every stop (0.2.2). The old
stop()generated a fresh token on every server stop, so a Theseus quit, a panel toggle-off, or even a 0.3.X → 0.3.X+1 install silently invalidated every registered Claude. The Connect button wrote the new token to~/.claude.json, but any already-running Claude Code or Claude Desktop process holds the previous token in memory and only re-reads config on launch, so/mcpreconnect kept sending the stale bearer and the server rejected it. Observed symptom from the connector log: after installing 0.3.131 and clicking Connect,.claude.jsonwas updated (correct new token written at 01:02:53) but the running Claude Code session's MCP calls stayed 401 forever. Fix in bundled-addons/claude-connector/index.js:stop()keeps the stored token; only the panel's "Revoke token" button rotates. Addon version bumped 0.2.1 → 0.2.2 soseedBundledAddonspicks up the fix on the first boot of 0.3.132. -
LANDED: Nostr per-site identities (0.1.1). The 0.3.131 Nostr add-on always signed with Hermes's one
npub, which gives sites a single identity they can correlate across the Nostr network. 0.3.132 adds a per-origin profile picked on first approval:lib/hermes.jsgainsnostrKeyFromRootForOrigin(messengerRoot, origin)— HKDF with infosilentmode/nostr-origin/v1/<origin>over the existing 32-byte messengerRoot, so every site that chooses "site- specific identity" sees a differentnpuband clients can't cross- correlate. Deterministic from the mnemonic, no new vault field needed.- main.js:
_nostrAPImethods take{ profileId, origin }.profileIdis"hermes"or"origin"; the signer cache keys on both. Per-origin secret keys are hot-cached undernostrOriginSkCacheso the async HKDF only runs once per (vault, origin). Backward-compatible: callers that omitprofileIdget the Hermes identity (what 0.3.131 did). - bundled-addons/nostr/index.js: grant
schema gains
profileId. First-time approval modal shows BOTH npubs side-by-side and two Allow buttons ("Use site-specific identity" is primary, "Use my Hermes identity" is the opt-in to the shared key). Subsequent calls reuse the stored profile silently. Pre-upgrade grants (noprofileIdfield) default to"hermes"so existing approvals keep behaving the same. - bundled-addons/nostr/panel.html: each grant row shows which identity the site sees — "Shared Hermes identity" or "Site-specific identity" with the derived npub under it.
- Addon version bumped 0.1.0 → 0.1.1 so
seedBundledAddonsreseeds the fresh-from-0.3.131 copy on the next Theseus start.
Staged for the next release (post-0.3.130)
Queue of asks for the next cut. Items marked LANDED are edited in the working tree waiting for a bump + build. Items marked TODO still need the code change.
- LANDED: Nostr NIP-07 signer — new bundled add-on
bundled-addons/nostr/(0.1.0) plus host support. Putswindow.nostron https + localhost pages so any Nostr client (Primal, Coracle, Snort, nostrudel) can sign with the identity Theseus already holds. Needs a Theseus release: it changesmain.jsand bundles a new add-on, so the extension OTA alone cannot deliver it. MISSED 0.3.130 — the folder is untracked (??in git status), so the detached-HEAD build worktree never saw it. For 0.3.131 the ship script must eithergit addthe folder first orcp -rit into the build worktree the same waybuild/,tor/,snapshots/are copied.- lib/nostr-signer.js — new. Crypto half:
getPublicKey,signEvent(BIP340 via nostr-toolsfinalizeEvent), nip04 + nip44 encrypt/decrypt. Recomputespubkey/idrather than trusting the page. - main.js —
global._nostrAPInext to_hermesAPI. - Identity is Hermes's key (
nostrKeyFromRoot(messengerRoot)); vault with no mnemonic reports no identity instead of failing obscurely. - Policy per-origin (read vs sign), kinds 0/3/5/10002 re-prompt every time with no remember option.
- Tests:
scratchpad/signer-test.mjs,nostr-policy-test.mjs,nostr-e2e.mjs.
- lib/nostr-signer.js — new. Crypto half:
- LANDED: Home — SilentMode.X moved to the quick-links strip, Game.X
takes its place in the Silent Mode cards. home.html
defaultState().sections.smand.q. Game.X entry uses a built-ingamebrand mark (new SVG inBRAND); the real description and favicon will come from the live site once game.x is up (currently a stub). SilentMode.X moves into the slots strip as the 5th quick-link. Still TODO: update the remote cache athttps://dl.silentmode.st/home-cards.jsonso existing profiles pick the swap up without resetting (localsections.smisn't reseeded bymigrateCards— only the remote fetch rewrites it for installed users). - LANDED: Mail is now a Sidebar quicklink, not an extension. The
user flagged two things in one: the Mail add-on's 0.1.0 panel was a
black screen (iframe + XFO: DENY), AND Mail conceptually belongs
under Settings → Sidebar (webapp quicklinks) rather than Settings →
Extensions. Both resolved by dropping the extension form entirely:
settings.quickLinksdefault list in main.js gains{ id: "silentmail", url: "https://mail.silentmode.st/", title: "Silent Mode Mail" }as the first entry.migrateAegisRename()grew a mail retirement block: on first boot of this Theseus, any installedextensions/mail/folder moves toaddons-backups/mail-migrated-<stamp>/. The one-offmail/directory I added underbundled-addons/earlier in this session is removed again (the quicklink + retire is the right path)."mail"added to the first-party reserved-ids list so a community add-on can't claim the id after retirement.- The quicklink does exactly what the old extension's "Open Mail"
button did (new tab at
mail.silentmode.st), without taking a panel slot or an Extensions row.
- LANDED: Left-side sidebar panels free their render tree after idle.
main.js
closeLeftPanel: closed panels used to keep their loaded page (leftPanelLoadedIdkept, webContents warm) forever — great for fast reopen, bad for RAM when the user docks a heavy app-like panel (Hermes, Pithos, mail) once and never comes back. Now a 2-minute idle timer blanks the panel toabout:blankafter close, dropping iframes/media/listeners; reopen inside the window still reuses the loaded page (cancelLeftPanelIdleUnloadon open).LEFT_PANEL_IDLE_MS = 2 * 60 * 1000. Does NOT touch the right-sidesidebarview (webapp tabs — Telegram, X, WhatsApp, AI chat) — those are longer-lived by design; follow-up decision whether to apply the same idle unload there. - LANDED: Startpage light theme palette flip under
body.light. home.html: the existing@media (prefers-color-scheme: light)block only flipped tokens when the OS preferred light. Picking the "light" background preset (body.light, set byapplyBg()) left--inkwhite against a white page, so hero title, SM card titles, slot labels and the ".bch" extension read as pale ghosts. Added a fullbody.light { --ink; --mut; --card; --line; ... }block plus overrides for the hero/card translucent panels (dark-glass → light- glass on light theme so the dark text inside reads), the ctx-menu and modal (white surfaces, dark text). Dark theme untouched.
session: parallel:collision-policy
Owner's focus: BCNR ↔ ICANN name collision handling. Not mine — leave for that session to land or bundle by explicit ask.
- Android / mobile: ../AriadneResolver/mobile/app/AndroidManifest.xml, BchFetcher.java, Bns.java, build.ps1 — mobile-side collision changes.
- Repo-wide:
.gitignoregained a/.keys/line (harmless).
Live state
Shipped hashes live at ../site/releases-manifest.json and
https://dl.silentmode.st/releases-manifest.json. On-chain pointer at
releases.silentmode.bch. See GOTCHAS.md for the release
gotchas.