Skip to content

Commit 3f92277

Browse files
committed
Initial commit
0 parents  commit 3f92277

34 files changed

+1537
-0
lines changed

.github/workflows/release.yml

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
name: Release
2+
3+
on:
4+
push:
5+
tags:
6+
- 'v*'
7+
workflow_dispatch: # click the button on Github repo!
8+
9+
jobs:
10+
build-macos:
11+
runs-on: macos-latest
12+
strategy:
13+
matrix:
14+
target:
15+
- x86_64-apple-darwin
16+
- aarch64-apple-darwin
17+
18+
steps:
19+
- name: Checkout code
20+
uses: actions/checkout@v4
21+
22+
- name: Set up Rust
23+
uses: dtolnay/rust-toolchain@v1
24+
with:
25+
toolchain: stable
26+
targets: ${{ matrix.target }}
27+
28+
- name: Install cargo-bundle
29+
run: cargo install cargo-bundle
30+
31+
- name: Cache cargo registry
32+
uses: actions/cache@v4
33+
with:
34+
path: ~/.cargo/registry
35+
key: ${{ runner.os }}-cargo-registry-${{ hashFiles('**/Cargo.lock') }}
36+
37+
- name: Cache cargo index
38+
uses: actions/cache@v4
39+
with:
40+
path: ~/.cargo/git
41+
key: ${{ runner.os }}-cargo-index-${{ hashFiles('**/Cargo.lock') }}
42+
43+
- name: Cache cargo build
44+
uses: actions/cache@v4
45+
with:
46+
path: target
47+
key: >-
48+
${{ runner.os }}-cargo-build-target-${{ matrix.target }}-${{
49+
hashFiles('**/Cargo.lock') }}
50+
51+
- name: Build release binary
52+
run: cargo build --release --target ${{ matrix.target }}
53+
54+
- name: Create app bundle
55+
run: cargo bundle --release --target ${{ matrix.target }}
56+
57+
- name: Create archive
58+
run: |
59+
tar -czf "Something-in-the-Background-${{ matrix.target }}.tar.gz" \
60+
-C "target/${{ matrix.target }}/release/bundle/osx" \
61+
"Something in the Background.app"
62+
63+
- name: Upload artifact
64+
uses: actions/upload-artifact@v4
65+
with:
66+
name: something-bg-${{ matrix.target }}
67+
path: Something-in-the-Background-${{ matrix.target }}.tar.gz
68+
69+
release:
70+
needs: build-macos
71+
runs-on: ubuntu-latest
72+
if: startsWith(github.ref, 'refs/tags/v')
73+
74+
steps:
75+
- name: Checkout code
76+
uses: actions/checkout@v4
77+
78+
- name: Download all artifacts
79+
uses: actions/download-artifact@v4
80+
81+
- name: Move artifacts to root
82+
run: |
83+
mv something-bg-*/Something-in-the-Background-*.tar.gz .
84+
85+
- name: Create Release
86+
uses: softprops/action-gh-release@v1
87+
with:
88+
files: |
89+
Something-in-the-Background-x86_64-apple-darwin.tar.gz
90+
Something-in-the-Background-aarch64-apple-darwin.tar.gz
91+
generate_release_notes: true
92+
env:
93+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
/target
2+
.DS_Store

CLAUDE.md

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
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

Comments
 (0)