diff --git a/ui/src/components/IssueAttachmentsSection.test.tsx b/ui/src/components/IssueAttachmentsSection.test.tsx index 6fca448a..d9c3ff1b 100644 --- a/ui/src/components/IssueAttachmentsSection.test.tsx +++ b/ui/src/components/IssueAttachmentsSection.test.tsx @@ -153,6 +153,35 @@ describe("IssueAttachmentsSection", () => { }); }); + it("does not promote specific non-markdown content types by filename alone", async () => { + const attachment = makeAttachment({ + id: "zip-markdown", + originalFilename: "report.md", + contentType: "application/zip", + contentPath: "/api/attachments/zip-markdown/content", + openPath: "/api/attachments/zip-markdown/content", + downloadPath: "/api/attachments/zip-markdown/content?download=1", + }); + + await act(async () => { + root.render( + + + , + ); + }); + await flushReact(); + + expect(container.querySelector('[data-testid="markdown-body"]')).toBeNull(); + expect(container.textContent).toContain("report.md"); + expect(container.textContent).toContain("application/zip"); + expect(fetchSpy).not.toHaveBeenCalled(); + }); + it("renders video attachments through the same player used for artifact outputs", async () => { const attachment = makeAttachment({ id: "video-attachment", diff --git a/ui/src/lib/issue-attachments.ts b/ui/src/lib/issue-attachments.ts index 39534d48..8c6859da 100644 --- a/ui/src/lib/issue-attachments.ts +++ b/ui/src/lib/issue-attachments.ts @@ -63,5 +63,6 @@ export function isMarkdownAttachment( } const filename = (attachment.originalFilename ?? "").toLowerCase(); - return filename.endsWith(".md") || filename.endsWith(".markdown"); + if (!filename.endsWith(".md") && !filename.endsWith(".markdown")) return false; + return contentType === "text/plain" || GENERIC_ATTACHMENT_CONTENT_TYPES.has(contentType); }