Intelligence

Artifacts

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

Repository
README.md
CONSTITUTION_COMPLIANCE_AUDIT_V1.mdREADME.md
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