146 lines · 5.2 KB
import { useState } from "react";
import type { ReactNode } from "react";
import { applyPullMergeFix } from "~/fns/mergefix";
import type { MergeFix, PullParams } from "~/hooks/use-merge-fix";
import { useAction } from "~/hooks/use-action";
import { Badge } from "~/ui/Badge";
import { Button } from "~/ui/Button";
import { ErrorBanner } from "~/ui/Callout";
import { cn } from "~/utils/cn";

type FixFile = NonNullable<MergeFix>["files"][number];

function percent(value: number): string {
  return `${Math.round(value * 100)}%`;
}

function DiffView({ diff }: { diff: string }) {
  return (
    <pre className="max-h-80 overflow-auto rounded-md border border-gray-800 bg-gray-950 p-2 font-mono text-xs leading-5">
      {diff.split("\n").map((line, index) => (
        <div
          // oxlint-disable-next-line no-array-index-key -- diff lines have no identity beyond position
          key={index}
          className={cn(
            line.startsWith("+") && !line.startsWith("+++") && "bg-success-950 text-success-300",
            line.startsWith("-") && !line.startsWith("---") && "bg-danger-950 text-danger-300",
            line.startsWith("@@") && "text-accent-300",
            !/^[-+@]/.test(line) && "text-gray-400",
          )}
        >
          {line || " "}
        </div>
      ))}
    </pre>
  );
}

function Reasoning({ file }: { file: Extract<FixFile, { status: "planned" }> }) {
  const confidences = file.hunks.map((hunk) => (hunk.selected ? (hunk.probabilities[hunk.selected] ?? 0) : 0));
  return (