|
| 1 | +# CLAUDE.md |
| 2 | + |
| 3 | +This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. |
| 4 | + |
| 5 | +## Project Overview |
| 6 | + |
| 7 | +Something in the Background is a macOS menu bar application written in Rust that manages SSH tunnels, Kubernetes port forwarding, and other background processes. It provides a simple interface for toggling various services through the system menu bar. |
| 8 | + |
| 9 | +## Build and Development Commands |
| 10 | + |
| 11 | +### Building the Application |
| 12 | +```bash |
| 13 | +cargo build --release |
| 14 | +``` |
| 15 | + |
| 16 | +### Creating macOS App Bundle |
| 17 | +```bash |
| 18 | +cargo bundle --release |
| 19 | +``` |
| 20 | +The app bundle will be created at `target/release/bundle/osx/Something in the Background.app` |
| 21 | + |
| 22 | +### Installing to Applications |
| 23 | +```bash |
| 24 | +cp -r "target/release/bundle/osx/Something in the Background.app" /Applications/ |
| 25 | +``` |
| 26 | + |
| 27 | +### Running in Development |
| 28 | +```bash |
| 29 | +cargo run |
| 30 | +``` |
| 31 | + |
| 32 | +## Architecture |
| 33 | + |
| 34 | +### Core Components |
| 35 | + |
| 36 | +- **main.rs** - Entry point with Cocoa setup, global app initialization, and run loop |
| 37 | +- **app.rs** - Main application state containing TunnelManager and StatusItem wrapper |
| 38 | +- **config.rs** - TOML configuration loading and management |
| 39 | +- **menu.rs** - NSStatusItem and NSMenu creation, icon management, Objective-C bridge |
| 40 | +- **tunnel.rs** - SSH tunnel and port forwarding logic with TunnelManager |
| 41 | +- **logger.rs** - macOS-specific logging configuration using oslog |
| 42 | + |
| 43 | +### Key Design Patterns |
| 44 | + |
| 45 | +1. **Global App State**: Uses `OnceLock<App>` for thread-safe global access from Objective-C callbacks |
| 46 | +2. **Thread-Safe Wrappers**: `StatusItemWrapper` makes Cocoa objects thread-safe |
| 47 | +3. **Objective-C Bridge**: Custom MenuHandler class bridges Cocoa events to Rust functions |
| 48 | +4. **Async Tunnel Management**: Spawns threads for long-running SSH processes |
| 49 | + |
| 50 | +### Tunnel Configuration |
| 51 | + |
| 52 | +Tunnels are configured via TOML file at `~/.config/something_bg/config.toml`. The configuration file is automatically created with defaults on first run. Default tunnels include: |
| 53 | +- **example-ssh**: SSH tunnel with port forwarding |
| 54 | +- **k8s-example**: Kubernetes port forwarding for services |
| 55 | +- **colima**: Docker environment management via Colima |
| 56 | + |
| 57 | +Each tunnel configuration includes: |
| 58 | +- `name`: Display name in the menu |
| 59 | +- `command`: Command to execute |
| 60 | +- `args`: Arguments for the command |
| 61 | +- `kill_command`: Command to stop the tunnel |
| 62 | +- `kill_args`: Arguments for the kill command |
| 63 | + |
| 64 | +The configuration also includes a global `path` setting that defines the PATH environment variable used when executing commands. This allows customization of where the system looks for executables. |
| 65 | + |
| 66 | +The configuration structure in `config.rs` handles TOML serialization/deserialization and loading from the user's home directory. |
| 67 | + |
| 68 | +### Configuration Management |
| 69 | + |
| 70 | +The app uses a TOML-based configuration system: |
| 71 | + |
| 72 | +1. **Default Configuration**: If no config file exists, the app creates one with default tunnels |
| 73 | +2. **Dynamic Loading**: Configuration is loaded both at startup and when creating the menu |
| 74 | +3. **Fallback Behavior**: If config loading fails, the app falls back to hardcoded defaults |
| 75 | +4. **User Customization**: Users can modify `~/.config/something_bg/config.toml` to add/remove tunnels |
| 76 | + |
| 77 | +The configuration format supports any command-line tool that can be started and stopped, not just SSH tunnels. |
| 78 | + |
| 79 | +### Icon System |
| 80 | + |
| 81 | +The app uses PNG icons in `resources/images/` with two states: |
| 82 | +- **Inactive**: `peacock_folded_16x16.png` |
| 83 | +- **Active**: `peacock_open_16x16.png` |
| 84 | + |
| 85 | +Falls back to Unicode symbols (☷/☰) if images fail to load. |
| 86 | + |
| 87 | +## Dependencies |
| 88 | + |
| 89 | +- **cocoa/objc**: macOS Cocoa framework bindings |
| 90 | +- **core-foundation**: Core Foundation framework access |
| 91 | +- **log/oslog**: macOS system logging |
| 92 | +- **libc**: System calls |
| 93 | +- **toml**: TOML configuration file parsing |
| 94 | +- **serde**: Serialization/deserialization framework |
| 95 | + |
| 96 | +Uses a patched version of `objc` crate from a third-party fork for compatibility. |
| 97 | + |
| 98 | +## Important Notes |
| 99 | + |
| 100 | +- App uses NSApplicationActivationPolicyAccessory (background/menu bar only) |
| 101 | +- Tunnels are cleaned up automatically on app termination |
| 102 | +- Status item icon updates based on active tunnel state |
| 103 | +- PATH is extended to include Homebrew binaries for command execution |
| 104 | +- Uses NSAutoreleasePool for proper memory management |
0 commit comments