Skip to main content

CLI Reference

Implementation Reference​

Source Files:

  • apps/xec/src/main.ts - Main CLI entry point (lines 45-312)
  • apps/xec/src/utils/error-handler.ts - Error handling and exit codes
  • apps/xec/src/script-runner.ts - Script execution engine
  • apps/xec/src/utils/dynamic-commands.ts - Dynamic command loading
  • apps/xec/src/config/loader.ts - Configuration loading

Key Functions:

  • main() - CLI entry point and command dispatcher
  • handleError() - Maps errors to exit codes (1-13)
  • ScriptRunner.execute() - Script file execution
  • loadDynamicCommands() - Loads .xec/commands
  • loadConfig() - Configuration file loading

Overview​

Complete reference for the Xec command-line interface, including global options, execution flow, and configuration.

Synopsis​

xec [global-options] <command> [command-options] [arguments]
xec [global-options] <script-file> [script-arguments]
xec [global-options] <task-name> [task-parameters]

Global Options​

Options that apply to all commands and execution modes (defined in apps/xec/src/main.ts:71-97):

Output Control​

  • -v, --verbose - Enable verbose output with detailed logging
    • Sets log level to DEBUG
    • Shows stack traces for errors
    • Displays connection details
  • -q, --quiet - Suppress all non-essential output
    • Only shows errors
    • Suppresses progress indicators
  • --no-color - Disable colored output
    • Sets process.env.NO_COLOR = '1'
    • Useful for logs and CI environments

Execution Control​

  • --cwd <path> - Set current working directory before execution
    • Changes process.cwd() to specified path
    • Affects all relative path resolution
  • -e, --eval <code> - Evaluate JavaScript/TypeScript code directly
    • Executes via ScriptRunner.evalCode()
    • Has access to Xec core modules
  • --repl - Start interactive REPL (Read-Eval-Print Loop)
    • Launches via ScriptRunner.startRepl()
    • Pre-imports Xec core modules
  • --dry-run - Preview actions without execution
    • Available to all commands via this.isDryRun
    • Shows what would be executed

Configuration​

  • --config <path> - Custom configuration file path
    • Default: .xec/config.yaml
    • Overrides default config location

Help and Information​

  • -h, --help - Display help information
    • Shows command-specific help when used with command
  • -V, --version - Display version information
    • Shows package version from package.json

Command Execution Flow​

Xec resolves and executes commands using the following priority order (implemented in apps/xec/src/main.ts:175-240):

1. Special Modes​

Direct Code Evaluation:

xec -e "console.log('Hello, World!')"
xec --eval "const { $ } = require('@xec-sh/core'); await $\`echo test\`"

Interactive REPL:

xec --repl
# Starts interactive session with Xec core imported

2. Script File Execution​

If the first argument is a file path with recognized extensions:

xec script.js [args...]
xec script.ts [args...]
xec script.mjs [args...]
xec ./path/to/script [args...]

Supported Extensions: (detected in apps/xec/src/main.ts:207)

  • .js - JavaScript files (CommonJS)
  • .ts - TypeScript files (compiled on-the-fly)
  • .mjs - ES modules
  • .mts - TypeScript ES modules
  • .cjs - CommonJS modules
  • .cts - TypeScript CommonJS

Execution Environment: (via ScriptRunner class)

  • Xec core modules pre-imported ($, $$, types)
  • Script arguments available via process.argv
  • Current working directory preserved
  • TypeScript compilation via tsx or ts-node

3. Task Execution​

If the first argument matches a configured task name:

xec deploy --env=production
xec build --parallel --output=dist
xec test --coverage

Task Parameter Parsing:

  • --param=value format supported
  • --param value format supported
  • Remaining arguments passed to task

4. Built-in Commands​

Core commands shipped with Xec:

xec config get targets.hosts
xec copy src/ hosts.web:/app/
xec on "hosts.*" "uptime"
xec logs containers.app --follow

5. Dynamic Commands​

Commands loaded from .xec/commands/ directories:

xec deploy production
xec database:migrate
xec custom-command --option value

6. Direct Command Execution​

If no matching command/task/script found, execute as shell command:

xec echo "Hello from shell"
xec ls -la
xec npm install

Configuration Precedence​

Configuration values are resolved in this order (highest to lowest priority):

1. Command-line Options​

Options passed directly to commands:

xec copy --timeout 30s --parallel src/ hosts.web:/app/

2. Environment Variables​

Environment variables with XEC_ prefix:

export XEC_TIMEOUT=30s
export XEC_PARALLEL=true
export XEC_VERBOSE=true

Common Environment Variables: (checked in various modules)

  • XEC_CONFIG_PATH - Path to configuration file (default: .xec/config.yaml)
  • XEC_COMMANDS_PATH - Additional command directories (colon-separated)
  • XEC_DEBUG - Enable debug output (true/1)
  • XEC_NO_COLOR - Disable colored output (same as NO_COLOR)
  • XEC_CACHE_DIR - Custom cache directory
  • XEC_RUNTIME - Force specific runtime (node, bun, deno)
  • XEC_SHELL - Default shell for command execution
  • XEC_TIMEOUT - Default timeout for operations (in ms)
  • XEC_SSH_KEY - Default SSH key path
  • XEC_SSH_CONFIG - SSH config file path

