diff --git a/packages/session-ui/src/storybook/current-session-fixtures.ts b/packages/session-ui/src/storybook/current-session-fixtures.ts index 10cdadccec..bb8c75ca7f 100644 --- a/packages/session-ui/src/storybook/current-session-fixtures.ts +++ b/packages/session-ui/src/storybook/current-session-fixtures.ts @@ -784,6 +784,50 @@ export const skillWorkflowDocument = document([ }), ] satisfies SessionMessageInfo[]) +export const instructionsUpdatedSingleDocument = document([ + user("msg_user_instructions_single", "Check if beta service reports the shared session as running.", 85_000), + assistant({ + id: "msg_assistant_instructions_single", + offset: 86_000, + completed: 88_000, + content: [ + { + type: "text", + text: "The beta service is healthy and already reports this shared session as running. I found unrelated desktop changes in the worktree and will leave them untouched; next I'm narrowing the beta-only capabilities to features that can be demonstrated safely in this session rather than invoking every administrative API.", + }, + ], + }), + { + id: "msg_instructions_updated_single", + type: "system", + text: "Updated instructions for api/v2-demo", + description: "Instructions updated: api/v2-demo", + time: { created: STORY_TIME + 89_000 }, + }, +] satisfies SessionMessageInfo[]) + +export const instructionsUpdatedMultipleDocument = document([ + user("msg_user_instructions_multi", "Check if beta service reports the shared session as running.", 85_000), + assistant({ + id: "msg_assistant_instructions_multi", + offset: 86_000, + completed: 88_000, + content: [ + { + type: "text", + text: "The beta service is healthy and already reports this shared session as running. I found unrelated desktop changes in the worktree and will leave them untouched; next I'm narrowing the beta-only capabilities to features that can be demonstrated safely in this session rather than invoking every administrative API.", + }, + ], + }), + { + id: "msg_instructions_updated_multi", + type: "system", + text: "Updated instructions for api/v2-demo and api/session", + description: "Instructions updated: api/v2-demo, api/session", + time: { created: STORY_TIME + 89_000 }, + }, +] satisfies SessionMessageInfo[]) + export const permissionPendingDocument = document( [ user("msg_user_permission_pending", "Publish the verified preview build to the canary channel.", 83_000), diff --git a/packages/session-ui/src/timeline/session-timeline-row.tsx b/packages/session-ui/src/timeline/session-timeline-row.tsx index 870d6f8442..4f91d50d94 100644 --- a/packages/session-ui/src/timeline/session-timeline-row.tsx +++ b/packages/session-ui/src/timeline/session-timeline-row.tsx @@ -8,7 +8,7 @@ import { Card } from "@opencode-ai/ui/card" import { useI18n } from "@opencode-ai/ui/context/i18n" import { TextReveal } from "@opencode-ai/ui/text-reveal" import { TextShimmer } from "@opencode-ai/ui/text-shimmer" -import { Show, createMemo, type Accessor, type JSX } from "solid-js" +import { For, Show, createMemo, type Accessor, type JSX } from "solid-js" import type { SessionUserActions, SessionUserComment } from "../actions" import { MessageDivider, @@ -152,7 +152,17 @@ export function createSessionTimelineRowRenderer(input: { if (message.type === "location-switched") return { label: i18n.t("ui.patch.action.moved"), data: message.location.directory } if (message.type === "skill") return { label: i18n.t("ui.tool.skill"), data: message.name } - if (message.type === "system") return { label: message.description ?? message.text } + if (message.type === "system") { + const prefix = "Instructions updated: " + if (message.description?.startsWith(prefix)) { + const keys = message.description.slice(prefix.length).split(",").map((s) => s.trim()).filter(Boolean) + return { + label: i18n.t("ui.sessionTimeline.notice.instructionsUpdated"), + items: keys, + } + } + return { label: message.description ?? message.text } + } if (message.type === "compaction") return { label: i18n.t("ui.messagePart.compaction"), data: message.status } if (message.type !== "synthetic") return undefined if (message.description === "Continuing after restart") return { label: message.description } @@ -274,19 +284,30 @@ export function createSessionTimelineRowRenderer(input: { {(content) => (