Stop memorizing command names. Search by what you want to do.
cmdpeek is a searchable command palette for discovering and running reusable terminal workflows.
It lets you find commands by intent using titles, descriptions, labels and command contents, resolve their inputs interactively, preview the rendered shell command and execute it only after explicit confirmation.
Aliases optimize commands you remember.
cmdpeekhelps you discover commands you do not.
⭐ Drop a star to support cmdpeek ⭐
Search by intent
↓
Select a command
↓
Resolve interactive variables
↓
Review the rendered command
↓
Confirm and execute
- YAML-driven command catalog
- Search by title, name, description, labels and script contents
- Ranked multi-term filtering
- Searchable and paginated variable selectors
- Interactive inputs, static options and environment values
- Dynamic options generated by shell commands
- Dependent variables resolved in declaration order
- Live, scrollable command preview
- Configurable shell globally or per command
- Explicit confirmation before execution
- Command-line search that opens the catalog already filtered
- Non-interactive execution for scripts, aliases and CI
Command names and aliases are fast when you remember them. The problem is the command you know exists but cannot recall exactly.
cmdpeek searches structured command metadata while you type:
title
name
description
labels
command contents
A command such as:
- name: github-run-logs
title: Download GitHub Actions run logs
description: Download and extract logs from a workflow run
labels:
- github
- actions
- logs
- download
run: |
# ...can be discovered with searches such as:
github logs
actions
download logs
workflow
Labels act as both categories and semantic aliases. They let one workflow be found through different vocabulary without duplicating commands:
labels:
- kubernetes
- pods
- logs
- troubleshooting
- stream
- kloThe same command can then be found with:
pod logs
troubleshooting
stream
klo
This is especially useful when turning large alias collections into a smaller set of guided workflows. Historical aliases can remain as labels while output modes, namespaces and resource names become interactive variables.
Useful commands are often scattered across shell history, aliases, snippets, README files and team documentation.
cmdpeek turns them into a catalog that can be explored without memorizing exact names:
version: 1
shell: bash
commands:
- name: pod-logs
title: Follow Kubernetes pod logs
description: Select a namespace and stream logs from one of its pods
labels:
- kubernetes
- pods
- logs
- troubleshooting
- klo
run: kubectl logs -f "{{pod}}" -n "{{namespace}}"
variables:
- name: namespace
prompt: Select namespace
description: Namespace from the current Kubernetes context
source:
type: command
command: >-
kubectl get namespaces
-o jsonpath='{range .items[*]}{.metadata.name}{"\n"}{end}'
- name: pod
prompt: Select pod
description: Pod discovered inside the selected namespace
source:
type: command
command: >-
kubectl get pods -n "{{namespace}}"
-o jsonpath='{range .items[*]}{.metadata.name}{"\n"}{end}'The workflow becomes:
discover → resolve → preview → confirm → execute
cmdpeek is not intended to replace every task runner, snippet manager or fuzzy finder. Its focus is interactive discovery through structured metadata and guided execution.
| Tool | Best suited for | cmdpeek focus |
|---|---|---|
| Shell aliases | Very fast shortcuts you already remember | Discover commands without remembering the alias |
fzf |
Fuzzy-searching arbitrary text streams | Search structured command metadata and then resolve variables |
just |
Project recipes and command execution | Discover workflows by intent with labels, descriptions and live previews |
Task |
Project automation and task dependencies | Interactive catalog navigation and dynamic selectors |
lets |
YAML-defined developer tasks and commands | Search-first discovery across metadata, guided values and confirmation |
pet |
Saving, tagging and recalling command snippets | Typed variables, dependent selectors and final command preview |
These tools can overlap and can often be combined with external fuzzy finders. In cmdpeek, discovery is part of the command model itself: titles, descriptions and labels are first-class searchable data.
/ Search
↑ / ↓ Navigate
← / → Change page
e Open details
Enter Select
q Quit
Search terms are matched across multiple fields and ranked. Multiple terms can be used together:
kubernetes logs
production deploy
github actions
elasticsearch size
Search terms can be passed directly after cmdpeek:
cmdpeek kubernetes context
cmdpeek aws login
cmdpeek elasticsearch shardsThe positional arguments are joined into an initial search query and matched against the same searchable fields as the interactive catalog:
title
name
description
labels
command contents
The resulting behavior is:
exact command name → select that command directly
one search result → select that command directly
multiple results → open the interactive catalog already filtered
no results → open the catalog showing no matching commands
For example:
cmdpeek switch-kubernetes-contextselects the command directly when its internal name is exactly switch-kubernetes-context.
A broader query such as:
cmdpeek kubernetes contextkeeps the workflow interactive when several commands match, allowing the user to review and choose the intended command.
This mode is different from --no-interactive: command-line search still uses the interactive variable selectors, command preview and execution confirmation.
Press e to inspect:
description
internal name
shell
labels
command template
variables and their sources
Long detail views support scrolling and pagination.
Four variable sources are supported:
| Source | Purpose |
|---|---|
input |
Free-form user input |
options |
Static selectable values |
environment |
Initial value loaded from an environment variable |
command |
Options generated by running a shell command |
- name: output
prompt: Output directory
description: Directory used to store generated files
default: $HOME/example-directory/output
source:
type: input- name: environment
prompt: Select environment
default: staging
source:
type: options
values:
- development
- staging
- production- name: profile
prompt: AWS profile
default: default
source:
type: environment
variable: AWS_PROFILE- name: branch
prompt: Select Git branch
source:
type: command
command: git branch --format='%(refname:short)'When a command source returns exactly one value, cmdpeek accepts it automatically.
Command sources have a 10-second timeout. Empty and duplicate output lines are removed.
Command variables may reference variables declared earlier:
variables:
- name: namespace
prompt: Select namespace
source:
type: command
command: >-
kubectl get namespaces
-o jsonpath='{range .items[*]}{.metadata.name}{"\n"}{end}'
- name: pod
prompt: Select pod
source:
type: command
command: >-
kubectl get pods -n "{{namespace}}"
-o jsonpath='{range .items[*]}{.metadata.name}{"\n"}{end}'The second selector is populated using the namespace selected in the first.
Long static or command-generated option lists can be searched and paginated:
/ Filter options
↑ / ↓ Navigate
← / → Change page
Enter Select
r Retry command source
Esc Clear search or cancel
For example:
Search: sandbox
sandbox-cat-3
sandbox-dog-2
sandbox-pet-1
Page 1/2 · 11 options
The command preview updates while values are entered or selected.
Ctrl+↑ Scroll preview up
Ctrl+↓ Scroll preview down
Long scripts remain inside a stable terminal-width viewport, with the current line range shown below it.
After resolving all variables, cmdpeek displays the final rendered command.
Execute this command?
╭────────────────────────────────────────────╮
│ kubectl logs -f api-7d9f8 -n production │
╰────────────────────────────────────────────╯
y execute n cancel enter cancel
Execution requires an explicit y. Pressing Enter cancels.
Commands can also be selected by their exact internal name without opening the searchable catalog.
Provide variable values by name with repeatable --set flags:
cmdpeek \
--no-interactive \
--name deploy \
--set environment=staging \
--set version=1.4.2--set is the recommended form because scripts remain readable and do not depend on the order of variables in the YAML catalog.
When --no-interactive is enabled, positional values are assigned to variables in declaration order:
cmdpeek \
--no-interactive \
--name gcommit \
"Add non-interactive execution" \
mainWithout --no-interactive, positional arguments are treated as an initial interactive search query instead.
For a completely unattended execution, add --yes:
cmdpeek \
--no-interactive \
--name copy-source-files \
--set file_type=go \
--yesUse --dry-run to render and print the final command without executing it:
cmdpeek \
--no-interactive \
--name deploy \
--set environment=production \
--set version=1.4.2 \
--dry-runNon-interactive resolution follows these rules:
input use --set or a positional value, otherwise use the default
environment use --set, then the environment variable, then the default
options validate the supplied value against the configured options
command generate and validate available values in declaration order
For a command source, a single generated option is selected automatically. If multiple options are returned, a value must be supplied with --set or positionally.
Unless --yes or --dry-run is used, the final rendered command is still shown in the confirmation interface before execution.
Available flags:
--no-interactive select a command without the catalog TUI
--name exact command name
--set NAME=VALUE provide a named variable; may be repeated
--yes skip execution confirmation
--dry-run print the rendered command without executing it
Linux and macOS users:
brew install --cask pierinho13/tools/cmdpeekUpgrade:
brew update
brew upgrade --cask cmdpeekThe cask is published through pierinho13/homebrew-tools.
Download the archive for your operating system and architecture from the Releases page, extract it and place the binary in your PATH.
Linux and macOS:
tar -xzf cmdpeek_<version>_<os>_<arch>.tar.gz
chmod +x cmdpeek
sudo mv cmdpeek /usr/local/bin/Windows releases are distributed as ZIP archives.
git clone https://github.com/pierinho13/cmdpeek.git
cd cmdpeek
go build -o cmdpeek ./cmd/cmdpeek
sudo mv cmdpeek /usr/local/bin/Verify the installation:
cmdpeek --config examples/basic.yamlCopy the basic example:
cp examples/basic.yaml .cmdpeek.yaml
cmdpeekOr provide a configuration explicitly:
cmdpeek --config examples/kubernetes.yamlConfiguration lookup order:
1. --config <path>
2. CMDPEEK_CONFIG_GITHUB
3. CMDPEEK_CONFIG_FILE
4. .cmdpeek.yaml
Use a local configuration file:
export CMDPEEK_CONFIG_FILE="$HOME/.config/cmdpeek/commands.yaml"
cmdpeekOr load a versioned catalog directly from GitHub:
export CMDPEEK_CONFIG_GITHUB="company/platform-config:cmdpeek/commands.yaml@main"
cmdpeekFor private repositories, cmdpeek reads CMDPEEK_GITHUB_TOKEN first and falls back to GITHUB_TOKEN:
export CMDPEEK_CONFIG_GITHUB="company/private-config:cmdpeek/commands.yaml@main"
export CMDPEEK_GITHUB_TOKEN="github_pat_..."
cmdpeekRemote configurations are checked on every startup using GitHub ETags. Changed files are downloaded and validated before replacing the local cache. If GitHub is temporarily unavailable, the last valid cached configuration is used with a warning.
version: 1
shell: bash
commands:
- name: greet
title: Greet a person
description: Print a personalized greeting
labels:
- example
- input
- greeting
run: |
set -euo pipefail
name="{{name}}"
echo "Hello, ${name}!"
variables:
- name: name
prompt: Person name
description: Name included in the greeting
default: world
source:
type: inputA command may override the global shell:
shell: shexamples/basic.yamlcovers all supported variable sources, defaults, dependent variables, shell overrides and long previews.examples/kubernetes.yamlcontains interactive Kubernetes workflows and demonstrates aliases represented as searchable labels.examples/java.yamlcontains Java, Maven, Gradle and Spring Boot development workflows.
Run a collection with:
cmdpeek --config examples/basic.yaml
cmdpeek --config examples/kubernetes.yaml
cmdpeek --config examples/java.yamlcmdpeek runs commands locally with the current user's environment and permissions. It does not sandbox commands or restrict filesystem, network or process access.
Variable values are inserted directly into shell command templates. Configuration files should therefore be treated as executable code.
Before confirming execution:
- review the rendered command;
- do not use untrusted configuration files;
- pay special attention to destructive commands;
- remember that values may remain visible in terminal scrollback, recordings or screenshots.
go test ./...
go build -o cmdpeek ./cmd/cmdpeekProject structure:
cmd/cmdpeek CLI entry point
internal/catalog YAML loading and validation
internal/configsource Local and GitHub configuration resolution and caching
internal/template Variable rendering and previews
internal/variable Dynamic command option resolution
internal/tui Catalog, variable and confirmation interfaces
internal/executor Shell execution
internal/noninteractive Non-interactive command and variable resolution
examples Example command catalogs
Potential improvements include:
- shell-safe variable quoting;
- optional and secret variables;
- stronger confirmation for destructive commands;
- global and project-local configuration merging;
- standalone configuration validation;
- command history and favorites;
- richer release automation and additional package-manager support.
Contributions are welcome. See CONTRIBUTING.md, CODE_OF_CONDUCT.md and SECURITY.md.
Licensed under the MIT License.