Bossa

Unified CLI for managing your development environment.

Bossa (Portuguese for "style" or "flair") brings together machine bootstrapping, package management, repository collections, and storage management into a single, declarative tool.

Why Bossa?

Setting up and maintaining a development environment involves many moving parts:

  • Installing and updating packages (Homebrew, npm, pip)
  • Managing dotfiles and configurations
  • Cloning and organizing reference repositories
  • Handling storage across local SSD, iCloud, and external drives
  • Bootstrapping new machines consistently

Bossa unifies these concerns with a declarative, idempotent approach.

Key Features

FeatureDescription
NovaBootstrap a new machine in 16 stages
BrewDeclarative Homebrew management with drift detection
CollectionsManage groups of git repositories
StorageUnified view of SSD, iCloud, and external drives
iCloudDownload, evict, and manage iCloud Drive files
ManifestHash files and find duplicates across locations
DoctorHealth checks for all systems

Quick Example

# Bootstrap a new machine
bossa nova

# Check system status
bossa status

# Apply desired state
bossa apply

# Manage Homebrew packages
bossa brew apply
bossa brew audit

# Sync repository collections
bossa collections sync refs

Design Principles

  1. Declarative: Define desired state, let bossa figure out how to get there
  2. Idempotent: Run commands multiple times safely
  3. Parallel: Operations run concurrently where possible
  4. Observable: Clear status reporting and drift detection

Getting Started

License

MIT

Installation

The easiest way to install bossa on macOS:

brew install albertocavalcante/tap/bossa

Note: Use the full tap path to avoid conflict with homebrew-core's bossa (a flash programmer tool).

Pre-built Binaries

Download pre-built binaries from the GitHub Releases page.

macOS

# Apple Silicon (arm64)
curl -LO https://github.com/albertocavalcante/bossa/releases/latest/download/bossa-darwin-arm64.tar.gz
tar xzf bossa-darwin-arm64.tar.gz
sudo mv bossa /usr/local/bin/

# Intel (amd64)
curl -LO https://github.com/albertocavalcante/bossa/releases/latest/download/bossa-darwin-amd64.tar.gz
tar xzf bossa-darwin-amd64.tar.gz
sudo mv bossa /usr/local/bin/

Linux

# x86_64
curl -LO https://github.com/albertocavalcante/bossa/releases/latest/download/bossa-linux-amd64.tar.gz
tar xzf bossa-linux-amd64.tar.gz
sudo mv bossa /usr/local/bin/

# ARM64
curl -LO https://github.com/albertocavalcante/bossa/releases/latest/download/bossa-linux-aarch64.tar.gz
tar xzf bossa-linux-aarch64.tar.gz
sudo mv bossa /usr/local/bin/

From Source

Using Cargo

# Clone the repository
git clone https://github.com/albertocavalcante/bossa.git
cd bossa

# Install with cargo
cargo install --path .

Using Bazel

# Clone the repository
git clone https://github.com/albertocavalcante/bossa.git
cd bossa

# Build and install
bazel run //:install

Shell Completions

Generate shell completions for your preferred shell:

# Bash
bossa completions bash >> ~/.bashrc

# Zsh
bossa completions zsh >> ~/.zshrc

# Fish
bossa completions fish > ~/.config/fish/completions/bossa.fish

# PowerShell
bossa completions powershell >> $PROFILE

Verify Installation

bossa --version
bossa --help

Updating

Homebrew

brew upgrade bossa

Cargo

cargo install --path . --force

Quick Start

This guide gets you up and running with bossa in minutes.

Prerequisites

  • macOS or Linux
  • Git installed
  • Homebrew (optional, for bossa brew commands)

First Steps

1. Check System Status

See what bossa can manage on your system:

bossa status

This shows an overview of:

  • Homebrew packages (installed vs desired)
  • Repository collections
  • Storage locations

2. Run Health Checks

Verify your system is properly configured:

bossa doctor

The doctor command checks:

  • Git configuration
  • SSH keys
  • Homebrew installation
  • Required tools

Common Workflows

Managing Homebrew Packages

# See what would change
bossa brew audit

# Apply your Brewfile
bossa brew apply

# Capture currently installed packages
bossa brew capture

Managing Repository Collections

Collections are groups of git repositories that you want to keep in sync.

# List your collections
bossa collections list

# Check collection status
bossa collections status refs

# Clone missing repositories
bossa collections sync refs

# Add a new repo to a collection
bossa collections add refs https://github.com/user/repo.git

Bootstrapping a New Machine

The nova command runs through 16 stages to set up a new machine:

# See available stages
bossa nova --list-stages

# Run all stages
bossa nova

# Run specific stages only
bossa nova --only=homebrew,brew,stow

# Skip certain stages
bossa nova --skip=dock,handlers

# Dry run to see what would happen
bossa nova --dry-run

Storage Management

Get a unified view of your storage:

# Overview of all storage locations
bossa storage status

# Find duplicates across locations
bossa storage duplicates

iCloud Management

Control what's downloaded from iCloud Drive:

# See iCloud status
bossa icloud status

# Download files
bossa icloud download ~/Library/Mobile\ Documents/

# Evict files to free local space
bossa icloud evict ~/Library/Mobile\ Documents/some-folder/

Configuration

Bossa reads configuration from ~/.config/bossa/:

