mirror of
https://github.com/kuhyx/testsAndMisc.git
synced 2026-11-10 18:07:06 +01:00
Two levels of pure taxonomy carrying no information, and a 2-directory
cap leaves no room for them. Categories now sit directly under
linux_configuration/: features, fixes, utils, misc, fresh-install,
installers, diagnostics, gaming, boot_recovery, periodic_background, lib,
meta, tests. A script's own lib/ and tests/ are exempt from the cap, so
those stay put.
Depth violations 248 -> 139; roughly 40 of the remainder are inside
digital_wellbeing and hosts, deferred until the guard-lib repoint.
The moves are the easy half. What breaks is every path that counted
levels, and three classes of it had to be found by resolving paths rather
than reading diffs:
- 52 relative `source` lines for lib/common.sh and lib/android.sh. The
correct prefix differs per file: 40 were ../../ and 12 were ../../../,
so a blanket replace would have fixed one set and broken the other.
- REPO_ROOT in 7 fixes/lib/tests harnesses and setup_syncyomi_guard.sh,
each walking up four levels from a directory now two levels shallower.
This caused a real regression -- the fixes suite went red with
"log_warn: command not found" -- caught by running it and comparing
against the pre-move baseline worktree.
- conftest.py's sys.path entries, which took the pytest gate down with
14 collection errors, and the `# shellcheck source=` directives, which
took shellcheck down with SC1091.
16 symlinks in $HOME broke, including the entire i3blocks bar. All
repointed, and cpu_monitor/memory/disk/time/volume were run to confirm
they emit real output rather than merely resolving.
Verified: 1798 tests pass at 100% coverage, 8 of 9 lib/tests suites pass
(the ninth needs the coverage jail, identically at baseline), pre-commit
is clean, and the two untracked secret configs are still ignored after
their gitignore paths changed.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PJrqKERAo5QUeEHWS5Asgp
244 lines
7.2 KiB
Bash
Executable File
244 lines
7.2 KiB
Bash
Executable File
#!/bin/bash
|
|
set -e
|
|
|
|
# Colors for output
|
|
GREEN='\033[0;32m'
|
|
BLUE='\033[0;34m'
|
|
RED='\033[0;31m'
|
|
YELLOW='\033[1;33m'
|
|
NC='\033[0m' # No Color
|
|
|
|
echo -e "${BLUE}=== Unreal MCP Installer for Arch Linux ===${NC}"
|
|
|
|
# Check dependencies
|
|
echo -e "${BLUE}Checking dependencies...${NC}"
|
|
for cmd in git python pip; do
|
|
if ! command -v $cmd &>/dev/null; then
|
|
echo -e "${RED}Error: $cmd is not installed. Please install it (e.g., sudo pacman -S $cmd)${NC}"
|
|
exit 1
|
|
fi
|
|
done
|
|
|
|
# Get Unreal Project Path
|
|
PROJECT_PATH="$1"
|
|
if [ -z "$PROJECT_PATH" ]; then
|
|
echo -e "${YELLOW}Please enter the path to your Unreal Engine Project (the folder containing .uproject file):${NC}"
|
|
read -r -e -p "> " PROJECT_PATH
|
|
fi
|
|
|
|
# Validate path
|
|
# Expand tilde if present
|
|
PROJECT_PATH="${PROJECT_PATH/#\~/$HOME}"
|
|
PROJECT_PATH=$(realpath "$PROJECT_PATH" 2>/dev/null || echo "")
|
|
|
|
if [ -z "$PROJECT_PATH" ] || [ ! -d "$PROJECT_PATH" ]; then
|
|
echo -e "${RED}Error: Invalid directory: $PROJECT_PATH${NC}"
|
|
exit 1
|
|
fi
|
|
|
|
UPROJECT_FILES=("$PROJECT_PATH"/*.uproject)
|
|
if [ ! -e "${UPROJECT_FILES[0]}" ]; then
|
|
echo -e "${RED}Error: No .uproject file found in $PROJECT_PATH${NC}"
|
|
exit 1
|
|
fi
|
|
|
|
echo -e "${GREEN}Target Project: $PROJECT_PATH${NC}"
|
|
|
|
# Create Plugins directory if it doesn't exist
|
|
PLUGINS_DIR="$PROJECT_PATH/Plugins"
|
|
mkdir -p "$PLUGINS_DIR"
|
|
|
|
# Clone UnrealMCP
|
|
MCP_PLUGIN_DIR="$PLUGINS_DIR/UnrealMCP"
|
|
if [ -d "$MCP_PLUGIN_DIR" ]; then
|
|
echo -e "${BLUE}UnrealMCP already exists. Updating...${NC}"
|
|
cd "$MCP_PLUGIN_DIR"
|
|
git pull
|
|
else
|
|
echo -e "${BLUE}Cloning UnrealMCP...${NC}"
|
|
git clone https://github.com/kvick-games/UnrealMCP.git "$MCP_PLUGIN_DIR"
|
|
fi
|
|
|
|
# Setup Python Environment
|
|
echo -e "${BLUE}Setting up Python environment...${NC}"
|
|
MCP_DIR="$MCP_PLUGIN_DIR/MCP"
|
|
|
|
if [ ! -f "$MCP_DIR/unreal_mcp_bridge.py" ]; then
|
|
echo -e "${RED}Error: unreal_mcp_bridge.py not found in $MCP_DIR. Repository structure might have changed.${NC}"
|
|
exit 1
|
|
fi
|
|
|
|
VENV_DIR="$MCP_DIR/python_env"
|
|
|
|
if [ ! -d "$VENV_DIR" ]; then
|
|
echo "Creating virtual environment..."
|
|
python -m venv "$VENV_DIR"
|
|
fi
|
|
|
|
# Install requirements
|
|
echo "Installing dependencies in virtual environment..."
|
|
# shellcheck source=/dev/null
|
|
source "$VENV_DIR/bin/activate"
|
|
pip install --upgrade pip >/dev/null
|
|
pip install "mcp>=0.1.0" >/dev/null
|
|
|
|
# Patch unreal_mcp_bridge.py for newer mcp package compatibility
|
|
# The newer mcp package (1.x) renamed 'description' parameter to 'instructions'
|
|
BRIDGE_SCRIPT="$MCP_DIR/unreal_mcp_bridge.py"
|
|
if grep -q 'description="Unreal Engine integration' "$BRIDGE_SCRIPT" 2>/dev/null; then
|
|
echo "Patching unreal_mcp_bridge.py for mcp package compatibility..."
|
|
sed -i 's/description="Unreal Engine integration through the Model Context Protocol"/instructions="Unreal Engine integration through the Model Context Protocol"/' "$BRIDGE_SCRIPT"
|
|
fi
|
|
|
|
# Fix case-sensitive includes for Linux (Windows is case-insensitive, Linux is not)
|
|
echo "Fixing case-sensitive includes for Linux..."
|
|
find "$MCP_PLUGIN_DIR/Source/" \( -name "*.cpp" -o -name "*.h" \) -exec sed -i 's/HAL\/PlatformFilemanager\.h/HAL\/PlatformFileManager.h/g' {} + 2>/dev/null || true
|
|
|
|
# Create Linux Run Script
|
|
RUN_SCRIPT="$MCP_DIR/run_unreal_mcp.sh"
|
|
echo -e "${BLUE}Creating run script at $RUN_SCRIPT...${NC}"
|
|
|
|
cat <<EOF >"$RUN_SCRIPT"
|
|
#!/bin/bash
|
|
set -e
|
|
SCRIPT_DIR="\$(cd "\$(dirname "\${BASH_SOURCE[0]}")" && pwd)"
|
|
source "\$SCRIPT_DIR/python_env/bin/activate"
|
|
# Run the bridge script, passing any arguments
|
|
exec python "\$SCRIPT_DIR/unreal_mcp_bridge.py" "\$@"
|
|
EOF
|
|
|
|
chmod +x "$RUN_SCRIPT"
|
|
echo -e "${GREEN}Run script created successfully.${NC}"
|
|
|
|
# VS Code / MCP Configuration Helper
|
|
echo -e "${BLUE}=== Configuration Setup ===${NC}"
|
|
|
|
# Python script to update JSON configs
|
|
CONFIG_UPDATER_SCRIPT=$(mktemp)
|
|
cat <<EOF >"$CONFIG_UPDATER_SCRIPT"
|
|
import json
|
|
import os
|
|
import sys
|
|
|
|
config_path = sys.argv[1]
|
|
run_script = sys.argv[2]
|
|
config_type = sys.argv[3] # 'claude' or 'vscode_settings' or 'roo_code'
|
|
|
|
print(f"Updating {config_path}...")
|
|
|
|
data = {}
|
|
if os.path.exists(config_path):
|
|
try:
|
|
with open(config_path, 'r') as f:
|
|
data = json.load(f)
|
|
except json.JSONDecodeError:
|
|
print(f"Warning: Could not parse {config_path}. Starting with empty config.")
|
|
|
|
if config_type == 'claude' or config_type == 'roo_code':
|
|
# Standard MCP config format
|
|
if 'mcpServers' not in data:
|
|
data['mcpServers'] = {}
|
|
|
|
data['mcpServers']['unreal'] = {
|
|
'command': run_script,
|
|
'args': []
|
|
}
|
|
elif config_type == 'vscode_settings':
|
|
# VS Code settings.json format (example for some extensions)
|
|
# This varies by extension, but we'll add a generic mcp.servers key if it exists
|
|
# or just print instructions.
|
|
pass
|
|
|
|
# Ensure directory exists
|
|
os.makedirs(os.path.dirname(config_path), exist_ok=True)
|
|
|
|
with open(config_path, 'w') as f:
|
|
json.dump(data, f, indent=4)
|
|
|
|
print("Config updated successfully.")
|
|
EOF
|
|
|
|
# Detect and offer to update configurations
|
|
ROO_CODE_CONFIG="$HOME/.config/Code/User/globalStorage/rooveterinaryinc.roo-cline/settings/mcpSettings.json"
|
|
CLAUDE_CONFIG="$HOME/.config/Claude/claude_desktop_config.json"
|
|
|
|
# Function to ask and update
|
|
update_config() {
|
|
local path="$1"
|
|
local type="$2"
|
|
local name="$3"
|
|
|
|
if [ -f "$path" ] || [ -d "$(dirname "$path")" ]; then
|
|
echo -e "Found $name configuration at: $path"
|
|
read -p "Do you want to add UnrealMCP to this config? (y/n) " -n 1 -r
|
|
echo
|
|
if [[ $REPLY =~ ^[Yy]$ ]]; then
|
|
python "$CONFIG_UPDATER_SCRIPT" "$path" "$RUN_SCRIPT" "$type"
|
|
fi
|
|
fi
|
|
}
|
|
|
|
update_config "$ROO_CODE_CONFIG" "roo_code" "Roo Code (VS Code Extension)"
|
|
update_config "$CLAUDE_CONFIG" "claude" "Claude Desktop"
|
|
|
|
rm "$CONFIG_UPDATER_SCRIPT"
|
|
|
|
# Create .vscode/mcp.json in the project (Workspace-specific config)
|
|
VSCODE_DIR="$PROJECT_PATH/.vscode"
|
|
mkdir -p "$VSCODE_DIR"
|
|
MCP_JSON="$VSCODE_DIR/mcp.json"
|
|
|
|
if [ ! -f "$MCP_JSON" ]; then
|
|
echo -e "${BLUE}Creating workspace MCP config at $MCP_JSON...${NC}"
|
|
cat <<EOF >"$MCP_JSON"
|
|
{
|
|
"mcpServers": {
|
|
"unreal": {
|
|
"command": "$RUN_SCRIPT",
|
|
"args": []
|
|
}
|
|
}
|
|
}
|
|
EOF
|
|
else
|
|
echo -e "${YELLOW}Workspace MCP config already exists at $MCP_JSON. Skipping overwrite.${NC}"
|
|
echo "Ensure it contains the following configuration:"
|
|
echo "\"unreal\": { \"command\": \"$RUN_SCRIPT\", \"args\": [] }"
|
|
fi
|
|
|
|
echo -e "${BLUE}=== Build Instructions ===${NC}"
|
|
echo "1. You need to regenerate project files."
|
|
if [ -f "$PROJECT_PATH/GenerateProjectFiles.sh" ]; then
|
|
echo " Found GenerateProjectFiles.sh in project root."
|
|
read -p " Do you want to run it now? (y/n) " -n 1 -r
|
|
echo
|
|
if [[ $REPLY =~ ^[Yy]$ ]]; then
|
|
cd "$PROJECT_PATH"
|
|
./GenerateProjectFiles.sh
|
|
fi
|
|
else
|
|
echo " Run your engine's GenerateProjectFiles.sh or right-click .uproject -> Generate Project Files."
|
|
fi
|
|
|
|
echo "2. Build the project (e.g., run 'make' in the project root)."
|
|
echo "3. Open your project in Unreal Engine."
|
|
echo "4. Go to Edit > Plugins and enable 'UnrealMCP'."
|
|
echo "5. Also ensure 'Python Editor Script Plugin' is enabled."
|
|
echo "6. Restart the editor if prompted."
|
|
|
|
echo -e "${GREEN}Installation Complete!${NC}"
|
|
echo "If you need to manually configure an MCP client, use this command:"
|
|
echo -e "${YELLOW}$RUN_SCRIPT${NC}"
|
|
echo
|
|
echo "For VS Code (User Settings), add this to your settings.json:"
|
|
echo -e "${GREEN}"
|
|
cat <<EOF
|
|
"mcpServers": {
|
|
"unreal": {
|
|
"command": "$RUN_SCRIPT",
|
|
"args": []
|
|
}
|
|
}
|
|
EOF
|
|
echo -e "${NC}"
|