box-cli 0.0.24

Sandboxed Docker environments for git repos
box-cli-0.0.24 is not a library.

box

日本語

Crates.io License: MIT CI

Isolated git workspaces with a built-in terminal multiplexer. Clone, branch, break things — your repo stays untouched.

demo

Why box?

Box gives you isolated git workspaces with persistent terminal sessions — two core ideas:

1. git clone --local for instant isolation

Each session gets its own independent git repo — a full clone with all history and branches, created via hardlinks so it's fast even for large repos. Nothing you do in a box session can affect your original repository.

2. Built-in terminal multiplexer for persistent sessions

Every session runs inside a terminal multiplexer with scrollback, mouse support, and a persistent connection. Detach and reattach freely — your process keeps running in the background.

 COMMAND  ^P/^N scroll  ^Q detach  ^X stop  Esc exit              x
$ make test
...

Features

  • Isolated git workspacesgit clone --local creates an independent repo per session; host files are never modified
  • Persistent sessions — detach with Ctrl+PCtrl+Q, reattach with box resume; processes keep running
  • Terminal multiplexer — scrollback history, mouse scroll, scrollbar, COMMAND mode for navigation
  • Named sessions — run multiple experiments in parallel, each with its own workspace
  • Session manager TUI — interactive dashboard to create, resume, and manage sessions
  • Docker mode — optional full container isolation with any Docker image (BOX_MODE=docker)

Requirements

Install

Quick install

curl -fsSL https://raw.githubusercontent.com/yusukeshib/box/main/install.sh | bash

From crates.io

cargo install box-cli

From source

cargo install --git https://github.com/yusukeshib/box

Nix

nix run github:yusukeshib/box

Binary download

Pre-built binaries are available on the GitHub Releases page.

Quick Start

box my-feature
# Creates an isolated git workspace and opens a shell inside it

Box must be run inside a git repository. It clones the current repo into ~/.box/workspaces/<name>/.

# Work in the isolated workspace...
$ git checkout -b experiment
$ make test  # break things freely

# Detach (Ctrl+P enters COMMAND mode, then Ctrl+Q)
# Your process keeps running in the background

# Reattach later
box resume my-feature

# Done? Clean up
box remove my-feature

Terminal Multiplexer

Every box session runs inside a built-in terminal multiplexer. This gives you session persistence, scrollback, and keyboard-driven navigation.

COMMAND mode

Press Ctrl+P (configurable) to enter COMMAND mode. The header bar turns dark gray and shows available keys:

 COMMAND  ^P/^N scroll  ^Q detach  ^X stop  Esc exit              x
Key Action
Ctrl+P Scroll up 1 line
Ctrl+N Scroll down 1 line
Ctrl+U Scroll up half page
Ctrl+D Scroll down half page
Arrow keys Scroll up/down
PgUp / PgDn Scroll by half page
Ctrl+Q Detach from session (process keeps running)
Ctrl+X Stop/kill the session
Esc Exit COMMAND mode (snap to bottom)

Mouse scroll works in both normal and COMMAND mode. A scrollbar appears when there is scrollback content.

Configuring the prefix key

The key that enters COMMAND mode can be changed via ~/.config/box/config.toml:

[mux]
prefix_key = "Ctrl+B"   # default: "Ctrl+P"

Supports Ctrl+A through Ctrl+Z.

Session Manager

Running box with no arguments opens an interactive TUI:

 NAME            PROJECT      MODE    STATUS   CMD      IMAGE            CREATED
  New box...
> my-feature     /U/y/p/app   local   running  bash                      2026-02-07 12:00:00 UTC
  experiment     /U/y/p/app   local                                      2026-02-07 12:15:00 UTC
  docker-test    /U/y/p/other docker                    ubuntu:latest    2026-02-07 12:30:00 UTC

 [Enter] Resume  [c] Cd  [o] Origin  [d] Delete  [q] Quit
  • Enter — resume a session, or create a new one on "New box..."
  • c — cd to the session's workspace directory
  • o — cd to the session's origin project directory
  • d — delete the highlighted session (with confirmation)
  • q / Esc — quit

Usage

box                                               Session manager (TUI)
box <name> [--local] [--docker]                   Shortcut for `box create <name>`
box create <name> [--local] [--docker] [options] [-- cmd...] Create a new session
box resume <name> [-d] [--docker-args <args>]     Resume an existing session
box stop <name>                                   Stop a running session
box exec <name> -- <cmd...>                       Run a command in a running session
box list [options]                                List sessions (alias: ls)
box remove <name>                                 Remove a session
box cd <name>                                     Print host project directory
box path <name>                                   Print workspace path
box origin                                        Cd back to origin project from workspace
box config zsh|bash                               Output shell completions
box upgrade                                       Upgrade to latest version

Create a session

# Shortcut: just pass a name
box my-feature

# With a specific command
box create my-feature -- make test

# Create in detached mode (background)
box create my-feature -d -- long-running-task

Resume a session