~/.config/bossa/
├── config.toml    # Unified config (collections, workspaces, storage, packages)
└── caches.toml    # Cache mappings (created by `bossa caches init`)

Homebrew uses a Brewfile at ~/dotfiles/Brewfile by default (override with bossa brew apply --file <path>).

See Configuration for details.

Next Steps

Configuration

Bossa uses configuration files to define your desired system state.

Configuration Directory

All configuration lives in ~/.config/bossa/:

~/.config/bossa/
├── config.toml    # Unified config (collections, workspaces, storage, packages)
├── caches.toml    # Cache mappings (created by `bossa caches init`)
└── manifests/     # Manifest databases (auto-generated)

File Format

Bossa uses TOML for config.toml. The caches file is also TOML by default (created with bossa caches init).

Legacy configs from ~/.config/workspace-setup/ can be migrated with:

bossa migrate --dry-run
bossa migrate

Repository Collections (config.toml)

Define groups of repositories to manage:

# Collection name becomes a directory
[collections.refs]
path = "~/dev/refs"

[[collections.refs.repos]]
url = "https://github.com/rust-lang/rust.git"
name = "rust"
name = "rust" # Optional, derived from URL if omitted

[[collections.refs.repos]]
url = "https://github.com/torvalds/linux.git"
name = "linux"

[collections.tools]
path = "~/dev/tools"

[[collections.tools.repos]]
url = "https://github.com/neovim/neovim.git"
name = "neovim"

Workspaces (config.toml)

Define development workspaces:

[workspaces]
root = "~/dev/ws"
structure = "bare-worktree"

[[workspaces.repos]]
name = "myproject"
url = "https://github.com/user/myproject.git"
category = "work"

[[workspaces.repos]]
name = "another"
url = "git@github.com:user/another.git"
category = "personal"

Brewfile

Standard Homebrew bundle format. By default bossa reads ~/dotfiles/Brewfile (override with --file or --output):

# Taps
tap "homebrew/bundle"
tap "albertocavalcante/tap"

# Formulae
brew "git"
brew "ripgrep"
brew "fd"
brew "jq"
brew "gh"

# Casks
cask "visual-studio-code"
cask "iterm2"
cask "docker"

# Mac App Store
mas "Xcode", id: 497799835

Cache Mappings (caches.toml)

Map cache directories to external storage:

external_drive = { name = "T9", mount_point = "/Volumes/T9", base_path = "caches" }

[[symlinks]]
name = "homebrew"
source = "~/Library/Caches/Homebrew"
target = "homebrew"
description = "Homebrew downloads"

[[symlinks]]
name = "cargo-registry"
source = "~/.cargo/registry"
target = "cargo/registry"

Validation

Validate your configuration files:

# Check all configs
bossa doctor

# Show health checks
bossa doctor

Best Practices

  1. Use TOML - More readable than JSON, with comments support
  2. Version control - Keep configs in a dotfiles repo
  3. Keep Brewfile in dotfiles - Default is ~/dotfiles/Brewfile
  4. Capture regularly - Run bossa brew capture after installing packages
  5. Audit for drift - Run bossa brew audit periodically

Machine Bootstrap (Nova)

The nova command bootstraps a new machine through 16 stages. The name comes from "bossa nova" - the Brazilian music genre.

Usage

# Run all stages
bossa nova

# List available stages
bossa nova --list-stages

# Run specific stages only
bossa nova --only=homebrew,brew,stow

# Skip certain stages
bossa nova --skip=dock,handlers

# Dry run
bossa nova --dry-run

# Parallel execution
bossa nova -j 4

Stages

StageDescription
defaultsmacOS system defaults (Finder, Dock, keyboard settings)
terminalTerminal font setup
git-signingGit commit signing key configuration
homebrewHomebrew installation
bashBash 4+ bootstrap (macOS ships with Bash 3)
essentialEssential packages (stow, jq, gh, ripgrep, fd)
brewFull Brewfile installation
pnpmNode.js packages via pnpm
dockDock configuration (apps, size, position)
ecosystemEcosystem extensions (VS Code, etc.)
handlersFile type handlers via duti
stowSymlinks via GNU Stow
cachesCache symlinks to external drive
mcpMCP server configuration
refsReference repository collections
workspacesDevelopment workspaces

Stage Details

defaults

Configures macOS system preferences:

  • Finder: Show hidden files, path bar, status bar
  • Dock: Size, magnification, position
  • Keyboard: Key repeat rate, disable auto-correct
  • Screenshots: Location, format

homebrew

Installs Homebrew if not present:

/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"

essential

Installs core utilities needed by other stages:

  • stow - Symlink manager for dotfiles
  • jq - JSON processor
  • gh - GitHub CLI
  • ripgrep - Fast search
  • fd - Fast find

brew

Runs brew bundle with your Brewfile:

brew bundle --file=~/dotfiles/Brewfile

stow

Symlinks dotfiles from your dotfiles repository:

cd ~/dotfiles
stow -t ~ bash zsh git vim

caches

Applies cache symlink configuration:

bossa caches apply

refs

Clones repository collections defined in config.toml:

bossa collections sync refs

Customizing Stages

Running Specific Stages

# Only install Homebrew and essential tools
bossa nova --only=homebrew,essential

# Skip dock configuration
bossa nova --skip=dock

Stage Dependencies

Some stages depend on others:

  • brew requires homebrew
  • stow requires essential (for stow binary)
  • refs requires essential (for git)

