un-inception/clients/CLI_SPEC.md
russell@unturf.com eeb1dcb3dc feat: add --show-freeze-page and --no-show-freeze-page CLI flags
Add CLI support for toggling the show_freeze_page service setting,
which controls whether frozen services display an HTML payment page
or return a JSON error response.

Updated 18 SDK implementations + CLI_SPEC.md documentation.
2026-01-25 04:28:24 -05:00

10 KiB

Unsandbox CLI Specification

Every SDK implementation MUST include a CLI interface identical to un.c.

One file. One CLI spec. 42+ languages. All implementing the same API.

Core Principle

Each SDK file (un.py, un.js, un.rb, etc.) is BOTH:

  1. A library - Can be imported/required by other code
  2. A CLI tool - Can be executed directly from command line
# Library usage
python -c "from un import execute_code; print(execute_code('python', 'print(1)'))"

# CLI usage
python un.py script.py
python un.py -s bash 'echo hello'
python un.py session --tmux

CLI Entry Points

Each language must detect when run as main:

# Python
if __name__ == "__main__":
    cli_main()
// JavaScript (Node.js)
if (require.main === module) {
    cliMain();
}
# Ruby
if __FILE__ == $0
  cli_main
end
// Go - separate main.go that imports the library
func main() {
    un.CliMain()
}

Command Structure

un [options] <source_file>        # Execute code file
un session [options]              # Interactive session
un service [options]              # Manage services
un snapshot [options]             # Manage snapshots
un image [options]                # Manage images
un languages [options]            # List available languages
un key                            # Check API key

Global Options

Option Short Description
--shell LANG -s Language for inline code
--env KEY=VAL -e Set environment variable
--file FILE -f Add input file to /tmp/
--file-path FILE -F Add input file with path preserved
--artifacts -a Return compiled artifacts
--output DIR -o Output directory for artifacts
--public-key KEY -p API public key
--secret-key KEY -k API secret key
--network MODE -n Network: zerotrust or semitrusted
--vcpu N -v vCPU count (1-8)
--yes -y Skip confirmation prompts
--help -h Show help

Execute Command (Default)

un script.py                      # Execute Python script
un -s bash 'echo hello'           # Inline bash command
un -e DEBUG=1 script.py           # With environment variable
un -f data.csv process.py         # With input file
un -a -o ./bin main.c             # Save compiled artifacts
un -n semitrusted crawler.py      # With network access

Session Command

un session                        # Interactive bash
un session --shell python3        # Python REPL
un session --tmux                 # Persistent session (can reconnect)
un session --screen               # Persistent with screen
un session --list                 # List active sessions
un session --attach ID            # Reconnect to session
un session --kill ID              # Terminate session
un session --freeze ID            # Pause session
un session --unfreeze ID          # Resume session
un session --boost ID             # Add resources
un session --unboost ID           # Remove boost
un session --snapshot ID          # Create snapshot
un session -n semitrusted         # With network access

Session Options

Option Description
--shell SHELL Shell/REPL to use (default: bash)
--list, -l List active sessions
--attach ID Reconnect to existing session
--kill ID Terminate a session
--freeze ID Pause session
--unfreeze ID Resume session
--boost ID Add vCPUs/RAM
--unboost ID Remove boost
--tmux Enable persistence with tmux
--screen Enable persistence with screen
--snapshot ID Create snapshot
--snapshot-name NAME Name for snapshot
--hot Live snapshot (no freeze)
--audit Record session

Service Command

un service --list                 # List all services
un service --name myapp --ports 80 --bootstrap "python -m http.server 80"
un service --info ID              # Get service details
un service --logs ID              # Get bootstrap logs
un service --freeze ID            # Pause service
un service --unfreeze ID          # Resume service
un service --destroy ID           # Delete service
un service --lock ID              # Prevent deletion
un service --unlock ID            # Allow deletion
un service --execute ID 'cmd'     # Run command in service
un service --redeploy ID          # Re-run bootstrap
un service --snapshot ID          # Create snapshot

Service Options

