A CLI tool that manages sandboxed git workspaces. Multi-repo support included.
Box creates and manages named workspaces using git worktree (default) or git clone --local.
- Register repos with
box repo add(bare-cloned to~/.box/repos/), then create sessions — each session sets up repos in~/.box/workspaces/<session>/ - Multiple repos can be grouped into a single session, or saved as a named preset for reuse
- Worktree mode is lightweight and fast; clone mode gives full
.gitisolation
- Two workspace strategies —
git worktree(default, lightweight) orgit clone --local(full isolation) - Multi-repo sessions — group multiple repos into one workspace, optionally via reusable presets
- Interactive TUI — select repos, enter session name, with history
- Shell integration — completions,
cdwrapper, and terminal-tab renaming for zsh/bash
curl -fsSL https://raw.githubusercontent.com/yusukeshib/box/main/install.sh | bashcargo install box-clicargo install --git https://github.com/yusukeshib/boxnix run github:yusukeshib/boxPre-built binaries are available on the GitHub Releases page.
# 1. Register a repo
box repo add ~/projects/my-app
# 2. Create a session via TUI
box
# 3. Or create via CLI
box new my-feature --repo my-app
# 4. Switch into the workspace later
box switch my-feature
# 5. Clean up
box remove my-featurebox Interactive TUI (create new sessions)
box new <name> --repo <r> [options] Create a new session
box edit <name> [--add <r>] [--remove <r>] Add/remove repos in a session
box list [options] List sessions (alias: ls)
box remove [<name>] [--all] Remove a session (alias: rm)
box switch <name> Switch into the session workspace (aliases: cd, sw)
box rebase <branch> Fetch origin and rebase HEAD onto <branch>
box repo add [path] Register a git repo (bare clone)
box repo remove <name> Unregister a repo (alias: rm)
box repo list List registered repos (alias: ls)
box preset add <name> --repo <r>... Create or update a preset
box preset edit <name> Edit repos in a preset (TUI)
box preset remove <name> Remove a preset (alias: rm)
box preset list List presets (alias: ls)
box config zsh|bash Output shell configuration
box upgrade Upgrade to latest version-v/--verbose is a global flag (also via BOX_VERBOSE=1) that turns on detailed output.
# Default (worktree strategy)
box new my-feature --repo my-app
# Use clone strategy for full isolation
box new my-feature --repo my-app --strategy clone
# Multiple repos
box new my-feature --repo frontend --repo backend
# From a preset
box new my-feature --preset work--repo (repeatable) or --preset is required. To create sessions interactively, run box with no arguments.
box edit my-feature # TUI: toggle repos
box edit my-feature --add app-c # non-interactive add
box edit my-feature --add app-c --remove app-a # add and remove--add and --remove may be repeated. When either is set, the TUI is skipped.
box list # List all sessions
box ls # Alias
box list -q # Names only (for scripting)
box list -p # Only sessions for the current project
box remove my-feature # Remove a session by name
box remove # Interactive selector (multi-select)
box remove --all # Remove every sessionbox switch my-feature # Switch into the session workspace
box cd my-feature # Alias
box sw my-feature # AliasWith shell integration enabled (eval "$(box config zsh)"), box switch changes your working directory and renames the current zellij/tmux tab to the session name. Without it, the workspace path is printed to stdout.
box rebase main # fetch origin in the bare repo, then rebase HEAD onto mainbox rebase runs from inside any session worktree. It fetches the bare repo behind the worktree (handling sibling-worktree branches safely) and then runs git rebase <branch> in the current worktree.
Register repos (bare-cloned to ~/.box/repos/), then reference them by name when creating sessions:
box repo add ~/projects/frontend
box repo add ~/projects/backend
box new my-feature --repo frontend --repo backendRepos are always fetched before session creation. Each repo is set up in ~/.box/workspaces/<session>/<repo>/. For single-repo sessions, the workspace path resolves directly to the repo subdirectory.
A preset is a named list of repos you create sessions from regularly:
box preset add work --repo frontend --repo backend # define
box preset add work # interactive selector
box preset edit work # update repos (TUI)
box preset list # list presets
box preset remove work # delete
box new my-feature --preset work # use it| Option | Description |
|---|---|
<name> |
Session name (required) |
--repo <name> |
Repos to include (repeatable; mutually exclusive with --preset) |
--preset <name> |
Use a preset (mutually exclusive with --repo) |
--strategy <strategy> |
worktree (default) or clone |
| Option | Description |
|---|---|
<name> |
Session name (required) |
--add <repo> |
Add a repo (repeatable; skips the TUI when set) |
--remove <repo> |
Remove a repo (repeatable; skips the TUI when set) |
| Option | Description |
|---|---|
--project, -p |
Show only sessions for the current project directory |
--quiet, -q |
Only print session names |
| Option | Description |
|---|---|
<name> |
Session name (omit to open interactive selector) |
--all, -a |
Remove every session (conflicts with <name>) |
| Variable | Description |
|---|---|
BOX_STRATEGY |
Default workspace strategy (worktree or clone). Overridden by --strategy |
BOX_VERBOSE |
When set, equivalent to --verbose |
BOX_ROOT |
Override the box data directory (default ~/.box). Read by the shell completions |
# Zsh (~/.zshrc)
eval "$(box config zsh)"
# Bash (~/.bashrc)
eval "$(box config bash)"This provides:
- Tab completion for sessions, repos, and presets
- A
boxshell function sobox switch/box newchange your working directory - Automatic zellij/tmux tab renaming to the session name when switching into or creating a session
Box supports two workspace strategies:
~/.box/repos/ box new my-feature ~/.box/workspaces/my-feature/
frontend.git ──── git worktree add ─────> frontend/
backend.git backend/
git worktree creates a lightweight working tree linked to the bare repo. It shares the object store, so creation is instant and uses minimal disk space. Each worktree gets its own box/<session> branch, and box remove cleans up the worktree properly.
~/.box/repos/ box new my-feature ~/.box/workspaces/my-feature/
frontend.git ──── git clone --local ────> frontend/
backend.git backend/
git clone --local creates a fully independent git repo using hardlinks for file objects. Each clone has its own .git directory — commits, branches, resets, and destructive operations in the workspace do not affect the original.
| Worktree | Clone | |
|---|---|---|
| Speed | Instant | Fast (hardlinks) |
| Disk usage | Minimal (shared objects) | Low (hardlinked objects) |
| Isolation | Separate working tree, shared .git |
Fully independent .git |
| Best for | Feature branches, quick experiments | Full isolation, destructive operations |
| Aspect | Detail |
|---|---|
| Bare repos | ~/.box/repos/<name>.git/ |
| Workspace location | ~/.box/workspaces/<session>/ |
| Session metadata | ~/.box/sessions/<session>/ |
| Presets | ~/.box/presets/<name> |
| Default strategy | git worktree (override with --strategy clone) |
| Cleanup | box remove deletes workspace and session data |
MIT