When using --only, dependencies are not automatically included. Make sure to include required stages.

Dry Run

Preview what would happen without making changes:

bossa nova --dry-run

Idempotency

All stages are idempotent - running them multiple times is safe:

  • Already installed packages are skipped
  • Existing symlinks are preserved
  • Configurations are applied only if different

Parallelism

Use -j to run independent stages in parallel:

bossa nova -j 4

Stages with dependencies still run in order.

Troubleshooting

Stage Failed

If a stage fails, fix the issue and re-run:

# Re-run failed stage
bossa nova --only=brew

Reset and Retry

# Skip problematic stages
bossa nova --skip=dock,handlers

Verbose Output

bossa nova -vv

Homebrew Management

Bossa provides declarative Homebrew package management with drift detection.

Commands

bossa brew apply     # Install packages from Brewfile
bossa brew capture   # Update Brewfile with installed packages
bossa brew audit     # Detect drift between installed and desired
bossa brew list      # List installed packages

Workflow

1. Capture Current State

Start by capturing your currently installed packages:

bossa brew capture

This updates ~/dotfiles/Brewfile with all installed:

  • Formulae
  • Casks
  • Taps
  • Mac App Store apps

2. Apply Desired State

Install packages defined in your Brewfile:

bossa brew apply

This runs brew bundle and installs missing packages.

3. Detect Drift

Check if installed packages match your Brewfile:

bossa brew audit

Output shows:

  • Missing: In Brewfile but not installed
  • Untracked: Installed but not in Brewfile
  • Version mismatches: Installed version differs from Brewfile

Brewfile Format

Standard Homebrew bundle format:

# Taps - third-party repositories
tap "homebrew/bundle"
tap "homebrew/services"
tap "albertocavalcante/tap"

# Formulae - command-line tools
brew "git"
brew "ripgrep"
brew "fd"
brew "jq"
brew "gh"
brew "neovim"

# Casks - GUI applications
cask "visual-studio-code"
cask "iterm2"
cask "docker"
cask "1password"

# Mac App Store apps (requires `mas` CLI)
mas "Xcode", id: 497799835
mas "Slack", id: 803453959

Options

Apply Options

# Only install essentials (no casks/mas/vscode)
bossa brew apply --essential

# Dry run
bossa brew apply --dry-run

# Use a specific Brewfile
bossa brew apply --file ~/path/to/Brewfile

Capture Options

# Write to a specific path
bossa brew capture --output ~/dotfiles/Brewfile

List Options

# Filter by type: tap, brew, cask, mas, vscode
bossa brew list --type cask

Best Practices

1. Organize Your Brewfile

Group packages by category with comments:

# === Development ===
brew "git"
brew "gh"
brew "neovim"

# === Languages ===
brew "rust"
brew "go"
brew "python@3.12"

# === Utilities ===
brew "ripgrep"
brew "fd"
brew "jq"
brew "yq"

# === Applications ===
cask "visual-studio-code"
cask "iterm2"

2. Version Control

Keep your Brewfile in version control (default is ~/dotfiles/Brewfile):

cd ~/dotfiles
git add Brewfile
git commit -m "Update Brewfile"

3. Regular Audits

Run audits periodically to catch drift:

# Add to crontab or run weekly
bossa brew audit

4. Capture After Installing

After installing new packages manually, capture the change:

brew install something-new
bossa brew capture

Troubleshooting

Package Not Found

If brew apply fails to find a package:

  1. Check the tap is included in Brewfile
  2. Run brew update
  3. Verify package name: brew search <name>

Cask Already Installed

Casks installed outside Homebrew aren't tracked. Either:

  • Uninstall and reinstall via brew install --cask
  • Add to Brewfile anyway (Homebrew will adopt it)

Mac App Store Apps

Requires mas CLI:

brew install mas
mas signin # Sign in to App Store
bossa brew apply

Collections

Collections are groups of git repositories that you want to manage together. Use them for reference repositories, tools, or any set of repos you want to keep in sync.

Commands

bossa collections list                # List all collections
bossa collections status <name>       # Show clone status
bossa collections sync <name>         # Clone missing repos
bossa collections audit <name>        # Find drift
bossa collections snapshot <name>     # Regenerate config from disk
bossa collections add <name> <url>    # Add repo to collection
bossa collections rm <name> <repo>    # Remove repo from collection
bossa collections clean <name>        # Delete clones (preserve config)

Defining Collections

Collections are defined in ~/.config/bossa/config.toml:

[collections.refs]
path = "~/dev/refs"

[[collections.refs.repos]]
url = "https://github.com/rust-lang/rust.git"
name = "rust"

[[collections.refs.repos]]
url = "https://github.com/torvalds/linux.git"
name = "linux"

[[collections.refs.repos]]
url = "https://github.com/neovim/neovim.git"
name = "neovim"

[collections.tools]
path = "~/dev/tools"

[[collections.tools.repos]]
url = "https://github.com/BurntSushi/ripgrep.git"
name = "ripgrep"

[[collections.tools.repos]]
url = "https://github.com/sharkdp/fd.git"
name = "fd"

Workflow

1. List Collections

See all defined collections:

bossa collections list

Output:

refs (~/dev/refs)
  - rust-lang/rust
  - torvalds/linux
  - neovim/neovim

tools (~/dev/tools)
  - BurntSushi/ripgrep
  - sharkdp/fd

2. Check Status

See which repos are cloned:

