mirror of
https://github.com/openswarm-ai/openswarm.git
synced 2026-08-17 18:25:42 +02:00
[Haik]: ckpt (Removed utils.sh) (Simplified run scripts) (Added global run.sh in the root) (Start sort is enabled by default when u open the mcp registry in the tools page) (Reload issue when your in a specific dashboard is now fixed)
This commit is contained in:
@@ -41,7 +41,7 @@ Frontend (React/TypeScript :3000) Backend (FastAPI/Python :8324)
|
||||
### Backend
|
||||
|
||||
```bash
|
||||
bash backend/run/dev.sh
|
||||
bash backend/run.sh
|
||||
# API runs at http://localhost:8324
|
||||
# Docs at http://localhost:8324/docs
|
||||
```
|
||||
@@ -49,7 +49,7 @@ bash backend/run/dev.sh
|
||||
### Frontend
|
||||
|
||||
```bash
|
||||
bash frontend/run/dev.sh
|
||||
bash frontend/run.sh
|
||||
# App runs at http://localhost:3000
|
||||
```
|
||||
|
||||
|
||||
@@ -13,14 +13,13 @@ else
|
||||
# echo "NOT in macOS server START"
|
||||
fi
|
||||
chmod +x "$DEV_ABSPATH"
|
||||
source "$(dirname "$DEV_ABSPATH")/_utils.sh"
|
||||
|
||||
|
||||
PROJECT_ROOT_ABSPATH="$(dirname "$BACKEND_DIR_ABSPATH")"
|
||||
PROJECT_ROOT_ABSPATH="$(dirname "$(dirname "$DEV_ABSPATH")")"
|
||||
BACKEND_DIR_ABSPATH="$PROJECT_ROOT_ABSPATH/backend"
|
||||
|
||||
# Cleanup function on exit
|
||||
cleanup() {
|
||||
formatted_echo --yellow "Shutting down..."
|
||||
echo "Shutting down..."
|
||||
cd - > /dev/null 2>&1
|
||||
}
|
||||
trap cleanup EXIT INT TERM
|
||||
@@ -28,34 +27,34 @@ trap cleanup EXIT INT TERM
|
||||
# --- Create virtual environment if it doesn't exist ---
|
||||
VENV_DIR="$BACKEND_DIR_ABSPATH/.venv"
|
||||
if [[ ! -d "$VENV_DIR" ]]; then
|
||||
formatted_echo --green "Creating virtual environment..."
|
||||
echo "Creating virtual environment..."
|
||||
python -m venv "$VENV_DIR"
|
||||
fi
|
||||
source "$VENV_DIR/bin/activate"
|
||||
|
||||
# --- Install custom debugger module if not already installed ---
|
||||
DEBUGGER_DIR_ABSPATH="$PROJECT_ROOT_ABSPATH/debugger"
|
||||
if ! pip show debug > /dev/null 2>&1; then
|
||||
formatted_echo --green "Installing debugger module..."
|
||||
if ! pip3 show debug > /dev/null 2>&1; then
|
||||
echo "Installing debugger module..."
|
||||
cd "$DEBUGGER_DIR_ABSPATH"
|
||||
pip install -e .
|
||||
pip3 install -e .
|
||||
if [[ $? -ne 0 ]]; then
|
||||
formatted_error "Failed to install debugger module."
|
||||
echo "Failed to install debugger module."
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
# --- Install Python dependencies ---
|
||||
formatted_echo --green "Installing dependencies..."
|
||||
echo "Installing dependencies..."
|
||||
cd "$BACKEND_DIR_ABSPATH"
|
||||
pip install -r requirements.txt
|
||||
pip3 install -r requirements.txt
|
||||
if [[ $? -ne 0 ]]; then
|
||||
formatted_error "Failed to install Python dependencies."
|
||||
echo "Failed to install Python dependencies."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# --- Start the backend server ---
|
||||
formatted_echo --green "Starting backend server on http://0.0.0.0:8324 ..."
|
||||
echo "Starting backend server on http://0.0.0.0:8324 ..."
|
||||
cd "$PROJECT_ROOT_ABSPATH"
|
||||
python -m uvicorn backend.main:app --host 0.0.0.0 --port 8324 --reload \
|
||||
--reload-dir "$BACKEND_DIR_ABSPATH" \
|
||||
@@ -1,202 +0,0 @@
|
||||
#!/bin/bash
|
||||
# Flag processing function with namespacing and global variable declaration
|
||||
UTILS_FILE_ABSPATH="$(readlink -f "${BASH_SOURCE[0]}")"
|
||||
if [[ "$OSTYPE" == "darwin"* ]]; then
|
||||
# echo "In macOS utils sed START"
|
||||
# echo "UTILS_ABSPATH: $UTILS_FILE_ABSPATH"
|
||||
sed -i '' 's/\r//g' "$UTILS_FILE_ABSPATH"
|
||||
# echo "In macOS utils sed END"
|
||||
else
|
||||
# echo "NOT in macOS utils START"
|
||||
# echo "UTILS_ABSPATH: $UTILS_FILE_ABSPATH"
|
||||
sed -i 's/\r//g' "$UTILS_FILE_ABSPATH"
|
||||
# echo "NOT in macOS utils END"
|
||||
fi
|
||||
chmod +x "$UTILS_FILE_ABSPATH"
|
||||
|
||||
RUN_DIR_ABSPATH="$(dirname "$UTILS_FILE_ABSPATH")"
|
||||
BACKEND_DIR_ABSPATH="$(dirname "$RUN_DIR_ABSPATH")"
|
||||
|
||||
formatted_error() {
|
||||
# Arguments: error message and array of conflicting flags
|
||||
local initial_message="$1"
|
||||
shift
|
||||
local conflicting_flags=("$@")
|
||||
|
||||
# Red color for the error message box
|
||||
local COLOR_CODE='\033[0;31m'
|
||||
local NC='\033[0m' # No Color
|
||||
|
||||
# Start the error message with the initial message
|
||||
local error_message="$initial_message"
|
||||
|
||||
# Add each conflicting flag on a new line with indentation
|
||||
for conflict in "${conflicting_flags[@]}"; do
|
||||
error_message+="\n $conflict" # Replacing `\t` with four spaces
|
||||
done
|
||||
|
||||
# Prepare for printing by finding max length of each line in the message
|
||||
local lines=()
|
||||
local max_length=0
|
||||
|
||||
# Use printf to interpret new lines and calculate max length with spaces instead of tabs
|
||||
while IFS= read -r line; do
|
||||
# Substitute tabs with spaces for consistent width measurement
|
||||
local line_with_spaces="${line//$'\t'/ }"
|
||||
lines+=("$line_with_spaces")
|
||||
if (( ${#line_with_spaces} > max_length )); then
|
||||
max_length=${#line_with_spaces}
|
||||
fi
|
||||
done <<< "$(printf "$error_message")"
|
||||
|
||||
# Create the top and bottom borders based on the maximum line length
|
||||
local border=$(printf '%*s' "$((max_length + 4))" '' | tr ' ' '-')
|
||||
|
||||
# Print the formatted error message with a red box
|
||||
printf "\n${COLOR_CODE}%s${NC}\n" "$border"
|
||||
for line in "${lines[@]}"; do
|
||||
printf "${COLOR_CODE}| %-*s |${NC}\n" "$max_length" "$line"
|
||||
done
|
||||
printf "${COLOR_CODE}| %-*s |${NC}\n" "$max_length" ""
|
||||
printf "${COLOR_CODE}%s${NC}\n" "$border"
|
||||
}
|
||||
|
||||
|
||||
function process_flags() {
|
||||
local -n flags_to_commands="$1" # Reference to the dictionary of flags and commands
|
||||
local -n exclusives="$2" # Reference to the list of exclusive flag groups
|
||||
local namespace="$3" # Unique prefix for variables
|
||||
local calling_script_name="$(basename "$(readlink -f "${BASH_SOURCE[1]}")")"
|
||||
local caller_id="${FUNCNAME[1]}"
|
||||
local should_exit=false
|
||||
if [ "$caller_id" == "main" ]; then
|
||||
caller_id="$calling_script_name"
|
||||
fi
|
||||
# echo "caller_id: $caller_id"
|
||||
# echo "Initializing flags with namespace: $namespace"
|
||||
|
||||
# Initialize flag variables with namespacing in the sourcing script context
|
||||
for flag in "${!flags_to_commands[@]}"; do
|
||||
# Convert flag to uppercase variable name and apply namespace, e.g., MYAPP_FLAG1
|
||||
local flag_var="${namespace}_${flag^^}" # Prefix and uppercase
|
||||
flag_var="${flag_var//-}" # Remove dashes
|
||||
eval "declare -g $flag_var=false" # Initialize as global false
|
||||
|
||||
# Diagnostic output for each initialized variable
|
||||
# echo "Initialized $flag_var as false"
|
||||
done
|
||||
|
||||
# echo "Parsing command line arguments: $@"
|
||||
|
||||
# Parse command line arguments and set flags
|
||||
local unsupported_flags=()
|
||||
# local potential_typos=()
|
||||
for arg in "$@"; do
|
||||
# echo "Processing argument: $arg"
|
||||
if [[ -n "${flags_to_commands[$arg]}" ]]; then
|
||||
# echo "Flag found: $arg"
|
||||
local flag_var="${namespace}_${arg^^}" # Prefix and uppercase
|
||||
flag_var="${flag_var//-}" # Remove dashes
|
||||
eval "declare -g $flag_var=true" # Set as global true
|
||||
# echo "Set $flag_var to true"
|
||||
# echo "Executing command for $arg: ${flags_to_commands[$arg]}"
|
||||
eval "${flags_to_commands[$arg]}"
|
||||
else
|
||||
if [[ "$arg" == "-"* ]]; then
|
||||
# echo "Flag not found: $arg"
|
||||
unsupported_flags+=("$arg")
|
||||
if [[ -n "${flags_to_commands[-$arg]}" ]]; then
|
||||
# echo "Potential typo: $arg"
|
||||
unsupported_flags+=("\t*Note: Potential typo detected.")
|
||||
unsupported_flags+=("\tDid you mean: -$arg")
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
done
|
||||
# Check exclusive flag groups for conflicts
|
||||
# echo "Checking exclusive flag groups"
|
||||
for group in "${exclusives[@]}"; do
|
||||
local count=0
|
||||
local conflicting_flags=()
|
||||
for flag in $group; do
|
||||
local flag_var="${namespace}_${flag^^}"
|
||||
flag_var="${flag_var//-}"
|
||||
if [[ "$(eval echo "\$$flag_var")" == "true" ]]; then
|
||||
conflicting_flags+=("$flag")
|
||||
# count=$((count + 1))
|
||||
# ec "$flag_var is true in exclusive group"
|
||||
fi
|
||||
done
|
||||
if (( ${#conflicting_flags[@]} > 1 )); then
|
||||
# echo "found conflicting flags"
|
||||
formatted_error "Error: $caller_id\n-----------------------------------------\nIncompatible flags:\nThe flags below cannot be used together\n-----------------------------------------\n" "${conflicting_flags[@]}"
|
||||
should_exit=true
|
||||
fi
|
||||
done
|
||||
# echo "should_exit: $should_exit"
|
||||
# echo "unsupported_flags: ${#unsupported_flags[@]}"
|
||||
if (( ${#unsupported_flags[@]} > 0 )); then
|
||||
# echo "found unsupported flags 2"
|
||||
formatted_error "Error: $caller_id\n-------------------------------------------------\nUnsupported flags:\nThe flags below are not supported by this script\n-------------------------------------------------\n" "${unsupported_flags[@]}"
|
||||
should_exit=true
|
||||
fi
|
||||
if [[ $should_exit == true ]]; then
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
|
||||
formatted_echo() {
|
||||
local COLOR_CODE='\033[0m' # No Color
|
||||
local NC='\033[0m' # No Color variable
|
||||
# local message="$2"
|
||||
# If the second argument is empty, then theres no color specified, so we use the first argument as the message
|
||||
if [[ -z "$2" ]]; then
|
||||
message="$1"
|
||||
else
|
||||
message="$2"
|
||||
fi
|
||||
|
||||
declare -A format_flags
|
||||
format_flags=(
|
||||
[--red]="COLOR_CODE='\033[0;31m'"
|
||||
[--green]="COLOR_CODE='\033[0;32m'"
|
||||
[--yellow]="COLOR_CODE='\033[0;33m'"
|
||||
[--blue]="COLOR_CODE='\033[0;34m'"
|
||||
[--purple]="COLOR_CODE='\033[0;35m'"
|
||||
[--cyan]="COLOR_CODE='\033[0;36m'"
|
||||
)
|
||||
exclusive_format_flags=(
|
||||
"--red --green --yellow --blue --purple --cyan"
|
||||
)
|
||||
|
||||
# Pass the arguments with the namespace "FORMAT"
|
||||
process_flags format_flags exclusive_format_flags "FORMAT" "$@"
|
||||
|
||||
# Process the message
|
||||
local text
|
||||
text=$(printf "%b" "$message")
|
||||
|
||||
# Expand any escaped characters in the input (e.g., \n)
|
||||
local lines=()
|
||||
local max_length=0
|
||||
|
||||
# Read the text line by line and find the maximum length
|
||||
while IFS= read -r line; do
|
||||
lines+=("$line")
|
||||
if (( ${#line} > max_length )); then
|
||||
max_length=${#line}
|
||||
fi
|
||||
done <<< "$text"
|
||||
|
||||
# Create the top and bottom borders based on the maximum line length
|
||||
local border=$(printf '%*s' "$((max_length + 4))" '' | tr ' ' '-')
|
||||
|
||||
# Print the formatted box with selected color
|
||||
printf "\n${COLOR_CODE}%s${NC}\n" "$border"
|
||||
for line in "${lines[@]}"; do
|
||||
printf "${COLOR_CODE}| %-*s |${NC}\n" "$max_length" "$line"
|
||||
done
|
||||
printf "${COLOR_CODE}%s${NC}\n" "$border"
|
||||
}
|
||||
@@ -13,14 +13,14 @@ else
|
||||
# echo "NOT in macOS server START"
|
||||
fi
|
||||
chmod +x "$DEV_ABSPATH"
|
||||
source "$(dirname "$DEV_ABSPATH")/_utils.sh"
|
||||
|
||||
FRONTEND_DIR_ABSPATH="$(dirname "$DEV_ABSPATH")"
|
||||
|
||||
formatted_echo --green "Installing dependencies..."
|
||||
echo "Installing dependencies..."
|
||||
cd "$FRONTEND_DIR_ABSPATH"
|
||||
npm install
|
||||
|
||||
formatted_echo --green "Building with development mode..."
|
||||
echo "Building with development mode..."
|
||||
npm run dev
|
||||
|
||||
# exit back to the dir that we were in before
|
||||
@@ -1,202 +0,0 @@
|
||||
#!/bin/bash
|
||||
# Flag processing function with namespacing and global variable declaration
|
||||
UTILS_FILE_ABSPATH="$(readlink -f "${BASH_SOURCE[0]}")"
|
||||
if [[ "$OSTYPE" == "darwin"* ]]; then
|
||||
# echo "In macOS utils sed START"
|
||||
# echo "UTILS_ABSPATH: $UTILS_FILE_ABSPATH"
|
||||
sed -i '' 's/\r//g' "$UTILS_FILE_ABSPATH"
|
||||
# echo "In macOS utils sed END"
|
||||
else
|
||||
# echo "NOT in macOS utils START"
|
||||
# echo "UTILS_ABSPATH: $UTILS_FILE_ABSPATH"
|
||||
sed -i 's/\r//g' "$UTILS_FILE_ABSPATH"
|
||||
# echo "NOT in macOS utils END"
|
||||
fi
|
||||
chmod +x "$UTILS_FILE_ABSPATH"
|
||||
|
||||
RUN_DIR_ABSPATH="$(dirname "$UTILS_FILE_ABSPATH")"
|
||||
FRONTEND_DIR_ABSPATH="$(dirname "$RUN_DIR_ABSPATH")"
|
||||
|
||||
formatted_error() {
|
||||
# Arguments: error message and array of conflicting flags
|
||||
local initial_message="$1"
|
||||
shift
|
||||
local conflicting_flags=("$@")
|
||||
|
||||
# Red color for the error message box
|
||||
local COLOR_CODE='\033[0;31m'
|
||||
local NC='\033[0m' # No Color
|
||||
|
||||
# Start the error message with the initial message
|
||||
local error_message="$initial_message"
|
||||
|
||||
# Add each conflicting flag on a new line with indentation
|
||||
for conflict in "${conflicting_flags[@]}"; do
|
||||
error_message+="\n $conflict" # Replacing `\t` with four spaces
|
||||
done
|
||||
|
||||
# Prepare for printing by finding max length of each line in the message
|
||||
local lines=()
|
||||
local max_length=0
|
||||
|
||||
# Use printf to interpret new lines and calculate max length with spaces instead of tabs
|
||||
while IFS= read -r line; do
|
||||
# Substitute tabs with spaces for consistent width measurement
|
||||
local line_with_spaces="${line//$'\t'/ }"
|
||||
lines+=("$line_with_spaces")
|
||||
if (( ${#line_with_spaces} > max_length )); then
|
||||
max_length=${#line_with_spaces}
|
||||
fi
|
||||
done <<< "$(printf "$error_message")"
|
||||
|
||||
# Create the top and bottom borders based on the maximum line length
|
||||
local border=$(printf '%*s' "$((max_length + 4))" '' | tr ' ' '-')
|
||||
|
||||
# Print the formatted error message with a red box
|
||||
printf "\n${COLOR_CODE}%s${NC}\n" "$border"
|
||||
for line in "${lines[@]}"; do
|
||||
printf "${COLOR_CODE}| %-*s |${NC}\n" "$max_length" "$line"
|
||||
done
|
||||
printf "${COLOR_CODE}| %-*s |${NC}\n" "$max_length" ""
|
||||
printf "${COLOR_CODE}%s${NC}\n" "$border"
|
||||
}
|
||||
|
||||
|
||||
function process_flags() {
|
||||
local -n flags_to_commands="$1" # Reference to the dictionary of flags and commands
|
||||
local -n exclusives="$2" # Reference to the list of exclusive flag groups
|
||||
local namespace="$3" # Unique prefix for variables
|
||||
local calling_script_name="$(basename "$(readlink -f "${BASH_SOURCE[1]}")")"
|
||||
local caller_id="${FUNCNAME[1]}"
|
||||
local should_exit=false
|
||||
if [ "$caller_id" == "main" ]; then
|
||||
caller_id="$calling_script_name"
|
||||
fi
|
||||
# echo "caller_id: $caller_id"
|
||||
# echo "Initializing flags with namespace: $namespace"
|
||||
|
||||
# Initialize flag variables with namespacing in the sourcing script context
|
||||
for flag in "${!flags_to_commands[@]}"; do
|
||||
# Convert flag to uppercase variable name and apply namespace, e.g., MYAPP_FLAG1
|
||||
local flag_var="${namespace}_${flag^^}" # Prefix and uppercase
|
||||
flag_var="${flag_var//-}" # Remove dashes
|
||||
eval "declare -g $flag_var=false" # Initialize as global false
|
||||
|
||||
# Diagnostic output for each initialized variable
|
||||
# echo "Initialized $flag_var as false"
|
||||
done
|
||||
|
||||
# echo "Parsing command line arguments: $@"
|
||||
|
||||
# Parse command line arguments and set flags
|
||||
local unsupported_flags=()
|
||||
# local potential_typos=()
|
||||
for arg in "$@"; do
|
||||
# echo "Processing argument: $arg"
|
||||
if [[ -n "${flags_to_commands[$arg]}" ]]; then
|
||||
# echo "Flag found: $arg"
|
||||
local flag_var="${namespace}_${arg^^}" # Prefix and uppercase
|
||||
flag_var="${flag_var//-}" # Remove dashes
|
||||
eval "declare -g $flag_var=true" # Set as global true
|
||||
# echo "Set $flag_var to true"
|
||||
# echo "Executing command for $arg: ${flags_to_commands[$arg]}"
|
||||
eval "${flags_to_commands[$arg]}"
|
||||
else
|
||||
if [[ "$arg" == "-"* ]]; then
|
||||
# echo "Flag not found: $arg"
|
||||
unsupported_flags+=("$arg")
|
||||
if [[ -n "${flags_to_commands[-$arg]}" ]]; then
|
||||
# echo "Potential typo: $arg"
|
||||
unsupported_flags+=("\t*Note: Potential typo detected.")
|
||||
unsupported_flags+=("\tDid you mean: -$arg")
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
done
|
||||
# Check exclusive flag groups for conflicts
|
||||
# echo "Checking exclusive flag groups"
|
||||
for group in "${exclusives[@]}"; do
|
||||
local count=0
|
||||
local conflicting_flags=()
|
||||
for flag in $group; do
|
||||
local flag_var="${namespace}_${flag^^}"
|
||||
flag_var="${flag_var//-}"
|
||||
if [[ "$(eval echo "\$$flag_var")" == "true" ]]; then
|
||||
conflicting_flags+=("$flag")
|
||||
# count=$((count + 1))
|
||||
# ec "$flag_var is true in exclusive group"
|
||||
fi
|
||||
done
|
||||
if (( ${#conflicting_flags[@]} > 1 )); then
|
||||
# echo "found conflicting flags"
|
||||
formatted_error "Error: $caller_id\n-----------------------------------------\nIncompatible flags:\nThe flags below cannot be used together\n-----------------------------------------\n" "${conflicting_flags[@]}"
|
||||
should_exit=true
|
||||
fi
|
||||
done
|
||||
# echo "should_exit: $should_exit"
|
||||
# echo "unsupported_flags: ${#unsupported_flags[@]}"
|
||||
if (( ${#unsupported_flags[@]} > 0 )); then
|
||||
# echo "found unsupported flags 2"
|
||||
formatted_error "Error: $caller_id\n-------------------------------------------------\nUnsupported flags:\nThe flags below are not supported by this script\n-------------------------------------------------\n" "${unsupported_flags[@]}"
|
||||
should_exit=true
|
||||
fi
|
||||
if [[ $should_exit == true ]]; then
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
|
||||
formatted_echo() {
|
||||
local COLOR_CODE='\033[0m' # No Color
|
||||
local NC='\033[0m' # No Color variable
|
||||
# local message="$2"
|
||||
# If the second argument is empty, then theres no color specified, so we use the first argument as the message
|
||||
if [[ -z "$2" ]]; then
|
||||
message="$1"
|
||||
else
|
||||
message="$2"
|
||||
fi
|
||||
|
||||
declare -A format_flags
|
||||
format_flags=(
|
||||
[--red]="COLOR_CODE='\033[0;31m'"
|
||||
[--green]="COLOR_CODE='\033[0;32m'"
|
||||
[--yellow]="COLOR_CODE='\033[0;33m'"
|
||||
[--blue]="COLOR_CODE='\033[0;34m'"
|
||||
[--purple]="COLOR_CODE='\033[0;35m'"
|
||||
[--cyan]="COLOR_CODE='\033[0;36m'"
|
||||
)
|
||||
exclusive_format_flags=(
|
||||
"--red --green --yellow --blue --purple --cyan"
|
||||
)
|
||||
|
||||
# Pass the arguments with the namespace "FORMAT"
|
||||
process_flags format_flags exclusive_format_flags "FORMAT" "$@"
|
||||
|
||||
# Process the message
|
||||
local text
|
||||
text=$(printf "%b" "$message")
|
||||
|
||||
# Expand any escaped characters in the input (e.g., \n)
|
||||
local lines=()
|
||||
local max_length=0
|
||||
|
||||
# Read the text line by line and find the maximum length
|
||||
while IFS= read -r line; do
|
||||
lines+=("$line")
|
||||
if (( ${#line} > max_length )); then
|
||||
max_length=${#line}
|
||||
fi
|
||||
done <<< "$text"
|
||||
|
||||
# Create the top and bottom borders based on the maximum line length
|
||||
local border=$(printf '%*s' "$((max_length + 4))" '' | tr ' ' '-')
|
||||
|
||||
# Print the formatted box with selected color
|
||||
printf "\n${COLOR_CODE}%s${NC}\n" "$border"
|
||||
for line in "${lines[@]}"; do
|
||||
printf "${COLOR_CODE}| %-*s |${NC}\n" "$max_length" "$line"
|
||||
done
|
||||
printf "${COLOR_CODE}%s${NC}\n" "$border"
|
||||
}
|
||||
@@ -398,7 +398,7 @@ const Tools: React.FC = () => {
|
||||
// Registry browser
|
||||
const [registryOpen, setRegistryOpen] = useState(false);
|
||||
const [regQuery, setRegQuery] = useState('');
|
||||
const [regSort, setRegSort] = useState<'name' | 'stars'>('name');
|
||||
const [regSort, setRegSort] = useState<'name' | 'stars'>('stars');
|
||||
const [regSource, setRegSource] = useState<'' | 'community' | 'google'>('');
|
||||
const [expandedServer, setExpandedServer] = useState<string | null>(null);
|
||||
const [snackbar, setSnackbar] = useState<{ open: boolean; message: string; severity?: 'success' | 'error' }>({ open: false, message: '' });
|
||||
@@ -609,11 +609,11 @@ const Tools: React.FC = () => {
|
||||
handleMenuClose();
|
||||
setRegistryOpen(true);
|
||||
setRegQuery('');
|
||||
setRegSort('name');
|
||||
setRegSort('stars');
|
||||
setRegSource('');
|
||||
setExpandedServer(null);
|
||||
dispatch(fetchRegistryStats());
|
||||
dispatch(searchRegistry({ q: '', limit: 20, offset: 0, sort: 'name', source: '' }));
|
||||
dispatch(searchRegistry({ q: '', limit: 20, offset: 0, sort: 'stars', source: '' }));
|
||||
};
|
||||
|
||||
// --------------- Tool CRUD ---------------
|
||||
|
||||
@@ -10,6 +10,7 @@ module.exports = (env, argv) => {
|
||||
output: {
|
||||
path: path.resolve(__dirname, 'dist'),
|
||||
filename: 'bundle.js',
|
||||
publicPath: '/',
|
||||
clean: true
|
||||
},
|
||||
|
||||
|
||||
@@ -0,0 +1,124 @@
|
||||
#!/bin/bash
|
||||
# The comment above is shebang, DO NOT REMOVE
|
||||
SCRIPT_ABSPATH="$(readlink -f "${BASH_SOURCE[0]}")"
|
||||
if [[ "$OSTYPE" == "darwin"* ]]; then
|
||||
sed -i '' 's/\r//g' "$SCRIPT_ABSPATH"
|
||||
else
|
||||
sed -i 's/\r//g' "$SCRIPT_ABSPATH"
|
||||
fi
|
||||
chmod +x "$SCRIPT_ABSPATH"
|
||||
|
||||
PROJECT_ROOT="$(dirname "$SCRIPT_ABSPATH")"
|
||||
|
||||
BLUE='\033[0;34m'
|
||||
GREEN='\033[0;32m'
|
||||
RED='\033[0;31m'
|
||||
YELLOW='\033[0;33m'
|
||||
BOLD='\033[1m'
|
||||
RESET='\033[0m'
|
||||
|
||||
BACKEND_PID=""
|
||||
FRONTEND_PID=""
|
||||
SHUTTING_DOWN=false
|
||||
|
||||
kill_tree() {
|
||||
local pid=$1 sig=${2:-TERM}
|
||||
local children
|
||||
children=$(pgrep -P "$pid" 2>/dev/null)
|
||||
for child in $children; do
|
||||
kill_tree "$child" "$sig"
|
||||
done
|
||||
kill -"$sig" "$pid" 2>/dev/null
|
||||
}
|
||||
|
||||
cleanup() {
|
||||
$SHUTTING_DOWN && return
|
||||
SHUTTING_DOWN=true
|
||||
|
||||
echo ""
|
||||
echo -e "${YELLOW}${BOLD}Gracefully shutting down all services...${RESET}"
|
||||
|
||||
for pid in $BACKEND_PID $FRONTEND_PID; do
|
||||
[[ -n "$pid" ]] && kill_tree "$pid" TERM
|
||||
done
|
||||
|
||||
local elapsed=0
|
||||
while (( elapsed < 5 )); do
|
||||
local alive=false
|
||||
for pid in $BACKEND_PID $FRONTEND_PID; do
|
||||
[[ -n "$pid" ]] && kill -0 "$pid" 2>/dev/null && alive=true
|
||||
done
|
||||
$alive || break
|
||||
sleep 1
|
||||
((elapsed++))
|
||||
done
|
||||
|
||||
for pid in $BACKEND_PID $FRONTEND_PID; do
|
||||
[[ -n "$pid" ]] && kill -0 "$pid" 2>/dev/null && kill_tree "$pid" KILL
|
||||
done
|
||||
|
||||
wait 2>/dev/null
|
||||
echo -e "${GREEN}${BOLD}All services stopped.${RESET}"
|
||||
}
|
||||
|
||||
trap 'cleanup; exit 0' INT TERM
|
||||
trap cleanup EXIT
|
||||
|
||||
# --- Start backend ---
|
||||
echo -e "${BLUE}${BOLD}[backend]${RESET} Starting backend server..."
|
||||
bash "$PROJECT_ROOT/backend/run.sh" > >(
|
||||
while IFS= read -r line; do
|
||||
printf "${BLUE}${BOLD}[backend]${RESET} %s\n" "$line"
|
||||
done
|
||||
) 2>&1 &
|
||||
BACKEND_PID=$!
|
||||
|
||||
# --- Wait for backend to become healthy ---
|
||||
echo -e "${YELLOW}${BOLD}Waiting for backend (http://localhost:8324) to be ready...${RESET}"
|
||||
MAX_WAIT=120
|
||||
elapsed=0
|
||||
while (( elapsed < MAX_WAIT )); do
|
||||
if curl -s -o /dev/null --connect-timeout 1 http://localhost:8324/ 2>/dev/null; then
|
||||
echo -e "${GREEN}${BOLD}Backend is ready!${RESET}"
|
||||
break
|
||||
fi
|
||||
if ! kill -0 "$BACKEND_PID" 2>/dev/null; then
|
||||
echo -e "${RED}${BOLD}Backend process exited before becoming ready.${RESET}"
|
||||
exit 1
|
||||
fi
|
||||
sleep 2
|
||||
((elapsed += 2))
|
||||
done
|
||||
|
||||
if (( elapsed >= MAX_WAIT )); then
|
||||
echo -e "${RED}${BOLD}Backend did not become ready within ${MAX_WAIT}s. Aborting.${RESET}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# --- Start frontend ---
|
||||
echo -e "${GREEN}${BOLD}[frontend]${RESET} Starting frontend dev server..."
|
||||
bash "$PROJECT_ROOT/frontend/run.sh" > >(
|
||||
while IFS= read -r line; do
|
||||
printf "${GREEN}${BOLD}[frontend]${RESET} %s\n" "$line"
|
||||
done
|
||||
) 2>&1 &
|
||||
FRONTEND_PID=$!
|
||||
|
||||
echo ""
|
||||
echo -e "${BOLD}Both services are running. Press Ctrl+C to stop.${RESET}"
|
||||
echo -e " Backend: ${BLUE}http://localhost:8324${RESET}"
|
||||
echo -e " Frontend: ${GREEN}http://localhost:3000${RESET}"
|
||||
echo ""
|
||||
|
||||
# --- Monitor: if either service exits, tear down both ---
|
||||
while ! $SHUTTING_DOWN; do
|
||||
if ! kill -0 "$BACKEND_PID" 2>/dev/null; then
|
||||
echo -e "${RED}${BOLD}Backend process exited unexpectedly. Shutting down...${RESET}"
|
||||
exit 1
|
||||
fi
|
||||
if [[ -n "$FRONTEND_PID" ]] && ! kill -0 "$FRONTEND_PID" 2>/dev/null; then
|
||||
echo -e "${RED}${BOLD}Frontend process exited unexpectedly. Shutting down...${RESET}"
|
||||
exit 1
|
||||
fi
|
||||
sleep 3
|
||||
done
|
||||
Reference in New Issue
Block a user