feat(site): rewrite landing page — Claude Code Command Center
Reposition cladm from "monitor & launcher" to "command center" with embedded PTY grid, tabbed workspaces, and pane controls. New hero animation shows picker → grid transition. JSX workspace mockup with 4 active panes, traffic-light buttons, and live terminal content. Updated features, two-mode controls, and metadata throughout. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -14,9 +14,9 @@ const pixel = Silkscreen({
|
||||
});
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: "cladm — Monitor & launch Claude Code sessions",
|
||||
title: "cladm — Claude Code Command Center",
|
||||
description:
|
||||
"Multi-project Claude Code session monitor. Track busy/idle status in real time, see usage costs, get notified when Claude finishes, and launch everything in parallel.",
|
||||
"Multiproject workspace for Claude Code. Embedded terminal grid with tabbed workspaces, pane controls, real-time status tracking, usage monitoring, and full keyboard-driven workflow.",
|
||||
icons: {
|
||||
icon: [
|
||||
{ url: "/favicon.ico", sizes: "32x32" },
|
||||
@@ -26,8 +26,8 @@ export const metadata: Metadata = {
|
||||
apple: "/apple-touch-icon.png",
|
||||
},
|
||||
openGraph: {
|
||||
title: "cladm",
|
||||
description: "Monitor & launch Claude Code sessions across all your projects",
|
||||
title: "cladm — Claude Code Command Center",
|
||||
description: "Manage all your Claude Code sessions from one terminal. Embedded PTY grid, tabbed workspaces, live monitoring, and pane controls.",
|
||||
url: "https://claudm.com",
|
||||
siteName: "cladm",
|
||||
type: "website",
|
||||
@@ -36,14 +36,14 @@ export const metadata: Metadata = {
|
||||
url: "/og-image.png",
|
||||
width: 1200,
|
||||
height: 630,
|
||||
alt: "cladm — Monitor & launch Claude Code sessions",
|
||||
alt: "cladm — Claude Code Command Center",
|
||||
},
|
||||
],
|
||||
},
|
||||
twitter: {
|
||||
card: "summary_large_image",
|
||||
title: "cladm",
|
||||
description: "Monitor & launch Claude Code sessions across all your projects",
|
||||
title: "cladm — Claude Code Command Center",
|
||||
description: "Manage all your Claude Code sessions from one terminal. Embedded PTY grid, tabbed workspaces, live monitoring, and pane controls.",
|
||||
images: ["/og-image.png"],
|
||||
},
|
||||
};
|
||||
|
||||
@@ -11,10 +11,7 @@ import {
|
||||
NetworkIcon,
|
||||
GamepadIcon,
|
||||
BlocksIcon,
|
||||
ArrowRightIcon,
|
||||
ExternalLinkIcon,
|
||||
LinkedinIcon,
|
||||
MailIcon,
|
||||
SpaceInvadersIcon,
|
||||
EyeIcon,
|
||||
BellIcon,
|
||||
@@ -90,13 +87,56 @@ function FeatureBlock({
|
||||
);
|
||||
}
|
||||
|
||||
function GridPaneMockup({
|
||||
name,
|
||||
status,
|
||||
elapsed,
|
||||
children,
|
||||
focused,
|
||||
}: {
|
||||
name: string;
|
||||
status: "busy" | "idle";
|
||||
elapsed?: string;
|
||||
children: React.ReactNode;
|
||||
focused?: boolean;
|
||||
}) {
|
||||
return (
|
||||
<div className={`bg-bg border ${focused ? "border-accent" : "border-border"}`}>
|
||||
{/* Pane title bar */}
|
||||
<div className="flex items-center justify-between px-3 py-1 border-b border-border bg-surface-2/60">
|
||||
<div className="font-[family-name:var(--font-mono)] text-[10px] flex items-center gap-1.5">
|
||||
{status === "busy" ? (
|
||||
<span className="text-green">●</span>
|
||||
) : (
|
||||
<>
|
||||
<span className="text-yellow">◉</span>
|
||||
{elapsed && <span className="text-dim">{elapsed}</span>}
|
||||
</>
|
||||
)}
|
||||
<span className="text-text">{name}</span>
|
||||
</div>
|
||||
<div className="flex items-center gap-1">
|
||||
<span className="text-cyan text-[8px]">●</span>
|
||||
<span className="text-dim text-[8px]">─</span>
|
||||
<span className="text-[#27c93f] text-[8px]">●</span>
|
||||
<span className="text-[#ff5f56] text-[8px]">●</span>
|
||||
</div>
|
||||
</div>
|
||||
{/* Pane content */}
|
||||
<div className="p-3 font-[family-name:var(--font-mono)] text-[10px] text-dim leading-relaxed">
|
||||
{children}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default function Home() {
|
||||
return (
|
||||
<div className="min-h-screen bg-bg selection:bg-accent/30">
|
||||
<SubscribeModal />
|
||||
|
||||
{/* ══════ HERO ══════ */}
|
||||
<section className="relative overflow-hidden scanlines">
|
||||
{/* Grid background */}
|
||||
<div
|
||||
className="absolute inset-0 opacity-[0.04]"
|
||||
style={{
|
||||
@@ -142,14 +182,13 @@ export default function Home() {
|
||||
</h1>
|
||||
|
||||
<p className="font-[family-name:var(--font-pixel)] text-accent text-lg md:text-xl mb-5">
|
||||
MULTI-PROJECT CLAUDE CODE MONITOR
|
||||
CLAUDE CODE COMMAND CENTER
|
||||
</p>
|
||||
|
||||
<p className="font-[family-name:var(--font-mono)] text-dim text-sm max-w-md leading-relaxed mb-8">
|
||||
Track all your Claude Code sessions in one place. See
|
||||
busy/idle status in real time, monitor usage costs, get
|
||||
notified when Claude finishes, and launch everything in
|
||||
parallel Terminal windows.
|
||||
Manage all your Claude Code sessions from one terminal.
|
||||
An embedded PTY grid with tabbed workspaces, pane controls,
|
||||
real-time status tracking, and full keyboard-driven workflow.
|
||||
</p>
|
||||
|
||||
{/* Install command */}
|
||||
@@ -169,7 +208,7 @@ export default function Home() {
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{/* Right — terminal cascade */}
|
||||
{/* Right — terminal cascade: picker → grid */}
|
||||
<div className="flex-1 w-full max-w-xl">
|
||||
<TerminalCascade />
|
||||
</div>
|
||||
@@ -186,50 +225,185 @@ export default function Home() {
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* ══════ DEMO GIF ══════ */}
|
||||
{/* ══════ THE WORKSPACE ══════ */}
|
||||
<section className="max-w-5xl mx-auto px-6 py-20">
|
||||
<div className="text-center mb-10">
|
||||
<div className="text-center mb-4">
|
||||
<h2 className="font-[family-name:var(--font-pixel)] text-accent text-sm uppercase tracking-[0.3em] mb-3">
|
||||
// SEE IT IN ACTION
|
||||
// THE WORKSPACE
|
||||
</h2>
|
||||
<p className="font-[family-name:var(--font-mono)] text-dim text-xs max-w-2xl mx-auto leading-relaxed">
|
||||
Every Claude Code session runs in an embedded terminal pane — no separate windows.
|
||||
See all your projects at once, switch focus with a click, and never lose track of what Claude is doing.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<TerminalWindow title="cladm">
|
||||
{/* Grid workspace mockup */}
|
||||
<div className="mt-10">
|
||||
<div className="pixel-border bg-surface overflow-hidden">
|
||||
{/* Tab bar */}
|
||||
<div className="flex items-center bg-surface-2 border-b-2 border-border">
|
||||
<div className="px-4 py-2 border-b-2 border-accent font-[family-name:var(--font-mono)] text-xs">
|
||||
<span className="text-green">●</span>
|
||||
<span className="text-text"> acme-api</span>
|
||||
<span className="text-dim"> · </span>
|
||||
<span className="text-yellow">◉</span>
|
||||
<span className="text-text"> quantum-dash</span>
|
||||
</div>
|
||||
<div className="px-4 py-2 font-[family-name:var(--font-mono)] text-xs text-dim border-b-2 border-transparent">
|
||||
<span className="text-green">●</span>
|
||||
<span> ml-pipeline</span>
|
||||
<span className="text-dim"> · </span>
|
||||
<span className="text-green">●</span>
|
||||
<span> infra-k8s</span>
|
||||
</div>
|
||||
<div className="ml-auto px-3 py-2 font-[family-name:var(--font-mono)] text-[10px] text-dim">
|
||||
<span className="text-accent">+</span> add pane
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Pane grid */}
|
||||
<div className="grid grid-cols-2 gap-[2px] p-[2px]">
|
||||
{/* Pane 1: acme-api */}
|
||||
<GridPaneMockup name="acme-api" status="busy" focused>
|
||||
<div className="text-green mb-1">> I'll analyze the authentication module and</div>
|
||||
<div className="text-green">{" "}fix the token refresh bug you mentioned.</div>
|
||||
<div className="mt-2">
|
||||
<span className="text-accent">⏺</span> Reading src/auth/token.ts
|
||||
</div>
|
||||
<div>
|
||||
<span className="text-accent">⏺</span> Reading src/auth/middleware.ts
|
||||
</div>
|
||||
<div>
|
||||
<span className="text-accent">⏺</span> Grep: refreshToken pattern
|
||||
</div>
|
||||
<div className="text-green mt-1">
|
||||
Found 3 files with stale token logic.
|
||||
<span className="cursor-blink text-accent">_</span>
|
||||
</div>
|
||||
</GridPaneMockup>
|
||||
|
||||
{/* Pane 2: quantum-dash */}
|
||||
<GridPaneMockup name="quantum-dash" status="idle" elapsed="4m">
|
||||
<div className="text-text">I've updated the chart component to use</div>
|
||||
<div className="text-text">the new streaming data format. Changes:</div>
|
||||
<div className="mt-2">
|
||||
<span className="text-green">✓</span> src/components/chart.tsx
|
||||
</div>
|
||||
<div>
|
||||
<span className="text-green">✓</span> src/hooks/useChartData.ts
|
||||
</div>
|
||||
<div>
|
||||
<span className="text-green">✓</span> src/types/stream.d.ts
|
||||
</div>
|
||||
<div className="mt-2 text-yellow">Waiting for your input...</div>
|
||||
</GridPaneMockup>
|
||||
|
||||
{/* Pane 3: ml-pipeline */}
|
||||
<GridPaneMockup name="ml-pipeline" status="busy">
|
||||
<div className="text-green">> Building the BERT fine-tuning pipeline</div>
|
||||
<div className="text-green">{" "}with the new training dataset.</div>
|
||||
<div className="mt-2">
|
||||
<span className="text-accent">⏺</span> Writing src/train.py
|
||||
</div>
|
||||
<div className="mt-1">
|
||||
Processing: epoch 3/10{" "}
|
||||
<span className="text-accent">████████</span>
|
||||
<span className="text-border">░░░░░░░░░░░░</span>{" "}
|
||||
<span className="text-text">30%</span>
|
||||
</div>
|
||||
</GridPaneMockup>
|
||||
|
||||
{/* Pane 4: infra-k8s */}
|
||||
<GridPaneMockup name="infra-k8s" status="busy">
|
||||
<div className="text-green">> Updating the Kubernetes deployment</div>
|
||||
<div className="text-green">{" "}manifests for staging.</div>
|
||||
<div className="mt-2">
|
||||
<span className="text-accent">⏺</span> Reading k8s/staging/deployment.yaml
|
||||
</div>
|
||||
<div>
|
||||
<span className="text-accent">⏺</span> Reading k8s/staging/service.yaml
|
||||
</div>
|
||||
<div className="mt-1 text-green">
|
||||
Scaling replicas 2 → 4 for load test
|
||||
<span className="cursor-blink text-accent">_</span>
|
||||
</div>
|
||||
</GridPaneMockup>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Feature callouts */}
|
||||
<div className="grid grid-cols-1 md:grid-cols-3 gap-6 mt-10">
|
||||
<div className="text-center">
|
||||
<div className="font-[family-name:var(--font-pixel)] text-accent text-xs uppercase tracking-wider mb-2">
|
||||
Embedded PTY Grid
|
||||
</div>
|
||||
<p className="font-[family-name:var(--font-mono)] text-dim text-[10px] leading-relaxed">
|
||||
Each pane runs a real pseudo-terminal via forkpty(). Full I/O, ANSI colors, resize — no tmux needed.
|
||||
</p>
|
||||
</div>
|
||||
<div className="text-center">
|
||||
<div className="font-[family-name:var(--font-pixel)] text-accent text-xs uppercase tracking-wider mb-2">
|
||||
Tabbed Workspaces
|
||||
</div>
|
||||
<p className="font-[family-name:var(--font-mono)] text-dim text-[10px] leading-relaxed">
|
||||
Group sessions into tabs. Inline pane names with status icons show what's running at a glance.
|
||||
</p>
|
||||
</div>
|
||||
<div className="text-center">
|
||||
<div className="font-[family-name:var(--font-pixel)] text-accent text-xs uppercase tracking-wider mb-2">
|
||||
Pane Controls
|
||||
</div>
|
||||
<p className="font-[family-name:var(--font-mono)] text-dim text-[10px] leading-relaxed">
|
||||
Traffic-light buttons on every pane: close, expand, minimize, plus a folder-open button. Fully mouse-driven.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<PixelDivider />
|
||||
|
||||
{/* ══════ SMART PICKER ══════ */}
|
||||
<section className="max-w-5xl mx-auto px-6 py-16">
|
||||
<div className="text-center mb-4">
|
||||
<h2 className="font-[family-name:var(--font-pixel)] text-accent text-sm uppercase tracking-[0.3em] mb-3">
|
||||
// THE SMART PICKER
|
||||
</h2>
|
||||
<p className="font-[family-name:var(--font-mono)] text-dim text-xs max-w-2xl mx-auto leading-relaxed">
|
||||
It starts with a smart project picker. cladm reads{" "}
|
||||
<code className="text-accent">~/.claude/history.jsonl</code> to discover every project
|
||||
you've used with Claude Code — git branch, sync status, dirty state, session history, stack detection — all loaded in parallel.
|
||||
Select what you need, hit Enter, and the grid workspace takes over.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="mt-8">
|
||||
<TerminalWindow title="cladm — 8 projects">
|
||||
<Image
|
||||
src="/demo.gif"
|
||||
alt="cladm demo showing project navigation"
|
||||
alt="cladm smart picker showing project navigation and selection"
|
||||
width={980}
|
||||
height={500}
|
||||
className="w-full"
|
||||
unoptimized
|
||||
/>
|
||||
</TerminalWindow>
|
||||
</section>
|
||||
</div>
|
||||
|
||||
<PixelDivider />
|
||||
|
||||
{/* ══════ SCREENSHOTS ══════ */}
|
||||
<section className="max-w-5xl mx-auto px-6 py-16">
|
||||
<h2 className="font-[family-name:var(--font-pixel)] text-accent text-sm uppercase tracking-[0.3em] mb-12 text-center">
|
||||
// SCREENSHOTS
|
||||
</h2>
|
||||
|
||||
<div className="space-y-16">
|
||||
{/* Main view */}
|
||||
{/* Picker screenshots */}
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-8 mt-12">
|
||||
<div>
|
||||
<div className="flex items-center gap-4 mb-4">
|
||||
<div className="flex items-center gap-4 mb-3">
|
||||
<div className="h-[2px] flex-1 bg-border" />
|
||||
<h3 className="font-[family-name:var(--font-pixel)] text-text text-xs uppercase tracking-wider whitespace-nowrap">
|
||||
PROJECT LIST
|
||||
</h3>
|
||||
<div className="h-[2px] flex-1 bg-border" />
|
||||
</div>
|
||||
<p className="font-[family-name:var(--font-mono)] text-dim text-xs text-center mb-6">
|
||||
All your projects sorted by recent Claude usage. Git branch, sync
|
||||
status, dirty state, session count, and auto-detected stack at a
|
||||
glance.
|
||||
<p className="font-[family-name:var(--font-mono)] text-dim text-[10px] text-center mb-4">
|
||||
Sorted by recent Claude usage. Git metadata, session count, and stack tags at a glance.
|
||||
</p>
|
||||
<TerminalWindow title="cladm — 8 projects">
|
||||
<TerminalWindow title="cladm — project list">
|
||||
<Image
|
||||
src="/screenshot-main.png"
|
||||
alt="cladm main project list view"
|
||||
@@ -240,25 +414,21 @@ export default function Home() {
|
||||
</TerminalWindow>
|
||||
</div>
|
||||
|
||||
{/* Expanded view */}
|
||||
<div>
|
||||
<div className="flex items-center gap-4 mb-4">
|
||||
<div className="flex items-center gap-4 mb-3">
|
||||
<div className="h-[2px] flex-1 bg-border" />
|
||||
<h3 className="font-[family-name:var(--font-pixel)] text-text text-xs uppercase tracking-wider whitespace-nowrap">
|
||||
EXPANDED VIEW
|
||||
</h3>
|
||||
<div className="h-[2px] flex-1 bg-border" />
|
||||
</div>
|
||||
<p className="font-[family-name:var(--font-mono)] text-dim text-xs text-center mb-6">
|
||||
Press <Keycap>→</Keycap> to expand. Browse branches, see
|
||||
session conversations with last prompt and Claude's response.
|
||||
Running sessions show <span className="text-green">● running</span> or{" "}
|
||||
<span className="text-yellow">◉ idle</span> status inline. Resume any session directly.
|
||||
<p className="font-[family-name:var(--font-mono)] text-dim text-[10px] text-center mb-4">
|
||||
Browse branches, past sessions with conversation previews. Resume any session directly.
|
||||
</p>
|
||||
<TerminalWindow title="cladm — 2 selected (1 branch switch)">
|
||||
<TerminalWindow title="cladm — expanded">
|
||||
<Image
|
||||
src="/screenshot-expanded.png"
|
||||
alt="cladm expanded view with sessions and branches"
|
||||
alt="cladm expanded view with sessions"
|
||||
width={980}
|
||||
height={600}
|
||||
className="w-full"
|
||||
@@ -273,104 +443,83 @@ export default function Home() {
|
||||
{/* ══════ LIVE MONITORING ══════ */}
|
||||
<section className="max-w-5xl mx-auto px-6 py-16">
|
||||
<h2 className="font-[family-name:var(--font-pixel)] text-accent text-sm uppercase tracking-[0.3em] mb-12 text-center">
|
||||
// LIVE SESSION MONITORING
|
||||
// REAL-TIME STATUS
|
||||
</h2>
|
||||
|
||||
<div className="max-w-2xl mx-auto">
|
||||
<div className="max-w-3xl mx-auto">
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-8">
|
||||
{/* Status indicators */}
|
||||
<div className="pixel-border bg-surface p-6">
|
||||
<p className="font-[family-name:var(--font-mono)] text-dim text-xs leading-relaxed mb-5">
|
||||
cladm detects all running Claude Code sessions across every project and shows their real-time status.
|
||||
When any session finishes, a sound plays and the dock icon bounces — so you never miss it, even across dozens of parallel sessions.
|
||||
</p>
|
||||
|
||||
<h3 className="font-[family-name:var(--font-pixel)] text-text text-xs uppercase tracking-wider mb-4">
|
||||
Session Status
|
||||
</h3>
|
||||
<div className="space-y-3 font-[family-name:var(--font-mono)] text-xs">
|
||||
<div className="flex items-center gap-3">
|
||||
<span className="text-green text-base">●</span>
|
||||
<span className="text-text">Busy</span>
|
||||
<span className="text-dim">— Claude is actively processing</span>
|
||||
<span className="text-dim">— Claude is actively working</span>
|
||||
</div>
|
||||
<div className="flex items-center gap-3">
|
||||
<span className="text-yellow text-base">◉</span>
|
||||
<span className="text-dim">3m</span>
|
||||
<span className="text-text">Idle</span>
|
||||
<span className="text-dim">— Claude finished 3 min ago, waiting for input</span>
|
||||
<span className="text-dim">— waiting for your input</span>
|
||||
</div>
|
||||
<div className="flex items-center gap-3">
|
||||
<span className="text-dim text-base">○</span>
|
||||
<span className="text-text ml-[22px]">No session</span>
|
||||
<span className="text-dim">— No active Claude process</span>
|
||||
<span className="text-dim">— not running</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="mt-5 pt-4 border-t border-border">
|
||||
<div className="mt-4 pt-3 border-t border-border">
|
||||
<p className="font-[family-name:var(--font-mono)] text-dim text-[10px] leading-relaxed">
|
||||
Detection reads the tail of each session's JSONL in{" "}
|
||||
<code className="text-accent">~/.claude/projects/</code>. A session is
|
||||
busy if the file was written recently OR the last assistant message
|
||||
has a pending tool call. This prevents false idle triggers during
|
||||
long-running tools and subtasks.
|
||||
Status visible in both picker rows and grid pane headers.
|
||||
Sound + dock bounce on idle transitions.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<PixelDivider />
|
||||
|
||||
{/* ══════ USAGE + IDLE PANELS ══════ */}
|
||||
<section className="max-w-5xl mx-auto px-6 py-16">
|
||||
<h2 className="font-[family-name:var(--font-pixel)] text-accent text-sm uppercase tracking-[0.3em] mb-12 text-center">
|
||||
// USAGE & IDLE PANELS
|
||||
</h2>
|
||||
|
||||
<div className="space-y-12 max-w-4xl mx-auto">
|
||||
{/* Usage panel screenshot */}
|
||||
<div>
|
||||
<div className="flex items-center gap-4 mb-4">
|
||||
<div className="h-[2px] flex-1 bg-border" />
|
||||
<h3 className="font-[family-name:var(--font-pixel)] text-text text-xs uppercase tracking-wider whitespace-nowrap">
|
||||
USAGE TRACKING
|
||||
{/* Usage tracking */}
|
||||
<div className="pixel-border bg-surface p-6">
|
||||
<h3 className="font-[family-name:var(--font-pixel)] text-text text-xs uppercase tracking-wider mb-4">
|
||||
Usage Tracking
|
||||
</h3>
|
||||
<div className="h-[2px] flex-1 bg-border" />
|
||||
</div>
|
||||
<p className="font-[family-name:var(--font-mono)] text-dim text-xs text-center mb-6">
|
||||
Press <Keycap>u</Keycap> to toggle. Tracks session (5h window), weekly
|
||||
all-model and sonnet-only costs against configurable plan limits, plus monthly totals.
|
||||
</p>
|
||||
<TerminalWindow title="cladm — usage panel">
|
||||
<Image
|
||||
src="/screenshot-usage.png"
|
||||
alt="cladm usage tracking panel with session, weekly, and monthly cost bars"
|
||||
width={980}
|
||||
height={500}
|
||||
className="w-full"
|
||||
/>
|
||||
</TerminalWindow>
|
||||
</div>
|
||||
|
||||
{/* Idle sessions screenshot */}
|
||||
<div className="space-y-3 font-[family-name:var(--font-mono)] text-[10px]">
|
||||
<div>
|
||||
<div className="flex items-center gap-4 mb-4">
|
||||
<div className="h-[2px] flex-1 bg-border" />
|
||||
<h3 className="font-[family-name:var(--font-pixel)] text-text text-xs uppercase tracking-wider whitespace-nowrap">
|
||||
IDLE SESSIONS
|
||||
</h3>
|
||||
<div className="h-[2px] flex-1 bg-border" />
|
||||
<div className="flex justify-between mb-1">
|
||||
<span className="text-dim">session (5h)</span>
|
||||
<span className="text-text">$2.40 / $5.00</span>
|
||||
</div>
|
||||
<p className="font-[family-name:var(--font-mono)] text-dim text-xs text-center mb-6">
|
||||
Press <Keycap>i</Keycap> to toggle. Shows sessions waiting for your
|
||||
input, sorted by most recently idle. Press Enter to focus a session's
|
||||
Terminal tab directly.
|
||||
<div className="h-2 bg-bg border border-border">
|
||||
<div className="h-full bg-accent" style={{ width: "48%" }} />
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div className="flex justify-between mb-1">
|
||||
<span className="text-dim">weekly all-model</span>
|
||||
<span className="text-text">$18.50 / $100</span>
|
||||
</div>
|
||||
<div className="h-2 bg-bg border border-border">
|
||||
<div className="h-full bg-green" style={{ width: "18.5%" }} />
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div className="flex justify-between mb-1">
|
||||
<span className="text-dim">monthly total</span>
|
||||
<span className="text-text">$67.20</span>
|
||||
</div>
|
||||
<div className="h-2 bg-bg border border-border">
|
||||
<div className="h-full bg-cyan" style={{ width: "33.6%" }} />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="mt-4 pt-3 border-t border-border">
|
||||
<p className="font-[family-name:var(--font-mono)] text-dim text-[10px] leading-relaxed">
|
||||
Press <Keycap>u</Keycap> in picker mode. Tracks session, weekly,
|
||||
and monthly costs against configurable plan limits.
|
||||
</p>
|
||||
<TerminalWindow title="cladm — idle sessions (2)">
|
||||
<Image
|
||||
src="/screenshot-idle.png"
|
||||
alt="cladm idle sessions panel showing waiting sessions with elapsed time"
|
||||
width={980}
|
||||
height={500}
|
||||
className="w-full"
|
||||
/>
|
||||
</TerminalWindow>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
@@ -384,81 +533,84 @@ export default function Home() {
|
||||
</h2>
|
||||
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
|
||||
<FeatureBlock
|
||||
icon={<TerminalIcon size={28} />}
|
||||
title="EMBEDDED GRID"
|
||||
desc="Run multiple Claude Code sessions side by side in a tiled terminal grid. Each pane is a real PTY with full I/O — no separate windows needed."
|
||||
/>
|
||||
<FeatureBlock
|
||||
icon={<BlocksIcon size={28} />}
|
||||
title="TABBED WORKSPACES"
|
||||
desc="Group sessions into named tabs. Inline pane indicators show project names and busy/idle status at a glance."
|
||||
/>
|
||||
<FeatureBlock
|
||||
icon={<GamepadIcon size={28} />}
|
||||
title="PANE CONTROLS"
|
||||
desc="Traffic-light buttons on every pane: close, minimize, expand to full screen. Blue button opens the project folder."
|
||||
/>
|
||||
<FeatureBlock
|
||||
icon={<SearchIcon size={28} />}
|
||||
title="SELECT MODE"
|
||||
desc="Double-click any pane to enter select mode. Copy text from the full scrollback buffer — up to 5,000 lines of history."
|
||||
/>
|
||||
<FeatureBlock
|
||||
icon={<EyeIcon size={28} />}
|
||||
title="LIVE MONITORING"
|
||||
desc="Track all Claude sessions across every project. Busy/idle status updates in real time with elapsed timers."
|
||||
desc="Track busy/idle status across all sessions in real time. Elapsed timers show how long each session has been waiting."
|
||||
/>
|
||||
<FeatureBlock
|
||||
icon={<TrendingUpIcon size={28} />}
|
||||
title="USAGE TRACKING"
|
||||
desc="Session, weekly, and monthly cost bars. Track all-model and sonnet-only usage against configurable plan limits."
|
||||
desc="Session, weekly, and monthly cost bars against configurable plan limits. Track all-model and sonnet-only usage."
|
||||
/>
|
||||
<FeatureBlock
|
||||
icon={<BellIcon size={28} />}
|
||||
title="NOTIFICATIONS"
|
||||
desc="Sound + dock bounce when any session finishes. Never miss a completed task across dozens of parallel sessions."
|
||||
/>
|
||||
<FeatureBlock
|
||||
icon={<ThunderIcon size={28} />}
|
||||
title="FOCUS SESSION"
|
||||
desc="Press Enter on any idle session to instantly focus its Terminal tab. Flash animation highlights the window."
|
||||
/>
|
||||
<FeatureBlock
|
||||
icon={<SearchIcon size={28} />}
|
||||
title="AUTO-DISCOVERY"
|
||||
desc="Reads ~/.claude/history.jsonl to find every project you've used with Claude Code. No config needed."
|
||||
/>
|
||||
<FeatureBlock
|
||||
icon={<NetworkIcon size={28} />}
|
||||
title="GIT METADATA"
|
||||
desc="Branch, sync status (ahead/behind), last commit, dirty state — all loaded in parallel per project."
|
||||
/>
|
||||
<FeatureBlock
|
||||
icon={<FolderIcon size={28} />}
|
||||
title="SESSION BROWSER"
|
||||
desc="Expand any project to browse past sessions. See conversation previews and resume directly."
|
||||
title="AUTO-DISCOVERY"
|
||||
desc="Reads ~/.claude/history.jsonl to find every project. Git branch, sync status, dirty state — all loaded in parallel."
|
||||
/>
|
||||
<FeatureBlock
|
||||
icon={<TerminalIcon size={28} />}
|
||||
title="PARALLEL LAUNCH"
|
||||
desc="Select multiple projects and hit Enter. Each opens in a new Terminal.app window simultaneously."
|
||||
/>
|
||||
<FeatureBlock
|
||||
icon={<BlocksIcon size={28} />}
|
||||
title="STACK DETECTION"
|
||||
desc="Auto-detects project stack: TypeScript, Python, Rust, Go, Docker, and more from config files."
|
||||
icon={<ThunderIcon size={28} />}
|
||||
title="DIRECT PTY"
|
||||
desc="Native pseudo-terminal management via forkpty(). No tmux dependency. Zero configuration. Just works."
|
||||
/>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<PixelDivider />
|
||||
|
||||
{/* ══════ KEYBINDINGS ══════ */}
|
||||
{/* ══════ CONTROLS ══════ */}
|
||||
<section className="max-w-5xl mx-auto px-6 py-16">
|
||||
<h2 className="font-[family-name:var(--font-pixel)] text-accent text-sm uppercase tracking-[0.3em] mb-12 text-center">
|
||||
// CONTROLS
|
||||
</h2>
|
||||
|
||||
<div className="max-w-2xl mx-auto">
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-6 max-w-4xl mx-auto">
|
||||
{/* Picker mode */}
|
||||
<div className="pixel-border bg-surface p-6">
|
||||
<div className="grid grid-cols-2 gap-y-3 font-[family-name:var(--font-mono)] text-xs">
|
||||
<h3 className="font-[family-name:var(--font-pixel)] text-accent text-xs uppercase tracking-wider mb-4 text-center">
|
||||
Picker Mode
|
||||
</h3>
|
||||
<div className="grid grid-cols-2 gap-y-2 font-[family-name:var(--font-mono)] text-xs">
|
||||
{[
|
||||
["↑ ↓", "Navigate"],
|
||||
["Space", "Toggle selection"],
|
||||
["Space", "Toggle select"],
|
||||
["→", "Expand project"],
|
||||
["←", "Collapse"],
|
||||
["Enter", "Launch selected / focus session"],
|
||||
["i", "Toggle idle sessions panel"],
|
||||
["u", "Toggle usage panel"],
|
||||
["/", "Filter projects"],
|
||||
["Enter", "Launch grid"],
|
||||
["/", "Filter"],
|
||||
["a", "Select all"],
|
||||
["n", "Deselect all"],
|
||||
["s", "Cycle sort mode"],
|
||||
["f", "Open folder in Finder"],
|
||||
["g", "Go to active session"],
|
||||
["PgUp PgDn", "Jump 15 rows"],
|
||||
["q / Esc", "Quit"],
|
||||
["s", "Cycle sort"],
|
||||
["u", "Usage panel"],
|
||||
["i", "Idle sessions"],
|
||||
["f", "Open folder"],
|
||||
["g", "Go to session"],
|
||||
["q", "Quit"],
|
||||
].map(([key, desc]) => (
|
||||
<div key={key} className="contents">
|
||||
<div className="text-accent">{key}</div>
|
||||
@@ -467,12 +619,58 @@ export default function Home() {
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Grid mode */}
|
||||
<div className="pixel-border bg-surface p-6">
|
||||
<h3 className="font-[family-name:var(--font-pixel)] text-accent text-xs uppercase tracking-wider mb-4 text-center">
|
||||
Grid Mode
|
||||
</h3>
|
||||
<div className="grid grid-cols-2 gap-y-2 font-[family-name:var(--font-mono)] text-xs">
|
||||
{[
|
||||
["Click", "Focus pane"],
|
||||
["Dbl-click", "Select mode"],
|
||||
["Alt+1-9", "Switch tab"],
|
||||
["Alt+n/p", "Next/prev tab"],
|
||||
["+ button", "Add pane"],
|
||||
["Esc", "Back to picker"],
|
||||
].map(([key, desc]) => (
|
||||
<div key={key} className="contents">
|
||||
<div className="text-accent">{key}</div>
|
||||
<div className="text-dim">{desc}</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
<div className="mt-4 pt-3 border-t border-border">
|
||||
<div className="font-[family-name:var(--font-pixel)] text-text text-[10px] uppercase tracking-wider mb-2">
|
||||
Pane Buttons
|
||||
</div>
|
||||
<div className="grid grid-cols-2 gap-y-2 font-[family-name:var(--font-mono)] text-xs">
|
||||
{[
|
||||
["● blue", "Open folder"],
|
||||
["● green", "Expand pane"],
|
||||
["● yellow", "Minimize"],
|
||||
["● red", "Close pane"],
|
||||
].map(([key, desc], i) => (
|
||||
<div key={key} className="contents">
|
||||
<div className={
|
||||
i === 0 ? "text-cyan" :
|
||||
i === 1 ? "text-[#27c93f]" :
|
||||
i === 2 ? "text-yellow" :
|
||||
"text-[#ff5f56]"
|
||||
}>{key}</div>
|
||||
<div className="text-dim">{desc}</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<PixelDivider />
|
||||
|
||||
{/* ══════ INSTALL ══════ */}
|
||||
{/* ══════ QUICK START ══════ */}
|
||||
<section className="max-w-5xl mx-auto px-6 py-16">
|
||||
<h2 className="font-[family-name:var(--font-pixel)] text-accent text-sm uppercase tracking-[0.3em] mb-12 text-center">
|
||||
// QUICK START
|
||||
@@ -514,91 +712,13 @@ export default function Home() {
|
||||
|
||||
<div className="mt-6 text-center">
|
||||
<p className="font-[family-name:var(--font-mono)] text-dim text-xs">
|
||||
Or try with mock data:{" "}
|
||||
Try with mock data:{" "}
|
||||
<code className="text-yellow">cladm --demo</code>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* ══════ LAUNCH RESULT ══════ */}
|
||||
<section className="max-w-5xl mx-auto px-6 py-16">
|
||||
<h2 className="font-[family-name:var(--font-pixel)] text-accent text-sm uppercase tracking-[0.3em] mb-4 text-center">
|
||||
// HIT ENTER
|
||||
</h2>
|
||||
<p className="font-[family-name:var(--font-mono)] text-dim text-xs text-center mb-10 max-w-lg mx-auto">
|
||||
Select your projects, press Enter, and watch them all launch in
|
||||
parallel. Each project opens a fresh Claude Code session in its own
|
||||
Terminal window.
|
||||
</p>
|
||||
|
||||
<div className="flex flex-col md:flex-row items-center gap-6">
|
||||
{/* Mini cladm picker */}
|
||||
<div className="flex-1 w-full">
|
||||
<TerminalWindow title="cladm — 3 selected">
|
||||
<div className="p-3 font-[family-name:var(--font-mono)] text-[10px] leading-relaxed">
|
||||
<div className="text-dim mb-1">
|
||||
{" PROJECT BRANCH LAST USE"}
|
||||
</div>
|
||||
<div className="bg-[#283457] px-1">
|
||||
<span className="text-green">●</span>
|
||||
<span className="text-green"> [✓]</span>
|
||||
<span className="text-text">
|
||||
{" "}
|
||||
acme-api{" "}
|
||||
</span>
|
||||
<span className="text-magenta">main</span>
|
||||
<span className="text-cyan">{" "}25m ago</span>
|
||||
</div>
|
||||
<div className="px-1">
|
||||
<span className="text-yellow">◉</span>
|
||||
<span className="text-dim">2m</span>
|
||||
<span className="text-green">[✓]</span>
|
||||
<span className="text-text"> quantum-dashboard{" "}</span>
|
||||
<span className="text-magenta">feat/cha</span>
|
||||
<span className="text-cyan">{" "}1h ago</span>
|
||||
</div>
|
||||
<div className="px-1">
|
||||
<span className="text-green">●</span>
|
||||
<span className="text-green"> [✓]</span>
|
||||
<span className="text-text"> ml-pipeline{" "}</span>
|
||||
<span className="text-magenta">exp/bert</span>
|
||||
<span className="text-cyan">{" "}just now</span>
|
||||
</div>
|
||||
<div className="px-1">
|
||||
<span className="text-dim">○</span>
|
||||
<span className="text-dim"> [ ]</span>
|
||||
<span className="text-dim"> pixel-engine{" "}develop{" "}3h ago</span>
|
||||
</div>
|
||||
</div>
|
||||
</TerminalWindow>
|
||||
</div>
|
||||
|
||||
{/* Arrow */}
|
||||
<div className="font-[family-name:var(--font-pixel)] text-accent text-2xl flex-shrink-0 rotate-90 md:rotate-0">
|
||||
>>>
|
||||
</div>
|
||||
|
||||
{/* Claude Code terminals */}
|
||||
<div className="flex-1 w-full">
|
||||
<div className="relative">
|
||||
{/* Stacked terminal windows effect */}
|
||||
<div className="absolute top-3 left-3 right-[-3px] bottom-[-3px] border-2 border-border bg-surface-2 opacity-40" />
|
||||
<div className="absolute top-[6px] left-[6px] right-[-6px] bottom-[-6px] border-2 border-border bg-surface-2 opacity-20" />
|
||||
<TerminalWindow title="claude — acme-api">
|
||||
<Image
|
||||
src="/claude-terminal.webp"
|
||||
alt="Claude Code session launched in Terminal"
|
||||
width={960}
|
||||
height={518}
|
||||
className="w-full"
|
||||
/>
|
||||
</TerminalWindow>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* ══════ NEWSLETTER ══════ */}
|
||||
<section className="max-w-5xl mx-auto px-6 py-16">
|
||||
<div className="max-w-md mx-auto">
|
||||
@@ -665,7 +785,7 @@ export default function Home() {
|
||||
</div>
|
||||
</div>
|
||||
<div className="mt-6 font-[family-name:var(--font-mono)] text-dim text-[10px] text-center">
|
||||
Built with Bun + OpenTUI. Pixel art by the cladm creatures.
|
||||
Built with Bun + OpenTUI. Direct PTY grid, no tmux. Pixel art by the cladm creatures.
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
"use client";
|
||||
|
||||
import { useEffect, useState, useCallback } from "react";
|
||||
import Image from "next/image";
|
||||
|
||||
const projects = [
|
||||
{ name: "acme-api", branch: "main", time: "25m ago", status: "busy" as const },
|
||||
@@ -10,13 +9,13 @@ const projects = [
|
||||
];
|
||||
|
||||
type Phase =
|
||||
| "typing" // cladm console visible, cursor selecting projects
|
||||
| "selecting" // checkboxes toggling on one by one
|
||||
| "enter" // "Enter" flash, cladm fades
|
||||
| "cascade" // terminals fly in
|
||||
| "hold" // terminals visible
|
||||
| "fadeout" // everything fades, restart
|
||||
| "pause"; // brief gap before loop
|
||||
| "typing"
|
||||
| "selecting"
|
||||
| "enter"
|
||||
| "grid"
|
||||
| "hold"
|
||||
| "fadeout"
|
||||
| "pause";
|
||||
|
||||
export function TerminalCascade() {
|
||||
const [phase, setPhase] = useState<Phase>("typing");
|
||||
@@ -27,31 +26,18 @@ export function TerminalCascade() {
|
||||
setSelectedCount(0);
|
||||
setPhase("typing");
|
||||
|
||||
// Typing/appear cladm console
|
||||
const t1 = setTimeout(() => setPhase("selecting"), 800);
|
||||
|
||||
// Toggle checkboxes one by one
|
||||
const t2 = setTimeout(() => setSelectedCount(1), 1200);
|
||||
const t3 = setTimeout(() => setSelectedCount(2), 1600);
|
||||
const t4 = setTimeout(() => setSelectedCount(3), 2000);
|
||||
|
||||
// Enter pressed
|
||||
const t5 = setTimeout(() => setPhase("enter"), 2600);
|
||||
|
||||
// Cascade terminals in
|
||||
const t6 = setTimeout(() => setPhase("cascade"), 3200);
|
||||
|
||||
// Hold
|
||||
const t7 = setTimeout(() => setPhase("hold"), 3800);
|
||||
|
||||
// Fade out
|
||||
const t8 = setTimeout(() => setPhase("fadeout"), 6200);
|
||||
|
||||
// Pause then restart
|
||||
const t6 = setTimeout(() => setPhase("grid"), 3400);
|
||||
const t7 = setTimeout(() => setPhase("hold"), 4000);
|
||||
const t8 = setTimeout(() => setPhase("fadeout"), 7000);
|
||||
const t9 = setTimeout(() => {
|
||||
setPhase("pause");
|
||||
setCycle((c) => c + 1);
|
||||
}, 7000);
|
||||
}, 7800);
|
||||
|
||||
return [t1, t2, t3, t4, t5, t6, t7, t8, t9];
|
||||
}, []);
|
||||
@@ -65,19 +51,18 @@ export function TerminalCascade() {
|
||||
return () => clearTimeout(start);
|
||||
}, [cycle, runCycle]);
|
||||
|
||||
const showCladm = phase === "typing" || phase === "selecting" || phase === "enter";
|
||||
const showCascade = phase === "cascade" || phase === "hold" || phase === "fadeout";
|
||||
const showPicker = phase === "typing" || phase === "selecting" || phase === "enter";
|
||||
const showGrid = phase === "grid" || phase === "hold" || phase === "fadeout";
|
||||
|
||||
return (
|
||||
<div className="relative w-full min-h-[340px]">
|
||||
{/* ── CLADM console (cause) ── */}
|
||||
<div className="relative w-full min-h-[360px]">
|
||||
{/* ── Picker (select projects) ── */}
|
||||
<div
|
||||
className={`transition-all duration-500 ${
|
||||
showCladm ? "opacity-100 scale-100" : "opacity-0 scale-95 pointer-events-none absolute inset-0"
|
||||
showPicker ? "opacity-100 scale-100" : "opacity-0 scale-95 pointer-events-none absolute inset-0"
|
||||
}`}
|
||||
>
|
||||
<div className="pixel-border bg-surface overflow-hidden">
|
||||
{/* Title bar */}
|
||||
<div className="flex items-center gap-2 px-4 py-2 bg-surface-2 border-b-2 border-border">
|
||||
<div className="w-3 h-3 bg-[#ff5f56]" />
|
||||
<div className="w-3 h-3 bg-[#ffbd2e]" />
|
||||
@@ -86,7 +71,6 @@ export function TerminalCascade() {
|
||||
cladm — {selectedCount} selected
|
||||
</span>
|
||||
</div>
|
||||
{/* Project rows */}
|
||||
<div className="p-3 font-[family-name:var(--font-mono)] text-[11px] leading-relaxed">
|
||||
<div className="text-dim mb-1 text-[10px]">
|
||||
{" PROJECT BRANCH LAST USE"}
|
||||
@@ -121,15 +105,14 @@ export function TerminalCascade() {
|
||||
<span>○</span><span> </span>[ ] pixel-engine{" "}develop{" "}3h ago
|
||||
</div>
|
||||
|
||||
{/* Enter hint */}
|
||||
<div className="mt-3 pt-2 border-t border-border text-[10px]">
|
||||
{phase === "enter" ? (
|
||||
<span className="text-accent font-bold cascade-flash">
|
||||
⏎ Launching 3 projects...
|
||||
⏎ Launching 3 sessions into grid...
|
||||
</span>
|
||||
) : (
|
||||
<span className="text-dim">
|
||||
↑↓ navigate · space toggle · enter launch
|
||||
↑↓ navigate · space toggle · enter launch grid
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
@@ -137,45 +120,92 @@ export function TerminalCascade() {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* ── Terminal cascade (effect) ── */}
|
||||
{/* ── Grid workspace (result) ── */}
|
||||
<div
|
||||
className={`transition-opacity duration-500 ${
|
||||
showCascade ? "opacity-100" : "opacity-0 pointer-events-none absolute inset-0"
|
||||
className={`transition-opacity duration-600 ${
|
||||
showGrid ? "opacity-100" : "opacity-0 pointer-events-none absolute inset-0"
|
||||
}`}
|
||||
>
|
||||
<div className="relative h-[320px]">
|
||||
{projects.map((proj, i) => (
|
||||
<div
|
||||
key={`term-${proj.name}-${cycle}`}
|
||||
className={`absolute left-0 right-0 border-2 bg-surface overflow-hidden
|
||||
${phase === "cascade" || phase === "hold" ? "cascade-in" : ""}
|
||||
${phase === "hold" && i === projects.length - 1 ? "cascade-glow" : ""}`}
|
||||
style={{
|
||||
animationDelay: `${i * 0.2}s`,
|
||||
top: `${i * 80}px`,
|
||||
marginLeft: `${i * 16}px`,
|
||||
marginRight: `${(projects.length - 1 - i) * 16}px`,
|
||||
zIndex: i + 1,
|
||||
borderColor: "var(--color-border)",
|
||||
}}
|
||||
>
|
||||
<div className="flex items-center gap-1.5 px-3 py-1 bg-surface-2 border-b border-border">
|
||||
<div className="w-[7px] h-[7px] bg-[#ff5f56]" />
|
||||
<div className="w-[7px] h-[7px] bg-[#ffbd2e]" />
|
||||
<div className="w-[7px] h-[7px] bg-[#27c93f]" />
|
||||
<span className="ml-2 font-[family-name:var(--font-mono)] text-dim text-[9px] truncate">
|
||||
claude — {proj.name}
|
||||
</span>
|
||||
<div className={`pixel-border bg-surface overflow-hidden ${phase === "hold" ? "cascade-glow" : phase === "grid" ? "cascade-in" : ""}`}>
|
||||
{/* Tab bar */}
|
||||
<div className="flex items-center bg-surface-2 border-b-2 border-border">
|
||||
<div className="px-3 py-1.5 border-b-2 border-accent font-[family-name:var(--font-mono)] text-[9px]">
|
||||
<span className="text-green">●</span>
|
||||
<span className="text-text"> acme-api</span>
|
||||
<span className="text-dim"> · </span>
|
||||
<span className="text-yellow">◉</span>
|
||||
<span className="text-text"> quantum-dash</span>
|
||||
</div>
|
||||
<div className="px-3 py-1.5 font-[family-name:var(--font-mono)] text-[9px] text-dim border-b-2 border-transparent">
|
||||
<span className="text-green">●</span>
|
||||
<span> ml-pipeline</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Pane grid */}
|
||||
<div className="grid grid-cols-2 gap-px bg-border">
|
||||
{/* Pane 1: acme-api (busy) */}
|
||||
<div className="bg-surface">
|
||||
<div className="flex items-center justify-between px-2 py-[3px] border-b border-border">
|
||||
<div className="font-[family-name:var(--font-mono)] text-[8px]">
|
||||
<span className="text-green">●</span>
|
||||
<span className="text-text"> acme-api</span>
|
||||
</div>
|
||||
<div className="flex items-center gap-[3px]">
|
||||
<span className="text-cyan text-[6px]">●</span>
|
||||
<span className="text-[#27c93f] text-[6px]">●</span>
|
||||
<span className="text-[#ff5f56] text-[6px]">●</span>
|
||||
</div>
|
||||
</div>
|
||||
<div className="p-2 font-[family-name:var(--font-mono)] text-[8px] text-dim leading-[1.6] h-[85px]">
|
||||
<div className="text-green">> I'll fix the token refresh bug</div>
|
||||
<div>Reading src/auth/token.ts...</div>
|
||||
<div>Reading src/auth/middleware.ts...</div>
|
||||
<div>Grep: refreshToken pattern<span className="cursor-blink text-accent">_</span></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Pane 2: quantum-dash (idle) */}
|
||||
<div className="bg-surface">
|
||||
<div className="flex items-center justify-between px-2 py-[3px] border-b border-border">
|
||||
<div className="font-[family-name:var(--font-mono)] text-[8px]">
|
||||
<span className="text-yellow">◉</span>
|
||||
<span className="text-dim"> 4m </span>
|
||||
<span className="text-text">quantum-dash</span>
|
||||
</div>
|
||||
<div className="flex items-center gap-[3px]">
|
||||
<span className="text-cyan text-[6px]">●</span>
|
||||
<span className="text-[#27c93f] text-[6px]">●</span>
|
||||
<span className="text-[#ff5f56] text-[6px]">●</span>
|
||||
</div>
|
||||
</div>
|
||||
<div className="p-2 font-[family-name:var(--font-mono)] text-[8px] text-dim leading-[1.6] h-[85px]">
|
||||
<div className="text-text">Updated chart component</div>
|
||||
<div className="text-text">New hook: useChartData.ts</div>
|
||||
<div className="text-yellow mt-1">Waiting for input...</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Pane 3: ml-pipeline (busy, full width) */}
|
||||
<div className="bg-surface col-span-2">
|
||||
<div className="flex items-center justify-between px-2 py-[3px] border-b border-border">
|
||||
<div className="font-[family-name:var(--font-mono)] text-[8px]">
|
||||
<span className="text-green">●</span>
|
||||
<span className="text-text"> ml-pipeline</span>
|
||||
</div>
|
||||
<div className="flex items-center gap-[3px]">
|
||||
<span className="text-cyan text-[6px]">●</span>
|
||||
<span className="text-[#27c93f] text-[6px]">●</span>
|
||||
<span className="text-[#ff5f56] text-[6px]">●</span>
|
||||
</div>
|
||||
</div>
|
||||
<div className="p-2 font-[family-name:var(--font-mono)] text-[8px] text-dim leading-[1.6] h-[65px]">
|
||||
<div className="text-green">> Building BERT fine-tuning pipeline</div>
|
||||
<div>Processing dataset: train.jsonl</div>
|
||||
<div>Epoch 3/10 <span className="text-accent">████████</span><span className="text-border">░░░░░░░░░░░░</span> 30%</div>
|
||||
</div>
|
||||
</div>
|
||||
<Image
|
||||
src="/claude-welcome.png"
|
||||
alt="Claude Code welcome screen"
|
||||
width={570}
|
||||
height={260}
|
||||
className="w-full h-auto"
|
||||
/>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user