#!/bin/bash set -euo pipefail # satware® CLI Suite Update Script # Version: 1.0.0 # Target: mw-pfeddersheim-workstation (Manjaro/Arch, macOS, Debian) # Source: Workflows/infra.cli-suite-update.md SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" PROJECT_DIR="$(cd "$SCRIPT_DIR/.." && pwd)" CAPS_DIR="$PROJECT_DIR/docs/tech/capabilities" LOG_FILE="$PROJECT_DIR/logs/cli-suite-$(date +%Y%m%d).log" # --- CLI Suite Definition --- # Format: binary_name:package_name (colon-separated if different) PACMAN_TOOLS=(shellcheck fd rg:ripgrep jq bat eza zoxide fzf gum dust btm:bottom syft cosign) NPM_TOOLS=(cline) # --- Helpers --- log() { echo "[$(date '+%H:%M:%S')] $*" | tee -a "$LOG_FILE"; } # Get binary name from entry (before colon, or whole string) bin_name() { echo "${1%%:*}"; } # Get package name from entry (after colon, or whole string) pkg_name() { echo "${1#*:}"; } show_help() { cat </dev/null; then log " ✓ $bin installed" else log " ✗ $bin missing - installing package $pkg..." $CHECK_MODE || sudo pacman -S --noconfirm "$pkg" 2>&1 | tee -a "$LOG_FILE" fi done if [[ "$CHECK_MODE" == false ]]; then log " Updating pacman packages..." PKGS=() for tool in "${PACMAN_TOOLS[@]}"; do PKGS+=("$(pkg_name "$tool")"); done sudo pacman -Syu --noconfirm "${PKGS[@]}" 2>&1 | tee -a "$LOG_FILE" || true fi # --- Section 2: Standalone / Custom Install Tools --- log "[2/5] Standalone tools..." # gh - GitHub CLI if command -v gh &>/dev/null; then log " ✓ gh installed" else log " ✗ gh missing" $CHECK_MODE || sudo pacman -S --noconfirm gh 2>&1 | tee -a "$LOG_FILE" || true fi # tea - Gitea CLI if command -v tea &>/dev/null; then log " ✓ tea installed" else log " ✗ tea missing - install via: pacman -S tea or download from git.satware.ai" fi # glab - GitLab CLI if command -v glab &>/dev/null; then log " ✓ glab installed" else log " ✗ glab missing" $CHECK_MODE || sudo pacman -S --noconfirm glab 2>&1 | tee -a "$LOG_FILE" || true fi # uv - Python package manager if command -v uv &>/dev/null; then log " ✓ uv installed" $CHECK_MODE || uv self update 2>&1 | tee -a "$LOG_FILE" || true else log " ✗ uv missing" $CHECK_MODE || sudo pacman -S --noconfirm uv 2>&1 | tee -a "$LOG_FILE" || true fi # ruff - Python linter if command -v ruff &>/dev/null; then log " ✓ ruff installed" else log " ✗ ruff missing" $CHECK_MODE || sudo pacman -S --noconfirm ruff 2>&1 | tee -a "$LOG_FILE" || true fi # himalaya - Email CLI if command -v himalaya &>/dev/null; then log " ✓ himalaya installed" else log " ✗ himalaya missing" $CHECK_MODE || sudo pacman -S --noconfirm himalaya 2>&1 | tee -a "$LOG_FILE" || true fi # semgrep - Static analysis if command -v semgrep &>/dev/null; then log " ✓ semgrep installed" else log " ✗ semgrep missing - install via: pipx install semgrep" fi # hf - Hugging Face Hub CLI (via pipx) if command -v hf &>/dev/null; then log " ✓ hf installed" else log " ✗ hf missing - install via: pipx install 'huggingface_hub[cli]'" fi # scrot - Screenshot (Linux only) if command -v scrot &>/dev/null; then log " ✓ scrot installed" else log " ✗ scrot missing" $CHECK_MODE || sudo pacman -S --noconfirm scrot 2>&1 | tee -a "$LOG_FILE" || true fi # --- Section 3: npm Global Tools --- log "[3/5] npm global tools..." for tool in "${NPM_TOOLS[@]}"; do if command -v "$tool" &>/dev/null; then log " ✓ $tool installed" $CHECK_MODE || npm update -g "$tool" 2>&1 | tee -a "$LOG_FILE" || true else log " ✗ $tool missing - installing..." $CHECK_MODE || npm install -g "$tool" 2>&1 | tee -a "$LOG_FILE" fi done # --- Section 4: Go/Custom Tools --- log "[4/5] Go/custom tools..." # nuclei - Vulnerability scanner if command -v nuclei &>/dev/null; then log " ✓ nuclei installed" else log " ✗ nuclei missing - install via: go install or download release" fi # --- Section 5: Summary --- log "[5/5] Installation summary..." INSTALLED=0 MISSING=0 ALL_TOOLS=(shellcheck fd rg jq bat eza zoxide fzf gum dust btm scrot gh tea ruff uv glab himalaya semgrep syft cosign nuclei hf cline) for tool in "${ALL_TOOLS[@]}"; do if command -v "$tool" &>/dev/null; then INSTALLED=$((INSTALLED + 1)) else MISSING=$((MISSING + 1)) log " MISSING: $tool" fi done log "Result: ${INSTALLED}/${#ALL_TOOLS[@]} tools installed, ${MISSING} missing" # --- Capability Discovery --- if [[ "$DISCOVER_MODE" == true ]]; then log "=== Capability Discovery ===" # Capture help output for key tools for tool in uv glab gh tea ruff; do if command -v "$tool" &>/dev/null; then OUTFILE="$CAPS_DIR/${tool}-help.txt" log " Capturing $tool help -> $OUTFILE" ${tool} --help > "$OUTFILE" 2>&1 || true fi done # Capture subcommand help for tools with complex CLIs for sub in "uv audit" "uv pip" "glab mcp" "glab ci" "gh api" "tea login"; do CMD_ARRAY=($sub) OUTFILE="$CAPS_DIR/${sub// /-}-help.txt" log " Capturing '$sub' help -> $OUTFILE" "${CMD_ARRAY[@]}" --help > "$OUTFILE" 2>&1 || true done log "Capability discovery complete. Files in $CAPS_DIR/" fi log "=== CLI Suite Update Finished ==="