bossa collections status refs

Output:

refs (3 repos)
  ✓ rust           cloned
  ✓ linux          cloned
  ✗ neovim         missing

3. Sync Collections

Clone missing repositories:

bossa collections sync refs

Features:

  • Parallel cloning (configurable with -j)
  • Automatic retry on failure
  • Progress reporting

4. Add Repositories

Add a new repo to a collection:

bossa collections add refs https://github.com/golang/go.git

This:

  1. Adds the repo to config.toml
  2. Optionally clones immediately with --clone

5. Remove Repositories

Remove a repo from a collection:

bossa collections rm refs neovim

This removes from config only. Use --delete to also delete the clone.

6. Audit for Drift

Find repos on disk that aren't in config:

bossa collections audit refs

Output:

refs: 1 untracked repo
  ~/dev/refs/some-repo  (not in config)

7. Snapshot from Disk

Regenerate config from what's actually on disk:

bossa collections snapshot refs

Useful when you've manually cloned repos and want to track them.

Options

Sync Options

# Parallel cloning
bossa collections sync refs -j 8

# Retry failed clones
bossa collections sync refs --retries 5

# Dry run
bossa collections sync refs --dry-run

# Verbose output
bossa collections sync refs -v

Add Options

# Custom name
bossa collections add refs https://github.com/user/repo.git --name myrepo

# Clone immediately
bossa collections add refs https://github.com/user/repo.git --clone

Configuration Format

Basic Repository

[[collections.refs.repos]]
url = "https://github.com/user/repo.git"
name = "repo"

When you add repos with the CLI, the name is derived from the URL if omitted.

With Custom Name

[[collections.refs.repos]]
url = "https://github.com/user/repo.git"
name = "custom-name"

SSH URLs

[[collections.refs.repos]]
url = "git@github.com:user/repo.git"
name = "repo"

Use Cases

Reference Repositories

Keep copies of important projects for reference:

[collections.refs]
path = "~/dev/refs"

[[collections.refs.repos]]
url = "https://github.com/rust-lang/rust.git"
name = "rust"

[[collections.refs.repos]]
url = "https://github.com/golang/go.git"
name = "go"

Tool Sources

Track tools you might want to build from source:

[collections.tools]
path = "~/dev/tools"

[[collections.tools.repos]]
url = "https://github.com/neovim/neovim.git"
name = "neovim"

Learning Projects

Curate repos for learning:

[collections.learning]
path = "~/dev/learning"

[[collections.learning.repos]]
url = "https://github.com/codecrafters-io/build-your-own-x.git"
name = "build-your-own-x"

Tips

  1. Use HTTPS for public repos - No SSH key needed
  2. Use SSH for private repos - git@github.com:...
  3. Parallel sync - Use -j for faster cloning
  4. Audit regularly - Catch manual clones with audit
  5. Snapshot before changes - Backup current state

Storage Management

Bossa provides a unified view of storage across your local SSD, iCloud Drive, and external drives.

Commands

bossa storage status      # Unified storage overview
bossa storage duplicates  # Find duplicates across locations

Storage Overview

Get a bird's-eye view of all storage:

bossa storage status

Output:

Storage Overview
================

Local SSD (500 GB)
  Used:      350 GB (70%)
  Available: 150 GB

  Top directories:
    ~/Library           45 GB
    ~/dev               80 GB
    ~/Downloads         12 GB

iCloud Drive (200 GB)
  Used:      120 GB (60%)
  Available:  80 GB
  Local:      45 GB (downloaded)
  Cloud:      75 GB (evicted)

External: T9 (/Volumes/T9)
  Used:      1.2 TB
  Available: 800 GB

  Top directories:
    /Volumes/T9/Backups    500 GB
    /Volumes/T9/Media      400 GB
    /Volumes/T9/Caches     300 GB

Finding Duplicates

Find duplicate files across storage locations:

bossa storage duplicates

This requires manifests to be scanned first:

# Scan locations to build manifests
bossa manifest scan ~/dev
bossa manifest scan ~/Library/Mobile\ Documents
bossa manifest scan /Volumes/External

# Then find duplicates
bossa storage duplicates

Output:

Duplicates Found: 15 files (2.3 GB total)

project-backup.zip (500 MB)
  ~/Downloads/project-backup.zip
  /Volumes/External/Backups/project-backup.zip

photo-2024.jpg (15 MB)
  ~/Pictures/photo-2024.jpg
  ~/Library/Mobile Documents/com~apple~CloudDocs/Photos/photo-2024.jpg

Cache Management

Move caches to external storage:

bossa caches status     # Show cache locations
bossa caches apply      # Apply cache config (create symlinks)
bossa caches audit      # Detect drift
bossa caches doctor     # Health checks
bossa caches init       # Create a starter config

iCloud Management

Control iCloud Drive downloads:

bossa icloud status     # Show iCloud space usage
bossa icloud download   # Download files from cloud
bossa icloud evict      # Evict files to free space

Manifest Operations

Build file manifests for duplicate detection:

bossa manifest scan <path>   # Hash files in directory
bossa manifest stats <path>  # Show manifest stats
bossa manifest duplicates <path>  # Find duplicates in manifest

Configuration

Cache Mappings

Define cache locations in ~/.config/bossa/caches.toml:

external_drive = { name = "T9", mount_point = "/Volumes/T9", base_path = "caches" }

