Intelligence

Artifacts

Browse the repository, read documents, and manage the governance folders. Source, runtime, and infrastructure are read-only.

Repository
.gitignoreDockerfilenext-env.d.tsnext.config.mjspackage-lock.jsonpackage.jsonpostcss.config.mjsREADME.mdtailwind.config.tstsconfig.jsontsconfig.tsbuildinfo
README.md
CONSTITUTION_COMPLIANCE_AUDIT_V1.mdREADME.md
repositories/aaf-holdings/hq01/components/sessions/session-status-badge.tsx
2.3 KB
import { cn } from "@/lib/utils";
import type { SessionStatus } from "@/lib/sessions/types";

/**
 * Status pill for a Claude session. Kept separate from the content StatusBadge
 * because session lifecycle states ("running", "exited"…) are distinct from
 * mission/work-order statuses — the two vocabularies should not be conflated.
 */

const STYLES: Record<
  SessionStatus,
  { dot: string; text: string; bg: string; pulse?: boolean; label: string }
> = {
  starting: {
    dot: "bg-amber-500",
    text: "text-amber-700",
    bg: "bg-amber-50",
    pulse: true,
    label: "Starting",
  },
  running: {
    dot: "bg-emerald-500",
    text: "text-emerald-700",
    bg: "bg-emerald-50",
    pulse: true,
    label: "Running",
  },
  stopped: {
    dot: "bg-slate-400",
    text: "text-slate-600",
    bg: "bg-slate-100",
    label: "Stopped",
  },
  exited: {
    dot: "bg-teal-500",
    text: "text-teal-700",
    bg: "bg-teal-50",
    label: "Exited",
  },
  completed: {
    dot: "bg-emerald-500",
    text: "text-emerald-700",
    bg: "bg-emerald-50",
    label: "Completed",
  },
  completed_missing_report: {
    dot: "bg-amber-500",
    text: "text-amber-700",
    bg: "bg-amber-50",
    label: "Completed · no report",
  },
  terminated: {
    dot: "bg-slate-400",
    text: "text-slate-600",
    bg: "bg-slate-100",
    label: "Terminated",
  },
  failed: {
    dot: "bg-red-500",
    text: "text-red-700",
    bg: "bg-red-50",
    label: "Failed",
  },
  unknown: {
    dot: "bg-slate-300",
    text: "text-slate-500",
    bg: "bg-slate-100",
    label: "Unknown",
  },
};

export function SessionStatusBadge({
  status,
  className,
}: {
  status: SessionStatus;
  className?: string;
}) {
  const s = STYLES[status] ?? STYLES.unknown;
  return (
    <span
      className={cn(
        "inline-flex items-center gap-1.5 rounded-full px-2.5 py-0.5 text-xs font-medium",
        s.bg,
        s.text,
        className,
      )}
    >
      <span className="relative flex h-1.5 w-1.5">
        {s.pulse && (
          <span
            className={cn(
              "absolute inline-flex h-full w-full animate-ping rounded-full opacity-75",
              s.dot,
            )}
          />
        )}
        <span className={cn("relative inline-flex h-1.5 w-1.5 rounded-full", s.dot)} />
      </span>
      {s.label}
    </span>
  );
}

root · /srv/aaf