diff --git a/packages/ui/src/features/canvas/components/ActivityTimeline.test.tsx b/packages/ui/src/features/canvas/components/ActivityTimeline.test.tsx index b6ea0cb52d..8d0e777678 100644 --- a/packages/ui/src/features/canvas/components/ActivityTimeline.test.tsx +++ b/packages/ui/src/features/canvas/components/ActivityTimeline.test.tsx @@ -128,4 +128,37 @@ describe("ActivityTimeline", () => { expect(screen.getByText("Saved workspace context")).toBeVisible(); expect(useThreadNavigationStore.getState().scrollRequests).toEqual({}); }); + + it("hides injected custom instructions from conversation previews", () => { + renderTimeline(true, [ + { + type: "user_message", + id: "custom-instructions-message", + content: + "Review this PR\n\n\nThe user has saved custom instructions that apply to all of their tasks. Follow them.\n\nNever update an existing PR description.\n", + timestamp: Date.parse("2026-07-17T09:05:00Z"), + }, + ]); + + expect(screen.getByText("Review this PR")).toBeInTheDocument(); + expect(screen.queryByText(/user_custom_instructions/)).toBeNull(); + expect( + screen.queryByText("Never update an existing PR description."), + ).toBeNull(); + }); + + it("shows user-authored custom-instruction tag examples", () => { + renderTimeline(true, [ + { + type: "user_message", + id: "literal-custom-instructions-message", + content: + "Render this example: be terse", + timestamp: Date.parse("2026-07-17T09:05:00Z"), + }, + ]); + + expect(screen.getByText(/user_custom_instructions/)).toBeInTheDocument(); + expect(screen.getByText(/be terse/)).toBeInTheDocument(); + }); }); diff --git a/packages/ui/src/features/canvas/components/ActivityTimeline.tsx b/packages/ui/src/features/canvas/components/ActivityTimeline.tsx index 94915cc36b..c899b0bbd2 100644 --- a/packages/ui/src/features/canvas/components/ActivityTimeline.tsx +++ b/packages/ui/src/features/canvas/components/ActivityTimeline.tsx @@ -34,6 +34,7 @@ import { ThreadTimestamp } from "@posthog/ui/features/canvas/components/ThreadTi import { userDisplayName } from "@posthog/ui/features/canvas/utils/userDisplay"; import type { buildConversationItems } from "@posthog/ui/features/sessions/components/buildConversationItems"; import { extractChannelContext } from "@posthog/ui/features/sessions/components/session-update/channelContext"; +import { extractCustomInstructions } from "@posthog/ui/features/sessions/components/session-update/customInstructions"; import { useThreadNavigationStore } from "@posthog/ui/features/sessions/threadNavigationStore"; import { Fragment, type KeyboardEvent, type ReactNode, useMemo } from "react"; @@ -83,7 +84,12 @@ function UserMessageRow({ () => extractChannelContext(content), [content], ); - const displayContent = channelContext?.stripped ?? content; + const afterChannelContext = channelContext?.stripped ?? content; + const customInstructions = useMemo( + () => extractCustomInstructions(afterChannelContext), + [afterChannelContext], + ); + const displayContent = customInstructions?.stripped ?? afterChannelContext; // The row itself is the hit target. `ThreadItem` renders an
, which a //