feat: add multilingual support so Naomi can use Python too

This commit is contained in:
2026-01-23 15:32:02 -08:00
parent 38e7f15d93
commit c0ad74367a
52 changed files with 1305 additions and 46 deletions
Executable
+194
View File
@@ -0,0 +1,194 @@
#!/bin/bash
# Colors and formatting
PINK='\033[38;5;213m'
BLUE='\033[38;5;117m'
GREEN='\033[38;5;156m'
YELLOW='\033[38;5;229m'
CYAN='\033[38;5;123m'
WHITE='\033[1;37m'
DIM='\033[2m'
BOLD='\033[1m'
RESET='\033[0m'
# Box drawing characters
TOP_LEFT='╭'
TOP_RIGHT='╮'
BOTTOM_LEFT='╰'
BOTTOM_RIGHT='╯'
HORIZONTAL='─'
VERTICAL='│'
ARROW=''
SPARKLE='✨'
STAR='★'
# Clear screen and show header
clear
echo -e "${PINK}${BOLD} ${TOP_LEFT}────────────────────────────────────${TOP_RIGHT}"
echo -e " ${VERTICAL} ${SPARKLE} ${WHITE}Ephemere Script Runner${PINK} ${SPARKLE} ${VERTICAL}"
echo -e " ${BOTTOM_LEFT}────────────────────────────────────${BOTTOM_RIGHT}${RESET}"
# Function to display a menu and get selection
select_option() {
local prompt="$1"
shift
local options=("$@")
local selected=0
local key
# Hide cursor
tput civis
# Trap to restore cursor on exit
trap 'tput cnorm' EXIT
while true; do
# Clear previous menu (move up and clear lines)
if [ -n "$menu_drawn" ]; then
for ((i=0; i<=${#options[@]}+1; i++)); do
tput cuu1
tput el
done
fi
menu_drawn=1
# Print prompt
echo -e "${CYAN}${BOLD} $prompt${RESET}"
echo ""
# Print options
for i in "${!options[@]}"; do
if [ $i -eq $selected ]; then
echo -e " ${PINK}${BOLD}$ARROW ${WHITE}${options[$i]}${RESET}"
else
echo -e " ${DIM}${options[$i]}${RESET}"
fi
done
# Read a single keypress
read -rsn1 key
# Handle arrow keys (they come as escape sequences)
if [[ $key == $'\x1b' ]]; then
read -rsn2 key
case $key in
'[A') # Up arrow
((selected--))
[ $selected -lt 0 ] && selected=$((${#options[@]}-1))
;;
'[B') # Down arrow
((selected++))
[ $selected -ge ${#options[@]} ] && selected=0
;;
esac
elif [[ $key == "" ]]; then
# Enter pressed
tput cnorm # Show cursor
unset menu_drawn
return $selected
elif [[ $key == "q" || $key == "Q" ]]; then
tput cnorm
echo -e "\n${YELLOW} Bye bye! $SPARKLE${RESET}\n"
exit 0
fi
done
}
# Step 1: Select Language
echo ""
languages=("TypeScript" "Python")
select_option "Select a language:" "${languages[@]}"
lang_index=$?
language="${languages[$lang_index]}"
echo -e "\n ${GREEN}$STAR Selected: ${WHITE}$language${RESET}\n"
# Step 2: Get categories based on language
if [ "$language" == "TypeScript" ]; then
script_dir="typescript/src"
runner="pnpm tsx"
# Get subdirectories as categories (excluding utils and interfaces)
mapfile -t categories < <(find "$script_dir" -mindepth 1 -maxdepth 1 -type d ! -name 'utils' ! -name 'interfaces' -exec basename {} \; | sort)
else
script_dir="python"
runner="uv run python"
# Get subdirectories as categories (excluding __pycache__ and .venv)
mapfile -t categories < <(find "$script_dir" -mindepth 1 -maxdepth 1 -type d ! -name '__pycache__' ! -name '.venv' ! -name '*.egg-info' -exec basename {} \; | sort)
# Add "Root Scripts" option for Python files in root
if ls "$script_dir"/*.py &>/dev/null 2>&1; then
categories=("Root Scripts" "${categories[@]}")
fi
fi
if [ ${#categories[@]} -eq 0 ]; then
echo -e " ${YELLOW}No script categories found!${RESET}\n"
exit 1
fi
select_option "Select a category:" "${categories[@]}"
cat_index=$?
category="${categories[$cat_index]}"
echo -e "\n ${GREEN}$STAR Selected: ${WHITE}$category${RESET}\n"
# Step 3: Get scripts in category
if [ "$category" == "Root Scripts" ]; then
search_dir="$script_dir"
mapfile -t scripts < <(find "$search_dir" -maxdepth 1 -name "*.py" -exec basename {} \; | sort)
elif [ "$language" == "TypeScript" ]; then
search_dir="$script_dir/$category"
mapfile -t scripts < <(find "$search_dir" -name "*.ts" -exec basename {} \; | sort)
else
search_dir="$script_dir/$category"
mapfile -t scripts < <(find "$search_dir" -name "*.py" ! -name "__init__.py" -exec basename {} \; | sort)
fi
if [ ${#scripts[@]} -eq 0 ]; then
echo -e " ${YELLOW}No scripts found in this category!${RESET}\n"
exit 1
fi
select_option "Select a script:" "${scripts[@]}"
script_index=$?
script="${scripts[$script_index]}"
echo -e "\n ${GREEN}$STAR Selected: ${WHITE}$script${RESET}\n"
# Build the full script path
if [ "$category" == "Root Scripts" ]; then
script_path="$script"
elif [ "$language" == "TypeScript" ]; then
script_path="src/$category/$script"
else
script_path="$category/$script"
fi
# Show what we're about to run
echo -e "${BLUE}${BOLD} ${TOP_LEFT}───────────────────────${TOP_RIGHT}"
echo -e " ${VERTICAL} ${WHITE}Running script...${BLUE} ${VERTICAL}"
echo -e " ${BOTTOM_LEFT}───────────────────────${BOTTOM_RIGHT}${RESET}"
echo ""
echo -e " ${DIM}Language:${RESET} $language"
echo -e " ${DIM}Category:${RESET} $category"
echo -e " ${DIM}Script:${RESET} $script"
echo ""
# Run the script with 1Password env injection
if [ "$language" == "TypeScript" ]; then
cd typescript
echo -e " ${DIM}$ op run --env-file=../prod.env -- $runner $script_path${RESET}\n"
op run --env-file=../prod.env --no-masking -- $runner "$script_path"
else
cd python
echo -e " ${DIM}$ op run --env-file=../prod.env -- $runner $script_path${RESET}\n"
op run --env-file=../prod.env --no-masking -- $runner "$script_path"
fi
exit_code=$?
echo ""
if [ $exit_code -eq 0 ]; then
echo -e " ${GREEN}${BOLD}$SPARKLE Script completed successfully! $SPARKLE${RESET}\n"
else
echo -e " ${YELLOW}${BOLD}Script exited with code $exit_code${RESET}\n"
fi