diff --git a/apps/code/src/renderer/features/message-editor/utils/content.test.ts b/apps/code/src/renderer/features/message-editor/utils/content.test.ts index 825dd20efd..8db8a9a480 100644 --- a/apps/code/src/renderer/features/message-editor/utils/content.test.ts +++ b/apps/code/src/renderer/features/message-editor/utils/content.test.ts @@ -4,6 +4,7 @@ import { type EditorContent, extractFilePaths, xmlToContent, + xmlToPlainText, } from "./content"; describe("xmlToContent", () => { @@ -196,6 +197,30 @@ describe("xmlToContent", () => { expect(extractFilePaths(content)).toEqual(["src/sub", "src/a.ts"]); }); + it("xmlToPlainText renders folder mentions as @mentions", () => { + expect( + xmlToPlainText('look at please'), + ).toBe("look at @products/agentic_tests please"); + }); + + it("xmlToPlainText renders file mentions as @mentions", () => { + expect( + xmlToPlainText('see for details'), + ).toBe("see @foo/bar.ts for details"); + }); + + it("xmlToPlainText renders structured chip types as @label", () => { + expect( + xmlToPlainText( + 'investigate and ', + ), + ).toBe("investigate @err-1 and @flag-2"); + }); + + it("xmlToPlainText leaves plain text untouched", () => { + expect(xmlToPlainText("ship the fix")).toBe("ship the fix"); + }); + it("round-trips contentToXml for a mix of text and chips", () => { const content: EditorContent = { segments: [ diff --git a/apps/code/src/renderer/features/message-editor/utils/content.ts b/apps/code/src/renderer/features/message-editor/utils/content.ts index 5207e55473..5b0e195c57 100644 --- a/apps/code/src/renderer/features/message-editor/utils/content.ts +++ b/apps/code/src/renderer/features/message-editor/utils/content.ts @@ -142,6 +142,10 @@ function chipFromTag(tag: string, rawAttrs: string): MentionChip | null { } } +export function xmlToPlainText(xml: string): string { + return contentToPlainText(xmlToContent(xml)); +} + export function xmlToContent(xml: string): EditorContent { const segments: EditorContent["segments"] = []; let lastIndex = 0; diff --git a/apps/code/src/renderer/features/sessions/components/ConversationView.tsx b/apps/code/src/renderer/features/sessions/components/ConversationView.tsx index 6d0773c56d..4afb50fd67 100644 --- a/apps/code/src/renderer/features/sessions/components/ConversationView.tsx +++ b/apps/code/src/renderer/features/sessions/components/ConversationView.tsx @@ -1,6 +1,7 @@ import { CHAT_CONTENT_MAX_WIDTH } from "@features/sessions/constants"; import { useContextUsage } from "@features/sessions/hooks/useContextUsage"; import { useConversationSearch } from "@features/sessions/hooks/useConversationSearch"; +import { SessionTaskIdProvider } from "@features/sessions/hooks/useSessionTaskId"; import { sessionStoreSetters, useOptimisticItemsForTask, @@ -267,37 +268,39 @@ export function ConversationView({ /> )} - - 0} - pausedDurationMs={pausedDurationMs} - isCompacting={isCompacting} - usage={contextUsage} - /> - - } - /> + + + 0} + pausedDurationMs={pausedDurationMs} + isCompacting={isCompacting} + usage={contextUsage} + /> + + } + /> + {showScrollButton && (