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:
$and the scripting utilities injected as globals- Script arguments injected as
args(andargv, shell convention) - Current working directory preserved
- TypeScript compiled by the built-in loader — no
tsx/ts-nodeneeded
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=valueformat supported--param valueformat 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
Any variable with the XEC_ prefix overrides configuration by path — the
rest of the name is lowercased and underscores become dots:
export XEC_VARS_APP_NAME=web # sets vars.app_name
export XEC_COMMANDS_DEFAULTS_TIMEOUT=30s # sets commands.defaults.timeout
A few names additionally have dedicated meaning:
XEC_CONFIG- Path to an additional configuration file to loadXEC_PROFILE- Configuration profile to activateXEC_COMMANDS_PATH- Additional command directories (colon-separated)XEC_DEBUG- Enable debug output (true/1)NO_COLOR/FORCE_COLOR=0- Disable colored output (standard variables)
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 (getExitCode in
packages/ops/src/utils/error-handler.ts):
Success
0- Success, no errors
Error Codes (mapped from error classes)
2-ValidationError- Invalid arguments, options, or input3-ConfigurationError- Configuration file issues4-ModuleError- Module loading failures5-TaskError- Task execution failed6-RecipeError- Recipe execution failed7-NetworkError- Network-related errors8-FileSystemError- File operation errors9-TimeoutError- Operation timeout10- SystemENOENT- File or command not found11- SystemEACCES- Permission denied12- SystemENOTDIR/13-EISDIR- Path type mismatch1- Everything else, including a script that threw
A script that calls process.exit(n) keeps its own n.
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
export XEC_CONFIG=/custom/path/to/config.yaml
xec config get targets # Also loads the config file at that path
XEC_PROFILE
export XEC_PROFILE=production
xec inspect # Runs with the production profile active
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
Output Control
NO_COLOR
export NO_COLOR=1
xec inspect # Outputs without colors (FORCE_COLOR=0 works too)
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 { $ } from '@xec-sh/core';
console.log(await $\`uptime\`.text());
"
# REPL with pre-loaded modules
XEC_DEBUG=true xec --repl
> const date = await $\`date\`.text()
> console.log(date)
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.