One binary. Every prompt. JSON out. Go home.
A clet is a CLI-let - Simple CLI commands that prompt the user with rich TUI (full mouse/keyboard), typed inputs, consistent JSON output and exit codes.
Works for humans and AI agents alike.
| Alias | Description | Options |
|---|---|---|
select |
Presents a list of options and returns the text of the selected item. | --options, args... |
text |
Prompts for free-form text input and returns the entered string. | |
multiline-text, mt |
Prompts for multi-line text input and returns the entered string. | |
int |
Prompts for an integer value using a numeric spinner. | --step |
decimal |
Prompts for a decimal value using a numeric spinner. | --step |
confirm |
Prompts for a yes/no confirmation and returns a boolean. | --prompt |
date |
Prompts for a date and returns an ISO-8601 date string (YYYY-MM-DD). | |
time |
Prompts for a time and returns an ISO-8601 time string (HH:MM:SS). | |
duration |
Prompts for a duration and returns an ISO-8601 duration string (e.g. PT1H30M). | |
color |
Prompts for a color and returns a hex string (#rrggbb). | |
multi-select |
Presents a list of options with checkboxes and returns the selected texts. | --options, args... |
attribute-picker, attribute |
Prompts for text attributes (foreground, background, style) and returns a JSON object. | |
pick-file, file |
Opens a file picker dialog and returns the selected file path(s). | --multi, --root, --filter |
pick-directory, dir |
Opens a directory picker dialog and returns the selected directory path. | --root |
linear-range, range |
Presents a linear range selector (single, multi, or bounded range) over labelled options. | --mode, --options, --range-kind, args... |
md, markdown |
Browse and render Markdown files with link navigation and syntax highlighting. | --theme, --cat, --no-browse, args... |
brew install gui-cs/tap/clet # macOS / Linux
winget install gui-cs.clet # Windows 10/11
dotnet tool install -g clet # any platform with .NET SDKTracks Terminal.Gui's develop channel — a new clet prerelease lands on NuGet for every TG develop publish.
dotnet tool install -g clet --prereleasezsh/bash users: If
cletisn't found afterdotnet tool install, add the tools directory to your PATH:echo 'export PATH="$HOME/.dotnet/tools:$PATH"' >> ~/.zshrc # or ~/.bashrc source ~/.zshrcPowerShell does this automatically; zsh and bash do not.
| Task | Before clet |
With clet |
|---|---|---|
| Prompt for a choice | select / gum choose / fzf |
clet select "prod" "staging" "dev" |
| Pick a file | gum file (fuzzy filter) |
clet pick-file (real tree dialog) |
| Confirm an action | read -p "Sure? [y/N]" |
clet confirm "Deploy to prod?" |
| Render Markdown | glow / bat / mdcat |
clet md ./CHANGELOG.md |
| Multiple tools, mismatched exit codes | read + dialog + fzf + glow |
clet — one tool, one contract |
# Pick from a list
clet select "prod" "staging" "dev"
# Pick a file from a tree dialog
clet pick-file --root ./src --title "Choose a source file"
# Confirm before a destructive action
clet confirm "This will delete 40k rows. Continue?"
# Render a Markdown file — full-screen, dismiss with q / Esc
clet md ./CHANGELOG.md
# See all available clets
clet list# Structured elicitation — agent gets a typed result, not raw text
clet select --json "prod" "staging" "dev"
# → {"schemaVersion":1,"status":"ok","value":"staging"}
# Pick a file with a timeout
clet pick-file --json --root ./src --timeout 30s
# → {"schemaVersion":1,"status":"ok","value":"src/User.ts"}
# Confirm an action
clet confirm --json "Apply this patch?"
# → {"schemaVersion":1,"status":"cancelled"} (exit 130)
# Discover available clets once per session
clet list --json
# → {"schemaVersion":1,"clets":[{"alias":"select","kind":"input","resultType":"string",...},...]}Exit codes:
0success2usage error130cancelled (SIGINT convention).
clet is in friends-and-family alpha (milestone tracker). If something doesn't work, looks wrong, or is just confusing, file an issue. Include:
clet --versionoutput (e.g.1.0.0-alpha (Terminal.Gui 2.0.2-develop.37)).- Your terminal + OS (e.g. "Windows Terminal on Windows 11", "iTerm2 on macOS 15").
- What you ran, what you expected, what happened.
Each of those is good at one thing. clet is the unification, with a real UI toolkit underneath. Every clet has full mouse support, configurable keybindings, themed colors, and one consistent navigation model. clet pick-file is Terminal.Gui's FileDialog — a real tree with sortable columns, extension filters, and breadcrumbs, not a fuzzy-filter over find output. And because inputs and viewers live in one tool, you get the same keys and colors whether you're picking a file or reading a Markdown document.
For a shell user who only needs read-with-validation, gum is fine. We are not competing for that user.
- Input clets (
select,text,pick-file, …) prompt for a value and return a typed result: exit 0,{"schemaVersion":1,"status":"ok","value":…}. - Browser clets (
md) render content with link navigation, back/forward history, and return on dismiss: exit 0,{"schemaVersion":1,"status":"ok"}.
Both share theming, keybindings, mouse support, and the JSON envelope.
{ "schemaVersion": 1, "status": "ok", "value": "prod" } // input selected
{ "schemaVersion": 1, "status": "ok" } // viewer dismissed
{ "schemaVersion": 1, "status": "cancelled" } // Esc / Ctrl-C (exit 130)
{ "schemaVersion": 1, "status": "error", "code": "validation", "message": "…" }0success1no-result2usage error130cancelled (SIGINT convention).
Esc and Ctrl-C cancel input clets; q, Esc, and Ctrl-C dismiss viewer clets. --timeout <duration> (e.g. --timeout 30s) cancels automatically — useful for AI agent scripts.
Input (14): text, int, decimal, select, multi-select, confirm, pick-file, pick-directory, date, time, duration, color, attribute-picker, linear-range
Browser (1): md (Markdown browser with link navigation, back/forward history, and syntax highlighting)
Run clet list to see what's available in your installed version.
Every clet inherits the active Terminal.Gui theme automatically. To customize, create ~/.tui/clet.config.json:
{
"Theme": "MyTheme",
"Themes": {
"MyTheme": {
"ColorSchemes": {
"Base": {
"Normal": { "Foreground": "#E0E0E0", "Background": "#1E1E1E" },
"Focus": { "Foreground": "#FFFFFF", "Background": "#264F78" },
"HotNormal": { "Foreground": "#569CD6", "Background": "#1E1E1E" },
"HotFocus": { "Foreground": "#9CDCFE", "Background": "#264F78" }
}
}
}
}
}Or, you can pick from a built-in Terminal.Gui Theme. This example picks the Anders theme, a nod to Anders Heilsberg who created TurboPascal.
{
"Theme": "Anders"
}
All clets render with the Base color scheme, so customizing Base controls every clet's appearance. See the Terminal.Gui Configuration docs for the full schema.
Key bindings are also configured via ~/.tui/clet.config.json:
{
"Key.Bindings": {
"Application.QuitKey": "Ctrl+Q"
}
}This changes the quit/dismiss key for all clets. clet md shows the active quit key in the status bar automatically.
No - for brew install and winget install — those ship a self-contained NativeAOT binary (~8 MB, no runtime needed).
Yes - for dotnet tool install -g clet.
Every push to develop triggers a matching clet prerelease push to NuGet (versioned 1.x.y-develop.NN). Stable users see no churn — dotnet tool install -g clet still resolves to the latest non-prerelease, and brew/winget only ship stable main releases. If you want the bleeding edge, pass --prerelease.
File an issue. That's the only feedback channel — no Discussions, no forum. See the Alpha feedback section above for what to include.
- Demo scripts — runnable examples showing how to chain clets in scripts
- Press release & customer voices
- Implementation spec

