2026-08-31 12:29:17 +02:00
|
|
|
<!doctype html>
|
|
|
|
|
<html lang="en">
|
|
|
|
|
<head>
|
|
|
|
|
<meta charset="utf-8">
|
2026-08-31 12:44:03 +02:00
|
|
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
|
|
|
<title>Hephaestus — the forge</title>
|
|
|
|
|
<meta name="description" content="Public code on Hephaestus. Sign in with a Bitcoin Cash wallet to push your own or open private orgs.">
|
2026-08-31 12:29:17 +02:00
|
|
|
<style>
|
2026-08-31 12:44:03 +02:00
|
|
|
:root{
|
|
|
|
|
--bg:#0b0e14; --panel:#141a24; --panel2:#18202c; --line:rgba(255,255,255,.09);
|
|
|
|
|
--ink:#e7eaf1; --mut:#8b98a9; --dim:#5e6678; --acid:#d6ff3d;
|
|
|
|
|
}
|
|
|
|
|
*{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;
|
|
|
|
|
display:flex;flex-direction:column}
|
|
|
|
|
a{color:var(--acid);text-decoration:none}
|
2026-08-31 12:29:17 +02:00
|
|
|
a:hover{text-decoration:underline}
|
2026-08-31 12:44:03 +02:00
|
|
|
.wrap{max-width:820px;margin:0 auto;padding:0 1.2rem;width:100%;flex:1}
|
|
|
|
|
header.hero{text-align:center;padding:5rem 1.2rem 1rem}
|
|
|
|
|
.mark{font-size:56px;line-height:1}
|
|
|
|
|
h1{font-size:clamp(2rem,5.5vw,2.9rem);margin:.4rem 0 .3rem;letter-spacing:-0.01em}
|
|
|
|
|
h1 .g{color:var(--acid)}
|
|
|
|
|
.tag{color:var(--mut);font-size:1.05rem;max-width:600px;margin:0 auto}
|
|
|
|
|
.cta{margin-top:1.8rem;display:flex;gap:10px;justify-content:center;flex-wrap:wrap}
|
|
|
|
|
.btn{display:inline-block;padding:11px 22px;border-radius:10px;font-size:14.5px;font-weight:500;
|
|
|
|
|
border:1px solid var(--line);color:var(--ink);background:transparent;transition:filter .1s,background .1s;text-decoration:none}
|
|
|
|
|
.btn.acid{background:var(--acid);color:#0b0e14;font-weight:600;border-color:var(--acid)}
|
|
|
|
|
.btn:hover{filter:brightness(1.12);background:var(--panel);text-decoration:none}
|
|
|
|
|
.btn.acid:hover{background:var(--acid)}
|
|
|
|
|
section.list{padding:3rem 0 1rem}
|
|
|
|
|
h2{font-size:1.15rem;margin:0 0 .8rem;color:var(--ink);font-weight:500}
|
|
|
|
|
.lede{color:var(--mut);margin:0 0 1.4rem;font-size:14px}
|
|
|
|
|
.repo{display:grid;grid-template-columns:1fr auto;gap:16px;align-items:baseline;
|
|
|
|
|
background:var(--panel);border:1px solid var(--line);border-radius:12px;
|
|
|
|
|
padding:16px 20px;margin-bottom:10px;transition:border-color .1s,background .1s}
|
|
|
|
|
.repo:hover{border-color:var(--acid);background:var(--panel2)}
|
|
|
|
|
.repo .name{font-family:ui-monospace,monospace;font-size:14.5px;color:var(--ink)}
|
|
|
|
|
.repo .name a{color:var(--ink)}
|
|
|
|
|
.repo .name .owner{color:var(--dim)}
|
|
|
|
|
.repo .name .sep{color:var(--dim);margin:0 2px}
|
|
|
|
|
.repo .name .repo-label{color:var(--acid)}
|
|
|
|
|
.repo .desc{color:var(--mut);font-size:13.5px;line-height:1.5;margin:.3rem 0 0;grid-column:1/-1}
|
|
|
|
|
.repo .meta{color:var(--dim);font-size:12px;font-family:ui-monospace,monospace;text-align:right;white-space:nowrap}
|
|
|
|
|
.empty{color:var(--dim);font-size:14px;text-align:center;padding:2rem 1rem;
|
|
|
|
|
background:var(--panel);border:1px dashed var(--line);border-radius:12px}
|
|
|
|
|
.empty a{color:var(--acid)}
|
|
|
|
|
footer{border-top:1px solid var(--line);padding:2.4rem 1.2rem 3.4rem;color:var(--dim);font-size:13px;text-align:center;margin-top:3rem}
|
|
|
|
|
footer a{color:var(--mut)}
|
|
|
|
|
footer a:hover{color:var(--ink)}
|
|
|
|
|
code{background:#0e131b;border:1px solid var(--line);border-radius:5px;padding:1px 6px;font-family:ui-monospace,monospace;font-size:12.5px}
|
2026-08-31 12:29:17 +02:00
|
|
|
</style>
|
|
|
|
|
</head>
|
|
|
|
|
<body>
|
2026-08-31 12:44:03 +02:00
|
|
|
|
|
|
|
|
<div class="wrap">
|
|
|
|
|
|
|
|
|
|
<header class="hero">
|
2026-08-31 12:29:17 +02:00
|
|
|
<div class="mark">⚒️</div>
|
2026-08-31 12:44:03 +02:00
|
|
|
<h1><span class="g">the forge</span></h1>
|
|
|
|
|
<p class="tag">Public code on Hephaestus. Click through to read, or sign in with your wallet to push your own.</p>
|
|
|
|
|
<div class="cta">
|
|
|
|
|
<a class="btn acid" href="https://code.silentmode.st/user/oauth2/hephaestus-wallet">Sign in with wallet</a>
|
|
|
|
|
<a class="btn" href="https://code.silentmode.st/explore/repos">Explore all →</a>
|
|
|
|
|
<a class="btn" href="../">About Hephaestus</a>
|
|
|
|
|
</div>
|
|
|
|
|
</header>
|
|
|
|
|
|
|
|
|
|
<section class="list">
|
|
|
|
|
<h2>Public repositories</h2>
|
|
|
|
|
<p class="lede">Fetched live from Hephaestus. Sign in to see private orgs you belong to.</p>
|
|
|
|
|
|
|
|
|
|
<div id="repos">
|
|
|
|
|
<div class="empty" id="loading">Loading from <code>code.silentmode.st</code>…</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<p class="lede" style="margin-top:1.2rem">
|
|
|
|
|
Clone URL patterns:
|
|
|
|
|
<code>git clone https://code.silentmode.st/<owner>/<repo>.git</code> (HTTPS with a personal token)
|
|
|
|
|
·
|
|
|
|
|
<code>git clone ssh://git@code.silentmode.st:2222/<owner>/<repo>.git</code> (SSH with your registered key)
|
|
|
|
|
</p>
|
|
|
|
|
</section>
|
|
|
|
|
|
2026-08-31 12:29:17 +02:00
|
|
|
</div>
|
2026-08-31 12:44:03 +02:00
|
|
|
|
|
|
|
|
<footer>
|
|
|
|
|
A tool from <a href="https://silentmode.st/">Silent Mode</a> · alpha on chipnet · <a href="../">hephaestus.x</a>
|
|
|
|
|
</footer>
|
|
|
|
|
|
|
|
|
|
<script type="module">
|
|
|
|
|
const API = "https://code.silentmode.st/api/v1/repos/search?limit=50&private=false&sort=updated&order=desc";
|
|
|
|
|
const container = document.getElementById("repos");
|
|
|
|
|
|
|
|
|
|
function escapeHtml(s) {
|
|
|
|
|
return String(s ?? "").replace(/[&<>"']/g, c =>
|
|
|
|
|
({"&":"&","<":"<",">":">",'"':""","'":"'"}[c]));
|
|
|
|
|
}
|
|
|
|
|
function fmtDate(iso) {
|
|
|
|
|
if (!iso) return "";
|
|
|
|
|
const d = new Date(iso);
|
|
|
|
|
return isNaN(d) ? "" : d.toISOString().slice(0, 10);
|
|
|
|
|
}
|
|
|
|
|
function renderRepo(r) {
|
|
|
|
|
const owner = escapeHtml(r.owner?.login || "?");
|
|
|
|
|
const name = escapeHtml(r.name);
|
|
|
|
|
const desc = escapeHtml(r.description || "");
|
|
|
|
|
const updated = fmtDate(r.updated_at);
|
|
|
|
|
const stars = r.stars_count ?? 0;
|
|
|
|
|
return `
|
|
|
|
|
<a class="repo" href="https://code.silentmode.st/${owner}/${name}">
|
|
|
|
|
<div class="name">
|
|
|
|
|
<span class="owner">${owner}</span><span class="sep">/</span><span class="repo-label">${name}</span>
|
|
|
|
|
${desc ? `<div class="desc">${desc}</div>` : ""}
|
|
|
|
|
</div>
|
|
|
|
|
<div class="meta">
|
|
|
|
|
${updated ? `updated ${updated}` : ""}${stars ? ` · ★ ${stars}` : ""}
|
|
|
|
|
</div>
|
|
|
|
|
</a>`;
|
|
|
|
|
}
|
|
|
|
|
try {
|
|
|
|
|
const res = await fetch(API);
|
|
|
|
|
if (!res.ok) throw new Error(`HTTP ${res.status}`);
|
|
|
|
|
const body = await res.json();
|
|
|
|
|
const list = body.data || [];
|
|
|
|
|
if (!list.length) {
|
|
|
|
|
container.innerHTML = `<div class="empty">
|
|
|
|
|
No public repos yet. <a href="https://code.silentmode.st/user/oauth2/hephaestus-wallet">Sign in</a> to push the first one.
|
|
|
|
|
</div>`;
|
|
|
|
|
} else {
|
|
|
|
|
container.innerHTML = list.map(renderRepo).join("");
|
|
|
|
|
}
|
|
|
|
|
} catch (e) {
|
|
|
|
|
container.innerHTML = `<div class="empty">
|
|
|
|
|
Couldn't reach the forge API right now (${escapeHtml(e.message)}).<br>
|
|
|
|
|
Try <a href="https://code.silentmode.st/explore/repos">browsing directly at code.silentmode.st</a>.
|
|
|
|
|
</div>`;
|
|
|
|
|
}
|
|
|
|
|
</script>
|
2026-08-31 12:29:17 +02:00
|
|
|
</body>
|
|
|
|
|
</html>
|