3. Configuration File​

Values from .xec/config.yaml:

# Global defaults
timeout: 30s
parallel: true
verbose: false

# Command-specific defaults
commands:
copy:
parallel: true
timeout: 60s
on:
timeout: 30s
shell: /bin/bash

4. Built-in Defaults​

Default values defined in Xec source code.

Exit Codes​

Xec uses standardized exit codes (defined in apps/xec/src/utils/error-handler.ts:4-41):

Success​

  • 0 - Success, no errors

Error Codes (mapped from error classes)​

  • 1 - ValidationError - Invalid arguments, options, or input
  • 2 - ConfigurationError - Configuration file issues
  • 3 - TargetNotFoundError - Target doesn't exist in config
  • 4 - ConnectionError - Connection failures (SSH, Docker, K8s)
  • 5 - ExecutionError - Command execution failed
  • 6 - AuthenticationError - Authentication failed
  • 7 - FileSystemError - File operation errors
  • 8 - DockerError - Docker-specific errors
  • 9 - KubernetesError - Kubernetes-specific errors
  • 10 - TimeoutError - Operation timeout
  • 11 - PermissionError - Permission denied
  • 12 - DependencyError - Missing dependencies
  • 13 - NetworkError - Network-related errors
  • 1 - Unknown errors (default for unhandled exceptions)

Usage Examples​

# Check exit code in scripts
xec deploy production
if [ $? -eq 0 ]; then
echo "Deployment successful"
else
echo "Deployment failed with code $?"
fi

# Use with conditional execution
xec test && xec deploy production
xec build || exit 1

Environment Variables​

Core Variables​

XEC_CONFIG_PATH

export XEC_CONFIG_PATH=/custom/path/to/config.yaml
xec config get targets # Uses custom config file

XEC_COMMANDS_PATH

export XEC_COMMANDS_PATH="/shared/commands:/team/commands"
xec --help # Shows commands from additional directories

XEC_DEBUG

export XEC_DEBUG=true
xec any-command # Shows detailed debug information

XEC_CACHE_DIR

export XEC_CACHE_DIR=/tmp/xec-cache
xec run script.ts # Uses custom cache directory

Output Control​

NO_COLOR / XEC_NO_COLOR

export NO_COLOR=1
# or
export XEC_NO_COLOR=1
xec status # Outputs without colors

XEC_QUIET

export XEC_QUIET=true
xec deploy # Suppresses non-essential output

XEC_VERBOSE

export XEC_VERBOSE=true
xec copy files/ remote:/ # Shows detailed progress

Execution Environment​

XEC_TIMEOUT

export XEC_TIMEOUT=5m
xec on hosts.slow "long-running-command" # Uses 5-minute timeout

XEC_PARALLEL

export XEC_PARALLEL=false
xec on "hosts.*" "command" # Executes sequentially

XEC_SHELL

export XEC_SHELL=/bin/zsh
xec on hosts.server "echo $SHELL" # Uses zsh instead of default

Advanced Usage​

Combining Options​

# Multiple global options
xec --verbose --no-color --cwd /project deploy

# Mixed with environment variables
XEC_DEBUG=true xec --quiet copy src/ dest/

# Script with arguments
xec --cwd /project script.ts --input data.json --output results/

Complex Command Lines​

# Task with parameters and environment
XEC_VERBOSE=true xec deploy \
--env=production \
--targets=web1,web2 \
--parallel \
--timeout=10m

# Script evaluation with imports
xec -e "
import { $, on } from '@xec-sh/core';
const result = await on('hosts.web', 'uptime');
console.log(result.stdout);
"

