#!/usr/bin/env bash # Hermit Desktop — official local dev entry (engine preferred). # # Required for real turns: # - libcstcore.a at repo root (auto-enables --features engine), OR HERMIT_FEATURES=engine # - DEEPSEEK_API_KEY in the environment, OR set the key in Settings after launch # # Host-only (no engine): HERMIT_FEATURES=host ./run-dev.sh # Composer will refuse send until engine is available (no silent mock product path). # UI mock turns (browser/host demos only): localStorage hermit.allowMock=1 or VITE_HERMIT_ALLOW_MOCK=1 # # Hand-check: new session → type → streaming assistant → Stop → reopen session has history set -euo pipefail cd "$(dirname "$0")" # 补 PKG_CONFIG_PATH(勿整文件 source set-environment:会撞 set -u) if [[ -z "${PKG_CONFIG_PATH:-}" ]]; then if [[ -f /etc/set-environment ]]; then PKG_CONFIG_PATH="$(set +u; . /etc/set-environment >/dev/null; printf '%s' "${PKG_CONFIG_PATH:-}")" export PKG_CONFIG_PATH fi fi if [[ -z "${PKG_CONFIG_PATH:-}" ]]; then echo "hermit-dev: PKG_CONFIG_PATH 为空。请用 hermit-tauri-dev 或 nixos-rebuild 后重开终端" >&2 exit 1 fi if ! pkg-config --exists webkit2gtk-4.1 gdk-pixbuf-2.0 2>/dev/null; then echo "hermit-dev: 缺少 webkit/gdk-pixbuf .pc" >&2 exit 1 fi unset WEBKIT_DISABLE_COMPOSITING_MODE || true if [[ -f /proc/driver/nvidia/version ]]; then export __NV_DISABLE_EXPLICIT_SYNC="${__NV_DISABLE_EXPLICIT_SYNC:-1}" # X11/XWayland 上 WebKit DMABUF →「Failed to create GBM buffer」→ 空白灰窗 # 必须关 DMABUF;Wayland 原生则可只靠 __NV_DISABLE_EXPLICIT_SYNC if [[ -n "${WAYLAND_DISPLAY:-}" || "${XDG_SESSION_TYPE:-}" == wayland ]]; then export GDK_BACKEND="${GDK_BACKEND:-x11}" fi if [[ "${GDK_BACKEND:-}" == x11 ]]; then export WEBKIT_DISABLE_DMABUF_RENDERER="${WEBKIT_DISABLE_DMABUF_RENDERER:-1}" else unset WEBKIT_DISABLE_DMABUF_RENDERER || true fi fi export TAURI_DEV_HOST="${TAURI_DEV_HOST:-127.0.0.1}" # Optional real engine (libcstcore). Example: # HERMIT_FEATURES=engine ./run-dev.sh # # or: # HERMIT_CORE_LIB=$PWD/../../libcstcore.a \ # HERMIT_CORE_INCLUDE=$PWD/../../include \ # npm run tauri -- dev -- --features engine TAURI_EXTRA=() ROOT="$(cd ../.. && pwd)" # Auto-enable engine when libcstcore.a exists, unless HERMIT_FEATURES=host if [[ "${HERMIT_FEATURES:-}" == *engine* ]] || { [[ "${HERMIT_FEATURES:-}" != *host* ]] && [[ -f "$ROOT/libcstcore.a" ]] }; then export HERMIT_CORE_LIB="${HERMIT_CORE_LIB:-$ROOT/libcstcore.a}" export HERMIT_CORE_INCLUDE="${HERMIT_CORE_INCLUDE:-$ROOT/include}" if [[ -f "$HERMIT_CORE_LIB" ]]; then # NixOS: -lcurl needs an explicit libdir (pkg-config or ldd). if [[ -z "${HERMIT_CURL_LIBDIR:-}" ]]; then if pkg-config --exists libcurl 2>/dev/null; then HERMIT_CURL_LIBDIR="$(pkg-config --variable=libdir libcurl 2>/dev/null || true)" fi if [[ -z "${HERMIT_CURL_LIBDIR:-}" ]] && command -v curl >/dev/null 2>&1; then curl_so="$(ldd "$(command -v curl)" 2>/dev/null | awk '/libcurl\.so/ { print $3; exit }' || true)" if [[ -n "${curl_so:-}" && -e "$curl_so" ]]; then HERMIT_CURL_LIBDIR="$(dirname "$curl_so")" fi fi if [[ -n "${HERMIT_CURL_LIBDIR:-}" ]]; then export HERMIT_CURL_LIBDIR export LD_LIBRARY_PATH="${HERMIT_CURL_LIBDIR}${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}" fi fi echo "hermit-dev: engine feature HERMIT_CORE_LIB=$HERMIT_CORE_LIB curl=${HERMIT_CURL_LIBDIR:-default}" >&2 TAURI_EXTRA+=(--features engine) else echo "hermit-dev: engine requested but missing $HERMIT_CORE_LIB (host mock)" >&2 fi fi for p in 1420 1421; do if command -v fuser >/dev/null 2>&1; then fuser -k "${p}/tcp" 2>/dev/null || true else mapfile -t pids < <(ss -ltnp 2>/dev/null | awk -v p=":$p" '$4 ~ p { if (match($0, /pid=[0-9]+/)) { print substr($0, RSTART+4, RLENGTH-4) } }' | sort -u) for pid in "${pids[@]:-}"; do [[ -n "${pid:-}" ]] && kill "$pid" 2>/dev/null || true done fi done sleep 0.3 if [[ -z "${DEEPSEEK_API_KEY:-}" && -z "${OPENAI_API_KEY:-}" ]]; then echo "hermit-dev: note — no DEEPSEEK_API_KEY/OPENAI_API_KEY in env; set one or paste key in Settings" >&2 fi if printf '%s\n' "${TAURI_EXTRA[@]:-}" | grep -qx -- '--features' && printf '%s\n' "${TAURI_EXTRA[@]:-}" | grep -qx engine; then echo "hermit-dev: mode=engine (libcstcore)" >&2 elif printf '%s\n' "${TAURI_EXTRA[@]:-}" | grep -q engine; then echo "hermit-dev: mode=engine (libcstcore)" >&2 else echo "hermit-dev: mode=host (Composer send disabled until engine)" >&2 fi echo "hermit-dev: GDK_BACKEND=${GDK_BACKEND:-none} DMABUF_OFF=${WEBKIT_DISABLE_DMABUF_RENDERER:-0} NV_SYNC=${__NV_DISABLE_EXPLICIT_SYNC:-0} host=${TAURI_DEV_HOST}" >&2 exec npm run tauri -- dev "${TAURI_EXTRA[@]}" "$@"