theseus-site/plug-ins/index.html
Local Dev 6f5bf7df64 site(ariadne.x, theseus.x): protocol-relative sibling links
The Sirius.X / Theseus.X / Ariadne.X / Hephaestus.X links in the family
topnavs and body copy were written as full https URLs — href="https://sirius.x/".
In Theseus's own browser (where the current page is served over the bns://
scheme) that absolute URL triggers the gateway-fallback path on top of the
current host, producing URLs like bns://theseus.x/bns/sirius.x/ that then
accumulate segments as the user clicks around.

Switched 56 cross-family link hrefs to protocol-relative (href="//sirius.x/"
etc.). Protocol-relative URLs inherit the scheme of the current page, so:
- In Theseus on bns://theseus.x/ the link resolves to bns://sirius.x/ —
  direct BCNR, no gateway rewrite, no URL accumulation.
- On the silentmode.st ICANN mirror it resolves to https://sirius.x/ —
  unchanged from the previous behaviour.
Only the four sibling .X hosts were swapped; silentmode.st, dl.silentmode.st,
code.silentmode.st, navigate.st, and every forge or API URL still carry
their explicit scheme.
2026-10-04 19:18:32 +02:00

287 lines
18 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)}
.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}
/* Mobile hamburger — matches the home-page pattern. */
.topnav .menu{display:none}
@media (max-width:720px){
.topnav{flex-wrap:nowrap;padding:10px 1rem}
.topnav .brand{margin-right:0}
.topnav > a:not(.brand){display:none}
.topnav .menu{display:block;margin-left:auto;position:relative}
.topnav .menu > summary{list-style:none;cursor:pointer;padding:8px 10px;
border-radius:8px;color:var(--mut);display:inline-flex;align-items:center;gap:6px}
.topnav .menu > summary::-webkit-details-marker{display:none}
.topnav .menu > summary svg{width:22px;height:22px;display:block}
.topnav .menu > summary:hover,
.topnav .menu[open] > summary{color:var(--ink);background:var(--panel)}
.topnav .menu .menu-panel{position:absolute;top:calc(100% + 6px);right:0;
background:var(--bg);border:1px solid var(--line);border-radius:12px;
padding:6px;min-width:220px;display:flex;flex-direction:column;gap:2px;
box-shadow:0 10px 32px rgba(0,0,0,.55)}
.topnav .menu .menu-panel a{padding:10px 14px;border-radius:8px;font-size:14.5px;
color:var(--mut);text-decoration:none;display:flex;align-items:center;gap:8px}
.topnav .menu .menu-panel a:hover{color:var(--ink);background:var(--panel)}
}
.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:200px;--tn-h:52px}
body{padding-top:var(--tn-h)}
.sidenav{position:fixed;top:var(--tn-h);left:0;bottom:0;width:var(--sn-w);z-index:15;
background:transparent;padding:56px 12px 22px 18px;
overflow-y:auto;transition:width .15s ease;pointer-events:none}
.sidenav a{display:flex;align-items:center;gap:14px;color:var(--mut);text-decoration:none;
padding:9px 12px;border-radius:10px;
font-size:14.5px;font-weight:500;opacity:.35;pointer-events:auto;
transition:opacity .12s,color .12s,background .12s,backdrop-filter .12s}
.sidenav a .ic{flex:none;width:22px;font-size:18px;line-height:1;text-align:center;
display:none;justify-content:center;align-items:center}
.sidenav a .lb{flex:1;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.sidenav a:hover{opacity:1;color:var(--ink);background:rgba(11,14,20,.72);backdrop-filter:blur(8px)}
.sidenav a.active{opacity:.85;color:var(--acid)}
.sidenav a.active:hover{opacity:1}
@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 .ic{display:inline-flex}
.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;background:rgba(11,14,20,.52);
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;gap:0}
.sidenav a .ic{display:inline-flex}
.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;display:inline-flex;align-items:center;line-height:1}
.ext h3 .icon img{width:26px;height:26px;display:block}
.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 class="here" href="./">Plug-ins</a>
<a href="../extensions/">Extensions</a>
<a href="../dev/">Developers</a>
<a href="//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><span>Sirius<span class="g">.X</span></span></a>
<a class="get" href="../#download">Get Theseus</a>
<details class="menu">
<summary aria-label="Open menu">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" aria-hidden="true"><path d="M4 7h16M4 12h16M4 17h16"/></svg>
</summary>
<div class="menu-panel">
<a href="./">Plug-ins</a>
<a href="../extensions/">Extensions</a>
<a href="../dev/">Developers</a>
<a href="//sirius.x/">Sirius.X</a>
</div>
</details>
</nav>
<aside class="sidenav" aria-label="On this page">
<a href="#aegis-section" title="Aegis wallet" ><span class="ic" aria-hidden="true"><svg viewBox="0 0 32 32" fill="none" width="20" height="20"><polygon points="16,2 28,9 28,23 16,30 4,23 4,9" fill="#0a0a0d" stroke="#D6FF3D" stroke-width="1.6" stroke-linejoin="round"/><circle cx="16" cy="16" r="4.5" fill="none" stroke="#D6FF3D" stroke-width="1.4"/><circle cx="16" cy="16" r="1.6" fill="#D6FF3D"/></svg></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" style="font-size:0;line-height:0"><svg viewBox="0 0 32 32" fill="none" width="26" height="26" style="vertical-align:-6px"><polygon points="16,2 28,9 28,23 16,30 4,23 4,9" fill="#0a0a0d" stroke="#D6FF3D" stroke-width="1.6" stroke-linejoin="round"/><circle cx="16" cy="16" r="4.5" fill="none" stroke="#D6FF3D" stroke-width="1.4"/><circle cx="16" cy="16" r="1.6" fill="#D6FF3D"/></svg></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"><img src="../assets/thread.svg" alt="" aria-hidden="true"></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.
// Uses scroll-position tracking so short sections at the end of the page
// still activate their link when the reader scrolls to them.
(() => {
const links = document.querySelectorAll(".sidenav a[href^='#']");
if (!links.length) return;
const entries = [];
links.forEach((a) => { const el = document.querySelector(a.getAttribute("href")); if (el) entries.push({ el, link: a }); });
if (!entries.length) return;
const setActive = (link) => { links.forEach((l) => l.classList.remove("active")); link.classList.add("active"); };
const update = () => {
const doc = document.documentElement;
const scrollBottom = window.scrollY + window.innerHeight;
if (scrollBottom >= (doc.scrollHeight - 4)) { setActive(entries[entries.length - 1].link); return; }
const line = window.scrollY + window.innerHeight * 0.35;
let active = entries[0].link;
for (const e of entries) {
if (e.el.getBoundingClientRect().top + window.scrollY <= line) active = e.link;
else break;
}
setActive(active);
};
window.addEventListener("scroll", update, { passive: true });
window.addEventListener("resize", update);
update();
})();
</script>
</body>
</html>