[[symlinks]]
name = "homebrew"
source = "~/Library/Caches/Homebrew"
target = "homebrew"

[[symlinks]]
name = "cargo"
source = "~/.cargo/registry"
target = "cargo/registry"

Workflows

Free Up Local Space

  1. Check storage status:

    bossa storage status
    
  2. Evict iCloud files:

    bossa icloud evict ~/Library/Mobile\ Documents/large-folder/
    
  3. Move caches to external:

    bossa caches apply
    
  4. Find and remove duplicates:

    bossa storage duplicates
    

External Drive Setup

  1. Create cache directories:

    mkdir -p /Volumes/External/Caches/{Homebrew,cargo,npm}
    
  2. Configure mappings in caches.toml

  3. Move caches:

    bossa caches apply
    
  4. Verify:

    bossa caches status
    

Tips

  1. Scan regularly - Keep manifests up to date for accurate duplicate detection
  2. Use external drives for caches - Keep SSD space for active work
  3. Evict large iCloud folders - Download on demand
  4. Check before deleting - Review duplicates carefully before removal

iCloud Integration

Bossa provides tools for managing iCloud Drive storage, including downloading, evicting, and monitoring files.

Commands

bossa icloud status     # Show iCloud space usage
bossa icloud download   # Download files from cloud
bossa icloud evict      # Evict files to free local space
bossa icloud list       # List files with their status
bossa icloud find-evictable  # Find large local files

Understanding iCloud States

Files in iCloud Drive can be in different states:

StateIconDescription
Local(solid cloud)File is downloaded and available locally
Cloud(cloud outline)File is in cloud only, not downloaded
Downloading(progress)File is being downloaded
Uploading(arrow up)Local changes being synced

Status Overview

Check iCloud storage usage:

bossa icloud status

Output:

iCloud Drive Status
===================

Storage: 200 GB plan
  Used:      120 GB (60%)
  Available:  80 GB

Local Usage:
  Downloaded:  45 GB
  Cloud-only:  75 GB

By Folder:
  Documents/         15 GB (local)
  Photos/            50 GB (cloud)
  Developer/         30 GB (mixed)
  Archives/          25 GB (cloud)

Downloading Files

Download files from iCloud to local storage:

# Download a specific folder
bossa icloud download ~/Library/Mobile\ Documents/com~apple~CloudDocs/Documents/

# Download a folder recursively
bossa icloud download ~/Library/Mobile\ Documents/ --recursive

Evicting Files

Remove local copies to free space (files remain in iCloud):

# Evict a folder
bossa icloud evict ~/Library/Mobile\ Documents/com~apple~CloudDocs/Archives/

# Evict files larger than 100MB (recursive)
bossa icloud evict ~/Library/Mobile\ Documents/ --min-size 100MB --recursive

# Dry run
bossa icloud evict ~/Library/Mobile\ Documents/ --min-size 100MB --dry-run

Finding Evictable Files

Find large local files that are safe to evict:

bossa icloud find-evictable ~/Library/Mobile\ Documents/ --min-size 100MB

Listing Files

See file states:

bossa icloud list ~/Library/Mobile\ Documents/

Output:

Status  Size     Name
------  ----     ----
local   15 MB    Documents/report.pdf
cloud   500 MB   Archives/backup.zip
local   2 MB     Documents/notes.md
cloud   1.2 GB   Videos/recording.mov

Filter Options

# Show only cloud files
bossa icloud list --cloud

# Show only local files
bossa icloud list --local

iCloud Drive Paths

iCloud Drive files are stored in:

~/Library/Mobile Documents/
├── com~apple~CloudDocs/     # iCloud Drive root
├── com~apple~Numbers/       # Numbers documents
├── com~apple~Pages/         # Pages documents
└── [app-bundle-id]/         # Third-party app documents

Common Paths

LocationPath
iCloud Drive root~/Library/Mobile Documents/com~apple~CloudDocs/
Desktop~/Library/Mobile Documents/com~apple~CloudDocs/Desktop/
Documents~/Library/Mobile Documents/com~apple~CloudDocs/Documents/

Workflows

Free Local Space

  1. Check what's using space:

    bossa icloud status
    
  2. Find large local files:

    bossa icloud find-evictable --min-size 100MB
    
  3. Evict old files:

    bossa icloud evict ~/Library/Mobile\ Documents/ --min-size 50MB --recursive
    

Prepare for Offline

Download files you need offline:

# Download work folder
bossa icloud download ~/Library/Mobile\ Documents/com~apple~CloudDocs/Work/

# Verify
bossa icloud list ~/Library/Mobile\ Documents/com~apple~CloudDocs/Work/

Clean Up After Project

Evict project files you no longer need locally:

bossa icloud evict ~/Library/Mobile\ Documents/com~apple~CloudDocs/Projects/old-project/

Options

Download Options

--recursive, -r    Download directories recursively

Evict Options

--recursive, -r    Evict directories recursively
--min-size <SIZE>  Only evict files larger than SIZE
--dry-run          Preview what would be evicted

List Options

--local            Show only local files
--cloud            Show only cloud-only files

Tips

  1. Evict archives - Old backups and archives are good eviction candidates
  2. Keep active work local - Download folders you're actively using
  3. Check before evicting - Use --dry-run first
  4. Monitor regularly - Run bossa icloud status periodically

CLI Commands

Complete reference for bossa commands.

Global Options

