← Files Codex Security CloudARCHIVED FILE

.internal/defense-factory-ui/src/workbench/repository-detail.tsx

17.6 KB · Oct 5, 2026 · 18:24 UTC

↓ Download file

import type { components } from "@oai/aardvark-client/components";
import { Plus as PlusIcon } from "@oai/ds/icons/plus";
import { useState, type ReactNode } from "react";
import { FormattedMessage, useIntl } from "react-intl";
import { useLocation } from "react-router";

import { AppLink, ExternalLink } from "../link";
import { DateTime, Report } from "../ui";
import { WorkbenchButton as Button, WorkbenchLink } from "./controls";
import {
  WorkbenchPageHeader,
  WorkbenchState,
  WorkbenchStatusBadge,
} from "./layout";
import { RepositoryScanActivity } from "./repository-scan-activity";
import { workbenchStyles } from "./styles";

type Configuration = components["schemas"]["AardvarkScanConfigurationResponse"];
type ConfigurationSummary =
  components["schemas"]["AardvarkScanConfigurationListItem"];
type RepositorySection = "overview" | "findings" | "scans";

function monitoringState(
  configuration: Configuration | undefined,
  configurationSummary: ConfigurationSummary | undefined,
): "active" | "paused" | "unmonitored" {
  const scanInput =
    configuration?.scan_input ?? configurationSummary?.scan_input;
  if (!scanInput || !("state" in scanInput)) {
    return "unmonitored";
  }
  return scanInput.state === "enabled" ? "active" : "paused";
}

function MonitoringStatusBadge({
  state,
}: {
  state: ReturnType<typeof monitoringState>;
}) {
  return (
    <WorkbenchStatusBadge
      variant={
        state === "active"
          ? "success"
          : state === "paused"
          ? "warning"
          : "muted"
      }
    >
      {state === "active" ? (
        <FormattedMessage
          id="codexSecurity.workbench.repositories.statusActive"
          defaultMessage="Monitoring"
          description="Repository monitoring is enabled."
        />
      ) : state === "paused" ? (
        <FormattedMessage
          id="codexSecurity.workbench.repositories.statusPaused"
          defaultMessage="Paused"
          description="Repository monitoring is paused."
        />
      ) : (
        <FormattedMessage
          id="codexSecurity.workbench.repositories.statusUnmonitored"
          defaultMessage="Not monitored"
          description="Repository does not have continuous monitoring configured."
        />
      )}
    </WorkbenchStatusBadge>
  );
}

function repositoryThreatModel(configuration: Configuration | undefined) {
  if (
    !configuration ||
    !("project_overview" in configuration.scan_input) ||
    !configuration.scan_input.project_overview
  ) {
    return null;
  }
  const raw = configuration.scan_input.project_overview;
  try {
    const value: unknown = JSON.parse(raw);
    if (
      value &&
      typeof value === "object" &&
      "threat_model" in value &&
      typeof value.threat_model === "string"
    ) {
      return value.threat_model;
    }
    return null;
  } catch {
    return raw;
  }
}

function currentStepLabel(
  step: ConfigurationSummary["current_step"],
): ReactNode {
  switch (step) {
    case "initialized":
      return "Initialized";
    case "waiting_for_new_commits":
      return "Waiting for new commits";
    case "generating_threat_model":
      return "Generating threat model";
    case "threat_model_generated":
      return "Threat model ready";
    case "scanning_commit":
      return "Scanning a commit";
    default:
      return "—";
  }
}

