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/mission-control/page.tsx
3.7 KB
import Link from "next/link";
import { Rocket, ChevronRight } from "lucide-react";
import { PageHeader } from "@/components/layout/page-header";
import { Card } from "@/components/ui/card";
import { EmptyState } from "@/components/shared/empty-state";
import { PriorityBadge } from "@/components/shared/status-badge";
import { MissionStatusBadge } from "@/components/missions/mission-status-badge";
import { CreateMissionForm } from "@/components/missions/create-mission-form";
import { listMissions } from "@/lib/missions/manager";
import { isExecutable } from "@/lib/missions/lifecycle";
import { loadRegistry } from "@/lib/executives/registry";
/**
* Mission Control — the Mission Registry surface (PASS M0). Missions are the
* permanent objects all execution attaches to. (The legacy content-based
* "Mission Sessions" view at /missions is left untouched.)
*/
export const dynamic = "force-dynamic";
export const metadata = { title: "Mission Control" };
export default function MissionControlPage() {
const missions = listMissions();
const owners = loadRegistry().map((e) => ({
id: e.id,
label: `${e.displayName} — ${e.office}`,
active: e.status === "active",
}));
return (
<div>
<PageHeader
eyebrow="Operate"
title="Mission Control"
description="Every mission is a governed change the organization is making. All execution attaches to a mission."
actions={<CreateMissionForm owners={owners} defaultRepository="aaf-holdings" />}
/>
{missions.length === 0 ? (
<EmptyState
icon={Rocket}
title="No missions yet"
description="Create a mission to begin. Dispatched executive work must belong to a mission."
hint="/srv/aaf/missions/MISSION-000001/"
/>
) : (
<div className="overflow-hidden rounded-lg border border-border bg-card divide-y divide-border">
{missions.map((m) => (
<Link
key={m.id}
href={`/mission-control/${m.id}`}
className="group flex items-center gap-4 px-4 py-3.5 transition-colors hover:bg-secondary/60"
>
<div className="min-w-0 flex-1">
<div className="flex items-center gap-2.5">
<span className="font-mono text-xs font-medium text-muted-foreground">
{m.id.replace("MISSION-", "M-")}
</span>
<span className="truncate text-[14px] font-medium text-foreground">
{m.title}
</span>
</div>
<div className="mt-0.5 flex flex-wrap items-center gap-x-3 gap-y-0.5 text-[12px] text-muted-foreground">
<span className="font-mono">{m.executive_owner ?? "unassigned"}</span>
<span>· {m.product}</span>
<span className="font-mono">· {m.repository}</span>
<span>· updated {new Date(m.updated_at).toLocaleString()}</span>
</div>
</div>
<div className="hidden shrink-0 items-center gap-2 sm:flex">
{isExecutable(m.status) && (
<span className="inline-flex items-center gap-1 rounded-full bg-emerald-50 px-2 py-0.5 text-[10px] font-medium text-emerald-700">
dispatchable
</span>
)}
<PriorityBadge priority={m.priority} />
<MissionStatusBadge status={m.status} />
</div>
<ChevronRight className="h-4 w-4 shrink-0 text-muted-foreground/40 transition-colors group-hover:text-foreground" />
</Link>
))}
</div>
)}
</div>
);
}
root · /srv/aaf