Show code snippet in fix problems (#745)

This commit is contained in:
Will Chen
2025-07-30 16:03:17 -07:00
committed by GitHub
parent 3fe80d441a
commit 510d288d78
15 changed files with 283 additions and 3 deletions

View File

@@ -4,7 +4,15 @@ exports[`problem_prompt > createConciseProblemFixPrompt > should format a concis
"Fix these 2 TypeScript compile-time errors:
1. src/main.ts:5:12 - Cannot find module 'react-dom/client' or its corresponding type declarations. (TS2307)
\`\`\`
SNIPPET
\`\`\`
2. src/components/Modal.tsx:35:20 - Property 'isOpen' does not exist on type 'IntrinsicAttributes & ModalProps'. (TS2339)
\`\`\`
SNIPPET
\`\`\`
Please fix all errors in a concise way."
`;
@@ -13,6 +21,10 @@ exports[`problem_prompt > createConciseProblemFixPrompt > should format a concis
"Fix these 1 TypeScript compile-time error:
1. src/App.tsx:10:5 - Cannot find name 'consol'. Did you mean 'console'? (TS2552)
\`\`\`
SNIPPET
\`\`\`
Please fix all errors in a concise way."
`;
@@ -23,6 +35,10 @@ exports[`problem_prompt > createProblemFixPrompt > should format a single error
"Fix these 1 TypeScript compile-time error:
1. src/components/Button.tsx:15:23 - Property 'onClick' does not exist on type 'ButtonProps'. (TS2339)
\`\`\`
SNIPPET
\`\`\`
Please fix all errors in a concise way."
`;
@@ -31,9 +47,25 @@ exports[`problem_prompt > createProblemFixPrompt > should format multiple errors
"Fix these 4 TypeScript compile-time errors:
1. src/components/Button.tsx:15:23 - Property 'onClick' does not exist on type 'ButtonProps'. (TS2339)
\`\`\`
SNIPPET
\`\`\`
2. src/components/Button.tsx:8:12 - Type 'string | undefined' is not assignable to type 'string'. (TS2322)
\`\`\`
SNIPPET
\`\`\`
3. src/hooks/useApi.ts:42:5 - Argument of type 'unknown' is not assignable to parameter of type 'string'. (TS2345)
\`\`\`
SNIPPET
\`\`\`
4. src/utils/helpers.ts:45:8 - Function lacks ending return statement and return type does not include 'undefined'. (TS2366)
\`\`\`
SNIPPET
\`\`\`
Please fix all errors in a concise way."
`;
@@ -42,9 +74,25 @@ exports[`problem_prompt > createProblemFixPrompt > should handle realistic React
"Fix these 4 TypeScript compile-time errors:
1. src/components/UserProfile.tsx:12:35 - Type '{ children: string; }' is missing the following properties from type 'UserProfileProps': user, onEdit (TS2739)
\`\`\`
SNIPPET
\`\`\`
2. src/components/UserProfile.tsx:25:15 - Object is possibly 'null'. (TS2531)
\`\`\`
SNIPPET
\`\`\`
3. src/hooks/useLocalStorage.ts:18:12 - Type 'string | null' is not assignable to type 'T'. (TS2322)
\`\`\`
SNIPPET
\`\`\`
4. src/types/api.ts:45:3 - Duplicate identifier 'UserRole'. (TS2300)
\`\`\`
SNIPPET
\`\`\`
Please fix all errors in a concise way."
`;
@@ -55,9 +103,25 @@ exports[`problem_prompt > realistic TypeScript error scenarios > should handle c
"Fix these 4 TypeScript compile-time errors:
1. src/components/ProductCard.tsx:22:18 - Property 'price' is missing in type '{ name: string; description: string; }' but required in type 'Product'. (TS2741)
\`\`\`
SNIPPET
\`\`\`
2. src/components/SearchInput.tsx:15:45 - Type '(value: string) => void' is not assignable to type 'ChangeEventHandler<HTMLInputElement>'. (TS2322)
\`\`\`
SNIPPET
\`\`\`
3. src/api/userService.ts:8:1 - Function lacks ending return statement and return type does not include 'undefined'. (TS2366)
\`\`\`
SNIPPET
\`\`\`
4. src/utils/dataProcessor.ts:34:25 - Object is possibly 'undefined'. (TS2532)
\`\`\`
SNIPPET
\`\`\`
Please fix all errors in a concise way."
`;

View File

@@ -2,6 +2,8 @@ import { describe, it, expect } from "vitest";
import { createProblemFixPrompt } from "../shared/problem_prompt";
import type { ProblemReport } from "../ipc/ipc_types";
const snippet = `SNIPPET`;
describe("problem_prompt", () => {
describe("createProblemFixPrompt", () => {
it("should return a message when no problems exist", () => {
@@ -22,6 +24,7 @@ describe("problem_prompt", () => {
column: 23,
message: "Property 'onClick' does not exist on type 'ButtonProps'.",
code: 2339,
snippet,
},
],
};
@@ -39,6 +42,7 @@ describe("problem_prompt", () => {
column: 23,
message: "Property 'onClick' does not exist on type 'ButtonProps'.",
code: 2339,
snippet,
},
{
file: "src/components/Button.tsx",
@@ -47,6 +51,7 @@ describe("problem_prompt", () => {
message:
"Type 'string | undefined' is not assignable to type 'string'.",
code: 2322,
snippet,
},
{
file: "src/hooks/useApi.ts",
@@ -55,6 +60,7 @@ describe("problem_prompt", () => {
message:
"Argument of type 'unknown' is not assignable to parameter of type 'string'.",
code: 2345,
snippet,
},
{
file: "src/utils/helpers.ts",
@@ -63,6 +69,7 @@ describe("problem_prompt", () => {
message:
"Function lacks ending return statement and return type does not include 'undefined'.",
code: 2366,
snippet,
},
],
};
@@ -81,6 +88,7 @@ describe("problem_prompt", () => {
message:
"Type '{ children: string; }' is missing the following properties from type 'UserProfileProps': user, onEdit",
code: 2739,
snippet,
},
{
file: "src/components/UserProfile.tsx",
@@ -88,6 +96,7 @@ describe("problem_prompt", () => {
column: 15,
message: "Object is possibly 'null'.",
code: 2531,
snippet,
},
{
file: "src/hooks/useLocalStorage.ts",
@@ -95,6 +104,7 @@ describe("problem_prompt", () => {
column: 12,
message: "Type 'string | null' is not assignable to type 'T'.",
code: 2322,
snippet,
},
{
file: "src/types/api.ts",
@@ -102,6 +112,7 @@ describe("problem_prompt", () => {
column: 3,
message: "Duplicate identifier 'UserRole'.",
code: 2300,
snippet,
},
],
};
@@ -130,6 +141,7 @@ describe("problem_prompt", () => {
column: 5,
message: "Cannot find name 'consol'. Did you mean 'console'?",
code: 2552,
snippet,
},
],
};
@@ -148,6 +160,7 @@ describe("problem_prompt", () => {
message:
"Cannot find module 'react-dom/client' or its corresponding type declarations.",
code: 2307,
snippet,
},
{
file: "src/components/Modal.tsx",
@@ -156,6 +169,7 @@ describe("problem_prompt", () => {
message:
"Property 'isOpen' does not exist on type 'IntrinsicAttributes & ModalProps'.",
code: 2339,
snippet,
},
],
};
@@ -177,6 +191,7 @@ describe("problem_prompt", () => {
message:
"Property 'price' is missing in type '{ name: string; description: string; }' but required in type 'Product'.",
code: 2741,
snippet,
},
// Incorrect event handler type
{
@@ -186,6 +201,7 @@ describe("problem_prompt", () => {
message:
"Type '(value: string) => void' is not assignable to type 'ChangeEventHandler<HTMLInputElement>'.",
code: 2322,
snippet,
},
// Async/await without Promise return type
{
@@ -195,6 +211,7 @@ describe("problem_prompt", () => {
message:
"Function lacks ending return statement and return type does not include 'undefined'.",
code: 2366,
snippet,
},
// Strict null check
{
@@ -203,6 +220,7 @@ describe("problem_prompt", () => {
column: 25,
message: "Object is possibly 'undefined'.",
code: 2532,
snippet,
},
],
};

View File

@@ -7,13 +7,15 @@ import {
} from "lucide-react";
import type { Problem } from "@/ipc/ipc_types";
type ProblemWithoutSnippet = Omit<Problem, "snippet">;
interface DyadProblemSummaryProps {
summary?: string;
children?: React.ReactNode;
}
interface ProblemItemProps {
problem: Problem;
problem: ProblemWithoutSnippet;
index: number;
}
@@ -54,13 +56,13 @@ export const DyadProblemSummary: React.FC<DyadProblemSummaryProps> = ({
const [isContentVisible, setIsContentVisible] = useState(false);
// Parse problems from children content if available
const problems: Problem[] = React.useMemo(() => {
const problems: ProblemWithoutSnippet[] = React.useMemo(() => {
if (!children || typeof children !== "string") return [];
// Parse structured format with <problem> tags
const problemTagRegex =
/<problem\s+file="([^"]+)"\s+line="(\d+)"\s+column="(\d+)"\s+code="(\d+)">([^<]+)<\/problem>/g;
const problems: Problem[] = [];
const problems: ProblemWithoutSnippet[] = [];
let match;
while ((match = problemTagRegex.exec(children)) !== null) {

View File

@@ -109,6 +109,7 @@ const ProblemsSummary = ({ problemReport, appId }: ProblemsSummaryProps) => {
const { problems } = problemReport;
const totalErrors = problems.length;
const [selectedChatId] = useAtom(selectedChatIdAtom);
const handleFixAll = () => {
if (!selectedChatId) {
return;

View File

@@ -16,6 +16,10 @@ export function createProblemFixPrompt(problemReport: ProblemReport): string {
problems.forEach((problem, index) => {
prompt += `${index + 1}. ${problem.file}:${problem.line}:${problem.column} - ${problem.message} (TS${problem.code})\n`;
if (problem.snippet) {
prompt += `\`\`\`\n${problem.snippet}\n\`\`\`\n`;
}
prompt += "\n";
});
prompt += "\nPlease fix all errors in a concise way.";