Markdown Chat Interface
Relevant source files
The following files were used as context for generating this wiki page:
- buddi/Buddi/UI/Views/ChatView.swift
- buddi/Buddi/UI/Components/MarkdownRenderer.swift
- buddi/Buddi/Services/Session/ConversationParser.swift
- buddi/Buddi/Models/ChatMessage.swift
- buddi/Buddi/Services/State/SessionStore.swift
- buddi/Buddi/UI/Views/ToolResultViews.swift
- buddi/Buddi/Utilities/MCPToolFormatter.swift
The Markdown Chat Interface is a core feature of Buddi that provides a real-time, interactive visual representation of Claude Code sessions. It serves as a bridge between the CLI-based Claude environment and a rich macOS UI, allowing users to view conversation history, monitor tool executions, and send messages back to active sessions.
The system is designed with a clean visual hierarchy, supporting complex message types including markdown-rendered text, collapsible thinking blocks, and specialized views for tool inputs and results. It operates by monitoring local JSONL session files and receiving live events via Unix sockets to maintain state synchronization.
Sources: README.md, buddi/Buddi/UI/Views/ChatView.swift:1-15
Architecture and Data Flow
The chat interface follows a reactive architecture where the UI updates based on state changes managed by the SessionStore. Data flows from Claude Code hooks through a Unix domain socket into Buddi, which then parses session files for history.
The diagram shows the bidirectional flow between Claude Code and the Buddi UI.
Sources: README.md, buddi/Buddi/Services/State/SessionStore.swift:17-45, buddi/Buddi/UI/Views/ChatView.swift:105-155
Synchronization Logic
Buddi employs an incremental parsing strategy to handle large conversation files efficiently. The ConversationParser tracks file offsets to only process new JSONL lines since the last sync. This ensures the UI remains responsive even during high-volume tool outputs.
Sources: buddi/Buddi/Services/Session/ConversationParser.swift:12-25
Core Components
ChatView
The primary container for the chat interface. It manages the scrollable message list, input bars, and specialized approval interfaces. It uses an inverted scroll technique (scaleEffect(x: 1, y: -1)) to ensure new messages appear at the bottom while maintaining proper scroll behavior.
Sources: buddi/Buddi/UI/Views/ChatView.swift:45-100
Markdown Rendering
Text content is processed via the BuddiMarkdownText component. It utilizes AttributedString(markdown:options:) with interpretedSyntax: .inlineOnlyPreservingWhitespace to safely render markdown while preserving the formatting essential for code-related conversations.
Sources: buddi/Buddi/UI/Components/MarkdownRenderer.swift:5-24
Message Data Model
Messages are represented by the ChatMessage struct, which contains a collection of MessageBlock enums. This allows a single message turn to contain a mix of different content types.
| Block Type | Description |
|---|---|
.text(String) | Standard markdown-rendered text content. |
.toolUse(ToolUseBlock) | Represents an intent to use a tool or a completed tool call. |
.thinking(String) | Collapsible internal reasoning from the model. |
.interrupted | Visual indicator that a request was canceled by the user. |
Sources: buddi/Buddi/Models/ChatMessage.swift:10-45
Specialized Interface States
The chat interface dynamically adjusts based on the session's current phase.
Interaction Modes
- Input Bar: Visible when the session is idle or waiting for user input. It allows sending text to the session via
tmuxorcmux. - Approval Bar: Appears when Claude requests permission to execute a tool. It provides "Allow" and "Deny" actions.
- Interactive Prompt Bar: Specifically for tools like
AskUserQuestionthat require direct terminal input, providing a shortcut to focus the terminal window.
Sources: buddi/Buddi/UI/Views/ChatView.swift:65-90, buddi/Buddi/UI/Views/ClaudeInstancesView.swift:180-210
This sequence illustrates the flow of a tool approval interaction.
Sources: buddi/Buddi/Services/State/SessionStore.swift:350-380, buddi/Buddi/UI/Views/ChatView.swift:450-480
Tool Execution and Visualization
Tool results are handled by the ToolResultContent dispatcher, which renders specialized views based on the tool type and the structured data provided by the parser.
Supported Tool Viewers
- File Code View: Used for
Readtools, providing line numbers and filename headers. - Diff View: Used for
EditandWritetools, calculating and highlighting changes using a Longest Common Subsequence (LCS) algorithm. - Bash Result Content: Renders
stdoutandstderrseparately, with specific formatting for background tasks. - MCP Result Content: Formats Model Context Protocol (MCP) tool names and arguments into a human-readable "Server - Tool" format.
Sources: buddi/Buddi/UI/Views/ToolResultViews.swift:14-50, buddi/Buddi/Utilities/MCPToolFormatter.swift:45-75
Tool Statuses
The UI tracks the lifecycle of a tool call through several states, reflected in the ToolCallView:
Sources: buddi/Buddi/UI/Views/ChatView.swift:515-540
| Status | Visual Indicator | Behavior |
|---|---|---|
running | Pulsing White/Orange | Active execution in terminal. |
waitingForApproval | Pulsing Amber | Requires user intervention in UI. |
success | Static Green | Execution completed successfully. |
error | Static Red | Execution failed or was rejected. |
Autoscroll Management
To improve user experience, the interface includes a "New Messages" indicator. If a user has scrolled up to read previous history and new messages arrive, autoscroll is paused and a floating button appears showing the count of new messages.
Sources: buddi/Buddi/UI/Views/ChatView.swift:410-435, buddi/Buddi/UI/Views/ChatView.swift:655-680
Conclusion
The Markdown Chat Interface provides a sophisticated observability layer for Claude Code sessions. By integrating incremental file parsing with a dynamic SwiftUI frontend, it allows developers to monitor complex AI workflows, review code changes via rich diffs, and interact with tools without leaving the Buddi environment.