# REPL with pre-loaded modules
XEC_DEBUG=true xec --repl
> const result = await $\`date\`
> console.log(result.stdout)

Pipeline Integration​

CI/CD Integration:

#!/bin/bash
set -e

# Build and test
xec build --env=production
xec test --coverage --reporter=junit

# Deploy if tests pass
if [ $? -eq 0 ]; then
xec deploy production --timeout=15m
else
echo "Tests failed, skipping deployment"
exit 1
fi

Make Integration:

.PHONY: deploy test build

build:
xec build --parallel

test: build
xec test --coverage

deploy: test
xec deploy production --confirm

clean:
xec clean --force

Docker Integration:

FROM node:18-alpine
COPY . /app
WORKDIR /app

# Install Xec globally
RUN npm install -g @xec-sh/cli

# Use Xec for build process
RUN xec build --env=production

CMD ["xec", "start", "--port=3000"]

Performance Considerations​

Command Loading​

Commands are loaded lazily for better startup performance:

# Fast - only loads required command
xec config get targets

# Slower - discovers all dynamic commands
xec --help

Parallel Execution​

Many commands support parallel execution:

# Sequential (default for safety)
xec on "hosts.*" "command"

# Parallel (faster for independent operations)
xec on "hosts.*" "command" --parallel

# Control parallelism
export XEC_PARALLEL=true
xec copy files/ "hosts.*:/dest/"

Caching​

Xec caches compiled scripts and module resolution:

# Clear cache if needed
rm -rf ~/.xec/cache/

# Custom cache location
export XEC_CACHE_DIR=/tmp/xec-cache
xec run script.ts

Debugging and Troubleshooting​

Debug Mode​

Enable comprehensive debug output:

XEC_DEBUG=true xec command

Debug Information Includes:

  • Command resolution process
  • Configuration loading details
  • Module import and compilation
  • Network requests and responses
  • Execution timing

Verbose Output​

Get detailed execution information:

xec --verbose command
# or
export XEC_VERBOSE=true
xec command

Common Issues​

Command Not Found:

# Check command discovery
XEC_DEBUG=true xec --help

# Verify command file syntax
node -c .xec/commands/my-command.js

# Test command loading
XEC_DEBUG=true xec my-command --help

Configuration Problems:

# Validate configuration file
xec config validate

# Show effective configuration
xec config show --resolved

# Check configuration precedence
XEC_DEBUG=true xec config get key

Script Execution Issues:

# Test script syntax
node -c script.ts

# Run with debug output
XEC_DEBUG=true xec script.ts

# Check module resolution
XEC_DEBUG=true xec -e "import('missing-module')"

Performance Profiling​

# Time command execution
time xec command

# Profile with debug output
XEC_DEBUG=true time xec command 2>&1 | grep -E "(timing|duration)"

# Memory usage (Linux/macOS)
/usr/bin/time -l xec command

Performance Characteristics​

Based on Implementation Analysis:

Startup Performance​

  • Command Resolution: <5ms (direct lookup in registry)
  • Config Loading: 50-100ms (YAML parsing + schema validation)
  • Dynamic Command Discovery: 10-50ms (filesystem scanning)
  • TypeScript Compilation: 200-500ms (first run, cached after)

Execution Performance​

  • SSH Connection: 100-500ms (new), <10ms (pooled)
  • Docker Exec: 50-100ms per command
  • Kubernetes Exec: 200-500ms per pod
  • Parallel Execution: Linear scaling with connection pooling

Memory Usage​

  • Base Process: ~30MB (Node.js + Xec core)
  • Per Connection: ~2MB (SSH), ~1MB (Docker)
  • Config Object: 10-100KB depending on size
  • Script Compilation Cache: ~5MB per script

Integration Examples​

Shell Scripts​

#!/bin/bash
# deployment.sh

set -euo pipefail

# Configuration
ENVIRONMENT=${1:-staging}
TIMEOUT=${XEC_TIMEOUT:-10m}

# Pre-deployment checks
echo "Running pre-deployment checks..."
xec validate --env="$ENVIRONMENT" || {
echo "Validation failed"
exit 1
}

# Deploy
echo "Deploying to $ENVIRONMENT..."
xec deploy "$ENVIRONMENT" \
--timeout="$TIMEOUT" \
--parallel \
--confirm || {
echo "Deployment failed"
exit 1
}

echo "Deployment completed successfully"

Make Targets​

# Makefile
.DEFAULT_GOAL := help

ENVIRONMENT ?= development
XEC_OPTS ?= --verbose

.PHONY: help build test deploy clean

help: ## Show this help
@grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-20s\033[0m %s\n", $$1, $$2}'

build: ## Build the application
xec build $(XEC_OPTS) --env=$(ENVIRONMENT)

test: build ## Run tests
xec test $(XEC_OPTS) --coverage

deploy: test ## Deploy to environment
xec deploy $(ENVIRONMENT) $(XEC_OPTS) --confirm

clean: ## Clean build artifacts
xec clean $(XEC_OPTS) --force

watch: ## Watch files and rebuild
xec watch $(XEC_OPTS) --pattern="src/**/*.ts"

GitHub Actions​

# .github/workflows/deploy.yml
name: Deploy

on:
push:
branches: [main]

jobs:
deploy:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v3

- name: Setup Node.js
uses: actions/setup-node@v3
with:
node-version: '18'

- name: Install dependencies
run: npm ci

- name: Install Xec
run: npm install -g @xec-sh/cli

- name: Build application
run: xec build --env=production
env:
XEC_VERBOSE: true

- name: Run tests
run: xec test --coverage --reporter=junit

- name: Deploy to production
run: xec deploy production --timeout=15m
env:
XEC_SSH_KEY: ${{ secrets.SSH_PRIVATE_KEY }}
XEC_TIMEOUT: 15m

The Xec CLI provides a powerful and flexible interface for command execution across multiple environments. Understanding the execution flow, configuration precedence, and available options enables you to build efficient automation workflows and integrate Xec effectively with your existing tools and processes.