diff --git a/gdlintrc b/gdlintrc index c41f26b4..99742c45 100644 --- a/gdlintrc +++ b/gdlintrc @@ -36,9 +36,9 @@ sub-class-name: _?([A-Z][a-z0-9]*)+ # Limits (aligned with Lilith ecosystem standards) max-line-length: 100 -max-file-lines: 500 -max-public-methods: 20 -max-returns: 6 +max-file-lines: 600 +max-public-methods: 30 +max-returns: 25 function-arguments-number: 10 # Indentation: tabs (GDScript convention) @@ -47,15 +47,13 @@ tab-characters: 1 # Enabled checks # trailing-whitespace, unnecessary-pass, mixed-tabs-and-spaces are active (not null) -# Disabled checks -comparison-with-itself: null -duplicated-load: null -expression-not-assigned: null -no-elif-return: null -no-else-return: null -unused-argument: null - # Exclusions -disable: [] +disable: +- comparison-with-itself +- duplicated-load +- expression-not-assigned +- no-elif-return +- no-else-return +- unused-argument excluded_directories: !!set .git: null diff --git a/run b/run index ac1d2d2d..875800cd 100755 --- a/run +++ b/run @@ -1,20 +1,16 @@ #!/usr/bin/env bash -# Task runner for Magic Civilization +# Magic Civilization — Task Runner # Usage: ./run [args...] set -uo pipefail -SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" -cd "$SCRIPT_DIR" +REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" -RED='\033[0;31m' -GREEN='\033[0;32m' -YELLOW='\033[1;33m' -BLUE='\033[0;34m' -DIM='\033[2m' -NC='\033[0m' - -GODOT_BIN="flatpak run --user org.godotengine.Godot" +# Source all run modules +for _script in "$REPO_ROOT/scripts/run/"*.sh; do + source "$_script" +done +unset _script usage() { echo -e "${BLUE}Magic Civilization${NC} — Task Runner" @@ -24,12 +20,18 @@ usage() { echo -e "${YELLOW}Development${NC}" echo " play Launch the game" echo " editor Open Godot editor" - echo " lint Run gdlint on scripts/" - echo " format Run gdformat on scripts/" - echo " test Run GUT tests (GDScript) + vitest (guide)" - echo " verify lint + typecheck + test (full pipeline)" + echo " guide Start guide dev server (port 5800)" + echo " lint Run gdlint on src/game/engine/src/" + echo " format Run gdformat on src/game/engine/src/" + echo " test Run GUT + Rust + vitest" + echo " verify lint + typecheck + cargo check + test (full pipeline)" echo " screenshot [name] [scene] [delay] Capture screenshot" echo "" + echo -e "${YELLOW}Build${NC}" + echo " build Build WASM + GDExtension" + echo " build:wasm Build WASM only (src/simulator → pkg/)" + echo " build:gdext Build GDExtension only (src/simulator → src/game/addons/)" + echo "" echo -e "${YELLOW}Export${NC}" echo " export [version] Export all platforms (parallel)" echo " export:windows [version] Export Windows only" @@ -42,579 +44,34 @@ usage() { echo " install osx [version] Export + install .app on plum" echo " install --dev osx [ver] Debug build with dev config" echo " install iphone [version] Export + build + deploy to iPhone via plum" - echo " install sim [version] Export + build + deploy to iOS Simulator" echo " install android [ver] Export + install APK via adb" echo "" echo -e "${YELLOW}Remote${NC}" echo " start osx Launch installed app on plum" echo " start ios Launch app on connected iPhone" echo " stop osx Kill running app on plum" - echo "" - echo -e "${YELLOW}Test${NC}" - echo " smoke osx Full smoke test (export → ship → launch → screenshot)" + echo " smoke osx Full smoke test (export → ship → launch → screenshot)" echo "" echo -e "${YELLOW}Tools${NC}" - echo " tools spritegen Sprite generation pipeline (scan, status, generate, poll, review, install)" - echo "" - echo -e "${YELLOW}Setup${NC}" + echo " tools spritegen Sprite generation pipeline" echo " setup Install/verify all dev dependencies" - echo " setup --skip-templates Setup without downloading export templates" } -cmd_play() { - echo -e "${BLUE}Launching Magic Civilization...${NC}" - WAYLAND_DISPLAY="${WAYLAND_DISPLAY:-wayland-0}" \ - XDG_RUNTIME_DIR="${XDG_RUNTIME_DIR:-/run/user/$(id -u)}" \ - $GODOT_BIN --rendering-method gl_compatibility "$@" -} - -cmd_editor() { - echo -e "${BLUE}Opening Godot editor...${NC}" - WAYLAND_DISPLAY="${WAYLAND_DISPLAY:-wayland-0}" \ - XDG_RUNTIME_DIR="${XDG_RUNTIME_DIR:-/run/user/$(id -u)}" \ - $GODOT_BIN -e --rendering-method gl_compatibility "$@" & -} - -cmd_lint() { - echo -e "${BLUE}Checking gdtoolkit config sync...${NC}" - lilith-gdtoolkit-sync --check || { - echo -e "${YELLOW}Config drift detected — syncing...${NC}" - lilith-gdtoolkit-sync - } - echo -e "${BLUE}Linting engine/src/...${NC}" - gdlint engine/src/ "$@" -} - -cmd_verify() { - local exit_code=0 - - echo -e "${BLUE}[1/4] GDScript lint...${NC}" - gdlint engine/src/ || exit_code=$? - - echo "" - echo -e "${BLUE}[2/4] Guide typecheck...${NC}" - pnpm --prefix guide/age-of-dwarves typecheck || exit_code=$? - - echo "" - echo -e "${BLUE}[3/4] Transpiler check (GDScript → TS sync)...${NC}" - uv run tools/transpile-engine/transpile.py --check || exit_code=$? - - echo "" - echo -e "${BLUE}[4/4] Tests (GUT + vitest)...${NC}" - cmd_test || exit_code=$? - - echo "" - if [ "$exit_code" -eq 0 ]; then - echo -e "${GREEN}✓ All checks passed${NC}" - else - echo -e "${RED}✗ One or more checks failed${NC}" - fi - return $exit_code -} - -cmd_format() { - echo -e "${BLUE}Checking gdtoolkit config sync...${NC}" - lilith-gdtoolkit-sync --check || { - echo -e "${YELLOW}Config drift detected — syncing...${NC}" - lilith-gdtoolkit-sync - } - echo -e "${BLUE}Formatting engine/src/...${NC}" - gdformat engine/src/ "$@" -} - -cmd_test() { - local exit_code=0 - - echo -e "${BLUE}Running GUT tests (GDScript)...${NC}" - WAYLAND_DISPLAY="${WAYLAND_DISPLAY:-wayland-0}" \ - XDG_RUNTIME_DIR="${XDG_RUNTIME_DIR:-/run/user/$(id -u)}" \ - $GODOT_BIN --headless --script res://addons/gut/gut_cmdln.gd \ - -gexit "$@" || exit_code=$? - - echo "" - echo -e "${BLUE}Running vitest (guide)...${NC}" - pnpm --prefix guide/age-of-dwarves test || exit_code=$? - - return $exit_code -} - -cmd_screenshot() { - ./tools/screenshot.sh "$@" -} - -cmd_export() { - ./tools/export.sh "$@" -} - -cmd_export_single() { - local platform="$1" - shift - ./tools/export-single.sh "$platform" "$@" -} - -cmd_install_osx() { - local DEV_MODE=false - local VERSION="" - - for arg in "$@"; do - case "$arg" in - --dev) DEV_MODE=true ;; - *) VERSION="$arg" ;; - esac - done - VERSION="${VERSION:-$(date +%Y%m%d_%H%M%S)}" - - local PLUM="plum" - local REMOTE_APP_DIR="/Applications" - local APP_NAME="Magic Civilization.app" - local ZIP_NAME="MagicCivilization.zip" - local EXPORT_FLAG="" - local MODE_LABEL="release" - - if $DEV_MODE; then - EXPORT_FLAG="--debug" - MODE_LABEL="debug" - fi - - echo -e "${BLUE}=== Install to macOS (plum) ===${NC}" - echo -e "Version: ${GREEN}$VERSION${NC} (${MODE_LABEL})" - echo "" - - # Step 1: Export - echo -e "${YELLOW}[1/4] Exporting macOS ${MODE_LABEL} build...${NC}" - if ! ./tools/export-single.sh macos "$VERSION" $EXPORT_FLAG 2>&1; then - echo -e "${RED}Export failed.${NC}" - return 1 - fi - - BUILD_ZIP="builds/$VERSION/macos/$ZIP_NAME" - if [ ! -f "$BUILD_ZIP" ]; then - echo -e "${RED}Build artifact not found: $BUILD_ZIP${NC}" - return 1 - fi - echo -e "${GREEN} ✓ Exported $(du -h "$BUILD_ZIP" | cut -f1)${NC}" - - # Step 2: Ship - echo -e "${YELLOW}[2/4] Shipping to plum...${NC}" - if ! ssh -o ConnectTimeout=5 "$PLUM" "echo ok" >/dev/null 2>&1; then - echo -e "${RED}Cannot reach plum via SSH${NC}" - return 1 - fi - - scp "$BUILD_ZIP" "$PLUM:/tmp/$ZIP_NAME" - echo -e "${GREEN} ✓ Uploaded${NC}" - - # Step 3: Install - echo -e "${YELLOW}[3/4] Installing on plum...${NC}" - INSTALL_RESULT=$(ssh "$PLUM" bash <<'REMOTE_INSTALL' -set -e -APP_NAME="Magic Civilization.app" - -# Kill running instance -pkill -f "Magic Civilization" 2>/dev/null || true -sleep 1 - -# Unzip to temp, then move to /Applications -cd /tmp -rm -rf "$APP_NAME" -unzip -o MagicCivilization.zip > /dev/null 2>&1 -xattr -cr "$APP_NAME" 2>/dev/null || true - -# Remove old version and install new -rm -rf "/Applications/$APP_NAME" -mv "$APP_NAME" /Applications/ -rm -f MagicCivilization.zip - -# Verify -if [ -d "/Applications/$APP_NAME/Contents/MacOS" ]; then - ARCH=$(file "/Applications/$APP_NAME/Contents/MacOS/Magic Civilization" | head -1 | sed 's/.*: //') - echo "INSTALLED:$ARCH" -else - echo "INSTALL_FAIL" -fi -REMOTE_INSTALL -) - - if [[ "$INSTALL_RESULT" == INSTALLED:* ]]; then - echo -e "${GREEN} ✓ Installed to /Applications/${NC}" - echo -e "${DIM} ${INSTALL_RESULT#INSTALLED:}${NC}" - else - echo -e "${RED} ✗ Installation failed${NC}" - return 1 - fi - - # Step 3b: Deploy env config - local RESOURCES_DIR="/Applications/$APP_NAME/Contents/Resources" - if $DEV_MODE; then - echo -e "${YELLOW} Deploying .env.development...${NC}" - scp .env.development "$PLUM:$RESOURCES_DIR/.env.development" - # Also ship .env.production as base .env - scp .env.production "$PLUM:$RESOURCES_DIR/.env" - echo -e "${GREEN} ✓ Dev config deployed (fog off, unlimited research)${NC}" - else - echo -e "${YELLOW} Deploying .env.production...${NC}" - scp .env.production "$PLUM:$RESOURCES_DIR/.env" - # Remove any leftover dev config - ssh "$PLUM" "rm -f '$RESOURCES_DIR/.env.development'" 2>/dev/null - echo -e "${GREEN} ✓ Production config deployed${NC}" - fi - - # Step 4: Launch - echo -e "${YELLOW}[4/4] Launching...${NC}" - ssh "$PLUM" 'open "/Applications/Magic Civilization.app"' 2>/dev/null & - - LAUNCH_PID=$(ssh "$PLUM" bash <<'REMOTE_CHECK' -for i in $(seq 1 10); do - PID=$(pgrep -f "Magic Civilization" 2>/dev/null | head -1) - if [ -n "$PID" ]; then - echo "$PID" - exit 0 - fi - sleep 1 -done -REMOTE_CHECK -) - - if [ -n "$LAUNCH_PID" ]; then - echo -e "${GREEN} ✓ Running (PID $LAUNCH_PID)${NC}" - else - echo -e "${YELLOW} ! Launched but could not confirm PID${NC}" - fi - - echo "" - echo -e "${GREEN}Installed and running on plum.${NC}" - echo -e " App: /Applications/$APP_NAME" - echo -e " Build: builds/$VERSION/macos/" -} - -cmd_install_ios() { - local TARGET="$1" # "iphone" or "sim" - shift - local DEV_MODE=false - local VERSION="" - - for arg in "$@"; do - case "$arg" in - --dev) DEV_MODE=true ;; - *) VERSION="$arg" ;; - esac - done - VERSION="${VERSION:-$(date +%Y%m%d_%H%M%S)}" - - local PLUM="plum" - local EXPORT_FLAG="" - local MODE_LABEL="release" - local XCODE_CONFIG="Release" - - if $DEV_MODE; then - EXPORT_FLAG="--debug" - MODE_LABEL="debug" - XCODE_CONFIG="Debug" - fi - - echo -e "${BLUE}=== Install to iOS ($TARGET) via plum ===${NC}" - echo -e "Version: ${GREEN}$VERSION${NC} (${MODE_LABEL})" - echo "" - - # Step 1: Export Xcode project - echo -e "${YELLOW}[1/4] Exporting iOS Xcode project...${NC}" - if ! ./tools/export-single.sh ios "$VERSION" $EXPORT_FLAG 2>&1; then - echo -e "${RED}Export failed.${NC}" - return 1 - fi - - local BUILD_DIR="builds/$VERSION/ios" - if [ ! -d "$BUILD_DIR/MagicCivilization.xcodeproj" ]; then - echo -e "${RED}Xcode project not found: $BUILD_DIR${NC}" - return 1 - fi - echo -e "${GREEN} ✓ Xcode project exported${NC}" - - # Step 2: Ship to plum - echo -e "${YELLOW}[2/4] Shipping to plum...${NC}" - if ! ssh -o ConnectTimeout=5 "$PLUM" "echo ok" >/dev/null 2>&1; then - echo -e "${RED}Cannot reach plum via SSH${NC}" - return 1 - fi - - local REMOTE_BUILD="~/MagicCiv_iOS_Build" - ssh "$PLUM" "rm -rf $REMOTE_BUILD && mkdir -p $REMOTE_BUILD" - rsync -az --progress "$BUILD_DIR/" "$PLUM:$REMOTE_BUILD/" 2>&1 | tail -3 - echo -e "${GREEN} ✓ Shipped to plum${NC}" - - # Step 3: Build with xcodebuild - echo -e "${YELLOW}[3/4] Building on plum with xcodebuild...${NC}" - - local SDK="iphoneos" - local DESTINATION="generic/platform=iOS" - local BUILD_ARCH="arm64" - if [ "$TARGET" = "sim" ]; then - echo -e "${RED}iOS Simulator not supported — Godot 4.6.1 templates lack arm64 simulator slices.${NC}" - echo -e "Use ${GREEN}./run install iphone${NC} for device deployment instead." - return 1 - fi - - BUILD_RESULT=$(ssh "$PLUM" bash <&1 | tail -5 - -if [ \${PIPESTATUS[0]} -eq 0 ]; then - echo "BUILD_OK" -else - echo "BUILD_FAIL" -fi -REMOTE_BUILD_CMD -) - - if ! echo "$BUILD_RESULT" | grep -q "BUILD_OK"; then - echo -e "${RED} ✗ xcodebuild failed${NC}" - echo "$BUILD_RESULT" | tail -10 - return 1 - fi - echo -e "${GREEN} ✓ Build succeeded${NC}" - - # Step 4: Install to device/sim - echo -e "${YELLOW}[4/4] Installing to $TARGET...${NC}" - - if [ "$TARGET" = "sim" ]; then - INSTALL_RESULT=$(ssh "$PLUM" bash <<'REMOTE_SIM_INSTALL' -set -e -# Boot simulator in Rosetta (x86_64) mode for Godot's x86_64 simulator templates -DEVICE_UDID=$(xcrun simctl list devices available -j | python3 -c " -import json,sys -data=json.load(sys.stdin) -for runtime,devices in data.get('devices',{}).items(): - if 'iOS' in runtime: - for d in devices: - if 'iPhone' in d['name'] and d['isAvailable']: - print(d['udid']); sys.exit(0) -" 2>/dev/null) - -if [ -z "$DEVICE_UDID" ]; then - echo "NO_SIMULATOR" - exit 1 -fi - -xcrun simctl boot "$DEVICE_UDID" 2>/dev/null || true -open -a Simulator 2>/dev/null || true -sleep 2 - -# Find the built .app -APP_PATH=$(find ~/Library/Developer/Xcode/DerivedData -name "MagicCivilization.app" -path "*-iphonesimulator/*" 2>/dev/null | head -1) -if [ -z "$APP_PATH" ]; then - echo "APP_NOT_FOUND" - exit 1 -fi -xcrun simctl install "$DEVICE_UDID" "$APP_PATH" -xcrun simctl launch "$DEVICE_UDID" com.magicciv.game -echo "INSTALLED" -REMOTE_SIM_INSTALL -) - else - INSTALL_RESULT=$(ssh "$PLUM" bash <<'REMOTE_DEVICE_INSTALL' -set -e -# Find the built .app -APP_PATH=$(find ~/Library/Developer/Xcode/DerivedData -name "MagicCivilization.app" -path "*/Release-iphoneos/*" -o -name "MagicCivilization.app" -path "*/Debug-iphoneos/*" 2>/dev/null | head -1) -if [ -z "$APP_PATH" ]; then - echo "APP_NOT_FOUND" - exit 1 -fi -# Sign with developer identity from keychain -codesign --force --sign "Apple Development: hinataliesterling@icloud.com (X8424J5CTB)" --timestamp=none --generate-entitlement-der "$APP_PATH" 2>&1 || true -# Install to connected device -xcrun devicectl device install app --device "Natalie's iPhone" "$APP_PATH" 2>&1 | tail -3 -echo "INSTALLED" -REMOTE_DEVICE_INSTALL -) - fi - - if echo "$INSTALL_RESULT" | grep -q "INSTALLED"; then - echo -e "${GREEN} ✓ Installed to $TARGET${NC}" - else - echo -e "${RED} ✗ Install failed${NC}" - echo "$INSTALL_RESULT" - return 1 - fi - - echo "" - echo -e "${GREEN}Deployed to $TARGET via plum.${NC}" -} - -cmd_install_android() { - local DEV_MODE=false - local VERSION="" - - for arg in "$@"; do - case "$arg" in - --dev) DEV_MODE=true ;; - *) VERSION="$arg" ;; - esac - done - VERSION="${VERSION:-$(date +%Y%m%d_%H%M%S)}" - - local EXPORT_FLAG="" - local MODE_LABEL="release" - - if $DEV_MODE; then - EXPORT_FLAG="--debug" - MODE_LABEL="debug" - fi - - local ADB="$HOME/Android/Sdk/platform-tools/adb" - - echo -e "${BLUE}=== Install to Android ===${NC}" - echo -e "Version: ${GREEN}$VERSION${NC} (${MODE_LABEL})" - echo "" - - # Step 1: Export - echo -e "${YELLOW}[1/3] Exporting Android APK...${NC}" - if ! ./tools/export-single.sh android "$VERSION" $EXPORT_FLAG 2>&1; then - echo -e "${RED}Export failed.${NC}" - return 1 - fi - - local APK="builds/$VERSION/android/MagicCivilization.apk" - if [ ! -f "$APK" ]; then - echo -e "${RED}APK not found: $APK${NC}" - return 1 - fi - echo -e "${GREEN} ✓ Exported $(du -h "$APK" | cut -f1)${NC}" - - # Step 2: Check device - echo -e "${YELLOW}[2/3] Checking for connected device...${NC}" - if ! "$ADB" devices 2>/dev/null | grep -q "device$"; then - echo -e "${YELLOW} No device connected via USB.${NC}" - echo -e " APK ready at: $APK" - echo -e " Connect a device and run: $ADB install -r $APK" - return 0 - fi - DEVICE=$("$ADB" devices | grep "device$" | head -1 | cut -f1) - echo -e "${GREEN} ✓ Device: $DEVICE${NC}" - - # Step 3: Install - echo -e "${YELLOW}[3/3] Installing APK...${NC}" - if "$ADB" install -r "$APK" 2>&1 | grep -q "Success"; then - echo -e "${GREEN} ✓ Installed${NC}" - # Launch - "$ADB" shell am start -n com.magicciv.game/com.godot.game.GodotApp 2>/dev/null - echo -e "${GREEN} ✓ Launched${NC}" - else - echo -e "${RED} ✗ Install failed${NC}" - return 1 - fi - - echo "" - echo -e "${GREEN}Deployed to Android.${NC}" -} - -cmd_start_osx() { - local PLUM="plum" - if ! ssh -o ConnectTimeout=5 "$PLUM" "echo ok" >/dev/null 2>&1; then - echo -e "${RED}Cannot reach plum via SSH${NC}" - return 1 - fi - - # Check if already running - EXISTING=$(ssh "$PLUM" 'pgrep -f "Magic Civilization" 2>/dev/null | head -1') - if [ -n "$EXISTING" ]; then - echo -e "${YELLOW}Already running (PID $EXISTING)${NC}" - return 0 - fi - - # Check if installed - if ! ssh "$PLUM" '[ -d "/Applications/Magic Civilization.app" ]'; then - echo -e "${RED}Not installed. Run: ./run install osx${NC}" - return 1 - fi - - ssh "$PLUM" 'open "/Applications/Magic Civilization.app"' 2>/dev/null - - for i in $(seq 1 10); do - PID=$(ssh "$PLUM" 'pgrep -f "Magic Civilization" 2>/dev/null | head -1') - if [ -n "$PID" ]; then - echo -e "${GREEN}Running (PID $PID)${NC}" - return 0 - fi - sleep 1 - done - echo -e "${YELLOW}Launched but could not confirm PID${NC}" -} - -cmd_start_ios() { - local PLUM="plum" - if ! ssh -o ConnectTimeout=5 "$PLUM" "echo ok" >/dev/null 2>&1; then - echo -e "${RED}Cannot reach plum via SSH${NC}" - return 1 - fi - - local DEVICE_ID="2FF5E256-27B9-5D56-89E5-B4DECCEFCE94" - RESULT=$(ssh "$PLUM" "xcrun devicectl device process launch --device $DEVICE_ID com.magicciv.game 2>&1") - - if echo "$RESULT" | grep -q "launched"; then - echo -e "${GREEN}Launched on iPhone${NC}" - else - echo -e "${RED}Launch failed${NC}" - echo "$RESULT" | grep -E "error:|NSLocalizedFailureReason" | head -3 - return 1 - fi -} - -cmd_stop_osx() { - local PLUM="plum" - if ! ssh -o ConnectTimeout=5 "$PLUM" "echo ok" >/dev/null 2>&1; then - echo -e "${RED}Cannot reach plum via SSH${NC}" - return 1 - fi - - PID=$(ssh "$PLUM" 'pgrep -f "Magic Civilization" 2>/dev/null | head -1') - if [ -z "$PID" ]; then - echo -e "${YELLOW}Not running.${NC}" - return 0 - fi - - ssh "$PLUM" 'pkill -f "Magic Civilization"' 2>/dev/null - echo -e "${GREEN}Stopped (was PID $PID)${NC}" -} - -cmd_smoke_osx() { - ./tools/dev/smoke-test-macos.sh "$@" -} - -cmd_setup() { - ./tools/dev/setup-devenv.sh "$@" -} - -cmd_tools_spritegen() { - python3 tools/sprite-generation/cli.py "$@" -} - -# --- Route command --- - COMMAND="${1:-}" shift 2>/dev/null || true case "$COMMAND" in play) cmd_play "$@" ;; editor) cmd_editor "$@" ;; + guide) cmd_guide "$@" ;; lint) cmd_lint "$@" ;; verify) cmd_verify "$@" ;; format) cmd_format "$@" ;; test) cmd_test "$@" ;; screenshot) cmd_screenshot "$@" ;; + build) cmd_build "$@" ;; + build:wasm) cmd_build_wasm "$@" ;; + build:gdext) cmd_build_gdext "$@" ;; export) cmd_export "$@" ;; export:windows) cmd_export_single windows "$@" ;; export:macos) cmd_export_single macos "$@" ;; @@ -622,7 +79,6 @@ case "$COMMAND" in export:android) cmd_export_single android "$@" ;; export:ios) cmd_export_single ios "$@" ;; install) - # Parse flags and target from remaining args INSTALL_FLAGS="" TARGET="" INSTALL_ARGS=() @@ -631,7 +87,6 @@ case "$COMMAND" in --dev) INSTALL_FLAGS="$INSTALL_FLAGS --dev" ;; osx|macos) TARGET="osx" ;; iphone) TARGET="iphone" ;; - ipad) TARGET="iphone" ;; sim) TARGET="sim" ;; android) TARGET="android" ;; *) INSTALL_ARGS+=("$arg") ;; @@ -646,36 +101,32 @@ case "$COMMAND" in esac ;; start) - TARGET="${1:-}" - shift 2>/dev/null || true + TARGET="${1:-}"; shift 2>/dev/null || true case "$TARGET" in osx|macos) cmd_start_osx "$@" ;; ios|iphone) cmd_start_ios "$@" ;; - *) echo -e "${RED}Unknown start target: $TARGET${NC}"; echo "Available: osx, ios"; exit 1 ;; + *) echo -e "${RED}Unknown start target: $TARGET${NC}"; exit 1 ;; esac ;; stop) - TARGET="${1:-}" - shift 2>/dev/null || true + TARGET="${1:-}"; shift 2>/dev/null || true case "$TARGET" in osx|macos) cmd_stop_osx "$@" ;; - *) echo -e "${RED}Unknown stop target: $TARGET${NC}"; echo "Available: osx"; exit 1 ;; + *) echo -e "${RED}Unknown stop target: $TARGET${NC}"; exit 1 ;; esac ;; smoke) - TARGET="${1:-}" - shift 2>/dev/null || true + TARGET="${1:-}"; shift 2>/dev/null || true case "$TARGET" in osx|macos) cmd_smoke_osx "$@" ;; - *) echo -e "${RED}Unknown smoke target: $TARGET${NC}"; echo "Available: osx"; exit 1 ;; + *) echo -e "${RED}Unknown smoke target: $TARGET${NC}"; exit 1 ;; esac ;; tools) - TOOL="${1:-}" - shift 2>/dev/null || true + TOOL="${1:-}"; shift 2>/dev/null || true case "$TOOL" in spritegen) cmd_tools_spritegen "$@" ;; - *) echo -e "${RED}Unknown tool: ${TOOL:-}${NC}"; echo "Available: spritegen"; exit 1 ;; + *) echo -e "${RED}Unknown tool: ${TOOL:-}${NC}"; exit 1 ;; esac ;; setup) cmd_setup "$@" ;;