Created
April 14, 2026 11:18
-
-
Save ekaone/cd657c047eb15b3c06b23d1d7e22d5c6 to your computer and use it in GitHub Desktop.
Package Universe
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <!DOCTYPE html> | |
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>@ekaone package universe</title> | |
| <style> | |
| *{box-sizing:border-box;margin:0;padding:0} | |
| :root{ | |
| --color-background-primary:#ffffff; | |
| --color-background-secondary:#f5f5f3; | |
| --color-background-tertiary:#eeede8; | |
| --color-text-primary:#1a1a18; | |
| --color-text-secondary:#6b6b67; | |
| --color-text-tertiary:#9b9b97; | |
| --color-border-tertiary:rgba(0,0,0,0.1); | |
| --color-border-secondary:rgba(0,0,0,0.18); | |
| --font-mono:'Fira Code','Cascadia Code','JetBrains Mono',monospace; | |
| --border-radius-md:8px; | |
| --border-radius-lg:12px; | |
| } | |
| @media(prefers-color-scheme:dark){ | |
| :root{ | |
| --color-background-primary:#1c1c1a; | |
| --color-background-secondary:#252523; | |
| --color-background-tertiary:#2e2e2b; | |
| --color-text-primary:#f0efe8; | |
| --color-text-secondary:#9b9b97; | |
| --color-text-tertiary:#6b6b67; | |
| --color-border-tertiary:rgba(255,255,255,0.08); | |
| --color-border-secondary:rgba(255,255,255,0.15); | |
| } | |
| } | |
| html,body{height:100%;background:var(--color-background-tertiary);font-family:var(--font-mono)} | |
| body{display:flex;flex-direction:column;align-items:center;justify-content:center;padding:24px;min-height:100vh} | |
| h1{font-size:13px;font-weight:500;color:var(--color-text-secondary);letter-spacing:0.05em;margin-bottom:16px} | |
| #app{width:100%;max-width:860px;border-radius:var(--border-radius-lg);border:0.5px solid var(--color-border-tertiary);background:var(--color-background-primary);overflow:hidden} | |
| #filter-bar{display:flex;gap:6px;padding:10px 14px;flex-wrap:wrap;border-bottom:0.5px solid var(--color-border-tertiary)} | |
| .ftag{font-size:11px;padding:3px 10px;border-radius:12px;cursor:pointer;border:0.5px solid var(--color-border-tertiary);background:var(--color-background-primary);color:var(--color-text-secondary);transition:all .15s;font-family:var(--font-mono)} | |
| .ftag.active{background:var(--color-background-secondary);color:var(--color-text-primary);border-color:var(--color-border-secondary)} | |
| #legend{display:flex;gap:16px;padding:10px 14px;flex-wrap:wrap;border-bottom:0.5px solid var(--color-border-tertiary)} | |
| .leg{display:flex;align-items:center;gap:6px;font-size:11px;color:var(--color-text-secondary)} | |
| .leg-dot{width:8px;height:8px;border-radius:50%;flex-shrink:0} | |
| #universe{width:100%;position:relative;overflow:hidden} | |
| canvas{display:block;width:100%;height:100%} | |
| #tooltip{position:absolute;pointer-events:none;background:var(--color-background-primary);border:0.5px solid var(--color-border-secondary);border-radius:var(--border-radius-md);padding:10px 14px;font-size:12px;opacity:0;transition:opacity .15s;max-width:220px;z-index:10;font-family:var(--font-mono)} | |
| #tooltip .pkg-name{font-size:13px;font-weight:500;color:var(--color-text-primary);margin-bottom:6px} | |
| #tooltip .pkg-desc{color:var(--color-text-secondary);line-height:1.5;margin-bottom:6px} | |
| #tooltip .pkg-tags{display:flex;flex-wrap:wrap;gap:4px} | |
| #tooltip .tag{font-size:10px;padding:2px 6px;border-radius:4px;background:var(--color-background-secondary);color:var(--color-text-secondary)} | |
| #footer{font-size:11px;color:var(--color-text-tertiary);margin-top:12px;text-align:center} | |
| </style> | |
| </head> | |
| <body> | |
| <h1>@ekaone / package universe</h1> | |
| <div id="app"> | |
| <div id="filter-bar"> | |
| <span style="font-size:11px;color:var(--color-text-tertiary);align-self:center;margin-right:4px">filter</span> | |
| <span class="ftag active" data-cat="all">all</span> | |
| <span class="ftag" data-cat="agent">agent</span> | |
| <span class="ftag" data-cat="security">security</span> | |
| <span class="ftag" data-cat="cli">cli</span> | |
| <span class="ftag" data-cat="util">util</span> | |
| <span class="ftag" data-cat="ui">ui</span> | |
| </div> | |
| <div id="legend"> | |
| <span class="leg"><span class="leg-dot" style="background:#5DCAA5"></span>shipped</span> | |
| <span class="leg"><span class="leg-dot" style="background:#EF9F27"></span>active dev</span> | |
| <span class="leg"><span class="leg-dot" style="background:#AFA9EC"></span>planned</span> | |
| <span class="leg" style="margin-left:auto;font-size:11px;color:var(--color-text-tertiary)">hover · drag to pan</span> | |
| </div> | |
| <div id="universe"> | |
| <canvas id="c"></canvas> | |
| <div id="tooltip"> | |
| <div class="pkg-name" id="t-name"></div> | |
| <div class="pkg-desc" id="t-desc"></div> | |
| <div class="pkg-tags" id="t-tags"></div> | |
| </div> | |
| </div> | |
| </div> | |
| <div id="footer">21 packages · prasetia.me</div> | |
| <script> | |
| const PACKAGES = [ | |
| {id:'n-agent',name:'@ekaone/n-agent',desc:'Multi-agent conversation loop. Ping-pong turn rotation, per-agent history, AbortController, human-in-the-loop.',cat:'agent',status:'shipped',deps:['mock-ai'],x:0.35,y:0.22}, | |
| {id:'agent-relay',name:'@ekaone/agent-relay',desc:'Framework-agnostic multi-agent task delegation. In-memory bus, dead-letter queue, LLM coordinator.',cat:'agent',status:'active',deps:['n-agent','hermes'],x:0.55,y:0.3}, | |
| {id:'mock-ai',name:'@ekaone/mock-ai',desc:'DX layer over ai/test. Model factories, fluent builders, scenario presets.',cat:'util',status:'shipped',deps:[],x:0.2,y:0.38}, | |
| {id:'hermes',name:'@ekaone/hermes',desc:'Typed event bus with wildcards, priority, once-listeners, async emit. Zero deps.',cat:'util',status:'shipped',deps:[],x:0.72,y:0.2}, | |
| {id:'json-cli',name:'@ekaone/json-cli',desc:'AI-powered CLI task runner. Multi-intent extraction, --resume, --history, token cost tracking.',cat:'cli',status:'active',deps:[],x:0.8,y:0.45}, | |
| {id:'killx',name:'@ekaone/killx',desc:'Zero-dep cross-platform process tree killer. Dual ESM/CJS, dry-run, CLI.',cat:'cli',status:'shipped',deps:[],x:0.65,y:0.58}, | |
| {id:'repo-intel',name:'@ekaone/repo-intel',desc:'Rust core + TS wrapper. Repo analysis with 4 platform binaries.',cat:'cli',status:'shipped',deps:[],x:0.45,y:0.68}, | |
| {id:'vault',name:'@ekaone/vault',desc:'Encrypted ephemeral in-memory KV. AES-GCM 256-bit, Web Crypto, zero deps.',cat:'security',status:'shipped',deps:[],x:0.2,y:0.62}, | |
| {id:'masker',name:'@ekaone/masker',desc:'Universal data masking. Auto-detects sensitive types.',cat:'security',status:'shipped',deps:['mask-email','mask-card','mask-token','mask-name'],x:0.15,y:0.22}, | |
| {id:'mask-email',name:'@ekaone/mask-email',desc:'Email masking primitive.',cat:'security',status:'shipped',deps:[],x:0.05,y:0.42}, | |
| {id:'mask-card',name:'@ekaone/mask-card',desc:'Credit card masking primitive.',cat:'security',status:'shipped',deps:[],x:0.08,y:0.55}, | |
| {id:'mask-token',name:'@ekaone/mask-token',desc:'Token masking. #1 Google ranking.',cat:'security',status:'shipped',deps:[],x:0.08,y:0.68}, | |
| {id:'mask-name',name:'@ekaone/mask-name',desc:'Name masking with Latin/CJK/Japanese support.',cat:'security',status:'shipped',deps:[],x:0.15,y:0.78}, | |
| {id:'mcp-tools',name:'@ekaone/mcp-tools',desc:'MCP server: mask_email + mask_card as AI-callable tools via stdio.',cat:'util',status:'shipped',deps:['mask-email','mask-card'],x:0.3,y:0.82}, | |
| {id:'prompt-kit',name:'@ekaone/prompt-kit',desc:'Prompt template builder. Zero-dep, hand-rolled YAML frontmatter, strict variable injection.',cat:'util',status:'shipped',deps:[],x:0.55,y:0.12}, | |
| {id:'react-prompt-kit',name:'@ekaone/react-prompt-kit',desc:'React companion. /server + /client subpath exports, usePrompt hook.',cat:'ui',status:'shipped',deps:['prompt-kit'],x:0.7,y:0.08}, | |
| {id:'init',name:'@ekaone/init',desc:'pnpm create scaffolder for Next.js and Vite+React with shadcn.',cat:'cli',status:'shipped',deps:[],x:0.85,y:0.72}, | |
| {id:'rounded',name:'@ekaone/rounded',desc:'Financial rounding. Half Up, Banker\'s, Cash. 153-currency ISO 4217 map.',cat:'util',status:'shipped',deps:[],x:0.88,y:0.28}, | |
| {id:'entropy',name:'@ekaone/entropy',desc:'Shannon entropy primitive. Foundation layer for higher-level packages.',cat:'util',status:'shipped',deps:[],x:0.82,y:0.6}, | |
| {id:'nano-otp',name:'@ekaone/nano-otp',desc:'Zero-dep OTP with Web Crypto and toDataURL for authenticator apps.',cat:'security',status:'shipped',deps:[],x:0.3,y:0.58}, | |
| {id:'use-claude',name:'@ekaone/use-claude',desc:'React hook for Tauri IPC with Claude Code CLI. Callback API.',cat:'ui',status:'shipped',deps:[],x:0.55,y:0.82}, | |
| ]; | |
| const CAT_COLORS={agent:'#7F77DD',security:'#1D9E75',cli:'#EF9F27',util:'#378ADD',ui:'#D4537E'}; | |
| const STATUS_OPACITY={shipped:1,active:0.85,planned:0.55}; | |
| const STATUS_STROKE={shipped:'#5DCAA5',active:'#EF9F27',planned:'#AFA9EC'}; | |
| let W,H,scale,dpr,pan={x:0,y:0},dragging=false,dragStart={x:0,y:0},panStart={x:0,y:0}; | |
| let hoveredId=null,activeFilter='all'; | |
| const canvas=document.getElementById('c'); | |
| const ctx=canvas.getContext('2d'); | |
| const container=document.getElementById('universe'); | |
| const tooltip=document.getElementById('tooltip'); | |
| function isDark(){return window.matchMedia('(prefers-color-scheme:dark)').matches} | |
| function resize(){ | |
| dpr=window.devicePixelRatio||1; | |
| W=container.offsetWidth; | |
| H=Math.round(W*0.62); | |
| container.style.height=H+'px'; | |
| canvas.width=W*dpr;canvas.height=H*dpr; | |
| canvas.style.width=W+'px';canvas.style.height=H+'px'; | |
| ctx.scale(dpr,dpr); | |
| scale=Math.min(W,H); | |
| draw(); | |
| } | |
| function nodePos(pkg){return{x:pkg.x*W+pan.x,y:pkg.y*H+pan.y}} | |
| function nodeRadius(pkg){const base=pkg.deps&&pkg.deps.length>2?14:10;return base*(scale/600)} | |
| function isVisible(pkg){return activeFilter==='all'||pkg.cat===activeFilter} | |
| function draw(){ | |
| ctx.clearRect(0,0,W,H); | |
| const dark=isDark(); | |
| const gridCol=dark?'rgba(255,255,255,0.03)':'rgba(0,0,0,0.03)'; | |
| ctx.strokeStyle=gridCol;ctx.lineWidth=1; | |
| for(let x=0;x<W;x+=40){ctx.beginPath();ctx.moveTo(x,0);ctx.lineTo(x,H);ctx.stroke();} | |
| for(let y=0;y<H;y+=40){ctx.beginPath();ctx.moveTo(0,y);ctx.lineTo(W,y);ctx.stroke();} | |
| PACKAGES.forEach(pkg=>{ | |
| if(!isVisible(pkg))return; | |
| pkg.deps&&pkg.deps.forEach(depId=>{ | |
| const dep=PACKAGES.find(p=>p.id===depId); | |
| if(!dep||!isVisible(dep))return; | |
| const a=nodePos(pkg),b=nodePos(dep); | |
| ctx.beginPath();ctx.moveTo(a.x,a.y);ctx.lineTo(b.x,b.y); | |
| ctx.strokeStyle=dark?'rgba(255,255,255,0.08)':'rgba(0,0,0,0.07)'; | |
| ctx.lineWidth=1;ctx.setLineDash([3,4]);ctx.stroke();ctx.setLineDash([]); | |
| }); | |
| }); | |
| PACKAGES.forEach(pkg=>{ | |
| if(!isVisible(pkg))return; | |
| const{x,y}=nodePos(pkg); | |
| const r=nodeRadius(pkg); | |
| const col=CAT_COLORS[pkg.cat]||'#888'; | |
| const alpha=STATUS_OPACITY[pkg.status]; | |
| const stroke=STATUS_STROKE[pkg.status]; | |
| const hov=hoveredId===pkg.id; | |
| ctx.save(); | |
| ctx.globalAlpha=alpha*(hov?1:0.88); | |
| if(hov){ctx.shadowColor=col;ctx.shadowBlur=12;} | |
| ctx.beginPath();ctx.arc(x,y,r+(hov?2:0),0,Math.PI*2); | |
| ctx.fillStyle=col;ctx.fill(); | |
| ctx.strokeStyle=stroke;ctx.lineWidth=hov?2:1.5;ctx.stroke(); | |
| ctx.shadowBlur=0; | |
| if(hov||r>11){ | |
| ctx.font=`${Math.round(10*(scale/600))}px var(--font-mono)`; | |
| ctx.fillStyle=dark?'rgba(255,255,255,0.7)':'rgba(0,0,0,0.6)'; | |
| ctx.textAlign='center'; | |
| ctx.fillText(pkg.id,x,y+r+12*(scale/600)); | |
| } | |
| ctx.restore(); | |
| }); | |
| } | |
| function getHovered(mx,my){ | |
| for(let i=PACKAGES.length-1;i>=0;i--){ | |
| const pkg=PACKAGES[i]; | |
| if(!isVisible(pkg))continue; | |
| const{x,y}=nodePos(pkg); | |
| if(Math.hypot(mx-x,my-y)<nodeRadius(pkg)+4)return pkg.id; | |
| } | |
| return null; | |
| } | |
| canvas.addEventListener('mousemove',e=>{ | |
| const rect=canvas.getBoundingClientRect(); | |
| const mx=e.clientX-rect.left,my=e.clientY-rect.top; | |
| if(dragging){pan.x=panStart.x+(mx-dragStart.x);pan.y=panStart.y+(my-dragStart.y);draw();return;} | |
| const id=getHovered(mx,my); | |
| if(id!==hoveredId){hoveredId=id;draw();} | |
| if(id){ | |
| const pkg=PACKAGES.find(p=>p.id===id); | |
| const{x,y}=nodePos(pkg); | |
| document.getElementById('t-name').textContent=pkg.name; | |
| document.getElementById('t-desc').textContent=pkg.desc; | |
| const tagsEl=document.getElementById('t-tags'); | |
| tagsEl.innerHTML=`<span class="tag">${pkg.cat}</span><span class="tag">${pkg.status}</span>${pkg.deps&&pkg.deps.length?`<span class="tag">${pkg.deps.length} dep${pkg.deps.length>1?'s':''}</span>`:''}`; | |
| let tx=x+20,ty=y-10; | |
| if(tx+230>W)tx=x-240; | |
| if(ty+120>H)ty=H-120; | |
| tooltip.style.left=tx+'px';tooltip.style.top=ty+'px';tooltip.style.opacity='1'; | |
| canvas.style.cursor='pointer'; | |
| } else { | |
| tooltip.style.opacity='0';canvas.style.cursor='grab'; | |
| } | |
| }); | |
| canvas.addEventListener('mousedown',e=>{ | |
| dragging=true; | |
| const rect=canvas.getBoundingClientRect(); | |
| dragStart={x:e.clientX-rect.left,y:e.clientY-rect.top}; | |
| panStart={x:pan.x,y:pan.y}; | |
| canvas.style.cursor='grabbing'; | |
| }); | |
| window.addEventListener('mouseup',()=>{dragging=false;canvas.style.cursor='grab';}); | |
| canvas.addEventListener('mouseleave',()=>{hoveredId=null;tooltip.style.opacity='0';draw();}); | |
| document.querySelectorAll('.ftag').forEach(btn=>{ | |
| btn.addEventListener('click',()=>{ | |
| document.querySelectorAll('.ftag').forEach(b=>b.classList.remove('active')); | |
| btn.classList.add('active'); | |
| activeFilter=btn.dataset.cat; | |
| hoveredId=null;tooltip.style.opacity='0'; | |
| draw(); | |
| }); | |
| }); | |
| window.addEventListener('resize',resize); | |
| resize(); | |
| </script> | |
| </body> | |
| </html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment