--- url: /reference.md description: >- Complete reference for all SkyBox CLI commands. Manage containers, sync, remotes, projects, and configuration from the terminal. --- # Command Reference SkyBox provides a set of commands for managing your local-first development environments with remote sync. ## Commands Overview ::: tip Offline Reference All commands include built-in help with usage examples. Run `skybox --help` for the same information available on these pages. ::: ## Global Options All commands support these global options: ```bash -h, --help Show help for a command -v, --version Show SkyBox version --dry-run Preview commands without executing them ``` ### Dry-Run Mode The `--dry-run` flag previews what a command would do without executing any side effects (no SSH, Docker, filesystem writes, or sync operations). Each skipped action is printed with a `[dry-run]` prefix. ```bash # Preview starting a project skybox up my-project --dry-run # Preview removing a project and its remote copy skybox rm my-project --remote --dry-run # Preview cloning from remote skybox clone my-project --dry-run ``` Supported commands: `up`, `down`, `clone`, `push`, `rm`, `init`, `new`, `editor`, `config`, `config-devcontainer`, `remote`, `update`, `encrypt`, `open`, `shell`, `hook`. Read-only commands (`status`, `list`, `browse`, `logs`, `dashboard`, `doctor`) are unaffected since they have no side effects. ## Quick Reference ### Setup and Configuration ```bash # Initial setup skybox init # Diagnose common issues skybox doctor # View configuration skybox config # Test remote connections skybox config --validate # Change default editor skybox editor # Or via config skybox config set editor vim # Enable project encryption skybox encrypt enable my-app # Disable project encryption skybox encrypt disable my-app # Set up shell integration (auto-start containers on cd) eval "$(skybox hook bash)" # Add to ~/.bashrc eval "$(skybox hook zsh)" # Or add to ~/.zshrc ``` ### Managing Remote Servers ```bash # Add a new remote skybox remote add myserver user@host:~/code # List configured remotes skybox remote list # Remove a remote skybox remote remove myserver # Rename a remote skybox remote rename myserver production ``` ### Working with Projects ```bash # Start working on a project skybox up my-project # Stop a project skybox down my-project # Open editor/shell for running container skybox open my-project # Access shell inside container skybox shell my-project # Run a command in container skybox shell my-project -c "npm test" # Check project status skybox status my-project ``` ### Syncing with Remote ```bash # See what's on the remote server skybox browse # Clone a project from remote skybox clone my-project # Push a local project to remote skybox push ./my-project # Create a new project on remote skybox new ``` ### Diagnostics & Maintenance ```bash # Show container logs skybox logs my-project -f # Show sync logs skybox logs my-project --sync # Diagnose common issues skybox doctor # Check for and install updates skybox update ``` ### Batch Operations ```bash # Start all projects skybox up --all # Stop all projects skybox down --all # Remove multiple projects (interactive multi-select) skybox rm ``` ### Cleanup ```bash # Remove a project locally (remote copy preserved) skybox rm my-project ``` --- --- url: /reference/configuration.md description: >- SkyBox YAML configuration file reference. Configure remotes, sync modes, ignore patterns, editors, and project-specific settings. --- # Configuration Reference SkyBox uses a YAML configuration file to store global settings, remote server connections, sync preferences, and project-specific configurations. ## Config File Location The configuration file is located at: ``` ~/.skybox/config.yaml ``` You can override the SkyBox home directory by setting the `SKYBOX_HOME` environment variable: ```bash export SKYBOX_HOME=/custom/path/.skybox ``` When set, the config file will be located at `$SKYBOX_HOME/config.yaml`. ## Directory Structure SkyBox creates the following directory structure: ``` ~/.skybox/ ├── config.yaml # Main configuration file ├── .update-check.json # Update check cache (24h TTL) ├── audit.log # Audit log (when SKYBOX_AUDIT=1) ├── Projects/ # Local synced project copies │ ├── my-app/ │ └── backend/ ├── bin/ │ ├── mutagen # Auto-downloaded sync binary │ └── mutagen-agents.tar.gz # Mutagen agents archive ├── templates/ # Custom local devcontainer templates └── logs/ # Log files (auto-up, etc.) ``` ## Configuration Schema The configuration file has four main sections: ### `remotes` A map of named remote server configurations. Each remote represents a server where projects can be stored and synced. | Field | Type | Required | Description | |-------|------|----------|-------------| | `host` | `string` | Yes | SSH hostname or IP address | | `user` | `string` | No | SSH username (null to use SSH config default) | | `path` | `string` | Yes | Base directory for projects on the remote | | `key` | `string` | No | Path to SSH private key (null to use SSH config default) | | `useKeychain` | `boolean` | No | macOS only: persist SSH key passphrase in Keychain (default: `false`) | The `useKeychain` field is optional and defaults to `false`. When set to `true` on macOS, SkyBox uses the Keychain to store the passphrase for the SSH key, so you don't need to re-enter it after reboots. This setting is ignored on Linux and has no effect on passwordless keys. Example: ```yaml remotes: production: host: prod.example.com user: deploy path: ~/code key: ~/.ssh/id_ed25519 useKeychain: true # macOS only: persist passphrase in Keychain personal: host: home-server user: null # Uses SSH config path: ~/projects key: null # Uses SSH config ``` ### `editor` | Option | Type | Default | Description | |--------|------|---------|-------------| | `editor` | `string` | - | Command to launch your preferred editor | Supported editors: | Editor | Command | |--------|---------| | Cursor | `cursor` | | VS Code | `code` | | VS Code Insiders | `code-insiders` | | Zed | `zed` | | Other | custom command | Vim (`vim`), Neovim (`nvim`), and any custom editor command are also supported. ### `defaults` Default settings for file synchronization. | Option | Type | Default | Description | |--------|------|---------|-------------| | `sync_mode` | `string` | `"two-way-resolved"` | Mutagen sync mode for file synchronization | | `ignore` | `string[]` | See below | Default patterns to ignore during sync | | `encryption` | `boolean` | `false` | Enable encryption by default for new projects | | `auto_up` | `boolean` | `false` | Auto-start containers when entering project directories (see [Shell Integration](/guide/shell-integration)) | #### Default Ignore Patterns The following patterns are ignored by default: ```yaml ignore: - ".git/index.lock" - ".git/*.lock" - ".git/hooks/*" - "node_modules" - "venv" - ".venv" - "__pycache__" - "*.pyc" - ".skybox-local" - "dist" - "build" - ".next" - "target" - "vendor" ``` #### Sync Modes The `sync_mode` option accepts Mutagen sync mode values: | Mode | Description | |------|-------------| | `two-way-resolved` | Bidirectional sync with automatic conflict resolution (recommended) | | `two-way-safe` | Bidirectional sync that flags conflicts for manual resolution | | `one-way-replica` | One-way sync that mirrors alpha exactly on beta | ### `projects` A map of project names to project-specific configurations. Each project references a remote by name. | Option | Type | Required | Description | |--------|------|----------|-------------| | `remote` | `string` | Yes | Name of the remote this project belongs to | | `ignore` | `string[]` | No | Additional ignore patterns for this project | | `editor` | `string` | No | Override editor for this project | | `sync_paths` | `string[]` | No | Selective sync: only sync these subdirectories instead of the entire project | | `encryption` | `object` | No | Per-project encryption config (see below) | | `hooks` | `object` | No | Lifecycle hooks: shell commands to run before/after `up` and `down` (see [Hooks](/reference/hooks)) | | `auto_up` | `boolean` | No | Auto-start container when entering this project's directory (see [Shell Integration](/guide/shell-integration)) | Example: ```yaml projects: my-web-app: remote: production ignore: - ".cache" - "coverage" editor: code backend-api: remote: production ignore: - "*.log" - "tmp" side-project: remote: personal editor: nvim large-monorepo: remote: production sync_paths: - src - build ``` #### Per-Project Encryption Projects can have encryption at rest enabled. When enabled, project files are encrypted on the remote when not in active use. ```yaml projects: my-app: remote: production encryption: enabled: true salt: "a1b2c3d4e5f6..." kdf: "scrypt" kdfParamsVersion: 1 ``` | Field | Type | Description | |-------|------|-------------| | `enabled` | `boolean` | Whether encryption at rest is active | | `salt` | `string` | Auto-generated hex salt for key derivation. Do not edit. | | `kdf` | `"scrypt"` | Key-derivation function used for passphrase-to-key derivation. | | `kdfParamsVersion` | `1` | Parameter profile version for the configured KDF. | Use `skybox encrypt enable/disable` to manage these settings. See [`skybox encrypt`](/reference/encryption). ### `templates` (Optional) Custom project templates as git repository URLs. These templates appear in `skybox new` when selecting "From a template". ```yaml templates: company-starter: https://github.com/myorg/starter-template.git react-app: https://github.com/myorg/react-template.git ``` ::: tip You can also create local templates stored as `.json` files in `~/.skybox/templates/`. See [Custom Templates](/reference/custom-templates) for details. ::: ## Complete Example Here is a complete example configuration file: ```yaml # Default editor command editor: cursor # Default sync settings defaults: sync_mode: two-way-resolved # Default ignore patterns (see above for details) ignore: - ".git/index.lock" - ".git/*.lock" - ".git/hooks/*" - "node_modules" - "venv" - ".venv" - "__pycache__" - "*.pyc" - ".skybox-local" - "dist" - "build" - ".next" - "target" - "vendor" # Remote server configurations remotes: production: host: prod.example.com user: deploy path: ~/code key: ~/.ssh/id_ed25519 useKeychain: true # macOS only: persist passphrase in Keychain staging: host: staging.example.com user: deploy path: ~/code key: ~/.ssh/id_ed25519 personal: host: home-server user: null path: ~/projects key: null # Project-specific configurations projects: my-web-app: remote: production ignore: - ".cache" - "coverage" editor: code backend-api: remote: production ignore: - "*.log" - "tmp" data-pipeline: remote: staging editor: nvim ignore: - "data/*.csv" - "output" side-project: remote: personal large-monorepo: remote: production sync_paths: - src - build # Custom project templates templates: company-starter: https://github.com/myorg/starter.git react-app: https://github.com/myorg/react-template.git ``` ## Environment Variables **Runtime Configuration** | Variable | Default | Description | |----------|---------|-------------| | `SKYBOX_HOME` | `~/.skybox` | Override the default SkyBox home directory | | `SKYBOX_AUDIT` | `0` | Set to `1` to enable audit logging to `~/.skybox/audit.log` | | `SKYBOX_HOOK_WARNINGS` | `1` | Set to `0` to suppress one-time hook security warnings | | `HOME` | - | Used for `~` expansion in paths (e.g., remote `path` and `key` fields) | | `DEBUG` | unset | Set to any value to enable debug output in list command | | `EDITOR` | - | Fallback editor command if not configured in SkyBox config | **Build-Time Metadata** (not user-configurable — set during compilation) | Variable | Default | Description | |----------|---------|-------------| | `SKYBOX_INSTALL_METHOD` | unset | Install source metadata (`homebrew` or `github-release` for direct download) | ### Audit Logging When `SKYBOX_AUDIT=1`, security-relevant operations are logged to `~/.skybox/audit.log` in JSON Lines format: ```json {"timestamp":"2026-02-04T12:00:00Z","action":"clone:success","user":"john","machine":"macbook","details":{"project":"myapp"}} ``` Logged actions include: `clone:start`, `clone:success`, `clone:fail`, `push:start`, `push:success`, `push:fail`, `rm:local`, `rm:remote`, `up:start`, `up:success`, `down`, `lock:force`, `config:change`. #### Log Sanitization Audit log entries are automatically sanitized before being written: * **Home directory paths** are replaced with `~` (e.g., `/Users/john/code` becomes `~/code`) * **Credentials** matching `password=...` or `token=...` patterns are redacted #### Log Rotation The audit log is automatically rotated when it exceeds **10 MB**. When rotation occurs, the current log is renamed to `audit.log.YYYY-MM-DD` and a new log file is started. ::: tip Manual Rotation You can also rotate the log manually at any time: ```bash mv ~/.skybox/audit.log ~/.skybox/audit.log.$(date +%Y%m%d) ``` ::: ## Creating Configuration The configuration file is automatically created when you run: ```bash skybox init ``` This interactive command will: 1. Check for required dependencies (Docker, Node.js) 2. Download and install Mutagen for file synchronization 3. Configure your first remote SSH server 4. Set your preferred editor 5. Create the configuration file ## Modifying Configuration ### Using SkyBox Commands ```bash # View current configuration skybox config # Change editor skybox config set editor vim # Add a new remote skybox remote add myserver user@host:~/code # Remove a remote skybox remote remove myserver # Validate all remote connections skybox config --validate ``` ### Direct File Editing You can edit the configuration file directly: ```bash # Open with your default editor $EDITOR ~/.skybox/config.yaml # Or use any text editor nano ~/.skybox/config.yaml vim ~/.skybox/config.yaml ``` Changes take effect immediately for new commands. Running containers or sync sessions may need to be restarted to pick up configuration changes. ## Per-Project Overrides Projects can override global settings: ```yaml projects: my-project: remote: production # Use a different editor for this project editor: nvim # Additional ignore patterns (merged with defaults) ignore: - "local-only/" - "*.local" # Selective sync: only sync specific subdirectories sync_paths: - src - config ``` ## Validation SkyBox validates the configuration file on load. Common issues include: * **Missing remotes section**: At least one remote must be configured * **Invalid project remote reference**: Project references a non-existent remote * **Invalid YAML syntax**: Check for proper indentation and formatting * **Invalid sync mode**: Use one of the supported Mutagen sync modes If the configuration is invalid, SkyBox commands will fail with an error message indicating the issue. ## Migration from Old Format If you have an older configuration with a single `remote` section (instead of `remotes`), SkyBox will automatically migrate it on first use: **Old format:** ```yaml remote: host: my-server base_path: ~/code ``` **New format (auto-migrated):** ```yaml remotes: my-server: # Name derived from host host: my-server user: null path: ~/code key: null projects: existing-project: remote: my-server # Updated to reference new remote name ``` The migration happens automatically and preserves all your existing projects. ## See Also * [`skybox config`](/reference/config) - View and modify configuration via CLI * [`skybox remote`](/reference/remote) - Manage remote server connections * [Custom Templates](/reference/custom-templates) - Create reusable devcontainer templates * [`skybox hook`](/reference/hook) - Shell hook for auto-starting containers on `cd` --- --- url: /guide/concepts.md description: >- Understand SkyBox projects, containers, bidirectional sync via Mutagen, remote server architecture, and session-based multi-machine coordination. --- # Core Concepts This page explains the key concepts behind SkyBox: how projects, containers, sync, and the remote server work together. **On this page:** [Projects](#projects) | [Containers](#containers) | [Sync](#sync) | [Templates](#templates) | [Encryption](#encryption) | [Shell Integration](#shell-integration) | [Remote Server](#remote-server) | [Non-interactive Mode](#non-interactive-mode) | [Configuration](#configuration) ## Projects A **project** in SkyBox is a directory containing your source code, managed as a unit. Projects are: * Stored locally in `~/.skybox/Projects//` * Synced to your remote server at `//` * Registered in the SkyBox configuration ### Project Structure ```text ~/.skybox/Projects/my-app/ ├── .devcontainer/ │ └── devcontainer.json # Container configuration ├── .git/ # Git repository ├── .gitignore # Includes .skybox/* (auto-managed) ├── src/ # Your source code ├── package.json └── ... ``` ### Project Lifecycle ```text push/clone up down rm │ │ │ │ ▼ ▼ ▼ ▼ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ │Registered│───►│ Running │───►│ Stopped │───►│ Removed │ └─────────┘ └─────────┘ └─────────┘ └─────────┘ ``` 1. **Registered** - Project exists locally with sync configured 2. **Running** - Container is active, ready for development 3. **Stopped** - Container stopped, project still registered 4. **Removed** - Local files deleted (remote copy preserved) ## Containers SkyBox uses **[devcontainers](https://containers.dev/)** - Docker containers configured for development using the open [Development Containers specification](https://containers.dev/implementors/spec/). They provide: * Isolated development environment * Pre-installed tools and dependencies via [devcontainer features](https://containers.dev/features) * Consistent setup across machines * Editor integration (VS Code, Cursor) ### Devcontainer Configuration Each project can have a `.devcontainer/devcontainer.json` file: ```json { "name": "My App", "image": "mcr.microsoft.com/devcontainers/base:debian", "features": { "ghcr.io/devcontainers/features/node:1": {}, "ghcr.io/devcontainers/features/git:1": {} }, "customizations": { "vscode": { "extensions": ["dbaeumer.vscode-eslint"] } }, "postCreateCommand": "npm install" } ``` If no devcontainer configuration exists, SkyBox offers templates during `skybox up`. ### Container States | State | Description | |-------|-------------| | Running | Container is active and accepting connections | | Stopped | Container exists but is not running | | Not Found | No container exists for this project | ### Container vs Project It's important to understand the distinction: * **Project** = Your code files and configuration * **Container** = The running Docker environment You can: * Stop a container while keeping the project * Remove and recreate a container without losing code * Have a project without ever starting a container ## Sync SkyBox uses **Mutagen** for bidirectional file synchronization between your local machine and remote server. ### How Sync Works ```text Local Machine Remote Server ~/.skybox/Projects/my-app/ ~/code/my-app/ ├── src/index.js ◄────► ├── src/index.js ├── package.json ◄────► ├── package.json └── ... └── ... ``` * Changes on either side are synced to the other * Sync happens continuously in the background * Conflicts are resolved automatically (local changes win) ### Sync Modes SkyBox uses `two-way-resolved` sync mode: * Both local and remote can be modified * If both sides change the same file, local wins * Ensures you never lose local work ### Ignored Files By default, SkyBox excludes certain files from sync: ```yaml ignore: - ".git/index.lock" - ".git/*.lock" - ".git/hooks/*" - "node_modules" - "venv" - ".venv" - "__pycache__" - "*.pyc" - ".skybox-local" - "dist" - "build" - ".next" - "target" - "vendor" ``` These patterns prevent syncing: * Lock files that cause conflicts * Large dependency directories * Build artifacts ### Sync States | State | Description | |-------|-------------| | Syncing | Active, transferring changes | | Paused | Sync session exists but is paused | | No Session | No sync configured for this project | | Error | Sync encountered a problem | ### Managing Sync Sync is managed automatically by SkyBox: * **Created** when you `push` or `clone` a project * **Resumed** when you run `skybox up` * **Paused** when you run `skybox down` * **Terminated** when you run `skybox rm` ### Selective Sync For large monorepos or projects where you only need a subset of directories, SkyBox supports **selective sync**. Instead of syncing the entire project, you specify which subdirectories to sync, and SkyBox creates a separate Mutagen session for each path. This is useful when: * Your repository is too large to sync entirely * You only work on specific packages in a monorepo * You want to reduce bandwidth and disk usage Configure selective sync per project: ```bash skybox config sync-paths my-app packages/frontend,packages/shared,configs ``` Each listed path gets its own independent Mutagen session (e.g., `skybox-my-app-packages-frontend`), syncing only that subdirectory between local and remote. All sessions use the same sync mode and ignore patterns as full sync. ## Templates SkyBox uses a shared template selector whenever a devcontainer configuration is needed — during `skybox up`, `skybox new`, or `skybox config devcontainer reset`. When git templates are enabled (for example, in `skybox new`), the selector shows three categories: * **Built-in templates** — pre-configured environments for common languages * **Your custom templates** — local devcontainer.json files you create and manage * **Git URLs** — clone a repository as a project template (supported in `skybox new`) ### Built-in Templates | Template | Feature | Version | Post-Create Command | |----------|---------|---------|---------------------| | **Node.js** | [node](https://github.com/devcontainers/features/tree/main/src/node) | latest | `npm install` (if `package.json` exists) | | **Bun** | [bun](https://github.com/shyim/devcontainers-features/tree/main/src/bun) | latest | `bun install` (if `package.json` exists) | | **Python** | [python](https://github.com/devcontainers/features/tree/main/src/python) | latest | `pip install -r requirements.txt` (if exists) | | **Go** | [go](https://github.com/devcontainers/features/tree/main/src/go) | latest | `go mod download` (if `go.mod` exists) | | **Generic** | [common-utils](https://github.com/devcontainers/features/tree/main/src/common-utils) only | — | None | All templates use `mcr.microsoft.com/devcontainers/base:debian` as the base image with language-specific [devcontainer features](https://containers.dev/features) layered on top. This ensures you always get the latest versions without manual updates. All templates include these common features: * **[common-utils](https://github.com/devcontainers/features/tree/main/src/common-utils)** -- zsh (default shell), oh-my-zsh, and essential utilities * **[docker-outside-of-docker](https://github.com/devcontainers/features/tree/main/src/docker-outside-of-docker)** -- access the host Docker daemon from inside the container * **[git](https://github.com/devcontainers/features/tree/main/src/git)** -- pre-installed for version control * **SSH passthrough** -- your host `~/.ssh` directory is bind-mounted read-only, so container Git operations use your existing SSH keys ### Custom Local Templates You can store reusable devcontainer configurations as `.json` files in `~/.skybox/templates/`. The filename (minus `.json`) becomes the display name in the template selector. ``` ~/.skybox/templates/ ├── bun.json # Appears as "bun" ├── rust.json # Appears as "rust" └── company-stack.json # Appears as "company-stack" ``` Each file is a complete `devcontainer.json`. You can create templates through the CLI (select "Create new template" in the selector) or by manually placing files in the directory. For full details on creating, validating, and managing custom templates, see [Custom Templates Reference](/reference/custom-templates). ## Encryption SkyBox supports **per-project encryption at rest** using **AES-256-GCM** authenticated encryption with **scrypt** key derivation (`N=65536`, `r=8`, `p=1`, `maxmem=128 MiB`). ### How It Works When encryption is enabled for a project, its files are stored as an encrypted `.tar.enc` archive on the remote server when not in use. This protects your code at rest on the remote. The encrypted payload uses an initialization vector (16 bytes), authentication tag (16 bytes), and the encrypted data, all concatenated and base64-encoded. ### Enabling Encryption ```bash skybox encrypt enable ``` You will be prompted to set a passphrase. This passphrase is used to derive the encryption key via scrypt. ::: warning **Your passphrase cannot be recovered if forgotten.** There is no reset mechanism. If you lose your passphrase, your encrypted project data CANNOT be recovered. ::: ### What Is Protected Encryption protects your project files at rest on the remote server. It does not encrypt sync traffic (sync traffic is protected by SSH) or your local `config.yaml`. For command details, see [`skybox encrypt`](/reference/encryption). ## Shell Integration SkyBox can auto-start containers when you `cd` into a project directory. See [Shell Integration](/guide/shell-integration) for setup. ## Remote Server The **remote server** stores your project backups and enables multi-machine workflows. SkyBox supports **multiple remotes**, allowing you to organize projects across different servers (e.g., work server, personal server). ### Server Setup During `skybox init`, you configure your first remote. You can add more remotes later with [`skybox remote`](/reference/remote). For each remote, you specify: * **Name** - A friendly identifier (e.g., "production", "personal") * **SSH Host** - The server to connect to * **SSH User** - Username for SSH connection * **Base Path** - Directory where projects are stored (e.g., `~/code`) * **SSH Key** - Optional path to SSH private key (both passwordless and passphrase-protected keys are supported) SkyBox supports passphrase-protected SSH keys via `ssh-agent` integration. When a passphrase-protected key is used, SkyBox loads it into `ssh-agent` so you only enter the passphrase once. On macOS, passphrases can optionally be persisted in the Keychain by setting `useKeychain: true` in the remote configuration. ### Remote Directory Structure ``` ~/code/ # Base path ├── my-app/ # Project directories │ ├── .skybox/ │ │ └── state.lock # State file (ownership + session, synced via Mutagen) │ ├── src/ │ └── ... └── other-project/ └── ... ``` ### Session System SkyBox uses a **session system** to prevent conflicts when working from multiple machines. Sessions are local files stored inside each project that sync to other machines via Mutagen. When you run `skybox up`: 1. SkyBox checks for an existing session file in the project's `.skybox/` directory 2. If no session exists, creates one with your machine info 3. If a session exists from the same machine, updates the timestamp 4. If a session exists from a different machine, warns and asks to continue Session file format (stored as JSON): ```json { "ownership": { "owner": "alice", "created": "2026-02-04T09:00:00Z", "machine": "macbook-pro" }, "session": { "machine": "macbook-pro", "user": "alice", "timestamp": "2026-02-04T10:00:00Z", "pid": 12345, "expires": "2026-02-05T10:00:00Z", "hash": "7b9e4c5af2c48b3c1e7d9a0c4d0f3e6a9b8c2d1f4e7a6b5c3d2e1f0a9b8c7d6" } } ``` ### Session States | State | Description | |-------|-------------| | None | No active session for this project | | Active here | Your current machine has the session | | Active on other | Another machine has the session | ### How Session Sync Works Session data lives inside the project directory at `/.skybox/state.lock` (in the `session` section). Because Mutagen syncs project files bidirectionally, the state file is automatically visible on all machines syncing the same project. This means no SSH round-trip is needed to check session status. ### Session Conflicts If another machine has an active session: ``` This project is running on 'work-laptop' (started 4 days ago) ? Continue anyway? (y/N) ``` Continuing is safe when: * You know the other machine isn't actively editing * The other machine is unreachable * You want to work from this machine instead ### Session Integrity Session lock files are protected with HMAC-SHA256 integrity checking to detect tampering. If a session file has been modified outside of SkyBox, it is treated as invalid. ### Session Expiry Sessions automatically expire after 24 hours. If a machine crashes without running `skybox down`, the session becomes stale and is treated as inactive. No manual intervention is needed. ### Project Ownership SkyBox tracks **project ownership** on the remote server to prevent accidental overwrites and deletions by other users. When you push a project, ownership is recorded in `.skybox/state.lock` (in the `ownership` section) on the remote, storing your username and machine. Ownership is checked when: * **Pushing** to an existing remote project — only the owner can overwrite * **Deleting** a remote project with `skybox rm --remote` — only the owner can delete If you are not the owner, the operation is blocked with a message identifying the current owner. Projects without an ownership file (created before this feature) are accessible to anyone, and ownership is set on the next push. ::: info Ownership uses your local OS username (`whoami`), not the SSH remote user. This means ownership is consistent for you across machines as long as your local username is the same. ::: ### Force Bypass You can bypass the session check entirely when opening a shell: ```bash skybox shell --force my-app ``` This skips session verification and opens the container shell directly. ## Non-interactive Mode For scripting and CI pipelines, SkyBox supports a `--no-prompt` flag on commands that would normally prompt for user input: ```bash skybox up --no-prompt my-app skybox down --no-prompt my-app skybox open --no-prompt my-app ``` When `--no-prompt` is set, SkyBox will **error instead of prompting**. For example, if a session is active on another machine, the command will exit with an error rather than asking whether to continue. This makes SkyBox safe to use in automated workflows where no human is available to respond to prompts. ## Configuration SkyBox stores its configuration in `~/.skybox/config.yaml`: ```yaml editor: cursor # Default editor defaults: sync_mode: two-way-resolved ignore: - node_modules - .git/*.lock # ... more patterns remotes: # Multiple remote servers production: host: prod.example.com user: deploy path: ~/code key: ~/.ssh/id_ed25519 personal: host: home-server user: null # Uses SSH config path: ~/projects key: null projects: my-app: remote: production # Which remote this project belongs to other-project: remote: personal editor: code # Per-project overrides ``` ### Environment Variables **Runtime Configuration** | Variable | Default | Description | |----------|---------|-------------| | `SKYBOX_HOME` | `~/.skybox` | Override the default SkyBox home directory | | `SKYBOX_AUDIT` | `0` | Set to `1` to enable audit logging to `~/.skybox/audit.log` | | `SKYBOX_HOOK_WARNINGS` | `1` | Set to `0` to suppress one-time hook security warnings | | `HOME` | - | Used for `~` expansion in paths (e.g., remote `path` and `key` fields) | | `DEBUG` | unset | Set to any value to enable debug output in list command | | `EDITOR` | - | Fallback editor command if not configured in SkyBox config | **Build-Time Metadata** (not user-configurable — set during compilation) | Variable | Default | Description | |----------|---------|-------------| | `SKYBOX_INSTALL_METHOD` | unset | Install source metadata (`homebrew` or `github-release` for direct download) | ## Architecture Summary ```text ┌─────────────────────────────────────────────────────────────┐ │ Your Machine │ │ │ │ ┌──────────────────────────────────────────────────────┐ │ │ │ ~/.skybox/ │ │ │ │ ├── config.yaml Configuration │ │ │ │ ├── bin/mutagen Sync tool (bundled) │ │ │ │ └── projects/ │ │ │ │ └── my-app/ Your code ◄───────────┐ │ │ │ └──────────────────────────────────────────────│───────┘ │ │ │ │ │ ┌────────────────────┐ │ │ │ │ Docker Container │◄── Mounts project ──────┘ │ │ │ (devcontainer) │ │ │ └────────────────────┘ │ │ │ └──────────────────────────────────────────────────────────────┘ │ │ Mutagen Sync (SSH) │ ▼ ┌─────────────────────────────────────────────────────────────┐ │ Remote Server │ │ │ │ ~/code/ │ │ └── my-app/ Synced project files │ │ └── .skybox/ │ │ └── state.lock State file │ │ │ └─────────────────────────────────────────────────────────────┘ ``` ## Next Steps * See the [Command Reference](/reference/) for detailed command documentation * [Daily Development](/guide/workflows/daily-development) - Day-to-day workflow patterns * [New Project Setup](/guide/workflows/new-project) - Creating and pushing projects * [Multi-Machine Workflow](/guide/workflows/multi-machine) - Working across multiple machines --- --- url: /guide/workflows/new-project.md description: >- Create new SkyBox projects from scratch or bring an existing codebase. Push local code to remote servers and scaffold devcontainer configs. --- # Creating a New Project This guide walks through creating projects with SkyBox, whether starting from scratch or bringing an existing codebase. ## Prerequisites Before creating projects, ensure SkyBox is configured: ```bash skybox init ``` This sets up your remote server connection and preferred editor. ## Option 1: Push an Existing Project The most common workflow is pushing a local project to SkyBox for containerized development. ### Step 1: Push Your Project ```bash skybox push ./my-project ``` Or specify a custom name: ```bash skybox push ./my-project my-app ``` ### Step 2: What Happens 1. **Git Check** - SkyBox verifies the project is a git repository (offers to initialize if not) 2. **Remote Creation** - Creates the project directory on your remote server 3. **Local Copy** - Copies files to `~/.skybox/Projects/` 4. **Sync Setup** - Establishes two-way sync with Mutagen 5. **Initial Sync** - Waits for all files to sync to remote ### Step 3: Start Development After push completes, start the container: ```bash skybox up my-project ``` ## Option 2: Clone from Remote If a project already exists on your remote server (perhaps pushed from another machine), clone it locally. ### Step 1: Browse Available Projects ```bash skybox browse ``` This shows all projects in your remote code directory: ``` Remote projects (myserver:~/code): backend-api Branch: main frontend-app Branch: feature/auth ``` ### Step 2: Clone the Project ```bash skybox clone backend-api ``` ### Step 3: What Happens 1. **Remote Check** - Verifies the project exists on remote 2. **Local Directory** - Creates `~/.skybox/Projects/backend-api` 3. **[Sync](/guide/concepts#sync) Session** - Creates Mutagen sync session 4. **Initial Sync** - Downloads all files from remote 5. **Optional Start** - Prompts to start the dev container ## Option 3: Create a New Project with `skybox new` The `skybox new` command creates a project on the remote server from scratch, with full template selection: ```bash skybox new ``` SkyBox walks you through the full setup: 1. **Creates the project** on the remote server 2. **Prompts for template selection** (see below) 3. **Generates devcontainer configuration** 4. **Sets up sync** and optionally starts the container This is the recommended way to start a brand new project. ## Option 4: Start from a Template (Existing Directory) When pushing a project that has no `devcontainer.json`, SkyBox automatically offers template selection during `skybox up`. ### Step 1: Create Project Directory ```bash mkdir ~/code/new-app cd ~/code/new-app git init ``` ### Step 2: Push to SkyBox ```bash skybox push . ``` ### Step 3: Start and Select Template ```bash skybox up new-app ``` SkyBox detects no `devcontainer.json` and offers templates: ``` ? Select a template: ── Built-in ── Node.js — Node (latest) with npm/yarn + Common Utils + Docker Bun — Bun (latest) + Common Utils + Docker Python — Python (latest) with pip/venv + Common Utils + Docker Go — Go (latest) + Common Utils + Docker Generic — Debian with Common Utils + Docker ── Your Templates ── Create new template ``` ### Available Templates | Template | Base Image | Includes | |----------|-----------|----------| | **Node.js** | Debian + Node feature | Node.js (latest), npm/yarn, zsh, Docker, Git, SSH passthrough, ESLint extension | | **Bun** | Debian + Bun feature | Bun runtime, zsh, Docker, Git, SSH passthrough, Bun VS Code extension | | **Python** | Debian + Python feature | Python (latest), pip, venv, zsh, Docker, Git, SSH passthrough, Python extension | | **Go** | Debian + Go feature | Go (latest), Go tools, zsh, Docker, Git, SSH passthrough, Go extension | | **Generic** | Debian | zsh, Docker, Git, SSH passthrough | You can also use a **custom template** by providing a git URL. In the template selector, choose "Enter git URL" under the "Other" section: ``` ? Select a template: ── Built-in ── Node.js — Node (latest) with npm/yarn + Common Utils + Docker Bun — Bun (latest) + Common Utils + Docker Python — Python (latest) with pip/venv + Common Utils + Docker Go — Go (latest) + Common Utils + Docker Generic — Debian with Common Utils + Docker ── Other ── Enter git URL ── Your Templates ── Create new template ``` When selecting "Enter git URL", provide a git repository URL: ``` ? Git repository URL: https://github.com/my-org/custom-devcontainer.git ``` All built-in templates include these common features: * **[common-utils](https://github.com/devcontainers/features/tree/main/src/common-utils)** -- zsh (default shell), oh-my-zsh, and essential utilities * **[docker-outside-of-docker](https://github.com/devcontainers/features/tree/main/src/docker-outside-of-docker)** -- access the host Docker daemon from inside the container * **[git](https://github.com/devcontainers/features/tree/main/src/git)** -- pre-installed for version control * **SSH passthrough** -- your host `~/.ssh` directory is bind-mounted read-only, so container Git operations use your existing SSH keys ### Step 4: Template Creates Configuration SkyBox creates `.devcontainer/devcontainer.json`: ```json { "name": "Node.js", "image": "mcr.microsoft.com/devcontainers/base:debian", "workspaceFolder": "/workspaces/new-app", "features": { "ghcr.io/devcontainers/features/node:1": {}, "ghcr.io/devcontainers/features/docker-outside-of-docker:1": {}, "ghcr.io/devcontainers/features/git:1": {} }, "customizations": { "vscode": { "extensions": ["dbaeumer.vscode-eslint"] } } } ``` This configuration is automatically committed to git. ## Customizing devcontainer.json After SkyBox creates the initial configuration, you can customize it: ### Add More Extensions ```json { "customizations": { "vscode": { "extensions": [ "dbaeumer.vscode-eslint", "esbenp.prettier-vscode", "bradlc.vscode-tailwindcss" ] } } } ``` ### Add Environment Variables ```json { "containerEnv": { "NODE_ENV": "development", "DATABASE_URL": "postgres://localhost:5432/mydb" } } ``` ### Add Services with Docker Compose For more complex setups (databases, caches), create `.devcontainer/docker-compose.yml`: ```yaml services: app: build: context: . dockerfile: Dockerfile volumes: - ..:/workspaces/my-app:cached db: image: postgres:15 environment: POSTGRES_PASSWORD: dev ``` Update `devcontainer.json`: ```json { "dockerComposeFile": "docker-compose.yml", "service": "app", "workspaceFolder": "/workspaces/my-app" } ``` ## Project Structure After Setup After creating a project, your file structure looks like: ``` ~/.skybox/ Projects/ my-project/ # Local synced copy .devcontainer/ devcontainer.json .git/ src/ package.json Remote (your-server:~/code/): my-project/ # Remote backup copy .devcontainer/ devcontainer.json .git/ src/ package.json ``` ## Verifying Setup Check your project status: ```bash skybox status my-project ``` Output shows: ``` Project: my-project ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ Container Status: running Image: mcr.microsoft.com/devcontainers/base:debian Uptime: 2 hours CPU: 0.5% Memory: 256M / 4G Sync Status: syncing Session: skybox-my-project Pending: 0 files Last sync: - Git Branch: main Status: clean Ahead: 0 commits Behind: 0 commits Session Status: active here Machine: my-laptop User: me Started: 2 hours ago PID: 12345 Disk Usage Local: 45M Remote: 44M ``` ## Related Commands | Command | Usage in this workflow | |---------|----------------------| | [`skybox push`](/reference/push) | Push a local project to remote | | [`skybox clone`](/reference/clone) | Clone a remote project locally | | [`skybox new`](/reference/new) | Create a new project from scratch | | [`skybox browse`](/reference/browse) | List available remote projects | | [`skybox up`](/reference/up) | Start the dev container | | [`skybox status`](/reference/status) | Verify project setup | | [`skybox init`](/reference/init) | Initial SkyBox setup | ## Next Steps * [Daily Development](/guide/workflows/daily-development) - Learn the day-to-day workflow * [Multi-Machine Workflow](/guide/workflows/multi-machine) - Working across multiple computers --- --- url: /reference/custom-templates.md description: >- Create and manage reusable devcontainer templates in SkyBox. Store templates locally for consistent container configurations across projects. --- # Custom Templates Create and manage reusable devcontainer templates stored locally on your machine. ## Overview Custom templates are `.json` files stored in `~/.skybox/templates/`. Each file is a complete `devcontainer.json` that can be selected whenever SkyBox needs a devcontainer configuration — during `skybox up`, `skybox new`, or `skybox config devcontainer reset`. ## Template Storage | Property | Value | |----------|-------| | Location | `~/.skybox/templates/.json` | | Format | Standard devcontainer.json | | Display name | Filename without `.json` extension | **Example:** `~/.skybox/templates/bun.json` appears as "bun" in the template selector. The templates directory is created automatically the first time you create a template through the CLI. ## Built-In Templates SkyBox ships with built-in templates that are always available in the template selector, even if you have no local custom templates: | Template | Base Image | Includes | |----------|-----------|----------| | **Node.js** | Debian + Node feature | Node.js (latest), npm/yarn, zsh, Docker, Git, SSH passthrough, ESLint extension | | **Bun** | Debian + Bun feature | Bun runtime, zsh, Docker, Git, SSH passthrough, Bun VS Code extension | | **Python** | Debian + Python feature | Python (latest), pip, venv, zsh, Docker, Git, SSH passthrough, Python extension | | **Go** | Debian + Go feature | Go (latest), Go tools, zsh, Docker, Git, SSH passthrough, Go extension | | **Generic** | Debian | zsh, Docker, Git, SSH passthrough | These built-ins include the same core quality-of-life features used by the recommended custom template setup below (SSH passthrough, common utilities, and Docker access in-container). ## Required Fields Every custom template must contain these fields: | Field | Description | |-------|-------------| | `workspaceFolder` | Container path where the project is mounted (must use `/workspaces/` prefix) | | `workspaceMount` | Docker mount specification for the project | The `/workspaces/` prefix is required by the devcontainer spec — it's the standard location where projects are mounted inside the container. ::: warning When a template is applied to a project, SkyBox overrides `workspaceFolder` and `workspaceMount` with project-specific values (e.g., `/workspaces/my-app`). These fields are required for validation but their exact values in the template file are not used directly. ::: ## Starter Templates Choose a starter template based on your needs: | If you need... | Use | |---------------|-----| | Smallest possible config, add features yourself | [Minimal Template](#minimal-template) | | SSH keys, Docker, zsh — the same setup as built-in templates | [Recommended Template](#recommended-template) | | Full example with a language runtime (Bun/TypeScript) | [Language-Specific Example](#language-specific-example) | ### Minimal Template The bare minimum to get a working container. Copy this and customize it: ```json { "name": "my-template", "image": "mcr.microsoft.com/devcontainers/base:debian", "workspaceFolder": "/workspaces/${localWorkspaceFolderBasename}", "workspaceMount": "source=${localWorkspaceFolder},target=/workspaces/${localWorkspaceFolderBasename},type=bind,consistency=cached" } ``` This gives you a Debian container with basic dev tools. No SSH passthrough, no Docker access, no shell customization. ### Recommended Template This template includes the features that SkyBox's built-in templates use. These are recommended for a smooth development experience: ```json { "name": "my-template", "image": "mcr.microsoft.com/devcontainers/base:debian", "workspaceFolder": "/workspaces/${localWorkspaceFolderBasename}", "workspaceMount": "source=${localWorkspaceFolder},target=/workspaces/${localWorkspaceFolderBasename},type=bind,consistency=cached", "postCreateCommand": "", "postStartCommand": "[ ! -L $HOME/.ssh ] && rm -rf $HOME/.ssh && ln -s /var/ssh-config $HOME/.ssh || true", "features": { "ghcr.io/devcontainers/features/common-utils:2": { "configureZshAsDefaultShell": true }, "ghcr.io/devcontainers/features/docker-outside-of-docker:1": { "moby": false }, "ghcr.io/devcontainers/features/git:1": {} }, "mounts": [ "source=${localEnv:HOME}/.ssh,target=/var/ssh-config,type=bind,readonly" ], "customizations": { "vscode": { "extensions": [], "settings": { "terminal.integrated.defaultProfile.linux": "zsh" } } } } ``` ### Why These Features Are Recommended | Feature | What it does | Why you want it | |---------|-------------|-----------------| | **common-utils** (zsh) | Installs zsh and sets it as the default shell | Better shell experience with auto-completion and history | | **docker-outside-of-docker** | Exposes the host Docker daemon inside the container | Run `docker` commands from your dev container without nested Docker | | **git** | Ensures git is installed and configured | Required for version control inside the container | | **SSH passthrough** (mount + postStartCommand) | Bind-mounts your host `~/.ssh` directory read-only and symlinks it inside the container | Git operations over SSH (push, pull, clone) work using your existing keys — no need to copy keys into the container | | **zsh as default terminal** (VS Code setting) | Sets the integrated terminal to use zsh | Matches the shell configured by common-utils | The `postStartCommand` creates a symlink from `$HOME/.ssh` to the bind-mounted `/var/ssh-config` directory. This runs each time the container starts, ensuring SSH keys are always available. ### Language-Specific Example A complete template for a Bun/TypeScript project with all recommended features: ```json { "name": "bun", "image": "mcr.microsoft.com/devcontainers/base:debian", "workspaceFolder": "/workspaces/${localWorkspaceFolderBasename}", "workspaceMount": "source=${localWorkspaceFolder},target=/workspaces/${localWorkspaceFolderBasename},type=bind,consistency=cached", "postCreateCommand": "[ -f package.json ] && bun install || true", "postStartCommand": "[ ! -L $HOME/.ssh ] && rm -rf $HOME/.ssh && ln -s /var/ssh-config $HOME/.ssh || true", "features": { "ghcr.io/devcontainers/features/common-utils:2": { "configureZshAsDefaultShell": true }, "ghcr.io/devcontainers/features/docker-outside-of-docker:1": { "moby": false }, "ghcr.io/devcontainers/features/git:1": {}, "ghcr.io/shyim/devcontainers-features/bun:0": {} }, "mounts": [ "source=${localEnv:HOME}/.ssh,target=/var/ssh-config,type=bind,readonly" ], "customizations": { "vscode": { "extensions": ["oven.bun-vscode"], "settings": { "terminal.integrated.defaultProfile.linux": "zsh" } } } } ``` ::: tip Devcontainer Features Instead of installing tools via `postCreateCommand`, prefer using [devcontainer features](https://containers.dev/features) when available. Features are cached in the image layer and don't re-run on every container start. ::: ## Validation Templates are validated at two points: **At list time** — when the template selector is displayed: * Invalid templates appear with a warning indicator (e.g., `bun ⚠ invalid JSON`) * Templates missing required fields show the specific error (e.g., `python ⚠ missing workspaceFolder`) **At selection time** — when you select an invalid template: * The specific error is displayed * You are returned to the template selector to choose another ### Validation Rules * File must contain valid JSON * JSON must be an object (not an array or primitive) * Must contain `workspaceFolder` property * Must contain `workspaceMount` property * Non-`.json` files in the templates directory are ignored ## Template Selector SkyBox uses a shared template selector component. Available options can vary by command: ``` ? Select a template: ── Built-in ── Node.js — Node (latest) with npm/yarn + Common Utils + Docker Bun — Bun (latest) + Common Utils + Docker Python — Python (latest) with pip/venv + Common Utils + Docker Go — Go (latest) + Common Utils + Docker Generic — Debian with Common Utils + Docker ── Other ── Enter git URL ── Your Templates ── Create new template ``` If you have custom templates in `~/.skybox/templates/`, they appear in the "Your Templates" section with validation status: ``` ── Your Templates ── bun python ⚠ missing workspaceFolder Create new template ``` * **Built-in** and **Other** sections are fixed at the top * **Your Templates** section appears at the bottom and grows as you add templates * **Create new template** is always the last item `Enter git URL` is shown in `skybox new`. The `skybox up` and `skybox config devcontainer reset` selectors show built-in and local templates only. ## Creating a Template ### Through the CLI Select "Create new template" from the template selector. SkyBox walks you through: 1. **Name** — Enter a name (letters, numbers, hyphens, underscores only; no collisions with existing templates) 2. **Scaffold** — SkyBox creates a template file with required fields pre-filled 3. **Edit** — Choose how to edit the template: * **Open in editor** — launches your configured SkyBox editor * **Edit in terminal** — opens with `$EDITOR` (falls back to `vi`) * **Skip** — prints the file path, returns to the selector After creating and optionally editing, you return to the template selector where the new template is available for selection. ### Manually Create a `.json` file in `~/.skybox/templates/`. Copy one of the starter templates above and save it: ```bash mkdir -p ~/.skybox/templates # Then create your template file, e.g.: # ~/.skybox/templates/rust.json # ~/.skybox/templates/bun.json ``` The template will appear in the selector the next time any command needs a devcontainer configuration. ## Commands That Use Templates | Command | When templates are shown | |---------|------------------------| | `skybox up` | When a project has no `devcontainer.json` (built-in and local templates only) | | `skybox new` | When creating a new project (built-in/user templates create an empty project with the selected config; git URLs clone the repo) | | `skybox config devcontainer reset` | When resetting a project's devcontainer config (built-in and local templates only) | ## Field Reference All fields supported in a custom template: | Field | Required | Description | |-------|----------|-------------| | `name` | No | Display name for the container | | `image` | No | Docker image to use (e.g., `mcr.microsoft.com/devcontainers/base:debian`) | | `workspaceFolder` | **Yes** | Container path for the project (must start with `/workspaces/`) | | `workspaceMount` | **Yes** | Docker bind mount spec for the project directory | | `postCreateCommand` | No | Shell command to run after the container is first created (e.g., `npm install`) | | `postStartCommand` | No | Shell command to run each time the container starts (e.g., SSH symlink setup) | | `features` | No | Devcontainer features to install (e.g., git, Docker-outside-of-Docker, common-utils) | | `mounts` | No | Additional Docker bind mounts (e.g., SSH key passthrough) | | `customizations.vscode.extensions` | No | VS Code extensions to install in the container | | `customizations.vscode.settings` | No | VS Code settings to apply in the container | For the full devcontainer.json specification, see the [devcontainers spec](https://containers.dev/implementors/json_reference/). ## Edge Cases * **Template directory doesn't exist** — created automatically on first use * **Name collisions with built-in templates** — both appear in their respective sections, no conflict * **Template deleted between listing and selection** — error is shown, selector loops back * **Non-JSON files in templates directory** — ignored * **Empty templates directory** — "Your Templates" section shows only "Create new template" ## See Also * [skybox up](/reference/up) - Start a development container * [skybox new](/reference/new) - Create a new project * [skybox config](/reference/config) - Configure devcontainer settings * [Core Concepts — Templates](/guide/concepts#templates) - Template overview --- --- url: /guide/workflows/daily-development.md description: >- Day-to-day patterns for working with SkyBox. Start containers, switch between projects, manage sync, and shut down cleanly. --- # Daily Development Workflow This guide covers the day-to-day patterns for working with SkyBox: starting your work, switching between projects, and shutting down cleanly. ## Starting Your Day ### Quick Start a Project If you know which project you want to work on: ```bash skybox up my-project ``` Or navigate to the project directory and run: ```bash cd ~/.skybox/Projects/my-project skybox up ``` SkyBox auto-detects the project from your current directory. ::: tip Skip the Manual Start With [shell integration](/guide/shell-integration), containers start automatically when you `cd` into a project directory — no `skybox up` needed. ::: ### What Happens on Start 1. **Session Check** - SkyBox checks for an existing session and creates one for your machine 2. **Sync Resume** - If sync was paused, it resumes automatically 3. **Container Start** - Starts or creates the dev container 4. **Post-Start** - Prompts for editor/shell options ### Choose Your Entry Point After the container starts: ``` ? What would you like to do? 1) Open in editor 2) Attach to shell 3) Both 4) Neither (just exit) ``` **Option 1: Open in Editor** Opens your configured editor (Cursor, VS Code, Zed, etc.) with the Dev Container extension connecting to the running container. **Option 2: Attach to Shell** Drops you into an interactive shell inside the container: ```bash Attaching to shell (Ctrl+D to exit)... root@container:/workspaces/my-project# ``` **Option 3: Both** Opens the editor and attaches to a shell. ### Non-Interactive Start For scripting or quick access: ```bash # Just start, no prompts skybox up my-project --no-prompt # Start and open editor skybox up my-project --editor # Start and attach shell skybox up my-project --attach # Start, open editor, and attach shell skybox up my-project --editor --attach ``` ## Checking Project Status ### Overview of All Projects ```bash skybox status ``` Shows a table of all local projects: ``` Projects: NAME CONTAINER SYNC BRANCH SESSION LAST ACTIVE SIZE backend-api running syncing main active here 2 hours ago 245M frontend-app stopped paused develop none 3 days ago 512M shared-lib stopped syncing main none 1 day ago 48M ``` For a live-updating full-screen view, try [`skybox dashboard`](/reference/dashboard). ### Detailed Project Status ```bash skybox status my-project ``` Shows comprehensive information: ``` Project: my-project ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ Container Status: running Image: mcr.microsoft.com/devcontainers/base:debian Uptime: 2 hours CPU: 0.5% Memory: 256M / 4G Sync Status: syncing Session: skybox-my-project Pending: 0 files Last sync: - Git Branch: main Status: clean Ahead: 0 commits Behind: 0 commits Session Status: active here Machine: my-laptop User: me Started: 2 hours ago PID: 12345 Disk Usage Local: 45M Remote: 44M ``` ## Switching Between Projects ### Stop Current Project ```bash skybox down backend-api ``` This: 1. Flushes pending sync changes to remote 2. Stops the container 3. Ends the session 4. Optionally pauses sync to save resources ### Start Another Project ```bash skybox up frontend-app ``` ### Quick Project Selection Without specifying a project, SkyBox prompts you: ```bash skybox up ``` ``` ? Select a project: 1) backend-api 2) frontend-app 3) shared-lib ``` ### Multiple Projects Simultaneously You can run multiple projects at once - each gets its own container: ```bash # Terminal 1 skybox up backend-api --attach # Terminal 2 skybox up frontend-app --attach ``` Note: Each project has its own session, so SkyBox will warn you if the same project is active on another machine. ## Working with Running Containers ### Quick Access with `skybox open` For running containers, use `skybox open` for quick access without the full startup flow: ```bash # Open action menu (editor/shell/both) skybox open my-project # Open editor directly skybox open my-project --editor # Attach to shell directly skybox open my-project --shell ``` This is faster than `skybox up` because it skips session checks and sync checks. ### Using `skybox up` with Running Containers If a container is already running: ```bash skybox up my-project ``` ``` ? Container already running. What would you like to do? 1) Continue with existing container 2) Restart container 3) Rebuild container ``` * **Continue** - Just attach or open editor * **Restart** - Stop and start fresh * **Rebuild** - Full rebuild (use after devcontainer.json changes) ### Open Editor for Running Project ```bash skybox editor my-project ``` Opens your configured editor pointing to the running container. ### Multiple Shell Sessions Open additional shells for a running container with [`skybox shell`](/reference/shell): ```bash # Terminal 1: Main work skybox up my-project --attach # Terminal 2: Run tests skybox open my-project --shell # Terminal 3: Watch logs skybox open my-project --shell ``` ### List Local Projects ```bash skybox list ``` ``` Local projects: backend-api Branch: main Path: /Users/john/.skybox/Projects/backend-api frontend-app Branch: develop Path: /Users/john/.skybox/Projects/frontend-app ``` ## Ending Your Day ### Clean Shutdown ```bash skybox down my-project ``` Interactive prompts: ``` Syncing pending changes... done Stopping container... done Session ended ? Remove the container to free up resources? (y/N) ? Pause background sync to save resources? (y/N) ``` ### Quick Shutdown ```bash skybox down my-project --no-prompt ``` Stops container and ends session without prompts. ### Shutdown with Cleanup ```bash skybox down my-project --cleanup ``` Removes the container entirely (not just stops it). Useful for freeing disk space. ### Shutdown All Projects Stop all running containers at once using the `--all` flag: ```bash skybox down --all ``` This stops all running containers and ends all sessions. If some projects fail to shut down, the command continues with the remaining projects and reports failures at the end. ## Managing Sync ### Background Sync Behavior * Sync runs continuously in the background via Mutagen * Changes sync bidirectionally (local <-> remote) * Default mode: `two-way-resolved` (conflicts resolved automatically) ### Check Sync Status ```bash skybox status my-project ``` Look at the Sync section: * **syncing** - Active and healthy * **paused** - Manually paused or auto-paused * **error** - Sync problem (check mutagen logs) ### Pause Sync Manually During `skybox down`, you can choose to pause sync. This saves resources when you are not actively working. ### Resume Paused Sync Running `skybox up` automatically resumes paused sync sessions. ## Session Management ### Understanding Sessions Sessions track which machine is actively working on a project. When you run `skybox up`: 1. SkyBox checks for an existing session file in the project 2. If no session exists, creates one for your machine 3. If a session exists from the same machine, updates the timestamp 4. If a session exists from a different machine, warns and asks to continue ### Session Conflict Resolution ``` This project is running on work-laptop (started 3 days ago) ? Continue anyway? (y/N) ``` Continuing anyway: * Creates a new session for your current machine * The session file syncs to the other machine via Mutagen * Safe as long as you are not actively editing on both machines simultaneously ### Viewing Session Status ```bash skybox status my-project ``` Session section shows: * Current status (active here / active on another machine / none) * Machine name * Username * When the session started ## Debugging with Logs View container logs for a running project: ```bash skybox logs my-project ``` Follow logs in real time (useful for debugging server processes): ```bash skybox logs my-project -f ``` This streams container output continuously until you press `Ctrl+C`. See [`skybox logs`](/reference/logs) for all available options. ## Diagnosing Issues with Doctor If something is not working as expected, run the built-in diagnostic tool: ```bash skybox doctor ``` This checks Docker, Mutagen, SSH connectivity, and configuration in one command and suggests fixes for any problems found. Run this before diving into manual troubleshooting. ## Batch Operations For multi-project workflows, use the `--all` flag to operate on all projects at once: ```bash # Start all projects skybox up --all # Stop all projects skybox down --all ``` If individual projects fail during batch operations, the command continues with the remaining projects and reports failures at the end. ## Troubleshooting For solutions to common issues with containers, sync, and sessions, see the [Troubleshooting Guide](/guide/troubleshooting). ## Related Commands | Command | Usage in this workflow | |---------|----------------------| | [`skybox up`](/reference/up) | Start a project container | | [`skybox down`](/reference/down) | Stop a project container | | [`skybox open`](/reference/open) | Quick access to running containers | | [`skybox shell`](/reference/shell) | Open additional shell sessions | | [`skybox status`](/reference/status) | Check project and sync status | | [`skybox dashboard`](/reference/dashboard) | Live-updating full-screen view | | [`skybox logs`](/reference/logs) | View container or sync logs | | [`skybox doctor`](/reference/doctor) | Diagnose common issues | | [`skybox list`](/reference/list) | List local projects | ## See Also * [Multi-Machine Workflow](/guide/workflows/multi-machine) - Working across multiple machines * [Shell Integration](/guide/shell-integration) - Auto-start containers on `cd` * [Troubleshooting](/guide/troubleshooting) - Common issues and solutions --- --- url: /reference/hooks.md description: >- Run custom shell commands before and after SkyBox lifecycle operations. Configure pre/post hooks for up, down, sync, and other events. --- # Hooks Run custom shell commands before and after lifecycle operations. ## Overview Hooks let you define shell commands that run automatically at key points during `skybox up` and `skybox down`. Hooks are configured per-project in your SkyBox config file. ## Configuration Add a `hooks` section to a project in `~/.skybox/config.yaml`: ```yaml projects: my-app: remote: work hooks: pre-up: "echo 'Starting up...'" post-up: "npm run migrate" pre-down: "npm run cleanup" post-down: "echo 'Stopped.'" ``` ## Hook Events | Event | When it runs | |-------|-------------| | `pre-up` | Before the container starts during `skybox up` | | `post-up` | After the container starts during `skybox up` | | `pre-down` | Before the container stops during `skybox down` | | `post-down` | After the container stops during `skybox down` | ## Syntax ### Simple (string) A single shell command: ```yaml hooks: post-up: "npm run db:migrate" ``` ### Multiple commands (array) An array of hook entries: ```yaml hooks: post-up: - command: "npm run db:migrate" - command: "npm run seed" ``` Each entry supports: | Field | Required | Description | |-------|----------|-------------| | `command` | Yes | Shell command to execute | | `context` | No | Execution context: `host` (default) or `container` (not yet supported) | ## Behavior * Hooks run on the **host machine** in the project directory * Hooks are **non-fatal** — if a hook fails, a warning is shown but the operation continues * Multiple hooks for the same event run **sequentially** in order * Hook output is captured and displayed if the hook fails * A one-time security warning is shown the first time hooks execute in a session ::: tip Suppress Warning Set `SKYBOX_HOOK_WARNINGS=0` to disable the one-time hook security warning. ::: ::: warning Security Hook commands execute with full shell access on your host machine. Only define hooks in trusted configuration files. Review hooks before running `skybox up` or `skybox down` on shared configs. ::: ## Examples ```yaml projects: my-api: remote: work hooks: # Run database migrations after starting post-up: "docker exec skybox-my-api npm run migrate" # Back up database before stopping pre-down: "docker exec skybox-my-api npm run db:backup" frontend: remote: work hooks: # Multiple post-up hooks post-up: - command: "open http://localhost:3000" - command: "echo 'Frontend ready!'" ``` ## See Also * [skybox up](/reference/up) - Start a development container * [skybox down](/reference/down) - Stop a development container * [Configuration](/reference/configuration) - SkyBox config reference --- --- url: /guide/installation.md description: >- Install SkyBox and its prerequisites including Docker and the Devcontainer CLI. Set up your first remote server connection. --- # Installation This guide covers installing SkyBox and its dependencies. ## Prerequisites SkyBox requires: | Software | Version | Purpose | |----------|---------|---------| | Docker | 20.10+ | Running development containers | | Devcontainer CLI | 0.50+ | Building and managing dev containers | | SSH | - | Remote server connection | ::: tip Note The devcontainer CLI requires Node.js. Make sure Node.js is installed before installing the devcontainer CLI. ::: ### Installing Prerequisites Install the following tools from their official sources before continuing: * **Docker Desktop** (20.10+) — [Get Docker](https://docs.docker.com/get-started/get-docker/) * **Devcontainer CLI** (0.50+) — [Installation instructions](https://github.com/devcontainers/cli#install-script) * **SSH** — Pre-installed on macOS and Linux. Windows users need [WSL 2](https://learn.microsoft.com/en-us/windows/wsl/install). SkyBox supports both passwordless and passphrase-protected SSH keys. If your key has a passphrase, SkyBox will prompt you to load it into `ssh-agent` during setup. ## Install SkyBox ::: code-group ```bash [Homebrew (macOS)] brew install noorxlabs/tap/skybox ``` ```bash [Direct Download (macOS / Linux / WSL)] # Install with one command (auto-detects architecture) curl -fsSL https://install.noorxlabs.com/skybox | bash ``` ::: ## Verify Installation Check that SkyBox and its dependencies are installed correctly: ```bash # Check SkyBox skybox --version # Check Docker is installed and running docker --version docker ps # Check devcontainer CLI devcontainer --version ``` You should see version numbers for all three tools. If `docker ps` fails, make sure Docker Desktop is running. ## Initial Setup Run the interactive setup wizard: ```bash skybox init ``` The wizard will: 1. **Check dependencies** - Verify Docker and devcontainer CLI are installed 2. **Install Mutagen** - Extract the bundled file sync tool automatically 3. **Configure remote server** - Set up SSH connection to your backup server 4. **Choose editor** - Select your preferred code editor ### Example Setup Session ``` Welcome to skybox setup! Checking dependencies... Docker installed Devcontainer CLI available Installing mutagen... Mutagen installed Configure remote server Select SSH host: 1) my-server (192.168.1.100) 2) work-vps (work.example.com) 3) + Add new server Testing SSH connection... SSH connection successful Remote code directory: ~/code Remote directory exists Configure editor Preferred editor: 1) Cursor 2) VS Code 3) VS Code Insiders 4) Zed 5) Other (specify command) Setting up skybox... Created ~/.skybox Saved configuration skybox is ready! Next steps: Push a local project: skybox push ./my-project Clone from remote: skybox clone Browse remote projects: skybox browse ``` ## Configuration Location SkyBox stores its configuration and projects in `~/.skybox/`: ``` ~/.skybox/ ├── config.yaml # Main configuration file ├── Projects/ # Local synced project copies ├── bin/ # Bundled tools (mutagen) └── logs/ # Log files ``` You can override this location with the `SKYBOX_HOME` environment variable: ```bash export SKYBOX_HOME=/custom/path/.skybox ``` ## Troubleshooting ::: tip Quick Diagnosis Run `skybox doctor` to automatically check all dependencies, connectivity, and configuration in one command. It will identify most problems and suggest fixes. ::: ### Docker Not Found If `skybox init` reports Docker is not found: 1. Ensure Docker is installed: `docker --version` 2. Check Docker is running: `docker ps` 3. On macOS, make sure Docker Desktop is running (check the menu bar icon) 4. On Linux, ensure your user is in the docker group: `sudo usermod -aG docker $USER` (then log out and back in) ### Devcontainer CLI Not Found If `devcontainer --version` fails: 1. Ensure Node.js is installed first 2. Install the devcontainer CLI from the [official instructions](https://github.com/devcontainers/cli#install-script) ### SSH Connection Failed If the SSH connection test fails: 1. Verify you can connect manually: `ssh your-server` 2. Check your SSH key is added: `ssh-add -l` 3. Ensure the server is reachable: `ping your-server` 4. If you see "Could not open a connection to your authentication agent", start the agent first: ```bash eval $(ssh-agent) ``` ### Mutagen Installation Failed If Mutagen fails to install automatically: 1. Run `skybox doctor` to diagnose and automatically re-extract the bundled Mutagen binary 2. If running from source (dev mode), SkyBox falls back to downloading from GitHub — check your internet connection 3. Try manual installation: [Mutagen](https://mutagen.io/documentation/introduction/installation) ### Permission Denied Errors If you encounter permission issues: ```bash # Fix ownership of skybox directory sudo chown -R $USER:$USER ~/.skybox # Ensure SSH key has correct permissions chmod 600 ~/.ssh/id_ed25519 chmod 700 ~/.ssh ``` ## Next Steps Once installation is complete, follow the **[Quick Start](/guide/quick-start)** to set up your first project and start developing in a container. Want to learn more first? * [Core Concepts](/guide/concepts) - Understand how projects, containers, and sync work together * [Workflows](/guide/workflows/daily-development) - Day-to-day development patterns --- --- url: /guide.md description: >- Learn what SkyBox is and how it manages local-first development containers with remote sync, multi-machine workflows, and editor integration. --- # Introduction SkyBox is a CLI tool for local-first development containers with remote sync. It provides the best of both worlds: run your containers locally for speed and full resource access while automatically syncing your code to a remote server for backup and multi-machine workflows. ## What is SkyBox? SkyBox manages the complete lifecycle of containerized development environments: * **Local Development** - Run containers on your machine with native performance * **Remote Sync** - Automatically backup code to a remote server using Mutagen * **Multi-Machine Workflow** - Seamlessly switch between machines with session-based coordination * **Editor Integration** - Open projects directly in Cursor, VS Code, or your preferred editor ## How It Works ```text Your Machine Remote Server ┌─────────────────────┐ ┌─────────────────────┐ │ ~/.skybox/Projects │◄───────►│ ~/code/ │ │ ├── project-a/ │ Sync │ ├── project-a/ │ │ └── project-b/ │ │ └── project-b/ │ └─────────────────────┘ └─────────────────────┘ │ ▼ ┌─────────────────────┐ │ Docker Container │ │ (devcontainer) │ └─────────────────────┘ ``` 1. Projects are stored locally in `~/.skybox/Projects/` 2. Mutagen syncs files bidirectionally to your remote server 3. Docker containers run locally using devcontainer configurations 4. Session files prevent conflicts when switching between machines ## Why SkyBox? ### Local-First Performance Unlike cloud-based development environments, SkyBox runs containers on your machine. This means: * No network latency for file operations * Full access to local resources (CPU, memory, GPU) * Works offline after initial setup * No per-minute cloud billing ### Seamless Remote Backup Your code is automatically synced to remote servers: * Never lose work due to local machine issues * Easy to switch between work laptop and home desktop * Built-in session system warns when a project is active on another machine * Multi-remote support for organizing projects across different servers ### Developer Experience SkyBox is designed for developers who want minimal friction: * Interactive setup wizard (`skybox init`) * Smart project detection when running commands * Direct editor integration with devcontainer support * Clean status views showing all your projects at a glance ## Next Steps * [Installation](/guide/installation) - Install SkyBox on your system * [Quick Start](/guide/quick-start) - Get your first project running * [Concepts](/guide/concepts) - Understand how SkyBox works under the hood --- --- url: /guide/workflows/multi-machine.md description: >- Work across multiple machines with SkyBox. Session-based coordination prevents sync conflicts when switching between laptop and desktop. --- # Multi-Machine Workflow This guide covers working with SkyBox across multiple machines, such as a laptop and desktop. Sessions prevent sync conflicts when you switch between machines. ## How Sessions Prevent Sync Conflicts When you run `skybox up`, SkyBox creates a session file that records which machine is actively working on the project. This file lives at: ``` /.skybox/state.lock ``` Because this file is inside your project directory, Mutagen syncs it to your remote server and to any other machines syncing the same project. This means: * When you start working on your laptop, your desktop sees the session file within seconds * When you later sit down at your desktop, SkyBox warns you that the project is active elsewhere * You can choose to continue anyway or go back to the original machine first Sessions exist to protect you from sync conflicts, not to block you. If you know the other machine is idle (you just forgot to stop it), continuing is safe. ## Common Scenarios ### Forgot to Stop on Another Machine You were working on your laptop, closed the lid, and now you are at your desktop: ```bash skybox up my-project ``` ``` This project is running on 'macbook-pro'. ? Continue anyway? (y/N) ``` If you choose yes: * SkyBox creates a new session for your current machine * The session file syncs to the laptop * If you later return to the laptop and run a SkyBox command, it will see the session changed This is safe as long as you are not actively editing on both machines simultaneously. ### Intentional Switching Between Machines When you finish work on one machine, stop the project cleanly: ```bash # On your laptop when leaving skybox down my-project ``` This removes the session file. Then on your other machine: ```bash # On your desktop when arriving skybox up my-project ``` No warning appears because no active session exists. ### Working on the Same Machine If you run `skybox up` on the same machine where the session is already active, SkyBox recognizes this and updates the session timestamp. No warning appears. ## Checking Session Status Use `skybox status` to see if a session is active and where: ```bash skybox status my-project ``` The output includes a Session section: ``` Session Status: active here Machine: macbook-pro User: alice Started: 2026-02-04T10:30:00Z ``` If no session is active, you will see: ``` Session Status: none ``` ### Quick Status Check To see all projects at once: ```bash skybox status ``` The table shows session status for each project. ## Recovering from a Crashed Machine If your laptop died, lost power, or you simply forgot to run `skybox down`: 1. **Wait for session expiry** — sessions automatically expire after 24 hours. After that, `skybox up` on another machine proceeds without any warning. 2. **Continue past the warning** — if the session hasn't expired yet, `skybox up` will warn you that the project is active on the other machine. Choose "Continue anyway" since you know the machine is offline. 3. **Force shell access** — if you just need a shell without updating the session: ```bash skybox shell my-project --force ``` Your project files are safe on the remote server regardless. No data is lost when a machine crashes. ## Session Expiry Sessions expire after 24 hours. This handles cases where a machine crashed or lost network connectivity before running `skybox down`. Expired sessions are treated as inactive. ## What Sessions Are NOT Sessions are a personal safety feature for one person working across multiple computers. They are not a team collaboration tool. **For team collaboration, use Git.** * Multiple team members should each have their own remote folder or remote server * Use branches and pull requests to coordinate code changes * SkyBox remotes are for offloading disk space, not sharing workspaces If two people try to work on the same SkyBox project simultaneously, you will have sync conflicts regardless of sessions. Sessions only help when one person forgets to stop on another machine. ## Session File Details The session file contains: ```json { "ownership": { "owner": "alice", "created": "2026-02-04T09:00:00Z", "machine": "macbook-pro" }, "session": { "machine": "macbook-pro", "user": "alice", "timestamp": "2026-02-04T10:00:00Z", "pid": 12345, "expires": "2026-02-05T10:00:00Z", "hash": "7b9e4c5af2c48b3c1e7d9a0c4d0f3e6a9b8c2d1f4e7a6b5c3d2e1f0a9b8c7d6" } } ``` * **machine**: Hostname of the machine that started the session * **user**: Username who started it * **timestamp**: When the session started * **pid**: Process ID (used to detect stale sessions on the same machine) * **expires**: When the session automatically expires (24 hours from start) ## Related Commands | Command | Usage in this workflow | |---------|----------------------| | [`skybox up`](/reference/up) | Start a project on the current machine | | [`skybox down`](/reference/down) | Stop a project before switching machines | | [`skybox clone`](/reference/clone) | Clone a project on a new machine | | [`skybox status`](/reference/status) | Check session status across machines | | [`skybox shell`](/reference/shell) | Access container shell (supports `--force`) | ## Next Steps * [Daily Development](/guide/workflows/daily-development) - Day-to-day workflow patterns * [New Project Setup](/guide/workflows/new-project) - Creating and cloning projects --- --- url: /guide/quick-start.md description: >- Get started with SkyBox in minutes. Walk through initializing, pushing a project, starting a container, and syncing code to your remote server. --- # Quick Start This guide walks you through the typical SkyBox workflow: from setting up your first project to developing inside a container. ## Workflow Overview ```text skybox init Set up SkyBox (one-time) │ ├── skybox push ./project Push existing project to remote │ OR └── skybox clone project Clone project from remote │ ▼ skybox up Start the dev container │ ▼ Open in Editor Code inside the container │ ▼ skybox down Stop when done ``` ## Step 1: Initialize SkyBox If you haven't already, run the setup wizard: ```bash skybox init ``` This configures your remote server connection and preferred editor. See [Installation](/guide/installation) for details. ## Step 2: Add Your First Project You have two options for adding projects to SkyBox: ### Option A: Push an Existing Local Project If you have a project on your machine, push it to SkyBox: ```bash skybox push ./my-project ``` This will: 1. Copy the project to `~/.skybox/Projects/my-project/` 2. Create the project directory on your remote server 3. Set up bidirectional sync between local and remote 4. Register the project in SkyBox Example output: ``` Pushing 'my-project' to my-server:~/code/my-project... Remote path available Created remote directory Starting sync... Initial sync complete Start dev container now? (Y/n) ``` ### Option B: Clone from Remote If the project already exists on your remote server: ```bash # First, see what's available skybox browse # Clone the project skybox clone my-project ``` Example output: ``` Cloning 'my-project' from my-server:~/code/my-project... Project found on remote Created /Users/you/.skybox/Projects/my-project Setting up sync... Syncing files from remote... Initial sync complete Start dev container now? (Y/n) ``` ## Step 3: Start the Dev Container Start the development container: ```bash skybox up my-project ``` Or, if you're inside the project directory: ```bash cd ~/.skybox/Projects/my-project skybox up ``` ### First-Time Container Setup If your project doesn't have a `devcontainer.json`, SkyBox will offer to create one: ``` Starting 'my-project'... Session started Sync is active No devcontainer.json found ? Would you like to create a devcontainer.json from a template? (Y/n) ``` ``` ? Select a template: ── Built-in ── Node.js — Node (latest) with npm/yarn + Common Utils + Docker Bun — Bun (latest) + Common Utils + Docker Python — Python (latest) with pip/venv + Common Utils + Docker Go — Go (latest) + Common Utils + Docker Generic — Debian with Common Utils + Docker ── Your Templates ── Create new template ``` ### Container Startup Once the devcontainer is configured: ``` Container started ``` ``` ? What would you like to do? 1) Open in editor 2) Attach to shell 3) Both 4) Neither (just exit) ``` ## Step 4: Develop in Your Editor When you choose "Open in editor", SkyBox opens your project in your configured editor with full devcontainer support: * **Cursor/VS Code**: Opens with Dev Containers extension, running inside the container * **Other editors**: Opens the project folder Your editor connects to the running container, giving you: * Container's file system and tools * Installed extensions running in-container * Integrated terminal inside the container ## Step 5: Check Project Status See the status of all your projects: ```bash skybox status ``` Output: ``` Projects: NAME CONTAINER SYNC BRANCH SESSION LAST ACTIVE SIZE my-project running syncing main active here 2 hours ago 45M other-proj stopped paused dev none 3 days ago 120M ``` Get detailed info about a specific project: ```bash skybox status my-project ``` Output: ``` Project: my-project ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ Container Status: running Image: mcr.microsoft.com/devcontainers/base:debian Uptime: 2 hours CPU: 0.5% Memory: 256M / 4G Sync Status: syncing Session: skybox-my-project Pending: 0 files Last sync: - Git Branch: main Status: clean Ahead: 0 commits Behind: 0 commits Session Status: active here Machine: my-laptop User: me Started: 2 hours ago PID: 12345 Disk Usage Local: 45M Remote: 44M ``` ## Step 6: Stop When Done When you're finished working: ```bash skybox down my-project ``` Or with cleanup to remove the container: ```bash skybox down my-project --cleanup ``` ::: tip Auto-Start with Shell Integration Tired of running `skybox up` manually? Set up [shell integration](/guide/shell-integration) to auto-start containers when you `cd` into a project directory. ::: ## Need Help? If you hit issues during setup or first run: ```bash skybox doctor ``` * See [Troubleshooting](/guide/troubleshooting) for common fixes and recovery steps * Use [`skybox logs`](/reference/logs) to inspect container or sync output while debugging ## Common Workflows ### Switching Machines When moving from one machine to another: 1. On the old machine, stop the container: ```bash skybox down my-project ``` 2. On the new machine, clone and start: ```bash skybox clone my-project skybox up my-project ``` SkyBox's [session system](/guide/concepts#session-system) will warn you if you try to start on a new machine while another machine has an active session. ### Quick Container Access Start and immediately attach to shell: ```bash skybox up my-project --attach ``` Start and open in editor: ```bash skybox up my-project --editor ``` ### Non-Interactive Mode For scripts and automation: ```bash skybox up my-project --no-prompt skybox down my-project --no-prompt ``` ### Force Rebuild Container If you need to rebuild the container from scratch: ```bash skybox up my-project --rebuild ``` ::: tip Working with Large Repos? If you're working in a monorepo or large project and only need specific directories, use [selective sync](/guide/concepts#selective-sync) to sync just the paths you need: ```bash skybox config sync-paths my-app packages/frontend,packages/shared ``` ::: ## Next Steps * Learn about [Core Concepts](/guide/concepts) to understand projects, containers, and sync * See the [Command Reference](/reference/) for the full list of commands ### Workflows * [Daily Development](/guide/workflows/daily-development) - Day-to-day patterns for starting, switching, and stopping projects * [New Project Setup](/guide/workflows/new-project) - Creating and pushing projects to SkyBox * [Multi-Machine Workflow](/guide/workflows/multi-machine) - Working across multiple computers --- --- url: /guide/shell-integration.md description: >- Automatically start SkyBox containers when you cd into a project directory. Configure shell hooks for Bash, Zsh, and Fish. --- # Shell Integration Automatically start SkyBox containers when you `cd` into a project directory. ## Overview The SkyBox shell hook integrates with your shell to detect when you navigate into a SkyBox project directory. When enabled, it automatically starts the container in the background, so your development environment is ready by the time you need it. **Benefits:** * No manual `skybox up` needed * Container starts silently in the background * Does not block your shell prompt * Only triggers on actual directory changes ## Installation ### Bash Add the hook to your `~/.bashrc`: ```bash echo 'eval "$(skybox hook bash)"' >> ~/.bashrc source ~/.bashrc ``` ### Zsh Add the hook to your `~/.zshrc`: ```bash echo 'eval "$(skybox hook zsh)"' >> ~/.zshrc source ~/.zshrc ``` ## Configuration The shell hook only auto-starts containers for projects with `auto_up` enabled. By default, this is disabled (opt-in). ### Enable for a Specific Project Edit `~/.skybox/config.yaml` directly: ```yaml projects: my-project: remote: work auto_up: true ``` ### Enable Globally To auto-start all projects by default: ```yaml defaults: auto_up: true projects: my-project: remote: work ``` Per-project settings override the global default: ```yaml defaults: auto_up: true # Enable for all projects projects: my-project: remote: work auto_up: false # Disable for this specific project ``` ## How It Works 1. **Hook Registration** * Bash: Appends to `PROMPT_COMMAND` * Zsh: Registers a `precmd` hook via `add-zsh-hook` 2. **Directory Change Detection** * Tracks the previous directory in `_SKYBOX_PREV_DIR` * Only triggers when `$PWD` differs from the previous directory 3. **Project Resolution** * Checks if the current directory is inside `~/.skybox/Projects/` * Extracts the project name from the path 4. **Auto-Start Logic** * Verifies `auto_up` is enabled for the project * Checks if the container is already running * If not running, spawns `skybox up --no-prompt` in the background 5. **Background Execution** * The `skybox up` process runs detached from your shell * Output is logged to `~/.skybox/logs/auto-up.log` * Your shell prompt returns immediately ## Troubleshooting ### Check the Log File All auto-up activity is logged: ```bash cat ~/.skybox/logs/auto-up.log ``` Example output: ``` [2026-02-03T10:30:00.000Z] [my-project] Auto-starting container... [2026-02-03T10:30:05.000Z] [my-project] Container started successfully ``` ### Verify the Hook Is Active **Bash:** ```bash echo "$PROMPT_COMMAND" # Should contain: _skybox_hook ``` **Zsh:** ```bash typeset -f _skybox_hook # Should output the function definition ``` ### Container Not Starting? 1. **Check if auto\_up is enabled:** Check your `~/.skybox/config.yaml` and look for `auto_up: true` under your project: ```bash skybox config ``` 2. **Verify you are in a SkyBox project directory:** ```bash pwd # Should be inside ~/.skybox/Projects/ ``` 3. **Check if skybox is in your PATH:** ```bash which skybox ``` 4. **Try running the check manually:** ```bash skybox hook-check ``` This is the hidden command the hook calls. It should exit silently if everything is working. ### Disable the Hook Temporarily To disable shell integration without removing it: ```bash unset -f _skybox_hook ``` This lasts until you open a new shell. ## See Also * [Daily Development](/guide/workflows/daily-development) - Manual startup workflow * [skybox up](/reference/up) - Start a development container * [Configuration](/reference/configuration) - SkyBox config reference --- --- url: /reference/browse.md description: >- List projects available on the remote server with skybox browse. View and select remote projects for cloning. --- # skybox browse List projects available on the remote server. ## Usage ```bash skybox browse ``` ## Arguments This command takes no arguments. ## Options This command has no options. ## Description The `browse` command connects to your configured remote server and lists all projects in the configured base path. If multiple remotes are configured, you'll be prompted to select which remote to browse. For each project, it shows: * Project name (directory name) * Current git branch (if it's a git repository) This is useful for discovering what projects are available to clone. ### Remote Connection The command uses SSH to connect to the remote server configured during `skybox init`. It runs a script on the remote to enumerate directories and their git status. ### Output Format Projects are displayed in a table with name and branch: ``` Remote projects (my-server:~/code): NAME BRANCH my-api main frontend-app feature/new-ui data-service develop Run 'skybox clone ' to clone a project locally. ``` If no projects exist on the remote: ``` No projects found on remote. Run 'skybox push ./my-project' to push your first project. ``` ## Examples ```bash # List all remote projects skybox browse # Then clone one skybox clone my-api ``` ### Workflow Example ```bash # Check what's available on remote skybox browse # Output: # Remote projects (my-server:~/code): # # NAME BRANCH # awesome-project main # another-project feature/cool-stuff # Clone a project to work on it skybox clone awesome-project # Start the container (creates session) skybox up awesome-project ``` ## Exit Codes | Code | Meaning | |------|---------| | 0 | Success | | 1 | Error (not configured, SSH connection failed) | ## See Also * [skybox clone](/reference/clone) - Clone a project from remote * [skybox push](/reference/push) - Push a local project to remote * [skybox list](/reference/list) - List local projects * [skybox init](/reference/init) - Configure remote server --- --- url: /reference/clone.md description: >- Clone a remote project to your local machine with skybox clone. Download and set up remote projects locally. --- # skybox clone Clone a remote project to your local machine. ## Usage ```bash skybox clone [project] ``` ## Arguments | Argument | Description | |----------|-------------| | `[project]` | Name of the project to clone from the remote server. If omitted, shows an interactive multi-select of remote projects. | ## Options | Option | Description | |--------|-------------| | `--dry-run` | Show what would happen without making changes | ## Description The `clone` command downloads a project from your configured remote server to your local machine. It performs the following steps: 1. **Remote Selection** - If multiple remotes are configured, prompts you to select which remote to clone from 2. **Remote Check** - Verifies the project exists on the remote server 3. **Local Check** - Checks if project already exists locally (prompts to overwrite) 4. **Directory Creation** - Creates the local project directory 5. **Sync Setup** - Creates a Mutagen sync session for bidirectional file synchronization (uses selective sync if project has `sync_paths` configured) 6. **Initial Sync** - Downloads all files from remote to local 7. **Registration** - Registers the project in SkyBox configuration 8. **Container Prompt** - Offers to start the development container ### Interactive Multi-Clone When run without a project argument, `skybox clone` enters an interactive flow: 1. **Remote Selection** - Select which remote to clone from 2. **Project List** - Fetches all projects from the remote 3. **Multi-Select** - Shows a checkbox list of available projects (already-local projects are filtered out) 4. **Batch Clone** - Clones each selected project sequentially 5. **Summary** - Reports how many projects were cloned (e.g., "Cloned 3 projects: foo, bar, baz") 6. **Start Working** - If one project was cloned, offers to start its container. If multiple were cloned, prompts you to choose which project to start working on (or "None" to skip). The selected project goes through the full `skybox up` flow (session, container, editor/shell). 7. **Reminder** - After starting a project, prints a reminder with the remaining cloned projects you can start later with `skybox up` ### Project Name Validation Project names are validated before cloning. Names cannot contain path separators (`/`, `\`), traversal sequences (`..`), or start with a dash (`-`). ### Local Storage Projects are cloned to `~/.skybox/Projects/`. ### Sync Behavior The sync session uses "two-way-resolved" mode, meaning: * Changes on either side are synced to the other * Conflicts are automatically resolved (local changes win) * Default ignore patterns exclude node\_modules, .git, build artifacts, etc. ### Encrypted Projects If the project is encrypted on the remote (has a `.tar.enc` archive), SkyBox will notify you after cloning. You'll need to provide the passphrase when running `skybox up` to decrypt the project before working on it. ### Overwrite Behavior If a project already exists locally, you'll be prompted twice: 1. First confirmation to overwrite 2. Second confirmation warning that local changes will be lost This prevents accidental data loss. ## Examples ```bash # Clone a project from remote skybox clone my-api # Interactive multi-clone skybox clone # Shows checkbox list of remote projects to select # After cloning, start working skybox up my-api --editor ``` ### Workflow Example ```bash # See available projects on remote skybox browse # Output: # Remote projects (my-server:~/code): # # my-api # Branch: main # # frontend-app # Branch: feature/new-ui # Clone one of them skybox clone my-api # Start the container when prompted, or manually: skybox up my-api ``` ### Switching Machines ```bash # On Machine A - stop and clean up skybox down my-project --cleanup # Choose to remove local files # On Machine B - clone and continue skybox clone my-project skybox up my-project ``` ## Exit Codes | Code | Meaning | |------|---------| | 0 | Success | | 1 | Error (project not found on remote, sync failed) | ## See Also * [skybox browse](/reference/browse) - List projects on remote server * [skybox push](/reference/push) - Push local project to remote * [skybox up](/reference/up) - Start the container after cloning * [skybox rm](/reference/rm) - Remove project locally --- --- url: /reference/config.md description: >- View and modify SkyBox configuration with skybox config. Manage settings for remotes, defaults, and projects. --- # skybox config View and modify SkyBox configuration. ## Usage ```bash skybox config [subcommand] [options] ``` ## Subcommands | Subcommand | Description | |------------|-------------| | (none) | Display current configuration | | `set ` | Set a configuration value | | `sync-paths [paths]` | View or set selective sync paths | | `devcontainer edit ` | Open devcontainer.json in editor | | `devcontainer reset ` | Reset devcontainer.json from template | ## Options | Option | Description | |--------|-------------| | `--validate` | Test SSH connection to all configured remotes and show project counts | ## Description The `config` command provides ways to view and modify your SkyBox configuration. It shows your configured remotes and global settings, manages selective sync paths and provides devcontainer configuration management. ### Display Configuration Running `skybox config` without arguments shows: ``` ─── Remotes: ─── production deploy@prod.example.com:~/code personal me@home-server:~/projects ─── Settings: ─── editor: cursor ``` ### Set Configuration Values ```bash skybox config set ``` Currently supported configuration keys: | Key | Description | Example Values | |-----|-------------|----------------| | `editor` | Default editor command (supports command + flags) | `cursor`, `code --reuse-window`, `open -a Zed`, `/usr/local/bin/nvim` | On macOS, SkyBox will automatically fall back to `open -a ` for built-in GUI editors when the CLI command is not on `PATH`. ### Validate Configuration The `--validate` flag tests SSH connections to all remotes and shows project counts: ```bash skybox config --validate ``` Output: ``` ─── Testing remotes... ─── ✓ production - connected (5 projects) ✓ personal - connected (3 projects) All remotes connected successfully. ``` If a connection fails: ``` ✓ production - connected (5 projects) ✗ personal - failed Some remotes failed to connect. ``` ### Selective Sync Paths View or set which paths to sync for a project. By default, SkyBox syncs the entire project directory. Setting sync paths limits synchronization to only the specified subdirectories. ```bash # View current sync paths skybox config sync-paths my-project # Set sync paths (comma-separated) skybox config sync-paths my-project src,docs,package.json # Clear sync paths (sync entire project) skybox config sync-paths my-project "" ``` Paths are validated before saving. When no sync paths are configured, the entire project is synced. ### Devcontainer Edit Open the project's `devcontainer.json` in your configured editor. After saving and closing the editor, the updated file is automatically pushed to the remote server. ```bash skybox config devcontainer edit ``` If no `devcontainer.json` exists for the project, you will be prompted to create one using `devcontainer reset`. ### Devcontainer Reset Replace the project's `devcontainer.json` with a fresh copy from the unified template selector. You can choose from built-in templates and your custom local templates in `~/.skybox/templates/`. After selection, the new file is pushed to the remote server. See [Custom Templates](/reference/custom-templates) for details. ```bash skybox config devcontainer reset ``` ## Examples ```bash # Show current configuration skybox config # Test all remote connections skybox config --validate # Change default editor to VS Code skybox config set editor code # Change default editor to Vim skybox config set editor vim # View sync paths for a project skybox config sync-paths my-app # Set selective sync paths skybox config sync-paths my-app src,tests,package.json # Edit devcontainer.json for a project skybox config devcontainer edit my-app # Reset devcontainer.json from template skybox config devcontainer reset my-app ``` ### Workflow Example ```bash # Check current setup skybox config # Verify all remotes are accessible skybox config --validate # Switch editor preference skybox config set editor code # Limit sync to only source files for a large project skybox config sync-paths my-app src,package.json # Customize the devcontainer configuration skybox config devcontainer edit my-app ``` ## Configuration File The configuration is stored in `~/.skybox/config.yaml`. While `skybox config set` handles common changes, you can also edit the file directly for advanced configuration. For full configuration file documentation, see [Configuration Reference](/reference/configuration). ## Exit Codes | Code | Meaning | |------|---------| | 0 | Success | | 1 | Error (no config, unknown key, validation failed) | ## See Also * [Configuration Reference](/reference/configuration) - Full config file format * [skybox remote](/reference/remote) - Manage remote servers * [skybox editor](/reference/editor) - Interactive editor selection * [skybox init](/reference/init) - Initial setup wizard --- --- url: /reference/dashboard.md description: >- Full-screen status dashboard for all SkyBox projects. Monitor containers, sync status, and resources in real time. --- # skybox dashboard Full-screen status dashboard for all projects. ## Usage ```bash skybox dashboard [options] skybox dash [options] ``` ## Arguments This command takes no arguments. ## Options | Option | Description | |--------|-------------| | `-d, --detailed` | Start in detailed view showing extra project info | ## Description The `dashboard` command opens a full-screen terminal UI showing all local projects with live-updating status. It uses a responsive card grid layout that adjusts to terminal width. ### Card View Each project is shown as a card with: | Field | Description | |-------|-------------| | Name | Project name | | Container | Running or stopped (color-coded) | | Sync | Syncing, paused, or none | | Session | Session status: "active here" (green), "active on \" (yellow), or "none" (gray) | | Branch | Current git branch | ### Detailed View Press `d` to toggle detailed view, which adds: | Field | Description | |-------|-------------| | Git Status | Clean or dirty working tree, with ahead/behind counts | | Disk Usage | Local disk space used | | Last Active | Time since last activity | | Remote | Configured remote name | | Container Name | Docker container name | | Uptime | Container uptime or exit status | | Encrypted | Whether project encryption is enabled | ### Keyboard Navigation | Key | Action | |-----|--------| | `q`, `Ctrl+C`, `Escape` | Quit | | `r` | Refresh project data | | `d` | Toggle detailed/simple view | | `↑↓←→` | Navigate between project cards | ### Auto-Refresh The dashboard automatically refreshes project data every 10 seconds. ## Examples ```bash # Open the dashboard skybox dashboard # Use the alias skybox dash # Start in detailed view skybox dash --detailed ``` ## Exit Codes | Code | Meaning | |------|---------| | 0 | Normal exit | ## See Also * [skybox status](/reference/status) - Non-interactive project status * [skybox list](/reference/list) - Simple list of local projects --- --- url: /reference/doctor.md description: >- Diagnose common issues with your SkyBox setup, dependencies, and configuration using skybox doctor. --- # skybox doctor Diagnose common issues with your SkyBox setup, dependencies, and configuration. ## Usage ```bash skybox doctor ``` ## Arguments This command takes no arguments. ## Options This command has no options. ## Description The `doctor` command runs a series of health checks to verify that SkyBox and its dependencies are properly configured. It checks: | Check | Description | |-------|-------------| | Docker | Verifies Docker is installed and the daemon is running | | Mutagen | Verifies the Mutagen sync binary is installed and up to date; auto-repairs if missing or outdated | | Devcontainer CLI | Verifies the devcontainer CLI is installed | | Configuration | Verifies SkyBox config exists and is valid | | SSH Connectivity | Tests SSH connection to all configured remotes | Each check reports one of three statuses: | Status | Icon | Meaning | |--------|------|---------| | Pass | `✓` | Check passed successfully | | Warning | `!` | Non-critical issue, SkyBox may still work | | Fail | `✗` | Critical issue that must be fixed | For warnings and failures, the command suggests a fix. ## Examples ```bash # Run all health checks skybox doctor ``` ### Example Output (All Passing) ``` SkyBox Doctor ──────────────────────────────────────── ✓ Docker: Docker 24.0 is running ✓ Mutagen: Mutagen v0.18.1 ✓ Devcontainer CLI: devcontainer 0.62.0 ✓ Configuration: Config loaded (2 remotes) ✓ SSH: work: Connected to work-server ✓ SSH: personal: Connected to personal-server ──────────────────────────────────────── 6 passed All checks passed. SkyBox is ready to use! ``` ### Example Output (With Issues) ``` SkyBox Doctor ──────────────────────────────────────── ✓ Docker: Docker 24.0 is running ✓ Mutagen: Mutagen v0.18.1 (installed) ✓ Devcontainer CLI: devcontainer 0.62.0 ✓ Configuration: Config loaded (2 remotes) ✓ SSH: work: Connected to work-server ✗ SSH: personal: Cannot connect: Connection refused Fix: Check SSH key and host configuration for 'personal' ──────────────────────────────────────── 4 passed, 1 warnings, 1 failed Some checks failed. Please fix the issues above. ``` ## Exit Codes | Code | Meaning | |------|---------| | 0 | All checks passed (warnings are allowed) | | 1 | One or more checks failed | ## Common Issues and Fixes ### Docker not running ``` ✗ Docker: Docker is installed but not running Fix: Start Docker Desktop application ``` Start Docker Desktop or run `systemctl start docker` on Linux. ### Mutagen not installed or outdated Doctor automatically detects missing, outdated, or corrupted Mutagen binaries and attempts to repair them by re-extracting from the bundled asset (or downloading as a fallback). If repair succeeds, you'll see: ``` ✓ Mutagen: Mutagen v0.18.1 (installed) ``` If automatic repair fails: ``` ✗ Mutagen: Mutagen not installed — automatic repair failed Fix: Download Mutagen manually and place at ~/.skybox/bin/mutagen ``` ### Devcontainer CLI not found ``` ! Devcontainer CLI: Devcontainer CLI not found Fix: brew install devcontainer ``` Install the devcontainer CLI. On macOS with Homebrew: ```bash brew install devcontainer ``` Or via npm (any platform): ```bash npm install -g @devcontainers/cli ``` ### SSH connection failed ``` ✗ SSH: myserver: Cannot connect: Permission denied Fix: Check SSH key and host configuration for 'myserver' ``` Verify: * SSH key exists and has correct permissions (`chmod 600`) * SSH host is reachable * Correct user/host in SkyBox config * SSH agent is running with key loaded ### Configuration issues ``` ✗ Configuration: Config file exists but failed to load Fix: Check ~/.skybox/config.yaml for syntax errors ``` Check your config file for YAML syntax errors. You can validate with: ```bash cat ~/.skybox/config.yaml ``` ## See Also * [skybox init](/reference/init) - Initial setup wizard * [skybox config](/reference/config) - View/modify configuration * [Troubleshooting Guide](/guide/troubleshooting) - Common issues and solutions --- --- url: /reference/down.md description: >- Stop a development container with skybox down. Shut down running containers and release local session locks. --- # skybox down Stop a development container. ## Usage ```bash skybox down [project] [options] ``` ## Arguments | Argument | Description | |----------|-------------| | `[project]` | Name of the project to stop. If omitted, SkyBox resolves from the current directory or prompts with a checkbox to select one or more projects. | ## Options | Option | Description | |--------|-------------| | `-c, --cleanup` | Remove container and volumes after stopping | | `-f, --force` | Force stop even on errors | | `--no-prompt` | Non-interactive mode (fails if input would be required) | | `-A, --all` | Stop all local projects in batch mode (tallies success/failure counts) | | `--dry-run` | Show what would happen without making changes | ## Description The `down` command stops a running development container. It performs the following steps: 1. **Project Resolution** - Determines which project to stop (from argument, current directory, or interactive selection) 2. **Pre-Down Hooks** - Runs any configured `pre-down` hooks, e.g. `npm run db:dump` (see [Hooks](/reference/hooks)) 3. **Sync Flush** - Waits for pending file changes to sync to remote 4. **Container Stop** - Stops the running container 5. **Archive Encryption** - If encryption is enabled, encrypts the project on the remote 6. **Session End** - Removes the session file so other machines can start without warnings 7. **Post-Down Hooks** - Runs any configured `post-down` hooks, e.g. `slack-notify "stopped project"` (see [Hooks](/reference/hooks)) 8. **Optional Cleanup** - Removes container and volumes if requested 9. **Optional Local File Removal** - With cleanup, offers to delete local project files (double confirmation required) 10. **Sync Pause** - If not cleaning up, offers to pause background sync to save resources ### Multi-Select Workflow When you run `skybox down` without a project name: 1. SkyBox first checks whether your current directory maps to a known project. 2. If not, it shows a checkbox list so you can select one or more local projects to stop. 3. Selected projects are stopped sequentially, with a final success/failure summary. 4. After all selected projects are stopped, if any had containers running, SkyBox prompts whether to also clean up (remove containers and volumes) for the batch. This is the same as passing `--cleanup` but applied after the fact. If `--no-prompt` is set and no project can be resolved from the current directory, the command exits with an error. Use `--all` if you want to stop every local project without selecting from the checkbox list. ### Sync Safety Before stopping the container, SkyBox waits for all pending file changes to sync to the remote server. This prevents data loss when switching between machines. If the sync flush fails, you are warned but the stop continues. ### Archive Encryption If the project has encryption enabled, after the sync is flushed and the container is stopped, SkyBox will: 1. Prompt for your passphrase 2. Create a tar archive of the project on the remote 3. Download the archive, encrypt it locally 4. Upload the encrypted archive back to the remote 5. Delete plaintext files from the remote If encryption fails, a warning is shown but the shutdown continues. Project files remain unencrypted on the remote in this case. See [`skybox encrypt`](/reference/encryption) for more details. ### Cleanup Options When using `--cleanup`, SkyBox will: * Remove the Docker container * Remove associated volumes * Optionally remove local project files (with **double confirmation**) The first prompt asks if you want to remove local files. If you say yes, a second prompt confirms by showing the exact path that will be deleted. The remote copy is always preserved. ### Sync Pausing If you are not cleaning up, SkyBox offers to pause the background sync session to save system resources when you are not actively working on the project. Sync is automatically resumed the next time you run `skybox up`. ### Batch Mode With `-A, --all`, SkyBox stops every local project sequentially and reports a summary of how many succeeded and how many failed. ## Examples ```bash # Stop a specific project skybox down my-project # Stop and clean up container skybox down my-project --cleanup # Force stop (ignore errors) skybox down my-project --force # Stop from within project directory cd ~/.skybox/Projects/my-project skybox down # Non-interactive stop (for scripts) skybox down my-project --no-prompt # Stop all local projects skybox down --all ``` ### Workflow Example ```bash # Done working for the day skybox down my-project # Switching to different machine - clean up local resources skybox down my-project --cleanup # Keep remote copy, remove local files when prompted # Later, on another machine skybox clone my-project skybox up my-project ``` ## Exit Codes | Code | Meaning | |------|---------| | 0 | Success | | 1 | Error (project not found, failed to stop container without --force) | ## See Also * [skybox up](/reference/up) - Start the container * [skybox status](/reference/status) - Check container status * [skybox rm](/reference/rm) - Remove project locally --- --- url: /reference/editor.md description: >- Change the default editor for opening projects with skybox editor. Supports VS Code, Cursor, Zed, and custom editors. --- # skybox editor Change the default editor for opening projects. ## Usage ```bash skybox editor ``` ## Arguments This command takes no arguments. ## Options This command has no options. ## Description The `editor` command allows you to change the default editor that SkyBox uses when opening projects with `skybox up --editor`. It runs interactively and shows your current editor setting. ### Supported Editors SkyBox has built-in support for: | Editor | Command | |--------|---------| | Cursor | `cursor` | | VS Code | `code` | | VS Code Insiders | `code-insiders` | | Zed | `zed` | | Other | custom command | You can also specify a custom editor command by selecting "Other (specify command)". Custom editor values can include flags, for example: * `code --reuse-window` * `open -a Zed` ### How Editors Are Opened When you run `skybox up --editor`, SkyBox launches your configured editor command directly. * For `cursor`, `code`, and `code-insiders`, SkyBox opens the Dev Container URI with `--folder-uri`. * For other editors, SkyBox opens the local project folder path. * On macOS, if a built-in editor command is missing from `PATH` (for example `zed`), SkyBox automatically falls back to `open -a `. ## Examples ```bash # Change default editor skybox editor ``` ### Interactive Session ``` Editor Configuration Current default: cursor ? Select default editor: 1) Cursor (current) 2) VS Code 3) VS Code Insiders 4) Zed 5) Other (specify command) Answer: 2 Default editor updated to code. ``` ### Using a Custom Editor ``` ? Select default editor: Other (specify command) ? Enter editor command: open -a Zed Default editor updated to open -a Zed. ``` ## Configuration The editor setting is stored in `~/.skybox/config.yaml`. You can also set it during initial setup with `skybox init`. ## Exit Codes | Code | Meaning | |------|---------| | 0 | Success | | 1 | Error (SkyBox not configured or interactive prompt failure) | ## See Also * [skybox init](/reference/init) - Initial setup (also sets editor) * [skybox up](/reference/up) - Start container and open in editor --- --- url: /reference/encryption.md description: >- Manage project encryption at rest with skybox encrypt. Encrypt and decrypt remote project files using AES-256-GCM. --- # skybox encrypt Manage project encryption at rest. ## Usage ```bash skybox encrypt [project] ``` ## Subcommands | Subcommand | Description | |------------|-------------| | `enable [project]` | Enable encryption for a project | | `disable [project]` | Disable encryption for a project | ## Description The `encrypt` command manages per-project encryption at rest. When encryption is enabled for a project, `skybox down` encrypts the project directory on the remote server, and `skybox up` decrypts it before syncing. This protects project files on the remote server when not actively working. During active sessions, files are plaintext for Mutagen sync compatibility. ### How It Works * **On `skybox down`:** Project files are tarred, encrypted with AES-256-GCM, and plaintext is deleted from the remote * **On `skybox up`:** The encrypted archive is decrypted and extracted before sync starts * **Key derivation:** scrypt (memory-hard KDF) derives a 256-bit key from your passphrase * **Passphrase:** Never stored. You must enter it on every `skybox up` and `skybox down` ### Enable Encryption ```bash skybox encrypt enable [project] ``` If no project is specified, an interactive selection is shown. Enabling encryption requires a double confirmation: 1. Warning about passphrase-only recovery 2. Confirmation that you understand the risks After confirmation, you set your passphrase by entering it twice for confirmation. A random salt is generated and stored in the project config. ### Disable Encryption ```bash skybox encrypt disable [project] ``` If no project is specified, only projects with encryption enabled are shown. You must enter your passphrase to disable encryption. If an encrypted archive exists on the remote, it is automatically decrypted and extracted. ### Encryption Details | Component | Implementation | |-----------|---------------| | Key derivation | scrypt (`N=65536`, `r=8`, `p=1`, `maxmem=128 MiB`) | | Encryption | AES-256-GCM via `node:crypto` | | Salt | Random 16 bytes per project, stored in config | | Passphrase | Never stored — entered on every operation | ### Remote Directory Layout **When encrypted (project not in use):** ``` ~/code/myproject/myproject.tar.enc # encrypted archive ``` **During active work:** ``` ~/code/myproject/ # plaintext, actively synced ``` ### Config Format Per-project encryption in `config.yaml`: ```yaml projects: my-app: remote: work encryption: enabled: true salt: "a1b2c3d4..." kdf: "scrypt" kdfParamsVersion: 1 ``` ## Error Handling | Scenario | Behavior | |----------|----------| | Wrong passphrase | 3 attempts allowed, then exits | | Forgot passphrase | Data cannot be recovered — no reset mechanism | | Interrupted `skybox down` | Plaintext remains on remote, safe to retry | | Interrupted `skybox up` | Archive remains intact, safe to retry | ## Examples ```bash # Enable encryption for a project skybox encrypt enable my-app # Enable with interactive project selection skybox encrypt enable # Disable encryption skybox encrypt disable my-app ``` ### Workflow Example ```bash # Enable encryption skybox encrypt enable my-app # Work on the project (passphrase required to decrypt) skybox up my-app # Enter passphrase... # Done working (passphrase required to encrypt) skybox down my-app # Enter passphrase... # Project is now encrypted on remote ``` ## Exit Codes | Code | Meaning | |------|---------| | 0 | Success | | 1 | Error (no config, passphrase required, decryption failed) | ## Troubleshooting If you run into issues with encryption, see the [Troubleshooting Guide](/guide/troubleshooting#encryption-issues) for solutions to common problems like forgotten passphrases and decryption errors. ## See Also * [skybox up](/reference/up) - Decrypts project on start * [skybox down](/reference/down) - Encrypts project on stop * [skybox config](/reference/config) - View configuration * [Configuration Reference](/reference/configuration) - Full config format --- --- url: /reference/hook.md description: >- Output shell hook code for auto-starting containers when entering project directories with skybox hook. --- # skybox hook Output shell hook code for auto-starting containers when entering project directories. ## Usage ```bash skybox hook [shell] ``` ## Arguments | Argument | Required | Description | |----------|----------|-------------| | `shell` | No | Shell type: `bash` or `zsh` | ## Description The `hook` command outputs shell code that integrates SkyBox with your shell. When installed, this hook automatically starts containers when you `cd` into a SkyBox project directory. The hook: * Runs on every prompt (via `PROMPT_COMMAND` for bash, `precmd` for zsh) * Only triggers when the directory actually changes * Runs container startup in the background (doesn't block your prompt) * Respects the `auto_up` configuration setting per project ## Installation Add the appropriate line to your shell configuration file: ### Bash ```bash echo 'eval "$(skybox hook bash)"' >> ~/.bashrc source ~/.bashrc ``` ### Zsh ```bash echo 'eval "$(skybox hook zsh)"' >> ~/.zshrc source ~/.zshrc ``` ## Configuration The hook only auto-starts containers for projects with `auto_up` enabled. Enable it globally in `~/.skybox/config.yaml`: ```yaml defaults: auto_up: true ``` Or per-project by editing `~/.skybox/config.yaml` directly: ```yaml projects: my-project: remote: my-server auto_up: true ``` See [Shell Integration](/guide/shell-integration) for detailed configuration options. ## Examples ```bash # Output bash hook code skybox hook bash # Output zsh hook code skybox hook zsh # Install for bash (one-time setup) echo 'eval "$(skybox hook bash)"' >> ~/.bashrc # Verify hook is active (bash) echo "$PROMPT_COMMAND" # Should contain: _skybox_hook ``` ## Logging Auto-up activity is logged to: ``` ~/.skybox/logs/auto-up.log ``` View recent activity: ```bash cat ~/.skybox/logs/auto-up.log ``` ## Exit Codes | Code | Meaning | |------|---------| | 0 | Success | | 1 | Invalid or missing shell argument | ## See Also * [Shell Integration Guide](/guide/shell-integration) - Detailed setup and troubleshooting * [Configuration Reference](/reference/configuration) - `auto_up` setting documentation * [skybox up](/reference/up) - Manual container startup --- --- url: /reference/init.md description: >- Interactive setup wizard for configuring SkyBox. Set up remotes, SSH keys, and install dependencies with skybox init. --- # skybox init Interactive setup wizard for configuring SkyBox. ## Usage ```bash skybox init ``` ## Arguments This command takes no arguments. ## Options | Option | Description | |--------|-------------| | `--dry-run` | Preview what would happen without executing | ## Description The `init` command walks you through the initial SkyBox configuration: 1. **Dependency Check** - Verifies Docker and Node.js are installed 2. **Mutagen Installation** - Extracts the bundled Mutagen binary for file synchronization (if not already installed) 3. **Remote Server Configuration** - Sets up SSH connection to your remote server 4. **Editor Selection** - Configures your preferred code editor 5. **Encryption Default** - Optionally enable encryption for new projects by default If SkyBox is already configured, you'll be asked whether to reconfigure. ### Dependency Requirements * **Docker** - Required for running containers * **Node.js** - Required for the SkyBox CLI and devcontainer-cli ### Mutagen Installation Mutagen is bundled with SkyBox and extracted automatically during setup. In development mode (running from source), SkyBox falls back to downloading from GitHub if the bundled asset is not found. When downloading (dev mode only), SkyBox verifies the binary's integrity using **SHA256 checksum** — the download is verified against the official `SHA256SUMS` file before writing to disk. ### Remote Configuration The wizard configures your first remote server. You can add more remotes later with `skybox remote add`. The wizard allows you to: * Enter a name for the remote (e.g., "production", "personal") * Select an existing SSH host from your `~/.ssh/config` * Add a new server with hostname, username, and SSH key * Test the SSH connection * Optionally copy your SSH key to the server using `ssh-copy-id` * Set the remote base path for storing projects (default: `~/code`) SSH fields are validated as you enter them. Hostnames, usernames, key paths, and remote paths are checked for invalid characters (such as newlines or shell metacharacters) and will prompt you to re-enter if invalid. ### SSH Key Authentication SkyBox supports both **passwordless** and **passphrase-protected** SSH keys. When you select a passphrase-protected key during setup, SkyBox loads it into `ssh-agent` so you only need to enter your passphrase once per session. The behavior varies by platform: * **macOS** — You are offered the option to save the passphrase to the macOS Keychain. When enabled (`useKeychain: true` in config), the passphrase persists across reboots and you won't be prompted again. * **Linux** — The passphrase is held in `ssh-agent` for the duration of your current login session. You will need to re-enter it after logging out or rebooting. If no `ssh-agent` is running, SkyBox will inform you and provide instructions to start one: ```bash eval $(ssh-agent) ``` ::: tip If you already have your key loaded in `ssh-agent` (check with `ssh-add -l`), SkyBox will detect it and skip the passphrase prompt. ::: ### Editor Options SkyBox has built-in support for these editors: | Editor | Command | |--------|---------| | Cursor | `cursor` | | VS Code | `code` | | VS Code Insiders | `code-insiders` | | Zed | `zed` | | Other | custom command | Vim (`vim`), Neovim (`nvim`), and any custom editor command are also supported. ## Examples ```bash # Run the setup wizard skybox init ``` ### Example Session ``` Welcome to skybox setup! Checking dependencies... Docker installed Node.js available Installing mutagen... Mutagen installed Configure remote server ? Remote name: production ? Select SSH host: my-server (192.168.1.100) SSH connection successful ? Remote code directory: ~/code Remote directory exists Configure editor ? Preferred editor: Cursor Setting up skybox... Created ~/.skybox Saved configuration skybox is ready! Next steps: Push a local project: skybox push ./my-project Clone from remote: skybox clone Browse remote projects: skybox browse ``` ## Configuration File After running `init`, SkyBox creates a configuration file at `~/.skybox/config.yaml` containing: * Remote server configurations (supports multiple remotes) * Default editor * Sync settings and ignore patterns * Registered projects with remote associations ## See Also * [skybox remote](/reference/remote) - Add more remote servers * [skybox config](/reference/config) - View and modify configuration * [skybox editor](/reference/editor) - Change the default editor later * [skybox browse](/reference/browse) - View projects on remote server * [skybox push](/reference/push) - Push a local project to remote --- --- url: /reference/list.md description: >- List projects available on your local machine with skybox list. View local project names, paths, and container status. --- # skybox list List projects available on your local machine. ## Usage ```bash skybox list ``` ## Arguments This command takes no arguments. ## Options This command has no options. ## Description The `list` command shows all projects in your local SkyBox projects directory (`~/.skybox/Projects`). For each project, it displays: * Project name * Current git branch * Local path This gives you a quick overview of what projects are available to work on locally. ### Output Format Projects are displayed with their details: ``` Local projects: my-api Branch: main Path: /Users/you/.skybox/Projects/my-api frontend-app Branch: feature/new-ui Path: /Users/you/.skybox/Projects/frontend-app Run 'skybox up ' to start working. ``` If no projects exist locally: ``` No local projects yet. Run 'skybox clone ' or 'skybox push ./path' to get started. ``` ## Examples ```bash # List all local projects skybox list # Then start one skybox up my-api ``` ### Workflow Example ```bash # Check what's available locally skybox list # Output: # Local projects: # # my-api # Branch: main # Path: /Users/you/.skybox/Projects/my-api # Start working on it skybox up my-api --editor ``` ## Exit Codes | Code | Meaning | |------|---------| | 0 | Success | | 1 | Error (SkyBox not configured) | ## See Also * [skybox browse](/reference/browse) - List projects on remote server * [skybox up](/reference/up) - Start a project * [skybox status](/reference/status) - Show detailed project status * [skybox clone](/reference/clone) - Clone a project from remote --- --- url: /reference/logs.md description: >- Show container or sync logs for a project with skybox logs. Stream Docker and Mutagen output for debugging. --- # skybox logs Show container or sync logs for a project. ## Usage ```bash skybox logs [options] ``` ## Arguments | Argument | Description | |----------|-------------| | `` | Name of the project (required) | ## Options | Option | Description | |--------|-------------| | `-f, --follow` | Follow log output in real time | | `-n, --lines ` | Number of lines to show (default: `50`) | | `-s, --sync` | Show sync logs instead of container logs | ## Description The `logs` command has two modes depending on whether the `--sync` flag is provided: ### Container Logs (default) By default, `skybox logs` shows Docker container logs for the project. It looks up the running container by project path and passes the request to `docker logs`. The `--follow` and `--lines` options are forwarded to Docker. If no container is found for the project, an error is displayed. ### Sync Logs (`--sync`) When the `--sync` flag is provided, the command shows Mutagen sync session activity instead. It runs `mutagen sync monitor` filtered to the session matching the project name. This is useful for diagnosing file synchronization issues. Note: In sync mode, the `--follow` and `--lines` options are not used; Mutagen's monitor streams output continuously by default. ## Examples ```bash # Show last 50 lines of container logs skybox logs my-project # Follow container logs in real time skybox logs my-project --follow # Show last 200 lines skybox logs my-project --lines 200 # Show sync session activity skybox logs my-project --sync ``` ## Exit Codes | Code | Meaning | |------|---------| | 0 | Success | | 1 | Error (project not found, container not running, log retrieval failed) | ## See Also * [skybox up](/reference/up) - Start a project container * [skybox down](/reference/down) - Stop a project container * [skybox status](/reference/status) - Check project status --- --- url: /reference/new.md description: >- Create a new project on the remote server with skybox new. Scaffold projects from built-in or custom templates. --- # skybox new Create a new project on the remote server. ## Usage ```bash skybox new ``` ## Arguments This command takes no arguments. It runs interactively. ## Options | Option | Description | |--------|-------------| | `--dry-run` | Preview what would happen without executing | ## Description The `new` command creates a new project directly on your remote server. This is useful when you want to start fresh rather than pushing an existing local project. The command walks you through: 1. **Remote Selection** - Choose which remote server to create the project on 2. **Project Name** - Enter a valid project name 3. **Template Selection** - Choose a devcontainer template from the unified selector (built-in, git URL, or your custom templates) 4. **Encryption** - If default encryption is enabled, optionally enable encryption for the new project 5. **Clone Option** - Optionally clone the new project locally When encryption is enabled in this flow, SkyBox requires passphrase confirmation by prompting: * `Enter encryption passphrase:` * `Confirm passphrase:` ### Project Naming Rules Project names must: * Contain only letters, numbers, hyphens, and underscores * Not start with a hyphen or underscore * Not contain path separators (`/` or `\`) or traversal sequences (`..`) * Not already exist on the selected remote ### Template Selection The unified template selector offers three types of templates: * **Built-in templates** (Node.js, Bun, Python, Go, Generic) — creates an empty project with a devcontainer.json using that template's configuration * **Your custom templates** — local devcontainer.json files stored in `~/.skybox/templates/`. See [Custom Templates](/reference/custom-templates) for details * **Git URL** — clones a git repository to the remote as the project When selecting a built-in or custom template, SkyBox creates the project directory on the remote, writes the devcontainer.json, ensures `.skybox/*` is in `.gitignore`, and initializes a git repo. When using a git URL, SkyBox clones the repo and ensures `.skybox/*` is in `.gitignore`. ## Examples ```bash # Start the interactive wizard skybox new ``` ### Example Session ``` ─── Create a new project ─── ? Select remote: production ? Project name: my-new-api Checking remote... Name available ? Select a template: (use arrow keys) ...template options shown... Creating project on remote... done ? Clone this project locally now? (Y/n) ``` The template selector shows all available options: ``` ? Select a template: ── Built-in ── Node.js — Node (latest) with npm/yarn + Common Utils + Docker Bun — Bun (latest) + Common Utils + Docker Python — Python (latest) with pip/venv + Common Utils + Docker Go — Go (latest) + Common Utils + Docker Generic — Debian with Common Utils + Docker ── Other ── Enter git URL ── Your Templates ── Create new template ``` ### Using Custom Git URL ``` ? Select a template: Enter git URL... ? Git repository URL: https://github.com/org/template-repo.git ? Git history: > Start fresh (recommended) Keep original history Cloning template to remote... done ``` ## Templates For details on built-in templates, custom local templates, and the template selector, see [Custom Templates](/reference/custom-templates). ## Git History Options When using a custom git URL: **Start fresh (recommended):** * Removes the original `.git` directory * Initializes a new git repository * Your project starts with a clean history **Keep original history:** * Preserves the template's full git history * Useful for forking an existing project ## After Creation After creating a project, you're prompted to clone it locally: ``` ? Clone this project locally now? (Y/n) ``` * **Yes** - Syncs the project locally, then offers to start the dev container * **No** - Project exists only on remote; clone later with `skybox clone` If you choose to clone, SkyBox also prompts: ``` ? Start dev container now? (Y/n) ``` This lets you go from `skybox new` to a running container in a single flow. ## Exit Codes | Code | Meaning | |------|---------| | 0 | Success | | 1 | Error (project exists, clone failed, no config) | ## See Also * [skybox clone](/reference/clone) - Clone project from remote * [skybox push](/reference/push) - Push existing project to remote * [skybox browse](/reference/browse) - List projects on remote * [skybox remote](/reference/remote) - Manage remote servers * [Custom Templates](/reference/custom-templates) - Create and manage reusable templates --- --- url: /reference/open.md description: >- Open editor or shell for a running container without restarting it using skybox open. Attach to active dev environments. --- # skybox open Open editor or shell for a running container without restarting it. ## Usage ```bash skybox open [project] [options] ``` ## Arguments | Argument | Description | |----------|-------------| | `[project]` | Name of the project (optional, auto-detected from cwd or prompted) | ## Options | Option | Description | |--------|-------------| | `-e, --editor` | Open in editor only | | `-s, --shell` | Attach to shell only | | `--no-prompt` | Non-interactive mode | | `--dry-run` | Preview what would happen without executing | ## Description The `open` command provides quick access to a running container's editor or shell without going through the full `skybox up` workflow. It's designed for when you already have a container running and just want to: * Open another editor window * Attach a new shell session * Quickly jump into a project that's already up ### Key Differences from `skybox up` | Command | Behavior | |---------|----------| | `skybox up` | Creates session, resumes sync, starts container if needed, then opens editor/shell | | `skybox open` | Only works with running containers, just opens editor/shell | Use `skybox open` when: * Container is already running * You want quick access without session/sync checks * You need multiple editor windows or shell sessions Use `skybox up` when: * Starting a work session * Container might not be running * You need the full startup flow (session, sync, container start) ### Action Menu Without flags, `skybox open` presents the same action menu as `skybox up`: ``` ? What would you like to do? 1) Open in editor 2) Attach to shell 3) Both 4) Neither (just exit) ``` ### Container Must Be Running Unlike `skybox up`, the `open` command requires the container to already be running: ```bash $ skybox open my-project Error: Container for 'my-project' is not running. i Run 'skybox up' to start the container first. ``` ## Examples ```bash # Open action menu for a running project skybox open my-project # Open editor only (no prompts) skybox open my-project --editor # Attach to shell only skybox open my-project --shell # Open both editor and shell skybox open my-project --editor --shell # Auto-detect project from current directory cd ~/.skybox/Projects/my-project skybox open # Non-interactive mode (does nothing if no flags) skybox open my-project --no-prompt --editor ``` ### Workflow Example ```bash # Start your work session skybox up my-project --editor # Later, need another shell window skybox open my-project --shell # Or open in a different editor skybox open my-project --editor ``` ### Multiple Sessions Open multiple shells for the same running container: ```bash # Terminal 1: Main development skybox up my-project --attach # Terminal 2: Run tests skybox open my-project --shell # Terminal 3: Watch logs skybox open my-project --shell ``` ## Exit Codes | Code | Meaning | |------|---------| | 0 | Success | | 1 | Error (not configured, project not found, container not running) | ## See Also * [skybox up](/reference/up) - Start container with full workflow * [skybox shell](/reference/shell) - Direct shell access with auto-start option * [skybox status](/reference/status) - Check if container is running --- --- url: /reference/push.md description: >- Push a local project to the remote server with skybox push. Upload project files via SCP to your configured remote. --- # skybox push Push a local project to the remote server. ## Usage ```bash skybox push [name] ``` ## Arguments | Argument | Description | |----------|-------------| | `` | Path to the local project directory (required) | | `[name]` | Name for the project on remote. Defaults to the directory name if not specified. | ## Options | Option | Description | |--------|-------------| | `--dry-run` | Show what would happen without making changes | ## Description The `push` command uploads a local project to your configured remote server and sets up bidirectional sync. It performs the following steps: 1. **Path Resolution** - Resolves the provided path to an absolute path 2. **Remote Selection** - If multiple remotes are configured, prompts you to select which remote to push to 3. **Git Check** - Verifies project is a git repository (offers to initialize if not) 4. **Remote Check** - Checks if project already exists on remote (prompts to overwrite) 5. **Ownership Check** - If the project exists on remote, verifies you are the owner before allowing overwrite 6. **Remote Setup** - Creates the project directory on the remote server 7. **Local Copy** - Copies project to SkyBox projects directory 8. **Sync Setup** - Creates a Mutagen sync session for bidirectional synchronization (uses selective sync if project has `sync_paths` configured) 9. **Initial Sync** - Uploads all files to the remote 10. **Set Ownership** - Records you as the project owner on the remote 11. **Gitignore Check** - Ensures `.skybox/*` is in the project's `.gitignore` 12. **Registration** - Registers the project in SkyBox configuration 13. **Container Prompt** - Offers to start the development container immediately ### Git Repository SkyBox works best with git repositories. If the project isn't a git repo, you'll be prompted to initialize one. This enables: * Branch tracking in status output * Change detection * Better conflict resolution ### Project Naming If you don't specify a name, the directory name is used: ```bash skybox push ./my-awesome-project # Creates project named "my-awesome-project" skybox push ./my-awesome-project cool-api # Creates project named "cool-api" ``` ### Local Storage After pushing, the project is copied to `~/.skybox/Projects/` and sync is established between this location and the remote. ## Examples ```bash # Push current project with directory name skybox push ./my-project # Push with a custom name skybox push ./my-project my-api # Push project from anywhere skybox push /path/to/my-project ``` ### Container Auto-Start After pushing, you'll be prompted to start the development container: ```bash ? Start dev container now? (y/N) ``` Choosing **yes** runs the full [`skybox up`](/reference/up) flow: * Creates a session for your machine * Prompts for devcontainer template (if none exists) * Starts the container * Offers to open in your editor or attach to shell Choosing **no** displays the project location and you can start later with `skybox up`. ### Workflow Example ```bash # Start with an existing local project cd ~/code/my-new-app # Push it to remote and start container immediately skybox push . # ? Start dev container now? Yes # ─── Starting 'my-new-app'... ─── # ℹ Session started # ✔ Sync is active # ... ``` ### Project Ownership When you push a project, SkyBox automatically records you as the owner on the remote server (via the `ownership` section in `.skybox/state.lock`). This prevents other users from accidentally overwriting or deleting your projects. If someone else owns the project, the push is blocked: ``` Cannot overwrite: Project owned by 'alice' (created on alice-macbook) Contact the project owner to transfer ownership or use a different project name. ``` Projects without an ownership file (e.g., those created before this feature) can be pushed to by anyone, and ownership will be set on the next successful push. ### Overwrite Behavior If the project already exists on remote: ```bash skybox push ./my-project # Output: # Pushing 'my-project' to server:~/code/my-project... # Project already exists on remote # ? Project already exists on remote. Overwrite? (y/N) ``` You'll be prompted twice for confirmation to prevent accidental data loss. ## Exit Codes | Code | Meaning | |------|---------| | 0 | Success | | 1 | Error (path not found, git init failed, sync failed) | ## See Also * [skybox clone](/reference/clone) - Clone project from remote * [skybox browse](/reference/browse) - List projects on remote * [skybox up](/reference/up) - Start the container * [skybox list](/reference/list) - List local projects --- --- url: /reference/remote.md description: >- Manage remote server configurations with skybox remote. Add, edit, remove, and list configured remote servers. --- # skybox remote Manage remote server configurations. ## Usage ```bash skybox remote [options] ``` ## Subcommands | Subcommand | Description | |------------|-------------| | `add [name] [user@host:path]` | Add a new remote server | | `list` | List all configured remotes | | `remove ` | Remove a remote server | | `rename ` | Rename a remote server | ## Description The `remote` command manages connections to remote servers where your projects are stored and synced. SkyBox supports multiple remote servers, allowing you to organize projects across different machines (e.g., work server, personal server, client servers). ### Multi-Remote Support Each project is associated with exactly one remote. When you have multiple remotes configured, commands like `push`, `clone`, and `browse` will prompt you to select which remote to use. ## Subcommand Details ### `skybox remote add` Add a new remote server configuration. **Interactive mode:** ```bash skybox remote add ``` Walks you through: 1. Remote name (identifier) 2. Server hostname or IP 3. SSH username 4. Remote projects directory 5. SSH key selection 6. Connection test 7. Directory creation (if needed) All SSH fields are validated as you enter them. Hostnames, usernames, key paths, and remote paths are checked for invalid characters (such as newlines or shell metacharacters) and will prompt you to re-enter if invalid. **Direct mode:** ```bash skybox remote add [--key ] ``` | Option | Description | |--------|-------------| | `-k, --key ` | Path to SSH private key | ### `skybox remote list` Display all configured remotes. ```bash skybox remote list ``` Output: ``` production deploy@prod.example.com:~/code personal noor@home-server:~/projects ``` ### `skybox remote remove` Remove a remote configuration. ```bash skybox remote remove ``` If projects are associated with the remote, you'll be warned: ``` The following projects use this remote: my-app backend-api Remove remote anyway? (projects will need to be reassigned) (y/N) ``` ### `skybox remote rename` Rename a remote and update all project references. ```bash skybox remote rename ``` This automatically updates all projects that reference the old name. ## Examples ```bash # Interactive wizard to add a remote skybox remote add # Add remote directly skybox remote add myserver root@192.168.1.100:~/code # Add remote with specific SSH key skybox remote add myserver root@host:~/code --key ~/.ssh/id_ed25519 # List all remotes skybox remote list # Remove a remote skybox remote remove myserver # Rename a remote skybox remote rename myserver production ``` ### Typical Multi-Remote Setup ```bash # Add work server skybox remote add work deploy@work.example.com:~/projects # Add personal server skybox remote add personal me@home-server:~/code # Push project to specific remote skybox push ./my-project # ? Select remote: work # Clone from specific remote skybox clone my-project # ? Select remote: personal ``` ## Remote Entry Format Each remote is stored in the configuration with these fields: | Field | Description | |-------|-------------| | `host` | SSH hostname or IP address | | `user` | SSH username (or null to use SSH config default) | | `path` | Base directory for projects on the remote | | `key` | Path to SSH private key (or null to use SSH config default) | | `useKeychain` | macOS only: persist SSH key passphrase in Keychain (default: `false`) | Both passwordless and passphrase-protected SSH keys are supported. If you select a passphrase-protected key, SkyBox will prompt to load it into `ssh-agent` so you only enter the passphrase once. On macOS, you can set `useKeychain: true` to persist the passphrase across reboots. Example in `~/.skybox/config.yaml`: ```yaml remotes: production: host: prod.example.com user: deploy path: ~/code key: ~/.ssh/id_ed25519 useKeychain: true # macOS only: persist passphrase in Keychain personal: host: home-server user: null # Uses SSH config path: ~/projects key: null # Uses SSH config ``` ## SSH Key Setup SkyBox supports both passwordless and passphrase-protected SSH keys when adding a remote. If a passphrase-protected key is selected, SkyBox loads it into `ssh-agent` so you only need to enter the passphrase once. On macOS, you can enable `useKeychain: true` to persist the passphrase in the Keychain across reboots. When adding a remote, if the connection test fails, you'll be offered to copy your SSH key: ``` SSH connection failed Copy SSH key to server? (requires password) (Y/n) ``` This runs `ssh-copy-id` to install your public key on the server. ## Exit Codes | Code | Meaning | |------|---------| | 0 | Success | | 1 | Error (invalid format, remote not found, connection failed) | ## See Also * [skybox init](/reference/init) - Initial setup (creates first remote) * [skybox config](/reference/config) - View/modify configuration * [Configuration Reference](/reference/configuration) - Full config file format --- --- url: /reference/rm.md description: >- Remove a project from your local machine with skybox rm, with optional remote deletion. Clean up containers and files. --- # skybox rm Remove a project from your local machine, with optional remote deletion. ## Usage ```bash skybox rm [project] [options] ``` ## Arguments | Argument | Description | |----------|-------------| | `[project]` | Name of the project to remove. If omitted, shows an interactive multi-select list of all local projects. | ## Options | Option | Description | |--------|-------------| | `-f, --force` | Skip all confirmation prompts | | `-r, --remote` | Also delete the project from the remote server (requires double confirmation) | | `--dry-run` | Show what would happen without making changes | ## Description The `rm` command removes a project from your local machine. This is useful for freeing up disk space or cleaning up after switching to a different machine. The command performs the following steps: 1. **Confirmation** - Prompts for confirmation (unless `--force` is used) 2. **Session Cleanup** - Removes any active session for this project 3. **Container Cleanup** - Stops and removes the container and volumes 4. **Sync Termination** - Terminates the Mutagen sync session 5. **File Removal** - Deletes local project files 6. **Deregistration** - Removes project from SkyBox configuration ### Interactive Multi-Select When run without a project argument, `skybox rm` displays a checkbox list of all local projects. You can select multiple projects for batch removal using the spacebar and confirm with enter. ### Remote Interactive Multi-Select When run with `--remote` but **no project argument** (`skybox rm --remote`), the command enters an interactive flow for bulk-deleting projects from a remote server: 1. **Remote selection** - If multiple remotes are configured, prompts you to select which remote to delete from 2. **Project list** - Fetches all projects from the remote and displays them as a checkbox list (with branch names if available) 3. **Selection** - Select one or more projects using the spacebar, then press enter 4. **Double confirmation** - Lists the selected projects and requires two confirmations before proceeding 5. **Deletion** - Deletes each selected project from the remote. If a deletion fails, the remaining projects are still processed 6. **Local cleanup offer** - For each deleted remote project that also exists locally, prompts whether to remove the local copy too With `--force`, all confirmation prompts are skipped and local copies are kept by default (since the user did not explicitly opt in to local removal). ### Remote Deletion When using `--remote`, the command also deletes the project from the remote server. Because this is an irreversible action, it requires **double confirmation**: 1. First prompt: confirms you want to permanently delete from the remote 2. Second prompt: asks "Are you absolutely sure?" Both confirmations are skipped when `--force` is used. If the project does not exist locally but `--remote` is passed, the command skips local cleanup and proceeds directly to remote deletion. #### Ownership Check Remote deletion requires project ownership. If the project on the remote is owned by a different user, the deletion is blocked: ``` Only the project owner can delete remote projects. Project owned by 'alice' (created on alice-macbook) ``` Projects without an ownership file (created before this feature) can be deleted by anyone. ### Data Safety * Without `--remote`, remote files are **never deleted** * You can always restore a locally-removed project with `skybox clone` * Running containers are stopped before removal ### Session Handling If a session exists for this project, it will be removed as part of the cleanup. If another machine has an active session, the command continues with the removal since the project is being deleted locally. ## Examples ```bash # Remove a project (with confirmation) skybox rm my-project # Remove without confirmation skybox rm my-project --force # Remove locally and from remote (double confirmation) skybox rm my-project --remote # Force remove locally and from remote (no prompts) skybox rm my-project --remote --force # Interactive multi-select (no argument) skybox rm # Shows checkbox list: select projects with spacebar, confirm with enter # Interactive remote multi-select (no argument, --remote) skybox rm --remote # Prompts for remote, shows checkbox list of remote projects, double confirms # Force delete all selected remote projects (no prompts) skybox rm --remote --force ``` ### Interactive Session ```bash skybox rm my-project # Output: # ? Remove project 'my-project' locally? This will NOT delete remote files. (y/N) y # # Removing 'my-project'... # Session cleared # Container stopped # Container removed # Sync session terminated # Local files removed # # Project 'my-project' removed locally. Remote copy preserved. ``` ### Remote Deletion Session ```bash skybox rm my-project --remote # Output: # ? Remove project 'my-project' locally AND from the remote server? (y/N) y # # Removing 'my-project'... # Session cleared # Container stopped # Container removed # Sync session terminated # Local files removed # # ? This will permanently delete 'my-project' from server:~/code/my-project. Continue? (y/N) y # ? Are you absolutely sure? This action cannot be undone. (y/N) y # Deleted 'my-project' from remote # # Project 'my-project' removed locally and from remote. ``` ### Remote Multi-Select Session ```bash skybox rm --remote # Output: # ? Select a remote: work # ⠋ Fetching projects from work... # ? Select remote projects to delete: # ◻ old-api (main) # ◻ prototype (dev) # ◻ archived-site # (select with spacebar, confirm with enter) # # ⚠ The following projects will be permanently deleted from remote: # old-api # prototype # # ? Delete 2 project(s) from work? (y/N) y # ? Are you absolutely sure? This action cannot be undone. (y/N) y # Deleted 'old-api' from remote # ? 'old-api' also exists locally. Remove local copy too? (y/N) n # Deleted 'prototype' from remote # # Done. 2 of 2 project(s) deleted from work. ``` ### Workflow Example ```bash # Check disk usage of projects skybox status # Output shows my-old-project using 5GB # Remove it to free space skybox rm my-old-project # Later, if needed again skybox clone my-old-project ``` ## Exit Codes | Code | Meaning | |------|---------| | 0 | Success | | 1 | Error (SkyBox not configured, project not found, removal failed) | ## See Also * [skybox down](/reference/down) - Stop container (optionally with cleanup) * [skybox clone](/reference/clone) - Restore project from remote * [skybox list](/reference/list) - List local projects * [skybox status](/reference/status) - Check project disk usage --- --- url: /reference/shell.md description: >- Access an interactive shell inside a running container with skybox shell. Execute commands in your dev environment. --- # skybox shell Access an interactive shell inside a running container. ## Usage ```bash skybox shell [options] ``` ## Arguments | Argument | Description | |----------|-------------| | `` | Name of the project to access (required) | ## Options | Option | Description | |--------|-------------| | `-c, --command ` | Run a single command and exit instead of interactive shell | | `-f, --force` | Bypass session check (use with caution) | ## Description The `shell` command provides interactive shell access to a running development container. It performs the following steps: 1. **Configuration Check** - Verifies SkyBox is configured 2. **Project Verification** - Checks the project exists locally 3. **Session Check** - Verifies session status before allowing access 4. **Container Status** - Checks if container is running 5. **Auto-Start** - Offers to start the container if not running 6. **Shell Attach** - Opens an interactive shell inside the container ### Session Check Before attaching, `skybox shell` checks the project's session status: * If the project has an active session on **another machine**, the command warns you and shows which machine has the session. Use `--force` to bypass this check. * If **no session exists**, a warning is shown recommending you run `skybox up` first to start a session for safe editing. * If the session belongs to **your machine**, the command proceeds normally. Use `-f, --force` to skip the session check entirely (e.g., for quick read-only inspection). ### Interactive Mode By default, `skybox shell` opens an interactive `/bin/sh` session inside the container. The working directory is set to the `workspaceFolder` from `devcontainer.json` (defaults to `/workspaces/` if not specified). ### Command Mode With the `-c` flag, you can run a single command and exit. The exit code from the command is propagated back to your shell. ### Container Auto-Start If the container is not running, you'll be prompted: ``` Container is not running. Start it now? (Y/n) ``` Choosing **yes** runs `skybox up` with `--no-prompt` to start the container before attaching to the shell. ## Examples ```bash # Open interactive shell skybox shell my-project # Run a single command skybox shell my-project -c "npm run build" # Check Node version inside container skybox shell my-project -c "node --version" # Run tests inside container skybox shell my-project -c "npm test" # Bypass session check for quick inspection skybox shell my-project --force # Interactive shell for debugging skybox shell my-project # Then inside: ls -la, cat package.json, etc. ``` ### Workflow Example ```bash # Start a project skybox up my-project # Open shell to run commands skybox shell my-project # Inside container: # $ npm install # $ npm run dev # Press Ctrl+D to exit # Or run commands directly skybox shell my-project -c "npm install && npm run build" ``` ### Difference from `skybox up --attach` | Command | Behavior | |---------|----------| | `skybox up --attach` | Starts container + creates session + attaches shell | | `skybox shell` | Checks session + attaches to existing/started container | Use `skybox shell` when: * Container is already running * You just want shell access without the full startup flow * You want to run a quick command Use `skybox up --attach` when: * Starting a work session * You need a session created * Container might not be running ## Exit Codes | Code | Meaning | |------|---------| | 0 | Success (interactive mode exited cleanly) | | 1 | Error (project not found, container failed to start, session active on another machine) | | \* | Command exit code (when using `-c` flag) | ## See Also * [skybox up](/reference/up) - Start the container * [skybox down](/reference/down) - Stop the container * [skybox status](/reference/status) - Check container status --- --- url: /reference/status.md description: >- Show status of projects or detailed information about a specific project with skybox status. View container and sync state. --- # skybox status Show status of projects or detailed information about a specific project. ## Usage ```bash skybox status [project] ``` ## Arguments | Argument | Description | |----------|-------------| | `[project]` | Name of the project to show detailed status for. If omitted, shows overview of all projects. | ## Options This command has no options. ## Description ::: tip Live Updates For a real-time, auto-refreshing view of all projects, use [`skybox dashboard`](/reference/dashboard) instead. ::: The `status` command displays information about your SkyBox projects. It has two modes: ### Overview Mode (no argument) Shows a table of all local projects with columns: | Column | Description | |--------|-------------| | NAME | Project name | | CONTAINER | Container status (running/stopped) | | SYNC | Sync status (syncing/paused/error/no session) | | BRANCH | Current git branch | | SESSION | Session status (none/active here/active on machine) | | LAST ACTIVE | Time since last activity | | SIZE | Local disk usage | ### Detailed Mode (with project name) Shows comprehensive information organized into sections: **Container** * Status (running/stopped) * Image name * Uptime * CPU usage * Memory usage **Sync** * Status (syncing/paused/error) * Session name * Pending files * Last sync time **Git** * Current branch * Working tree status (clean/dirty) * Commits ahead of upstream * Commits behind upstream **Session** * Session status (none / active here / active on another machine) * Machine name (if active) * User and start time **Disk Usage** * Local size * Remote size ## Examples ```bash # Show overview of all projects skybox status # Show detailed status of specific project skybox status my-api ``` ### Overview Output Example ``` Projects: NAME CONTAINER SYNC BRANCH SESSION LAST ACTIVE SIZE my-api running syncing main active here 2 hours ago 1.2G frontend-app stopped paused dev none 3 days ago 856M data-service running syncing main active here just now 2.1G ``` ### Detailed Output Example ```bash skybox status my-api # Output: # Project: my-api # -------------------------------------------------- # # Container # Status: running # Image: node:20 # Uptime: 2 hours # CPU: 0.5% # Memory: 256MiB / 8GiB # # Sync # Status: syncing # Session: skybox-my-api # Pending: 0 files # Last sync: - # # Git # Branch: main # Status: clean # Ahead: 0 commits # Behind: 0 commits # # Session # Status: none # # Disk Usage # Local: 1.2G # Remote: 1.2G ``` ## Exit Codes | Code | Meaning | |------|---------| | 0 | Success | | 1 | Error (SkyBox not configured, project not found) | ## See Also * [skybox list](/reference/list) - Simple list of local projects * [skybox up](/reference/up) - Start a container * [skybox down](/reference/down) - Stop a container --- --- url: /reference/up.md description: >- Start a development container for a project with skybox up. Launch containers with bidirectional file sync. --- # skybox up Start a development container for a project. ## Usage ```bash skybox up [project] [options] ``` ## Arguments | Argument | Description | |----------|-------------| | `[project]` | Name of the project to start. If omitted, SkyBox will try to detect the project from the current directory or prompt for selection. | ## Options | Option | Description | |--------|-------------| | `-e, --editor` | Open in editor after container starts | | `-a, --attach` | Attach to shell after container starts | | `-r, --rebuild` | Force container rebuild | | `--no-prompt` | Non-interactive mode (errors instead of prompting) | | `--verbose` | Show detailed error output on container start failure | | `-A, --all` | Start all local projects in batch mode (tallies success/failure counts) | | `--dry-run` | Show what would happen without making changes | ## Description The `up` command starts a development container for the specified project. It performs the following steps: 1. **Project Resolution** - Determines which project to start (from argument, current directory, or interactive selection) 2. **Pre-Up Hooks** - Runs any configured `pre-up` hooks, e.g. `git pull` (see [Hooks](/reference/hooks)) 3. **Session Check** - Creates a session for your machine, warning if the project is active elsewhere 4. **Archive Decryption** - If encryption is enabled, decrypts the project archive on the remote 5. **Sync Check** - Ensures the Mutagen sync session is active, resuming it if paused 6. **Gitignore Check** - Ensures `.skybox/*` is in `.gitignore` on the remote (self-healing) 7. **Container Management** - Starts the container (or handles existing running containers) 8. **Devcontainer Setup** - Creates devcontainer.json from templates if needed 9. **Post-Up Hooks** - Runs any configured `post-up` hooks, e.g. `npm run db:migrate` (see [Hooks](/reference/hooks)) 10. **Post-Start Actions** - Optionally opens editor or attaches to shell ### Project Auto-Detection When no project argument is given, SkyBox resolves the project in this order: 1. Checks if the current working directory is inside a known project 2. Prompts with a multi-select checkbox to start one or more projects at once (unless `--no-prompt` is set) ### Session System SkyBox uses a session system to detect when a project is active on another machine. When starting a project: * If no session exists, one is created automatically for your machine * If your machine already has the session, the timestamp is updated * If another machine has an active session, you are warned and asked to continue * With `--no-prompt`, a session conflict causes an error instead of prompting ### Archive Decryption If the project has encryption enabled and an encrypted archive exists on the remote server, SkyBox will: 1. Prompt for your passphrase (up to 3 attempts) 2. Download the encrypted archive from the remote 3. Decrypt it locally using AES-256-GCM 4. Upload the decrypted files back to the remote 5. Extract and clean up If decryption fails after 3 attempts, `skybox up` exits without starting the container. See [`skybox encrypt`](/reference/encryption) for more details. ### Sync Resume If the Mutagen sync session exists but is paused (e.g., from a previous `skybox down`), it is automatically resumed during startup. ### Container Auto-Rebuild If the container fails to start on the first attempt, SkyBox automatically retries with a full rebuild. If the rebuild also fails, the error is displayed. Use `--verbose` to see the full error output. ### Container Rebuild SkyBox handles container rebuilds automatically when you pass `--rebuild`. No manual `devcontainer` CLI flags are needed. ### Devcontainer Templates If no `.devcontainer/devcontainer.json` exists, SkyBox offers to create one using the unified template selector. You can choose from built-in templates and your custom local templates stored in `~/.skybox/templates/`. ### Container States If the container is already running, you can choose to: * Continue with the existing container * Restart the container * Rebuild the container from scratch ### Post-Start Action Prompt After the container starts, SkyBox determines what to do next: * If `-e` is passed: opens the configured editor * If `-a` is passed: attaches to the container shell * If both `-e` and `-a` are passed: opens editor then attaches shell * If `--no-prompt` is passed: exits without further action * Otherwise: prompts you to choose from editor, shell, both, or exit ### Multi-Project Start When no project argument is given and multiple local projects exist, SkyBox shows a checkbox to select one or more projects. Selected projects are started sequentially. After all projects start, you can choose to open all, choose specific ones, or skip. ### Batch Mode With `-A, --all`, SkyBox starts every local project sequentially and reports a summary of how many succeeded and how many failed. ## Examples ```bash # Start a specific project skybox up my-project # Start project and open in editor skybox up my-project --editor # Start project and attach to shell skybox up my-project --attach # Start with both editor and shell skybox up my-project -e -a # Force rebuild the container skybox up my-project --rebuild # Non-interactive start (for scripts) skybox up my-project --no-prompt # Show full error logs on failure skybox up my-project --verbose # Start all local projects skybox up --all # Multi-select start (no argument) skybox up # Shows checkbox to pick which projects to start # Start from within project directory cd ~/.skybox/Projects/my-project skybox up ``` ### Workflow Example ```bash # Clone a project from remote skybox clone awesome-project # Start working on it skybox up awesome-project --editor # Or do it all in one go (clone offers to start container) skybox clone another-project # Answer "yes" when prompted to start container ``` ## Exit Codes | Code | Meaning | |------|---------| | 0 | Success | | 1 | Error (project not found, container failed to start, session conflict in non-interactive mode) | ## See Also * [skybox down](/reference/down) - Stop the container * [skybox status](/reference/status) - Check container status * [skybox clone](/reference/clone) - Clone a project from remote * [skybox editor](/reference/editor) - Change default editor * [Custom Templates](/reference/custom-templates) - Create and manage reusable templates * [Hooks](/reference/hooks) - Run commands before/after lifecycle events --- --- url: /reference/update.md description: >- Check for and install SkyBox updates with skybox update. Download the latest version from GitHub releases. --- # skybox update Check for and install SkyBox updates. ## Usage ```bash skybox update ``` ## Description The `update` command checks GitHub Releases for a newer version of SkyBox and either performs the update automatically or tells you the right command for your install method. ### Behavior by Install Method | Install Method | Behavior | |---------------|----------| | **Direct download** (GitHub Release binary) | Downloads the new binary and replaces the current one in place | | **Homebrew** | Shows the `brew upgrade skybox` command to run | | **Source** | Shows the `git pull && bun install` command to run | For direct download users, `skybox update` is the primary way to stay up to date. You'll also see a passive notification after any command when a new version is available: ``` Update available: 0.7.7 → 0.8.0. Run: skybox update ``` ### Self-Update Process (Direct Download) When installed via GitHub Release binary, the command: 1. **Verifies permissions** — checks write access to the binary directory before downloading 2. **Downloads checksum** — fetches `checksums.txt` from the release for integrity verification 3. **Downloads** the correct platform binary (e.g., `skybox-darwin-arm64`) to a temp file 4. **Verifies integrity** — computes SHA-256 of the download and compares against the expected checksum 5. **Prepares binary** — sets executable permissions and removes macOS quarantine attributes 6. **Backs up** the current binary before replacing it 7. **Replaces** the current binary atomically (rename temp over current) 8. **Verifies** the new binary runs correctly (`--version` check) 9. **Rolls back** automatically if verification fails, restoring the previous version If `checksums.txt` is not available for a release (e.g., older releases), the update proceeds with a warning but skips integrity verification. ## Examples ```bash # Check and update skybox update # Output when up to date: # Checking for updates... # ✔ No update available. You are on the latest version (0.8.0). # Output when updating (direct download): # Checking for updates... # ✔ SkyBox updated to v0.8.1 (verified). # Output when update available (Homebrew): # Checking for updates... # Update available: 0.7.7 → 0.8.0 # Run: brew upgrade skybox # Output when permission denied: # ✗ Cannot update: permission denied for /usr/local/bin. Try running with sudo. # Output when checksum fails: # ✗ Checksum verification failed. # ✗ The downloaded binary does not match the expected checksum. The download may be corrupted. # Output when post-update verification fails: # ✗ Update verification failed. # ✗ The new binary did not report version 0.8.1. Restored previous version. ``` ## Exit Codes | Code | Meaning | |------|---------| | 0 | Success (up to date or updated) | | 1 | Error (permission denied, network failure, checksum mismatch, or verification failed) | ## See Also * [skybox doctor](/reference/doctor) - Diagnose common issues * [Installation Guide](/guide/installation) - Install methods --- --- url: /guide/troubleshooting.md description: >- Resolve common SkyBox issues with Docker, sync, SSH connections, and container startup. Run skybox doctor for automated diagnostics. --- # Troubleshooting Common issues and solutions for SkyBox. ## First Step: Run Doctor Before diving into specific issues, run the built-in diagnostic tool: ```bash skybox doctor ``` This checks Docker, Mutagen, editor setup, SSH connectivity, and configuration in one command. It will identify most common problems and suggest fixes. ::: tip Debug Mode For verbose output on any command, prefix with `DEBUG=1`: ```bash DEBUG=1 skybox up myproject ``` ::: ## Editor Issues ### Editor Command Not Found (for example `zed`) **Symptoms:** * `skybox up --editor` or `skybox open --editor` fails to launch your editor * Error mentions command not found (`ENOENT`) **Solutions:** 1. **Run doctor** to inspect editor setup: ```bash skybox doctor ``` 2. **Set an explicit editor command** that works on your machine: ```bash skybox config set editor "open -a Zed" ``` Other examples: * `skybox config set editor "code --reuse-window"` * `skybox config set editor "cursor"` 3. **Install editor CLI tools** if you prefer direct commands (`zed`, `code`, `cursor`) instead of `open -a`. On macOS, SkyBox automatically tries a built-in app fallback for supported GUI editors (Cursor, VS Code, VS Code Insiders, Zed) when the CLI command is missing from `PATH`. ## Encryption Issues ### Forgotten Passphrase **Symptoms:** * Cannot decrypt project configuration * `skybox` prompts for passphrase and rejects all attempts **Solutions:** ::: danger Data Loss Warning Encrypted data **cannot be recovered** without the passphrase. There is no reset or recovery mechanism. If you have lost your passphrase, the encrypted configuration is permanently inaccessible. ::: 1. **Re-initialize the project** from an unencrypted backup or by re-creating the configuration from scratch. ### Decryption Errors **Symptoms:** * `Error: Decryption failed` when running commands * Garbled output from config operations **Solutions:** 1. **Verify the correct passphrase** - ensure no extra whitespace or encoding issues. 2. **Check config file integrity:** ```bash skybox config --validate ``` 3. **Re-encrypt from a clean state** if the encrypted file was corrupted (e.g., partial write during crash). See also: [Concepts: Encryption](/guide/concepts#encryption), [`skybox encrypt`](/reference/encryption) ## Selective Sync Issues ### Sync Path Not Syncing **Symptoms:** * Specified paths are not being synchronized * No errors shown but files are missing on remote **Solutions:** 1. **Check path format** - selective sync paths must be: * **Relative** to the project root (no leading `/`) * No `..` parent traversal * Example: `src/components` (correct), `/src/components` (incorrect), `../other` (incorrect) 2. **Verify configuration:** Open `~/.skybox/config.yaml` and check your project's configuration: ```bash skybox config ``` Confirm the `sync_paths` entries use the correct relative format. 3. **Restart sync** after changing selective sync settings: ```bash skybox down myproject skybox up myproject ``` See also: [Concepts: Selective Sync](/guide/concepts#selective-sync), [Configuration: Sync Modes](/reference/configuration#sync-modes) ## Mutagen Issues ### Mutagen Binary Missing or Corrupted **Symptoms:** * Mutagen binary not found after setup * Sync operations fail unexpectedly **Solutions:** 1. **Run doctor** to diagnose and repair: ```bash skybox doctor ``` Doctor will detect a missing or outdated Mutagen binary and re-extract it automatically. 2. **Re-run init** to re-extract the bundled binary: ```bash skybox init ``` 3. **Dev mode only** — if running from source and the download fallback fails, check network connectivity: ```bash curl -I https://github.com/mutagen-io/mutagen/releases ``` 4. **Manual installation** — download the Mutagen binary and place it at `~/.skybox/bin/mutagen`. ### Version Mismatches **Symptoms:** * Sync errors after updating SkyBox * `skybox doctor` reports Mutagen version issues **Solutions:** 1. **Run doctor** — it will detect the version mismatch and re-extract the correct bundled version: ```bash skybox doctor ``` 2. **Upgrade SkyBox** — Mutagen is bundled with SkyBox, so upgrading SkyBox brings the correct Mutagen version automatically: ```bash skybox update ``` ## Batch Operation Issues ### Partial Failures in `--all` Mode **Symptoms:** * Some projects succeed while others fail during batch operations (e.g., `skybox down --all`) * Mixed success/error output ::: info Batch behavior When using `--all`, SkyBox processes projects sequentially. If a project fails, the batch continues with remaining projects and reports a success/failure summary at the end. ::: **Solutions:** 1. **Check per-project errors** - the output lists which projects failed and why. Address each failure individually. 2. **Re-run for failed projects only:** ```bash skybox up failed-project ``` 3. **Run diagnostics on failing projects:** ```bash skybox doctor skybox status failed-project ``` ## Devcontainer Issues ### Container Won't Start After Config Changes **Symptoms:** * Container fails to start after editing `devcontainer.json` * Build errors or invalid configuration **Solutions:** 1. **Reset devcontainer configuration** to regenerate from template: ```bash skybox config devcontainer reset ``` 2. **Rebuild the container:** ```bash skybox up --rebuild ``` ## Connection Issues ### SSH Connection Failed **Symptoms:** * `skybox init` fails to connect * [`skybox browse`](/reference/browse) times out **Solutions:** 1. **Test SSH manually:** ```bash ssh your-host ``` 2. **Check SSH config:** ```bash cat ~/.ssh/config ``` 3. **Verify host is reachable:** ```bash ping your-host ``` 4. **Check SSH key permissions:** ```bash chmod 600 ~/.ssh/id_rsa chmod 644 ~/.ssh/id_rsa.pub ``` ### Passphrase-Protected Keys **Symptoms:** * SkyBox prompts for a passphrase during commands * SSH key is not loaded in `ssh-agent` **Solutions:** 1. **On macOS** — Enable `useKeychain: true` in your remote configuration to persist the passphrase across reboots: ```yaml remotes: myserver: host: example.com user: deploy path: ~/code key: ~/.ssh/id_ed25519 useKeychain: true ``` 2. **On Linux** — Load your key into `ssh-agent` before starting SkyBox, or add it to your shell profile (e.g., `~/.bashrc`): ```bash ssh-add ~/.ssh/your_key ``` 3. **If `ssh-add` fails** with "Could not open a connection to your authentication agent", start the agent first: ```bash eval $(ssh-agent) ssh-add ~/.ssh/your_key ``` ### Permission Denied **Symptoms:** * `Permission denied (publickey)` **Solutions:** 1. **Add key to SSH agent** (both passwordless and passphrase-protected keys are supported): ```bash ssh-add ~/.ssh/id_rsa ``` 2. **Specify key in skybox config:** ```bash skybox remote add myserver user@host --key ~/.ssh/specific_key ``` 3. **For passphrase-protected keys**, ensure the key is loaded in `ssh-agent` (see [Passphrase-Protected Keys](#passphrase-protected-keys) above). ## Container Issues ### Container Won't Start **Symptoms:** * `skybox up` hangs or fails * Container status shows "error" **Solutions:** 1. **Check Docker is running:** ```bash docker ps ``` 2. **Rebuild container:** ```bash skybox up myproject --rebuild ``` 3. **Check container logs for errors:** ```bash skybox logs myproject ``` See [`skybox logs`](/reference/logs) for more options. 4. **Check devcontainer.json:** ```bash cat ~/.skybox/Projects/myproject/.devcontainer/devcontainer.json ``` ### Container Not Found **Symptoms:** * `skybox shell` says container not found **Solutions:** 1. **Start the container first:** ```bash skybox up myproject ``` 2. **Check container status:** ```bash skybox status myproject ``` See also: [Concepts: Containers](/guide/concepts#containers), [`skybox up`](/reference/up) ## Sync Issues ### Sync Not Working **Symptoms:** * Files not appearing on remote * `skybox status` shows sync errors **Solutions:** 1. **Check Mutagen status:** ```bash ~/.skybox/bin/mutagen sync list ``` 2. **Check container logs** for errors that may indicate sync-related issues: ```bash skybox logs myproject ``` 3. **Restart sync session:** ```bash skybox down myproject skybox up myproject ``` 4. **Check ignored files:** Review `defaults.ignore` in `~/.skybox/config.yaml` ### Sync Conflicts **Symptoms:** * Mutagen reports conflicts **Solutions:** 1. **Check Mutagen conflicts:** ```bash ~/.skybox/bin/mutagen sync list --long ``` 2. **Resolve manually:** Choose which version to keep and delete the other See also: [Concepts: Sync](/guide/concepts#sync), [Configuration: Sync Modes](/reference/configuration#sync-modes) ## Session Issues ### Project Active on Another Machine **Symptoms:** * `skybox up` warns that the project is running on another machine * Message: "This project is running on \[machine]" **Solutions:** 1. **Proper handoff:** On the other machine: ```bash skybox down myproject ``` 2. **Continue anyway:** When prompted during `skybox up`, choose "Continue anyway" if you know the other machine is idle. 3. **Wait for expiry:** Sessions automatically expire after 24 hours if the other machine crashed without running `skybox down`. ### Stale Session **Symptoms:** * Session from a crashed machine * Machine listed no longer exists or is unreachable **Solutions:** 1. **Start the project:** Sessions expire after 24 hours automatically. If expired, `skybox up` proceeds without warning: ```bash skybox up myproject ``` 2. **Continue past the warning:** If the session hasn't expired yet: ```bash skybox up myproject # Choose "Continue anyway" when prompted ``` 3. **Bypass session check for shell access:** ```bash skybox shell myproject --force ``` See also: [Concepts: Session System](/guide/concepts#session-system), [Multi-Machine Workflow](/guide/workflows/multi-machine) ## Configuration Issues ### Config File Corrupted **Symptoms:** * YAML parse errors * Commands fail immediately **Solutions:** 1. **Validate config:** ```bash skybox config --validate ``` 2. **Reset config:** ```bash rm ~/.skybox/config.yaml skybox init ``` ### Missing Remote **Symptoms:** * "Remote 'xxx' not found" **Solutions:** 1. **List remotes:** ```bash skybox remote list ``` 2. **Add missing remote:** ```bash skybox remote add myremote user@host ``` ## Input Validation Errors SkyBox validates user input to prevent security issues. Here are common validation errors and how to resolve them. ### SSH Field Validation When adding remotes or running `skybox init`, SSH fields (hostname, username, key path) are restricted to alphanumeric characters and `@ . _ ~ : - /`. If you see errors like: * **"Hostname contains invalid characters"** — Remove spaces, quotes, or special characters from the hostname * **"Username cannot contain newlines"** — Re-enter the username without line breaks ### Project Name Restrictions Project names cannot contain: * Path separators (`/` or `\`) * Traversal sequences (`..`) * Leading dashes (`-`) If you see **"Project name cannot contain path separators"**, use a simple name like `my-app` instead. ### Remote Path Restrictions Remote paths cannot contain shell metacharacters. If you see: * **"Remote path cannot contain command substitution"** — Remove `$()`, `${}`, or backtick expressions from the path * **"Remote path cannot contain shell metacharacters"** — Remove `;`, `|`, or `&` characters from the path Use a plain path like `~/code` or `/home/user/projects`. ## Security & Integrity Issues ### Config Validation Errors **Symptoms:** * `skybox doctor` reports config validation failure * Error message: `Config file exists but failed validation` ``` ✗ Configuration: Config file exists but failed validation ``` This means your `~/.skybox/config.yaml` doesn't match the expected schema. **Common causes:** 1. **Invalid field types** — e.g., `auto_up: "yes"` instead of `auto_up: true` 2. **Unknown fields** — typos in field names 3. **Missing required fields** — `host` and `path` are required for each remote **Solutions:** 1. **Open your config and check for YAML syntax errors or invalid values:** ```bash $EDITOR ~/.skybox/config.yaml ``` 2. **Validate config:** ```bash skybox config --validate ``` 3. **Reset config** if the file is beyond repair: ```bash rm ~/.skybox/config.yaml skybox init ``` ### Session Integrity Warning **Symptoms:** * Warning during `skybox up`: `Session file integrity check failed` * Session treated as invalid despite existing session file ``` Warning: Session file integrity check failed ``` This means a session file was modified outside of SkyBox (the HMAC-SHA256 signature doesn't match). The session will be treated as invalid. **Common causes:** * Manual editing of `.skybox/state.lock` files * File corruption during sync **Solutions:** 1. **Stop and restart the project:** ```bash skybox down myproject skybox up myproject ``` 2. **If the project won't stop cleanly**, the session file can be removed manually: ```bash rm ~/.skybox/Projects/myproject/.skybox/state.lock skybox up myproject ``` ### Lockfile Verification Failed **Symptoms:** * Error message: `Lockfile integrity check failed` * SkyBox refuses to start This is a supply-chain security check on `bun.lock`. It means the lockfile was modified in a way that doesn't match expected integrity hashes. **Solutions:** 1. **Reinstall dependencies from a clean state:** ```bash rm bun.lock bun install ``` 2. **Verify no unexpected changes** were introduced to your dependencies after reinstalling. See also: [Concepts: Session System](/guide/concepts#session-system), [Configuration](/reference/configuration) ## Getting Help If these solutions don't help: 1. **Run diagnostics:** ```bash skybox doctor ``` 2. **Check project status:** ```bash skybox status myproject ``` 3. **Run with verbose:** ```bash DEBUG=1 skybox up myproject ``` 4. **Report an issue:** [GitHub Issues](https://github.com/NoorXLabs/SkyBox/issues) ## Next Steps * [Daily Development Workflow](/guide/workflows/daily-development) - Day-to-day patterns for working with SkyBox * [Core Concepts](/guide/concepts) - Understand how projects, containers, and sync work together * [`skybox doctor`](/reference/doctor) - Built-in diagnostic tool reference