| Publish | |
| Rust Coverage | |
| Angular Coverage |
A powerful automation tool for executing remote commands and transferring files via SSH. It uses configuration files to define execution scenarios, making system administration and deployment tasks repeatable and reliable.
- Scenario Configuration: Define your tasks in TOML files with inheritance support
- Remote Command Execution: Run commands on remote servers with sudo support
- File Transfer: Copy files to remote servers via SFTP
- Variable Substitution: Use variables in your commands and file paths, including
{env:VAR}for environment variables - Error Recovery: Define fallback tasks to execute when operations fail
- Modifier System: Path, string, and time modifiers (
{basename:var},{now:YYYY-MM-DD},{uuid}, etc.) - Progress Tracking: Monitor execution progress with detailed feedback
- JSON Schema Validation: Included schema file for TOML editor validation and autocompletion
- GUI, TUI & CLI Interfaces: Choose between a graphical interface, terminal UI, or command-line tool
Scenario configurations are defined in TOML files:
# Basic structure for a scenario configuration
[credentials]
username = "your-username" # will be added to the variables
password = "your-password" # optional, will use SSH agent if not provided
[server]
host = "your-server.example.com" # required
port = 22 # optional, default is 22
# Define the execution order of steps (order is preserved)
[[steps]]
name = "deploy_app"
task = "deploy_app"
[[steps]]
name = "extract_app"
task = "extract_app"
[[steps]]
name = "copy_config"
task = "copy_config"
on-fail = "rollback_steps" # Reference to a sequence for error recovery
# Define reusable sequences of tasks
[sequences]
rollback_steps = ["rollback_deployment"]
# Variables that must be provided by the user
[variables.required.app_archive]
label = "Application Archive"
file_picker = true
[variables.required.deployment_env]
label = "Environment"
[variables.required.timestamp]
label = "Deployment Time"
default = "{now:YYYY-MM-DDTHHMMSSZ}"
read_only = true
# Define variables to be used in commands and file paths
[variables.defined]
app_name = "myapp"
app_version = "1.0.0"
remote_app_path = "/opt/{app_name}"
# Define remote sudo tasks
[tasks.remote_sudo.deploy_app]
command = "mkdir -p {remote_app_path} && cp /tmp/{basename:app_archive} {remote_app_path}/"
description = "Deploy application"
error_message = "Failed to deploy application"
[tasks.remote_sudo.extract_app]
command = "tar -xzf {remote_app_path}/{basename:app_archive} -C {remote_app_path}"
description = "Extract application archive"
error_message = "Failed to extract application"
[tasks.remote_sudo.rollback_deployment]
command = "rm -rf {remote_app_path}/*"
description = "Rollback failed deployment"
error_message = "Failed to rollback deployment"
# Define SFTP copy tasks
[tasks.sftp_copy.copy_config]
source = "config/{deployment_env}.conf"
destination = "{remote_app_path}/config.conf"
description = "Copy configuration file"
error_message = "Failed to copy configuration"Required variables are defined in [variables.required.<name>] sections with optional metadata:
| Field | Description | Default |
|---|---|---|
label |
User-facing label in TUI/GUI | variable name |
default |
Default value (supports placeholders) | empty |
read_only |
Prevent user editing in TUI/GUI | false |
file_picker |
Show file picker button in TUI/GUI | false |
Variables are referenced in commands and paths using {variable_name} placeholders.
[variables.defined]
remote_backup_path = "/backup/{service_name}/{service_name}-{timestamp}.{env:USER}.jar"These require a base variable that represents a file path.
| Modifier | Description | Example |
|---|---|---|
{basename:var} |
File name with extension | /usr/src/app.jar → app.jar |
{stem:var} |
File name without extension | /usr/src/app.jar → app |
{dir:var} |
Parent directory path | /usr/src/app.jar → /usr/src |
{ext:var} |
File extension only | /usr/src/app.jar → jar |
{abspath:var} |
Resolve to absolute path | ./config/app.yml → /home/user/projects/config/app.yml |
The env: modifier requires a target; the others are zero-input and generate data on the fly.
| Modifier | Description | Example |
|---|---|---|
{env:VAR_NAME} |
Host environment variable | {env:USER} → stanislav |
{hostname} |
Machine network name | stanislav-macbook-pro |
{os} |
Operating system family | linux, macos, or windows |
Modifier placeholders are evaluated per occurrence. If you want the same generated value reused across multiple places, assign it once in a required or defined variable and reference that variable instead.
| Modifier | Description | Example |
|---|---|---|
{uuid} |
Random v4 UUID | f47ac10b-58cc-4372-a567-0e02b2c3d479 |
{now} |
Current date-time (ISO 8601) | 2026-04-11T14:53:34+02:00 |
{now:YYYY-MM-DD} |
Custom date format | 2026-04-11 |
{now:HHmmss} |
Custom time format | 145334 |
{now:epoch} |
UNIX epoch (seconds) | 1712836241 |
{now:epoch_ms} |
UNIX epoch (milliseconds) | 1712836241000 |
Format tokens: YYYY (year), YY (2-digit year), MM (month), DD (day), HH (24h hour), hh (12h hour), mm (minute), ss (second), SSS (milliseconds), Z (timezone offset).
These require a base variable and alter its text casing or encoding.
| Modifier | Description | Example |
|---|---|---|
{uppercase:var} |
Convert to uppercase | my_service → MY_SERVICE |
{lowercase:var} |
Convert to lowercase | My_Service → my_service |
{base64:var} |
Base64 encode | my_secret_token → bXlfc2VjcmV0X3Rva2Vu |
{trim:var} |
Remove leading/trailing whitespace | my_app → my_app |
You can split your configuration across multiple files and use inheritance:
[credentials]
username = "default-user"
[server]
host = "default-host"
port = 22
[variables.required.timestamp]
label = "Deployment Time"
default = "{now:YYYY-MM-DD}"
read_only = true
[variables.defined]
app_name = "default-app"
[[steps]]
name = "deploy"
task = "deploy"
[tasks.remote_sudo.deploy]
command = "echo deploying {app_name}"parent = "base.toml" # Will inherit and override from parent
[credentials]
username = "specific-user"
[variables.required.env_name]
label = "Environment Name"
[variables.defined]
app_version = "1.0.0" # Adds new variable while keeping app_name from parentA JSON Schema file (scenario-schema.json) is included at the repository root, generated from the Rust config types. Add a #:schema directive as the first line of your TOML files to enable editor validation and autocompletion (supported by Even Better TOML and taplo):
#:schema ../scenario-schema.json
[credentials]
username = "my-user"
# ...Regenerate the schema after config type changes with:
just schema > scenario-schema.json
The GUI provides a modern Tauri-based interface for managing and executing scenarios:
- Configuration Management: Load, validate, and execute scenario configurations
- Variable Management: Set and update required variables with type-specific controls
- Real-time Execution: Monitor scenario execution with step-by-step progress
- State Persistence: Save and restore application state between sessions
- Task & Step Visualization: Visual representation of scenario tasks and steps
- Detailed Logging: View detailed execution logs with filtering options
- Variable Resolution: See how variables are resolved during execution
- Configuration Loader: Open dialog for selecting TOML configuration files
- Variable Editor: Type-appropriate input fields for required variables
- Execution Panel: Control execution and view real-time progress
- Log Viewer: Structured view of execution events and messages
- Task Explorer: Hierarchical view of tasks and their relationships
- Variables Inspector: View all defined and resolved variables
The TUI provides an interactive terminal interface for selecting configs, filling in variables, and monitoring execution — no desktop environment required.
scenario-rs-tui [--config-path <path-to-config.toml>]
- File Browser: Browse and select TOML configuration files interactively
- Variable Form: Fill in required variables with type-aware input (includes file picker for Path variables)
- Live Execution View: Monitor step-by-step progress with output and error details
- Keyboard-Driven: Fully navigable with keyboard shortcuts
| Screen | Key | Action |
|---|---|---|
| File Browser | ↑/↓ |
Navigate entries |
| File Browser | Enter |
Open directory / confirm file |
| File Browser | Backspace |
Go to parent directory |
| File Browser | Esc |
Cancel |
| Variables | Tab/↑/↓ |
Navigate fields |
| Variables | Ctrl+B |
Open file picker (Path fields) |
| Variables | Ctrl+D |
Toggle dry run |
| Variables | Enter |
Start execution |
| Variables | Esc |
Quit |
| Executing | ↑/↓ |
Select step |
| Executing | PgUp/PgDn |
Scroll output |
| Done | q/Esc |
Quit |
| Done | r |
Re-run same scenario |
| Done | n |
Pick new scenario |
For automation scripts or CI/CD pipelines, use the command-line interface:
scenario-rs-cli --config-path <path-to-config.toml> [options]
Usage: scenario-rs-cli [OPTIONS] --config-path <TOML_FILE>
Options:
-c, --config-path <TOML_FILE> Path to the TOML file containing the scenario configuration
-l, --log-level <LOG_LEVEL> Log level for the application [default: INFO]
-r, --required-variables <REQUIRED_VARIABLES> Required variables in the format KEY=VALUE
-h, --help Print help
-V, --version Print version
Basic execution:
scenario-rs-cli -c ./example_configs/example-scenario.toml
With required variables:
scenario-rs-cli -c ./example_configs/deploy-scenario.toml -r app_version=1.2.3 -r env=production
With custom log level:
scenario-rs-cli -c ./example_configs/example-scenario.toml -l debug
demo_video.mp4
All build tasks can be run from the project root using just.
cargo install just
Run just to list all available recipes.
| Command | Description |
|---|---|
just cli |
Run CLI in development mode |
just tui |
Run TUI in development mode |
just gui |
Run GUI in development mode |
| Command | Description |
|---|---|
just check |
Run cargo check on the workspace |
just build |
Build the workspace (debug) |
just build-release |
Build the workspace (release) |
just tui-build |
Build TUI (release) |
just tauri-build-debug |
Build GUI (debug) |
just tauri-build |
Build GUI (release) |
just build-all |
Build everything (Rust + GUI debug) |
just build-all-release |
Build everything (Rust + GUI release) |
| Command | Description |
|---|---|
just test |
Run Rust tests with coverage (requires cargo-tarpaulin) |
just ng-test |
Run Angular unit tests with coverage |
just test-all |
Run all tests with coverage (Rust + Angular) |
just verify |
Full verification: check + all tests + Angular build |
| Command | Description |
|---|---|
just npm-install |
Install frontend dependencies |
just ng-build |
Build Angular frontend |
| Command | Description |
|---|---|
just version |
Show current version |
just bump-version x.y.z |
Set version across all packages |
just schema |
Generate JSON Schema for scenario config |





