System Architecture
Relevant source files
The following files were used as context for generating this wiki page:
Buddi is a macOS companion application designed to monitor and interact with Claude Code sessions. It functions as a bridge between the command-line AI interface and the macOS desktop environment, providing real-time session monitoring, permission approvals, and a rich chat interface.
The architecture follows a reactive, event-driven pattern where internal hooks from Claude Code transmit data over Unix domain sockets to a central Swift-based state manager, which then propagates updates to a SwiftUI-based user interface.
Sources: README.md:1-12, buddiApp.swift:1-25
1. High-Level Data Flow
The system operates through a unidirectional data flow from Claude Code to the Buddi Notch UI, supplemented by a reverse control path for tool approvals and user messaging via terminal multiplexers.
Buddi registers hooks with Claude Code on launch. These hooks capture events such as tool usage, thinking states, session transitions, and permission requests, forwarding them to Buddi via a Unix socket located at /tmp/buddi.sock.
Sources: README.md:46-52, Buddi/Services/State/SessionStore.swift:94-135, Buddi/Settings/ClaudeCodeSettings.swift:70-74
2. Core Components
2.1 Session Management (SessionStore)
The SessionStore actor acts as the central state manager and the single source of truth for all active Claude sessions. It processes various SessionEvent types and publishes updates to the UI via a Combine publisher.
| Component | Responsibility |
|---|---|
| SessionStore | Thread-safe actor managing a collection of SessionState objects. |
| SessionState | Tracks PID, TTY, current SessionPhase (idle, processing, waiting), and chat history. |
| ConversationParser | Incrementally parses Claude's .jsonl files to extract message history and tool results. |
Sources: Buddi/Services/State/SessionStore.swift:16-45, Buddi/Services/Session/ConversationParser.swift:25-50
2.2 Process and Multiplexer Integration
Buddi identifies active Claude sessions by inspecting the system process tree. It specifically looks for sessions running within terminal multiplexers like tmux or cmux to enable remote interaction.
The ProcessTreeBuilder uses the /bin/ps command to map PIDs and identify parent chains. This allows Buddi to determine if a Claude process is reachable via a multiplexer for sending approval commands (e.g., sending "1" + Enter for approval).
Sources: Buddi/Services/Shared/ProcessTreeBuilder.swift:24-65, Buddi/Services/Tmux/ToolApprovalHandler.swift:12-45
3. Communication and Hooks
3.1 Hook Mechanism
On application launch, Buddi installs hooks into the Claude Code environment. These hooks trigger during lifecycle events:
- PreToolUse / PostToolUse: Tracks the beginning and end of tool executions.
- PermissionRequest: Triggers the UI to expand the notch for user approval.
- UserPromptSubmit: Syncs new messages from the user.
Sources: Buddi/Services/State/SessionStore.swift:137-185, Buddi/Settings/ClaudeCodeSettings.swift:15-30
3.2 Tool Approval Logic
When Claude Code requires permission to execute a tool (like Bash or Write), Buddi intercepts the request. The ToolApprovalHandler manages the sending of specific keystrokes to the target terminal.
4. Chat and UI Layer
4.1 Incremental History Sync
To maintain performance, the ConversationParser performs incremental reads of the Claude session logs. It tracks the lastFileOffset to avoid re-reading the entire JSONL file on every update.
private func parseNewLines(filePath: String, state: inout IncrementalParseState) -> [ChatMessage] {
guard let fileHandle = FileHandle(forReadingAtPath: filePath) else { return [] }
let fileSize = try fileHandle.seekToEnd()
if fileSize < state.lastFileOffset { state = IncrementalParseState() } // Reset if file shrunk
try fileHandle.seek(toOffset: state.lastFileOffset)
// ... Read and parse new lines ...
}
Sources: Buddi/Services/Session/ConversationParser.swift:274-295
4.2 Tool Result Rendering
Buddi includes specialized views for different tool outputs. The ToolResultContent dispatcher maps structured data to specific SwiftUI components:
- ReadResultContent: Displays file contents with line numbers.
- EditResultContent: Computes and displays diffs using an LCS (Longest Common Subsequence) algorithm.
- BashResultContent: Separates
stdoutandstderr(rendered in red).
Sources: Buddi/UI/Views/ToolResultViews.swift:15-55, Buddi/UI/Views/ToolResultViews.swift:446-480
5. Summary
The Buddi architecture is a specialized monitor-and-control system. It relies on non-intrusive observation of Claude Code via file-system logs and process-tree inspection, while using terminal multiplexers as an out-of-band control channel for user interaction. This allows for a rich macOS-native experience without modifying the core Claude Code execution environment.
Sources: README.md:46-55, Buddi/Services/State/SessionStore.swift:16-25