[object Object]

← back to Stack Map Viewer

stack-map live interconnection viewer

e4565d35fb28a6d8017c6d912ec6b4d9c6350af8 · 2026-09-22 10:18:48 -0700 · steve

Files touched

Diff

commit e4565d35fb28a6d8017c6d912ec6b4d9c6350af8
Author: steve <steve@designerwallcoverings.com>
Date:   Tue Sep 22 10:18:48 2026 -0700

    stack-map live interconnection viewer
---
 .gitignore |   6 +++
 index.html | 159 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 server.js  |  76 +++++++++++++++++++++++++++++
 3 files changed, 241 insertions(+)

diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..3426b46
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,6 @@
+node_modules/
+.env*
+tmp/
+*.log
+.DS_Store
+dist/
diff --git a/index.html b/index.html
new file mode 100644
index 0000000..f0fe56f
--- /dev/null
+++ b/index.html
@@ -0,0 +1,159 @@
+<!doctype html><html><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1">
+<title>Stack Interconnection Map</title>
+<style>
+  :root{--bg:#0f1117;--panel:#12151f;--ink:#eef1f7;--dim:#7d8aa5}
+  *{box-sizing:border-box}
+  html,body{margin:0;background:var(--bg);color:var(--ink);font-family:-apple-system,'Helvetica Neue',Arial,sans-serif}
+  header{display:flex;align-items:baseline;gap:14px;flex-wrap:wrap;padding:14px 20px;border-bottom:1px solid #222a3a}
+  header h1{font-size:20px;margin:0}
+  .sub{color:var(--dim);font-size:13px}
+  .badge{margin-left:auto;font-weight:700;padding:4px 12px;border-radius:20px;font-size:13px}
+  .PASS{background:#14261d;color:#8fe3b4;border:1px solid #2f6a48}
+  .WARN{background:#2e2712;color:#ffd27a;border:1px solid #8a6a2a}
+  .FAIL{background:#2e1c1c;color:#f3b6b6;border:1px solid #8a4a4a}
+  .UNKNOWN{background:#20233a;color:#b9c0ff;border:1px solid #4a5388}
+  #wrap{overflow:auto;padding:8px}
+  svg{display:block}
+  rect.node{cursor:pointer;transition:filter .12s}
+  rect.node:hover{filter:brightness(1.35)}
+  #drawer{position:fixed;top:0;right:-420px;width:400px;height:100%;background:var(--panel);border-left:1px solid #2a3247;
+    transition:right .18s;overflow:auto;padding:18px;box-shadow:-8px 0 30px rgba(0,0,0,.5)}
+  #drawer.open{right:0}
+  #drawer h2{font-size:16px;margin:0 0 4px}
+  #drawer .cnt{color:var(--dim);font-size:12px;margin-bottom:12px}
+  #drawer ul{list-style:none;margin:0;padding:0;font-size:13px}
+  #drawer li{padding:6px 8px;border-radius:6px}
+  #drawer li:nth-child(odd){background:#181c28}
+  #close{float:right;cursor:pointer;color:var(--dim);font-size:20px;line-height:1}
+  .foot{color:var(--dim);font-size:12px;padding:8px 20px}
+</style></head><body>
+<header>
+  <h1>Steve's Stack — Interconnection Map</h1>
+  <span class="sub" id="sub">scanning…</span>
+  <span class="badge UNKNOWN" id="verdict">…</span>
+</header>
+<div id="wrap"><div id="svgbox"></div></div>
+<div class="foot" id="foot"></div>
+<div id="drawer"><span id="close" onclick="document.getElementById('drawer').classList.remove('open')">✕</span>
+  <h2 id="dtitle"></h2><div class="cnt" id="dcnt"></div><ul id="dlist"></ul></div>
+<script>
+const N=(v)=>v==null?'…':v.toLocaleString();
+function box(x,y,w,h,fill,stroke,kind){return `<rect class="node" x="${x}" y="${y}" width="${w}" height="${h}" rx="10" fill="${fill}" stroke="${stroke}"${kind?` data-kind="${kind}"`:''}/>`}
+function txt(x,y,s,fill,size,extra=''){return `<text x="${x}" y="${y}" fill="${fill}" font-size="${size}" ${extra}>${s}</text>`}
+
+function render(d){
+  const s=`<svg width="1680" height="1120" viewBox="0 0 1680 1120" xmlns="http://www.w3.org/2000/svg">
+  <defs>
+   <marker id="arw" markerWidth="10" markerHeight="10" refX="8" refY="3" orient="auto"><path d="M0,0 L8,3 L0,6 Z" fill="#7d8aa5"/></marker>
+   <marker id="arwG" markerWidth="10" markerHeight="10" refX="8" refY="3" orient="auto"><path d="M0,0 L8,3 L0,6 Z" fill="#4fae7a"/></marker>
+   <marker id="arwR" markerWidth="10" markerHeight="10" refX="8" refY="3" orient="auto"><path d="M0,0 L8,3 L0,6 Z" fill="#d98b3a"/></marker>
+  </defs>
+  <rect width="1680" height="1120" fill="#0f1117"/>
+  ${box(60,120,220,66,'#243b53','#4a6c92')}
+  ${txt(170,150,'STEVE','#eef1f7',20,'text-anchor="middle" font-weight="700"')}
+  ${txt(170,172,'/dtd · /officer-yolo · /yolo','#a9b6cc',12,'text-anchor="middle"')}
+
+  ${box(40,240,480,116,'#1c2740','#3f5a86','officers')}
+  ${txt(56,268,`${N(d.officers)} CABINET OFFICERS (vp-*)`,'#9fc4ff',16,'font-weight="700"')}
+  ${txt(56,294,'commerce · marketing · engineering · operations · security · cncp','#c7d2e6',12)}
+  ${txt(56,314,'research · directories · compliance · special-projects · consulting · abramsego','#c7d2e6',12)}
+  ${txt(56,340,'route + final sign-off on gated work — click to list','#6f7d97',11,'font-style="italic"')}
+  <line x1="170" y1="186" x2="230" y2="238" stroke="#7d8aa5" stroke-width="2" marker-end="url(#arw)"/>
+
+  ${box(40,406,480,120,'#1c2740','#3f5a86')}
+  ${txt(56,432,`~${N(d.agents-d.officers)} WORKER AGENTS  (${N(d.agents)} total)`,'#9fc4ff',16,'font-weight="700"')}
+  ${txt(56,456,'vendor stewards · site/build · marketing · directory builders','#c7d2e6',12)}
+  ${txt(56,476,'contrarian · approval-agent · fleet-lifecycle · masterdot · google-merchant','#c7d2e6',12)}
+  ${txt(56,500,'own & supervise; recruit subagents (plan→split→argue→merge)','#6f7d97',11,'font-style="italic"')}
+  <line x1="280" y1="356" x2="280" y2="404" stroke="#7d8aa5" stroke-width="2" marker-end="url(#arw)"/>
+
+  ${box(40,576,480,214,'#182135','#39507a')}
+  ${txt(56,602,`${N(d.skills)} SKILLS (invoked via Skill tool)`,'#9fc4ff',16,'font-weight="700"')}
+  ${box(56,616,200,34,'#20304d','#20304d','canaries')}${txt(66,637,`${N(d.canaries)} canaries / monitors`,'#c7d2e6',12)}
+  ${box(266,616,238,34,'#20304d','#20304d','scrapers')}${txt(276,637,`${N(d.scrapers)} vendor scraper-managers`,'#c7d2e6',12)}
+  ${box(56,658,200,34,'#20304d','#20304d','dots')}${txt(66,679,`${N(d.dots)} terminal dot/color`,'#c7d2e6',12)}
+  ${box(266,658,238,34,'#20304d','#20304d','video')}${txt(276,679,`${N(d.video)} hyperframes / video`,'#c7d2e6',12)}
+  ${txt(56,724,'+ deploy · pricing · settlement gate · storefront builders · research','#c7d2e6',12)}
+  ${txt(56,760,`${N(d.health)} emit data/latest.json health heartbeat`,'#6f7d97',11,'font-style="italic"')}
+  <line x1="280" y1="526" x2="280" y2="574" stroke="#7d8aa5" stroke-width="2" marker-end="url(#arw)"/>
+
+  ${box(600,120,300,120,'#2a2136','#6b4f86')}
+  ${txt(616,146,`${N(d.cronLoaded)} CRON JOBS (launchd)`,'#d6b8ff',16,'font-weight="700"')}
+  ${txt(616,170,`com.steve.* — ${N(d.cronPlists)} plists on disk`,'#cfc3e0',12)}
+  ${txt(616,190,'canaries · drips · refreshes · rollups','#cfc3e0',12)}
+  ${txt(616,214,`${N(d.cronToSkill)} point directly at a skill dir`,'#8f7fb0',11,'font-style="italic"')}
+  <path d="M600,200 C560,210 540,540 524,646" fill="none" stroke="#d98b3a" stroke-width="2.4" marker-end="url(#arwR)"/>
+  ${txt(548,470,`drives (${N(d.cronToSkill)})`,'#d98b3a',12,'font-weight="700" transform="rotate(-82 548 470)"')}
+
+  ${box(600,300,300,96,'#14261d','#2f6a48')}
+  ${txt(616,326,`${N(d.canaries)} canaries + ${N(d.health)} health skills`,'#8fe3b4',15,'font-weight="700"')}
+  ${txt(616,350,'each writes data/latest.json','#bfe6cf',12)}
+  ${txt(616,372,'PASS / WARN / FAIL vocabulary','#5f9c78',11,'font-style="italic"')}
+  <path d="M520,686 C560,540 560,430 598,372" fill="none" stroke="#4fae7a" stroke-width="2.2" marker-end="url(#arwG)"/>
+
+  ${box(600,440,300,80,'#14261d','#3f8a5f')}
+  ${txt(616,470,'fleet-health-rollup','#8fe3b4',15,'font-weight="700"')}
+  ${txt(616,492,'→ single 7am "is anything on fire?" panel','#bfe6cf',12)}
+  <line x1="750" y1="396" x2="750" y2="438" stroke="#4fae7a" stroke-width="2.2" marker-end="url(#arwG)"/>
+  ${box(600,560,300,52,'#0f2016','#2f6a48')}
+  ${txt(750,591,`MORNING PANEL → Steve  [${d.verdict}]`,'#8fe3b4',14,'text-anchor="middle" font-weight="700"')}
+  <line x1="750" y1="520" x2="750" y2="558" stroke="#4fae7a" stroke-width="2.2" marker-end="url(#arwG)"/>
+
+  ${box(600,680,300,150,'#2e1c1c','#8a4a4a','parked')}
+  ${txt(616,708,`${N(d.parked)} PARKED (pending-approval)`,'#f3b6b6',15,'font-weight="700"')}
+  ${txt(616,732,'gated: spend · send-list · publish · DNS','#e6c7c7',12)}
+  ${txt(616,752,'remote push · canonical dw_unified/Shopify','#e6c7c7',12)}
+  ${txt(616,778,`⚠ ${N(d.p24)} > 24h old · ${N(d.p7d)} > 7 days`,'#ff9b6a',12,'font-weight="700"')}
+  ${txt(616,800,'cleared by /ungate · approval-agent — click to list','#a87a7a',11,'font-style="italic"')}
+  <path d="M280,790 C420,880 520,800 598,760" fill="none" stroke="#d98b3a" stroke-width="2.2" marker-end="url(#arwR)"/>
+  ${txt(410,862,'draft gated →','#d98b3a',12,'font-weight="700"')}
+
+  ${box(950,680,290,150,'#14261d','#2f6a48')}
+  ${txt(966,708,`${N(d.ledger)} REVERSIBLE ACTIONS`,'#8fe3b4',15,'font-weight="700"')}
+  ${txt(966,732,'auto-executed (3-question tier):','#bfe6cf',12)}
+  ${txt(966,752,'reversible + no externality + bounded','#bfe6cf',12)}
+  ${txt(966,778,'→ executed-reversible/ledger.jsonl','#bfe6cf',12)}
+  ${txt(966,800,'post-hoc /rollback-runbook','#5f9c78',11,'font-style="italic"')}
+  <line x1="900" y1="770" x2="948" y2="760" stroke="#4fae7a" stroke-width="2" marker-end="url(#arwG)"/>
+
+  ${box(950,120,290,150,'#20233a','#4a5388')}
+  ${txt(966,148,'TERMINAL FLEET (iTerm2)','#b9c0ff',15,'font-weight="700"')}
+  ${txt(966,172,'🟢 working · 🟡 needs direction','#cfd3ee',12)}
+  ${txt(966,192,'🟣 gated · 🟠 paste · 🔵 needs-Steve','#cfd3ee',12)}
+  ${txt(966,212,'🩷 parked','#cfd3ee',12)}
+  ${txt(966,238,`painted by ${N(d.dots)} dot skills + masterdot + router`,'#7f88ad',11,'font-style="italic"')}
+  <path d="M300,585 C620,560 820,360 948,240" fill="none" stroke="#3a4761" stroke-width="1.6" stroke-dasharray="5 4" marker-end="url(#arw)"/>
+
+  ${box(1270,120,370,700,'#12151f','#2a3247')}
+  ${txt(1288,150,'Reading the map','#eef1f7',17,'font-weight="700"')}
+  ${txt(1288,184,'Four control planes tie it together:','#c7d2e6',13)}
+  ${txt(1288,214,'1 · Cron → Skills','#d98b3a',13,'font-weight="700"')}${txt(1300,234,'365 jobs fire skills on a clock.','#c7d2e6',13)}
+  ${txt(1288,264,'2 · Canaries → fleet-health-rollup','#4fae7a',13,'font-weight="700"')}${txt(1300,284,`${N(d.health)} heartbeats fold into one panel.`,'#c7d2e6',13)}
+  ${txt(1288,314,'3 · Officers → Agents → Skills','#9fc4ff',13,'font-weight="700"')}${txt(1300,334,'the cabinet hierarchy does the work.','#c7d2e6',13)}
+  ${txt(1288,364,'4 · Gated → pending-approval','#f3b6b6',13,'font-weight="700"')}${txt(1300,384,'risky pool for Steve; reversible auto-run.','#c7d2e6',13)}
+  <line x1="1288" y1="410" x2="1620" y2="410" stroke="#2a3247"/>
+  ${txt(1288,438,'Streamline signals','#ffd27a',14,'font-weight="700"')}
+  ${txt(1288,464,`• ${N(d.parked)} parked, ${N(d.p24)} >24h — backlog`,'#e6c7c7',13)}
+  ${txt(1288,486,`• ${N(d.skills)} skills — heavy sprawl`,'#e6c7c7',13)}
+  ${txt(1288,508,`• ${N(d.canaries)} canaries + ${N(d.cronLoaded)} cron — dense`,'#e6c7c7',13)}
+  ${txt(1288,530,'• ~130 vendor aliases — collapsible','#e6c7c7',13)}
+  ${txt(1288,552,`• ${N(d.agents)} agents / ${N(d.officers)} officers — deep`,'#e6c7c7',13)}
+  ${txt(1288,596,'Click any bordered node to drill in.','#6f7d97',11,'font-style="italic"')}
+  ${txt(1288,614,`Live scan · updated ${new Date(d.ts).toLocaleTimeString()}`,'#6f7d97',11,'font-style="italic"')}
+  </svg>`;
+  document.getElementById('svgbox').innerHTML=s;
+  document.getElementById('sub').textContent=`${N(d.skills)} skills · ${N(d.agents)} agents · ${N(d.cronLoaded)} cron · ${N(d.parked)} parked · ${N(d.ledger)} reversible actions`;
+  const vb=document.getElementById('verdict'); vb.textContent='fleet: '+d.verdict; vb.className='badge '+d.verdict;
+  document.getElementById('foot').textContent=`Live from ~/.claude · ~/Library/LaunchAgents · yolo-queue — auto-refresh 30s — last scan ${new Date(d.ts).toLocaleTimeString()}`;
+  document.querySelectorAll('rect.node[data-kind]').forEach(r=>r.addEventListener('click',()=>drill(r.dataset.kind)));
+}
+async function drill(kind){
+  const r=await fetch('/api/list?kind='+kind); const j=await r.json();
+  document.getElementById('dtitle').textContent=kind;
+  document.getElementById('dcnt').textContent=j.items.length+' items';
+  document.getElementById('dlist').innerHTML=j.items.map(i=>`<li>${i}</li>`).join('')||'<li>(none)</li>';
+  document.getElementById('drawer').classList.add('open');
+}
+async function refresh(){ try{const r=await fetch('/api/stats'); render(await r.json());}catch(e){document.getElementById('sub').textContent='scan error';} }
+refresh(); setInterval(refresh,30000);
+</script></body></html>
diff --git a/server.js b/server.js
new file mode 100644
index 0000000..df4923b
--- /dev/null
+++ b/server.js
@@ -0,0 +1,76 @@
+#!/usr/bin/env node
+// Stack Interconnection Map — live web viewer
+// Basic-auth admin/DW2024!  ·  live-scans ~/.claude, ~/Library/LaunchAgents, yolo-queue
+const http = require('http');
+const { execSync } = require('child_process');
+const fs = require('fs');
+const os = require('os');
+const path = require('path');
+
+const HOME = os.homedir();
+const SKILLS = path.join(HOME, '.claude/skills');
+const AGENTS = path.join(HOME, '.claude/agents');
+const LA = path.join(HOME, 'Library/LaunchAgents');
+const PENDING = path.join(HOME, '.claude/yolo-queue/pending-approval');
+const LEDGER = path.join(HOME, '.claude/yolo-queue/executed-reversible/ledger.jsonl');
+const AUTH = 'Basic ' + Buffer.from('admin:DW2024!').toString('base64');
+
+const sh = (c) => { try { return execSync(c, { encoding: 'utf8', timeout: 15000 }); } catch { return ''; } };
+const lsdirs = (p, re) => { try { return fs.readdirSync(p, { withFileTypes: true }).filter(d => d.isDirectory() && (!re || re.test(d.name))).map(d => d.name); } catch { return []; } };
+
+let CACHE = null, CACHE_TS = 0;
+function scan() {
+  if (CACHE && Date.now() - CACHE_TS < 20000) return CACHE;
+  const skillDirs = lsdirs(SKILLS);
+  const canaries = skillDirs.filter(n => /canary/.test(n));
+  const scrapers = skillDirs.filter(n => /scraper-manager$/.test(n));
+  const dots = skillDirs.filter(n => /dot|^color$|green|orange|purple|yellow|pink|lightblue/.test(n));
+  const video = skillDirs.filter(n => /hyperframes|video/.test(n));
+  const health = (sh(`ls ${SKILLS}/*/data/latest.json 2>/dev/null | wc -l`).trim() || '0');
+  const agentFiles = (() => { try { return fs.readdirSync(AGENTS).filter(f => f.endsWith('.md')); } catch { return []; } })();
+  const officers = agentFiles.filter(f => f.startsWith('vp-'));
+  const cronLoaded = (sh(`launchctl list 2>/dev/null | grep -c com.steve`).trim() || '0');
+  const cronPlists = (() => { try { return fs.readdirSync(LA).filter(f => /^com\.steve\..*\.plist$/.test(f)); } catch { return []; } })();
+  // cron -> skill edges
+  let cronToSkill = 0;
+  for (const f of cronPlists) { const t = sh(`grep -oE '/skills/[^/< ]+' '${path.join(LA, f)}' 2>/dev/null | head -1`).trim(); if (t) cronToSkill++; }
+  // parked + age buckets
+  let parked = [], p3 = 0, p24 = 0, p7d = 0; const now = Date.now();
+  try { parked = fs.readdirSync(PENDING).filter(f => f.endsWith('.md')); } catch {}
+  for (const f of parked) { try { const m = fs.statSync(path.join(PENDING, f)).mtimeMs; const h = (now - m) / 3.6e6; if (h >= 3) p3++; if (h >= 24) p24++; if (h >= 168) p7d++; } catch {} }
+  const ledger = (sh(`wc -l < ${LEDGER} 2>/dev/null`).trim() || '0');
+  // live fleet-health verdict
+  let verdict = 'UNKNOWN';
+  try { const j = JSON.parse(fs.readFileSync(path.join(SKILLS, 'fleet-health-rollup/data/latest.json'), 'utf8')); verdict = j.verdict || j.status || 'UNKNOWN'; } catch {}
+
+  CACHE = {
+    ts: new Date().toISOString(),
+    skills: skillDirs.length, canaries: canaries.length, scrapers: scrapers.length,
+    dots: dots.length, video: video.length, health: +health,
+    agents: agentFiles.length, officers: officers.length,
+    cronLoaded: +cronLoaded, cronPlists: cronPlists.length, cronToSkill,
+    parked: parked.length, p3, p24, p7d, ledger: +ledger, verdict,
+    _lists: { canaries, scrapers, dots, video, officers: officers.map(f => f.replace('.md', '')), parked }
+  };
+  CACHE_TS = Date.now();
+  return CACHE;
+}
+
+const PAGE = fs.readFileSync(path.join(__dirname, 'index.html'), 'utf8');
+
+const server = http.createServer((req, res) => {
+  if (req.headers.authorization !== AUTH) {
+    res.writeHead(401, { 'WWW-Authenticate': 'Basic realm="stack-map"' }); return res.end('auth required');
+  }
+  const u = new URL(req.url, 'http://x');
+  if (u.pathname === '/api/stats') { res.writeHead(200, { 'content-type': 'application/json' }); return res.end(JSON.stringify(scan())); }
+  if (u.pathname === '/api/list') {
+    const kind = u.searchParams.get('kind'); const s = scan();
+    res.writeHead(200, { 'content-type': 'application/json' });
+    return res.end(JSON.stringify({ kind, items: (s._lists[kind] || []).sort() }));
+  }
+  res.writeHead(200, { 'content-type': 'text/html' }); res.end(PAGE);
+});
+
+const PORT = process.env.PORT || 9768;
+server.listen(PORT, () => console.log(`stack-map viewer → http://127.0.0.1:${PORT}  (admin/DW2024!)`));

(oldest)  ·  back to Stack Map Viewer  ·  auto-data-snapshot: 2026-09-22T10:38:29 (1 data files) — .po c84072e →