run
Implementation Reference
Source Files:
apps/xec/src/commands/run.ts
- Main run command implementationapps/xec/src/script-runner.ts
- Script execution engineapps/xec/src/utils/unified-module-loader.ts
- Module loading and TypeScript compilationapps/xec/src/config/task-manager.ts
- Task execution logic
Key Functions:
RunCommand.execute()
- Main command entry point (lines 15-120)ScriptRunner.executeScript()
- Script file executionScriptRunner.evalCode()
- Inline code evaluationScriptRunner.startRepl()
- REPL initializationTaskManager.run()
- Task execution from config
Overview
Execute Xec scripts, tasks, or evaluate code with multiple runtime support.
Synopsis
xec run [fileOrTask] [args...] [options]
xec r [fileOrTask] [args...] [options] # Alias
Description
The run
command is a versatile executor that can run JavaScript/TypeScript files, execute configured tasks, evaluate inline code, or start an interactive REPL. It supports multiple JavaScript runtimes including Node.js, Bun, and Deno.
Arguments
[fileOrTask]
- Script file path or task name to execute[args...]
- Arguments to pass to the script
Options
Execution Options (from RunCommand
implementation)
-e, --eval <code>
- Evaluate inline code- Executes via
ScriptRunner.evalCode()
- Has access to Xec core modules
- Supports async/await
- Executes via
--repl
- Start interactive REPL- Launches via
ScriptRunner.startRepl()
- Pre-imports Xec core (
$
,$$
, types) - Supports multi-line input
- Launches via
--typescript
- Enable TypeScript support- Uses
tsx
orts-node
for compilation - Automatic for
.ts
files
- Uses
--watch
- Watch for file changes and re-execute- Uses
chokidar
for file watching - Debounced re-execution
- Uses
--runtime <runtime>
- Specify runtime: auto, node, bun, deno- Default: auto (detects from environment)
- Runtime detection order: Bun → Deno → Node.js
--no-universal
- Disable universal loader (legacy mode)- Falls back to direct require/import
Task Options
-p, --param <key=value>
- Task parameters (can be used multiple times)- Parsed by
parseTaskParams()
function - Supports nested objects:
-p "obj.key=value"
- Supports arrays:
-p "arr=[1,2,3]"
- Parsed by
Examples
Script Execution
# Run JavaScript file
xec run script.js
# Run TypeScript file
xec run script.ts
# Run script with arguments
xec run deploy.js production --force
# Run script with specific runtime
xec run --runtime bun script.js
# Enable watch mode for development
xec run --watch build.js
Task Execution
# Run a configured task
xec run build
# Run task with parameters
xec run deploy -p environment=production -p version=1.2.3
# Run task with complex parameters
xec run backup -p "databases=['users','orders']" -p compress=true
Inline Code Evaluation
# Simple evaluation
xec run -e "console.log('Hello, World!')"
# Evaluate with Xec features
xec run -e "const result = await $\`ls -la\`; console.log(result.stdout)"
# Complex evaluation with TypeScript
xec run --typescript -e "
const files: string[] = await glob('**/*.ts');
console.log(\`Found \${files.length} TypeScript files\`);
"
# Evaluate with arguments
xec run -e "console.log('Args:', process.argv.slice(2))" arg1 arg2
REPL Mode
# Start interactive REPL
xec run --repl
# Start TypeScript REPL
xec run --repl --typescript
# Start REPL with specific runtime
xec run --repl --runtime bun
Script Execution
Supported File Types
The run command automatically detects and executes (detected in ScriptRunner
):
- JavaScript (
.js
,.mjs
,.cjs
) - Direct execution - TypeScript (
.ts
,.mts
,.cts
) - Transpiled via tsx/ts-node - JSON (
.json
) - Loaded as modules - Any executable - Falls back to direct execution with shebang support
Runtime Detection
The command automatically selects the best available runtime (implemented in ScriptRunner.detectRuntime()
):
- Auto mode (default): Detects available runtimes in order:
- Checks for Bun (
process.versions.bun
) - Checks for Deno (
Deno
global) - Falls back to Node.js
- Checks for Bun (
- Node.js: Standard JavaScript runtime (always available)
- Bun: Fast all-in-one JavaScript runtime (if installed)
- Deno: Secure TypeScript/JavaScript runtime (if installed)
# Auto-detect runtime
xec run script.ts
# Force specific runtime
xec run --runtime node script.ts
xec run --runtime bun script.ts
xec run --runtime deno script.ts
Script Environment
Scripts executed with xec run
have access to:
Global Variables
// Process information
console.log(process.argv); // Command line arguments
console.log(__filename); // Current file path (when available)
console.log(__dirname); // Current directory (when available)
// Xec context (injected by ScriptRunner)
console.log($target); // Current target from config
console.log($config); // Loaded configuration object
Built-in Modules
// Command execution
const result = await $`ls -la`;
console.log(result.stdout);
// File system operations
const files = await glob('**/*.js');
const content = await fs.readFile('package.json', 'utf-8');
// HTTP requests
const response = await fetch('https://api.example.com');
const data = await response.json();
// Interactive prompts
const answer = await question({
message: 'Continue?',
defaultValue: 'yes'
});
// Logging utilities
log.info('Information message');
log.success('Success message');
log.error('Error message');
log.warning('Warning message');
Utilities
// Chalk for colors
console.log(chalk.blue('Blue text'));
console.log(chalk.red.bold('Bold red text'));
// Lodash utilities
const result = _.uniq([1, 2, 2, 3]);
// Date utilities (dayjs)
const now = dayjs().format('YYYY-MM-DD HH:mm:ss');
Task Execution
Task Resolution
The command resolves tasks from .xec/config.yaml
(via TaskManager.run()
):
tasks:
build:
description: Build the application
command: npm run build
deploy:
description: Deploy to server
params:
- name: environment
required: true
values: [development, staging, production]
- name: version
required: true
steps:
- name: Build
command: npm run build
- name: Deploy
command: ./deploy.sh ${params.environment} ${params.version}
Parameter Passing
Task parameters can be passed using the -p
flag:
# Simple parameters
xec run deploy -p environment=production -p version=1.2.3
# Boolean parameters
xec run build -p minify=true -p sourcemap=false
# Numeric parameters
xec run test -p timeout=30000 -p workers=4
# JSON parameters
xec run backup -p "config={'databases':['users','orders'],'compress':true}"
Parameter Types
Parameters are automatically parsed:
- Strings: Regular text values
- Booleans:
true
/false
values - Numbers: Numeric values
- JSON: Objects and arrays (when starting with
{
or[
)
Code Evaluation
Inline Evaluation
Execute JavaScript/TypeScript code directly:
# Simple expressions
xec run -e "console.log(Math.random())"
# Async operations
xec run -e "
const result = await $\`uname -a\`;
console.log('System:', result.stdout.trim());
"
# File operations
xec run -e "
const pkg = JSON.parse(await fs.readFile('package.json', 'utf-8'));
console.log('Project:', pkg.name, pkg.version);
"
# Complex logic
xec run -e "
const files = await glob('src/**/*.ts');
const stats = await Promise.all(
files.map(async f => ({
file: f,
size: (await fs.stat(f)).size
}))
);
console.log('Total files:', stats.length);
console.log('Total size:', stats.reduce((sum, s) => sum + s.size, 0));
"
REPL Mode
Interactive Shell
Start an interactive session with full Xec environment:
xec run --repl
In the REPL:
// Execute commands
> await $`ls -la`
{ stdout: '...', stderr: '', exitCode: 0 }
// Work with files
> const files = await glob('**/*.js')
> files.length
42
// Make HTTP requests
> const response = await fetch('https://httpbin.org/json')
> await response.json()
{ ... }
// Use utilities
> chalk.blue('Hello')
'\u001b[34mHello\u001b[39m'
// Access configuration
> xec.config
{ name: 'my-project', ... }
REPL Features
- Auto-completion: Tab completion for variables and methods
- History: Up/down arrow key navigation
- Multi-line input: Automatic continuation for incomplete statements
- Error handling: Graceful error display without crashing
- Context preservation: Variables persist between commands
TypeScript Support
Automatic Detection
TypeScript files (.ts
) are automatically transpiled:
# Automatic TypeScript compilation
xec run script.ts
# Explicit TypeScript mode
xec run --typescript script.js
Type Definitions
Built-in type definitions are available:
// Xec types
const target: ResolvedTarget = xec.target;
const config: XecConfig = xec.config;
// Process promise types
const result: ProcessPromise = $`ls -la`;
const output: string = result.stdout;
// File operations
const files: string[] = await glob('**/*.ts');
const stats: fs.Stats = await fs.stat('package.json');
Watch Mode
Development Workflow
Use watch mode for rapid development:
# Watch TypeScript file for changes
xec run --watch build.ts
# Watch with specific runtime
xec run --watch --runtime bun script.ts
# Combine with evaluation
xec run --watch -e "
console.log('Build started at:', new Date());
await $\`npm run build\`;
console.log('Build completed at:', new Date());
"
Watch Behavior
- File monitoring: Watches the specified file for changes
- Auto-restart: Automatically re-executes on file modification
- Error isolation: Errors don't stop watching
- Graceful shutdown: Ctrl+C stops watching cleanly
Runtime Comparison
Node.js
xec run --runtime node script.js
Features:
- Mature ecosystem
- NPM package support
- CommonJS and ES modules
- Built-in debugging tools
Bun
xec run --runtime bun script.js
Features:
- Fast startup and execution
- Built-in TypeScript support
- NPM compatibility
- Integrated bundler and test runner
Deno
xec run --runtime deno script.ts
Features:
- Secure by default
- Native TypeScript support
- URL-based imports
- Built-in utilities (test, fmt, lint)
Error Handling
Script Errors
# Script with syntax error
xec run broken.js
# Error: Unexpected token
# Script with runtime error
xec run failing.js
# Error: Cannot read property 'foo' of undefined
Task Errors
# Non-existent task
xec run nonexistent
# Error: Task 'nonexistent' not found
# Invalid parameters
xec run deploy -p invalid_param=value
# Error: Invalid parameter format: invalid_param=value
Helpful Error Messages
The command provides context-aware error messages:
- File not found: Suggests checking file path or task name
- Runtime errors: Shows stack trace with source mapping
- Parameter errors: Explains correct parameter format
- Task validation: Shows required parameters
Performance Characteristics
Based on Implementation:
Startup Performance
- Script Resolution: <5ms (file existence check)
- Task Resolution: <10ms (config lookup)
- TypeScript Compilation: 200-500ms (first run), <50ms (cached)
- Runtime Detection: <1ms (environment check)
Execution Performance
- Node.js: ~50ms startup overhead
- Bun: ~20ms startup overhead (when available)
- Deno: ~100ms startup overhead (when available)
- Module Loading: 10-50ms per require/import
Memory Usage
- Base Process: ~30MB (Node.js runtime)
- TypeScript Compiler: +20MB when active
- Script Context: 5-10MB per loaded module
- REPL Session: ~40MB persistent
Related Commands
- new - Create new scripts and tasks
- watch - Watch files and auto-execute
- config - Manage task configuration
- inspect - Inspect tasks and scripts
Configuration
Script execution can be configured in .xec/config.yaml
:
scripts:
# Global environment variables
env:
NODE_ENV: development
API_URL: https://api.example.com
# Global modules available in scripts
globals:
- lodash
- dayjs
- axios
# Runtime preferences
runtime:
default: auto
typescript: true
commands:
run:
defaultRuntime: node
watchDebounce: 300
replHistory: true
Exit Codes
Exit codes follow the standard error mapping (from apps/xec/src/utils/error-handler.ts
):
0
- Success1
-ValidationError
- Invalid arguments or script syntax2
-ConfigurationError
- Task configuration issues3
-TargetNotFoundError
- Script or task not found5
-ExecutionError
- Script/task execution failed7
-FileSystemError
- File not found or inaccessible10
-TimeoutError
- Script execution timeout12
-DependencyError
- Missing runtime or module