JCL provides a comprehensive suite of command-line tools for working with JCL configurations.
jcl - Main CLI
The primary JCL command-line interface.
Commands
eval
Evaluate a JCL file and print the results.
jcl eval <file>
Example:
$ jcl eval config.jcf
name: "my-app"
version: "1.0.0"
port: 8080
database: {host: "localhost", port: 5432}
repl
Start an interactive REPL (Read-Eval-Print Loop).
jcl repl
REPL Commands:
:help,:h- Show help:quit,:q,:exit- Exit REPL:clear,:c- Clear all variables:vars,:v- Show all variables
Features:
- Persistent history (
~/.jcf_history) - Multi-line input (use
\at end of line) - Tab completion
- History search (Ctrl-R)
Example:
$ jcl repl
JCL REPL v0.1.0
jcl:1 x = 42
✓
jcl:2 x * 2
84
jcl:3 :quit
Goodbye!
jcl-validate - Schema Validation
Validate JCL configuration files against schemas.
Usage
jcl-validate <config> --schema <schema>
Options
-s, --schema <SCHEMA>- Schema file (JSON or YAML)-f, --schema-format <FORMAT>- Schema format (json, yaml) - auto-detects if not specified-v, --verbose- Verbose output--no-fail- Exit with status 0 even if validation fails
Examples
Basic validation:
$ jcl-validate config.jcf --schema schema.yaml
✅ Validation passed!
With errors:
$ jcl-validate invalid.jcf --schema schema.yaml
❌ 3 validation error(s) found:
• version
String '1.2' does not match pattern '^\d+\.\d+\.\d+$'
• port
Number 99999 exceeds maximum 65535
• database.port
Required property 'port' is missing
Verbose mode:
$ jcl-validate config.jcf --schema schema.yaml --verbose
📋 Schema loaded from schema.yaml
📄 Configuration loaded from config.jcf
🔍 Validating...
✅ Validation passed!
Schema Format
Schemas can be defined in JSON or YAML:
version: "1.0"
title: "Application Configuration Schema"
parent: Reference
nav_order: 3
description: "Schema for validating app configs"
type:
kind: map
required:
- name
- version
- port
properties:
name:
type:
kind: string
min_length: 1
max_length: 50
port:
type:
kind: number
minimum: 1
maximum: 65535
integer_only: true
jcl-migrate - Format Migration
Convert configuration files from JSON, YAML, or TOML to JCL.
Usage
jcl-migrate <input> [options]
Options
-o, --output <OUTPUT>- Output file (prints to stdout if not specified)-f, --from <FORMAT>- Input format (json, yaml, toml) - auto-detects if not specified-v, --verbose- Verbose output
Examples
Convert JSON to JCL:
$ jcl-migrate config.json
name = "my-app"
version = "1.0.0"
port = 8080
database = (
host = "localhost",
port = 5432
)
Save to file:
$ jcl-migrate config.json -o config.jcf
$ cat config.jcf
name = "my-app"
version = "1.0.0"
...
Convert YAML:
$ jcl-migrate config.yaml --verbose
📄 Converting from Yaml to JCL...
name = "my-app"
...
Convert TOML:
$ jcl-migrate config.toml
name = "my-app"
enabled = true
...
jcl-fmt - Code Formatter
Format JCL files according to standard style.
Usage
jcl-fmt <files>... [options]
Options
-c, --check- Check only (don’t modify files)-v, --verbose- Verbose output
Examples
Format a single file:
$ jcl-fmt config.jcf
✓ config.jcf - Formatted
✅ Formatted 1 file(s)
Format multiple files:
$ jcl-fmt *.jcf
✓ config.jcf - Formatted
✓ app.jcf - Already formatted
✓ db.jcf - Formatted
✅ Formatted 3 file(s)
Check formatting (CI mode):
$ jcl-fmt --check config.jcf
✅ All files are properly formatted!
$ jcl-fmt --check *.jcf
! config.jcf - Needs formatting
! app.jcf - Needs formatting
⚠️ 2 file(s) need formatting:
- config.jcf
- app.jcf
Verbose mode:
$ jcl-fmt config.jcf --verbose
📝 Processing: config.jcf
✓ config.jcf - Formatted
Formatting Rules
- Consistent spacing around operators (
=,+, etc.) - Proper indentation for nested structures
- Consistent comma placement in maps and lists
- Normalized quote usage
jcl-watch - Auto-format on Save
Watch JCL files for changes and automatically format them.
Usage
jcl-watch <paths>... [options]
Options
-r, --recursive- Recursive watch for directories-c, --check- Check only (don’t modify files)-v, --verbose- Verbose output
Examples
Watch a single file:
$ jcl-watch config.jcf
🔍 JCL Watch Mode
Watching for changes... (Press Ctrl+C to stop)
✓ config.jcf - Formatted
Watch a directory:
$ jcl-watch ./configs --recursive
🔍 JCL Watch Mode
Watching for changes... (Press Ctrl+C to stop)
👁️ Watching: ./configs
Check mode (no modifications):
$ jcl-watch config.jcf --check
🔍 JCL Watch Mode
Watching for changes... (Press Ctrl+C to stop)
! config.jcf - Needs formatting
jcl-bench - Performance Benchmarking
Benchmark JCL parsing and evaluation performance.
Usage
jcl-bench [file] [options]
Options
-n, --iterations <N>- Number of iterations (default: 1000)-v, --verbose- Show detailed timing for each iteration--builtin- Run built-in benchmarks
Examples
Benchmark a file:
$ jcl-bench config.jcf
JCL Benchmarking Tool
Benchmarking: config.jcf
Iterations: 1000
📊 Parsing Benchmark
Average: 559.041µs
Min: 521.958µs
Max: 1.311041ms
📊 Evaluation Benchmark
Average: 22.307µs
Min: 19.125µs
Max: 140.042µs
Summary
──────────────────────────────────────────────────
Total parsing time: 55.904162ms (96.2%)
Total evaluation time: 2.230706ms (3.8%)
Total time: 58.134868ms
Operations per second:
Parsing: 1788 ops/sec
Evaluation: 44828 ops/sec
Combined: 1720 ops/sec
Custom iteration count:
$ jcl-bench config.jcf -n 10000
...
Built-in benchmarks:
$ jcl-bench --builtin
JCL Benchmarking Tool
Running Built-in Benchmarks
Testing: Simple arithmetic
📊 Parsing Benchmark
Average: 38.161µs
...
Total: 4.095333ms (24418 ops/sec)
Testing: String operations
...
Verbose mode:
$ jcl-bench config.jcf -n 100 --verbose
...
Iteration 1: 545.125µs
Iteration 2: 532.792µs
...
jcl-lsp - Language Server
Start a Language Server Protocol server for editor integration.
Usage
jcl-lsp
Features
The LSP server provides:
- Syntax highlighting - Semantic token highlighting
- Diagnostics - Parse errors, linting warnings, and schema validation errors
- Schema validation - Automatic schema discovery and real-time validation (see LSP Guide)
- Go to definition - Jump to variable/function definitions
- Find references - Find all uses of a symbol
- Rename symbol - Rename variables/functions
- Hover information - View type and documentation
- Code completion - Auto-complete suggestions
Editor Integration
VS Code:
The LSP server can be integrated with VS Code using the provided extension in editors/vscode/.
Vim/Neovim:
Use with any LSP client plugin (e.g., coc.nvim, nvim-lspconfig):
" Configure JCL LSP
call coc#config('languageserver', {
\ 'jcl': {
\ 'command': 'jcl-lsp',
\ 'filetypes': ['jcl']
\ }
\ })
Other Editors:
Any editor with LSP support can use jcl-lsp. Configure it to start the jcl-lsp command for .jcf files.
Common Workflows
CI/CD Pipeline
#!/bin/bash
# Validate and format JCL configs in CI
# Check formatting
jcl-fmt --check *.jcf || exit 1
# Validate against schema
jcl-validate config.jcf --schema schema.yaml || exit 1
# Run tests
jcl eval test.jcf || exit 1
echo "✅ All checks passed!"
Pre-commit Hook
#!/bin/bash
# .git/hooks/pre-commit
# Format all staged .jcf files
git diff --cached --name-only --diff-filter=ACM | grep '\.jcf$' | while read file; do
jcl-fmt "$file"
git add "$file"
done
Development Workflow
# Start watch mode in one terminal
jcl-watch ./configs --recursive
# Edit configs in your editor
# Files are automatically formatted on save
# In another terminal, test configs
jcl eval configs/app.jcf
Migration from JSON
# Migrate all JSON files to JCL
for file in *.json; do
jcl-migrate "$file" -o "${file%.json}.jcf"
done
# Format the new files
jcl-fmt *.jcf
# Validate them
for file in *.jcf; do
jcl-validate "$file" --schema schema.yaml
done
jcl-module - Module Management
Manage JCL modules including creation, validation, dependency installation, and listing.
Commands
init
Initialize a new JCL module with scaffolding.
jcl-module init <name> [OPTIONS]
Options:
-p, --path <PATH>- Directory to create module in (defaults to module name)-v, --version <VERSION>- Module version (default: “0.1.0”)-d, --description <DESCRIPTION>- Module description-a, --author <AUTHOR>- Module author-l, --license <LICENSE>- Module license (default: “MIT”)
Example:
$ jcl-module init my-module \
--version "0.1.0" \
--description "My awesome module" \
--author "Your Name" \
--license "MIT"
Creating module 'my-module' in my-module
✓ Created jcl.json
✓ Created module.jcl
✓ Created README.md
✓ Created .gitignore
✓ Module 'my-module' initialized successfully!
Next steps:
1. cd my-module
2. Edit module.jcf to define your module
3. Run 'jcl-module validate' to check your module
Creates:
jcl.json- Module manifest with metadata and dependenciesmodule.jcf- Module template with interface and outputs structureREADME.md- Documentation template with usage examples.gitignore- JCL cache and OS file exclusions
Module Template:
# my-module Module
module.interface = (
inputs = (
# Define your module inputs here
# Example:
# name = (type = string, required = true, description = "Resource name")
),
outputs = (
# Define your module outputs here
# Example:
# id = (type = string, description = "Resource ID")
)
)
module.outputs = (
# Implement your module outputs here
# Example:
# id = "resource-${module.inputs.name}"
)
validate
Validate module structure, manifest, and interface.
jcl-module validate [PATH]
Arguments:
PATH- Path to module directory (defaults to current directory)
Example:
$ jcl-module validate ./my-module
Validating module in ./my-module
✓ Valid manifest (jcl.json)
Name: my-module
Version: 0.1.0
✓ Main module file exists (module.jcf)
✓ Module file parses successfully
✓ Module interface defined
✓ Module outputs defined
Dependencies:
aws-base @ ^2.0.0
networking @ ~1.5.0
✓ Module validation successful!
Checks:
jcl.jsonmanifest exists and is valid JSON- Manifest contains required fields (name, version, main)
- Main module file exists
- Module file parses without syntax errors
module.interfacestatement is presentmodule.outputsstatement is present- All dependencies are listed
Exit Codes:
0- Validation passed1- Validation failed
get
Download and install module dependencies from the registry.
jcl-module get [PATH]
Arguments:
PATH- Path to module directory (defaults to current directory)
Example:
$ jcl-module get ./my-module
Downloading dependencies for module in ./my-module
Resolving aws-base @ ^2.0.0...
→ Resolved to v2.1.3
Downloading...
✓ Downloaded to /Users/user/.cache/jcl/modules/registry/aws-base/2.1.3
Resolving networking @ ~1.5.0...
→ Resolved to v1.5.2
Downloading...
✓ Downloaded to /Users/user/.cache/jcl/modules/registry/networking/1.5.2
✓ All dependencies downloaded successfully!
Features:
- Reads dependencies from
jcl.jsonmanifest - Resolves version requirements using semantic versioning
- Downloads modules from the default registry
- Caches modules locally for performance
- Shows progress and resolved versions
Cache Location:
- Default:
~/.cache/jcl/modules/registry/ - Structure:
{cache_dir}/{module_name}/{version}/
list
List all installed modules.
jcl-module list [OPTIONS]
Options:
-v, --verbose- Show detailed information including versions and descriptions
Example (basic):
$ jcl-module list
Installed modules:
aws-base
aws-ec2
networking
Total: 3 module(s)
Example (verbose):
$ jcl-module list --verbose
Installed modules:
aws-base
v2.0.0
v2.1.3
Base AWS configuration module
aws-ec2
v1.2.3
AWS EC2 instance configuration
networking
v1.5.0
v1.5.2
Network configuration utilities
Total: 3 module(s)
Module Cache: The list command shows modules cached in:
~/.cache/jcl/modules/registry/- Registry modules- Organized by module name, then version
Environment Variables
JCL_LSP_LOG_LEVEL- Set LSP logging level (trace, debug, info, warn, error)HOME- Used for REPL history file location (~/.jcf_history)
Exit Codes
All tools follow standard exit code conventions:
0- Success1- Error (parse error, validation failure, etc.)2- Invalid usage (wrong arguments, missing files, etc.)
For jcl-fmt --check:
0- All files properly formatted1- Some files need formatting
For jcl-validate:
0- Validation passed1- Validation failed (unless--no-failis used)