-v, --verbose    Increase verbosity (can repeat: -v, -vv, -vvv)
-q, --quiet      Suppress non-essential output
-h, --help       Print help
-V, --version    Print version

Commands Overview

CommandDescription
novaBootstrap a new machine
statusShow current vs desired state
applyApply desired state
diffPreview what would change
addAdd resources to config
rmRemove resources from config
listList resources
showShow detailed resource info
doctorSystem health check
migrateMigrate legacy configs
cachesManage cache locations
collectionsManage repository collections
manifestContent manifest operations
icloudiCloud Drive management
storageUnified storage overview
brewHomebrew package management
refsDeprecated refs commands
completionsGenerate shell completions

nova

bossa nova [OPTIONS]

Options:

--skip <STAGES>      Skip specific stages (comma-separated)
--only <STAGES>      Only run specific stages (comma-separated)
--list-stages        List all available stages
--dry-run            Show what would be done
-j, --jobs <N>       Number of parallel jobs (max 128)

Examples:

bossa nova
bossa nova --list-stages
bossa nova --only=homebrew,brew
bossa nova --skip=dock
bossa nova --dry-run

status

bossa status [TARGET]

Examples:

bossa status
bossa status collections.refs
bossa status storage.t9

apply

bossa apply [TARGET] [OPTIONS]

Options:

--dry-run           Show what would be done
-j, --jobs <N>       Number of parallel jobs (max 128)

Examples:

bossa apply
bossa apply collections.refs
bossa apply --dry-run

diff

bossa diff [TARGET]

Examples:

bossa diff
bossa diff workspaces

add

bossa add <SUBCOMMAND>

Subcommands:

SubcommandDescription
collectionAdd a collection
repoAdd a repo to a collection
workspaceAdd a workspace repo
storageAdd a storage volume

Examples:

bossa add collection refs ~/dev/refs --description "Reference repos"
bossa add repo refs https://github.com/rust-lang/rust.git
bossa add workspace https://github.com/user/app.git --category work
bossa add storage t9 /Volumes/T9 --storage-type external

rm

bossa rm <SUBCOMMAND>

Subcommands:

SubcommandDescription
collectionRemove a collection
repoRemove a repo from a collection
workspaceRemove a workspace repo
storageRemove a storage volume

Examples:

bossa rm collection refs
bossa rm repo refs rust
bossa rm workspace myproject
bossa rm storage t9

list

bossa list <collections|repos|workspaces|storage>

Examples:

bossa list collections
bossa list workspaces

show

bossa show <TARGET>

Examples:

bossa show collections.refs
bossa show workspaces.myproject
bossa show storage.t9

doctor

bossa doctor

migrate

bossa migrate [OPTIONS]

Options:

-n, --dry-run    Preview changes without writing

caches

bossa caches <COMMAND>

Subcommands:

CommandDescription
statusShow cache status
applyApply cache config (create symlinks)
auditDetect drift
doctorCache health check
initCreate starter config

Examples:

bossa caches init
bossa caches status
bossa caches apply
bossa caches apply --dry-run
bossa caches audit

collections

bossa collections <COMMAND>

Subcommands:

CommandDescription
listList all collections
statusShow collection status
syncClone missing repos
auditFind drift
snapshotRegenerate config from disk
addAdd repo to collection
rmRemove repo from collection
cleanDelete clones

Examples:

bossa collections list
bossa collections status refs
bossa collections sync refs -j 8
bossa collections audit refs --fix
bossa collections add refs https://github.com/neovim/neovim.git --clone
bossa collections rm refs neovim --delete
bossa collections clean refs --dry-run

manifest

bossa manifest <COMMAND>

Subcommands:

CommandDescription
scanHash files in directory
statsShow manifest statistics
duplicatesFind duplicates

Examples:

bossa manifest scan ~/dev --force
bossa manifest stats ~/dev
bossa manifest duplicates ~/dev --min-size 1048576

icloud

bossa icloud <COMMAND>

Subcommands:

CommandDescription
statusShow iCloud status
listList files with status
find-evictableFind large local files
evictEvict files to free space
downloadDownload files from iCloud

Examples:

bossa icloud status
bossa icloud list --cloud
bossa icloud find-evictable --min-size 100MB
bossa icloud evict ~/Library/Mobile\ Documents --recursive --dry-run
bossa icloud download ~/Library/Mobile\ Documents --recursive

storage

bossa storage <COMMAND>

Subcommands:

CommandDescription
statusShow storage overview
duplicatesFind duplicates

Examples:

bossa storage status
bossa storage duplicates --list
bossa storage duplicates icloud t9 --min-size 1048576 --limit 5

brew

bossa brew <COMMAND>

Subcommands:

CommandDescription
applyInstall packages from Brewfile
captureUpdate Brewfile with installed packages
auditDetect drift
listList installed packages

Examples:

bossa brew apply --dry-run
bossa brew apply --file ~/dotfiles/Brewfile
bossa brew capture --output ~/dotfiles/Brewfile
bossa brew audit --file ~/dotfiles/Brewfile
bossa brew list --type cask

refs (deprecated)

bossa refs <COMMAND>

Use bossa collections instead. Subcommands mirror collections behavior.


completions

bossa completions <SHELL>

Supported shells:

  • bash
  • zsh
  • fish
  • powershell

Configuration Files

Reference for bossa configuration and state files.

Configuration Directory

Default location: ~/.config/bossa/

