fix: address pr review follow-ups
This commit is contained in:
parent
4dac245b81
commit
7bc98aa387
|
|
@ -203,6 +203,15 @@ describe("parsePrFromUrl", () => {
|
|||
});
|
||||
});
|
||||
|
||||
it("parses GitHub pull request URLs with trailing path segments", () => {
|
||||
expect(parsePrFromUrl("https://github.com/foo/bar/pull/123/files")).toEqual({
|
||||
owner: "foo",
|
||||
repo: "bar",
|
||||
number: 123,
|
||||
url: "https://github.com/foo/bar/pull/123/files",
|
||||
});
|
||||
});
|
||||
|
||||
it("returns null when the URL has no PR number", () => {
|
||||
expect(parsePrFromUrl("https://example.com/foo/bar/pull/not-a-number")).toBeNull();
|
||||
});
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ export function parsePrFromUrl(prUrl: string): ParsedPrUrl | null {
|
|||
const pathSegments = parsedUrl?.pathname.split("/").filter(Boolean) ?? [];
|
||||
|
||||
const githubStylePullIndex = pathSegments.findIndex((segment) => segment === "pull");
|
||||
if (githubStylePullIndex >= 2 && githubStylePullIndex === pathSegments.length - 2) {
|
||||
if (githubStylePullIndex >= 2 && githubStylePullIndex + 1 < pathSegments.length) {
|
||||
const owner = pathSegments[githubStylePullIndex - 2];
|
||||
const repo = pathSegments[githubStylePullIndex - 1];
|
||||
const prNumber = pathSegments[githubStylePullIndex + 1];
|
||||
|
|
|
|||
|
|
@ -226,7 +226,8 @@ export function SessionDetailPRCard({
|
|||
{pr.ciChecks.length > 0 ? (
|
||||
<>
|
||||
<div className="session-detail-pr-sep" />
|
||||
{pr.ciChecks.map((check) => {
|
||||
{pr.ciChecks.map((check, index) => {
|
||||
const key = check.url ?? `${check.name}-${index}`;
|
||||
const chip = (
|
||||
<span
|
||||
className={cn(
|
||||
|
|
@ -252,7 +253,7 @@ export function SessionDetailPRCard({
|
|||
);
|
||||
return check.url ? (
|
||||
<a
|
||||
key={check.name}
|
||||
key={key}
|
||||
href={check.url}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
|
|
@ -262,7 +263,7 @@ export function SessionDetailPRCard({
|
|||
{chip}
|
||||
</a>
|
||||
) : (
|
||||
<span key={check.name}>{chip}</span>
|
||||
<span key={key}>{chip}</span>
|
||||
);
|
||||
})}
|
||||
</>
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
import { act, fireEvent, render, screen } from "@testing-library/react";
|
||||
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
||||
import { SessionDetail } from "../SessionDetail";
|
||||
import { buildAgentFixMessage } from "../session-detail-agent-actions";
|
||||
import { makePR, makeSession } from "../../__tests__/helpers";
|
||||
|
||||
vi.mock("next/navigation", () => ({
|
||||
|
|
@ -243,6 +244,41 @@ describe("SessionDetail desktop layout", () => {
|
|||
expect(screen.getByRole("button", { name: "Ask Agent to Fix" })).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("builds branch links from the PR host for GitHub Enterprise repos", () => {
|
||||
render(
|
||||
<SessionDetail
|
||||
session={makeSession({
|
||||
id: "worker-ghe",
|
||||
projectId: "my-app",
|
||||
branch: "feat/ghe-detail",
|
||||
pr: makePR({
|
||||
number: 312,
|
||||
url: "https://github.enterprise.local/acme/app/pull/312",
|
||||
owner: "acme",
|
||||
repo: "app",
|
||||
branch: "feat/ghe-detail",
|
||||
}),
|
||||
})}
|
||||
/>,
|
||||
);
|
||||
|
||||
expect(screen.getByRole("link", { name: "feat/ghe-detail" })).toHaveAttribute(
|
||||
"href",
|
||||
"https://github.enterprise.local/acme/app/tree/feat/ghe-detail",
|
||||
);
|
||||
});
|
||||
|
||||
it("truncates review-comment messages below the API payload cap", () => {
|
||||
const message = buildAgentFixMessage({
|
||||
url: "https://github.com/acme/app/pull/311#discussion_r2",
|
||||
path: `packages/web/${"deep/".repeat(200)}component.tsx`,
|
||||
body: `### ${"T".repeat(500)}\n<!-- DESCRIPTION START -->${"D".repeat(15_000)}<!-- DESCRIPTION END -->`,
|
||||
});
|
||||
|
||||
expect(message.length).toBeLessThanOrEqual(9_500);
|
||||
expect(message).toContain("Resolve the comment at https://github.com/acme/app/pull/311#discussion_r2");
|
||||
});
|
||||
|
||||
it("shows terminal-ended placeholder for exited desktop sessions", () => {
|
||||
render(
|
||||
<SessionDetail
|
||||
|
|
|
|||
|
|
@ -1,5 +1,30 @@
|
|||
import { cleanBugbotComment } from "./session-detail-utils";
|
||||
|
||||
const MAX_AGENT_MESSAGE_LENGTH = 9_500;
|
||||
const MAX_TITLE_LENGTH = 240;
|
||||
const MAX_DESCRIPTION_LENGTH = 7_500;
|
||||
|
||||
function truncate(value: string, maxLength: number): string {
|
||||
const trimmed = value.trim();
|
||||
if (trimmed.length <= maxLength) return trimmed;
|
||||
return `${trimmed.slice(0, Math.max(0, maxLength - 1)).trimEnd()}…`;
|
||||
}
|
||||
|
||||
function buildAgentFixMessage(comment: { url: string; path: string; body: string }): string {
|
||||
const { title, description } = cleanBugbotComment(comment.body);
|
||||
const message = [
|
||||
"Please address this review comment:",
|
||||
"",
|
||||
`File: ${truncate(comment.path, 500)}`,
|
||||
`Comment: ${truncate(title, MAX_TITLE_LENGTH)}`,
|
||||
`Description: ${truncate(description, MAX_DESCRIPTION_LENGTH)}`,
|
||||
"",
|
||||
`Resolve the comment at ${comment.url} after fixing it.`,
|
||||
].join("\n");
|
||||
|
||||
return truncate(message, MAX_AGENT_MESSAGE_LENGTH);
|
||||
}
|
||||
|
||||
export async function askAgentToFix(
|
||||
sessionId: string,
|
||||
comment: { url: string; path: string; body: string },
|
||||
|
|
@ -7,8 +32,7 @@ export async function askAgentToFix(
|
|||
onError: () => void,
|
||||
) {
|
||||
try {
|
||||
const { title, description } = cleanBugbotComment(comment.body);
|
||||
const message = `Please address this review comment:\n\nFile: ${comment.path}\nComment: ${title}\nDescription: ${description}\n\nComment URL: ${comment.url}\n\nAfter fixing, mark the comment as resolved at ${comment.url}`;
|
||||
const message = buildAgentFixMessage(comment);
|
||||
const response = await fetch(`/api/sessions/${encodeURIComponent(sessionId)}/message`, {
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
|
|
@ -21,3 +45,5 @@ export async function askAgentToFix(
|
|||
onError();
|
||||
}
|
||||
}
|
||||
|
||||
export { buildAgentFixMessage };
|
||||
|
|
|
|||
|
|
@ -52,7 +52,15 @@ export function cleanBugbotComment(body: string): { title: string; description:
|
|||
}
|
||||
|
||||
export function buildGitHubBranchUrl(pr: DashboardPR): string {
|
||||
return `https://github.com/${pr.owner}/${pr.repo}/tree/${pr.branch}`;
|
||||
let origin = "https://github.com";
|
||||
|
||||
try {
|
||||
origin = new URL(pr.url).origin;
|
||||
} catch {
|
||||
// Fall back to the public GitHub host if the PR URL is missing or invalid.
|
||||
}
|
||||
|
||||
return `${origin}/${pr.owner}/${pr.repo}/tree/${pr.branch}`;
|
||||
}
|
||||
|
||||
export function activityStateClass(activityLabel: string): string {
|
||||
|
|
|
|||
Loading…
Reference in New Issue