fix: narrow macOS app installer per review
This commit is contained in:
44
README.md
44
README.md
@@ -89,6 +89,20 @@ cp mykey_template.py mykey.py
|
|||||||
python launch.pyw
|
python launch.pyw
|
||||||
```
|
```
|
||||||
|
|
||||||
|
#### Method 2: uv (for experienced Python users)
|
||||||
|
|
||||||
|
If you prefer a modern Python workflow, GenericAgent also provides a minimal `pyproject.toml`:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git clone https://github.com/lsdefine/GenericAgent.git
|
||||||
|
cd GenericAgent
|
||||||
|
uv pip install -e ".[ui]" # Core + GUI dependencies
|
||||||
|
cp mykey_template.py mykey.py
|
||||||
|
python launch.pyw
|
||||||
|
```
|
||||||
|
|
||||||
|
> GenericAgent is meant to grow its environment through the Agent itself, not by pre-installing every possible package.
|
||||||
|
|
||||||
Full guide: [GETTING_STARTED.md](GETTING_STARTED.md)
|
Full guide: [GETTING_STARTED.md](GETTING_STARTED.md)
|
||||||
|
|
||||||
---
|
---
|
||||||
@@ -191,10 +205,9 @@ You're also welcome to join our **GenericAgent Community Group** for discussion,
|
|||||||
<div align="center">
|
<div align="center">
|
||||||
<table>
|
<table>
|
||||||
<tr>
|
<tr>
|
||||||
<td align="center"><strong>WeChat Group 6</strong><br><img src="assets/images/wechat_group6.jpg" alt="WeChat Group 6 QR Code" width="250"/></td>
|
|
||||||
<td align="center"><strong>WeChat Group 8</strong><br><img src="assets/images/wechat_group8.jpg" alt="WeChat Group 8 QR Code" width="250"/></td>
|
<td align="center"><strong>WeChat Group 8</strong><br><img src="assets/images/wechat_group8.jpg" alt="WeChat Group 8 QR Code" width="250"/></td>
|
||||||
<td align="center"><strong>WeChat Group 9</strong><br><img src="assets/images/wechat_group9.jpg" alt="WeChat Group 9 QR Code" width="250"/></td>
|
<td align="center"><strong>WeChat Group 9</strong><br><img src="assets/images/wechat_group9.jpg" alt="WeChat Group 9 QR Code" width="250"/></td>
|
||||||
<td align="center"><strong>WeChat Group 10</strong><br><img src="assets/images/wechat_group10.jpg" alt="WeChat Group 10 QR Code" width="250"/></td>
|
<td align="center"><strong>WeChat Group 11</strong><br><img src="assets/images/wechat_group11.jpg" alt="WeChat Group 11 QR Code" width="250"/></td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
@@ -293,6 +306,20 @@ cp mykey_template.py mykey.py
|
|||||||
python launch.pyw
|
python launch.pyw
|
||||||
```
|
```
|
||||||
|
|
||||||
|
#### 方法二:uv 快速安装(熟悉 Python 的用户)
|
||||||
|
|
||||||
|
如果你习惯现代 Python 工作流,GenericAgent 也提供了一个最小化的 `pyproject.toml`:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git clone https://github.com/lsdefine/GenericAgent.git
|
||||||
|
cd GenericAgent
|
||||||
|
uv pip install -e ".[ui]" # 核心 + GUI 依赖
|
||||||
|
cp mykey_template.py mykey.py
|
||||||
|
python launch.pyw
|
||||||
|
```
|
||||||
|
|
||||||
|
> GenericAgent 更推荐由 Agent 在使用中自举环境,而不是预先手动装完整依赖。
|
||||||
|
|
||||||
完整引导流程见 [GETTING_STARTED.md](GETTING_STARTED.md)。
|
完整引导流程见 [GETTING_STARTED.md](GETTING_STARTED.md)。
|
||||||
|
|
||||||
📖 新手使用指南(图文版):[飞书文档](https://my.feishu.cn/wiki/CGrDw0T76iNFuskmwxdcWrpinPb)
|
📖 新手使用指南(图文版):[飞书文档](https://my.feishu.cn/wiki/CGrDw0T76iNFuskmwxdcWrpinPb)
|
||||||
@@ -400,16 +427,6 @@ streamlit run frontends/stapp2.py # 另一种 Streamlit 风格 UI
|
|||||||
- `/continue` - 列出可恢复会话快照
|
- `/continue` - 列出可恢复会话快照
|
||||||
- `/continue N` - 恢复第 `N` 个可恢复会话
|
- `/continue N` - 恢复第 `N` 个可恢复会话
|
||||||
|
|
||||||
### macOS Desktop App (Optional)
|
|
||||||
|
|
||||||
将 GenericAgent 安装为 macOS 原生桌面应用,支持通过 Spotlight、Launchpad 或应用程序文件夹一键启动:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
bash scripts/install-macos-app.sh
|
|
||||||
```
|
|
||||||
|
|
||||||
安装后按 `Cmd + Space` → 输入 "GenericAgent" 即可启动。首次运行会提示选择 GenericAgent 项目文件夹。
|
|
||||||
|
|
||||||
|
|
||||||
## 📊 与同类产品对比
|
## 📊 与同类产品对比
|
||||||
|
|
||||||
@@ -475,10 +492,9 @@ GenericAgent 通过**分层记忆 × 最小工具集 × 自主执行循环**完
|
|||||||
<div align="center">
|
<div align="center">
|
||||||
<table>
|
<table>
|
||||||
<tr>
|
<tr>
|
||||||
<td align="center"><strong>微信群 6</strong><br><img src="assets/images/wechat_group6.jpg" alt="微信群 6 二维码" width="250"/></td>
|
|
||||||
<td align="center"><strong>微信群 8</strong><br><img src="assets/images/wechat_group8.jpg" alt="微信群 8 二维码" width="250"/></td>
|
<td align="center"><strong>微信群 8</strong><br><img src="assets/images/wechat_group8.jpg" alt="微信群 8 二维码" width="250"/></td>
|
||||||
<td align="center"><strong>微信群 9</strong><br><img src="assets/images/wechat_group9.jpg" alt="微信群 9 二维码" width="250"/></td>
|
<td align="center"><strong>微信群 9</strong><br><img src="assets/images/wechat_group9.jpg" alt="微信群 9 二维码" width="250"/></td>
|
||||||
<td align="center"><strong>微信群 10</strong><br><img src="assets/images/wechat_group10.jpg" alt="微信群 10 二维码" width="250"/></td>
|
<td align="center"><strong>微信群 11</strong><br><img src="assets/images/wechat_group11.jpg" alt="微信群 11 二维码" width="250"/></td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
179
assets/install-macos-app.sh
Executable file
179
assets/install-macos-app.sh
Executable file
@@ -0,0 +1,179 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# GenericAgent macOS Desktop App Installation Script
|
||||||
|
#
|
||||||
|
# Usage:
|
||||||
|
# bash assets/install-macos-app.sh [--auto]
|
||||||
|
#
|
||||||
|
# This installer creates a small .app bundle that opens Terminal and runs
|
||||||
|
# `python3 launch.pyw` from the current GenericAgent checkout.
|
||||||
|
|
||||||
|
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 -euo pipefail
|
||||||
|
|
||||||
|
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}"; }
|
||||||
|
|
||||||
|
AUTO_MODE=false
|
||||||
|
for arg in "$@"; do
|
||||||
|
case "$arg" in
|
||||||
|
--auto) AUTO_MODE=true ;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
APP_NAME="GenericAgent"
|
||||||
|
PRIMARY_INSTALL_DIR="/Applications"
|
||||||
|
FALLBACK_INSTALL_DIR="${HOME}/Applications"
|
||||||
|
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
PROJECT_ROOT="$(cd "${SCRIPT_DIR}/.." && pwd)"
|
||||||
|
ICON_PATH="${PROJECT_ROOT}/assets/images/logo.jpg"
|
||||||
|
LAUNCH_SCRIPT="${PROJECT_ROOT}/launch.pyw"
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
if ! command -v python3 >/dev/null 2>&1; then
|
||||||
|
log_error "python3 is not installed."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ ! -f "${LAUNCH_SCRIPT}" ]; then
|
||||||
|
log_error "launch.pyw not found at ${LAUNCH_SCRIPT}"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
project_path_for_applescript="${PROJECT_ROOT}/"
|
||||||
|
project_path_for_applescript="${project_path_for_applescript//\\/\\\\}"
|
||||||
|
project_path_for_applescript="${project_path_for_applescript//\"/\\\"}"
|
||||||
|
|
||||||
|
detect_existing_app() {
|
||||||
|
if [ -d "${PRIMARY_INSTALL_DIR}/${APP_NAME}.app" ]; then
|
||||||
|
echo "${PRIMARY_INSTALL_DIR}/${APP_NAME}.app"
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
if [ -d "${FALLBACK_INSTALL_DIR}/${APP_NAME}.app" ]; then
|
||||||
|
echo "${FALLBACK_INSTALL_DIR}/${APP_NAME}.app"
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
existing_app_path="$(detect_existing_app || true)"
|
||||||
|
if [ -n "${existing_app_path}" ]; then
|
||||||
|
log_warning "${APP_NAME}.app already exists at ${existing_app_path}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "${AUTO_MODE}" = false ]; then
|
||||||
|
echo ""
|
||||||
|
echo "This will install a desktop app that launches GenericAgent"
|
||||||
|
echo "from Spotlight, Launchpad, or the Applications folder."
|
||||||
|
echo ""
|
||||||
|
if [ -n "${existing_app_path}" ]; then
|
||||||
|
read -p "Reinstall ${APP_NAME}.app? (y/N) " -n 1 -r
|
||||||
|
else
|
||||||
|
read -p "Continue? (Y/n) " -n 1 -r
|
||||||
|
fi
|
||||||
|
echo
|
||||||
|
if [ -n "${existing_app_path}" ]; then
|
||||||
|
[[ ! ${REPLY:-} =~ ^[Yy]$ ]] && { echo "Aborted."; exit 0; }
|
||||||
|
else
|
||||||
|
[[ ${REPLY:-} =~ ^[Nn]$ ]] && { echo "Aborted."; exit 0; }
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
TMP_DIR="$(mktemp -d)"
|
||||||
|
trap 'rm -rf "${TMP_DIR}"' EXIT
|
||||||
|
|
||||||
|
log_info "Building ${APP_NAME}.app..."
|
||||||
|
|
||||||
|
cat > "${TMP_DIR}/${APP_NAME}.applescript" <<APPLESCRIPT
|
||||||
|
on run
|
||||||
|
set projectPathStr to "${project_path_for_applescript}"
|
||||||
|
tell application "Terminal"
|
||||||
|
activate
|
||||||
|
do script "cd " & quoted form of projectPathStr & " && python3 launch.pyw"
|
||||||
|
end tell
|
||||||
|
end run
|
||||||
|
APPLESCRIPT
|
||||||
|
|
||||||
|
osacompile -o "${TMP_DIR}/${APP_NAME}.app" "${TMP_DIR}/${APP_NAME}.applescript"
|
||||||
|
|
||||||
|
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"
|
||||||
|
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 icon."
|
||||||
|
fi
|
||||||
|
|
||||||
|
install_bundle() {
|
||||||
|
local install_dir="$1"
|
||||||
|
local destination="${install_dir}/${APP_NAME}.app"
|
||||||
|
mkdir -p "${install_dir}"
|
||||||
|
rm -rf "${destination}"
|
||||||
|
cp -R "${TMP_DIR}/${APP_NAME}.app" "${destination}"
|
||||||
|
}
|
||||||
|
|
||||||
|
install_path=""
|
||||||
|
if install_bundle "${PRIMARY_INSTALL_DIR}" 2>/dev/null; then
|
||||||
|
install_path="${PRIMARY_INSTALL_DIR}/${APP_NAME}.app"
|
||||||
|
else
|
||||||
|
log_warning "Could not write to ${PRIMARY_INSTALL_DIR}; falling back to ${FALLBACK_INSTALL_DIR}"
|
||||||
|
install_bundle "${FALLBACK_INSTALL_DIR}"
|
||||||
|
install_path="${FALLBACK_INSTALL_DIR}/${APP_NAME}.app"
|
||||||
|
fi
|
||||||
|
|
||||||
|
log_success "Installed to: ${install_path}"
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo -e "${CYAN}╔═══════════════════════════════════════════════════════════╗${NC}"
|
||||||
|
echo -e "${CYAN}║${NC} ✨ ${APP_NAME} Desktop App installed successfully! ${CYAN}║${NC}"
|
||||||
|
echo -e "${CYAN}╚═══════════════════════════════════════════════════════════╝${NC}"
|
||||||
|
echo ""
|
||||||
|
echo -e "${BLUE}Launch methods:${NC}"
|
||||||
|
echo " • Spotlight: Cmd + Space → type '${APP_NAME}' → Enter"
|
||||||
|
echo " • Launchpad: Find the '${APP_NAME}' icon"
|
||||||
|
echo " • Finder: Open ${install_path}"
|
||||||
|
echo ""
|
||||||
|
echo -e "${BLUE}Runtime behavior:${NC}"
|
||||||
|
echo " The app uses the current checkout path embedded at install time:"
|
||||||
|
echo " ${PROJECT_ROOT}"
|
||||||
|
echo " If you move the repo later, re-run this installer."
|
||||||
|
echo ""
|
||||||
|
echo -e "${BLUE}Uninstall:${NC}"
|
||||||
|
echo " rm -rf '${install_path}'"
|
||||||
|
echo ""
|
||||||
@@ -1,195 +0,0 @@
|
|||||||
#!/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