interactive-menu-builder
Included with Lifetime
$97 forever
Build multi-level interactive CLI menus for bash scripts
bashbashmenucliinteractivetuinavigation
What this skill does
# Interactive Menu Builder
Patterns for building professional multi-level interactive menus in bash scripts. Extracted from workspace-hub's workspace CLI and repository_sync tools.
## When to Use This Skill
✅ **Use when:**
- Building user-friendly CLI tools
- Need navigation through multiple options
- Complex tools with many sub-commands
- Tools used by humans (not just automation)
- Consolidating multiple scripts into one interface
❌ **Avoid when:**
- Scripts meant for automation/CI
- Simple single-purpose scripts
- When a plain command-line interface is sufficient
## Core Capabilities
### 1. Basic Menu Structure
Single-level menu with numbered options:
```bash
#!/bin/bash
# ABOUTME: Basic interactive menu pattern
# ABOUTME: Simple numbered option selection
# Colors
CYAN='\033[0;36m'
GREEN='\033[0;32m'
RED='\033[0;31m'
NC='\033[0m'
show_menu() {
clear
echo -e "${CYAN}═══════════════════════════════════════${NC}"
echo -e "${CYAN} Main Menu${NC}"
echo -e "${CYAN}═══════════════════════════════════════${NC}"
echo ""
echo " 1) Option One"
echo " 2) Option Two"
echo " 3) Option Three"
echo ""
echo " 0) Exit"
echo ""
echo -e "${CYAN}═══════════════════════════════════════${NC}"
echo ""
}
handle_choice() {
local choice="$1"
case "$choice" in
1)
echo "Running Option One..."
# Implementation
;;
2)
echo "Running Option Two..."
# Implementation
;;
3)
echo "Running Option Three..."
# Implementation
;;
0)
echo "Goodbye!"
exit 0
;;
*)
echo -e "${RED}Invalid option${NC}"
;;
esac
}
# Main loop
while true; do
show_menu
read -p "Select option: " choice
handle_choice "$choice"
echo ""
read -p "Press Enter to continue..."
done
```
### 2. Multi-Level Menu System
Hierarchical menu with breadcrumb navigation:
```bash
#!/bin/bash
# ABOUTME: Multi-level menu system with navigation stack
# ABOUTME: Pattern from workspace-hub workspace CLI
# Navigation stack
declare -a MENU_STACK=("main")
CURRENT_MENU="main"
# Menu definitions
declare -A MENU_TITLES=(
["main"]="Main Menu"
["repo"]="Repository Management"
["repo_ops"]="Repository Operations"
["compliance"]="Compliance & Standards"
["tools"]="Development Tools"
)
# Go to submenu
push_menu() {
local menu="$1"
MENU_STACK+=("$menu")
CURRENT_MENU="$menu"
}
# Go back
pop_menu() {
if [[ ${#MENU_STACK[@]} -gt 1 ]]; then
unset 'MENU_STACK[-1]'
CURRENT_MENU="${MENU_STACK[-1]}"
fi
}
# Display breadcrumb
show_breadcrumb() {
local crumb=""
for menu in "${MENU_STACK[@]}"; do
[[ -n "$crumb" ]] && crumb+=" > "
crumb+="${MENU_TITLES[$menu]}"
done
echo -e "${CYAN}$crumb${NC}"
}
# Main menu
show_main_menu() {
clear
echo -e "${CYAN}═══════════════════════════════════════════════════════${NC}"
echo -e "${CYAN} Workspace Hub - Management Console${NC}"
echo -e "${CYAN}═══════════════════════════════════════════════════════${NC}"
echo ""
show_breadcrumb
echo ""
echo " 1) Repository Management"
echo " 2) Compliance & Standards"
echo " 3) Development Tools"
echo " 4) System Configuration"
echo " 5) Help & Documentation"
echo ""
echo " 0) Exit"
echo ""
}
# Repository submenu
show_repo_menu() {
clear
echo -e "${CYAN}═══════════════════════════════════════════════════════${NC}"
show_breadcrumb
echo -e "${CYAN}═══════════════════════════════════════════════════════${NC}"
echo ""
echo " 1) Repository Sync Manager"
echo " 2) Configure Repository URLs"
echo " 3) Check All Repository Status"
echo " 4) Clone Repositories"
echo ""
echo " 0) Back"
echo ""
}
# Handle navigation
handle_menu() {
local choice="$1"
case "$CURRENT_MENU" in
main)
case "$choice" in
1) push_menu "repo" ;;
2) push_menu "compliance" ;;
3) push_menu "tools" ;;
4) run_system_config ;;
5) run_help ;;
0) exit 0 ;;
esac
;;
repo)
case "$choice" in
1) run_repo_sync ;;
2) run_configure_urls ;;
3) run_check_status ;;
4) push_menu "repo_ops" ;;
0) pop_menu ;;
esac
;;
# Add more menus...
esac
}
# Display current menu
show_current_menu() {
case "$CURRENT_MENU" in
main) show_main_menu ;;
repo) show_repo_menu ;;
# Add more...
esac
}
# Main loop
while true; do
show_current_menu
read -p "Select option: " choice
handle_menu "$choice"
done
```
### 3. Table Display
Display data in formatted tables:
```bash
#!/bin/bash
# ABOUTME: Table display functions for CLI menus
# ABOUTME: Format data in aligned columns with headers
# Print table header
print_table_header() {
local -a headers=("$@")
local format=""
# Build format string
for header in "${headers[@]}"; do
format+="%-20s "
done
echo ""
printf "${CYAN}${format}${NC}\n" "${headers[@]}"
printf "${CYAN}%s${NC}\n" "$(printf '─%.0s' {1..80})"
}
# Print table row
print_table_row() {
local format=""
local -a values=("$@")
for _ in "${values[@]}"; do
format+="%-20s "
done
printf "${format}\n" "${values[@]}"
}
# Display repository table
show_repo_table() {
print_table_header "Repository" "Category" "Status" "Branch"
for repo in "${REPOS[@]}"; do
local category=$(get_category "$repo")
local status=$(get_status "$repo")
local branch=$(get_branch "$repo")
# Color-code status
case "$status" in
"Clean") status="${GREEN}Clean${NC}" ;;
"Modified") status="${YELLOW}Modified${NC}" ;;
"Untracked") status="${RED}Untracked${NC}" ;;
esac
print_table_row "$repo" "$category" "$status" "$branch"
done
}
```
### 4. Selection Lists
Let users select from a list:
```bash
#!/bin/bash
# ABOUTME: Selection list patterns
# ABOUTME: Single and multi-select from numbered lists
# Single selection
select_single() {
local prompt="$1"
shift
local -a options=("$@")
echo ""
for i in "${!options[@]}"; do
echo " $((i+1))) ${options[$i]}"
done
echo ""
echo " 0) Cancel"
echo ""
read -p "$prompt: " choice
if [[ "$choice" == "0" ]]; then
return 1
elif [[ "$choice" -ge 1 && "$choice" -le ${#options[@]} ]]; then
SELECTED="${options[$((choice-1))]}"
return 0
else
echo -e "${RED}Invalid selection${NC}"
return 1
fi
}
# Multi-selection
select_multiple() {
local prompt="$1"
shift
local -a options=("$@")
local -a selected=()
echo ""
echo "Enter numbers separated by spaces (or 'all' for all):"
echo ""
for i in "${!options[@]}"; do
echo " $((i+1))) ${options[$i]}"
done
echo ""
read -p "$prompt: " input
if [[ "$input" == "all" ]]; then
SELECTED=("${options[@]}")
return 0
fi
for num in $input; do
if [[ "$num" -ge 1 && "$num" -le ${#options[@]} ]]; then
selected+=("${options[$((num-1))]}")
fi
done
SELECTED=("${selected[@]}")
[[ ${#SELECTED[@]} -gt 0 ]]
}
# Usage
repos=("repo1" "repo2" "repo3" "repo4")
if select_single "Select repository" "${repos[@]}"; then
echo "You selected: $SELECTED"
fi
if select_multiple "Select repositories" "${repos[@]}"; then
echo "You selected: ${SELECTED[*]}"
fi
```
### 5. Confirmation Dialogs
Request user confirmation:
```bash
#!/bin/bash
# ABOUTME: Confirmation dialog patterns
# ABOUTMRelated in bash
json-config-loader
IncludedConfiguration file parsing patterns for bash scripts (INI, key=value, JSON)
bash
git-sync-manager
IncludedMulti-repository git synchronization patterns for batch operations
bash
complexity-scorer
IncludedScore task complexity using keyword matching and heuristics
bash
state-directory-manager
IncludedManage persistent state directories for bash scripts
bash
usage-tracker
IncludedTrack and analyze usage metrics with timestamped logging
bash
parallel-batch-executor
IncludedParallel task execution patterns for 300% performance gains
bash