| author | |
| committer | |
| log | 1e87029261f9b81061a2a7420849b9eeaf1a2ebe |
| tree | 32ed0135c7c965c55539d75d0e6514228336ee02 |
| parent | 672216d7e152241213a8757892f281e1f4434e8a |
| signature | Signed by PGP key B5690EEEBB952194 |
3 files changed, 18 insertions(+), 0 deletions(-)
apps/web/src/components/chat/MessagesTimeline.logic.test.ts+12| ... | @@ -5,8 +5,20 @@ import { | ... | @@ -5,8 +5,20 @@ import { |
| 5 | deriveMessagesTimelineRows, | 5 | deriveMessagesTimelineRows, |
| 6 | normalizeCompactToolLabel, | 6 | normalizeCompactToolLabel, |
| 7 | resolveAssistantMessageCopyState, | 7 | resolveAssistantMessageCopyState, |
| 8 | shouldPreserveAssistantLineBreaks, | ||
| 8 | } from "./MessagesTimeline.logic"; | 9 | } from "./MessagesTimeline.logic"; |
| 9 | 10 | ||
| 11 | describe("shouldPreserveAssistantLineBreaks", () => { | ||
| 12 | it("preserves Claude insight formatting without changing regular markdown", () => { | ||
| 13 | expect( | ||
| 14 | shouldPreserveAssistantLineBreaks( | ||
| 15 | "★ Insight ─────────────────\\nFirst observation\\nSecond observation\\n─────────────────", | ||
| 16 | ), | ||
| 17 | ).toBe(true); | ||
| 18 | expect(shouldPreserveAssistantLineBreaks("A normal\\nmarkdown paragraph")).toBe(false); | ||
| 19 | }); | ||
| 20 | }); | ||
| 21 | |||
| 10 | describe("computeMessageDurationStart", () => { | 22 | describe("computeMessageDurationStart", () => { |
| 11 | it("returns message createdAt when there is no preceding user message", () => { | 23 | it("returns message createdAt when there is no preceding user message", () => { |
| 12 | const result = computeMessageDurationStart([ | 24 | const result = computeMessageDurationStart([ |
apps/web/src/components/chat/MessagesTimeline.logic.ts+4| ... | @@ -52,6 +52,10 @@ export function resolveTimelineIsAtEnd( | ... | @@ -52,6 +52,10 @@ export function resolveTimelineIsAtEnd( |
| 52 | return contentLength - scroll - scrollLength - endInset <= TIMELINE_FOLLOW_REARM_THRESHOLD_PX; | 52 | return contentLength - scroll - scrollLength - endInset <= TIMELINE_FOLLOW_REARM_THRESHOLD_PX; |
| 53 | } | 53 | } |
| 54 | 54 | ||
| 55 | export function shouldPreserveAssistantLineBreaks(text: string): boolean { | ||
| 56 | return /^★ Insight(?:\s|─)/mu.test(text); | ||
| 57 | } | ||
| 58 | |||
| 55 | export function resolveTimelineMinimapHeightStyle(itemCount: number): string { | 59 | export function resolveTimelineMinimapHeightStyle(itemCount: number): string { |
| 56 | const naturalHeight = Math.max(1, (itemCount - 1) * TIMELINE_MINIMAP_ITEM_SPACING); | 60 | const naturalHeight = Math.max(1, (itemCount - 1) * TIMELINE_MINIMAP_ITEM_SPACING); |
| 57 | return `min(${naturalHeight}px, ${TIMELINE_MINIMAP_MAX_HEIGHT_CSS})`; | 61 | return `min(${naturalHeight}px, ${TIMELINE_MINIMAP_MAX_HEIGHT_CSS})`; |
apps/web/src/components/chat/MessagesTimeline.tsx+2| ... | @@ -83,6 +83,7 @@ import { | ... | @@ -83,6 +83,7 @@ import { |
| 83 | resolveTimelineMinimapIndexFromPointer, | 83 | resolveTimelineMinimapIndexFromPointer, |
| 84 | resolveTimelineMinimapInteractiveWidth, | 84 | resolveTimelineMinimapInteractiveWidth, |
| 85 | resolveTimelineMinimapTopPercent, | 85 | resolveTimelineMinimapTopPercent, |
| 86 | shouldPreserveAssistantLineBreaks, | ||
| 86 | type StableMessagesTimelineRowsState, | 87 | type StableMessagesTimelineRowsState, |
| 87 | type MessagesTimelineRow, | 88 | type MessagesTimelineRow, |
| 88 | TIMELINE_MINIMAP_MIN_ITEMS, | 89 | TIMELINE_MINIMAP_MIN_ITEMS, |
| ... | @@ -1113,6 +1114,7 @@ function AssistantTimelineRow({ row }: { row: Extract<TimelineRow, { kind: "mess | ... | @@ -1113,6 +1114,7 @@ function AssistantTimelineRow({ row }: { row: Extract<TimelineRow, { kind: "mess |
| 1113 | cwd={ctx.markdownCwd} | 1114 | cwd={ctx.markdownCwd} |
| 1114 | threadRef={ctx.threadRef ?? undefined} | 1115 | threadRef={ctx.threadRef ?? undefined} |
| 1115 | isStreaming={Boolean(row.message.streaming)} | 1116 | isStreaming={Boolean(row.message.streaming)} |
| 1117 | lineBreaks={shouldPreserveAssistantLineBreaks(messageText)} | ||
| 1116 | skills={ctx.skills} | 1118 | skills={ctx.skills} |
| 1117 | /> | 1119 | /> |
| 1118 | <AssistantChangedFilesSection | 1120 | <AssistantChangedFilesSection |