export function WorkbenchRepositoryDetail({
  canEditMonitoring,
  children,
  configuration,
  configurationSummary,
  defaultBranch,
  fullName,
  repoId,
  repoUrl,
  section,
  settings,
}: {
  canEditMonitoring: boolean;
  children?: ReactNode;
  configuration?: Configuration;
  configurationSummary?: ConfigurationSummary;
  defaultBranch?: string | null;
  fullName: string;
  repoId: string;
  repoUrl: string;
  section: RepositorySection;
  settings: ReactNode;
}) {
  const intl = useIntl();
  const location = useLocation();
  const [showSettings, setShowSettings] = useState(false);
  const settingsId = "repository-monitoring-settings";
  const state = monitoringState(configuration, configurationSummary);
  const continuousInput =
    configuration && "lookback_days" in configuration.scan_input
      ? configuration.scan_input
      : configurationSummary &&
        "lookback_days" in configurationSummary.scan_input
      ? configurationSummary.scan_input
      : undefined;
  const threatModel = repositoryThreatModel(configuration);
  const repositoryPath = `/repositories/${encodeURIComponent(repoId)}`;
  const repositorySearch = new URLSearchParams(location.search);
  repositorySearch.set("repo", repoUrl);
  repositorySearch.set("repo_id", repoId);
  const configurationId =
    configuration?.hid ||
    configuration?.id ||
    configurationSummary?.hid ||
    configurationSummary?.id;
  if (configurationId) {
    repositorySearch.set("scan_configuration_id", configurationId);
  }
  function sectionHref(nextSection: RepositorySection) {
    const parameters = new URLSearchParams(repositorySearch);
    if (nextSection !== section) {
      // Findings and scans use different cursor formats and pagination state.
      for (const key of [
        "cursor",
        "page",
        "commit_cursor",
        "workflow_exhausted",
        "commit_exhausted",
      ]) {
        parameters.delete(key);
      }
    }
    const path = nextSection === "overview" ? "" : `/${nextSection}`;
    return `${repositoryPath}${path}?${parameters}`;
  }

  return (
    <section className={workbenchStyles.detailPage}>
      <WorkbenchPageHeader
        kind="detail"
        title={fullName}
        titleAdornment={<MonitoringStatusBadge state={state} />}
        description={
          <ExternalLink href={repoUrl} className={workbenchStyles.link}>
            <FormattedMessage
              id="codexSecurity.workbench.repositories.openOnGithub"
              defaultMessage="View on GitHub"
              description="Open the current repository on GitHub."
            />
          </ExternalLink>
        }
        actions={
          <>
            <Button
              color="outlineSurface"
              type="button"
              aria-controls={settingsId}
              aria-expanded={showSettings}
              onClick={() => setShowSettings((visible) => !visible)}
            >
              <FormattedMessage
                id="codexSecurity.workbench.repositories.monitoringSettings.button.label"
                defaultMessage="Monitoring settings"
                description="Show the current repository's continuous monitoring settings."
              />
            </Button>
            <WorkbenchLink
              to={`/scans/new?${repositorySearch}`}
              state={location.state}
            >
              <PlusIcon className="icon-sm" />
              <FormattedMessage
                id="codexSecurity.workbench.repositories.runScan"
                defaultMessage="Run scan"
                description="Run a one-off full repository scan."
              />
            </WorkbenchLink>
          </>
        }
      />

      <nav
        aria-label={intl.formatMessage({
          id: "codexSecurity.workbench.repositories.sectionsAriaLabel",
          defaultMessage: "Repository sections",
          description:
            "Navigation for the overview, findings, and scans of one repository.",
        })}
        className="-m-1 flex items-center gap-1 overflow-x-auto p-1"
      >
        <RepositoryNavigationLink
          active={section === "overview"}
          to={sectionHref("overview")}
        >
          <FormattedMessage
            id="codexSecurity.workbench.repositories.sectionOverview"
            defaultMessage="Overview"
            description="Repository overview tab."
          />
        </RepositoryNavigationLink>
        <RepositoryNavigationLink
          active={section === "findings"}
          to={sectionHref("findings")}
        >
          <FormattedMessage
            id="codexSecurity.workbench.repositories.sectionFindings"
            defaultMessage="Findings"
            description="Repository findings tab."
          />
        </RepositoryNavigationLink>
        <RepositoryNavigationLink
          active={section === "scans"}
          to={sectionHref("scans")}
        >
          <FormattedMessage
            id="codexSecurity.workbench.repositories.sectionScans"
            defaultMessage="Scans"
            description="Repository scans tab."
          />
        </RepositoryNavigationLink>
      </nav>

      {showSettings ? (
        <div id={settingsId} className="space-y-3">
          {!canEditMonitoring && configuration ? (
            <WorkbenchState variant="inline">
              <FormattedMessage
                id="codexSecurity.workbench.repositories.monitoringSettings.readOnly"
                defaultMessage="You can view these monitoring settings, but only the owner or a workspace administrator can change them."
                description="Read-only notice above repository monitoring settings."
              />
            </WorkbenchState>
          ) : null}
          {settings}
        </div>
      ) : null}

      {children ?? (
        <div className="space-y-6">
          <section className={`${workbenchStyles.card} space-y-5 p-6`}>
            <div className="space-y-1">
              <h2 className={workbenchStyles.sectionTitle}>
                <FormattedMessage
                  id="codexSecurity.workbench.repositories.monitoringHeading"
                  defaultMessage="Continuous monitoring"
                  description="Repository overview heading for continuous commit monitoring."
                />
              </h2>
              <p className={workbenchStyles.description}>
                {state === "paused" ? (
                  <FormattedMessage
                    id="codexSecurity.workbench.repositories.monitoringPaused.description"
                    defaultMessage="Monitoring is paused. New commits will not be reviewed automatically."
                    description="Repository monitoring is currently paused."
                  />
                ) : (
                  <FormattedMessage
                    id="codexSecurity.workbench.repositories.monitoringDescription"
                    defaultMessage="Review new commits automatically as your repository changes."
                    description="Explanation of continuous repository monitoring."
                  />
                )}
              </p>
            </div>
            <dl className="divide-token-border-light divide-y">
              <RepositoryMetadataRow
                label={intl.formatMessage({
                  id: "codexSecurity.workbench.repositories.metadataStatus",
                  defaultMessage: "Status",
                  description: "Repository monitoring status label.",
                })}
                value={<MonitoringStatusBadge state={state} />}
              />
              <RepositoryMetadataRow
                label={intl.formatMessage({
                  id: "codexSecurity.workbench.repositories.metadataBranch",
                  defaultMessage: "Default branch",
                  description: "Repository default branch label.",
                })}
                value={defaultBranch ?? "—"}
              />
              <RepositoryMetadataRow
                label={intl.formatMessage({
                  id: "codexSecurity.workbench.repositories.metadataOwner",
                  defaultMessage: "Monitoring owner",
                  description: "Repository monitoring owner label.",
                })}
                value={
                  configuration?.owner?.email ??
                  configurationSummary?.owner?.email ??
                  "—"
                }
              />
              {configuration?.updated_at || configurationSummary?.updated_at ? (
                <RepositoryMetadataRow
                  label={intl.formatMessage({
                    id: "codexSecurity.workbench.repositories.metadataMonitoringUpdated",
                    defaultMessage: "Monitoring settings updated",
                    description:
                      "Timestamp of the last monitoring-settings update.",
                  })}
                  value={
                    <DateTime
                      value={
                        configuration?.updated_at ??
                        configurationSummary!.updated_at
                      }
                    />
                  }
                />
              ) : null}
              {continuousInput?.lookback_days != null ? (
                <RepositoryMetadataRow
                  label={intl.formatMessage({
                    id: "codexSecurity.workbench.repositories.metadataHistory",
                    defaultMessage: "Commit history",
                    description:
                      "Configured continuous-monitoring lookback period.",
                  })}
                  value={intl.formatMessage(
                    {
                      id: "codexSecurity.workbench.repositories.metadataHistoryValue",
                      defaultMessage:
                        "{days, plural, one {# day} other {# days}}",
                      description:
                        "Number of days of commit history monitored.",
                    },
                    { days: continuousInput.lookback_days },
                  )}
                />
              ) : null}
              {state === "active" && configurationSummary?.current_step ? (
                <RepositoryMetadataRow
                  label={intl.formatMessage({
                    id: "codexSecurity.workbench.repositories.metadataLastReportedActivity",
                    defaultMessage: "Last reported activity",
                    description:
                      "Last activity recorded by continuous monitoring.",
                  })}
                  value={currentStepLabel(configurationSummary.current_step)}
                />
              ) : null}
            </dl>
          </section>

          <RepositoryScanActivity
            configurationId={configurationId}
            configurationRecordIds={[
              configuration?.id,
              configuration?.hid,
              configurationSummary?.id,
              configurationSummary?.hid,
            ].filter((value): value is string => Boolean(value))}
            repoConnectorId={
              configuration?.scan_input.repo_connector_id ??
              configurationSummary?.scan_input.repo_connector_id ??
              null
            }
            repoId={repoId}
            repoUrl={repoUrl}
          />

          {configurationSummary ? (
            <section className={`${workbenchStyles.card} space-y-3 p-6`}>
              <h2 className={workbenchStyles.sectionTitle}>
                <FormattedMessage
                  id="codexSecurity.workbench.repositories.threatModel.title"
                  defaultMessage="Threat model"
                  description="Repository threat model heading."
                />
              </h2>
              {configuration && threatModel ? (
                <Report>{threatModel}</Report>
              ) : !configuration ? (
                <p className={workbenchStyles.description}>
                  <FormattedMessage
                    id="codexSecurity.workbench.repositories.threatModel.unavailable"
                    defaultMessage="Threat model details are unavailable."
                    description="Privacy-preserving message when a monitored repository's threat model cannot be loaded."
                  />
                </p>
              ) : (
                <p className={workbenchStyles.description}>
                  <FormattedMessage
                    id="codexSecurity.workbench.repositories.threatModel.empty"
                    defaultMessage="No threat model is available yet."
                    description="Repository has monitoring but no generated threat model."
                  />
                </p>
              )}
            </section>
          ) : (
            <section className={`${workbenchStyles.card} space-y-2 p-6`}>
              <h2 className={workbenchStyles.sectionTitle}>
                <FormattedMessage
                  id="codexSecurity.workbench.repositories.setupHeading"
                  defaultMessage="Set up monitoring"
                  description="Heading for an unmonitored repository."
                />
              </h2>
              <p className={workbenchStyles.description}>
                <FormattedMessage
                  id="codexSecurity.workbench.repositories.setupDescription"
                  defaultMessage="Configure continuous monitoring to review new commits and generate a threat model for this repository."
                  description="Explanation of repository monitoring setup."
                />
              </p>
            </section>
          )}
        </div>
      )}
    </section>
  );
}

function RepositoryNavigationLink({
  active,
  children,
  to,
}: {
  active: boolean;
  children: ReactNode;
  to: string;
}) {
  return (
    <AppLink
      aria-current={active ? "page" : undefined}
      className={[
        "df-workbench-navigation-tab rounded-full px-3 py-2 whitespace-nowrap",
        active
          ? "bg-token-bg-secondary text-token-text-primary"
          : "text-token-text-secondary hover:bg-token-bg-tertiary hover:text-token-text-primary",
      ].join(" ")}
      to={to}
    >
      {children}
    </AppLink>
  );
}

function RepositoryMetadataRow({
  label,
  value,
}: {
  label: string;
  value: ReactNode;
}) {
  return (
    <div className="grid min-h-12 gap-1 py-3 sm:grid-cols-[minmax(0,1fr)_minmax(0,2fr)] sm:items-center sm:gap-5">
      <dt className={workbenchStyles.metadataLabel}>{label}</dt>
      <dd
        className={`${workbenchStyles.metadataValue} min-w-0 break-words sm:text-end`}
      >
        {value}
      </dd>
    </div>
  );
}

SHA-256: 82d6109895de560efebceba39941d727d4e558ead3748d68c24ce87debcb7cc7