Option Description
--name NAME Service name (creates new)
--ports PORTS Comma-separated ports
--domains DOMAINS Custom domains
--type TYPE Service type (minecraft, tcp, udp)
--bootstrap CMD Bootstrap command
--bootstrap-file FILE Bootstrap from file
--env-file FILE Load env from .env file
--list, -l List all services
--info ID Get service details
--logs ID Get all logs
--tail ID Get last 9000 lines
--freeze ID Pause service
--unfreeze ID Resume service
--destroy ID Delete service
--lock ID Prevent deletion
--unlock ID Allow deletion
--auto-unfreeze ID Enable auto-unfreeze on HTTP request
--no-auto-unfreeze ID Disable auto-unfreeze
--show-freeze-page ID Show payment page when frozen (default)
--no-show-freeze-page ID Return JSON error when frozen
--resize ID Resize (with --vcpu)
--redeploy ID Re-run bootstrap
--execute ID CMD Run command
--snapshot ID Create snapshot

Service Environment Vault

un service env status ID          # Show vault status
un service env set ID             # Set from --env-file or stdin
un service env export ID          # Export to stdout
un service env delete ID          # Delete vault

Snapshot Command

un snapshot --list                # List all snapshots
un snapshot --info ID             # Get details
un snapshot --delete ID           # Delete snapshot
un snapshot --lock ID             # Prevent deletion
un snapshot --unlock ID           # Allow deletion
un snapshot --clone ID            # Clone to new session/service
un snapshot --clone ID --type service --name myapp --ports 80

Snapshot Options

Option Description
--list, -l List all snapshots
--info ID Get snapshot details
--delete ID Delete snapshot
--lock ID Prevent deletion
--unlock ID Allow deletion
--clone ID Clone snapshot
--type TYPE Clone type: session or service
--name NAME Name for cloned service
--shell SHELL Shell for cloned session
--ports PORTS Ports for cloned service

Image Command

un image --list                   # List all images
un image --info ID                # Get image details
un image --delete ID              # Delete image
un image --lock ID                # Prevent deletion
un image --unlock ID              # Allow deletion
un image --publish ID             # Publish from service/snapshot
un image --visibility ID public   # Set visibility (private/unlisted/public)
un image --spawn ID               # Spawn new service from image
un image --clone ID               # Clone image

Image Options

Option Description
--list, -l List all images
--info ID Get image details
--delete ID Delete image
--lock ID Prevent deletion
--unlock ID Allow deletion
--publish ID Publish image from service or snapshot
--visibility ID MODE Set visibility: private, unlisted, or public
--spawn ID Spawn new service from image
--clone ID Clone image
--name NAME Name for spawned/cloned resource
--ports PORTS Ports for spawned service
--source-type TYPE Source type: service or snapshot (for publish)

Languages Command

un languages                      # List all available languages (one per line)
un languages --json               # Output as JSON array for scripts

Languages Options

Option Description
--json Output as JSON array instead of one per line

The languages command fetches the list from the API and caches it in ~/.unsandbox/languages.json for 1 hour.

Default output (one language per line, suitable for piping):

python
javascript
go
rust
...

JSON output (--json):

["python", "javascript", "go", "rust", ...]

Key Command

un key                            # Check API key validity

Output Formatting

Execute Output

stdout content here
---
Exit code: 0
Execution time: 123ms

List Output (sessions, services, snapshots)

ID                                    NAME              STATUS    CREATED
abc123-def456-789                     my-session        running   2024-01-15 10:30:00

Error Output

Error: <message>

Errors go to stderr, exit code 1.

Exit Codes

Code Meaning
0 Success
1 General error
2 Invalid arguments
3 Authentication error
4 API error
5 Timeout

Implementation Requirements

  1. Argument parsing - Use language-appropriate library (argparse, commander, clap, etc.)
  2. Subcommands - session, service, snapshot, key
  3. Consistent output - Same format across all languages
  4. Error handling - Proper exit codes, errors to stderr
  5. Credential resolution - 4-tier system (-p/-k flags > env > ~/.unsandbox > ./accounts.csv)

Available Shells/REPLs

Shells: bash, dash, sh, zsh, fish, ksh, tcsh, csh, elvish, xonsh, ash
REPLs:  python3, bpython, ipython, node, ruby, irb, lua, php, perl
        guile, ghci, erl, iex, sbcl, clisp, r, julia, clojure

File Size Target

With CLI included, each SDK should be approximately:

  • 2,000-3,000 lines for higher-level languages (Python, Ruby, JavaScript)
  • 3,000-4,000 lines for verbose languages (Java, Go, Rust)

Reference: un.c = 6,354 lines (includes manual HTTP, JSON, crypto)