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 codesapps/xec/src/script-runner.ts
- Script execution engineapps/xec/src/utils/dynamic-commands.ts
- Dynamic command loadingapps/xec/src/config/loader.ts
- Configuration loading
Key Functions:
main()
- CLI entry point and command dispatcherhandleError()
- Maps errors to exit codes (1-13)ScriptRunner.execute()
- Script file executionloadDynamicCommands()
- Loads .xec/commandsloadConfig()
- 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
- Sets
Execution Controlβ
--cwd <path>
- Set current working directory before execution- Changes
process.cwd()
to specified path - Affects all relative path resolution
- Changes
-e, --eval <code>
- Evaluate JavaScript/TypeScript code directly- Executes via
ScriptRunner.evalCode()
- Has access to Xec core modules
- Executes via
--repl
- Start interactive REPL (Read-Eval-Print Loop)- Launches via
ScriptRunner.startRepl()
- Pre-imports Xec core modules
- Launches via
--dry-run
- Preview actions without execution- Available to all commands via
this.isDryRun
- Shows what would be executed
- Available to all commands via
Configurationβ
--config <path>
- Custom configuration file path- Default:
.xec/config.yaml
- Overrides default config location
- Default:
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
- Shows package version from
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
orts-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 asNO_COLOR
)XEC_CACHE_DIR
- Custom cache directoryXEC_RUNTIME
- Force specific runtime (node
,bun
,deno
)XEC_SHELL
- Default shell for command executionXEC_TIMEOUT
- Default timeout for operations (in ms)XEC_SSH_KEY
- Default SSH key pathXEC_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 input2
-ConfigurationError
- Configuration file issues3
-TargetNotFoundError
- Target doesn't exist in config4
-ConnectionError
- Connection failures (SSH, Docker, K8s)5
-ExecutionError
- Command execution failed6
-AuthenticationError
- Authentication failed7
-FileSystemError
- File operation errors8
-DockerError
- Docker-specific errors9
-KubernetesError
- Kubernetes-specific errors10
-TimeoutError
- Operation timeout11
-PermissionError
- Permission denied12
-DependencyError
- Missing dependencies13
-NetworkError
- Network-related errors1
- 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.