diff --git a/src/create-prompt/index.ts b/src/create-prompt/index.ts
index d0cc7e0..0a6c385 100644
--- a/src/create-prompt/index.ts
+++ b/src/create-prompt/index.ts
@@ -9,6 +9,7 @@ import {
formatComments,
formatReviewComments,
formatChangedFilesWithSHA,
+ stripHtmlComments,
} from "../github/data/formatter";
import {
isIssuesEvent,
@@ -418,14 +419,14 @@ ${
eventData.eventName === "pull_request_review") &&
eventData.commentBody
? `
-${eventData.commentBody}
+${stripHtmlComments(eventData.commentBody)}
`
: ""
}
${
context.directPrompt
? `
-${context.directPrompt}
+${stripHtmlComments(context.directPrompt)}
`
: ""
}
diff --git a/src/github/data/formatter.ts b/src/github/data/formatter.ts
index 4b04dd9..df7b485 100644
--- a/src/github/data/formatter.ts
+++ b/src/github/data/formatter.ts
@@ -7,6 +7,10 @@ import type {
} from "../types";
import type { GitHubFileWithSHA } from "./fetcher";
+export function stripHtmlComments(text: string): string {
+ return text.replace(//g, "");
+}
+
export function formatContext(
contextData: GitHubPullRequest | GitHubIssue,
isPR: boolean,
@@ -33,7 +37,7 @@ export function formatBody(
body: string,
imageUrlMap: Map,
): string {
- let processedBody = body;
+ let processedBody = stripHtmlComments(body);
// Replace image URLs with local paths
for (const [originalUrl, localPath] of imageUrlMap) {
@@ -49,7 +53,7 @@ export function formatComments(
): string {
return comments
.map((comment) => {
- let body = comment.body;
+ let body = stripHtmlComments(comment.body);
// Replace image URLs with local paths if we have a mapping
if (imageUrlMap && body) {
@@ -81,7 +85,7 @@ export function formatReviewComments(
) {
const comments = review.comments.nodes
.map((comment) => {
- let body = comment.body;
+ let body = stripHtmlComments(comment.body);
// Replace image URLs with local paths if we have a mapping
if (imageUrlMap) {
diff --git a/test/data-formatter.test.ts b/test/data-formatter.test.ts
index 9ff2654..1729732 100644
--- a/test/data-formatter.test.ts
+++ b/test/data-formatter.test.ts
@@ -6,6 +6,7 @@ import {
formatReviewComments,
formatChangedFiles,
formatChangedFilesWithSHA,
+ stripHtmlComments,
} from "../src/github/data/formatter";
import type {
GitHubPullRequest,
@@ -578,3 +579,150 @@ describe("formatChangedFilesWithSHA", () => {
expect(result).toBe("");
});
});
+
+describe("stripHtmlComments", () => {
+ test("strips simple HTML comments", () => {
+ const text = "Hello world";
+ expect(stripHtmlComments(text)).toBe("Hello world");
+ });
+
+ test("strips multiple HTML comments", () => {
+ const text = "Start middle end";
+ expect(stripHtmlComments(text)).toBe("Start middle end");
+ });
+
+ test("strips multi-line HTML comments", () => {
+ const text = `Line 1
+
+Line 2`;
+ expect(stripHtmlComments(text)).toBe(`Line 1
+
+Line 2`);
+ });
+
+ test("strips nested comment-like content", () => {
+ const text = "Text still in comment --> after";
+ // HTML doesn't support true nested comments - the first --> ends the comment
+ expect(stripHtmlComments(text)).toBe("Text still in comment --> after");
+ });
+
+ test("handles empty string", () => {
+ expect(stripHtmlComments("")).toBe("");
+ });
+
+ test("handles text without comments", () => {
+ const text = "No comments here!";
+ expect(stripHtmlComments(text)).toBe("No comments here!");
+ });
+
+ test("strips complex hidden content with XML tags", () => {
+ const text = `Normal request
+
+More normal text`;
+ expect(stripHtmlComments(text)).toBe(`Normal request
+
+More normal text`);
+ });
+
+ test("handles malformed comments - no closing", () => {
+ const text = "Text is not stripped
+ expect(stripHtmlComments(text)).toBe("Text comment";
+ // Just --> without opening comment");
+ });
+
+ test("preserves legitimate HTML-like content outside comments", () => {
+ const text = "Use the tag and
closing tag";
+ expect(stripHtmlComments(text)).toBe(
+ "Use the tag and
closing tag",
+ );
+ });
+});
+
+describe("formatBody with HTML comment stripping", () => {
+ test("strips HTML comments from body", () => {
+ const body = "Issue description visible text";
+ const imageUrlMap = new Map();
+
+ const result = formatBody(body, imageUrlMap);
+ expect(result).toBe("Issue description visible text");
+ });
+
+ test("strips HTML comments and replaces images", () => {
+ const body = `Check this `;
+ const imageUrlMap = new Map([
+ [
+ "https://github.com/user-attachments/assets/test.png",
+ "/tmp/github-images/image-1234-0.png",
+ ],
+ ]);
+
+ const result = formatBody(body, imageUrlMap);
+ expect(result).toBe(
+ "Check this ",
+ );
+ });
+});
+
+describe("formatComments with HTML comment stripping", () => {
+ test("strips HTML comments from comment bodies", () => {
+ const comments: GitHubComment[] = [
+ {
+ id: "1",
+ databaseId: "100001",
+ body: "Good work on this PR",
+ author: { login: "user1" },
+ createdAt: "2023-01-01T00:00:00Z",
+ },
+ ];
+
+ const result = formatComments(comments);
+ expect(result).toBe(
+ "[user1 at 2023-01-01T00:00:00Z]: Good work on this PR",
+ );
+ });
+});
+
+describe("formatReviewComments with HTML comment stripping", () => {
+ test("strips HTML comments from review comment bodies", () => {
+ const reviewData = {
+ nodes: [
+ {
+ id: "review1",
+ databaseId: "300001",
+ author: { login: "reviewer1" },
+ body: "LGTM",
+ state: "APPROVED",
+ submittedAt: "2023-01-01T00:00:00Z",
+ comments: {
+ nodes: [
+ {
+ id: "comment1",
+ databaseId: "200001",
+ body: "Nice work here",
+ author: { login: "reviewer1" },
+ createdAt: "2023-01-01T00:00:00Z",
+ path: "src/index.ts",
+ line: 42,
+ },
+ ],
+ },
+ },
+ ],
+ };
+
+ const result = formatReviewComments(reviewData);
+ expect(result).toBe(
+ `[Review by reviewer1 at 2023-01-01T00:00:00Z]: APPROVED\n [Comment on src/index.ts:42]: Nice work here`,
+ );
+ });
+});