iforgor
The CLI tool for all those commands you forget about.
Installation
Quick start
- Create a
.iforgor/folder in your project (or~/.iforgor/for global commands). - Add a TOML file with your commands:
[]
= "My commands"
[[]]
= "Hello world"
= 'echo "Hello, world!"'
[[]]
= "Deploy"
= "Deploy to production"
= ["deploy"]
= true
= '''
echo "Deploying $ENV..."
'''
[[]]
= "ENV"
= "Select environment"
= "select"
= ["staging", "prod"]
- Run
iforgorin that directory.
How it works
iforgor auto-discovers .iforgor/ folders by walking from your current directory upward
to the filesystem root, plus ~/.iforgor/ for global commands. Each .toml file inside
these folders is a domain containing one or more command entries.
Example layout:
~/.iforgor/ # Global commands
rust.toml
git.toml
~/project/.iforgor/ # Project-specific
dev.toml
ci/deploy.toml # Subfolders become domain prefixes
TUI keyboard shortcuts
| Key | Action |
|---|---|
| Type | Search (comma = AND, tag:x / shell:x / source:x / risky:yes filters) |
| Up/Down | Navigate list |
| Enter | Run selected command |
| Tab | Toggle script preview |
| Ctrl+E | Open selected command in $EDITOR at its line |
| Ctrl+N | New command wizard |
| Ctrl+R | Reload commands from disk |
| Esc | Quit |
When the search is empty, the list shows your command history (most recent first). Type a space to show the full command list.
Command format
Each TOML file has an optional [source] header and one or more [[entries]]:
[]
= "Domain name"
= "Optional description"
[[]]
= "Command name"
= '''
echo "hello"
'''
Optional fields
| Field | Type | Description |
|---|---|---|
id |
string | Stable ID (otherwise generated from script hash) |
description |
string | Shown in the TUI list |
tags |
string[] | Categorization, filterable with tag:x |
shell |
string/table | Shell to use (see below) |
only_on |
string | Platform filter, matches std::env::consts::OS (e.g. "linux", "macos", "windows"). Run iforgor --info to see your value. |
only_in_dir |
string[] | Glob patterns for CWD visibility (OR semantics) |
risky |
bool | Require y/N confirmation before running |
after_run |
string/table | "auto" (default), "wait" (press Enter), or { Delay = N } (countdown) |
working_dir |
string | Relative to project root (parent of .iforgor/) |
Shell
Predefined shells: "sh", "bash", "zsh", "fish", "cmd", "powershell".
Custom shell:
= { = "nushell", = ".nu", = "#!/usr/bin/env nu" }
Arguments
Arguments are collected before script execution and injected as environment variables:
[[]]
= "BRANCH" # Variable name in the script ($BRANCH)
= "Select branch" # Displayed to user (defaults to name)
= "select" # "text" (default), "select", or "multi-select"
= ["main", "dev"] # Static choices for select/multi-select
= "git branch" # Or dynamic choices from a shell command's stdout
= "main" # Default for text args
= "tr '\\n' ' '" # Pipe selected value through a shell command
= false # Mask input (for passwords/tokens)
= true # Remember last value across runs (default: true)
For select and multi-select, provide either choices (static list) or source
(shell command whose stdout lines become choices).
Config
Create .iforgor/.config.toml to set defaults. The closest config file wins (project
overrides global):
= "bash"
= "wait"
CLI subcommands
| Command | Description |
|---|---|
iforgor |
Launch interactive TUI |
iforgor new |
New command wizard |
iforgor run <name> |
Run command by name without TUI (--tag, --id, --source, --dry-run) |
iforgor edit [path] |
Open a source file in $EDITOR |
iforgor reload |
Reload commands from all sources |
iforgor source add <path> |
Register a legacy source file |
iforgor source list |
List legacy sources |
iforgor source remove <path> |
Unregister a legacy source |
iforgor --info |
Show app directory and platform string |
iforgor --purge-all |
Reset legacy sources and history |
iforgor --purge-history |
Clear command history only |