diff --git a/site/app/layout.tsx b/site/app/layout.tsx
index 3acd0b5..42f6439 100644
--- a/site/app/layout.tsx
+++ b/site/app/layout.tsx
@@ -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"],
},
};
diff --git a/site/app/page.tsx b/site/app/page.tsx
index 90b4af5..824af9b 100644
--- a/site/app/page.tsx
+++ b/site/app/page.tsx
@@ -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 (
+
+ {/* Pane title bar */}
+
+
+ {status === "busy" ? (
+ ●
+ ) : (
+ <>
+ ◉
+ {elapsed && {elapsed}}
+ >
+ )}
+ {name}
+
+
+ ●
+ ─
+ ●
+ ●
+
+
+ {/* Pane content */}
+
+ {children}
+
+
+ );
+}
+
export default function Home() {
return (
+
{/* ══════ HERO ══════ */}
- {/* Grid background */}
- MULTI-PROJECT CLAUDE CODE MONITOR
+ CLAUDE CODE COMMAND CENTER
- 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.
{/* Install command */}
@@ -169,7 +208,7 @@ export default function Home() {
- {/* Right — terminal cascade */}
+ {/* Right — terminal cascade: picker → grid */}
@@ -186,50 +225,185 @@ export default function Home() {
- {/* ══════ DEMO GIF ══════ */}
+ {/* ══════ THE WORKSPACE ══════ */}
-
+
- // SEE IT IN ACTION
+ // THE WORKSPACE
+
+ 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.
+
-
-
-
+ {/* Grid workspace mockup */}
+
+
+ {/* Tab bar */}
+
+
+ ●
+ acme-api
+ ·
+ ◉
+ quantum-dash
+
+
+ ●
+ ml-pipeline
+ ·
+ ●
+ infra-k8s
+
+
+ + add pane
+
+
+
+ {/* Pane grid */}
+
+ {/* Pane 1: acme-api */}
+
+ > I'll analyze the authentication module and
+ {" "}fix the token refresh bug you mentioned.
+
+ ⏺ Reading src/auth/token.ts
+
+
+ ⏺ Reading src/auth/middleware.ts
+
+
+ ⏺ Grep: refreshToken pattern
+
+
+ Found 3 files with stale token logic.
+ _
+
+
+
+ {/* Pane 2: quantum-dash */}
+
+ I've updated the chart component to use
+ the new streaming data format. Changes:
+
+ ✓ src/components/chart.tsx
+
+
+ ✓ src/hooks/useChartData.ts
+
+
+ ✓ src/types/stream.d.ts
+
+ Waiting for your input...
+
+
+ {/* Pane 3: ml-pipeline */}
+
+ > Building the BERT fine-tuning pipeline
+ {" "}with the new training dataset.
+
+ ⏺ Writing src/train.py
+
+
+ Processing: epoch 3/10{" "}
+ ████████
+ ░░░░░░░░░░░░{" "}
+ 30%
+
+
+
+ {/* Pane 4: infra-k8s */}
+
+ > Updating the Kubernetes deployment
+ {" "}manifests for staging.
+
+ ⏺ Reading k8s/staging/deployment.yaml
+
+
+ ⏺ Reading k8s/staging/service.yaml
+
+
+ Scaling replicas 2 → 4 for load test
+ _
+
+
+
+
+
+
+ {/* Feature callouts */}
+
+
+
+ Embedded PTY Grid
+
+
+ Each pane runs a real pseudo-terminal via forkpty(). Full I/O, ANSI colors, resize — no tmux needed.
+
+
+
+
+ Tabbed Workspaces
+
+
+ Group sessions into tabs. Inline pane names with status icons show what's running at a glance.
+
+
+
+
+ Pane Controls
+
+
+ Traffic-light buttons on every pane: close, expand, minimize, plus a folder-open button. Fully mouse-driven.
+
+
+
- {/* ══════ SCREENSHOTS ══════ */}
+ {/* ══════ SMART PICKER ══════ */}
-
- // SCREENSHOTS
-
+
+
+ // THE SMART PICKER
+
+
+ It starts with a smart project picker. cladm reads{" "}
+ ~/.claude/history.jsonl 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.
+
+
-
- {/* Main view */}
+
+
+
+
+
+
+ {/* Picker screenshots */}
+
-
+
-
- All your projects sorted by recent Claude usage. Git branch, sync
- status, dirty state, session count, and auto-detected stack at a
- glance.
+
+ Sorted by recent Claude usage. Git metadata, session count, and stack tags at a glance.
-
+
- {/* Expanded view */}
-
+
-
- Press → to expand. Browse branches, see
- session conversations with last prompt and Claude's response.
- Running sessions show ● running or{" "}
- ◉ idle status inline. Resume any session directly.
+
+ Browse branches, past sessions with conversation previews. Resume any session directly.
-
+
- // LIVE SESSION MONITORING
+ // REAL-TIME STATUS
-
-
-
- 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.
-
-
-
-
- ●
- Busy
- — Claude is actively processing
-
-
- ◉
- 3m
- Idle
- — Claude finished 3 min ago, waiting for input
-
-
- ○
- No session
- — No active Claude process
-
-
-
-
-
- Detection reads the tail of each session's JSONL in{" "}
- ~/.claude/projects/. 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.
-
-
-
-
-
-
-
-
- {/* ══════ USAGE + IDLE PANELS ══════ */}
-
-
- // USAGE & IDLE PANELS
-
-
-
- {/* Usage panel screenshot */}
-
-
-
-
- USAGE TRACKING
+
+
+ {/* Status indicators */}
+
+
+ Session Status
-
+
+
+ ●
+ Busy
+ — Claude is actively working
+
+
+ ◉
+ 3m
+ Idle
+ — waiting for your input
+
+
+ ○
+ No session
+ — not running
+
+
+
+
+ Status visible in both picker rows and grid pane headers.
+ Sound + dock bounce on idle transitions.
+
+
-
- Press u to toggle. Tracks session (5h window), weekly
- all-model and sonnet-only costs against configurable plan limits, plus monthly totals.
-
-
-
-
-
- {/* Idle sessions screenshot */}
-
-
-
-
- IDLE SESSIONS
+ {/* Usage tracking */}
+
+
+ Usage Tracking
-
+
+
+
+ session (5h)
+ $2.40 / $5.00
+
+
+
+
+
+ weekly all-model
+ $18.50 / $100
+
+
+
+
+
+ monthly total
+ $67.20
+
+
+
+
+
+
+ Press u in picker mode. Tracks session, weekly,
+ and monthly costs against configurable plan limits.
+
+
-
- Press i to toggle. Shows sessions waiting for your
- input, sorted by most recently idle. Press Enter to focus a session's
- Terminal tab directly.
-
-
-
-
@@ -384,81 +533,84 @@ export default function Home() {
+ }
+ 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."
+ />
+ }
+ title="TABBED WORKSPACES"
+ desc="Group sessions into named tabs. Inline pane indicators show project names and busy/idle status at a glance."
+ />
+ }
+ title="PANE CONTROLS"
+ desc="Traffic-light buttons on every pane: close, minimize, expand to full screen. Blue button opens the project folder."
+ />
+ }
+ 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."
+ />
}
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."
/>
}
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."
/>
}
title="NOTIFICATIONS"
desc="Sound + dock bounce when any session finishes. Never miss a completed task across dozens of parallel sessions."
/>
- }
- title="FOCUS SESSION"
- desc="Press Enter on any idle session to instantly focus its Terminal tab. Flash animation highlights the window."
- />
- }
- title="AUTO-DISCOVERY"
- desc="Reads ~/.claude/history.jsonl to find every project you've used with Claude Code. No config needed."
- />
- }
- title="GIT METADATA"
- desc="Branch, sync status (ahead/behind), last commit, dirty state — all loaded in parallel per project."
- />
}
- 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."
/>
}
- title="PARALLEL LAUNCH"
- desc="Select multiple projects and hit Enter. Each opens in a new Terminal.app window simultaneously."
- />
- }
- title="STACK DETECTION"
- desc="Auto-detects project stack: TypeScript, Python, Rust, Go, Docker, and more from config files."
+ icon={}
+ title="DIRECT PTY"
+ desc="Native pseudo-terminal management via forkpty(). No tmux dependency. Zero configuration. Just works."
/>
- {/* ══════ KEYBINDINGS ══════ */}
+ {/* ══════ CONTROLS ══════ */}
// CONTROLS
-
+
+ {/* Picker mode */}
-
+
+ Picker Mode
+
+
{[
["↑ ↓", "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]) => (
{key}
@@ -467,12 +619,58 @@ export default function Home() {
))}
+
+ {/* Grid mode */}
+
+
+ Grid Mode
+
+
+ {[
+ ["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]) => (
+
+ ))}
+
+
+
+
+ Pane Buttons
+
+
+ {[
+ ["● blue", "Open folder"],
+ ["● green", "Expand pane"],
+ ["● yellow", "Minimize"],
+ ["● red", "Close pane"],
+ ].map(([key, desc], i) => (
+
+ ))}
+
+
+
- {/* ══════ INSTALL ══════ */}
+ {/* ══════ QUICK START ══════ */}
// QUICK START
@@ -514,91 +712,13 @@ export default function Home() {
- Or try with mock data:{" "}
+ Try with mock data:{" "}
cladm --demo
- {/* ══════ LAUNCH RESULT ══════ */}
-
-
- // HIT ENTER
-
-
- 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.
-
-
-
- {/* Mini cladm picker */}
-
-
-
-
- {" PROJECT BRANCH LAST USE"}
-
-
- ●
- [✓]
-
- {" "}
- acme-api{" "}
-
- main
- {" "}25m ago
-
-
- ◉
- 2m
- [✓]
- quantum-dashboard{" "}
- feat/cha
- {" "}1h ago
-
-
- ●
- [✓]
- ml-pipeline{" "}
- exp/bert
- {" "}just now
-
-
- ○
- [ ]
- pixel-engine{" "}develop{" "}3h ago
-
-
-
-
-
- {/* Arrow */}
-
- >>>
-
-
- {/* Claude Code terminals */}
-
-
- {/* Stacked terminal windows effect */}
-
-
-
-
-
-
-
-
-
-
{/* ══════ NEWSLETTER ══════ */}
@@ -665,7 +785,7 @@ export default function Home() {
- 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.
diff --git a/site/app/terminal-cascade.tsx b/site/app/terminal-cascade.tsx
index 88263cd..8eaf911 100644
--- a/site/app/terminal-cascade.tsx
+++ b/site/app/terminal-cascade.tsx
@@ -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("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 (
-
- {/* ── CLADM console (cause) ── */}
+
+ {/* ── Picker (select projects) ── */}
- {/* Title bar */}
@@ -86,7 +71,6 @@ export function TerminalCascade() {
cladm — {selectedCount} selected
- {/* Project rows */}
{" PROJECT BRANCH LAST USE"}
@@ -121,15 +105,14 @@ export function TerminalCascade() {
○ [ ] pixel-engine{" "}develop{" "}3h ago
- {/* Enter hint */}
{phase === "enter" ? (
- ⏎ Launching 3 projects...
+ ⏎ Launching 3 sessions into grid...
) : (
- ↑↓ navigate · space toggle · enter launch
+ ↑↓ navigate · space toggle · enter launch grid
)}
@@ -137,45 +120,92 @@ export function TerminalCascade() {
- {/* ── Terminal cascade (effect) ── */}
+ {/* ── Grid workspace (result) ── */}
-
- {projects.map((proj, i) => (
-
-
-
-
-
-
- claude — {proj.name}
-
-
-
+
+ {/* Tab bar */}
+
+
+ ●
+ acme-api
+ ·
+ ◉
+ quantum-dash
- ))}
+
+ ●
+ ml-pipeline
+
+
+
+ {/* Pane grid */}
+
+ {/* Pane 1: acme-api (busy) */}
+
+
+
+ ●
+ acme-api
+
+
+ ●
+ ●
+ ●
+
+
+
+
> I'll fix the token refresh bug
+
Reading src/auth/token.ts...
+
Reading src/auth/middleware.ts...
+
Grep: refreshToken pattern_
+
+
+
+ {/* Pane 2: quantum-dash (idle) */}
+
+
+
+ ◉
+ 4m
+ quantum-dash
+
+
+ ●
+ ●
+ ●
+
+
+
+
Updated chart component
+
New hook: useChartData.ts
+
Waiting for input...
+
+
+
+ {/* Pane 3: ml-pipeline (busy, full width) */}
+
+
+
+ ●
+ ml-pipeline
+
+
+ ●
+ ●
+ ●
+
+
+
+
> Building BERT fine-tuning pipeline
+
Processing dataset: train.jsonl
+
Epoch 3/10 ████████░░░░░░░░░░░░ 30%
+
+
+