Files
nntrivi2001 57dc91585d feat: Claude Code Monitor — lanes, pipelines and a merged workspace
Internal SmartGift build of a Claude Code monitoring dashboard.

Lanes: a durable unit of parallel agent work, one per working directory,
tracked across session restarts. Managed lanes are git worktrees the
dashboard provisions and can reset or remove behind a three-check destroy
guard and a counted preflight; adopted lanes are directories you already
own and are never destroyable.

Pipelines: a lane moves through pipeline stages. A stage the agent declares
with evidence renders green; a stage inferred from the tool-event stream
renders dashed amber and never counts as done. Detection is forward-only
within a 30-minute window, and never writes the declared stage.

Workspace: one page at /run with a lane grid, the selected lane's pipeline,
and a full Claude console behind a disclosure.
2026-07-30 14:39:03 +07:00

123 lines
6.4 KiB
XML

<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1200 630" width="1200" height="630">
<defs>
<linearGradient id="bgGrad" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" stop-color="#0d0d16"/>
<stop offset="100%" stop-color="#12121e"/>
</linearGradient>
<linearGradient id="hexGrad" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" stop-color="#6366f1"/>
<stop offset="100%" stop-color="#818cf8"/>
</linearGradient>
<linearGradient id="nodeGrad" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" stop-color="#a5b4fc" stop-opacity="0.9"/>
<stop offset="100%" stop-color="#c7d2fe" stop-opacity="0.6"/>
</linearGradient>
<linearGradient id="titleGrad" x1="0%" y1="0%" x2="100%" y2="0%">
<stop offset="0%" stop-color="#e2e2f0"/>
<stop offset="55%" stop-color="#a5b4fc"/>
<stop offset="100%" stop-color="#818cf8"/>
</linearGradient>
<radialGradient id="glow1" cx="50%" cy="50%" r="50%">
<stop offset="0%" stop-color="#6366f1" stop-opacity="0.18"/>
<stop offset="100%" stop-color="#6366f1" stop-opacity="0"/>
</radialGradient>
<radialGradient id="glow2" cx="50%" cy="50%" r="50%">
<stop offset="0%" stop-color="#10b981" stop-opacity="0.10"/>
<stop offset="100%" stop-color="#10b981" stop-opacity="0"/>
</radialGradient>
<filter id="blur1">
<feGaussianBlur stdDeviation="40"/>
</filter>
</defs>
<!-- Background -->
<rect width="1200" height="630" fill="url(#bgGrad)"/>
<!-- Ambient glow blobs -->
<ellipse cx="200" cy="200" rx="340" ry="280" fill="url(#glow1)" filter="url(#blur1)"/>
<ellipse cx="1050" cy="480" rx="280" ry="220" fill="url(#glow2)" filter="url(#blur1)"/>
<!-- Grid dots (subtle background texture) -->
<g opacity="0.07" fill="#6366f1">
<circle cx="80" cy="80" r="1.5"/><circle cx="160" cy="80" r="1.5"/><circle cx="240" cy="80" r="1.5"/><circle cx="320" cy="80" r="1.5"/>
<circle cx="80" cy="160" r="1.5"/><circle cx="160" cy="160" r="1.5"/><circle cx="240" cy="160" r="1.5"/><circle cx="320" cy="160" r="1.5"/>
<circle cx="80" cy="240" r="1.5"/><circle cx="160" cy="240" r="1.5"/><circle cx="240" cy="240" r="1.5"/><circle cx="320" cy="240" r="1.5"/>
<circle cx="900" cy="400" r="1.5"/><circle cx="980" cy="400" r="1.5"/><circle cx="1060" cy="400" r="1.5"/><circle cx="1140" cy="400" r="1.5"/>
<circle cx="900" cy="480" r="1.5"/><circle cx="980" cy="480" r="1.5"/><circle cx="1060" cy="480" r="1.5"/><circle cx="1140" cy="480" r="1.5"/>
<circle cx="900" cy="560" r="1.5"/><circle cx="980" cy="560" r="1.5"/><circle cx="1060" cy="560" r="1.5"/><circle cx="1140" cy="560" r="1.5"/>
</g>
<!-- Large background hex (decorative) -->
<polygon points="980,120 1120,200 1120,360 980,440 840,360 840,200"
fill="none" stroke="#6366f1" stroke-width="1" opacity="0.12"/>
<polygon points="980,150 1095,215 1095,345 980,410 865,345 865,215"
fill="none" stroke="#6366f1" stroke-width="0.5" opacity="0.08"/>
<!-- Left-side decorative connection lines -->
<line x1="60" y1="560" x2="200" y2="460" stroke="#6366f1" stroke-width="1" opacity="0.15"/>
<line x1="200" y1="460" x2="380" y2="540" stroke="#6366f1" stroke-width="1" opacity="0.15"/>
<circle cx="60" cy="560" r="3" fill="#6366f1" opacity="0.3"/>
<circle cx="200" cy="460" r="3" fill="#6366f1" opacity="0.3"/>
<circle cx="380" cy="540" r="3" fill="#6366f1" opacity="0.3"/>
<!-- ── Main icon (hex + nodes) centered-left ── -->
<g transform="translate(128, 265)">
<!-- Hex -->
<polygon points="64,0 112,28 112,92 64,120 16,92 16,28" fill="url(#hexGrad)"/>
<!-- Center node -->
<circle cx="64" cy="60" r="11" fill="white" opacity="0.95"/>
<!-- Lines -->
<line x1="64" y1="49" x2="64" y2="18" stroke="white" stroke-width="5" stroke-linecap="round" opacity="0.7"/>
<line x1="73.5" y1="65.5" x2="97" y2="79" stroke="white" stroke-width="5" stroke-linecap="round" opacity="0.7"/>
<line x1="54.5" y1="65.5" x2="31" y2="79" stroke="white" stroke-width="5" stroke-linecap="round" opacity="0.7"/>
<!-- Outer nodes -->
<circle cx="64" cy="14" r="7" fill="url(#nodeGrad)"/>
<circle cx="100" cy="80" r="7" fill="url(#nodeGrad)"/>
<circle cx="28" cy="80" r="7" fill="url(#nodeGrad)"/>
</g>
<!-- ── Typography ── -->
<!-- Title -->
<text x="290" y="298"
font-family="'Inter', 'Helvetica Neue', Arial, sans-serif"
font-size="72" font-weight="800" letter-spacing="-2"
fill="url(#titleGrad)">Agent Dashboard</text>
<!-- Subtitle -->
<text x="292" y="355"
font-family="'Inter', 'Helvetica Neue', Arial, sans-serif"
font-size="26" font-weight="400"
fill="#8888aa">Real-time monitoring platform for Claude Code agent activity</text>
<!-- Divider line -->
<line x1="290" y1="385" x2="840" y2="385" stroke="#252538" stroke-width="1"/>
<!-- Tech pills -->
<g transform="translate(290, 408)" font-family="'Inter', 'Helvetica Neue', Arial, sans-serif" font-size="15" font-weight="600">
<!-- Node.js -->
<rect x="0" y="0" width="88" height="28" rx="6" fill="#33993320" stroke="#33993340"/>
<text x="44" y="19" text-anchor="middle" fill="#6dbf6d">Node.js 18+</text>
<!-- React -->
<rect x="100" y="0" width="82" height="28" rx="6" fill="#61dafb18" stroke="#61dafb30"/>
<text x="141" y="19" text-anchor="middle" fill="#61dafb">React 18</text>
<!-- TypeScript -->
<rect x="194" y="0" width="100" height="28" rx="6" fill="#3178c618" stroke="#3178c630"/>
<text x="244" y="19" text-anchor="middle" fill="#5a9fd4">TypeScript</text>
<!-- SQLite -->
<rect x="306" y="0" width="72" height="28" rx="6" fill="#003b5718" stroke="#005f8a30"/>
<text x="342" y="19" text-anchor="middle" fill="#5bb8e0">SQLite</text>
<!-- WebSocket -->
<rect x="390" y="0" width="100" height="28" rx="6" fill="#10b98118" stroke="#10b98130"/>
<text x="440" y="19" text-anchor="middle" fill="#34d399">WebSocket</text>
<!-- MIT -->
<rect x="502" y="0" width="62" height="28" rx="6" fill="#f59e0b18" stroke="#f59e0b30"/>
<text x="533" y="19" text-anchor="middle" fill="#fbbf24">MIT</text>
</g>
<!-- Bottom author strip -->
<text x="290" y="580"
font-family="'Inter', 'Helvetica Neue', Arial, sans-serif"
font-size="18" font-weight="500"
fill="#55556a">github.com/SmartGift · smartgift.vn</text>
</svg>