Bossa currently uses fixed paths (no environment variable overrides).


config.toml

Unified configuration for collections, workspaces, storage, packages, nova, and more.

Location

~/.config/bossa/config.toml

Example

[collections.refs]
path = "~/dev/refs"

[[collections.refs.repos]]
url = "https://github.com/rust-lang/rust.git"
name = "rust"

[workspaces]
root = "~/dev/ws"
structure = "bare-worktree"

[[workspaces.repos]]
name = "myproject"
url = "https://github.com/user/myproject.git"
category = "work"

[storage.t9]
mount = "/Volumes/T9"
type = "external"

[[storage.t9.symlinks]]
from = "~/Library/Caches/Homebrew"
to = "{mount}/caches/homebrew"

Key Fields

FieldTypeDescription
collections.<name>.pathstringDirectory for a collection
collections.<name>.repos[].namestringRepository name
collections.<name>.repos[].urlstringGit repository URL
workspaces.rootstringWorkspace root directory
workspaces.repos[].namestringWorkspace repository name
workspaces.repos[].urlstringWorkspace repository URL
storage.<name>.mountstringStorage mount point
storage.<name>.typestringexternal, internal, or network
storage.<name>.symlinks[]tableSymlinks to create under that storage mount

caches.toml

Cache mappings used by bossa caches commands.

Location

~/.config/bossa/caches.toml (create with bossa caches init)

Example

external_drive = { name = "T9", mount_point = "/Volumes/T9", base_path = "caches" }

[[symlinks]]
name = "homebrew"
source = "~/Library/Caches/Homebrew"
target = "homebrew"

[[symlinks]]
name = "cargo-registry"
source = "~/.cargo/registry"
target = "cargo/registry"

[bazelrc]
output_base = "/Volumes/T9/caches/bazel/output_base"

Key Fields

FieldTypeDescription
external_drive.namestringDrive label used in status output
external_drive.mount_pointstringExpected mount path
external_drive.base_pathstringBase folder under the mount point
symlinks[].namestringHuman-friendly identifier
symlinks[].sourcestringSource path to replace with a symlink
symlinks[].targetstringTarget path under the cache root
bazelrc.output_basestringOptional Bazel output base

Brewfile

Homebrew bundle configuration.

Location

Default path: ~/dotfiles/Brewfile (override with bossa brew apply --file <path>).

Format

Standard Homebrew bundle format (Ruby DSL).


Manifests

SQLite databases created by bossa manifest scan.

Location

