feat(web): workspace components — ComparePane, Memory page, McpDialog, error boundaries, message-parts
- Add ComparePane.tsx: side-by-side AI response comparison - Add Memory.tsx: memory management page with CRUD UI - Add McpPermissionDialog.tsx: MCP tool permission approval dialog - Add McpResponseDisplay.tsx: MCP response visualization - Add MessageBoundary.tsx + MessageListErrorBoundary.tsx: error resilience - Add EmptyState.tsx: contextual empty state component - Add KeyboardShortcutsDialog.tsx: keyboard shortcut reference - Add message-parts/: ActionRow, CompactCard, MistakeRecoverySentinel, ReasoningBlock, SendToTerminalMenu, StatsLine, SummaryCard - Add useDraftPersistence.ts: draft message persistence hook - Add useTerminals.ts: terminal session management hook - Add keyboard-shortcuts.ts + tool-utils.ts: shared utilities - Extend components: ChatInput, MessageBubble, MessageList, Workspace, panes - Extend hooks: useTerminalSocket, useSessionStream test suite - Update pages: Home, Project — workspace layout and session flow
This commit is contained in:
@@ -8,6 +8,7 @@ import Markdown from 'react-markdown';
|
||||
import type { Components } from 'react-markdown';
|
||||
import remarkGfm from 'remark-gfm';
|
||||
import { CodeBlock } from './CodeBlock';
|
||||
import { MessageBoundary } from './MessageBoundary';
|
||||
import { linkifyPaths } from '@/lib/linkify-paths';
|
||||
|
||||
function linkifyChildren(children: ReactNode, keyPrefix = 'l'): ReactNode {
|
||||
@@ -40,7 +41,11 @@ const codeRenderer = (props: { children?: unknown; className?: string }) => {
|
||||
const langMatch = /language-([\w-]+)/.exec(className ?? '');
|
||||
const isBlock = !!langMatch || text.includes('\n');
|
||||
if (isBlock) {
|
||||
return <CodeBlock code={text} lang={langMatch?.[1]} />;
|
||||
return (
|
||||
<MessageBoundary fallback={<pre className="overflow-x-auto px-3 py-2 font-mono text-xs leading-relaxed">{text}</pre>}>
|
||||
<CodeBlock code={text} lang={langMatch?.[1]} />
|
||||
</MessageBoundary>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<code
|
||||
@@ -102,8 +107,10 @@ const MARKDOWN_COMPONENTS: Components = {
|
||||
|
||||
export const MarkdownRenderer = memo(function MarkdownRenderer({ content }: { content: string }) {
|
||||
return (
|
||||
<Markdown remarkPlugins={[remarkGfm]} components={MARKDOWN_COMPONENTS}>
|
||||
{content}
|
||||
</Markdown>
|
||||
<MessageBoundary>
|
||||
<Markdown remarkPlugins={[remarkGfm]} components={MARKDOWN_COMPONENTS}>
|
||||
{content}
|
||||
</Markdown>
|
||||
</MessageBoundary>
|
||||
);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user