Intelligence
Artifacts
Browse the repository, read documents, and manage the governance folders. Source, runtime, and infrastructure are read-only.
Repository
repositories/aaf-holdings/hq01/app/sessions/page.tsx
2.2 KB
import { SquareTerminal } from "lucide-react";
import { PageHeader } from "@/components/layout/page-header";
import { EmptyState } from "@/components/shared/empty-state";
import { SessionCard } from "@/components/sessions/session-card";
import { StartSessionLauncher } from "@/components/sessions/start-session-launcher";
import { AutoRefresh } from "@/components/sessions/auto-refresh";
import { listSessions } from "@/lib/sessions/manager";
import { SESSION_PRESETS } from "@/lib/sessions/presets";
/**
* Sessions dashboard — the management surface for Claude CLI sessions running on
* HQ01. Server-rendered from the filesystem (no database); kept live by a small
* client-side AutoRefresh that re-reads state every few seconds.
*/
export const dynamic = "force-dynamic";
export const metadata = { title: "Sessions" };
export default function SessionsPage() {
const sessions = listSessions();
const running = sessions.filter(
(s) => s.status === "running" || s.status === "starting",
).length;
return (
<div>
<AutoRefresh intervalMs={5000} />
<PageHeader
eyebrow="Operate"
title="Sessions"
description="Claude CLI sessions running on HQ01. Start a session, lock your phone, and come back to read its logs and status — the process keeps running on the server."
actions={<StartSessionLauncher presets={SESSION_PRESETS} />}
/>
{sessions.length > 0 && (
<div className="mb-5 text-[13px] text-muted-foreground">
{sessions.length} session{sessions.length === 1 ? "" : "s"} ·{" "}
<span className="font-medium text-foreground">{running}</span> running
</div>
)}
{sessions.length === 0 ? (
<EmptyState
icon={SquareTerminal}
title="No sessions yet"
description="Start a session to launch a Claude CLI process on HQ01. It runs in the background and streams its output to the logs."
hint="/srv/aaf/runtime/claude/sessions/"
/>
) : (
<div className="grid grid-cols-1 gap-4 sm:grid-cols-2 xl:grid-cols-3">
{sessions.map((s) => (
<SessionCard key={s.id} session={s} />
))}
</div>
)}
</div>
);
}
root · /srv/aaf