Standardmäßig ist der Prompt ausgewählt, der zuerst die Quelle prüft. Sie können zu einem direkten Befehl wechseln oder eine lokale Kopie herunterladen.
Quelldateien prüfen
Lesen Sie SKILL.md und alle von SkillsMP angezeigten Begleitdateien, bevor Sie sich für eine Installation entscheiden.
Mit Codex oder Claude installieren Kopieren Sie diesen Prompt, fügen Sie ihn in Codex, Claude oder einen anderen Assistant ein und lassen Sie die Skill-Seite prüfen und installieren.
Ein direkter Befehl überspringt den Prüf-Prompt. Prüfen Sie die Quelle, bevor Sie ihn ausführen.
#!/bin/bash# lib/menu.sh - Menu system utilities# Source after colors.sh# Display menu and get selectionshow_menu() {
local title="$1"shiftlocal options=("$@")
print_header "$title"local i=1
for option in"${options[@]}"; doif [[ "$option" == "---" ]]; then
print_separator 40
elseprintf" ${CYAN}%2d)${NC} %s\n""$i""$option"
((i++))
fidoneecho""printf" ${CYAN} 0)${NC}${DIM}Exit / Back${NC}\n"echo""read -p "$(echo -e ${BOLD}Select option: ${NC})" choice
echo"$choice"
}
# Confirm actionconfirm() {
local message="${1:-Are you sure?}"local default="${2:-n}"if [[ "$default" == "y" ]]; thenread -p "$(echo -e ${YELLOW}$message [Y/n]: ${NC})" response
response=${response:-y}elseread -p "$(echo -e ${YELLOW}$message [y/N]: ${NC})" response
response=${response:-n}fi
[[ "$response" =~ ^[Yy]$ ]]
}
# Prompt for inputprompt_input() {
local message="$1"local default="${2:-}"local result
if [[ -n "$default" ]]; thenread -p "$(echo -e ${CYAN}$message [$default]: ${NC})" result
result=${result:-$default}elseread -p "$(echo -e ${CYAN}$message: ${NC})" result
fiecho"$result"
}
# Select from listselect_from_list() {
local title="$1"shiftlocal items=("$@")
echo -e "\n${BOLD}$title${NC}\n"local i=1
for item in"${items[@]}"; doprintf" ${CYAN}%2d)${NC} %s\n""$i""$item"
((i++))
doneecho""read -p "$(echo -e ${BOLD}Select [1-${#items[@]}]: ${NC})" choice
if [[ "$choice" =~ ^[0-9]+$ ]] && [[ "$choice" -ge 1 ]] && [[ "$choice" -le ${#items[@]} ]]; thenecho"${items[$((choice-1))]}"elseecho""fi
}
# Multi-select from listmulti_select() {
local title="$1"shiftlocal items=("$@")
local selected=()
echo -e "\n${BOLD}$title${NC}"echo -e "${DIM}(Enter numbers separated by spaces, or 'all')${NC}\n"local i=1
for item in"${items[@]}"; doprintf" ${CYAN}%2d)${NC} %s\n""$i""$item"
((i++))
doneecho""read -p "$(echo -e ${BOLD}Select: ${NC})" choices
if [[ "$choices" == "all" ]]; then
selected=("${items[@]}")
elsefor choice in$choices; doif [[ "$choice" =~ ^[0-9]+$ ]] && [[ "$choice" -ge 1 ]] && [[ "$choice" -le ${#items[@]} ]]; then
selected+=("${items[$((choice-1))]}")
fidonefiprintf'%s\n'"${selected[@]}"
}
# Wait for keypresswait_for_key() {
local message="${1:-Press any key to continue...}"echo -e "\n${DIM}$message${NC}"read -n 1 -s
}
# Clear screen with headerclear_with_header() {
local title="${1:-Menu}"
clear
print_header "$title" 60
}
4. Utilities (lib/utils.sh)
#!/bin/bash# lib/utils.sh - General utilities# Check if command existscommand_exists() {
command -v "$1" &> /dev/null
}
# Check required commandsrequire_commands() {
local missing=()
for cmd in"$@"; doif ! command_exists "$cmd"; then
missing+=("$cmd")
fidoneif [[ ${#missing[@]} -gt 0 ]]; then
log_error "Missing required commands: ${missing[*]}"return 1
fireturn 0
}
# Get script directoryget_script_dir() {
echo"$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
}
# Get project rootget_project_root() {
localdir="$(get_script_dir)"while [[ "$dir" != "/" ]]; doif [[ -f "$dir/pyproject.toml" ]] || [[ -f "$dir/CLAUDE.md" ]]; thenecho"$dir"return 0
fidir="$(dirname "$dir")"doneecho"$(pwd)"
}
# Run command with error handlingrun_cmd() {
local cmd="$*"
log_debug "Running: $cmd"ifeval"$cmd"; thenreturn 0
elselocal exit_code=$?
log_error "Command failed (exit code $exit_code): $cmd"return$exit_codefi
}
# Retry commandretry() {
local max_attempts="${1:-3}"local delay="${2:-5}"shift 2
local cmd="$*"local attempt=1
while [[ $attempt -le $max_attempts ]]; do
log_info "Attempt $attempt/$max_attempts: $cmd"ifeval"$cmd"; thenreturn 0
fiif [[ $attempt -lt $max_attempts ]]; then
log_warn "Retrying in ${delay}s..."sleep"$delay"fi
((attempt++))
done
log_error "All $max_attempts attempts failed"return 1
}
# Check if running as rootis_root() {
[[ $EUID -eq 0 ]]
}
# Check OS typeget_os() {
case"$(uname -s)"in
Linux*) echo"linux" ;;
Darwin*) echo"macos" ;;
CYGWIN*|MINGW*|MSYS*) echo"windows" ;;
*) echo"unknown" ;;
esac
}
# Check if in git repositoryis_git_repo() {
git rev-parse --is-inside-work-tree &> /dev/null
}
# Get current git branchget_git_branch() {
git rev-parse --abbrev-ref HEAD 2>/dev/null
}
# Cleanup handlercleanup() {
local exit_code=$?
# Add cleanup tasks hereexit$exit_code
}
# Setup signal handlerssetup_cleanup() {
trap cleanup EXIT INT TERM
}
# Parse argumentsparse_args() {
while [[ $# -gt 0 ]]; docase"$1"in
-v|--verbose) VERBOSE=true ;;
-q|--quiet) QUIET=true ;;
-h|--help) show_help; exit 0 ;;
--) shift; break ;;
-*) log_error "Unknown option: $1"; exit 1 ;;
*) ARGS+=("$1") ;;
esacshiftdone
}
# File operationsbackup_file() {
local file="$1"if [[ -f "$file" ]]; thenlocal backup="${file}.bak.$(date +%Y%m%d%H%M%S)"cp"$file""$backup"
log_info "Backed up: $file -> $backup"fi
}
# Ensure directory existsensure_dir() {
localdir="$1"if [[ ! -d "$dir" ]]; thenmkdir -p "$dir"
log_debug "Created directory: $dir"fi
}
5. Main Script Template
#!/bin/bash# scripts/my-tool - Main entry point# Description: Tool description hereset -e # Exit on error# Get script directory and load libraries
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"source"${SCRIPT_DIR}/lib/colors.sh"source"${SCRIPT_DIR}/lib/logging.sh"source"${SCRIPT_DIR}/lib/menu.sh"source"${SCRIPT_DIR}/lib/utils.sh"# Configuration
VERSION="1.0.0"
TOOL_NAME="My Tool"# Show helpshow_help() {
cat << EOF
${BOLD}${TOOL_NAME}${NC} v${VERSION}
${BOLD}Usage:${NC}
$0 [options] [command]
${BOLD}Commands:${NC}
menu Show interactive menu (default)
status Show status
run Run operation
help Show this help
${BOLD}Options:${NC}
-v, --verbose Enable verbose output
-q, --quiet Suppress output
-h, --help Show this help
${BOLD}Examples:${NC}
$0 # Interactive menu
$0 status # Show status
$0 run --verbose # Run with verbose output
EOF
}
# Show versionshow_version() {
echo"${TOOL_NAME} v${VERSION}"
}
# Status commandcmd_status() {
print_header "Status"
print_info "Version: ${VERSION}"
print_info "OS: $(get_os)"
print_info "User: $(whoami)"if is_git_repo; then
print_success "Git repository: $(get_git_branch)"else
print_warning "Not a git repository"fi
}
# Run commandcmd_run() {
print_header "Running Operation"
log_info "Starting operation..."# Add operation logic here
print_success "Operation completed"
}
# Main menumain_menu() {
whiletrue; do
clear_with_header "$TOOL_NAME"
choice=$(show_menu "Main Menu" \
"View Status" \
"Run Operation" \
"Settings" \
"---" \
"Help"
)
case"$choice"in
1) cmd_status; wait_for_key ;;
2) cmd_run; wait_for_key ;;
3) settings_menu ;;
4) show_help; wait_for_key ;;
0|"") break ;;
*) print_error "Invalid option"; sleep 1 ;;
esacdone
}
# Settings submenusettings_menu() {
whiletrue; do
choice=$(show_menu "Settings" \
"Set Log Level" \
"Enable File Logging" \
"View Configuration"
)
case"$choice"in
1)
level=$(select_from_list "Log Level""debug""info""warn""error")
[[ -n "$level" ]] && set_log_level "$level"
;;
2) enable_file_logging "logs/tool.log" ;;
3) print_info "Config: verbose=$VERBOSE" ;;
0|"") break ;;
esacdone
}
# Main entry pointmain() {
# Parse global optionswhile [[ $# -gt 0 ]]; docase"$1"in
-v|--verbose) set_log_level debug ;;
-q|--quiet) set_log_level error ;;
-h|--help) show_help; exit 0 ;;
--version) show_version; exit 0 ;;
-*) log_error "Unknown option: $1"; exit 1 ;;
*) break ;;
esacshiftdone# Handle commandslocal cmd="${1:-menu}"case"$cmd"in
menu) main_menu ;;
status) cmd_status ;;
run) shift; cmd_run "$@" ;;
help) show_help ;;
*) log_error "Unknown command: $cmd"; show_help; exit 1 ;;
esac
}
# Run main
main "$@"
Usage Examples
Example 1: Create New CLI Tool
# Initialize framework
/bash-script-framework init
# Create tool with menu
/bash-script-framework new repo-manager --menu
# Result: scripts/repo-manager with full menu system