box resume my-feature

# Resume in detached mode
box resume my-feature -d

List and manage sessions

box list                        # List all sessions
box ls                          # Alias
box list --running              # Only running sessions
box list -q --running           # Names only (for scripting)
box stop my-feature             # Stop a session
box remove my-feature           # Remove session, workspace, and data
box stop $(box list -q --running)  # Stop all running sessions

Navigate between workspaces

box cd my-feature               # Print the host project directory
cd "$(box path my-feature)"    # cd to the workspace
box origin                      # From workspace, cd back to origin

Docker Mode

For full container isolation, set BOX_MODE=docker. Each session runs inside a Docker container with the workspace bind-mounted.

export BOX_MODE=docker

Optionally configure a custom image and defaults:

export BOX_DEFAULT_IMAGE=mydev              # your custom image
export BOX_DOCKER_ARGS="--network host"     # extra Docker flags
export BOX_DEFAULT_CMD="bash"               # default command
# Docker sessions with explicit options
box create my-feature --docker --image ubuntu:latest -- bash
box create my-feature --docker --docker-args "-e KEY=VALUE -v /host:/container"

Options

box create

Option Description
-d Run in the background (detached)
--local Create a local session (default)
--docker Create a Docker session (requires Docker)
--image <image> Docker image to use (default: alpine:latest)
--docker-args <args> Extra Docker flags (e.g. -e KEY=VALUE, -v /host:/container). Overrides $BOX_DOCKER_ARGS
-- cmd... Command to run (default: $BOX_DEFAULT_CMD if set)

box list

Option Description
--running, -r Show only running sessions
--stopped, -s Show only stopped sessions
--quiet, -q Only print session names (useful for scripting)

box resume

Option Description
-d Resume in the background (detached)
--docker-args <args> Extra Docker flags. Overrides $BOX_DOCKER_ARGS

Environment Variables

Variable Description
BOX_DEFAULT_IMAGE Default Docker image for new sessions (default: alpine:latest)
BOX_DOCKER_ARGS Default extra Docker flags, used when --docker-args is not provided
BOX_DEFAULT_CMD Default command for new sessions, used when no -- cmd is provided
BOX_MODE Session mode: local (default) or docker

Shell Completions

# Zsh (~/.zshrc)
eval "$(box config zsh)"

# Bash (~/.bashrc)
eval "$(box config bash)"

How It Works

your-repo/          box create my-feature         ~/.box/workspaces/my-feature/
  .git/        ──── git clone --local ────>         .git/  (independent)
  src/                                              src/   (hardlinked)
  ...                                               ...

git clone --local creates a fully independent git repo using hardlinks for file objects. The clone has its own .git directory — commits, branches, resets, and destructive operations in the workspace cannot affect your original repository.

The built-in terminal multiplexer wraps each session with:

  • Session persistence — the process runs in a background server; detach and reattach without interruption
  • Scrollback — 10,000 lines of history with keyboard and mouse navigation
  • Header bar — shows session name, scroll position, and COMMAND mode status
Aspect Detail
Workspace location ~/.box/workspaces/<name>/
Session metadata ~/.box/sessions/<name>/
Git isolation Full — independent .git, no shared refs
Session persistence Multiplexer server keeps process alive across detach/reattach
Cleanup box remove deletes workspace, session data, and container (if Docker)

Design Decisions

Strategy Problem
Bind-mount the host repo No isolation at all; the agent modifies your actual files
git worktree Shares the .git directory with the host; checkout, reset, and rebase can affect host branches and refs
Bare-git mount Still shares state; branch creates/deletes in the container affect the host
Branch-only isolation Nothing stops destructive git commands on shared refs
Full copy (cp -r) Truly isolated but slow for large repos

git clone --local is fully independent (own .git), fast (hardlinks), complete (full history), and simple (no wrapper scripts).

Box needs session persistence — the ability to detach from a running process and reattach later. Rather than requiring tmux or screen as external dependencies, box includes a purpose-built terminal multiplexer that:

  • Requires zero configuration — works out of the box
  • Provides a consistent UI across all sessions (header bar, scrollback, COMMAND mode)
  • Handles the client-server architecture for session persistence transparently
  • Supports mouse scroll and a visual scrollbar for navigating output history

Some tools provide built-in Docker sandboxing. Box uses plain Docker directly, which gives you:

  • Your own toolchain — any Docker image with the exact tools you need
  • Full Docker control — custom network, volumes, env vars, and any docker run flags
  • Works with any workflow — not tied to a specific tool or agent

Claude Code Integration

Box works well with Claude Code for running AI agents in isolated workspaces:

box create ai-experiment -- claude
box create ai-experiment -d -- claude -p "refactor the auth module"

Everything the agent does stays in the workspace. Delete the session when you're done.

Security Note

The --docker-args flag and BOX_DOCKER_ARGS environment variable pass arguments directly to docker run. Flags like --privileged or -v /:/host can weaken container sandboxing. Only use trusted values.

License

MIT