import { Button, CONTROL_TOOLTIP_DELAY, Icon, InlineCode, LoadingIcon, Tooltip, } from "@yaakapp-internal/ui"; import classNames from "classnames"; import { useAtomValue } from "jotai"; import type { ReactNode } from "react"; import { useDecryptList, useEditDecryptList } from "../hooks/useDecryptList"; import { useRpcMutation } from "../hooks/useRpcMutation"; import { everythingEdit } from "../lib/decrypt"; import { decryptStep } from "../lib/firstRun"; import { encryptingPercent } from "../lib/encrypting"; import { proxyStateAtom } from "../lib/store"; import { useCopyEnvironment, useProxySetup, useSystemProxySwitch } from "./ProxyStatus"; type StepState = "todo" | "next" | "wait" | "done" | "fail"; /** * The list's empty state until traffic arrives: trust the certificate, turn on the system proxy, * choose what to decrypt, then see traffic. Not dismissable and nothing remembered; the first flow replaces it. Copy * environment beside it serves someone who wants one terminal proxied and nothing system-wide. */ export function FirstRun() { const proxyState = useAtomValue(proxyStateAtom); const setup = useProxySetup(); const { caStatus, trust, systemProxy, setSystemProxy } = setup; const systemSwitch = useSystemProxySwitch(setup); const execute = useRpcMutation("execute_action"); const retry = useRpcMutation("take_over"); const copyEnvironment = useCopyEnvironment(); const decryptList = useDecryptList(); const saveDecryptList = useEditDecryptList(); const running = proxyState?.state === "running"; // Changed only by the process that owns the engine, so not from here while the CLI does. const otherOwner = proxyState?.otherOwner != null; const recording = proxyState?.recording !== false; const trusted = caStatus.data?.trusted === true; const systemSupported = systemProxy.data?.supported !== false; const systemOn = systemProxy.data?.enabled === true; const trustState: StepState = trusted ? "done" : trust.isPending ? "wait" : trust.error != null ? "fail" : "next"; const systemState: StepState = setSystemProxy.isPending ? "wait" : systemOn ? "done" : systemSwitch.failed ? "fail" : trusted ? "next" : "todo"; const decrypt = decryptStep(decryptList, trusted); const everything = decrypt.choice === "everything"; const setEverything = (on: boolean) => saveDecryptList.mutate(everythingEdit(on)); const ready = trusted && (systemOn || !systemSupported); const encrypting = !running && !otherOwner ? encryptingPercent(proxyState) : null; const trafficState: StepState = encrypting != null ? "wait" : !running && !otherOwner ? "fail" : ready ? "wait" : "todo"; return (