Chau7 is a macOS menu bar helper and floating terminal overlay built for AI-assisted CLI work. It tails local JSONL logs and CLI history to send notifications and keep a live multi-tab terminal in view.
- Menu bar status item with quick toggles, recent activity, and session status.
- Native notifications for AI events and command idle detection.
- Multi-tab terminal overlay with rename, colors, last-command badges, and git branch indicator.
- Command palette, search overlay (regex + case sensitivity), snippets, clipboard history, bookmarks, and broadcast input.
- AI CLI detection with auto tab theming and custom detection rules.
- Multi-agent event monitoring, notifications, and runtime integration for modern AI CLIs.
- SSH connection manager with jump hosts and import from
~/.ssh/config.
For a complete feature inventory, see docs/FEATURES.md:
- Overview
- Terminal Overlay and Emulator
- AI Integration and Monitoring
- Productivity Tools
- Settings and Customization
- Debugging and Diagnostics
- Keyboard Shortcuts
- Environment Variables
- macOS 14+
- Xcode 26+ to build
- Network access the first time to fetch Swift Package Manager dependencies
Repo-root verification lives outside the app-specific build helpers:
../../Scripts/ci-local-fast
../../Scripts/ci-localUse those for local verification. Keep ./Scripts/build-app.sh, ./Scripts/build-and-run.sh, and
./Scripts/order66 for packaging and launch workflows.
For repo-wide doc ownership and canonical entry points, see ../../docs/README.md.
brew tap aeptus/chau7
brew install --cask chau7Or grab the DMG from the latest release.
All commands below assume you are in apps/chau7-macos.
- Open
Package.swiftin Xcode. - Select the
Chau7scheme. - Run (Cmd+R).
The first time it runs, macOS will ask for Notifications permission.
To see verbose logs when launched from Terminal, set CHAU7_VERBOSE=1.
From the project folder:
swift build -c release
CHAU7_VERBOSE=1 .build/release/Chau7Keep the app running to keep notifications active.
For notifications to show up under their own app entry in macOS Settings, run the helper script to create an app bundle:
swift build -c release
./Scripts/build-app.sh
open ./build/Chau7.appbuild-app.sh now defaults to a development bundle identifier (com.chau7.app.dev) to avoid
macOS TCC permission collisions with the Launchpad app.
Quick install one-liner:
swift build -c release && ./Scripts/build-app.sh && open ./build/Chau7.appDock icon is enabled by default for the app bundle; to hide it:
SHOW_DOCK_ICON=0 ./Scripts/build-app.sh./Scripts/build-and-run.shbuild-and-run.sh now defaults to a dev bundle identifier (com.chau7.app.dev) to avoid
macOS permission collisions with /Applications/Chau7.app.
When ad-hoc signing is used, it now applies a stable designated requirement
(designated => identifier "<bundle-id>") so TCC permissions do not churn on every rebuild.
The local build scripts also rebuild and bundle chau7-remote automatically so the remote
helper stays in sync with app bundles.
Code signing is auto-detected. Local dev builds prefer an Apple Development: certificate,
installed/release builds prefer Developer ID Application:, and scripts fall back to
stable ad-hoc signing when no Apple signing identity is installed.
Override when needed:
BUNDLE_IDENTIFIER=com.chau7.app ./Scripts/build-and-run.sh
CHAU7_CODESIGN_IDENTITY="Apple Development: Your Name (TEAMID)" ./Scripts/build-and-run.shTo install the production Launchpad app (com.chau7.app) into /Applications:
./Scripts/install-launchpad-app.shNote: this script refuses to replace /Applications/Chau7.app while it is running.
Replacing a running app causes TCC code-requirement mismatches and repeated permission prompts.
To force Developer ID signing for the Launchpad app:
CHAU7_CODESIGN_IDENTITY="Developer ID Application: Your Name (TEAMID)" ./Scripts/install-launchpad-app.shBuild a clean testing DMG:
./Scripts/build-dist.shThis produces apps/chau7-macos/dist/Chau7-AppleSilicon.dmg with:
Chau7.app- an
Applicationssymlink - bundled legal notices inside the app
When a Developer ID Application: identity is installed, the app bundle and DMG are signed
with it automatically. Without one, the script falls back to stable ad-hoc app signing.
If you explicitly want the larger mixed-architecture helper build, use:
./Scripts/build-dist.sh --universalThat produces apps/chau7-macos/dist/Chau7-Universal.dmg.
Notarization is opt-in. First store Apple notary credentials in the keychain:
xcrun notarytool store-credentials chau7-notary --apple-id you@example.com --team-id TEAMID --password app-specific-passwordThen build, submit, wait, and staple:
CHAU7_CODESIGN_IDENTITY="Developer ID Application: Your Name (TEAMID)" \
CHAU7_NOTARY_PROFILE=chau7-notary \
CHAU7_NOTARIZE=1 \
./Scripts/build-dist.shImportant limits:
- ad-hoc fallback builds are not notarized
- first launch after switching from ad-hoc to Apple signing may require macOS permissions once
- first launch of an ad-hoc build on another Mac may require Finder: Control-click
Chau7.app->Open
Optional: launch it after install:
OPEN_AFTER_INSTALL=1 ./Scripts/install-launchpad-app.shYou can also run the bundled binary directly with verbose logs:
CHAU7_VERBOSE=1 ./build/Chau7.app/Contents/MacOS/Chau7For extremely verbose trace logs (tailers, parsing, idle tracking):
CHAU7_VERBOSE=1 CHAU7_TRACE=1 ./build/Chau7.app/Contents/MacOS/Chau7Logs are written to:
~/Library/Logs/Chau7.log
- Open overlay: menu bar icon → "Open Terminal"
- New tab: Cmd+T
- Command palette: Cmd+Shift+P
- Find: Cmd+F (regex and case toggles)
- Snippets: Cmd+;
- Next/prev tab: Cmd+Shift+] / Cmd+Shift+[
- Toggle dropdown: Ctrl+` (if enabled)
- Debug console: Cmd+Shift+D
The app ships with a floating terminal overlay powered by the native Rust terminal backend. It starts automatically and provides:
- A shell running your default login shell (configurable)
- Tabs with standard shortcuts (Cmd+T, Cmd+W, Cmd+Shift+[ / ], Ctrl+Tab)
- Multi-window support (Cmd+N) and tab jump (Cmd+1-9)
- Search overlay with regex/case-sensitive options (Cmd+F)
- Command palette (Cmd+Shift+P) and snippets (Cmd+;)
- Clipboard history, bookmarks, and broadcast input
- AI CLI detection with auto tab colors and product icons
- Command idle notifications based on input/output activity
- Optional dropdown terminal (Ctrl+`) when enabled in Settings
Use the menu bar icon to reopen the overlay if the window is hidden.
Idle behavior:
- "Idle seconds" triggers a notification.
- "Stale seconds" marks sessions closed and stops further idle alerts.
Default log file: ~/.ai-events.log
Use the helper script:
./Scripts/ai-event.sh needs_validation "Claude" "Please review the plan"
./Scripts/ai-event.sh finished "Codex" "Bulk upload complete"
./Scripts/ai-event.sh failed "Codex" "Tests failed"Each line is JSON. Example:
{"type":"finished","tool":"Codex","message":"Bulk upload complete","ts":"2026-01-09T12:00:00+01:00"}You can wrap your commands. Example pattern:
your_command_here || ./Scripts/ai-event.sh failed "Claude" "Command failed"
./Scripts/ai-event.sh finished "Claude" "Command finished"There are example wrapper scripts in Scripts/.
The history JSONL logs do not include the live terminal output. To capture it, use the PTY wrappers:
./Scripts/codex-pty.sh
./Scripts/claude-pty.shWhen running AI CLIs inside the Chau7 terminal overlay, PTY output and AI events are captured automatically. The wrappers are only needed for external terminals.
These log raw terminal output to:
~/Library/Logs/Chau7/codex-pty.log~/Library/Logs/Chau7/claude-pty.log
You can override the paths with:
AI_CODEX_TTY_LOG=~/codex-tty.log ./Scripts/codex-pty.sh
AI_CLAUDE_TTY_LOG=~/claude-tty.log ./Scripts/claude-pty.shInput lines are tagged as:
[INPUT] your text
If Codex is installed through Volta, Terminal.app can resolve codex through
~/.volta/bin before the npm-managed Node image bin. That leaves Terminal.app
running a stale Volta package image even after Codex's update prompt updates the
npm global package. Chau7's built-in terminal already repairs this PATH order at
startup; for Terminal.app, install the same managed zsh startup block:
./Scripts/install-codex-terminal-path-fix.shOpen a new Terminal.app window and verify:
command -v codex
codex --versionThe first command should point under ~/.volta/tools/image/node/.../bin/codex,
not ~/.volta/bin/codex.
TTY readability:
- "Normalize terminal output" strips ANSI codes, handles backspaces, and removes control chars.
- You can disable it in the UI or set
CHAU7_TERMINAL_NORMALIZE=0(legacyAI_TTY_NORMALIZE=0). - "Render ANSI styling" keeps ANSI colors/styles in the terminal stream (set
CHAU7_TERMINAL_ANSI=0or legacyAI_TTY_ANSI=0).
A sample LaunchAgent plist is included in LaunchAgent/.
Because the binary path depends on where you built it, do this:
- Build release:
swift build -c release- Copy the binary somewhere stable, for example:
mkdir -p ~/Applications/Chau7
cp .build/release/Chau7 ~/Applications/Chau7/- Edit
LaunchAgent/com.chau7.plistand set the binary path to:
$HOME/Applications/Chau7/Chau7
- Install the LaunchAgent:
mkdir -p ~/Library/LaunchAgents
cp LaunchAgent/com.chau7.plist ~/Library/LaunchAgents/
launchctl load -w ~/Library/LaunchAgents/com.chau7.plistUnload:
launchctl unload -w ~/Library/LaunchAgents/com.chau7.plist- API Proxy: The optional TLS proxy (
chau7-proxy) runs locally on your machine for AI API analytics. API keys pass through to the original provider and are never stored or transmitted elsewhere. The proxy is opt-in and can be disabled in Settings. - MCP Server: The Unix socket API is bound to
~/.chau7/mcp.sockwith0600permissions (owner-only access). - Bug Reports: Submitted via a Cloudflare Worker relay to a private GitHub repo. No data is sent without explicit user action. All diagnostic sections are opt-in. See the in-app privacy page for full GDPR sub-processor disclosure.
- Terminal Data: Scrollback, command history, and telemetry stay on your machine in
~/.chau7/and~/Library/Application Support/Chau7/.
For vulnerability reports, see SECURITY.md.
- Notifications do not appear: run the app bundle (
./Scripts/build-app.sh), and verify notifications are allowed in System Settings. - Menu bar icon is missing: quit and relaunch, or check
~/Library/Logs/Chau7.logfor launch errors. - No AI events: confirm
~/.ai-events.logis being written andCHAU7_EVENTS_LOGis not pointing elsewhere. - PTY logs are empty: if you are using an external terminal, run
./Scripts/codex-pty.shor./Scripts/claude-pty.shand verifyCHAU7_CODEX_TERMINAL_LOG/CHAU7_CLAUDE_TERMINAL_LOG. Inside the Chau7 terminal overlay, logs are captured automatically. - Overlay is hidden or off-screen: use Settings -> Actions -> Reset Window Positions, then reopen via the menu bar icon.
Q: What does an AI event line look like?
A: Each line is JSON with at least type and tool. Example:
{"type":"finished","tool":"Codex","message":"Bulk upload complete","ts":"2026-01-09T12:00:00+01:00"}Q: How do I emit events from my own CLI? A: Use the helper script or inline it in your wrappers:
./Scripts/ai-event.sh needs_validation "Claude" "Please review the plan"
./Scripts/ai-event.sh finished "Codex" "All done"
./Scripts/ai-event.sh failed "Codex" "Tests failed"Q: How do I capture live terminal output (PTY)? A: Run the PTY wrappers instead of calling the CLI directly:
./Scripts/codex-pty.sh
./Scripts/claude-pty.shLogs default to ~/Library/Logs/Chau7/codex-pty.log and ~/Library/Logs/Chau7/claude-pty.log.
Chau7 includes a comprehensive test suite for core functionality.
# Ensure Xcode is set as the developer directory
sudo xcode-select -s /Applications/Xcode.app/Contents/Developer
# Run all tests
swift test- CommandDetectionTests (40 tests): AI CLI detection, tokenization, environment parsing
- EventParsingTests (6 tests): Hook event parsing, session ID extraction
Tests live in apps/chau7-macos/Tests/Chau7Tests/. The testable logic is in apps/chau7-macos/Sources/Chau7Core/:
CommandDetection.swift- Pure functions for detecting AI CLIs- Add new pure functions here for testability
- Build the remote agent from the repo root:
cd services/chau7-remote && go build ./cmd/chau7-remote - Configure relay and pairing in Chau7 settings:
Settings > Remote Control
Press Cmd+Shift+D anywhere in the app to open the Debug Console:
- State: Real-time app state, tabs, Claude sessions
- Contexts: Active debug operations with correlation IDs
- Events: Claude Code event stream
- Logs: Live log viewer with filtering
- Report: Generate bug reports and state snapshots
All operations use correlation IDs for tracing:
[ABC123] START command-detection {input=claude --help}
[ABC123] Found token {token=claude}
[ABC123] END command-detection SUCCESS (2ms) {result=Claude}
Logs are written to ~/Library/Logs/Chau7.log
Generate detailed bug reports from the Debug Console or programmatically:
let path = BugReporter.shared.generateReport(userDescription: "Describe the issue")Reports are saved to ~/.chau7/reports/ and include:
- Full app state snapshot
- Recent events
- Last 50 log lines
- Feature flag states
- Notifications are delivered via UserNotifications (native).
- If you want action buttons (Approve or Retry), that is a small follow-up change.