theseus-site/plug-ins/index.html
Local Dev 7d12f97d39 site-theseus-x: full-width topnav, Sirius.X tab icon
Sidebar was drawing above the topnav border line — the sticky topnav
only spanned the content column, so where the sidebar met it a T-shape
break was visible. Topnav is now position:fixed spanning the full page
width, and the sidebar is anchored to var(--tn-h)=52px so it sits
cleanly below the topnav border on all breakpoints.

Also: the sirius.x tab is now capitalised Sirius.X and carries its own
brand mark (the 4-point sparkle from sirius.x's own favicon) so the
tabs read as three named things — Home, Plug-ins, Extensions, Sirius.X
— not one lowercase outlier. A shared .topnav a .g rule paints the .X
suffix acid green.
2026-09-20 16:17:08 +02:00

245 lines
15 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>theseus.x — Plug-ins</title>
<meta name="description" content="Silent Mode's first-party plug-ins for Theseus Navigator: the Aegis wallet and the Ariadne's Thread system-wide resolver. Current signed versions, hashes, and how they update.">
<link rel="icon" href="/assets/favicon.svg" type="image/svg+xml">
<link rel="mask-icon" href="/assets/favicon.svg" color="#d6ff3d">
<meta property="og:type" content="website">
<meta property="og:site_name" content="theseus.x">
<meta property="og:title" content="theseus.x — Plug-ins">
<meta property="og:description" content="First-party plug-ins for Theseus: Aegis wallet and Ariadne's Thread. Signed, verified on the device.">
<meta property="og:url" content="https://theseus.x/plug-ins/">
<style>
:root{
--bg:#0b0e14; --panel:#141a24; --panel2:#18202c; --line:rgba(255,255,255,.09);
--ink:#e7eaf1; --mut:#8b98a9; --dim:#5e6678; --acid:#d6ff3d; --ok:#4fd1a5;
}
*{box-sizing:border-box}
body{margin:0;background:radial-gradient(1100px 560px at 50% -12%,#16202e,var(--bg));
color:var(--ink);font:16px/1.65 system-ui,-apple-system,Segoe UI,Roboto,sans-serif;min-height:100vh}
a{color:var(--acid)}
.wrap{max-width:900px;margin:0 auto;padding:0 1.2rem}
.topnav{position:fixed;top:0;left:0;right:0;z-index:20;display:flex;gap:2px;align-items:center;flex-wrap:wrap;
padding:10px 1.2rem;background:rgba(11,14,20,.88);backdrop-filter:blur(10px);border-bottom:1px solid var(--line)}
.topnav .brand{font-weight:600;color:var(--ink);text-decoration:none;margin-right:14px;font-size:15px;letter-spacing:.2px;display:flex;align-items:center;gap:8px}
.topnav .brand .g{color:var(--acid)}
.topnav .brand svg{width:20px;height:20px}
.topnav a{color:var(--mut);text-decoration:none;padding:6px 12px;border-radius:8px;font-size:14px;
display:inline-flex;align-items:center;gap:6px}
.topnav a:hover{color:var(--ink);background:var(--panel)}
.topnav a.here{color:var(--acid);background:rgba(214,255,61,.08)}
.topnav a .g{color:var(--acid)}
.topnav a svg.tabicon{width:15px;height:15px;flex:none}
.topnav a.get{margin-left:auto;background:rgba(214,255,61,.10);color:var(--acid);font-weight:500}
.topnav a.get:hover{background:rgba(214,255,61,.18)}
/* Adaptive edge nav: full-width panel at left edge on wide,
icon rail on medium, bottom bar with icons on mobile. */
:root{--sn-w:220px;--tn-h:52px}
body{padding-left:var(--sn-w);padding-top:var(--tn-h)}
.sidenav{position:fixed;top:var(--tn-h);left:0;bottom:0;width:var(--sn-w);z-index:15;
background:rgba(11,14,20,.82);backdrop-filter:blur(10px);
border-right:1px solid var(--line);padding:22px 14px 22px 18px;
overflow-y:auto;transition:width .15s ease}
.sidenav .lbl{color:var(--dim);font:600 10.5px/1 system-ui;letter-spacing:.24em;text-transform:uppercase;
margin:0 0 14px 4px}
.sidenav a{display:flex;align-items:center;gap:14px;color:var(--mut);text-decoration:none;
padding:11px 12px;border-radius:10px;border-left:3px solid transparent;margin-left:-3px;
font-size:14.5px;font-weight:500;transition:color .1s,background .1s,border-color .1s}
.sidenav a .ic{flex:none;width:22px;font-size:18px;line-height:1;text-align:center;
display:inline-flex;justify-content:center;align-items:center}
.sidenav a .lb{flex:1;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.sidenav a:hover{color:var(--ink);background:var(--panel)}
.sidenav a.active{color:var(--acid);border-left-color:var(--acid);background:rgba(214,255,61,.07)}
@media (max-width:1180px){
:root{--sn-w:64px}
.sidenav{padding:22px 6px}
.sidenav .lbl{display:none}
.sidenav a{justify-content:center;padding:12px 4px;gap:0}
.sidenav a .lb{display:none}
}
@media (max-width:720px){
:root{--sn-w:0px}
body{padding-left:0;padding-bottom:64px}
.sidenav{top:auto;bottom:0;left:0;right:0;width:100%;height:auto;
padding:4px 4px;flex-direction:row;border-right:none;border-top:1px solid var(--line);
display:flex;justify-content:space-around;overflow-x:auto}
.sidenav .lbl{display:none}
.sidenav a{flex:1;min-width:56px;padding:10px 6px;justify-content:center;border-left:none;
border-top:3px solid transparent;margin-left:0;margin-top:-3px;gap:0}
.sidenav a.active{border-left-color:transparent;border-top-color:var(--acid)}
.sidenav a .lb{display:none}
}
header.hero{text-align:center;padding:3.5rem 1.2rem 1rem}
h1{font-size:clamp(1.8rem,4.5vw,2.4rem);margin:.6rem 0 .3rem;letter-spacing:-.3px}
h1 .g{color:var(--acid)}
.tag{color:var(--mut);font-size:1.02rem;max-width:640px;margin:0 auto}
section{padding:2rem 0;border-top:1px solid var(--line);margin-top:1.6rem;scroll-margin-top:72px}
section:first-of-type{border-top:none;margin-top:1rem}
h2{font-size:1.35rem;margin:0 0 .5rem}
.lede{color:var(--mut);margin:0 0 1.2rem;max-width:720px}
code{background:#0e131b;border:1px solid var(--line);border-radius:6px;padding:1px 6px;font-family:ui-monospace,monospace;font-size:13px}
.ext{background:var(--panel);border:1px solid var(--line);border-radius:14px;padding:20px 22px;margin:1rem 0}
.ext h3{margin:0 0 .3rem;font-size:1.15rem;display:flex;align-items:center;gap:10px;flex-wrap:wrap}
.ext h3 .icon{font-size:1.4rem}
.ext .cur{color:var(--acid);font-size:12px;font-weight:600;letter-spacing:.14em;text-transform:uppercase}
.ext .desc{color:var(--mut);font-size:14px;margin:.3rem 0 .8rem}
.ext .verifybox{margin-top:.9rem;padding-top:.8rem;border-top:1px solid var(--line);font-size:11.5px;color:var(--dim)}
.ext .verifybox .lbl{color:var(--mut);font-size:12px;margin-bottom:6px}
.ext .h{display:flex;gap:8px;flex-wrap:wrap;align-items:baseline;margin-top:4px}
.ext .h b{color:var(--mut);font-weight:600;min-width:90px}
.ext .h code{font-family:ui-monospace,monospace;font-size:10.5px;color:#c9d4e3;word-break:break-all;background:transparent;border:none;padding:0}
.ext .meta{color:var(--dim);font-size:12.5px;margin-top:.4rem}
.btns{display:flex;gap:8px;flex-wrap:wrap;margin-top:.8rem}
.btn{display:inline-block;padding:.45rem .9rem;border-radius:9px;background:var(--acid);color:#0b0e14;font-weight:650;text-decoration:none;font-size:14px}
.btn.ghost{background:transparent;color:var(--ink);border:1px solid var(--line)}
.note{background:var(--panel);border:1px solid var(--line);border-left:3px solid var(--acid);border-radius:10px;padding:14px 18px;color:var(--mut);font-size:14px;margin:1.4rem 0}
.note b{color:var(--ink)}
footer{color:var(--dim);font-size:12.5px;margin:3rem 0 2rem;text-align:center}
footer a{color:var(--mut)}
</style>
</head>
<body>
<nav class="topnav">
<a class="brand" href="/">
<svg viewBox="0 0 64 64" aria-hidden="true">
<rect width="64" height="64" rx="12" fill="#0b0e14"/>
<path d="M32 6 L38 32 L26 32 Z" fill="#e04e4e"/>
<path d="M38 32 L32 58 L26 32 Z" fill="#d6ff3d"/>
<path d="M6 32 L32 27 L58 32 L32 37 Z" fill="#d6ff3d" opacity=".55"/>
<circle cx="32" cy="32" r="3" fill="#0b0e14"/>
</svg>
<span>Theseus<span class="g">.X</span></span>
</a>
<a href="/">Home</a>
<a class="here" href="./">Plug-ins</a>
<a href="/extensions/">Extensions</a>
<a href="https://sirius.x/" title="Register a BCNR name"><svg class="tabicon" viewBox="0 0 64 64" aria-hidden="true"><rect width="64" height="64" rx="12" fill="#0b0e14"/><path d="M32 4 L36.4 27.6 L60 32 L36.4 36.4 L32 60 L27.6 36.4 L4 32 L27.6 27.6 Z" fill="#d6ff3d"/></svg>Sirius<span class="g">.X</span></a>
<a class="get" href="/#download">Get Theseus</a>
</nav>
<aside class="sidenav" aria-label="On this page">
<div class="lbl">On this page</div>
<a href="#aegis-section" title="Aegis wallet" ><span class="ic" aria-hidden="true">🛡</span><span class="lb">Aegis wallet</span></a>
<a href="#ariadne-section" title="Ariadne's Thread" ><span class="ic" aria-hidden="true">🧵</span><span class="lb">Ariadne's Thread</span></a>
<a href="#line" title="Plug-ins vs extensions"><span class="ic" aria-hidden="true">🧩</span><span class="lb">Plug-ins vs extensions</span></a>
</aside>
<header class="hero">
<h1>Theseus <span class="g">Plug-ins</span></h1>
<p class="tag">Silent Mode's own components that ship inside Theseus and appear under
<b>Settings › Plug-ins</b>: the wallet and the system-wide resolver. Community-made
add-ons live on the separate <a href="/extensions/">Extensions</a> page.</p>
</header>
<div class="wrap">
<section id="aegis-section">
<h2>Aegis — the wallet</h2>
<p class="lede">Multi-chain wallet derived from your Theseus vault (BCH, BTC, TRX, ETH, SOL, SC, DGB) with a
dApp bridge for the pages you visit. Bundled with every Theseus build and updated over a signed channel
between releases; the panel's own <i>Stage → Restart</i> flow applies an update without reinstalling Theseus.</p>
<div class="ext" id="aegis" data-channel="../extensions/aegis/updates.json">
<h3><span class="icon">🛡️</span> Aegis <span class="cur" style="margin-left:auto">current <span data-live="version">0.6.31</span></span></h3>
<div class="desc">Vault-derived keys, per-chain accounts, imported keys, message signing, dApp permissions per site.</div>
<div class="meta">Plug-in · Settings › Plug-ins · <span data-live="count">signed versions on the channel</span></div>
<div class="verifybox">
<div class="lbl">Signed update manifest — Ed25519 by the Silent Mode operator, SHA-256 verified before install</div>
<div class="h"><b>updates.json</b><code><a href="../extensions/aegis/updates.json">theseus.x/extensions/aegis/updates.json</a></code></div>
<div class="h"><b>Tarball</b><code><a data-live="url" href="../extensions/aegis/">…</a></code></div>
<div class="h"><b>sha256</b><code data-live="sha256">—</code></div>
</div>
</div>
</section>
<section id="ariadne-section">
<h2>Ariadne's Thread — the system-wide resolver</h2>
<p class="lede">Makes BCDN names resolve for <em>every</em> program on the machine, not only Theseus: a local
DNS resolver plus gateway, installed by Theseus's setup by default (opt-out) and switchable from
<b>Settings › Plug-ins</b>. The same resolver ships standalone for Windows and as Ariadne for Android.</p>
<div class="ext" id="ariadne">
<h3><span class="icon">🧵</span> Ariadne's Thread <span class="cur" style="margin-left:auto">current <span data-live="resolver-version">0.1.3</span></span></h3>
<div class="desc">Windows service: answers A/AAAA for registered names, forwards everything else to your upstream
resolver, serves Sia-hosted content through a local gateway with a machine-local CA. Answers MX/TXT/NS from
owner-signed DNS records.</div>
<div class="meta">Plug-in · Settings › Plug-ins · Turn on / off · Install / Update / Uninstall from inside Theseus</div>
<div class="btns">
<a class="btn" href="https://dl.silentmode.st/latest/AriadneResolver-Setup.exe">Windows installer</a>
<a class="btn ghost" href="https://dl.silentmode.st/latest/ariadne.apk">Ariadne for Android (APK) · v<span data-live="android-version">0.19</span></a>
</div>
<div class="verifybox">
<div class="lbl">Hashes from the releases manifest — verify before running</div>
<div class="h"><b>Installer</b><code data-live="resolver-sha">—</code></div>
<div class="h"><b>APK</b><code data-live="android-sha">—</code></div>
<div class="h"><b>Manifest</b><code><a href="https://dl.silentmode.st/releases-manifest.json">dl.silentmode.st/releases-manifest.json</a></code></div>
</div>
</div>
</section>
<section id="line">
<h2>Where the line is</h2>
<p class="lede">Plug-ins are first-party: Silent Mode builds them, signs them with the operator key, and Theseus treats
them as part of itself (own Settings section, own update flow). Extensions are everyone else's: published by
any BCDN name holder, signed with that name's wallet, listed on <a href="/extensions/">theseus.x/extensions</a>
and installed from <b>Settings › Extensions</b>. Both are verified on your device before a byte runs.</p>
<div class="note"><b>Want to build one?</b> Start on the <a href="/extensions/#build">Extensions page</a> — the same add-on
format powers both, and publishing takes a name and a signature, nothing else.</div>
</section>
<footer>
Silent Mode · <a href="https://code.silentmode.st/silentmode/theseus/src/branch/master/TheseusNavigator/docs/ADDON-UPDATES.md">how signed updates work</a>
</footer>
</div>
<script>
(async () => {
const set = (k, f) => document.querySelectorAll('[data-live="' + k + '"]').forEach(f);
const cmp = (a, b) => { const x = String(a).split(".").map(Number), y = String(b).split(".").map(Number); for (let i = 0; i < Math.max(x.length, y.length); i++) { const d = (x[i] || 0) - (y[i] || 0); if (d) return d; } return 0; };
try {
const r = await fetch("../extensions/aegis/updates.json", { cache: "no-store" });
if (r.ok) {
const m = await r.json(); const list = (m.addons || []).slice().sort((x, y) => cmp(y.version, x.version)); const top = list[0];
if (top) {
set("version", (el) => { el.textContent = top.version; });
set("sha256", (el) => { el.textContent = top.sha256 || "—"; });
set("url", (el) => { el.href = top.url; el.textContent = String(top.url).split("/").pop(); });
set("count", (el) => { el.textContent = list.length + " signed version" + (list.length === 1 ? "" : "s") + " on the channel"; });
}
}
} catch {}
try {
const r = await fetch("https://dl.silentmode.st/releases-manifest.json", { cache: "no-store" });
if (r.ok) {
const m = await r.json(); const g = (id) => (m.releases || []).find((x) => x.id === id);
const res = g("ariadne-resolver"), an = g("ariadne-android");
if (res) { set("resolver-version", (el) => { el.textContent = res.version; }); const f = Object.keys(res.files || {})[0]; set("resolver-sha", (el) => { el.textContent = f ? res.files[f] : "—"; }); }
if (an) { set("android-version", (el) => { el.textContent = an.version; }); const f = Object.keys(an.files || {})[0]; set("android-sha", (el) => { el.textContent = f ? an.files[f] : "—"; }); }
}
} catch {}
})();
// Sidenav scroll-spy: highlight the section currently in view.
(() => {
const links = document.querySelectorAll(".sidenav a[href^='#']");
if (!links.length) return;
const map = new Map();
links.forEach((a) => { const el = document.querySelector(a.getAttribute("href")); if (el) map.set(el, a); });
const io = new IntersectionObserver((entries) => {
entries.forEach((en) => {
if (!en.isIntersecting) return;
const a = map.get(en.target); if (!a) return;
links.forEach((l) => l.classList.remove("active"));
a.classList.add("active");
});
}, { rootMargin: "-40% 0px -55% 0px", threshold: 0 });
map.forEach((_, el) => io.observe(el));
})();
</script>
</body>
</html>