4e0ab94ee2
- Added start-llama-server.bat with cross-brand GPU auto-detection: * Detection 1: nvidia-smi for NVIDIA * Detection 2: WMIC for AMD, Intel Arc, Intel HD/Iris/UHD * Detection 3: vulkaninfo as final fallback probe * Falls back to CPU-only build when no GPU found - Downloaded llama-server b9947 builds: * Vulkan build (91 MB) - supports all GPU brands * CPU build (45 MB) - fallback in cpu/ subdir - Downloaded Qwen2.5-Coder-1.5B Q4_K_M model (1.1 GB) - Fixed run-hermes.bat polling: replaces fixed 5s timeout with curl-based readiness polling (up to 30 attempts, 1s apart) - All .bat files verified: ASCII text, CRLF line terminators - Added .gitignore for build artifacts and large binaries
251 lines
10 KiB
Bash
Executable File
251 lines
10 KiB
Bash
Executable File
#!/bin/sh
|
||
# ==============================================================================
|
||
# Hermes Portable Rescue — Auto-Launch Script (Source)
|
||
# ==============================================================================
|
||
#
|
||
# This is the master auto-launch script for the Hermes Portable Rescue USB.
|
||
# It runs when the rescue environment boots and orchestrates the entire
|
||
# diagnostic workflow.
|
||
#
|
||
# Design:
|
||
# - Detects the boot filesystem and mounts the Hermes partition
|
||
# - Creates a report directory and starts logging
|
||
# - Runs diagnostics in dependency order (inventory → analysis → fix)
|
||
# - Launches the Hermes agent for LLM-powered interpretation
|
||
# - Falls back to a diagnostic shell if the agent isn't available
|
||
#
|
||
# Environment variables (set by build/usb-image.sh or the boot environment):
|
||
# HERMES_DIR — Root of the Hermes runtime filesystem
|
||
# CONFIG — Path to config.yaml
|
||
# REPORT_DIR — Where to save diagnostic reports
|
||
# BOOT_MODE — 'live' (default), 'safe', 'recovery'
|
||
#
|
||
# ==============================================================================
|
||
|
||
set -e
|
||
|
||
# ─── Configuration ────────────────────────────────────────────────────────────
|
||
|
||
HERMES_DIR="${HERMES_DIR:-/hermes}"
|
||
CONFIG="${CONFIG:-${HERMES_DIR}/config.yaml}"
|
||
REPORT_DIR="${REPORT_DIR:-${HERMES_DIR}/reports}"
|
||
LOG_FILE="${LOG_FILE:-${REPORT_DIR}/session.log}"
|
||
BOOT_MODE="${BOOT_MODE:-live}"
|
||
|
||
# ─── Utility Functions ────────────────────────────────────────────────────────
|
||
|
||
timestamp() {
|
||
date "+%Y-%m-%d %H:%M:%S"
|
||
}
|
||
|
||
log() {
|
||
local level="$1"
|
||
shift
|
||
echo "[$(timestamp)] [${level}] $*" | tee -a "${LOG_FILE}"
|
||
}
|
||
|
||
info() { log "INFO" "$@"; }
|
||
warn() { log "WARN" "$@" >&2; }
|
||
error() { log "ERROR" "$@" >&2; }
|
||
|
||
# ─── Banner ────────────────────────────────────────────────────────────────────
|
||
|
||
print_banner() {
|
||
cat << 'BANNER'
|
||
|
||
╔═══════════════════════════════════════════════════════════════╗
|
||
║ ║
|
||
║ ██╗ ██╗███████╗██████╗ ███╗ ███╗ ║
|
||
║ ██║ ██║██╔════╝██╔══██╗████╗ ████║ ║
|
||
║ ███████║█████╗ ██████╔╝██╔████╔██║ ║
|
||
║ ██╔══██║██╔══╝ ██╔══██╗██║╚██╔╝██║ ║
|
||
║ ██║ ██║███████╗██║ ██║██║ ╚═╝ ██║ ║
|
||
║ ╚═╝ ╚═╝╚══════╝╚═╝ ╚═╝╚═╝ ╚═╝ ║
|
||
║ ║
|
||
║ ┌─────────┐ ┌──────────┐ ┌──────────────────┐ ║
|
||
║ │ SCAN │→ │ ANALYZE │→ │ RECOMMEND/FIX │ ║
|
||
║ └─────────┘ └──────────┘ └──────────────────┘ ║
|
||
║ ║
|
||
║ Hermes Portable Rescue v1.0.0 ║
|
||
║ AI-driven Windows PC diagnostic & repair toolkit ║
|
||
║ ║
|
||
╚═══════════════════════════════════════════════════════════════╝
|
||
BANNER
|
||
}
|
||
|
||
# ─── Filesystem Setup ─────────────────────────────────────────────────────────
|
||
|
||
mount_windows_partition() {
|
||
local windows_mount="/mnt/c"
|
||
mkdir -p "${windows_mount}" 2>/dev/null || true
|
||
|
||
# Try common Windows partitions
|
||
for device in /dev/sda1 /dev/sda2 /dev/nvme0n1p1 /dev/nvme0n1p2 /dev/mmcblk0p1; do
|
||
if [ -b "${device}" ]; then
|
||
local fstype
|
||
fstype="$(blkid -o value -s TYPE "${device}" 2>/dev/null || echo '')"
|
||
case "${fstype}" in
|
||
ntfs)
|
||
if mount -t ntfs-3g "${device}" "${windows_mount}" 2>/dev/null; then
|
||
info "Mounted Windows partition: ${device} → ${windows_mount}"
|
||
return 0
|
||
fi
|
||
;;
|
||
ext4|vfat)
|
||
# Not a Windows partition (or could be EFI system partition)
|
||
;;
|
||
esac
|
||
fi
|
||
done
|
||
|
||
warn "No Windows partition found."
|
||
return 1
|
||
}
|
||
|
||
# ─── Diagnostic Pipeline ──────────────────────────────────────────────────────
|
||
|
||
run_script() {
|
||
local script="$1"
|
||
local report_name="$2"
|
||
local report_file="${REPORT_DIR}/${report_name}"
|
||
|
||
if [ ! -f "${script}" ]; then
|
||
warn "Script not found: ${script}"
|
||
return 1
|
||
fi
|
||
|
||
info "Running: ${script}"
|
||
if python3 "${script}" > "${report_file}" 2>&1; then
|
||
info " ✓ ${report_name} complete (exit 0)"
|
||
return 0
|
||
else
|
||
local rc=$?
|
||
if [ "${rc}" -eq 1 ]; then
|
||
# Component unavailable (stub)
|
||
info " ∼ ${report_name}: component unavailable"
|
||
elif [ "${rc}" -eq 2 ]; then
|
||
# Error during diagnosis
|
||
warn " ✗ ${report_name}: diagnostic error (exit ${rc})"
|
||
else
|
||
warn " ✗ ${report_name}: failed with exit code ${rc}"
|
||
fi
|
||
return ${rc}
|
||
fi
|
||
}
|
||
|
||
run_diagnostics() {
|
||
info "Starting diagnostic pipeline..."
|
||
echo "───────────────────────────────────────────────────────" >> "${LOG_FILE}"
|
||
|
||
# Phase 1: Hardware inventory (independent, runs first)
|
||
run_script "${HERMES_DIR}/scripts/hardware.py" "01-hardware.txt"
|
||
|
||
# Phase 2: BSOD analysis (needs hardware inventory context)
|
||
run_script "${HERMES_DIR}/scripts/bsod.py" "02-bsod-analysis.txt"
|
||
|
||
# Phase 3: Driver update check (needs hardware inventory)
|
||
run_script "${HERMES_DIR}/scripts/drivers.py" "03-drivers.txt"
|
||
|
||
# Phase 4: Stress testing (manual/safe mode only)
|
||
if [ "${BOOT_MODE}" = "recovery" ]; then
|
||
info "Skipping stress tests in recovery mode."
|
||
elif grep -q '"enabled": true' "${CONFIG}" 2>/dev/null || [ -n "${RUN_STRESS_TESTS}" ]; then
|
||
run_script "${HERMES_DIR}/scripts/stress.py" "04-stress.txt"
|
||
else
|
||
info "Stress tests disabled (enable in config or set RUN_STRESS_TESTS=1)"
|
||
fi
|
||
|
||
# Phase 5: Backup/restore (manual activation) — stub placeholder
|
||
# if [ -n "${RUN_BACKUP}" ]; then
|
||
# run_script "${HERMES_DIR}/scripts/backup.py" "05-backup.txt"
|
||
# fi
|
||
|
||
echo "───────────────────────────────────────────────────────" >> "${LOG_FILE}"
|
||
info "Diagnostic pipeline complete."
|
||
}
|
||
|
||
# ─── Agent Launch ─────────────────────────────────────────────────────────────
|
||
|
||
launch_agent() {
|
||
info "Starting Hermes agent..."
|
||
|
||
if [ -f "${HERMES_DIR}/agent/hermes" ]; then
|
||
exec "${HERMES_DIR}/agent/hermes" --config "${CONFIG}"
|
||
elif command -v hermes &>/dev/null; then
|
||
exec hermes --config "${CONFIG}"
|
||
else
|
||
error "Hermes agent not found on PATH or in ${HERMES_DIR}/agent/."
|
||
return 1
|
||
fi
|
||
}
|
||
|
||
start_diagnostic_shell() {
|
||
cat << 'SHELL'
|
||
|
||
╔═══════════════════════════════════════════════════════════════╗
|
||
║ DIAGNOSTIC SHELL ║
|
||
║ Hermes agent not available — running in manual mode. ║
|
||
╚═══════════════════════════════════════════════════════════════╝
|
||
|
||
Available diagnostic scripts:
|
||
|
||
python3 /hermes/scripts/hardware.py — Hardware inventory
|
||
python3 /hermes/scripts/bsod.py — BSOD minidump analysis
|
||
python3 /hermes/scripts/drivers.py — Driver scanner
|
||
python3 /hermes/scripts/stress.py — Stress testing
|
||
python3 /hermes/scripts/backup.py — Backup/restore
|
||
|
||
Reports saved to: /hermes/reports/
|
||
|
||
Type 'exit' to shut down.
|
||
|
||
SHELL
|
||
exec /bin/sh
|
||
}
|
||
|
||
# ─── Main ─────────────────────────────────────────────────────────────────────
|
||
|
||
main() {
|
||
print_banner
|
||
|
||
# Ensure report dir exists
|
||
mkdir -p "${REPORT_DIR}"
|
||
|
||
info "Hermes Portable Rescue v1.0.0 — Boot mode: ${BOOT_MODE}"
|
||
info "Config: ${CONFIG}"
|
||
info "Reports: ${REPORT_DIR}"
|
||
info "Log: ${LOG_FILE}"
|
||
echo ""
|
||
|
||
# Optional: mount Windows partition for access to minidumps, etc.
|
||
if [ "${MOUNT_WINDOWS}" != "no" ]; then
|
||
mount_windows_partition || true
|
||
fi
|
||
|
||
# Run diagnostic pipeline
|
||
if [ "${SKIP_DIAGNOSTICS}" != "1" ]; then
|
||
run_diagnostics
|
||
fi
|
||
|
||
# Print report summary
|
||
if [ -d "${REPORT_DIR}" ]; then
|
||
echo ""
|
||
info "Diagnostic reports:"
|
||
for report in "${REPORT_DIR}"/*.txt; do
|
||
if [ -f "${report}" ]; then
|
||
local rname
|
||
rname=$(basename "${report}")
|
||
echo " ${rname} ($(wc -l < "${report}") lines)"
|
||
fi
|
||
done
|
||
echo ""
|
||
fi
|
||
|
||
# Launch agent or fall back to diagnostic shell
|
||
if ! launch_agent; then
|
||
start_diagnostic_shell
|
||
fi
|
||
}
|
||
|
||
main "$@"
|