feat: add macOS Desktop App installation script
- Add scripts/install-macos-app.sh for one-click macOS app installation - Uses bundled assets/images/logo.jpg as app icon - AppleScript prompts for project folder on first run - Updates README with macOS Desktop App installation option - Supports both interactive and --auto non-interactive modes Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
This commit is contained in:
195
scripts/install-macos-app.sh
Executable file
195
scripts/install-macos-app.sh
Executable file
@@ -0,0 +1,195 @@
|
||||
#!/bin/bash
|
||||
|
||||
# GenericAgent macOS Desktop App Installation Script
|
||||
# Installs GenericAgent as a native macOS desktop application
|
||||
#
|
||||
# Usage: bash scripts/install-macos-app.sh [--auto]
|
||||
#
|
||||
# Options:
|
||||
# --auto Non-interactive mode, skip prompts and install directly
|
||||
|
||||
if [ -z "${BASH_VERSION}" ]; then
|
||||
if command -v bash >/dev/null 2>&1; then
|
||||
exec bash -- "${0}" "$@"
|
||||
else
|
||||
echo "Error: This script requires bash."
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
set -eo pipefail
|
||||
|
||||
# ============================================
|
||||
# Colors
|
||||
# ============================================
|
||||
RED='\033[0;31m'; GREEN='\033[0;32m'; YELLOW='\033[1;33m'; BLUE='\033[0;34m'; CYAN='\033[0;36m'; NC='\033[0m'
|
||||
log_info() { echo -e "${BLUE}ℹ️ $1${NC}"; }
|
||||
log_success() { echo -e "${GREEN}✅ $1${NC}"; }
|
||||
log_warning() { echo -e "${YELLOW}⚠️ $1${NC}"; }
|
||||
log_error() { echo -e "${RED}❌ $1${NC}"; }
|
||||
|
||||
# ============================================
|
||||
# Parse arguments
|
||||
# ============================================
|
||||
AUTO_MODE=false
|
||||
for arg in "$@"; do
|
||||
case "$arg" in --auto) AUTO_MODE=true ;; esac
|
||||
done
|
||||
|
||||
# ============================================
|
||||
# Configuration
|
||||
# ============================================
|
||||
APP_NAME="GenericAgent"
|
||||
APP_PATH="/Applications/${APP_NAME}.app"
|
||||
|
||||
# Icon: bundled alongside this script
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
PROJECT_ROOT="$(cd "${SCRIPT_DIR}/.." && pwd)"
|
||||
ICON_PATH="${PROJECT_ROOT}/assets/images/logo.jpg"
|
||||
|
||||
# ============================================
|
||||
# Pre-flight checks
|
||||
# ============================================
|
||||
echo -e "${CYAN}"
|
||||
echo "╔═══════════════════════════════════════════════════════════╗"
|
||||
echo "║ GenericAgent — macOS Desktop App Installer ║"
|
||||
echo "╚═══════════════════════════════════════════════════════════╝"
|
||||
echo -e "${NC}"
|
||||
|
||||
if [[ "$(uname)" != "Darwin" ]]; then
|
||||
log_error "This script only supports macOS."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Check Python and pip
|
||||
if ! command -v python3 &>/dev/null; then
|
||||
log_error "python3 is not installed."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Check if already installed
|
||||
APP_ALREADY_INSTALLED=false
|
||||
if [ -d "$APP_PATH" ]; then
|
||||
APP_ALREADY_INSTALLED=true
|
||||
log_warning "GenericAgent.app already exists in /Applications."
|
||||
fi
|
||||
|
||||
# Interactive prompt
|
||||
if [ "$AUTO_MODE" = false ]; then
|
||||
echo ""
|
||||
echo "This will install a desktop app that launches GenericAgent"
|
||||
echo "from Spotlight (Cmd+Space), Launchpad, or the Applications folder."
|
||||
echo ""
|
||||
if [ "$APP_ALREADY_INSTALLED" = true ]; then
|
||||
read -p "Reinstall GenericAgent.app? (y/N) " -n 1 -r
|
||||
else
|
||||
read -p "Continue? (Y/n) " -n 1 -r
|
||||
fi
|
||||
echo
|
||||
if [ "$APP_ALREADY_INSTALLED" = true ]; then
|
||||
[[ ! $REPLY =~ ^[Yy]$ ]] && { echo "Aborted."; exit 0; }
|
||||
else
|
||||
[[ $REPLY =~ ^[Nn]$ ]] && { echo "Aborted."; exit 0; }
|
||||
fi
|
||||
fi
|
||||
|
||||
# Remove existing app
|
||||
[ -d "$APP_PATH" ] && rm -rf "$APP_PATH"
|
||||
|
||||
# ============================================
|
||||
# Build the app
|
||||
# ============================================
|
||||
TMP_DIR=$(mktemp -d)
|
||||
trap 'rm -rf "$TMP_DIR"' EXIT
|
||||
|
||||
log_info "Building GenericAgent.app..."
|
||||
|
||||
# Create AppleScript — launches launch.pyw in project directory
|
||||
# The script prompts for project path on first run, or uses a default
|
||||
cat > "${TMP_DIR}/GenericAgent.applescript" << 'APPLESCRIPT'
|
||||
property defaultPath : ""
|
||||
|
||||
on run
|
||||
set projectPath to defaultPath
|
||||
|
||||
if projectPath is "" then
|
||||
-- Ask user for GenericAgent project folder
|
||||
set projectPath to choose folder with prompt "Select your GenericAgent project folder:"
|
||||
end if
|
||||
|
||||
set projectPathStr to POSIX path of projectPath
|
||||
set launchScript to projectPathStr & "launch.pyw"
|
||||
|
||||
tell application "Terminal"
|
||||
activate
|
||||
do script "cd " & quoted form of projectPathStr & " && python3 launch.pyw"
|
||||
end tell
|
||||
end run
|
||||
APPLESCRIPT
|
||||
|
||||
# Compile to .app
|
||||
osacompile -o "${TMP_DIR}/${APP_NAME}.app" "${TMP_DIR}/GenericAgent.applescript" 2>/dev/null
|
||||
|
||||
# ============================================
|
||||
# Install icon
|
||||
# ============================================
|
||||
log_info "Applying GenericAgent icon..."
|
||||
|
||||
if [ -f "$ICON_PATH" ]; then
|
||||
ICONSET_DIR="${TMP_DIR}/ga-icon.iconset"
|
||||
mkdir -p "$ICONSET_DIR"
|
||||
|
||||
sips -z 16 16 "$ICON_PATH" --out "${ICONSET_DIR}/icon_16x16.png" >/dev/null 2>&1
|
||||
sips -z 32 32 "$ICON_PATH" --out "${ICONSET_DIR}/icon_16x16@2x.png" >/dev/null 2>&1
|
||||
sips -z 32 32 "$ICON_PATH" --out "${ICONSET_DIR}/icon_32x32.png" >/dev/null 2>&1
|
||||
sips -z 64 64 "$ICON_PATH" --out "${ICONSET_DIR}/icon_32x32@2x.png" >/dev/null 2>&1
|
||||
sips -z 128 128 "$ICON_PATH" --out "${ICONSET_DIR}/icon_128x128.png" >/dev/null 2>&1
|
||||
sips -z 256 256 "$ICON_PATH" --out "${ICONSET_DIR}/icon_128x128@2x.png" >/dev/null 2>&1
|
||||
sips -z 256 256 "$ICON_PATH" --out "${ICONSET_DIR}/icon_256x256.png" >/dev/null 2>&1
|
||||
sips -z 512 512 "$ICON_PATH" --out "${ICONSET_DIR}/icon_256x256@2x.png" >/dev/null 2>&1
|
||||
sips -z 512 512 "$ICON_PATH" --out "${ICONSET_DIR}/icon_512x512.png" >/dev/null 2>&1
|
||||
cp "$ICON_PATH" "${ICONSET_DIR}/icon_512x512@2x.png"
|
||||
|
||||
iconutil -c icns "$ICONSET_DIR" -o "${TMP_DIR}/ga-icon.icns" 2>/dev/null
|
||||
cp "${TMP_DIR}/ga-icon.icns" "${TMP_DIR}/${APP_NAME}.app/Contents/Resources/applet.icns"
|
||||
log_success "Icon applied from assets/images/logo.jpg"
|
||||
else
|
||||
log_warning "Logo not found at ${ICON_PATH}, using default"
|
||||
fi
|
||||
|
||||
# ============================================
|
||||
# Install to /Applications
|
||||
# ============================================
|
||||
cp -R "${TMP_DIR}/${APP_NAME}.app" "/Applications/"
|
||||
log_success "Installed to: ${APP_PATH}"
|
||||
|
||||
# ============================================
|
||||
# Post-install: refresh icon cache
|
||||
# ============================================
|
||||
rm ~/Library/Application\ Support/Dock/*.db 2>/dev/null || true
|
||||
killall Dock 2>/dev/null || true
|
||||
|
||||
# ============================================
|
||||
# Summary
|
||||
# ============================================
|
||||
echo ""
|
||||
echo -e "${CYAN}╔═══════════════════════════════════════════════════════════╗${NC}"
|
||||
echo -e "${CYAN}║${NC} ✨ GenericAgent Desktop App installed successfully! ${CYAN}║${NC}"
|
||||
echo -e "${CYAN}╚═══════════════════════════════════════════════════════════╝${NC}"
|
||||
echo ""
|
||||
echo -e "${BLUE}Launch methods:${NC}"
|
||||
echo " • Spotlight: Cmd + Space → type 'GenericAgent' → Enter"
|
||||
echo " • Launchpad: Find the 'GenericAgent' icon"
|
||||
echo " • Finder: Open /Applications/GenericAgent.app"
|
||||
echo ""
|
||||
echo -e "${BLUE}First run:${NC}"
|
||||
echo " The app will ask you to select your GenericAgent project folder."
|
||||
echo " It then runs 'python3 launch.pyw' from that directory."
|
||||
echo ""
|
||||
echo -e "${BLUE}Set default project folder:${NC}"
|
||||
echo " Edit /Applications/GenericAgent.app and change the defaultPath property"
|
||||
echo " in Contents/Resources/Scripts/main.scpt (or re-run this installer)."
|
||||
echo ""
|
||||
echo -e "${BLUE}Uninstall:${NC}"
|
||||
echo " rm -rf '/Applications/GenericAgent.app'"
|
||||
echo ""
|
||||
Reference in New Issue
Block a user