Tool Approvals Handling
Relevant source files
The following files were used as context for generating this wiki page:
- buddi/Buddi/Services/Tmux/ToolApprovalHandler.swift
- buddi/Buddi/Models/ToolResultData.swift
- buddi/Buddi/UI/Views/ToolResultViews.swift
- buddi/Buddi/Services/State/SessionStore.swift
- buddi/Buddi/Models/SessionState.swift
- buddi/Buddi/UI/Views/ChatView.swift
- buddi/Buddi/UI/Views/ClaudeInstancesView.swift
Tool Approvals Handling is a core system in Buddi that manages the permission lifecycle for AI tool executions within Claude Code sessions. It provides a bridge between the macOS Notch UI and the terminal-based Claude Code instance, allowing users to inspect, approve, or reject tool calls (such as file edits, shell commands, or web searches) directly from the application interface.
The system monitors sessions for PermissionRequest events, transitions the session state to a waiting phase, and communicates user decisions back to the underlying terminal multiplexer (tmux or cmux). This ensures that sensitive operations are never executed without explicit user consent while maintaining a seamless "Notch" companion experience.
Sources: README.md, buddi/Buddi/Services/State/SessionStore.swift:105-115
Architecture and State Management
The tool approval flow is managed by the SessionStore, which acts as the single source of truth for all session states. When a tool requires permission, the session transitions into the waitingForApproval phase.
Permission Lifecycle
- Detection: The
SessionStorereceives aHookEventwith the typePermissionRequest. - State Transition: The session's
SessionPhaseis updated to.waitingForApproval, containing aPermissionContext(tool ID, name, and input). - UI Feedback: The Notch UI (via
ClaudeInstancesVieworChatView) displays "Allow" and "Deny" buttons. - Action Dispatch: User interaction triggers calls to the
ToolApprovalHandlerto send keystrokes to the terminal. - Completion: Once the terminal processes the input, a
PostToolUseevent or JSONL update returns the session toprocessingoridle.
Sources: buddi/Buddi/Services/State/SessionStore.swift:94-118, buddi/Buddi/Models/SessionState.swift:25-30
Interaction Flow Diagram
The following diagram illustrates how a permission request moves from Claude Code through Buddi's services to the user and back.
The ToolApprovalHandler
The ToolApprovalHandler is an actor responsible for the low-level communication with terminal multiplexers. It translates high-level user actions into specific keystrokes required by the Claude Code CLI.
Key Operations
| Method | Key Sent | Purpose |
|---|---|---|
approveOnce(target:) | 1 + Enter | Approves the current tool execution once. |
approveAlways(target:) | 2 + Enter | Configures Claude to always approve this tool. |
reject(target:message:) | n + Enter | Rejects the execution, optionally sending a reason. |
sendMessage(_:to:) | message + Enter | Sends arbitrary text to the session (used in Chat). |
Sources: buddi/Buddi/Services/Tmux/ToolApprovalHandler.swift:20-45
Multiplexer Support
The handler supports two primary multiplexers:
- tmux: Uses
tmux send-keys -t [target] -l [keys]followed by an explicitEntercommand. - cmux: Uses
cmux sendandcmux send-keycommands, requiring a workspace and surface reference. It also handles socket control passwords stored in Application Support.
Sources: buddi/Buddi/Services/Tmux/ToolApprovalHandler.swift:55-108
UI Components
Tool approvals are presented to the user in two main areas: the instances list and the chat view.
Inline Approval Buttons
In the ClaudeInstancesView, sessions requiring attention are prioritized. The InlineApprovalButtons component provides a compact interface for quick decisions.
- Allow: Triggers
approvePermission. - Deny: Triggers
denyPermission. - Chat: Opens the full conversation for detailed inspection.
Sources: buddi/Buddi/UI/Views/ClaudeInstancesView.swift:233-270
Chat Approval Bar
In the ChatView, a prominent ChatApprovalBar appears at the bottom of the message list. This view provides more context, showing the specific tool name and formatted input parameters being requested.
Interactive Tools
Certain tools, such as AskUserQuestion, are classified as "Interactive." Instead of simple binary approval, these require the user to provide text input. In these cases, the UI displays a ChatInteractivePromptBar with a "Terminal" button to quickly focus the underlying terminal window using Yabai.
Sources: buddi/Buddi/UI/Views/ChatView.swift:715-754, buddi/Buddi/UI/Views/ClaudeInstancesView.swift:135-145
Data Models
The system relies on structured data to render tool calls and their inputs accurately during the approval phase.
Tool Status and Transitions
Tool statuses are tracked within ToolCallItem and updated as the approval process progresses.
| Status | Meaning |
|---|---|
running | The tool is currently executing. |
waitingForApproval | Execution is paused awaiting user input. |
success | The tool completed successfully. |
error | The tool failed or was denied by the user. |
interrupted | The process was stopped by the user. |
Sources: buddi/Buddi/Services/Session/ChatHistoryManager.swift:150-170, buddi/Buddi/Models/ToolResultData.swift:160-170
Formatted Inputs
The MCPToolFormatter utility is used to clean up tool names and arguments for display. For example, a tool named mcp__deepwiki__ask_question is formatted as Deepwiki - Ask Question for the user.
Sources: buddi/Buddi/Utilities/MCPToolFormatter.swift:40-65
Summary
The Tool Approvals Handling system provides the critical safety and interactivity layer for Buddi. By integrating SessionStore state transitions with the ToolApprovalHandler's multiplexer communication, it allows users to safely manage AI operations. The system's architecture supports both quick inline approvals for routine tasks and deep inspection via the chat interface for complex file modifications.