1import type { PullRequestReviewGuideResult } from "@t3tools/contracts";
2
3/** Old failures must not follow a PR onto a different head. */
4export function reviewGuideState(data: PullRequestReviewGuideResult | null) {
5 const guide = data?.guide ?? null;
6 return {
7 guide,
8 running: data?.run?._tag === "Running",
9 stale: guide !== null && data?.currentHeadSha != null && guide.headSha !== data.currentHeadSha,
10 failure:
11 data?.run?._tag === "Failed" && data.run.headSha === data.currentHeadSha
12 ? data.run.detail
13 : null,
14 };
15}
16
17/** A pending refresh must not hide cached content, or a new run reveal an old failure. */
18export function guideNoticeState(state: {
19 readonly data: PullRequestReviewGuideResult | null;
20 readonly isPending: boolean;
21 readonly running: boolean;
22 readonly startError: string | null;
23 readonly error: string | null;
24}) {
25 const { guide, stale, failure } = reviewGuideState(state.data);
26 if (state.running) {
27 return {
28 kind: "writing" as const,
29 title: "Rewriting guide",
30 description: guide
31 ? "You can keep reading this guide while the agent writes the update."
32 : "An agent is reading the change and writing the tour. You can leave and come back when it’s ready.",
33 action: guide ? "Rewriting…" : "Writing guide…",
34 };
35 }
36 const error = state.startError ?? failure;
37 if (error) {
38 return {
39 kind: "failed" as const,
40 title: "Could not write guide",
41 description: error,
42 action: "Try again",
43 };
44 }
45 if (state.error) {
46 return {
47 kind: "unavailable" as const,
48 title: "Could not refresh guide",
49 description: state.error,
50 action: "Try again",
51 };
52 }
53 if (!state.data) {
54 return {
55 kind: "loading" as const,
56 title: "Review guide",
57 description: "Checking for a saved guide…",
58 action: "Loading guide…",
59 };
60 }
61 if (stale) {
62 return {
63 kind: "stale" as const,
64 title: "New changes since this guide",
65 description: "You can read the previous guide, or rewrite it for the latest changes.",
66 action: "Rewrite guide",
67 };
68 }
69 return {
70 kind: guide ? ("ready" as const) : ("empty" as const),
71 title: "Review guide",
72 description:
73 "Get a tour of the change, with code excerpts and notes on what needs a closer look.",
74 action: "Write guide",
75 };
76}