Create an easy to use interactive CLI to simplify your workflow with a single YAML file.
To install via Homebrew just run the following command:
brew install evilmarty/ilc/ilcEnsure you have Go installed then run the follow:
go install github.com/evilmarty/ilcBinaries are available to download. Get the latest release binary for your platform.
The usage is as followed:
ilc [flags] CONFIG [COMMAND ...] [INPUT ...]CONFIG is the path to your config file.
COMMAND is one or a cascade of subcommands defined in the config file.
INPUT is one or many inputs inherited by the command.
-version/--version: Displays the version information and exits.-debug/--debug: Prints debugging logs to standard error.-non-interactive/--non-interactive: Disables interactive terminal prompts. If any required inputs are missing, the tool immediately exits with an error listing the missing inputs. Useful for CI/CD or automated scripts.-validate/--validate: Validates the syntax, structure, and schema of the configuration file without executing any commands.
The best way to use ilc is to include it in the shebang of your config, like so:
#!/usr/bin/env ilcIf the configuration has defined commands they can either be passed as
arguments or an interactive prompt will allow you to choose a command. If the
command specified in the arguments has itself subcommands the interactive
prompt will appear to complete the selection process.
After a command is specified or selected, if any inputs are missing, an interactive TUI prompt will collect them before execution. Inputs are rendered natively according to their type:
boolean: Rendered as interactive selection toggles (Yes/No).number: Can be incremented or decremented using arrow keys, enforcingminandmaxconstraints.string(withoptions): Rendered as an interactive select list.string(withpattern): Validated live against the regex pattern as the user types.
Inputs can also be pre-filled via command-line arguments or environment variables prefixed with ILC_INPUT_. Inputs provided via these methods are not prompted interactively.
All resolved input values are accessible within the script environment via variables prefixed with ILC_INPUT_.
ilc examples/ilc.yml calendar -month Februaryexport ILC_INPUT_month=February
ilc examples/ilc.yml calendarilc logs the arguments of successfully executed commands in a history file.
- Replay Prefix (
!): You can replay a previous execution by prefixing the command name or argument with!. For example,ilc examples/ilc.yml !calendarorilc examples/ilc.yml !to replay the last run of that configuration. - History File Location: History is written to
~/.ilc_historyby default. This path can be overridden by setting theILC_HISTFILEenvironment variable.
The overall description of what is the config's purpose. Is optional.
Optionally set environment variables for the command. Cascades to descending commands and subcommands. Expressions can be used in values.
The shell to run the command in. Must be in JSON array format. Defaults to ["/bin/sh"].
Runs command-line programs using the specified shell. If commands is also
defined then run cannot be invoked directly and becomes a template accessible
to all nested commands. See Templating for more information.
Setting pure to true to not pass through environment variables and only use
environment variables that have been specified or inherited. Subcommands do not
inherit this option and must be set for each command.
Optionally specify inputs to be used in run and env values. Inputs can be
passed as arguments or will be asked when invoking a command. Nested commands
inherit inputs and cascade down.
The key input_name is a string and its value is a map of the input's
configuration. The name can be used as an argument in the form -<input_name>
or --<input_name> followed by a value. The value can be omitted for boolean types.
The type of input. Defaults to string but can also be boolean and number.
Optionally describe the input's purpose or outcome.
Limit the value to a set of acceptable choices. Options can be defined as either a list or a map, with behavior varying slightly based on the input type:
- String inputs: The list items are presented directly as selectable options.
- Boolean inputs: The list must contain exactly 2 items; the item at index 0 represents
falseand the item at index 1 representstrue.
String options list:
inputs:
month:
options:
- January
- February
- March
- April
- May
- June
- July
- August
- September
- October
- November
- DecemberBoolean options list:
inputs:
confirm:
type: boolean
options:
- No way # index 0 (false)
- Absolutely # index 1 (true)- Standard Behavior: In general (and for string inputs), keys are presented as the user-facing labels, and the corresponding values are the resulting values.
- Boolean inputs: Follows the standard
Label: Valueformat for consistency, but also supports the shorthandValue: Labelformat for convenience.
String options map:
inputs:
city:
options:
Brisbane: bne
Melbourne: mlb
Sydney: sydBoolean options map (Consistent style):
inputs:
confirm:
type: boolean
options:
Absolutely: true
No way: falseBoolean options map (Shorthand style):
inputs:
confirm:
type: boolean
options:
true: Absolutely
false: No wayA regex pattern to validate the input's value. Default is to allow any input.
Applies to string types only.
inputs:
year:
pattern: "(19|20)[0-9]{2}"Set the default value for the input. It is overwritten when a value is given as an argument or changed when prompted. If a default value is not defined then a value is required.
The minimum value the input can be. Applies to number types only.
The maximum value the input can be. Applies to number types only.
The commands defined are then available to be invoked from the command line either by passing arguments or by interactive selection. Must define at least one command.
Use commands.<command_name> to give your command a unique name. The key
command_name is a string and its value is a map of the command's configuration
data. A string value can be used as a shorthand for the run attribute.
commands:
calendar: calOptionally describe the command's purpose or outcome.
See run for more information.
Define sub-commands in the same structure as commands. All inputs or env
defined cascade to all sub-commands. Cannot be used in conjunction with run.
Optionally set environment variables for the command. Cascades to descending commands and subcommands. See Templating for more information.
commands:
greet:
env:
NAME: "{{ .Input.name }}"
GREETING: HelloSetting pure to true to not pass through environment variables and only use
environment variables that have been specified or inherited. Subcommands do not
inherit this option and must be set for each command.
Optionally specify inputs to be used in run and env values. Inputs can be
passed as arguments or will be asked when invoking a command. Nested commands
inherit inputs and cascade down. See inputs for more information.
Optionally include additional aliases to reference the command. Aliases must be unique within the same parent.
commands:
files:
commands:
list:
aliases:
- ls
run: ls -lf
directories:
aliases:
- dir
commands:
list:
aliases:
- ls
run: ls -ldGo's template language is available for
run and env values to construct complex entries. Templates are evaluated
after inputs are collected but before script execution. Along with inputs,
templates can access environment variables that are present and regardless
whether pure is enabled or not.
Nested commands can include the run scripts from their parent commands.
ie. {{template "<command_name>"}}
The expression to reference an input value. ie. '{{ .Input.my_input }}'
The expression to reference an environment variable. ie. '{{ .Env.HOME }}'
A function to retrieve the input by its name. ie. '{{input "my_input"}}'
A function to retrieve the environment variable by its name. ie. '{{env "HOME"}}'
description: Display a calendar for the month
inputs:
month:
options:
- January
- February
- March
- April
- May
- June
- July
- August
- September
- October
- November
- December
run: cal -m {{ .Input.month }}description: My awesome CLI
commands:
weather:
description: Show the current weather forecast
run: curl wttr.in?0QF
calendar:
description: Display a calendar for the month
inputs:
month:
options:
- January
- February
- March
- April
- May
- June
- July
- August
- September
- October
- November
- December
run: cal -m {{ .Input.month }}
greet:
description: Give a greeting
inputs:
name:
default: World
greeting:
options:
- Hello
- Hi
- G'day
run: echo $GREETING $NAME
env:
NAME: "{{ .Input.name }}"
GREETING: "{{ .Input.greeting }}"Contributions are welcome! Whether you are reporting a bug, proposing a feature, or submitting a pull request, we appreciate your help in making ilc better.
Before contributing, please read our Contributing Guidelines to understand:
- The project's architecture and package design (e.g., the separation of concerns between
internal/inputsandinternal/ilc). - How to format issues and pull requests.
- Our coding standards.
For AI agents contributing to this repository, please also refer to AGENTS.md for local agent execution guidelines and specialized workspace skills.
Ensure you have Go installed (Go 1.18 or later is recommended).
You can compile the binary locally by running:
make buildThis compiles the ilc executable using the -buildvcs=false flag to prevent VCS permission errors during sandboxed builds.
To run the automated unit test suite, use the following command:
make testOr run Go's test runner directly:
go test -buildvcs=false ./...Since ilc features rich interactive TUI components built on Bubble Tea, you can verify your changes using the configurations inside the examples/ directory:
-
Verify Numeric Inputs & Constraints:
./ilc examples/ilc.yml rate
Select the
ratecommand, navigate to theratinginput, and press theUpandDownarrows to test validation, increment/decrement, and bounds clamping. -
Verify Text Validation & Placeholders:
./ilc examples/ilc.yml greet
Verify that default text placeholders render correctly, and that live input regex pattern matching triggers validation ticks/crosses immediately as you type.
-
Verify Help Cascades:
./ilc examples/ilc.yml -help # Or for specific subcommands: ./ilc examples/ilc.yml weather -help
This project is licensed under the Apache 2.0 License. See the LICENSE file for details.

