The rapid proliferation of AI coding agents, from large language model integrations like Claude Code and Gemini CLI to specialized tools like Cursor and Antigravity, introduces a new challenge for developers: maintaining oversight and providing timely, contextual approvals without disrupting their flow. As these agents become more autonomous, the need for a non-intrusive human-in-the-loop mechanism increases.
coucou, an open-source project with 3,801 GitHub stars, addresses this pain point. Its adoption signals a recognized problem within the developer community and offers a practical solution. This article describes coucou's architectural decisions, applications, and technical underpinnings. It covers the core philosophy, walks through a realistic use-case, details its Swift-powered stack, guides you through building and extending it, and explains how to contribute to its open-source community. This article aims to provide an understanding of how coucou streamlines AI agent oversight and how to use or improve its capabilities in your development workflow.
The Core Philosophy: Explaining the Why
coucou is not an AI agent itself, nor does it orchestrate complex AI workflows. Its maintainers deliberately avoided the competitive and rapidly evolving space of AI prompt engineering or multi-agent system design. Instead, coucou focuses on the interface between human developers and existing AI agents. This clear scope prevents feature creep and lets it excel at its specific mission: providing an approval and monitoring channel.
This focused approach means several design trade-offs:
- Simplicity over Extensibility (for agent integration):
coucouoffers a "tiny friend" experience with minimal configuration and a quick path to utility. This means it might not offer deep, custom scripting capabilities for every AI agent's output. The trade-off is that integrating a new, unsupported AI agent might require a direct contribution tocoucou's codebase rather than a simple plugin system. For its supported agents, the user experience is simpler and more native. - Performance (low latency alerts) over Universal Abstraction (complex API handling):
coucou's core value is real-time, unobtrusive alerts and approvals. This prioritizes low-latency integration with system UI elements—the Mac's notch, Dynamic Island, and Lock Screen. While it handles various agent outputs, its design leans towards efficiently parsing and presenting actionable insights rather than building a monolithic abstraction layer for all possible AI agent APIs, which could introduce latency and complexity. - Opinionated Defaults (Apple Ecosystem Focus): The project is optimized for Apple hardware—specifically the Mac's notch and the iPhone's Dynamic Island/Lock Screen. This focus allows for deep integration with macOS and iOS system features, providing a native, fluid user experience. This would be difficult to replicate with a cross-platform toolkit. The trade-off is a higher barrier to entry for non-Apple users who might want
coucou's concept but cannot run the client. This decision simplifies UI/UX development and uses platform-specific APIs for a superior interaction model, delivering a "native" feel.
Many tools focus on using AI agents (IDEs with Copilot, CLI tools like Gemini CLI) or building agents (LangChain, LlamaIndex). coucou exists in a unique interstitial space: the human-agent interaction layer for oversight. Its closest conceptual "competitors" might be notification systems or custom scripts that pipe AI outputs, but coucou elevates this to a first-class, purpose-built experience. It distinguishes itself by its direct, actionable UI integration within the core operating system's most attention-grabbing elements. This makes approvals instant and contextually relevant, rather than buried in a terminal or a generic notification center.
The choice to target Apple's ecosystem comes from the specific UI elements it uses: the notch and Dynamic Island. These interaction points offer high visibility and low friction. By embracing these platform specifics, coucou delivers on its promise of a "tiny friend" that is always present but never intrusive. It provides a novel way to interact with AI agent outputs that goes beyond standard notifications. This deep integration is a core part of its identity and value.
A Practical Use-Case Walkthrough
Imagine a developer working on a complex Swift project. They have integrated several AI coding agents into their workflow: Claude Code for generating boilerplate and complex function implementations, and Cursor for refining existing code snippets. The developer uses an external terminal for their AI agent interactions.
Their starting state involves occasional context switching: constantly monitoring terminal output or notification center for AI agent responses, which might require a quick approval or rejection. This breaks their focus from the IDE.
Here is how coucou improves this workflow:
-
Initial Setup: The developer first installs
coucouon their Mac. The application lives in the menu bar and integrates with the Mac's notch. For iPhone users, the app can also be paired to display notifications and offer Lock Screen approvals. They opencoucou's preferences to ensure their preferred agents are monitored.coucoucan watch the output of the Gemini CLI for approval prompts.# Assuming coucou is installed (e.g., via Homebrew or direct download) # Start coucou, it will appear in your menu bar. open /Applications/coucou.app # Navigate to coucou's preferences (Cmd+, or right-click menu bar icon) # In preferences, enable monitoring for 'Gemini CLI'. # This might involve specifying a log file path or a specific command output stream. # For agents like Gemini CLI, coucou listens for specific approval prompts. ``` 2. **Agent Interaction and Real-time Oversight:** The developer is deep in coding, focused on implementing a new feature. They use Gemini CLI to generate a helper function. The Gemini CLI command is executed in their terminal. ```bash gemini code generate-function --prompt "create a Swift function to parse a URL query string into a dictionary"Normally, the developer would wait for the Gemini CLI output in the terminal, potentially scrolling through logs or switching back and forth. With `coucou` running, as soon as the Gemini CLI outputs a prompt like "Do you approve this code? (Y/n)", `coucou` detects it. 3. **Instantaneous Approval:** A small, unobtrusive `coucou` character appears in the Mac's notch. This "tiny friend" visually indicates that an AI agent requires attention. The developer does not need to switch applications. They glance at the notch, where `coucou` displays a summary of the pending action—e.g., "Gemini CLI: Approve code?". If the developer needs more context, clicking `coucou` in the notch (or tapping the Dynamic Island/Lock Screen notification on iPhone) brings up a quick pop-up with the full prompt and options: "Approve," "Reject," or "View Details." For quick approvals, `coucou` often provides a direct action in the notch or Lock Screen. The developer can click the `coucou` icon or tap the notification to trigger the default "Approve" action, without leaving their current application or even fully opening the `coucou` window. 4. **Result:** The approval is sent back to the Gemini CLI process, which continues its execution, integrating the generated code. The developer's workflow is minimally interrupted; they maintain their focus on their primary task while `coucou` handles the oversight of their AI assistants. This proactive, context-aware notification and interaction model transforms AI agent management from a disruptive chore into a seamless, integrated part of the development process. ## Under the Hood: The Tech Stack `coucou` runs entirely on **Swift**, using Apple's modern declarative UI framework, **SwiftUI**, for its user interfaces across both macOS and iOS. This choice uses the Apple ecosystem's strengths, providing deep integration with system-level features and a native look and feel. The project structure is typical for a Swift/SwiftUI application, organized into modules and targets. The core application logic resides in the `coucou` target, handling inter-process communication, agent monitoring, and notification management. Given its functionality, the application likely relies heavily on system frameworks such as `UserNotifications` for standard alerts, and private or undocumented APIs (or clever workarounds) for specific notch/Dynamic Island interactions, though the latter is an implementation detail that can evolve with OS versions. Data and content within `coucou` use native macOS/iOS application conventions. Configurations for monitored AI agents, user preferences, and potentially historical approval data store with `UserDefaults` for lightweight, persistent key-value storage, or potentially in a more structured format like property lists (`.plist` files) for complex settings. The identification of AI agents and their corresponding approval regex patterns or output formats likely define within Swift code, possibly driven by a configuration file or a database of known agent integration profiles that the app references. A typical project structure, verifiable by examining the public repository, looks like this:. ├── coucou.xcodeproj/ # Xcode project configuration ├── coucou/ # Main application source directory │ ├── ContentView.swift # Main UI view for macOS/iOS │ ├── coucouApp.swift # Entry point of the SwiftUI application │ ├── Agents/ # Directory for AI agent integration logic │ │ ├── ClaudeCodeAgent.swift │ │ ├── GeminiCLIAgent.swift │ │ └── ... │ ├── Services/ # Core services like notification handling, agent monitoring │ │ ├── NotificationService.swift │ │ └── AgentMonitor.swift │ ├── Models/ # Data models for agents, approvals, settings │ │ ├── AgentConfiguration.swift │ │ └── ApprovalRequest.swift │ ├── Views/ # UI components │ │ ├── AgentPreferencesView.swift │ │ └── NotchOverlayView.swift │ └── Assets.xcassets # Image assets, app icons ├── Tests/ # Unit and UI tests ├── Package.swift # Swift Package Manager manifest (if used for dependencies) └── README.md`coucou`'s build and deployment approach follows standard Apple development practices. It compiles via Xcode, producing a `.app` bundle for macOS and an `.ipa` for iOS. Distribution typically occurs through GitHub Releases for direct download, Homebrew for macOS package management, and potentially the App Store for a wider audience, though open-source projects often favor direct distribution for flexibility. It focuses on self-contained binaries, making installation straightforward for end-users without complex dependency management beyond what macOS/iOS provides. ## Building or Extending It: A Practical Guide Getting `coucou` running locally, or preparing to extend it, is a familiar process for Swift developers. The project uses standard Xcode workflows. First, ensure you have Xcode installed (available free from the Mac App Store), as it provides the Swift compiler and necessary development tools. 1. **Clone the Repository:**git clone https://github.com/Louis-CFM/coucou.git cd coucou2. **Open in Xcode:**open coucou.xcodeprojXcode will open the project. You might need to select your development team for code signing if you intend to run it on a physical device or distribute it. For local development and running on your Mac, this is often straightforward. 3. **Build and Run:** Select the `coucou` target and choose "My Mac" as the destination (or a simulator/physical iPhone for the iOS target). Then, click the "Run" button (the play icon) in Xcode. This will compile the application and launch it. The `coucou` app icon should appear in your menu bar.# From within Xcode, select the 'coucou' target and 'My Mac' destination, then click Run. # Alternatively, build from CLI (though Xcode GUI is more common for initial setup): # xcodebuild -scheme coucou -configuration Debug### Customizing an Agent Integration To add support for a new AI agent, or modify how `coucou` interacts with an existing one, look in the `Agents/` directory. Each agent might have its own Swift file defining how to parse its output or interact with its CLI. Here is an annotated snippet showing how to define a new agent or adjust an existing one by modifying a `Matcher` struct, which determines how `coucou` identifies and extracts information from agent output. This example assumes a simplified structure where `coucou` watches a specific log file or process output for patterns.// coucou/Agents/MyNewAgent.swift import Foundation struct MyNewAgent: Agent { let id: String = "my-new-agent" let name: String = "My Custom Agent" var isEnabled: Bool // Toggles in preferences // Configuration specific to MyNewAgent, e.g., log file path or a regex for its output. var configuration: AgentConfiguration // Assuming AgentConfiguration is a generic type init(isEnabled: Bool = false, configuration: AgentConfiguration = .default) { self.isEnabled = isEnabled self.configuration = configuration } // This function defines how coucou 'listens' to the agent. // It could involve tailing a log file, piping CLI output, or watching a process. func monitor(eventHandler: @escaping (ApprovalRequest) -> Void) { // Example: Monitor a dummy log file for specific patterns // In a real scenario, this would involve more robust file observation or process monitoring. let logFilePath = "/Users/your_user/my_new_agent_output.log" // Simplified, conceptual monitoring logic Timer.scheduledTimer(withTimeInterval: 5.0, repeats: true) { _ in if let content = try? String(contentsOfFile: logFilePath) { if content.contains("ACTION_REQUIRED: Approve this change?") { let request = ApprovalRequest( agentID: self.id, message: "My New Agent needs approval for a change.", timestamp: Date(), actions: [.approve, .reject] // Available actions ) eventHandler(request) // Clear or mark the log entry as handled to prevent re-triggering } } } } // A parser to extract details if an approval is needed. func parseOutputForApproval(output: String) -> ApprovalRequest? { let pattern = "ACTION_REQUIRED: (?.*?)\\s*\\(Approve|Reject\\)" let regex = try? NSRegularExpression(pattern: pattern, options: []) guard let match = regex?.firstMatch(in: output, options: [], range: NSRange(output.startIndex..., in: output)) else { return nil } if let messageRange = Range(match.range(withName: "message"), in: output) { let message = String(output[messageRange]) return ApprovalRequest( agentID: self.id, message: message, timestamp: Date(), actions: [.approve, .reject] ) } return nil } // Action execution (e.g., writing to a pipe, sending a command back to the agent) func executeAction(_ action: ApprovalAction, for request: ApprovalRequest) { switch action { case .approve: print("Approving request for \(request.agentID): \(request.message)") // Logic to send 'Y' or 'approve' command to the agent's input stream or API case .reject: print("Rejecting request for \(request.agentID): \(request.message)") // Logic to send 'n' or 'reject' command } } }This example illustrates the core components: an `Agent` protocol or struct, a `monitor` function to watch for triggers, a `parseOutputForApproval` function using regular expressions, and an `executeAction` method to send feedback. You would then integrate `MyNewAgent` into `coucou`'s main agent management system (e.g., in `AgentMonitor.swift`) to activate it in the app's preferences and monitoring loop. ### One Gotcha: Permissions and Sandbox A notable "gotcha" for `coucou` developers involves macOS Sandbox restrictions and necessary permissions. `coucou` needs to monitor outputs from other processes, potentially read log files from various locations, and interact with system UI elements. This requires specific entitlements. If you encounter issues where `coucou` is not detecting agent prompts or not appearing correctly, double-check the app's sandboxing entitlements in Xcode. You might need to grant it "App Sandbox" exceptions or specific access to user files (`User Selected File` or `Downloads folder` access) for it to function correctly with agents that write to non-standard locations. Incorrect entitlements can lead to silent failures where `coucou` cannot access the data it needs to monitor. ## Contributing to the Project: The Open-Source PR Process Contributing to `coucou` is a straightforward process, common to many open-source Swift projects. Here is a breakdown: ### Step 0: When to Open an Issue vs. Go Straight to a PR * **Open an Issue FIRST:** For structural changes, new agent integrations, significant feature requests, or discussions about architectural directions, always start by opening a GitHub Issue. This allows maintainers and the community to discuss the idea, provide feedback, and ensure the proposed change aligns with `coucou`'s vision before you invest significant development time. For example, proposing a new monitoring mechanism (e.g., directly interfacing with LSP servers) warrants an issue. * **Go Straight to a PR:** For content fixes (typos in the UI or documentation), small bug fixes, minor UI improvements, or adding support for a new version of an *already supported* agent (if the change is contained), you can often go straight to a pull request. If unsure, an issue is always the safer bet. ### Step 1: Fork, Clone, Install The first step is to get your own working copy of the codebase.# 1. Fork the repository on GitHub (e.g., to your_username/coucou) # 2. Clone your fork locally git clone https://github.com/your_username/coucou.git cd coucou # 3. Ensure you have Xcode installed, then open the project open coucou.xcodeproj # 4. In Xcode, select the 'coucou' target and choose 'My Mac' as the run destination. # Build and run to ensure everything is working correctly on your machine.### Step 2: Locate the Correct File and Follow Conventions Before coding, familiarize yourself with the project's structure (as discussed in "Under the Hood"). * **Agent Logic:** New agent integrations typically go into `coucou/Agents/`. * **UI Changes:** Core UI modifications might be in `coucou/Views/` or directly in `coucou/ContentView.swift`. * **Utility Functions:** Shared helper functions belong in `coucou/Services/` or a dedicated `Utils/` directory if one exists. * **Naming Conventions:** Adhere to Swift API Design Guidelines: clear, concise names; `camelCase` for variables and functions; `PascalCase` for types. * **Formatting:** Maintain consistency with existing code, usually enforced by Xcode's default formatting or a tool like SwiftFormat (if the project uses it). Avoid introducing large diffs that are purely whitespace changes. ### Step 3: Quality Bar for Contributions Maintainers generally look for: * **Functionality:** Does the change work as advertised? Does it resolve the issue or implement the feature correctly? * **Tests:** If applicable, does the contribution include unit or UI tests to cover the new functionality or fix? For a project like `coucou` interacting with external processes, robust testing can be challenging but is always a plus. * **Code Quality:** Clean, readable, idiomatic Swift. Avoid overly complex solutions when simpler ones exist. * **Performance:** No noticeable performance regressions introduced by the change. * **User Experience:** For UI changes, does it maintain or improve `coucou`'s "tiny friend" aesthetic and ease of use? Is the notch/Dynamic Island integration still seamless? * **Scope:** Is the PR focused on a single, well-defined problem or feature? Avoid "kitchen sink" PRs. ### Step 4: Open a PR - The Title, Description, and Post-Merge 1. **Create a New Branch:**git checkout -b feature/my-new-agent-support2. **Commit Your Changes:** Write clear, concise commit messages.git add . git commit -m "feat: add support for MyNewAgent"3. **Push to Your Fork:**git push origin feature/my-new-agent-support- Open a Pull Request: Navigate to your fork on GitHub. GitHub will usually prompt you to open a PR.
- Title Convention: Use a clear, descriptive title following a conventional commit-style (e.g.,
feat: Add support for MyNewAgent,fix: Resolve crash on agent misconfiguration,docs: Update README for new agent). - Description Checklist:
- Problem Solved: Clearly state the motivation.
- Solution: Briefly describe the technical approach.
- Testing: How was this change tested? (e.g., "Tested locally with a mock agent output").
- Screenshots/Video: For UI changes, provide visual evidence.
- Related Issues: Link to any relevant GitHub Issues (e.g.,
Closes #123,Fixes #456). - Self-Review: Mention any areas you are unsure about or would appreciate specific feedback on.
- Title Convention: Use a clear, descriptive title following a conventional commit-style (e.g.,
- Post-Merge: After submitting, maintainers will review, request changes, or merge your PR. Be responsive to feedback. Once merged,
coucou's CI/CD (if present) will handle subsequent builds and releases. You have successfully contributed to an impactful open-source project!
- Open a Pull Request: Navigate to your fork on GitHub. GitHub will usually prompt you to open a PR.
Conclusion
coucou is a pragmatic solution to a growing challenge in developer workflows: the need for unobtrusive oversight of AI coding agents. Its strength comes from its opinionated, deeply integrated approach within the Apple ecosystem, transforming a potential distraction into a seamless, actionable interaction.
Here are three takeaways for developers:
- Streamline AI Agent Approvals: If your workflow involves AI coding agents that require periodic human approval,
coucouoffers an alternative to monitoring terminals or generic notifications. Use its notch and Lock Screen integration for immediate, context-aware decision-making. - Use Swift for Native Integration: For those developing macOS or iOS tools,
coucoushows how to create highly integrated, performant system utilities with Swift and SwiftUI. Its architecture offers a reference for building applications that interact with OS-level UI components. - Contribute to a Focused Open-Source Project:
coucouprovides an opportunity to contribute to a well-scoped, impactful project. Whether it is adding support for a new AI agent, refining existing integrations, or improving the user experience, the clear contribution guidelines make it accessible for developers interested in enhancing a tool that solves a real-world problem.
Explore coucou further, examine its codebase, or contribute your own enhancements by visiting its project page on Fossy: https://fossy.dev/Louis-CFM/coucou.







