#!/usr/bin/env bash set -euo pipefail ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" WEB_SRC_DIR="$ROOT_DIR/web/src" PYTHON_BIN="$ROOT_DIR/.venv/bin/python" APP_NAME="${APP_NAME:-$(basename "$ROOT_DIR")}" if [[ ! -x "$PYTHON_BIN" ]]; then echo "Missing virtual environment. Run ./run.sh --setup-only first." >&2 exit 1 fi "$PYTHON_BIN" -m pip install -q pyinstaller TS="$(date +%Y%m%d-%H%M%S)" OUT_ROOT="$ROOT_DIR/dist-standalone/$TS" DIST_PATH="$OUT_ROOT/dist" WORK_PATH="$OUT_ROOT/build" SPEC_PATH="$OUT_ROOT/spec" mkdir -p "$DIST_PATH" "$WORK_PATH" "$SPEC_PATH" PYI_ARGS=( --noconfirm --windowed --name "$APP_NAME" --distpath "$DIST_PATH" --workpath "$WORK_PATH" --specpath "$SPEC_PATH" --add-data "$WEB_SRC_DIR/app.py:." --collect-all streamlit --collect-all streamlit_autorefresh --hidden-import yfinance --hidden-import pandas --collect-all plotly ) for source_dir in "$WEB_SRC_DIR"/*; do source_name="$(basename "$source_dir")" if [[ ! -d "$source_dir" ]]; then continue fi if [[ "$source_name" == "tests" ]] || [[ "$source_name" == "__pycache__" ]]; then continue fi PYI_ARGS+=(--add-data "$source_dir:$source_name") done if [[ -f "$WEB_SRC_DIR/ONBOARDING.md" ]]; then PYI_ARGS+=(--add-data "$WEB_SRC_DIR/ONBOARDING.md:.") fi "$PYTHON_BIN" -m PyInstaller "${PYI_ARGS[@]}" "$WEB_SRC_DIR/desktop_launcher.py" APP_BUNDLE="$DIST_PATH/${APP_NAME}.app" if [[ ! -d "$APP_BUNDLE" ]]; then echo "Build failed: ${APP_BUNDLE} not found" >&2 exit 1 fi echo "Standalone app created: $APP_BUNDLE" echo "To build DMG from this app:" echo "APP_BUNDLE_PATH=\"$APP_BUNDLE\" ./scripts/create_installer_dmg.sh"