onImageClick(attachment)}
>
![]()
{
});
});
+ it("shows an Artifacts nav item directly below Goals", async () => {
+ mockInstanceSettingsApi.getExperimental.mockResolvedValue({ enableIsolatedWorkspaces: false });
+ const root = await renderSidebar();
+
+ const artifactsLink = [...container.querySelectorAll("a")].find(
+ (anchor) => anchor.textContent === "Artifacts",
+ );
+ expect(artifactsLink?.getAttribute("href")).toBe("/artifacts");
+
+ const navText = container.querySelector("nav")?.textContent ?? "";
+ expect(navText).toContain("Goals");
+ expect(navText).toContain("Artifacts");
+ expect(navText.indexOf("Goals")).toBeLessThan(navText.indexOf("Artifacts"));
+
+ await act(async () => {
+ root.unmount();
+ });
+ });
+
it("shows the Workspaces link when isolated workspaces are enabled", async () => {
mockInstanceSettingsApi.getExperimental.mockResolvedValue({ enableIsolatedWorkspaces: true });
const root = await renderSidebar();
diff --git a/ui/src/components/Sidebar.tsx b/ui/src/components/Sidebar.tsx
index bce1f64aecf..9c4e9a9c7dc 100644
--- a/ui/src/components/Sidebar.tsx
+++ b/ui/src/components/Sidebar.tsx
@@ -11,6 +11,7 @@ import {
Boxes,
Repeat,
GitBranch,
+ Package,
Settings,
} from "lucide-react";
import { useQuery } from "@tanstack/react-query";
@@ -97,6 +98,7 @@ export function Sidebar() {
+
{showWorkspacesLink ? (
) : null}
diff --git a/ui/src/components/artifacts/ArtifactCard.test.tsx b/ui/src/components/artifacts/ArtifactCard.test.tsx
new file mode 100644
index 00000000000..ea9b979db9e
--- /dev/null
+++ b/ui/src/components/artifacts/ArtifactCard.test.tsx
@@ -0,0 +1,109 @@
+import type { ReactNode } from "react";
+import { renderToStaticMarkup } from "react-dom/server";
+import { describe, expect, it, vi } from "vitest";
+
+vi.mock("@/lib/router", () => ({
+ Link: ({ to, children, ...props }: { to: string; children: ReactNode }) => (
+
+ {children}
+
+ ),
+}));
+
+import { ArtifactCard } from "./ArtifactCard";
+import type { CompanyArtifact } from "@/api/artifacts";
+
+function makeArtifact(overrides: Partial
= {}): CompanyArtifact {
+ return {
+ id: "art-1",
+ source: "attachment",
+ mediaKind: "image",
+ title: "Hero shot",
+ previewText: null,
+ contentType: "image/png",
+ contentPath: "/files/art-1.png",
+ openPath: "/files/art-1.png",
+ downloadPath: "/files/art-1.png?download=1",
+ issue: { id: "issue-1", identifier: "PAP-10306", title: "Landing visuals" },
+ project: { id: "proj-1", name: "Paperclip App" },
+ createdByAgent: { id: "agent-1", name: "ClaudeCoder" },
+ updatedAt: "2026-06-01T00:00:00.000Z",
+ href: "/issues/PAP-10306#attachment-art-1",
+ ...overrides,
+ };
+}
+
+describe("ArtifactCard", () => {
+ it("renders an image preview with cover image and links to the issue anchor", () => {
+ const markup = renderToStaticMarkup();
+ expect(markup).toContain('href="/issues/PAP-10306#attachment-art-1"');
+ expect(markup).toContain('data-media-kind="image"');
+ expect(markup).toContain('src="/files/art-1.png"');
+ expect(markup).toContain("object-cover");
+ expect(markup).toContain("Hero shot");
+ expect(markup).toContain("PAP-10306");
+ });
+
+ it("renders a video preview with a video element and play glyph", () => {
+ const markup = renderToStaticMarkup(
+ ,
+ );
+ expect(markup).toContain('data-media-kind="video"');
+ expect(markup).toContain("
-