diff --git a/README.md b/README.md index 174069a..3e9504b 100644 --- a/README.md +++ b/README.md @@ -1,288 +1,102 @@ # πŸŸ§πŸ“¦ squarebox -**A curated set of modern CLI/TUI tools and AI coding assistants in a container. Batteries included.** +**Modern CLI/TUI tools and AI coding assistants in a portable development Box.** -*For developers who live in the terminal but need to work across -multiple platforms and devices.* - -**squarebox** packages a complete terminal-based development environment -into a single container (Docker; Podman experimental): modern CLI tools, AI coding -assistants, language SDKs, and an opinionated set of shell aliases. Run the -same box anywhere (desktop, VPS, or Codespace) and SSH in from your laptop, -tablet, or phone (please don't). - -A playground for modern CLI/TUI tools, a Box for -running AI agents, and a persistent terminal environment for remote development. -One-line install, interactive first-run setup, sensible defaults. - -Upgrading an existing installation? Read the relevant -[migration guide](docs/releases/) and [changelog](CHANGELOG.md). +Run the same terminal environment on your desktop, server, or Codespace. +One-line install, interactive setup, and persistent tools and settings. ![squarebox first-run setup](demo/squarebox-setup.gif) -*(Actual setup may involve more staring at the screen.)* - -Prerequisites -------------- - -- [Docker](https://docs.docker.com/get-docker/) or [Podman](https://podman.io/getting-started/installation) (experimental β€” see one-line install below if you don't have either) -- [Git](https://git-scm.com/) - on Windows, install [Git for Windows](https://gitforwindows.org/) - -The installer auto-detects which runtime is available. If both are installed, it -asks which to use. Override with `SQUAREBOX_RUNTIME=docker` or -`SQUAREBOX_RUNTIME=podman`. - -> **Podman (Experimental):** Docker is the primary tested runtime; Podman may -> have rough edges around volume mounts, SSH agent forwarding, or rebuild -> flows. The rootless adapter maps the host user to the image's `dev` account -> and uses `--security-opt label=disable`: host SELinux labels are left -> untouched, while SELinux container separation is disabled for this -> development Box. Please file an issue if you hit a runtime-specific edge. - -
-Don't have Docker or Podman? One-line install - -**macOS** (via [Homebrew](https://brew.sh)): - - brew install --cask docker-desktop - -**Linux** (official convenience script - inspect it first at [get.docker.com](https://get.docker.com)): - - curl -fsSL https://get.docker.com | sh && sudo usermod -aG docker $USER - -Log out and back in (or run `newgrp docker`) so your shell picks up the new group. - -**Windows** (via [winget](https://learn.microsoft.com/en-us/windows/package-manager/winget/), in PowerShell 7+): - - winget install --id Docker.DockerDesktop -e - -On macOS and Windows, start Docker Desktop once after install so the daemon is -running before you continue. - -
Install ------- -These commands install squarebox and drop you into the container (if possible). -By default they **pull a prebuilt image** from GHCR β€” no local Docker build, no -build toolchain β€” then clone the repo into `~/squarebox` for the config files -and the `sqrbx` helper commands. On first login, a setup script runs -automatically to configure git (pulling your name and email from the host's -global git config if available), optionally sign in to GitHub CLI, your choice -of AI coding assistant, and language SDKs. - -**Stable** - - curl -fsSL https://github.com/SquareWaveSystems/squarebox/releases/latest/download/install.sh | bash - -**Edge** - - curl -fsSL https://github.com/SquareWaveSystems/squarebox/releases/latest/download/install.sh | bash -s -- --edge - -Stable resolves the latest published GitHub Release and pulls the immutable -image digest recorded in its `release.json`. Raw Git tags are not installable -stable releases. An explicit `SQUAREBOX_TAG=v…` resolves that published Release -and its matching source revision. Edge builds the latest commit on `main`. To -build a published Release from source instead of pulling, pass `--build`. - -If the install fails or you want to see the full build/pull and git output, -re-run with `--verbose`. - -
-Advanced install options (flags & environment variables) - -Flags: `--build` (build from source), `--edge` (latest `main`), `--adopt` -(one-time migration of a legacy installation), and `--verbose`. - -| Variable | Default | Purpose | -|----------|---------|---------| -| `SQUAREBOX_DIR` | `~/squarebox` | Install location (repo + workspace). Point at durable storage on hosts where `$HOME` is volatile β€” e.g. Unraid `/mnt/user/appdata/squarebox`. | -| `SQUAREBOX_WORKSPACE` | `$SQUAREBOX_DIR/workspace` | Host path mounted as `/workspace`. | -| `SQUAREBOX_TAG` | latest published stable | Published Release to install (for example `v1.2.1`). Tags use `vMAJOR.MINOR.PATCH[-prerelease]`; build metadata is not published. | -| `SQUAREBOX_IMAGE` | value from `release.json` | Optional image-repository override for development/testing. | -| `SQUAREBOX_BUILD` | `0` | `1` is equivalent to `--build`. | -| `PUID` / `PGID` | invoking Linux user | Host uid/gid that should own bind-mounted files. Unprivileged Linux installs must match the invoking account. Root-run rootful runtimes, including Docker or Podman on NAS and Unraid, may override these (typically `99` / `100`); rootless Podman also requires the invoking host identity. | -| `SQUAREBOX_RUNTIME` | auto | Force `docker` or `podman`. | -| `SQUAREBOX_HOME_VOLUME` | `squarebox-home` | Name of the named volume backing `/home/dev`. | -| `SQUAREBOX_EDGE` | `0` | `1` is equivalent to `--edge`. | -| `SQUAREBOX_MOUNT_SSH` | `0` | `1` mounts your host `~/.ssh` directory, **private keys included**, read-only into the Box when no SSH agent is forwarded. Recorded for rebuilds; set `0` to turn it back off. See **SSH access** below. | - -**Non-interactive provisioning** β€” set any of these to a comma-separated list to -pre-select a toolset and install it without prompts (handy for servers and -scripted installs). Values use the same keys as `sqrbx-setup`: - -| Variable | Selects | -|----------|---------| -| `SQUAREBOX_AI` | AI assistants (`claude,copilot,gemini,codex,opencode,pi,omp`) | -| `SQUAREBOX_SDKS` | language SDKs (`node,python,go,dotnet,rust`) | -| `SQUAREBOX_EDITORS` | editors (`micro,edit,fresh,helix,nvim`; Helix launches as `hx`) | -| `SQUAREBOX_TUIS` | TUI tools (`lazygit,gh-dash,yazi,elio`) | -| `SQUAREBOX_MULTIPLEXERS` | multiplexers (`tmux,zellij,herdr`) | -| `SQUAREBOX_GIT_NAME` / `SQUAREBOX_GIT_EMAIL` | git identity (when no host gitconfig) | - -Example: +Requires [Docker](https://docs.docker.com/get-docker/) or +[Podman](https://podman.io/getting-started/installation), plus +[Git](https://git-scm.com/) ([Git for Windows](https://gitforwindows.org/)). +The installer detects your runtime and asks which to use if both are installed. +[Need Docker?](docs/usage.md#installing-docker) + +**Linux / macOS / Git Bash** ```bash -curl -fsSL https://github.com/SquareWaveSystems/squarebox/releases/latest/download/install.sh \ - | env SQUAREBOX_AI=claude SQUAREBOX_SDKS=node,python bash +curl -fsSL https://github.com/SquareWaveSystems/squarebox/releases/latest/download/install.sh | bash ``` -
- -Each successful v1.1-or-newer install records its effective lifecycle settings at -`/.squarebox/install-state` (mode 0600 on POSIX; inherited -current-user install-directory ACL on native Windows). Rebuild and uninstall -parse this file as data; they do not reconstruct defaults or source it as shell -code. Release pulls record an immutable image digest; source/edge builds record -their local image ID/reference. Existing pre-v1.1 checkouts require a one-time -reviewed `--adopt`/`-Adopt`. - -**SSH access** - -The Box does not receive your SSH private-key files by default, because anything -running inside it, including unattended `*-yolo` AI agents, could read them. - -- **SSH agent (recommended).** When `SSH_AUTH_SOCK` points at a running agent, - the Bash/POSIX and Git Bash adapters forward the agent socket and mount only - `~/.ssh/config` and `~/.ssh/known_hosts` read-only. Key files stay on the - host, though Box processes can ask the agent to sign while the socket is - available. -- **No agent.** `~/.ssh` is not mounted, and install prints a note. To mount - the directory read-only instead, opt in with `SQUAREBOX_MOUNT_SSH=1` (native - PowerShell: `.\install.ps1 -MountSsh` or `$env:SQUAREBOX_MOUNT_SSH = '1'`). - The choice is recorded in the Install identity and reused by - `sqrbx-rebuild`; set `SQUAREBOX_MOUNT_SSH=0` (or `-MountSsh:$false`) on a - rebuild to turn it back off. - **Windows (PowerShell 7+)** -Windows users can install directly from PowerShell - no Git Bash required. -This handles Release resolution, pull/build, Box creation, and PowerShell functions -(`sqrbx`, `squarebox`, etc.) natively: - - irm https://github.com/SquareWaveSystems/squarebox/releases/latest/download/install.ps1 | iex - -Once installed, you can re-run or pass flags from the local copy: - - .\install.ps1 # re-install / update - .\install.ps1 -Edge # latest main instead of latest release - .\install.ps1 -Build # build the resolved source locally - .\install.ps1 -Adopt # migrate a legacy pre-v1.1 installation - .\install.ps1 -MountSsh # opt in to mounting %USERPROFILE%\.ssh read-only - -> **Note:** `irm ... | iex` does not support flags - PowerShell interprets them -> as arguments to `Invoke-Expression`, not the script. Use the local -> `.\install.ps1` form for `-Edge`, `-Build`, `-Adopt`, or `-MountSsh`. -> PowerShell streams runtime and Git failures directly by default. - -> **Windows adapter boundary:** Keep install, rebuild, and uninstall on the -> adapter that created the Install identity. Native PowerShell and Git Bash -> use the same Install identity field names, but their native path and -> shell-profile values are not interchangeable; -> cross-adapter state consumption is rejected. -> Native PowerShell does not forward `SSH_AUTH_SOCK` and mounts -> `%USERPROFILE%\.ssh` read-only only when you opt in with `-MountSsh` or -> `SQUAREBOX_MOUNT_SSH=1`. The separate Git Bash adapter supports SSH -> agent-socket forwarding with its Bash lifecycle. -> Use `./scripts/migrate-windows-adapter.ps1 -Target PowerShell` or -> `-Target GitBash` from PowerShell 7 for an explicit cross-adapter migration. -> Normal installers and uninstallers continue to reject foreign adapter state. +```powershell +irm https://github.com/SquareWaveSystems/squarebox/releases/latest/download/install.ps1 | iex +``` + +The installer pulls the latest stable Release and sets up `~/squarebox`. +First login runs a wizard for Git identity, GitHub sign-in, and optional tools. +Keep using the same adapter (Bash/Git Bash or PowerShell) for updates and uninstall. + +For edge builds, custom paths, scripted setup, or Windows flags, see the +[usage reference](docs/usage.md#advanced-installation). +Upgrading? Check the [migration guides](docs/releases/) and [changelog](CHANGELOG.md). Start ----- - squarebox # or: sqrbx - -These are shell functions wrapping `docker start -ai squarebox` (or -`podman start -ai squarebox`), added automatically for Bash, Zsh, and -PowerShell 7+. - -The Box suspends on exit and resumes on start, keeping its current filesystem -between those starts. Box replacement discards that filesystem; selected -Box-tier packages are reconciled automatically in the replacement. Your -code lives on the host at `~/squarebox/workspace` (bind-mounted), and per-user -state β€” shell history, GitHub CLI auth, claude-code data, mise toolchains β€” -lives in a named Docker volume (`squarebox-home`) that survives replacement. -Image-managed config is refreshed safely into that Managed home at startup; -desktop source builds may instead use explicit managed bind mounts. - -Run as a long-lived server (Unraid / NAS / VPS) ------------------------------------------------ - -The `curl | bash` installer is built around an interactive desktop shell. To run -squarebox as a persistent server container you attach into on demand β€” on -Unraid, a NAS, or a VPS β€” use the prebuilt image directly with the bundled -`docker-compose.yml`: - - cp .env.example .env # set PUID/PGID, the workspace path, and a tag - docker compose up -d - docker compose exec -u dev squarebox bash - -Set `PUID`/`PGID` in `.env` to match your host so files squarebox writes to the -workspace mount are owned correctly β€” on Unraid that's `99` / `100`. The `-u dev` -on `exec` is needed because the container starts as root (to apply PUID/PGID) -then drops to the `dev` user; `exec` bypasses that, so `-u dev` lands you where -you want to be. - -Per-user state (shell history, gh auth, mise toolchains, AI-assistant state) -lives in the `squarebox-home` named volume and survives image updates; your code -lives on the host at the workspace path. To update, pull a newer tag and -`docker compose up -d`. The published image is multi-arch (amd64 + arm64), so it -also runs on ARM NAS/VPS hosts. - -> **Unraid note:** the host's `/root` is tmpfs and wiped on reboot, so a raw -> `curl | bash` install there won't persist. Either use compose (above) with the -> workspace path under `/mnt/user/appdata`, or run the installer with -> `SQUAREBOX_DIR` and `SQUAREBOX_WORKSPACE` pointed at appdata. +```bash +squarebox # or: sqrbx +``` + +Your code lives in `~/squarebox/workspace`, mounted at `/workspace`. +Shell history, credentials, assistant data, and SDKs live in the persistent +`squarebox-home` volume. Both survive Box replacement. Selected system packages +are reinstalled automatically; manually installed system packages are lost. + +For a persistent server or NAS, see [server deployment](docs/usage.md#server-deployment). +For VS Code or GitHub Codespaces, see [Dev Containers and Codespaces](docs/usage.md#dev-containers-and-codespaces). What's included --------------- ### CLI Tools -| Name | Language | Description | -|------|----------|-------------| -| [bat](https://github.com/sharkdp/bat) | Rust | Cat clone with syntax highlighting | -| [bubblewrap](https://github.com/containers/bubblewrap) | C | Unprivileged sandboxing tool (`bwrap`), used by the Codex CLI sandbox | -| [curl](https://github.com/curl/curl) | C | URL data transfer | -| [delta](https://github.com/dandavison/delta) | Rust | Syntax-highlighting pager for git diffs | -| [difftastic](https://github.com/Wilfred/difftastic) | Rust | Syntax-aware structural diff tool (`difft`) | -| [eza](https://github.com/eza-community/eza) | Rust | Modern ls replacement | -| [fd](https://github.com/sharkdp/fd) | Rust | Fast, user-friendly find alternative | -| [fzf](https://github.com/junegunn/fzf) | Go | Fuzzy finder | -| [gh](https://github.com/cli/cli) | Go | GitHub CLI | -| [glow](https://github.com/charmbracelet/glow) | Go | Terminal markdown renderer | -| [gum](https://github.com/charmbracelet/gum) | Go | Tool for shell scripts and dotfiles | -| [jq](https://github.com/jqlang/jq) | C | JSON processor | -| [just](https://github.com/casey/just) | Rust | Command runner / modern make alternative | -| [mise](https://github.com/jdx/mise) | Rust | Polyglot tool-version and SDK manager | -| [nano](https://nano-editor.org) | C | Default text editor | -| [ripgrep](https://github.com/BurntSushi/ripgrep) | Rust | Fast recursive grep | -| [starship](https://github.com/starship/starship) | Rust | Cross-shell prompt | -| [xh](https://github.com/ducaale/xh) | Rust | Friendly HTTP client | -| [yq](https://github.com/mikefarah/yq) | Go | YAML/JSON/XML processor | -| [zoxide](https://github.com/ajeetdsouza/zoxide) | Rust | Smarter cd command | +| Name | Description | +|------|-------------| +| [bat](https://github.com/sharkdp/bat) | Cat clone with syntax highlighting | +| [bubblewrap](https://github.com/containers/bubblewrap) | Unprivileged sandboxing tool (`bwrap`), used by the Codex CLI sandbox | +| [curl](https://github.com/curl/curl) | URL data transfer | +| [delta](https://github.com/dandavison/delta) | Syntax-highlighting pager for git diffs | +| [difftastic](https://github.com/Wilfred/difftastic) | Syntax-aware structural diff tool (`difft`) | +| [eza](https://github.com/eza-community/eza) | Modern ls replacement | +| [fd](https://github.com/sharkdp/fd) | Fast, user-friendly find alternative | +| [fzf](https://github.com/junegunn/fzf) | Fuzzy finder | +| [gh](https://github.com/cli/cli) | GitHub CLI | +| [glow](https://github.com/charmbracelet/glow) | Terminal markdown renderer | +| [gum](https://github.com/charmbracelet/gum) | Tool for shell scripts and dotfiles | +| [jq](https://github.com/jqlang/jq) | JSON processor | +| [just](https://github.com/casey/just) | Command runner / modern make alternative | +| [mise](https://github.com/jdx/mise) | Polyglot tool-version and SDK manager | +| [nano](https://nano-editor.org) | Default text editor | +| [ripgrep](https://github.com/BurntSushi/ripgrep) | Fast recursive grep | +| [starship](https://github.com/starship/starship) | Cross-shell prompt | +| [xh](https://github.com/ducaale/xh) | Friendly HTTP client | +| [yq](https://github.com/mikefarah/yq) | YAML/JSON/XML processor | +| [zoxide](https://github.com/ajeetdsouza/zoxide) | Smarter cd command | What's optional ---------------- -Selected during first-run setup. Choose any combination, all, or none. -Selections are saved under `/workspace/.squarebox` (on the host workspace bind -mount) and reused automatically on container rebuilds. They can also be -pre-selected non-interactively via the `SQUAREBOX_AI`/`SQUAREBOX_SDKS`/… env vars -(see *Advanced install options* above). +Choose any combination during first-run setup. Your selections are saved and +reused on rebuilds; change them anytime with `sqrbx-setup`. ### AI Coding Assistants -| Name | Language | Description | -|------|----------|-------------| -| [Claude Code](https://github.com/anthropics/claude-code) | TypeScript | AI coding assistant | -| [GitHub Copilot CLI](https://docs.github.com/en/copilot/how-tos/copilot-cli/cli-getting-started) | TypeScript | Supported GitHub Copilot terminal client (`copilot`) * | -| [Google Gemini CLI](https://github.com/google-gemini/gemini-cli) | TypeScript | Google Gemini in the terminal * | -| [OpenAI Codex CLI](https://github.com/openai/codex) | Rust | OpenAI Codex in the terminal * | -| [opencode](https://github.com/anomalyco/opencode) | TypeScript/Bun | AI coding TUI | -| [Pi Coding Agent](https://github.com/earendil-works/pi) | TypeScript | Minimal terminal coding harness (Earendil) * | -| [Oh My Pi](https://github.com/can1357/oh-my-pi) | TypeScript/Rust | Batteries-included coding harness (`omp`), installed via mise | +| Name | Description | +|------|-------------| +| [Claude Code](https://github.com/anthropics/claude-code) | AI coding assistant | +| [GitHub Copilot CLI](https://docs.github.com/en/copilot/how-tos/copilot-cli/cli-getting-started) | Supported GitHub Copilot terminal client (`copilot`) * | +| [Google Gemini CLI](https://github.com/google-gemini/gemini-cli) | Google Gemini in the terminal * | +| [OpenAI Codex CLI](https://github.com/openai/codex) | OpenAI Codex in the terminal * | +| [opencode](https://github.com/anomalyco/opencode) | AI coding TUI | +| [Pi Coding Agent](https://github.com/earendil-works/pi) | Minimal terminal coding harness (Earendil) * | +| [Oh My Pi](https://github.com/can1357/oh-my-pi) | Batteries-included coding harness (`omp`), installed via mise | + \* Requires Node.js (auto-installed if needed). ### Text Editors @@ -290,391 +104,90 @@ pre-selected non-interactively via the `SQUAREBOX_AI`/`SQUAREBOX_SDKS`/… env v Nano is always available and remains the fallback default unless you choose an installed editor instead. -| Name | Language | Description | -|------|----------|-------------| -| [micro](https://github.com/micro-editor/micro) | Go | Modern, intuitive terminal editor | -| [edit](https://github.com/microsoft/edit) | Rust | Terminal text editor (Microsoft) | -| [fresh](https://github.com/sinelaw/fresh) | Rust | Modern terminal text editor | -| [helix](https://github.com/helix-editor/helix) | Rust | Modal editor (Kakoune-inspired) | -| [nvim](https://github.com/neovim/neovim) | C/Lua | Neovim | +| Name | Description | +|------|-------------| +| [micro](https://github.com/micro-editor/micro) | Modern, intuitive terminal editor | +| [edit](https://github.com/microsoft/edit) | Terminal text editor (Microsoft) | +| [fresh](https://github.com/sinelaw/fresh) | Modern terminal text editor | +| [helix](https://github.com/helix-editor/helix) | Modal editor (Kakoune-inspired) | +| [nvim](https://github.com/neovim/neovim) | Neovim | -Selecting **nvim** offers to install the [LazyVim](https://www.lazyvim.org/) starter config to `~/.config/nvim`, turning Neovim into a preconfigured IDE. Plugins sync on first launch and persist in the `squarebox-home` volume. A Nerd Font in your terminal is recommended for icons; the starter is skipped if `~/.config/nvim` already exists, so your own config is never overwritten. +Selecting **nvim** offers a [LazyVim](https://www.lazyvim.org/) starter config. +Existing Neovim configuration is preserved. See [editor configuration](docs/usage.md#editor-configuration). ### TUI Tools -Installed during first-run setup. Choose any combination: - -| Name | Language | Description | -|------|----------|-------------| -| [lazygit](https://github.com/jesseduffield/lazygit) | Go | Git terminal UI | -| [gh-dash](https://github.com/dlvhdr/gh-dash) | Go | GitHub dashboard for the terminal | -| [yazi](https://github.com/sxyazi/yazi) | Rust | Terminal file manager | -| [elio](https://github.com/elio-fm/elio) | Rust | Terminal file manager with rich previews, inline images, and trash support | +| Name | Description | +|------|-------------| +| [lazygit](https://github.com/jesseduffield/lazygit) | Git terminal UI | +| [gh-dash](https://github.com/dlvhdr/gh-dash) | GitHub dashboard for the terminal | +| [yazi](https://github.com/sxyazi/yazi) | Terminal file manager | +| [elio](https://github.com/elio-fm/elio) | Terminal file manager with rich previews, inline images, and trash support | ### Terminal Multiplexers -Installed during first-run setup. Choose any combination, or none: - | Name | Description | |------|-------------| | [tmux](https://github.com/tmux/tmux) | Classic terminal multiplexer | | [zellij](https://github.com/zellij-org/zellij) | Friendly terminal workspace | | [herdr](https://herdr.dev) | Agent multiplexer β€” run multiple coding agents from one terminal | -### Shell (Experimental) +### Shells and SDKs -By default, squarebox uses Bash. During first-run setup you can opt in to -**Zsh**, **Fish**, or **PowerShell** instead. +Bash is the default shell; choose Zsh, Fish, or PowerShell during setup. +Node.js, Python, Go, .NET, and Rust are available through +[mise](https://github.com/jdx/mise). +See [shell configuration](docs/usage.md#shell-configuration) and +[SDK configuration](docs/usage.md#sdk-configuration). -**Zsh** installs: +Everyday commands +----------------- -| Name | Description | -|------|-------------| -| [zsh](https://www.zsh.org) | Z shell (via apt) | -| [Oh My Zsh](https://ohmyz.sh) | Community framework for managing zsh config | -| [zsh-autosuggestions](https://github.com/zsh-users/zsh-autosuggestions) | Fish-like history-based suggestions | -| [zsh-syntax-highlighting](https://github.com/zsh-users/zsh-syntax-highlighting) | Inline command syntax highlighting | - -The generated `~/.zshrc` mirrors the default bashrc β€” same aliases, starship -prompt, zoxide, and AI/editor/SDK sourcing β€” layered on top of Oh My Zsh. - -**Fish** installs [fish](https://fishshell.com) (via apt), which ships with -autosuggestions and syntax highlighting built in. The generated -`~/.config/fish/config.fish` mirrors the default bashrc in fish-native syntax; -AI/editor/TUI/SDK selections are translated from their bash files into -`~/.config/fish/conf.d/squarebox-selections.fish` at setup time. - -**PowerShell** installs PowerShell 7 (`pwsh`) from Microsoft's official -[GitHub release](https://github.com/PowerShell/PowerShell/releases) `.deb` -(asset SHA-256 verified against the release metadata before install). The -generated `~/.config/powershell/profile.ps1` mirrors the default bashrc in -PowerShell-native syntax β€” starship, zoxide, and mise activate, plus the -standard aliases as functions (PowerShell `Set-Alias` cannot attach -arguments); AI/editor/TUI selections are translated from their bash files into -`~/.config/powershell/squarebox-selections.ps1` at setup time. - -> **Experimental:** the marker file `~/.squarebox-use-zsh`, -> `~/.squarebox-use-fish`, or `~/.squarebox-use-pwsh` causes `~/.bashrc` to -> `exec` the chosen shell on every interactive login, so the next shell start -> picks up the new shell. Set `SQUAREBOX_NO_ZSH=1`, `SQUAREBOX_NO_FISH=1`, or -> `SQUAREBOX_NO_PWSH=1` to force bash for a single session, or re-run -> `sqrbx-setup shell` to switch back permanently. Tooling is primarily tested -> against bash, so a few edge cases may need polish β€” please file an issue if -> you hit one. SDK shims are wired into all four shells via -> `mise activate {bash,zsh,fish,pwsh}`. - -### SDKs - -All SDKs are managed by [mise](https://github.com/jdx/mise) β€” a single -polyglot version manager. Selections are written to `~/.config/mise/config.toml` -and `mise activate` wires up shims and PATH automatically across bash, zsh, -and fish. - -| SDK | mise tool | -|-------|-----------| -| Node.js | `node` | -| Python | `python` | -| Go | `go` | -| .NET | `dotnet` | -| Rust | `rust` | - -Getting help ------------- - -Run `sqrbx-help` inside the container for a one-screen overview of the -`sqrbx-*` commands, Bash's fzf (`Ctrl+R`/`Ctrl+T`/`Alt+C`/`**`) bindings, -and zoxide (`z`/`zi`) navigation. Zsh and Fish retain the `fzf`, `ff`, and -`eff` commands but do not claim those Bash-specific bindings. The MOTD points -to the help command on every shell start. - -Reconfiguring -------------- - -Re-run the first-run wizard at any time from inside the container with -`sqrbx-setup`. With no arguments it walks every section; pass one or more -section names to reconfigure just those: `git`, `github`, `ai`, `editors`, -`tuis`, `multiplexers`, `sdks`, `shell`. `sqrbx-setup --list` shows your -current selections and `sqrbx-setup --help` the usage. - -Aliases -------- +Run these inside the Box: -| Alias | Command | Description | -|-------|---------|-------------| -| `ls` | `eza --icons` | Modern ls with icons | -| `ll` | `eza -la --icons` | Long listing with icons | -| `lsa` | `ls -a` (resolves to `eza --icons -a`) | List all including hidden files | -| `lt` | `eza --tree --level=2 --long --icons --git` | Tree view with git status | -| `lta` | `lt -a` | Tree view including hidden files | -| `cat` | `bat --paging=never` | Syntax-highlighted cat | -| `ff` | `fzf --preview 'bat ...'` | Fuzzy find with preview | -| `eff` | `$EDITOR "$(ff)"` | Fuzzy find and edit | -| `..` | `cd ..` | Go up one directory | -| `...` | `cd ../..` | Go up two directories | -| `....` | `cd ../../..` | Go up three directories | -| `c` | first selected AI tool | Launch selected AI assistant | -| `g` | `git` | Git shorthand | -| `gcm` | `git commit -m` | Commit with message | -| `gcam` | `git commit -a -m` | Stage all and commit | -| `gcad` | `git commit -a --amend` | Stage all and amend | -| `lg` | `lazygit` | Launch lazygit (if installed) | -| `claude-yolo` | `claude --dangerously-skip-permissions` | Claude without prompts | -| `copilot-yolo` | `copilot --allow-all` | Copilot CLI without permission prompts | -| `codex-yolo` | `codex --dangerously-bypass-approvals-and-sandbox` | Codex without prompts or sandboxing | -| `gemini-yolo` | `gemini --approval-mode=yolo` | Gemini CLI without prompts | -| `opencode-yolo` | `opencode --dangerously-skip-permissions` | OpenCode without prompts | -| `omp-yolo` | `omp --approval-mode yolo` | Oh My Pi without prompts | - -The `*-yolo` aliases are generated only for selected AI tools that are -installed. They disable that tool's normal approval prompts; `codex-yolo` also -disables Codex's sandbox. Use them only in a workspace whose contents and -commands you trust. - -### Shared Keyboard Language (Experimental) - -Squarebox builds on Omarchy's defaults with one portable rule: `Super` belongs -to the OS/window manager, while `Ctrl` acts immediately in the focused app. -Herdr uses `Ctrl+Alt` for direct letter chords because many terminals collapse -`Ctrl+Shift+letter` into the unshifted control key. Its `F12` prefix remains -available as a compatibility fallback. - -Herdr's generated default uses familiar app shortcuts: - -| Feature | Herdr | -|---------|-------| -| New / close | `Ctrl+T` / `Ctrl+W` | -| Cycle / select tabs | `Ctrl+Tab`, `Ctrl+Shift+Tab` / `Ctrl+1-9` | -| Focus / swap pane | `Ctrl+Arrow` / `Ctrl+Shift+Arrow` | -| Sidebar / go to | `Ctrl+B` / `Ctrl+G` | -| Split right / down | `Ctrl+\\` / `Ctrl+Alt+\\` | -| Zoom / new workspace | `Ctrl+Alt+Z` / `Ctrl+Alt+N` | -| Compatibility prefix | `F12` | - -These bindings intentionally take precedence over matching shell or nested-app -shortcuts while Herdr is focused. Existing `~/.config/herdr/config.toml` files -remain user-managed and are never replaced by setup. - -Tmux and Zellij retain their earlier Omarchy-inspired matching defaults: - -| Feature | Tmux | Zellij | -|---------|------|--------| -| Config path | `~/.config/tmux/tmux.conf` | `~/.config/zellij/config.kdl` | -| Prefix | `Ctrl+Space` | `Ctrl+Space` (Tmux mode) | -| Alternate prefix | `Ctrl+B` | `Ctrl+B` (Tmux mode) | -| Prefix help | β€” | `prefix ?` | -| Pane navigation | `Ctrl+Alt+Arrow` | `Ctrl+Alt+Arrow` | -| Pane resizing | `Ctrl+Alt+Shift+Arrow` | `Ctrl+Alt+Shift+Arrow` | -| Tab/window select | `Alt+1-9` | `Alt+1-9` | -| Tab/window cycle | `Alt+Left/Right` | `Alt+Left/Right` | -| Split horizontal | `prefix h` | `prefix h` | -| Split vertical | `prefix v` | `prefix v` | -| Scrollback | 50,000 lines | 50,000 lines | -| Copy mode | Vi keys | Vi-style scroll | -| Theme | Blue accent, top bar | Blue accent, compact layout | - -Update ------- - -### Quick update (from inside the container) - - sqrbx-update - -Checks installed registered tools against upstream releases. A dry run never -installs absent optional tools; `--apply` updates the installed set only. Naming -an absent tool explicitly is an install request. Failures are aggregated, -reported with preserved logs, and return nonzero. Managed-home tools can advance -in place. Image-tier tools advance only through a newer Squarebox Candidate and -Box rebuild unless the current Candidate already authorizes the exact release -asset; an unvetted upstream release is reported but never advertised as applyable. -Broken version probes and incomplete Yazi, Helix, or Neovim output sets are -reported as repairs; a failed post-install verification restores prior managed -outputs. - - sqrbx-update # show available updates (dry run) - sqrbx-update --apply # update all installed registered tools - sqrbx-update lazygit # update, or explicitly install, one tool - sqrbx-update --list # list all tools and current versions - -Setup and `sqrbx-update` read GitHub release metadata through the GitHub API, -which allows only 60 unauthenticated requests per hour per IP address. On a -shared NAT or CI runner, authenticate those requests to avoid HTTP 403 rate -limits: export `GH_TOKEN` (or `GITHUB_TOKEN`), or run `gh auth login` inside -the Box. The token is optional, is sent only to the GitHub API, and a rejected -token falls back to unauthenticated requests. - -### Full rebuild (from the host) - - sqrbx-rebuild - -Resolves the requested published Release, pulls its immutable image digest, and -replaces the Box. Installations created with `--build` retain that choice and -build the matching source instead. -Your code in ~/squarebox/workspace is safe since it lives on the host. Most -in-container state (shell history, GitHub auth, SDK toolchains) survives -because /home/dev is backed by the `squarebox-home` named Docker volume. -Manually installed apt packages are still lost, since the image is rebuilt. - -#### What survives a rebuild - -| Survives | Reconciled or lost | -|----------|--------------------| -| Workspace code on the host | Selected tmux/Zsh/Fish packages are reconciled into the new Box | -| Managed home: history, auth, assistant data, mise toolchains | Manually installed, unselected APT packages are lost | -| Selection state in `/workspace/.squarebox` | Image-tier binaries are replaced by the Candidate digest | -| Host SSH access (agent forwarding, or the recorded `SQUAREBOX_MOUNT_SSH` opt-in) | Image-managed dotfiles are safely refreshed | - -Use `sqrbx-uninstall --purge` to wipe recorded state. Do not remove a volume by -name alone; lifecycle commands verify the Install identity and ownership -labels before deleting a Managed resource. - -> **Tip:** Use `sqrbx-update` from inside the container for Managed-home tools. -> Use `sqrbx-rebuild` for image-tier binaries, new APT packages, base-tool -> changes, or any upstream release the current Candidate cannot authorize. - -Disk usage ----------- - -The reviewed amd64 v1.1 Candidate is approximately **900 MB** in -`docker image ls` (about 638 MB of files in a running Box). Registry transfer, -shared local layers, and unpacked filesystem size are different measurements; -inspect the exact Release on your platform. - -First-run selections add to that: - -| Component | Adds | -|-----------|------| -| Claude Code | ~300 MB | -| GitHub Copilot CLI | ~50 MB | -| Google Gemini CLI | ~50 MB | -| OpenAI Codex CLI | ~50 MB | -| OpenCode | ~30 MB | -| Pi Coding Agent | ~50 MB | -| Oh My Pi | Varies by release | -| lazygit / gh-dash / yazi | ~10 / ~10 / ~10 MB | -| elio | ~14 MB | -| micro / edit | ~12 / ~7 MB | -| fresh / nvim | ~10 / ~45 MB | -| Helix | Varies by release (binary plus runtime files) | -| Node.js | ~90 MB | -| Python | ~50 MB | -| Go | ~500 MB | -| .NET | ~800 MB | - -Optional sizes are approximate and change independently of Squarebox Releases. +```bash +sqrbx-help # commands and navigation shortcuts +sqrbx-setup # rerun the setup wizard +sqrbx-setup ai editors # reconfigure specific sections +sqrbx-setup --list # show your selections +sqrbx-update # check for tool updates +sqrbx-update --apply # update installed registered tools +sqrbx-update lazygit # update or install one named tool +``` -Security --------- +From the host, run `sqrbx-rebuild` to update the Box itself. This keeps your +workspace and persistent home, and reuses your installation settings. +Some bundled tools require a rebuild to update. -Direct-download image-tier tools are pinned and fail closed against repository -SHA-256 checksums. Published image bytes are immutable by digest; rebuilding -later is not guaranteed to reproduce them because the Ubuntu base and APT -repositories are external mutable inputs. - -Optional tools selected during first-run setup (editors, TUIs, OpenCode, -zellij) install the latest upstream release at the time you run setup. For -GitHub-hosted artifacts, Squarebox resolves one exact release tag and asset -name, requires GitHub's SHA-256 release-asset digest, and verifies the bytes -before extraction. Missing or mismatched digest metadata fails closed. These -tools remain Managed-home selections rather than image-build pins. Setup -installs an absent selection; `sqrbx-update --apply` is the explicit path for -updating an already observed registered tool to a newer authorized release. - -SDKs (Node, Python, Go, .NET, Rust) are installed by [mise](https://github.com/jdx/mise), -which is itself a Dockerfile-tier pinned binary. mise downloads each SDK -toolchain from its upstream over HTTPS using its own integrity checks. npm-based -AI tools (Copilot CLI, Gemini CLI, Codex CLI, and Pi) use npm's built-in -integrity verification. Oh My Pi uses its official mise GitHub backend and -follows mise's backend integrity policy. - -For the full trust model (what `install.sh` does on your machine, how each -layer is verified, and how to inspect the script before running it) see -[SECURITY.md](SECURITY.md). - -Devcontainer / Codespaces -------------------------- - -Open this repo in VS Code with the -[Dev Containers extension](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers), -or launch it in [GitHub Codespaces](https://github.com/features/codespaces). -The included `.devcontainer/devcontainer.json` builds the full **squarebox** image -automatically and mounts the cloned repository at `/workspace`, matching setup -and Selection state. A per-Box named volume, derived from the stable -Dev Container identity, mounts at `/home/dev` so authentication, history, and -mise toolchains survive container rebuilds without being shared across -unrelated workspaces. - -The interactive first-run wizard can't run in devcontainer mode (no TTY at -create time), so a default toolset β€” **Claude Code + Node.js** β€” is installed -non-interactively by `postCreateCommand`. Override the defaults with these -container environment variables (set to an empty string to opt out of a tier): - -| Variable | Default | Selects | -|----------|---------|---------| -| `SQUAREBOX_DC_AI` | `claude` | AI assistants (`claude,copilot,gemini,codex,opencode,pi,omp`) | -| `SQUAREBOX_DC_SDKS` | `node` | SDKs (`node,python,go,dotnet,rust`) | -| `SQUAREBOX_DC_EDITORS` | _(none)_ | Editors (`micro,edit,fresh,helix,nvim`; Helix launches as `hx`) | -| `SQUAREBOX_DC_TUIS` | _(none)_ | TUI tools (`lazygit,gh-dash,yazi,elio`) | -| `SQUAREBOX_DC_MULTIPLEXERS` | _(none)_ | Multiplexers (`tmux,zellij,herdr`) | - -To add or change tools after the fact, run `sqrbx-setup` from the integrated -terminal. - -You can also attach to a running codespace directly from your local terminal -using `gh codespace ssh`. The official Dev Containers SSH server Feature is -version- and digest-locked for this path. It is added only to the derived Dev -Container image, not the published Squarebox Candidate, and remote-forwarded -ports remain bound to loopback by default. +See the [aliases](docs/usage.md#aliases), +[keyboard shortcuts](docs/usage.md#keyboard-shortcuts), and +[update details](docs/usage.md#updates-and-rebuilds). Uninstall --------- - sqrbx-uninstall - -Removes the recorded Box, owned image reference, and shell integration but **keeps** -the install directory/Workspace and Managed-home volume -(shell history, gh auth, mise toolchains) so your code and per-user state are -safe by default. Pass `--purge` to remove the Managed home and recorded install -directory. The default Workspace nested inside that directory is removed with -it; a custom external Workspace is always preserved: - - sqrbx-uninstall --purge - -The confirmation summary lists a non-empty nested Workspace, with its item count, -as something that will be deleted, and a second confirmation is required. -Pass `-y` (or `-Yes` on PowerShell) to skip prompts for scripting. Unattended -purge refuses, before removing anything, to delete a non-empty nested -Workspace unless you also pass `--delete-workspace` (`-DeleteWorkspace` on -PowerShell): - - sqrbx-uninstall --purge --yes --delete-workspace - -An empty Workspace or an external Workspace needs no extra flag. -Idempotent for a valid Install identity. Legacy resources require `--adopt`; -purging an adopted, unlabeled volume additionally requires `--force`. +From the host: -**Windows (PowerShell 7+):** - - sqrbx-uninstall # keep ~/squarebox - sqrbx-uninstall -Purge # also remove ~/squarebox - sqrbx-uninstall -Yes # skip confirmations - sqrbx-uninstall -Purge -Yes -DeleteWorkspace # also delete a non-empty nested Workspace +```bash +sqrbx-uninstall +``` -**Broken-state recovery** (e.g. shell functions are missing, or after partial -install): run the script matching the adapter that created the Install identity -directly from the install directory. PowerShell and Git Bash lifecycle state is -not cross-consumed: +This removes the Box and shell integration, keeping your workspace and +persistent home. `sqrbx-uninstall --purge` (PowerShell: `-Purge`) also removes +the persistent home and install directory, **including a workspace inside it**. +A custom external workspace is preserved. +See [uninstall options and recovery](docs/usage.md#uninstall-and-recovery). - ~/squarebox/uninstall.sh # Linux / macOS / Git Bash - ~/squarebox/uninstall.ps1 # Windows PowerShell +Security +-------- -Start a new shell afterwards (or `exec bash` / `exec zsh`) so the `sqrbx` and -`squarebox` functions are dropped from the current session. +The Box is a development environment with access to your mounted files and +credentials. SSH-directory mounts require explicit opt-in. +See [SECURITY.md](SECURITY.md) for SSH access, the trust model, artifact +verification, and vulnerability reporting. Make it your own ------------------ +---------------- -**squarebox** is meant to be a starting point, not a finished product. Fork it, -swap out tools, add your own dotfiles, change the theme - build the dev -environment that fits the way you work. The Dockerfile is intentionally -straightforward and the tool registry (`scripts/lib/tools.yaml`) makes it easy -to add or remove tools. Use it as a base, take what's useful, and make it yours. +Fork it, swap tools, or add your own dotfiles. The [Dockerfile](Dockerfile) and +[tool registry](scripts/lib/tools.yaml) define what's included. diff --git a/SECURITY.md b/SECURITY.md index 5e4a5c5..026b6b4 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -28,8 +28,8 @@ The Bash and PowerShell lifecycle adapters: 6. Mount the Workspace read-write, the private Git identity, optional SSH access, and explicitly documented managed configuration. Bash/POSIX and Git Bash adapters forward `SSH_AUTH_SOCK` when available and otherwise mount SSH files - read-only; native PowerShell currently provides only the read-only SSH-file - path. + read-only only on explicit opt-in; native PowerShell provides only the + opt-in read-only SSH-file path. 7. Add a sentinel-delimited shell integration block that reads the recorded Install identity for launch, rebuild, and uninstall operations. @@ -70,6 +70,23 @@ Before running a downloaded installer, inspect it: Piping directly to Bash trusts GitHub and TLS to deliver the intended bootstrap asset. Download-and-inspect is the safer default. +## SSH access + +The Box does not receive your SSH private-key files by default, because anything +running inside it, including unattended `*-yolo` AI agents, could read them. + +- **SSH agent (recommended).** When `SSH_AUTH_SOCK` points at a running agent, + the Bash/POSIX and Git Bash adapters forward the agent socket and mount only + `~/.ssh/config` and `~/.ssh/known_hosts` read-only. Key files stay on the + host, though Box processes can ask the agent to sign while the socket is + available. +- **No agent.** `~/.ssh` is not mounted, and install prints a note. To mount + the directory read-only instead, opt in with `SQUAREBOX_MOUNT_SSH=1` (native + PowerShell: `.\install.ps1 -MountSsh` or `$env:SQUAREBOX_MOUNT_SSH = '1'`). + The choice is recorded in the Install identity and reused by + `sqrbx-rebuild`; set `SQUAREBOX_MOUNT_SSH=0` (or `-MountSsh:$false`) on a + rebuild to turn it back off. + ## Release identity and verification Every v1.1+ Release includes: @@ -218,6 +235,10 @@ Post-install mismatch restores the prior complete output set. A broken version probe or missing Yazi helper, Helix runtime, or Neovim tree/link is reported as repairable incomplete state rather than β€œup to date.” +Setup installs absent selections; `sqrbx-update --apply` explicitly updates +already installed registered tools to newer authorized releases. Oh My Pi uses +its official mise GitHub backend and follows mise’s backend integrity policy. + External installers and package managers are outside this artifact registry. That includes npm assistants, Anthropic's Claude installer, mise SDK backends, APT, and `dpkg`; their integrity and transaction behavior remain the upstream diff --git a/docs/usage.md b/docs/usage.md new file mode 100644 index 0000000..9b9dfc6 --- /dev/null +++ b/docs/usage.md @@ -0,0 +1,445 @@ +# Usage reference + +[Back to README](../README.md) Β· [Security](../SECURITY.md) + +- [Installing Docker](#installing-docker) +- [Advanced installation](#advanced-installation) +- [Windows installation](#windows-installation) +- [Server deployment](#server-deployment) +- [Shell configuration](#shell-configuration) +- [Editor configuration](#editor-configuration) +- [SDK configuration](#sdk-configuration) +- [Help and reconfiguration](#help-and-reconfiguration) +- [Aliases](#aliases) +- [Keyboard shortcuts](#keyboard-shortcuts) +- [Updates and rebuilds](#updates-and-rebuilds) +- [Dev Containers and Codespaces](#dev-containers-and-codespaces) +- [Uninstall and recovery](#uninstall-and-recovery) + +## Installing Docker + +**macOS** (via [Homebrew](https://brew.sh)): + + brew install --cask docker-desktop + +**Linux** (official convenience script - inspect it first at [get.docker.com](https://get.docker.com)): + + curl -fsSL https://get.docker.com | sh && sudo usermod -aG docker $USER + +Log out and back in (or run `newgrp docker`) so your shell picks up the new group. + +**Windows** (via [winget](https://learn.microsoft.com/en-us/windows/package-manager/winget/), in PowerShell 7+): + + winget install --id Docker.DockerDesktop -e + +On macOS and Windows, start Docker Desktop once after install so the daemon is +running before you continue. + +## Advanced installation + +Stable resolves the latest published GitHub Release and pulls the immutable +image digest recorded in its `release.json`. Raw Git tags are not installable +stable releases. An explicit `SQUAREBOX_TAG=v…` resolves that published Release +and its matching source revision. Edge builds the latest commit on `main`. To +build a published Release from source instead of pulling, pass `--build`. + +Install edge from Bash: + +```bash +curl -fsSL https://github.com/SquareWaveSystems/squarebox/releases/latest/download/install.sh | bash -s -- --edge +``` + +If the install fails or you want to see the full build/pull and git output, +re-run with `--verbose`. + +Flags: `--build` (build from source), `--edge` (latest `main`), `--adopt` +(one-time migration of a legacy installation), and `--verbose`. + +| Variable | Default | Purpose | +|----------|---------|---------| +| `SQUAREBOX_DIR` | `~/squarebox` | Install location (repo + workspace). Point at durable storage on hosts where `$HOME` is volatile β€” e.g. Unraid `/mnt/user/appdata/squarebox`. | +| `SQUAREBOX_WORKSPACE` | `$SQUAREBOX_DIR/workspace` | Host path mounted as `/workspace`. | +| `SQUAREBOX_TAG` | latest published stable | Published Release to install (for example `v1.2.1`). Tags use `vMAJOR.MINOR.PATCH[-prerelease]`; build metadata is not published. | +| `SQUAREBOX_IMAGE` | value from `release.json` | Optional image-repository override for development/testing. | +| `SQUAREBOX_BUILD` | `0` | `1` is equivalent to `--build`. | +| `PUID` / `PGID` | invoking Linux user | Host uid/gid that should own bind-mounted files. Unprivileged Linux installs must match the invoking account. Root-run rootful runtimes, including Docker or Podman on NAS and Unraid, may override these (typically `99` / `100`); rootless Podman also requires the invoking host identity. | +| `SQUAREBOX_RUNTIME` | auto | Force `docker` or `podman`. | +| `SQUAREBOX_HOME_VOLUME` | `squarebox-home` | Name of the named volume backing `/home/dev`. | +| `SQUAREBOX_EDGE` | `0` | `1` is equivalent to `--edge`. | +| `SQUAREBOX_MOUNT_SSH` | `0` | `1` mounts your host `~/.ssh` directory, **private keys included**, read-only into the Box when no SSH agent is forwarded. Recorded for rebuilds; set `0` to turn it back off. See [SSH access](../SECURITY.md#ssh-access). | + +**Non-interactive provisioning** β€” set any of these to a comma-separated list to +pre-select a toolset and install it without prompts (handy for servers and +scripted installs). Values use the same keys as `sqrbx-setup`: + +| Variable | Selects | +|----------|---------| +| `SQUAREBOX_AI` | AI assistants (`claude,copilot,gemini,codex,opencode,pi,omp`) | +| `SQUAREBOX_SDKS` | language SDKs (`node,python,go,dotnet,rust`) | +| `SQUAREBOX_EDITORS` | editors (`micro,edit,fresh,helix,nvim`; Helix launches as `hx`) | +| `SQUAREBOX_TUIS` | TUI tools (`lazygit,gh-dash,yazi,elio`) | +| `SQUAREBOX_MULTIPLEXERS` | multiplexers (`tmux,zellij,herdr`) | +| `SQUAREBOX_GIT_NAME` / `SQUAREBOX_GIT_EMAIL` | git identity (when no host gitconfig) | + +Example: + +```bash +curl -fsSL https://github.com/SquareWaveSystems/squarebox/releases/latest/download/install.sh \ + | env SQUAREBOX_AI=claude SQUAREBOX_SDKS=node,python bash +``` + +Each successful v1.1-or-newer install records its effective lifecycle settings at +`/.squarebox/install-state` (mode 0600 on POSIX; inherited +current-user install-directory ACL on native Windows). Rebuild and uninstall +parse this file as data; they do not reconstruct defaults or source it as shell +code. Release pulls record an immutable image digest; source/edge builds record +their local image ID/reference. Existing pre-v1.1 checkouts require a one-time +reviewed `--adopt`/`-Adopt`. + +## Windows installation + +Windows users can install directly from PowerShell - no Git Bash required. +This handles Release resolution, pull/build, Box creation, and PowerShell functions +(`sqrbx`, `squarebox`, etc.) natively: + + irm https://github.com/SquareWaveSystems/squarebox/releases/latest/download/install.ps1 | iex + +Once installed, you can re-run or pass flags from the local copy: + + .\install.ps1 # re-install / update + .\install.ps1 -Edge # latest main instead of latest release + .\install.ps1 -Build # build the resolved source locally + .\install.ps1 -Adopt # migrate a legacy pre-v1.1 installation + .\install.ps1 -MountSsh # opt in to mounting %USERPROFILE%\.ssh read-only + +> **Note:** `irm ... | iex` does not support flags - PowerShell interprets them +> as arguments to `Invoke-Expression`, not the script. Use the local +> `.\install.ps1` form for `-Edge`, `-Build`, `-Adopt`, or `-MountSsh`. +> PowerShell streams runtime and Git failures directly by default. + +> **Windows adapter boundary:** Keep install, rebuild, and uninstall on the +> adapter that created the Install identity. Native PowerShell and Git Bash +> use the same Install identity field names, but their native path and +> shell-profile values are not interchangeable; +> cross-adapter state consumption is rejected. +> Native PowerShell does not forward `SSH_AUTH_SOCK` and mounts +> `%USERPROFILE%\.ssh` read-only only when you opt in with `-MountSsh` or +> `SQUAREBOX_MOUNT_SSH=1`. The separate Git Bash adapter supports SSH +> agent-socket forwarding with its Bash lifecycle. +> Use `./scripts/migrate-windows-adapter.ps1 -Target PowerShell` or +> `-Target GitBash` from PowerShell 7 for an explicit cross-adapter migration. +> Normal installers and uninstallers continue to reject foreign adapter state. + +## Server deployment + +The `curl | bash` installer is built around an interactive desktop shell. To run +squarebox as a persistent server container you attach into on demand β€” on +Unraid, a NAS, or a VPS β€” use the prebuilt image directly with the bundled +`docker-compose.yml`: + + cp .env.example .env # set PUID/PGID, the workspace path, and a tag + docker compose up -d + docker compose exec -u dev squarebox bash + +Set `PUID`/`PGID` in `.env` to match your host so files squarebox writes to the +workspace mount are owned correctly β€” on Unraid that's `99` / `100`. The `-u dev` +on `exec` is needed because the container starts as root (to apply PUID/PGID) +then drops to the `dev` user; `exec` bypasses that, so `-u dev` lands you where +you want to be. + +Per-user state (shell history, gh auth, mise toolchains, AI-assistant state) +lives in the `squarebox-home` named volume and survives image updates; your code +lives on the host at the workspace path. To update, pull a newer tag and +`docker compose up -d`. The published image is multi-arch (amd64 + arm64), so it +also runs on ARM NAS/VPS hosts. + +> **Unraid note:** the host's `/root` is tmpfs and wiped on reboot, so a raw +> `curl | bash` install there won't persist. Either use compose (above) with the +> workspace path under `/mnt/user/appdata`, or run the installer with +> `SQUAREBOX_DIR` and `SQUAREBOX_WORKSPACE` pointed at appdata. + +## Shell configuration + +By default, squarebox uses Bash. During first-run setup you can opt in to +**Zsh**, **Fish**, or **PowerShell** instead. + +**Zsh** installs: + +| Name | Description | +|------|-------------| +| [zsh](https://www.zsh.org) | Z shell (via apt) | +| [Oh My Zsh](https://ohmyz.sh) | Community framework for managing zsh config | +| [zsh-autosuggestions](https://github.com/zsh-users/zsh-autosuggestions) | Fish-like history-based suggestions | +| [zsh-syntax-highlighting](https://github.com/zsh-users/zsh-syntax-highlighting) | Inline command syntax highlighting | + +The generated `~/.zshrc` mirrors the default bashrc β€” same aliases, starship +prompt, zoxide, and AI/editor/SDK sourcing β€” layered on top of Oh My Zsh. + +**Fish** installs [fish](https://fishshell.com) (via apt), which ships with +autosuggestions and syntax highlighting built in. The generated +`~/.config/fish/config.fish` mirrors the default bashrc in fish-native syntax; +AI/editor/TUI/SDK selections are translated from their bash files into +`~/.config/fish/conf.d/squarebox-selections.fish` at setup time. + +**PowerShell** installs PowerShell 7 (`pwsh`) from Microsoft's official +[GitHub release](https://github.com/PowerShell/PowerShell/releases) `.deb` +(asset SHA-256 verified against the release metadata before install). The +generated `~/.config/powershell/profile.ps1` mirrors the default bashrc in +PowerShell-native syntax β€” starship, zoxide, and mise activate, plus the +standard aliases as functions (PowerShell `Set-Alias` cannot attach +arguments); AI/editor/TUI selections are translated from their bash files into +`~/.config/powershell/squarebox-selections.ps1` at setup time. + +> The marker file `~/.squarebox-use-zsh`, +> `~/.squarebox-use-fish`, or `~/.squarebox-use-pwsh` causes `~/.bashrc` to +> `exec` the chosen shell on every interactive login, so the next shell start +> picks up the new shell. Set `SQUAREBOX_NO_ZSH=1`, `SQUAREBOX_NO_FISH=1`, or +> `SQUAREBOX_NO_PWSH=1` to force bash for a single session, or re-run +> `sqrbx-setup shell` to switch back permanently. Tooling is primarily tested +> against bash, so a few edge cases may need polish β€” please file an issue if +> you hit one. SDK shims are wired into all four shells via +> `mise activate {bash,zsh,fish,pwsh}`. + +## Editor configuration + +Selecting **nvim** offers to install the [LazyVim](https://www.lazyvim.org/) starter config to `~/.config/nvim`, turning Neovim into a preconfigured IDE. Plugins sync on first launch and persist in the `squarebox-home` volume. A Nerd Font in your terminal is recommended for icons; the starter is skipped if `~/.config/nvim` already exists, so your own config is never overwritten. + +## SDK configuration + +All SDKs are managed by [mise](https://github.com/jdx/mise) β€” a single +polyglot version manager. Selections are written to `~/.config/mise/config.toml` +and `mise activate` wires up shims and PATH automatically across bash, zsh, +and fish. + +| SDK | mise tool | +|-------|-----------| +| Node.js | `node` | +| Python | `python` | +| Go | `go` | +| .NET | `dotnet` | +| Rust | `rust` | + +## Help and reconfiguration + +Run `sqrbx-help` inside the container for a one-screen overview of the +`sqrbx-*` commands, Bash's fzf (`Ctrl+R`/`Ctrl+T`/`Alt+C`/`**`) bindings, +and zoxide (`z`/`zi`) navigation. Zsh and Fish retain the `fzf`, `ff`, and +`eff` commands but do not claim those Bash-specific bindings. The MOTD points +to the help command on every shell start. + +Re-run the first-run wizard at any time from inside the container with +`sqrbx-setup`. With no arguments it walks every section; pass one or more +section names to reconfigure just those: `git`, `github`, `ai`, `editors`, +`tuis`, `multiplexers`, `sdks`, `shell`. `sqrbx-setup --list` shows your +current selections and `sqrbx-setup --help` the usage. + +## Aliases + +| Alias | Command | Description | +|-------|---------|-------------| +| `ls` | `eza --icons` | Modern ls with icons | +| `ll` | `eza -la --icons` | Long listing with icons | +| `lsa` | `ls -a` (resolves to `eza --icons -a`) | List all including hidden files | +| `lt` | `eza --tree --level=2 --long --icons --git` | Tree view with git status | +| `lta` | `lt -a` | Tree view including hidden files | +| `cat` | `bat --paging=never` | Syntax-highlighted cat | +| `ff` | `fzf --preview 'bat ...'` | Fuzzy find with preview | +| `eff` | `$EDITOR "$(ff)"` | Fuzzy find and edit | +| `..` | `cd ..` | Go up one directory | +| `...` | `cd ../..` | Go up two directories | +| `....` | `cd ../../..` | Go up three directories | +| `c` | first selected AI tool | Launch selected AI assistant | +| `g` | `git` | Git shorthand | +| `gcm` | `git commit -m` | Commit with message | +| `gcam` | `git commit -a -m` | Stage all and commit | +| `gcad` | `git commit -a --amend` | Stage all and amend | +| `lg` | `lazygit` | Launch lazygit (if installed) | +| `claude-yolo` | `claude --dangerously-skip-permissions` | Claude without prompts | +| `copilot-yolo` | `copilot --allow-all` | Copilot CLI without permission prompts | +| `codex-yolo` | `codex --dangerously-bypass-approvals-and-sandbox` | Codex without prompts or sandboxing | +| `gemini-yolo` | `gemini --approval-mode=yolo` | Gemini CLI without prompts | +| `opencode-yolo` | `opencode --dangerously-skip-permissions` | OpenCode without prompts | +| `omp-yolo` | `omp --approval-mode yolo` | Oh My Pi without prompts | + +The `*-yolo` aliases are generated only for selected AI tools that are +installed. They disable that tool's normal approval prompts; `codex-yolo` also +disables Codex's sandbox. Use them only in a workspace whose contents and +commands you trust. + +## Keyboard shortcuts + +Squarebox uses one portable rule: `Super` belongs +to the OS/window manager, while `Ctrl` acts immediately in the focused app. +Herdr uses `Ctrl+Alt` for direct letter chords because many terminals collapse +`Ctrl+Shift+letter` into the unshifted control key. Its `F12` prefix remains +available as a compatibility fallback. + +Herdr's generated default uses familiar app shortcuts: + +| Feature | Herdr | +|---------|-------| +| New / close | `Ctrl+T` / `Ctrl+W` | +| Cycle / select tabs | `Ctrl+Tab`, `Ctrl+Shift+Tab` / `Ctrl+1-9` | +| Focus / swap pane | `Ctrl+Arrow` / `Ctrl+Shift+Arrow` | +| Sidebar / go to | `Ctrl+B` / `Ctrl+G` | +| Split right / down | `Ctrl+\\` / `Ctrl+Alt+\\` | +| Zoom / new workspace | `Ctrl+Alt+Z` / `Ctrl+Alt+N` | +| Compatibility prefix | `F12` | + +These bindings intentionally take precedence over matching shell or nested-app +shortcuts while Herdr is focused. Existing `~/.config/herdr/config.toml` files +remain user-managed and are never replaced by setup. + +Tmux and Zellij use matching defaults: + +| Feature | Tmux | Zellij | +|---------|------|--------| +| Config path | `~/.config/tmux/tmux.conf` | `~/.config/zellij/config.kdl` | +| Prefix | `Ctrl+Space` | `Ctrl+Space` (Tmux mode) | +| Alternate prefix | `Ctrl+B` | `Ctrl+B` (Tmux mode) | +| Prefix help | β€” | `prefix ?` | +| Pane navigation | `Ctrl+Alt+Arrow` | `Ctrl+Alt+Arrow` | +| Pane resizing | `Ctrl+Alt+Shift+Arrow` | `Ctrl+Alt+Shift+Arrow` | +| Tab/window select | `Alt+1-9` | `Alt+1-9` | +| Tab/window cycle | `Alt+Left/Right` | `Alt+Left/Right` | +| Split horizontal | `prefix h` | `prefix h` | +| Split vertical | `prefix v` | `prefix v` | +| Scrollback | 50,000 lines | 50,000 lines | +| Copy mode | Vi keys | Vi-style scroll | +| Theme | Blue accent, top bar | Blue accent, compact layout | + +## Updates and rebuilds + +### Quick update (from inside the container) + + sqrbx-update + +Checks installed registered tools against upstream releases. A dry run never +installs absent optional tools; `--apply` updates the installed set only. Naming +an absent tool explicitly is an install request. Failures are aggregated, +reported with preserved logs, and return nonzero. Managed-home tools can advance +in place. Image-tier tools advance only through a newer Squarebox Candidate and +Box rebuild unless the current Candidate already authorizes the exact release +asset; an unvetted upstream release is reported but never advertised as applyable. +Broken version probes and incomplete Yazi, Helix, or Neovim output sets are +reported as repairs; a failed post-install verification restores prior managed +outputs. + + sqrbx-update # show available updates (dry run) + sqrbx-update --apply # update all installed registered tools + sqrbx-update lazygit # update, or explicitly install, one tool + sqrbx-update --list # list all tools and current versions + +Setup and `sqrbx-update` read GitHub release metadata through the GitHub API, +which allows only 60 unauthenticated requests per hour per IP address. On a +shared NAT or CI runner, authenticate those requests to avoid HTTP 403 rate +limits: export `GH_TOKEN` (or `GITHUB_TOKEN`), or run `gh auth login` inside +the Box. The token is optional, is sent only to the GitHub API, and a rejected +token falls back to unauthenticated requests. + +### Full rebuild (from the host) + + sqrbx-rebuild + +Resolves the requested published Release, pulls its immutable image digest, and +replaces the Box. Installations created with `--build` retain that choice and +build the matching source instead. +Your code in ~/squarebox/workspace is safe since it lives on the host. Most +in-container state (shell history, GitHub auth, SDK toolchains) survives +because /home/dev is backed by the `squarebox-home` named Docker volume. +Manually installed apt packages are still lost, since the image is rebuilt. + +#### What survives a rebuild + +| Survives | Reconciled or lost | +|----------|--------------------| +| Workspace code on the host | Selected tmux/Zsh/Fish packages are reconciled into the new Box | +| Managed home: history, auth, assistant data, mise toolchains | Manually installed, unselected APT packages are lost | +| Selection state in `/workspace/.squarebox` | Image-tier binaries are replaced by the Candidate digest | +| Host SSH access (agent forwarding, or the recorded `SQUAREBOX_MOUNT_SSH` opt-in) | Image-managed dotfiles are safely refreshed | + +Use `sqrbx-uninstall --purge` to wipe recorded state. Do not remove a volume by +name alone; lifecycle commands verify the Install identity and ownership +labels before deleting a Managed resource. + +> **Tip:** Use `sqrbx-update` from inside the container for Managed-home tools. +> Use `sqrbx-rebuild` for image-tier binaries, new APT packages, base-tool +> changes, or any upstream release the current Candidate cannot authorize. + +## Dev Containers and Codespaces + +Open this repo in VS Code with the +[Dev Containers extension](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers), +or launch it in [GitHub Codespaces](https://github.com/features/codespaces). +The included `.devcontainer/devcontainer.json` builds the full **squarebox** image +automatically and mounts the cloned repository at `/workspace`, matching setup +and Selection state. A per-Box named volume, derived from the stable +Dev Container identity, mounts at `/home/dev` so authentication, history, and +mise toolchains survive container rebuilds without being shared across +unrelated workspaces. + +The interactive first-run wizard can't run in devcontainer mode (no TTY at +create time), so a default toolset β€” **Claude Code + Node.js** β€” is installed +non-interactively by `postCreateCommand`. Override the defaults with these +container environment variables (set to an empty string to opt out of a tier): + +| Variable | Default | Selects | +|----------|---------|---------| +| `SQUAREBOX_DC_AI` | `claude` | AI assistants (`claude,copilot,gemini,codex,opencode,pi,omp`) | +| `SQUAREBOX_DC_SDKS` | `node` | SDKs (`node,python,go,dotnet,rust`) | +| `SQUAREBOX_DC_EDITORS` | _(none)_ | Editors (`micro,edit,fresh,helix,nvim`; Helix launches as `hx`) | +| `SQUAREBOX_DC_TUIS` | _(none)_ | TUI tools (`lazygit,gh-dash,yazi,elio`) | +| `SQUAREBOX_DC_MULTIPLEXERS` | _(none)_ | Multiplexers (`tmux,zellij,herdr`) | + +To add or change tools after the fact, run `sqrbx-setup` from the integrated +terminal. + +You can also attach to a running codespace directly from your local terminal +using `gh codespace ssh`. The official Dev Containers SSH server Feature is +version- and digest-locked for this path. It is added only to the derived Dev +Container image, not the published Squarebox Candidate, and remote-forwarded +ports remain bound to loopback by default. + +## Uninstall and recovery + +sqrbx-uninstall + +Removes the recorded Box, owned image reference, and shell integration but **keeps** +the install directory/Workspace and Managed-home volume +(shell history, gh auth, mise toolchains) so your code and per-user state are +safe by default. Pass `--purge` to remove the Managed home and recorded install +directory. The default Workspace nested inside that directory is removed with +it; a custom external Workspace is always preserved: + + sqrbx-uninstall --purge + +The confirmation summary lists a non-empty nested Workspace, with its item count, +as something that will be deleted, and a second confirmation is required. +Pass `-y` (or `-Yes` on PowerShell) to skip prompts for scripting. Unattended +purge refuses, before removing anything, to delete a non-empty nested +Workspace unless you also pass `--delete-workspace` (`-DeleteWorkspace` on +PowerShell): + + sqrbx-uninstall --purge --yes --delete-workspace + +An empty Workspace or an external Workspace needs no extra flag. +Idempotent for a valid Install identity. Legacy resources require `--adopt`; +purging an adopted, unlabeled volume additionally requires `--force`. + +**Windows (PowerShell 7+):** + + sqrbx-uninstall # keep ~/squarebox + sqrbx-uninstall -Purge # also remove ~/squarebox + sqrbx-uninstall -Yes # skip confirmations + sqrbx-uninstall -Purge -Yes -DeleteWorkspace # also delete a non-empty nested Workspace + +**Broken-state recovery** (e.g. shell functions are missing, or after partial +install): run the script matching the adapter that created the Install identity +directly from the install directory. PowerShell and Git Bash lifecycle state is +not cross-consumed: + + ~/squarebox/uninstall.sh # Linux / macOS / Git Bash + ~/squarebox/uninstall.ps1 # Windows PowerShell + +Start a new shell afterwards (or `exec bash` / `exec zsh`) so the `sqrbx` and +`squarebox` functions are dropped from the current session. diff --git a/tests/test-repository-consistency.sh b/tests/test-repository-consistency.sh index 394af8b..8690bc8 100755 --- a/tests/test-repository-consistency.sh +++ b/tests/test-repository-consistency.sh @@ -10,11 +10,11 @@ fail() { } if grep -E '(@githubnext/github-copilot-cli|github-copilot-cli)' \ - setup.sh README.md CLAUDE.md Dockerfile >/dev/null; then + setup.sh README.md docs/usage.md CLAUDE.md Dockerfile >/dev/null; then fail "production surfaces still reference deprecated Copilot CLI" fi -if grep -Eqi 'paseo' setup.sh README.md CLAUDE.md uat-checklist.md \ +if grep -Eqi 'paseo' setup.sh README.md docs/usage.md CLAUDE.md uat-checklist.md \ demo/setup-demo.sh scripts/squarebox-setup.sh scripts/e2e-test.sh; then fail "current product surfaces still reference removed Paseo support" fi @@ -98,14 +98,14 @@ grep -Fq 'uninstall.ps1' .github/workflows/e2e.yml \ || fail "PowerShell uninstaller is missing from release assets" grep -Fq 'release.json' .github/workflows/e2e.yml \ || fail "release identity is missing from publication" -grep -Fq 'env SQUAREBOX_AI=' README.md \ +grep -Fq 'env SQUAREBOX_AI=' docs/usage.md \ || fail "noninteractive installer example does not pass variables to Bash" -if grep -Eq '~370 MB|docker build.+reproducible' README.md SECURITY.md; then +if grep -Eq '~370 MB|docker build.+reproducible' README.md docs/usage.md SECURITY.md; then fail "stale image-size/reproducibility claim remains" fi -grep -Fq 'cross-adapter state consumption is rejected' README.md \ - || fail "README promises no Windows lifecycle-adapter boundary" +grep -Fq 'cross-adapter state consumption is rejected' docs/usage.md \ + || fail "usage reference promises no Windows lifecycle-adapter boundary" grep -Fq 'adapter may consume that state' CLAUDE.md \ || fail "agent guidance does not enforce adapter-native lifecycle state" grep -Fq 'are not cross-consumed' docs/releases/v1.1.0.md \ @@ -113,7 +113,7 @@ grep -Fq 'are not cross-consumed' docs/releases/v1.1.0.md \ grep -Fq 'does not claim `SSH_AUTH_SOCK` forwarding' uat-checklist.md \ || fail "PowerShell UAT still overclaims SSH-agent forwarding" if grep -Fq 'Bash and PowerShell lifecycle state must remain compatible' \ - README.md CLAUDE.md docs/releases/v1.1.0.md uat-checklist.md; then + README.md docs/usage.md CLAUDE.md docs/releases/v1.1.0.md uat-checklist.md; then fail "docs still promise unsupported cross-adapter lifecycle state" fi