src/renderer/components/chat/messages/README.md
This directory contains the shared message display component family for Home, Agents, History, Quick Assistant, and other chat-like surfaces.
The goal is one reusable message UI implementation with page-specific data and capabilities injected through adapters and providers.
This directory owns message display only:
This directory must not own page shell concerns:
Page-only UI should stay in the page directory. If a component is only a Home or Agent adapter, keep it in adapters/ or move it back to the page side.
MessageList.tsx and MessageListProvider.tsx: public list entry and context provider.types.ts: stable contract for state / actions / meta.list/: list behavior such as grouping, virtual scrolling, selection, and sibling navigation.frame/: message skeleton such as frame, header, content, editor, footer actions, tokens, attachments.blocks/: message parts and content blocks.tools/: tool call rendering, split by source or capability.markdown/: markdown renderer and markdown-only support components/plugins.stream/: message stream collectors and stream-specific plumbing.layout/: message-list local layout helpers.utils/: shared projections and formatting helpers for the message contract.MessageContentProvider owns the internal parts context. Pages and adapters should pass
state.partsByMessageId into the message-list provider value; they should not wrap PartsProvider manually.
Directory names stay lowercase. React component files stay PascalCase.
Complex UI must consume MessageListProviderValue rather than directly reaching into page state.
Use the standard shape:
type MessageListProviderValue = {
state: MessageListState
actions: MessageListActions
meta: MessageListMeta
}
state: renderable data and UI configuration, such as messages, topic, loading state, list key, navigation mode, sizing.actions: executable capabilities, such as loading older messages, selecting an active branch, deleting a message group, or regenerating a message.meta: environment and non-command display metadata, such as assistant profile or export filename.Shared UI components should treat missing actions as unavailable capabilities. Do not add isAgent, isHome, mode, or other page-mode booleans to shared components.
Adapters are the boundary between page/business data and this component family.
Adapters may:
MessageListProviderValueAdapters must not:
Home and Agents may have separate adapters, but both must render the same MessageList.
Message actions should be injected through provider actions or an action registry.
Shared UI should not directly call page-specific hooks such as useV2Chat unless that file is explicitly an adapter. If a shared component needs a capability, add it to MessageListActions or the message action registry and let the relevant adapter provide it.
Action visibility should be capability-driven:
Avoid separate booleans that mirror action availability.
Differences between Home and Agents should be expressed through provider values, actions, metadata, and explicit adapter composition.
Do not add page-mode props such as:
isAgentisHomemodeshowPromptIf the layout or behavior is truly different, create an explicit variant adapter or component around the shared pieces instead of branching inside the shared core.
The message UI may own transient UI state:
Business data stays outside:
The virtual list must not become a second source of truth for messages.
V2 in component names in this directory.MessageParts for parts-based message data.MessageMenuBar, not MessageMenubar.Message* for shared message components.Agent* only for agent-specific tool renderers or adapter code.Chat* for message-list internals unless the component is outside this shared message family.Shared message components should not import from page-private paths such as:
@renderer/pages/home/...@renderer/pages/agents/...If a shared component needs UI from a page-private module, extract a smaller shared primitive or inject the capability through an adapter.
Public entry files should export shared contracts and shared UI. Avoid exporting page adapter hooks from public barrels unless there is a deliberate package-level API decision.
For changes in this directory, prefer focused tests around the affected component family:
pnpm exec vitest run \
src/renderer/src/components/chat/messages \
src/renderer/src/pages/home/__tests__/ChatContent.test.tsx
When touching blocks, markdown, stream collectors, or tool renderers, include their local tests as well.
Before handing off implementation work, run:
npm run typecheck:web
Run broader project validation when the change reaches outside the message-list vertical slice.