← back to build-pages
ui: /about page explaining build-pages + sitemap + footer link + 3 smoke
e4c31da91892f071b2b1a270495dce70a51f328a · 2026-05-13 19:29:06 -0700 · SteveStudio2
Files touched
M server.jsM test/smoke.js
Diff
commit e4c31da91892f071b2b1a270495dce70a51f328a
Author: SteveStudio2 <stevestudio2@SteveStacStudio.lan>
Date: Wed May 13 19:29:06 2026 -0700
ui: /about page explaining build-pages + sitemap + footer link + 3 smoke
---
server.js | 38 +++++++++++++++++++++++++++++++++++++-
test/smoke.js | 6 ++++++
2 files changed, 43 insertions(+), 1 deletion(-)
diff --git a/server.js b/server.js
index 862731a..76b1477 100644
--- a/server.js
+++ b/server.js
@@ -211,6 +211,8 @@ function shell(title, body, headExtra = '', meta = {}) {
<footer class="bp-ftr">
<span>git is the source of truth — this page is rendered live from <code>git log</code>.</span>
<span class="bp-ftr-sep">·</span>
+ <a href="/about">about</a>
+ <span class="bp-ftr-sep">·</span>
<a href="/api">JSON API</a>
<span class="bp-ftr-sep">·</span>
<a href="/sitemap.xml">sitemap</a>
@@ -264,7 +266,10 @@ app.get('/sitemap.xml', async (_req, res, next) => {
try {
const base = 'https://projects.agentabrams.com';
const today = new Date().toISOString().slice(0, 10);
- const urls = [`<url><loc>${base}/</loc><lastmod>${today}</lastmod><changefreq>daily</changefreq><priority>1.0</priority></url>`];
+ const urls = [
+ `<url><loc>${base}/</loc><lastmod>${today}</lastmod><changefreq>daily</changefreq><priority>1.0</priority></url>`,
+ `<url><loc>${base}/about</loc><lastmod>${today}</lastmod><changefreq>monthly</changefreq><priority>0.6</priority></url>`,
+ ];
for (const slug of Object.keys(PROJECTS)) {
const bundle = await getProjectBundle(slug, PROJECTS[slug]).catch(() => null);
const lastmod = (bundle && bundle.commits[0]) ? bundle.commits[0].dateISO.slice(0, 10) : today;
@@ -1198,6 +1203,37 @@ app.get('/api/projects/:slug', async (req, res, next) => {
} catch (e) { next(e); }
});
+// /about — short explainer for visitors arriving at projects.agentabrams.com.
+app.get('/about', (_req, res) => {
+ res.send(shell('About — build-pages', `
+ <h1>About</h1>
+ <p class="bp-lede">build-pages is a live build journal for every project in Steve Abrams' workshop.</p>
+
+ <p>Every project here is a real git repo. The pages you're reading are rendered live from <code>git log</code>
+ on each refresh — no static export step, no CI build job. New commits appear within seconds of
+ landing locally.</p>
+
+ <h2>What you'll find</h2>
+ <ul>
+ <li><strong>Every commit</strong> — full subject, body, author, date, files touched, diff</li>
+ <li><strong>Search</strong> — across one project (<code>/p/<slug>?q=…</code>) or the whole fleet (<code>/?q=…</code>)</li>
+ <li><strong>Design rationale</strong> — long commit bodies (≥120 chars) are surfaced as "ideas"</li>
+ <li><strong>Sub-agents + skills used</strong> — auto-extracted from commit messages</li>
+ <li><strong>Authors + velocity</strong> — daily commit shape, who pushed what, rolling 24h / 7d counts</li>
+ <li><strong>Exports</strong> — every project ships .csv, .atom, JSON detail at <a href="/api">/api</a></li>
+ </ul>
+
+ <h2>Pattern</h2>
+ <p>git is the source of truth. The site reads a per-repo bundle keyed on HEAD SHA — when HEAD moves,
+ the cache invalidates and the next request rebuilds it. Cold render ~80ms, warm hit ~17ms.</p>
+
+ <p class="bp-meta"><a href="/">← back to all projects</a></p>
+ `, '', {
+ canonical: 'https://projects.agentabrams.com/about',
+ desc: 'build-pages — a live, git-rendered build journal for every project Steve ships.',
+ }));
+});
+
// Branded 404 — every other site in the fleet has one, parity matters.
app.use((req, res) => {
res.status(404).send(shell('Not found — build-pages', `
diff --git a/test/smoke.js b/test/smoke.js
index 7fc052b..f0f4677 100644
--- a/test/smoke.js
+++ b/test/smoke.js
@@ -154,6 +154,12 @@ function check(name, cond, hint = '') {
r = await fetch('/p/nope-not-a-project');
check('unknown project: 404', r.status === 404);
+ // 7b. /about page
+ r = await fetch('/about');
+ check('about: 200', r.status === 200);
+ check('about: build-pages title',/About — build-pages/.test(r.body));
+ check('about: explainer copy', /live build journal/.test(r.body));
+
// 8. robots.txt — public crawlable + sitemap referenced
r = await fetch('/robots.txt');
check('robots: 200', r.status === 200);
← e8b65d2 api: /api/fleet/buckets — daily commit buckets with ISO labe
·
back to build-pages
·
ui: /privacy + /terms boilerplate (no-tracking + as-is) — si 3af9a44 →