#!/usr/bin/env bash # Copyright © IQ.Lvbs, apart of Project Teal Lvbs, All Rights Reserved, licensed under https://konn3kt.com/tos set -euo pipefail IQ_RESET='\033[0m' IQ_BOLD='\033[1m' IQ_MUTED='\033[38;5;245m' IQ_RED='\033[38;5;204m' IQ_GREEN='\033[38;5;120m' IQ_CYAN='\033[38;2;38;145;184m' IQ_BLUE='\033[38;2;51;112;176m' IQ_PURPLE='\033[38;5;141m' IQ_PINK='\033[38;5;211m' IQ_ROOT='' IQ_DRY=0 IQ_NO_VERIFY=0 IQ_LOG_FILE='' if [[ ! -t 1 || "${NO_COLOR:-}" != '' ]]; then IQ_RESET='' IQ_BOLD='' IQ_MUTED='' IQ_RED='' IQ_GREEN='' IQ_CYAN='' IQ_BLUE='' IQ_PURPLE='' IQ_PINK='' fi iq_line() { printf '%b%s%b\n' "$IQ_CYAN" '━━━━━━━━━━━━' "$IQ_RESET" } iq_title() { printf '%bI%b%bQ%b%b.%b%bP%b%bilot%b %b%s%b\n' "$IQ_CYAN" "$IQ_RESET" "$IQ_BLUE" "$IQ_RESET" "$IQ_PURPLE" "$IQ_RESET" "$IQ_PINK" "$IQ_RESET" "$IQ_BOLD" "$IQ_RESET" "$IQ_MUTED" "$1" "$IQ_RESET" } iq_ok() { printf ' %b●%b %s\n' "$IQ_GREEN" "$IQ_RESET" "$1" } iq_fail() { printf ' %b●%b %s\n' "$IQ_RED" "$IQ_RESET" "$1" >&2 } iq_note() { printf ' %b●%b %s\n' "$IQ_CYAN" "$IQ_RESET" "$1" } iq_find_root() { local candidate="${IQ_ROOT:-$PWD}" while [[ "$candidate" != / ]]; do if [[ -f "$candidate/launch_openpilot.sh" && -d "$candidate/iqpilot" ]]; then IQ_ROOT="$candidate" return 0 fi candidate="$(cd "$candidate/.." && pwd)" done for candidate in "$HOME/openpilot" /data/openpilot; do if [[ -f "$candidate/launch_openpilot.sh" && -d "$candidate/iqpilot" ]]; then IQ_ROOT="$candidate" return 0 fi done return 1 } iq_require_root() { if ! iq_find_root; then iq_fail 'IQ.Pilot checkout not found. Run this inside the checkout or use --dir PATH.' return 1 fi } iq_run() { local rendered printf -v rendered '%q ' "$@" rendered="${rendered% }" printf '%b›%b %b%s%b\n' "$IQ_PINK" "$IQ_RESET" "$IQ_MUTED" "$rendered" "$IQ_RESET" [[ "$IQ_DRY" = 1 ]] || "$@" } iq_check() { iq_title 'environment check' iq_require_root iq_ok "checkout $IQ_ROOT" command -v git >/dev/null 2>&1 || { iq_fail 'git is not installed'; return 1; } iq_ok "git $(git --version | sed 's/git version //')" command -v python3 >/dev/null 2>&1 || { iq_fail 'python3 is not installed'; return 1; } iq_ok "python $(python3 --version | sed 's/Python //')" if [[ -x "$IQ_ROOT/.venv/bin/python3" ]]; then iq_ok 'venv ready' else iq_note 'venv not created yet — run iq setup' fi } iq_install() { local shell_name rc_file iq_script command shell_name="$(basename "${SHELL:-bash}")" rc_file="$HOME/.${shell_name}rc" [[ "$(uname)" = Darwin && "$shell_name" = bash ]] && rc_file="$HOME/.bash_profile" iq_script="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/iq.sh" command="alias iq='${iq_script} \"\$@\"'" touch "$rc_file" grep -Fqx "$command" "$rc_file" 2>/dev/null || printf '\n%s\n' "$command" >> "$rc_file" iq_title 'command installed' iq_ok "restart your shell, then use iq ${rc_file}" } iq_setup() { local script iq_require_root if [[ -f /AGNOS ]]; then iq_title 'setup' iq_note 'IQ.OS manages system dependencies and the base Python runtime' iq_note 'use iq pkg to synchronize private packages when needed' iq_check return 0 fi case "$OSTYPE" in linux-gnu*) script="$IQ_ROOT/iqpilot/tools/ubuntu_setup.sh" ;; darwin*) script="$IQ_ROOT/iqpilot/tools/mac_setup.sh" ;; *) iq_fail "unsupported platform: $OSTYPE"; return 1 ;; esac iq_title 'setup' iq_run "$script" if command -v git-lfs >/dev/null 2>&1; then iq_run git -C "$IQ_ROOT" lfs pull fi iq_ok 'setup complete' } iq_venv() { iq_require_root [[ -f "$IQ_ROOT/.venv/bin/activate" ]] || { iq_fail 'venv not found — run iq setup first'; return 1; } case "$(basename "${SHELL:-bash}")" in zsh) ZDOTDIR="$(mktemp -d)"; printf 'source %q\nsource %q\n' "$HOME/.zshrc" "$IQ_ROOT/.venv/bin/activate" > "$ZDOTDIR/.zshrc"; exec zsh ;; *) exec bash --rcfile <(printf 'source %q\nsource %q\n' "$HOME/.bashrc" "$IQ_ROOT/.venv/bin/activate") ;; esac } iq_build() { iq_require_root if [[ -f /AGNOS ]]; then iq_run "$IQ_ROOT/iqpilot/system/manager/build.py" else (cd "$IQ_ROOT" && iq_run scons "$@") fi } iq_quality() { iq_require_root (cd "$IQ_ROOT" && iq_run scripts/lint/lint.sh "$@") } iq_pkg() { iq_require_root (cd "$IQ_ROOT" && iq_run python3 iqpilot/tools/scripts/setup_private_packages.py "$@") if [[ -f "$IQ_ROOT/artifacts/runtime/ensure_private_installed.sh" ]]; then (cd "$IQ_ROOT" && iq_run bash artifacts/runtime/ensure_private_installed.sh) fi } iq_status() { local branch commit tree iq_require_root branch="$(git -C "$IQ_ROOT" branch --show-current 2>/dev/null || printf detached)" commit="$(git -C "$IQ_ROOT" rev-parse --short HEAD 2>/dev/null || printf unknown)" tree=clean [[ -n "$(git -C "$IQ_ROOT" status --porcelain 2>/dev/null)" ]] && tree=modified iq_title 'status' iq_note "root $IQ_ROOT" iq_note "branch $branch" iq_note "commit $commit" [[ "$tree" = clean ]] && iq_ok "tree $tree" || iq_note "tree $tree" } iq_switch() { local remote=origin branch iq_require_root [[ $# -ge 1 ]] || { iq_fail 'usage: iq switch [REMOTE] BRANCH'; return 1; } [[ $# -ge 2 ]] && { remote="$1"; shift; } branch="$1" iq_title "switching to $remote/$branch" iq_note 'this discards uncommitted changes and untracked files' iq_run git -C "$IQ_ROOT" fetch "$remote" "$branch:refs/remotes/$remote/$branch" iq_run git -C "$IQ_ROOT" checkout -B "$branch" --track "$remote/$branch" iq_run git -C "$IQ_ROOT" reset --hard "$remote/$branch" iq_run git -C "$IQ_ROOT" clean -df } iq_service() { local action="$1" [[ -f /AGNOS ]] || { iq_note "${action} is available on IQ.OS devices only"; return 0; } iq_run sudo systemctl "$action" comma } iq_help() { iq_title 'command center' printf '%bUsage%b iq [--dir PATH] [--dry] COMMAND\n\n' "$IQ_BOLD" "$IQ_RESET" printf '%bCOMMAND%b\n' "$IQ_PURPLE" "$IQ_RESET" printf ' %bsetup%b install development dependencies\n' "$IQ_CYAN" "$IQ_RESET" printf ' %bcheck%b verify checkout, Git, Python, and venv\n' "$IQ_CYAN" "$IQ_RESET" printf ' %bbuild%b build IQ.Pilot\n' "$IQ_CYAN" "$IQ_RESET" printf ' %bquality%b run code-quality checks\n' "$IQ_CYAN" "$IQ_RESET" printf ' %bpkg%b authenticate and synchronize private packages\n' "$IQ_CYAN" "$IQ_RESET" printf ' %bstatus%b show checkout, branch, commit, and tree state\n' "$IQ_CYAN" "$IQ_RESET" printf ' %bswitch%b replace the checkout with another branch\n' "$IQ_CYAN" "$IQ_RESET" printf ' %bvenv%b open a shell with the project venv active\n' "$IQ_CYAN" "$IQ_RESET" printf ' %bstart%b restart IQ.Pilot on IQ.OS\n' "$IQ_CYAN" "$IQ_RESET" printf ' %bstop%b stop IQ.Pilot on IQ.OS\n' "$IQ_CYAN" "$IQ_RESET" printf ' %binstall%b install the iq shell command\n' "$IQ_CYAN" "$IQ_RESET" printf '\n%bExamples%b\n' "$IQ_PURPLE" "$IQ_RESET" printf ' iq setup iq build -j4 iq pkg\n' iq_line } while [[ $# -gt 0 ]]; do case "$1" in -d|--dir) [[ $# -ge 2 ]] || { iq_fail 'missing path after --dir'; exit 2; }; IQ_ROOT="$2"; shift 2 ;; --dry) IQ_DRY=1; shift ;; -n|--no-verify) IQ_NO_VERIFY=1; shift ;; -l|--log) [[ $# -ge 2 ]] || { iq_fail 'missing file after --log'; exit 2; }; IQ_LOG_FILE="$2"; shift 2 ;; -h|--help|help) iq_help; exit 0 ;; *) break ;; esac done command="${1:-help}" [[ $# -gt 0 ]] && shift case "$command" in help) iq_help ;; setup) iq_setup "$@" ;; check) iq_check "$@" ;; build) iq_build "$@" ;; quality) iq_quality "$@" ;; pkg) iq_pkg "$@" ;; status) iq_status "$@" ;; switch) iq_switch "$@" ;; venv) iq_venv "$@" ;; start) iq_service restart "$@" ;; stop) iq_service stop "$@" ;; install) iq_install "$@" ;; *) iq_fail "unknown command: $command"; iq_help; exit 2 ;; esac