ScriptRunner - Create a simple UI for your favorite scripts and command line tools without any coding.
Stop copying CLI commands. Stop writing parameter docs. Stop forcing teammates to memorize flags.
Prepare manifest for your script in JSON and get a professional GUI automatically — with password fields, file pickers, dropdowns, and more.
ScriptRunner is a UI application designed to act as a shell for any command line program or script. The main idea behind ScriptRunner is to allow users to define actions in a JSON file, specifying the parameters for the programs/scripts. ScriptRunner automatically generates a UI form for entering these parameters, making it easy to run the desired script. This document provides a complete guide to using ScriptRunner, including the structure of the manifest file, an example, and a detailed explanation of its components.
- Key features
- How to install
- How to use it
- Ready-to-run examples
- Schema
- Predefined argument sets
- Interactive inputs
- Troubleshooting alerts
- Generate action definition from
PowerShellscript
- ✅ Provides an easy-to-use interface for CLI tools and scripts
- ✅ Compatible with any scripting language (PowerShell, Bash, Python, etc.)
- ✅ Fully cross-platform (Windows, Linux, MacOS)
- ✅ Securely manage passwords and API keys required by scripts
- ✅ Provides notifications for updates to scripts shared via Git repositories
- ✅ Allows creation of predefined parameter sets to streamline common use cases
- ✅ Supports pre-defined responses for interactive script prompts
- ✅ Includes troubleshooting messages for common script problems
- ✅ Allows you to define installation processes for script dependencies
- ✅ Maintains an execution history log, allowing reuse of parameters from previous runs
- ✅ Provides an intuitive browsing experience for your script library (tags, search, etc.)
- ✅ Displays markdown documentation for your scripts
✅ DevOps teams sharing deployment scripts
✅ Data engineers running ETL pipelines
✅ Sysadmins automating maintenance tasks
✅ Support teams running diagnostic scripts
✅ Anyone tired of writing --help documentation
ScriptRunner is built with dotnet core and AvaloniUI, which makes it fully cross-platform. The only required prerequisite is the presence of dotnet SDK 6.0+, which can be downloaded from here https://dotnet.microsoft.com/en-us/download/dotnet If you already have dotnet sdk, you can install ScriptRunner on any platform with the following command:
dotnet tool install --global ScriptRunnerGUI --no-cache --ignore-failed-sources --add-source https://api.nuget.org/v3/index.jsonAfter successful installation, simply type ScriptRunnerGUI in the console to run it. On Windows, you can pin the ScriptRunner icon to your taskbar for easy access.
Prepare a manifest for your action and save it as a json file. The recommended way is to use an editor like VSCode and include the schema reference available at: ScriptRunnerSchema.json Thanks to the power of VSCode and JSON schema, you will get intellisense and semantic validation. A sample manifest that allows to run docker container can look as follows:
{
"$schema": "https://raw.githubusercontent.com/cezarypiatek/ScriptRunnerPOC/main/schema/v1/ScriptRunnerSchema.json",
"actions": [
{
"name": "Run SQL Server Docker Container",
"description": "Run a Docker container with Microsoft SQL Server",
"command": "docker run -e ACCEPT_EULA=Y -e MSSQL_SA_PASSWORD={MSSQL_SA_PASSWORD} -e MSSQL_PID={MSSQL_PID} -p {HOST_PORT}:1433 -v {DATA_DIR}:/var/opt/mssql/data --name {CONTAINER_NAME} mcr.microsoft.com/mssql/server:latest",
"installCommand": "docker pull mcr.microsoft.com/mssql/server:latest",
"categories": ["docker", "SQL Server"],
"params": [
{
"name": "MSSQL_PID",
"prompt": "dropdown",
"description": "Product Edition",
"default": "Developer",
"promptSettings": {
"options": ["Developer", "Express", "Standard", "Enterprise"]
}
},
{
"name": "HOST_PORT",
"prompt": "numeric",
"description": "Server port",
"default": "1433"
},
{
"name": "MSSQL_SA_PASSWORD",
"prompt": "password",
"description": "Password for the SA"
},
{
"name": "CONTAINER_NAME",
"prompt": "text",
"description": "Name for the container",
"default": "sqlserver"
},
{
"name": "DATA_DIR",
"description": "Data directory",
"prompt": "directoryPicker"
}
]
}
]
}
Add a file or directory with your action manifest to Action Sources
Using script list locate your action
This field points to the JSON schema that validates the manifest file. It ensures that the file adheres to the required structure and formats and provides intellisense in editors like VSCode. Should be set to https://raw.githubusercontent.com/cezarypiatek/ScriptRunnerPOC/main/schema/v1/ScriptRunnerSchema.json
This is an array of action objects. Each action defines a specific script or command-line program that the UI will execute.
Each action object describes how a single automation should be rendered and executed:
name/description: Title and subtitle shown in ScriptRunner (names must be unique per source).command(required): CLI command template. Use{paramName}placeholders for parameter values. Relative paths are resolved against the JSON file.useSystemShell: Launches command via the OS shell instead of embedded console.runCommandAsAdmin: Blocks execution unless ScriptRunner is running elevated (Windows) orsudocapable.workingDirectory: Overrides the default (folder that contains the manifest) for the main command.installCommand,installCommandWorkingDirectory,runInstallCommandAsAdmin: Optional setup command shown as “Install”.categories: Labels used to group/search actions in the UI.docs: Path to a markdown file displayed alongside the action.environmentVariables: Key/value map (values can embed{paramName}placeholders) injected into the spawned process.autoParameterBuilderStyle/autoParameterBuilderPattern: Configure how parameters are appended to the command automatically.predefinedArgumentSets+ optionalpredefinedArgumentSetsOrdering: Named presets that pre-fill parameter values (ScriptRunner always adds a<default>set, but you can add more).params: Array of parameter definitions (see the next section).interactiveInputs: Map console output patterns to quick-reply buttons that feed text back to STDIN.troubleshooting/installTroubleshooting: Regex-driven alerts displayed when the main or install command writes matching output.
Each parameter object can shape both the UI control and how ScriptRunner constructs the final command. The most common properties are:
name(required): Identifier used for placeholders ({name}), predefined argument sets, and environment-variable substitutions.description: Text shown next to the control; falls back tonamewhen omitted.default: Value pre-populated in the UI and stored in the automatically generated<default>argument set.prompt(required): Chooses the control type (text box, dropdown, checkbox, etc.). See Prompt Types.promptSettings: Control-specific settings (date format, dropdown options, file template, etc.).autoParameterBuilderPattern: Overrides the action-level pattern when auto-appending this parameter to the command.valueGeneratorCommand: Optional helper command that runs on demand and fills the control with its stdout (relative paths are resolved from the action file).valueGeneratorLabel: Custom tooltip/label for the auto-fill button triggered byvalueGeneratorCommand.skipFromAutoParameterBuilder: Whentrue, excludes the parameter fromauto parameter builder(useful when parameter is used only invalue generatorsof other parameters).
The prompt property determines which control ScriptRunner renders for a parameter (text box, dropdown, checkbox, file picker, etc.) and which promptSettings are available. For the full catalog of controls, supported settings, and sample JSON snippets, see the dedicated Prompt Types guide.
environmentVariables lets you set additional process variables without touching the global shell. Values support {paramName} substitution, so you can easily reference values of other parameters:
"environmentVariables": {
"AWS_PROFILE": "{profile}",
"VAULT_TOKEN": "{vaultToken}"
}Add docs: "path/to/file.md" to show instructions, diagrams, or runbooks next to the action. ScriptRunner resolves the path relative to the manifest and automatically loads referenced assets (images, attachments) from the same folder.
If most of your commands follow a pattern how parameters are passed to executed action, set one of the builders instead of concatenating strings manually:
"autoParameterBuilderStyle": "powershell"The PowerShell builder emits -ParamName 'Value' for every parameter unless skipFromAutoParameterBuilder is true. For other CLIs you can provide a custom template:
"autoParameterBuilderPattern": "--{name} \"{{{name}}}\""You can still override the pattern per parameter via autoParameterBuilderPattern.
Bundle common parameter combinations into named presets so teammates can run frequent scenarios with one click:
"predefinedArgumentSets": [
{
"description": "Production",
"fallbackToDefault": true,
"arguments": {
"subscription": "prod-sub",
"resourceGroup": "rg-prod-shared"
}
}
],
"predefinedArgumentSetsOrdering": "Descending"fallbackToDefault fills in any missing parameters from the automatically generated <default> set.
The repository ships with examples/ScriptRunnerExamples.json, a manifest that contains four minimal actions showcasing how to wrap PowerShell, Python, Bash (via WSL), and .NET console apps. Import that file from Settings ➜ Config sources and you will get the following definitions (interactive inputs and troubleshooting rules are omitted here for brevity):
{
"name": "PowerShell Hello Prompt",
"description": "Demonstrates stdin buttons and troubleshooting with a PowerShell script.",
"command": "pwsh -NoProfile -Command ./examples/powershell/HelloPrompt.ps1",
"autoParameterBuilderStyle": "powershell",
"categories": ["powershell"],
"params": [
{
"name": "textArgument",
"description": "Text value passed to the script",
"default": "ScriptRunner",
"prompt": "text"
},
{
"name": "filePath",
"description": "File whose content can be displayed",
"default": "./examples/sample-data/hello.txt",
"prompt": "fileContent",
}
]
}{
"name": "Python Hello Prompt",
"description": "Same scenario implemented in Python.",
"command": "python -u ./examples/python/hello_prompt.py \"{textArgument}\" \"{filePath}\"",
"categories": ["python"],
"params": [
{
"name": "textArgument",
"description": "Text value passed to the script",
"default": "ScriptRunner",
"prompt": "text"
},
{
"name": "filePath",
"description": "File whose content can be displayed",
"default": "./examples/sample-data/hello.txt",
"prompt": "fileContent",
}
]
}{
"name": "WSL Bash Hello Prompt",
"description": "Runs the Bash implementation inside WSL",
"command": "wsl -e sh ./bash/hello_prompt.sh \"{textArgument}\" \"{filePath}\"",
"categories": ["bash", "wsl"],
"params": [
{
"name": "textArgument",
"description": "Text value passed to the script",
"default": "ScriptRunner",
"prompt": "text"
},
{
"name": "filePath",
"description": "File whose content can be displayed",
"default": "./examples/sample-data/hello.txt",
"prompt": "fileContent",
"promptSettings": {
"useWslPathFormat": true
}
}
]
}{
"name": "C# Hello Prompt",
"description": "Uses dotnet run on the HelloPromptApp console project.",
"command": "dotnet run --project ./examples/dotnet/HelloPromptApp/HelloPromptApp.csproj -- \"{textArgument}\" \"{filePath}\"",
"categories": ["dotnet"],
"params": [
{
"name": "textArgument",
"description": "Text value passed to the app",
"default": "ScriptRunner",
"prompt": "text"
},
{
"name": "filePath",
"description": "File whose content can be displayed",
"default": "./examples/sample-data/hello.txt",
"prompt": "fileContent"
}
]
}{
"name": "TypeScript Hello Prompt",
"description": "Runs the TypeScript version via ts-node.",
"installCommand": "npm i -D tsx",
"command": "npx tsx ./examples/node/tsconfig.json ./examples/node/hello_prompt.ts \"{textArgument}\" \"{filePath}\"",
"categories": ["node", "typescript"],
"params": [
{
"name": "textArgument",
"description": "Text value passed to the script",
"default": "ScriptRunner",
"prompt": "text"
},
{
"name": "filePath",
"description": "File whose content can be displayed",
"default": "./examples/sample-data/hello.txt",
"prompt": "fileContent"
}
]
}Interactive inputs let you display predefined buttons with replies whenever the running script prints a prompt you recognize. Each entry consists of:
whenMatched: Regex evaluated against live STDOUT (ANSI codes are stripped automatically).inputs: A list of{ label, value }pairs rendered as buttons; clicking a button writesvalueto the process STDIN, so you can automate those “Type YES” confirmations.
Example:
"interactiveInputs": [
{
"whenMatched": "Delete this directory?",
"inputs": [
{
"label": "Yes",
"value": "Y"
},
{
"label": "Yes to All",
"value": "A"
},
{
"label": "Skip",
"value": "S"
},
{
"label": "Abort",
"value": "X"
}
]
}
]Whenever the command prints “Delete this directory?”, ScriptRunner shows extra buttons representing predefined responses. After pressing selected button, corresponding value followed by a newline is sent to the process.
troubleshooting (and installTroubleshooting for the install command) let you transform noisy logs into actionable hints. Each rule has:
whenMatched: Regex that runs against sanitized STDOUT/STDERR.alertMessage: Text displayed in the UI (supports${namedGroup}replacements from the regex).severity: One oferror,warning,info,successwhich controls styling.
Example:
"troubleshooting": [
{
"whenMatched": "Missing secret (?<name>\\w+)",
"alertMessage": "Secret ${name} is missing. Open the vault and add it.",
"severity": "warning"
}
]When the output contains Missing secret API_TOKEN, ScriptRunner raises a yellow banner with the message above, helping teammates recover faster. Pair these alerts with markdown docs for a more guided troubleshooting flow.
function Get-ActionDefinition
{
param($CommandPath)
$data = Get-Command $CommandPath
[Ordered]@{
name = [regex]::Replace($data.Name.TrimEnd(".ps1"), "(\p{Ll})(\p{Lu})", '$1 $2')
command = "pwsh -NoProfile -Command "+ $(Resolve-Path $CommandPath -Relative)
autoParameterBuilderStyle = "powershell"
params = foreach($key in $data.Parameters.Keys)
{
[Ordered]@{
name = $key
description = [regex]::Replace($key, "(\p{Ll})(\p{Lu})", '$1 $2')
prompt = if($data.Parameters[$key].SwitchParameter)
{
"checkbox"
}
elseif($data.Parameters[$key].ParameterType.Name -eq "DateTime")
{
"datePicker"
}
elseif($key -match "path")
{
"filePicker"
}
else{
"text"
}
}
}
} | ConvertTo-Json -Depth 10
}