~/.config/bossa/manifests/*.db

Do not edit manually.


State

Internal state tracking for bossa operations.

Location

~/.local/state/bossa/state.toml

Do not edit manually.


Legacy Files

If you have older configs in ~/.config/workspace-setup/, migrate them with:

bossa migrate --dry-run
bossa migrate

Environment Variables

Bossa does not currently read custom environment variables for configuration paths.

Use standard tool-specific environment variables (e.g., HOMEBREW_*) as needed.

Declarative State

Bossa follows a declarative approach: you define the desired state, and bossa figures out how to achieve it.

Core Concepts

Desired State

Configuration files define what your system should look like:

# config.toml - desired repositories
[collections.refs]
path = "~/dev/refs"

[[collections.refs.repos]]
url = "https://github.com/rust-lang/rust.git"
name = "rust"
# Brewfile - desired packages
brew "ripgrep"
brew "fd"
brew "jq"

Current State

Bossa inspects your system to determine current state:

  • Installed packages
  • Cloned repositories
  • File states (local vs cloud)

Reconciliation

Commands compare desired vs current state and take action:

bossa status   # Show differences
bossa diff     # Preview changes
bossa apply    # Apply changes

The Apply Pattern

Check → Plan → Apply

  1. Check - Compare desired vs current
  2. Plan - Determine actions needed
  3. Apply - Execute actions
# Check: What's different?
bossa brew audit

# Plan: What would change?
bossa diff

# Apply: Make it so
bossa apply

Idempotency

All operations are idempotent - running them multiple times produces the same result:

# First run: installs 5 packages
bossa brew apply
# Output: Installed 5 packages

# Second run: nothing to do
bossa brew apply
# Output: Already in sync

State Operations

Capture

Capture current state to configuration:

# Capture installed packages
bossa brew capture

# Capture cloned repos
bossa collections snapshot refs

Audit

Detect drift between desired and current:

# Package drift
bossa brew audit

# Repository drift
bossa collections audit refs

Sync

Bring current state in line with desired:

# Sync packages
bossa brew apply

# Sync repositories
bossa collections sync refs

Drift Detection

What is Drift?

Drift occurs when current state diverges from desired:

  • Package drift: Manually installed/removed packages
  • Repository drift: Manually cloned/deleted repos
  • Config drift: Modified configuration files

Detecting Drift

# Overall status
bossa status

# Package drift
bossa brew audit
# Output:
#   Missing: ripgrep (in Brewfile, not installed)
#   Extra: wget (installed, not in Brewfile)

# Repository drift
bossa collections audit refs
# Output:
#   Untracked: ~/dev/refs/some-repo (not in config)

Resolving Drift

Two approaches:

  1. Apply desired state - Remove extras, add missing

    bossa apply
    
  2. Update desired state - Capture current state

    bossa brew capture
    bossa collections snapshot refs
    

Two-Way Sync

Bossa supports both directions:

Desired → Current (Apply)

Push configuration to system:

bossa brew apply        # Install packages
bossa collections sync refs  # Clone repos

Current → Desired (Capture)

Pull system state to configuration:

bossa brew capture           # Update Brewfile
bossa collections snapshot refs   # Update config.toml

Workflow Examples

New Machine Setup

  1. Clone dotfiles with configuration
  2. Apply desired state
    bossa nova
    # or
    bossa apply
    

After Manual Changes

After manually installing packages:

# Option 1: Capture the change
bossa brew capture
git add Brewfile
git commit -m "Add new package"

# Option 2: Revert to desired state
bossa brew apply

Regular Maintenance

Periodic drift check:

# Check for drift
bossa status

# If drift found, decide:
# - Capture: Accept current state as new desired
# - Apply: Revert to desired state

Best Practices

  1. Version control configs - Keep in dotfiles repo
  2. Capture after changes - Don't let drift accumulate
  3. Audit before apply - Know what will change
  4. Use dry-run - Preview before executing
  5. Single source of truth - Config files are authoritative

Caching

Bossa provides tools for managing caches across storage locations.

Cache Management

Problem

Development tools create large caches:

  • Homebrew: ~/Library/Caches/Homebrew (GBs of downloads)
  • Cargo: ~/.cargo/registry (Rust crate cache)
  • npm: ~/.npm (Node package cache)
  • pip: ~/.cache/pip (Python package cache)

These consume valuable SSD space.

Solution

Move caches to external storage while maintaining functionality:

# ~/.config/bossa/caches.toml
external_drive = { name = "T9", mount_point = "/Volumes/T9", base_path = "caches" }

[[symlinks]]
name = "homebrew"
source = "~/Library/Caches/Homebrew"
target = "homebrew"

Commands

bossa caches status    # Show cache locations
bossa caches apply     # Apply config (create/migrate symlinks)
bossa caches audit     # Detect drift
bossa caches doctor    # Health checks
bossa caches init      # Create a starter config

Configuration

caches.toml

external_drive = { name = "T9", mount_point = "/Volumes/T9", base_path = "caches" }

[[symlinks]]
name = "homebrew"
source = "~/Library/Caches/Homebrew"
target = "homebrew"

[[symlinks]]
name = "cargo-registry"
source = "~/.cargo/registry"
target = "cargo/registry"

[[symlinks]]
name = "npm"
source = "~/.npm"
target = "npm"

[bazelrc]
output_base = "/Volumes/T9/caches/bazel/output_base"

Workflow

Initial Setup

  1. Create a starter config:

    bossa caches init
    
  2. Edit ~/.config/bossa/caches.toml to your paths

  3. Apply the config:

    bossa caches apply
    

How It Works

The apply command:

  1. Moves cache contents to target location (if needed)
  2. Removes the original directory
  3. Creates a symlink from source to target
Before:
~/Library/Caches/Homebrew/  (actual directory)

After:
~/Library/Caches/Homebrew -> /Volumes/T9/caches/homebrew

Verification

bossa caches status

Output:

Cache Status
============

homebrew
  Source: ~/Library/Caches/Homebrew
  Target: /Volumes/T9/caches/homebrew
  Status: Symlinked ✓
  Size:   2.3 GB

cargo-registry
  Source: ~/.cargo/registry
  Target: /Volumes/T9/caches/cargo/registry
  Status: Symlinked ✓
  Size:   1.8 GB

npm
  Source: ~/.npm
  Target: /Volumes/T9/caches/npm
  Status: Not created ○
  Size:   500 MB

When External Drive is Disconnected

Detection

bossa caches status

If target is unavailable:

homebrew
  Status: Drive not mounted ⚠
  Target: /Volumes/T9/caches/homebrew

Graceful Handling

Most tools handle missing cache gracefully:

  • Homebrew: Re-downloads packages
  • Cargo: Re-downloads crates
  • npm: Re-downloads packages

No data loss, just longer first build.

Temporary Override

To use local cache temporarily:

# Homebrew
export HOMEBREW_CACHE=~/.local-cache/Homebrew

# Cargo
export CARGO_HOME=~/.local-cargo

CI/CD Integration

GitHub Actions

- name: Restore cache
  uses: actions/cache@v4
  with:
    path: |
      ~/.cargo/registry
      ~/.cargo/git
      target/
    key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}

Cache Modes

For CI, consider read-only mode to prevent cache pollution:

# Read from cache, don't write
export CARGO_NET_OFFLINE=true

Best Practices

  1. Use fast external storage - USB 3.0+ or Thunderbolt
  2. Format for your OS - APFS for macOS, ext4 for Linux
  3. Regular cleanup - Caches grow over time
  4. Backup important caches - Cargo registry, npm, etc.
  5. Monitor disk space - External drives fill up too

Cleanup

Periodically clean caches:

# Homebrew
brew cleanup

# Cargo
cargo cache --autoclean

# npm
npm cache clean --force

# pip
pip cache purge

Common Cache Locations

ToolDefault LocationTypical Size
Homebrew~/Library/Caches/Homebrew2-10 GB
Cargo~/.cargo/registry, ~/.cargo/git1-5 GB
npm~/.npm500 MB - 2 GB
pip~/.cache/pip200 MB - 1 GB
Go~/go/pkg/mod500 MB - 2 GB
Maven~/.m2/repository1-5 GB
Gradle~/.gradle/caches1-5 GB