#!/usr/bin/env bash set -euo pipefail REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" source "${REPO_ROOT}/lib/jeannie/core.sh" source "${REPO_ROOT}/lib/jeannie/env.sh" source "${REPO_ROOT}/lib/jeannie/toolchain.sh" source "${REPO_ROOT}/lib/jeannie/pimox.sh" print_usage() { cat <<'EOF' Usage: ./jeannie [args] Base, Inventory, And Planning help | -h | --help Show this grouped help. validate Run repo validation checks. inventory-check Validate the canonical homelab inventory. preflight Run non-mutating infrastructure preflight checks. doctor-preapply Run deeper pre-apply safety checks. plan [all|provisioning|cluster|platform|apps|edge] Run OpenTofu plans without applying changes. Build And Bootstrap up Deploy the full homelab pipeline. deploy-gitea Deploy the Debian-hosted Gitea container. deploy-heimdall Deploy the Debian-hosted Heimdall dashboard. deploy-matrix Deploy the Matrix homeserver (Synapse + Element + Postgres). deploy-omniroute Deploy the OmniRoute LLM routing gateway. deploy-hermes Deploy the Hermes agent (git-install + venv + gateway service). bootstrap-gitea-repo Ensure the Gitea repo and SSH key wiring exist. rpi-services Deploy Pi-hole, Unbound, and Uptime Kuma on RPi4. ollama-setup Install/configure Ollama on the Debian host. artifact-cache {status|up|down|instructions} Manage optional Debian artifact caches. blockchain-devnet {status|up|down|logs|rpc} Manage the local Ethereum Anvil devnet. blockchain-test [forge args...] Run Foundry tests for labs/blockchain. blockchain-wallet {instructions|new|address|sign-message} Practice dev wallet and signing workflows. golden-ledger {show|check} Show or validate Pimox golden image versions. Cluster Lifecycle rebuild-cluster Recreate the cluster through the guarded path. stop-cluster Stop Kubernetes and worker VMs without destroy. start-cluster Start Kubernetes and desired worker VMs. workers Manage Pimox/Kubernetes workers. move-prometheus-stack-workers Move monitoring workloads to worker nodes. doctor-versions [--all|--details|--verbose|--json] Check Kubernetes/container tooling versions. Operator View And Reports status [--all|--details|--verbose|--json] Problems-first cascade from host to public URLs. status --heal-plan Build a guarded self-heal plan from status. status --heal Dry-run auto-eligible self-heal actions. scorecard Compact pass/warn/fail operator scorecard. capacity Compact capacity and placement report. capacity-advisor Decide whether to add VMs or fix placement/resources. capacity-limits [namespace] Recommend requests/limits YAML snippets. recover-plan Print disaster recovery order and prerequisites. recover-power [--dry-run] Run or preview post-outage recovery. heal {plan|apply} Plan/apply guarded self-healing actions. incident {list|replay|triage} Classify incident text and suggest read-only next steps. safety-case [--since REF] [PATH...] Generate risk, blast-radius, test, and rollback case. agent-sandbox {check|policy} Classify proposed commands against agent policy. impact [--since REF] [PATH...] Explain affected lab areas before changes. review-last-change [REF] Summarize changed files, impact, validation. map [--dot] Print the homelab dependency map. change-journal {list|path} Show risky-command journal entries. release-snapshot Write a pre-change release snapshot. Observability And GitOps grafana-dashboards {list|apply} List or apply repo-managed Grafana dashboards. gitops-status Print focused Argo CD health and sync status. platform Deploy platform stack only. edge Deploy/check the OCI edge stack only. promote {plan|validate|rollback APP} Run canary promotion gates and rollback plan. cert-check Check public DNS, TLS, and edge URL health. backup-status Check backup and restore-drill freshness. synthetic-checks Run end-to-end service probes. resource-budget Report Kubernetes resource request/limit gaps. route-inventory Report routes and Uptime Kuma coverage. control-plane {status|taint|untaint|pods} Keep normal pods off the Debian control plane. explain |output Explain warnings/errors and fix commands. Recovery And State backup-gitea Back up the Debian-hosted Gitea data. drill-restore Run all restore drills. drill-gitea-restore Run the Gitea restore drill. drill-pihole-restore Run the Pi-hole restore drill. state-backup Back up local OpenTofu state files. Focused Doctors doctor-edge [--all|--details|--verbose|--json] Diagnose edge routing and public exposure. doctor-gitea [--all|--details|--verbose|--json] Diagnose Gitea local/public access. doctor-rpi [--all|--details|--verbose|--json] Diagnose RPi services and DNS. doctor-cluster [--all|--details|--verbose|--json] Diagnose Kubernetes cluster health. Access, Secrets, And Policy access-audit Audit SSH, Gitea, Kubernetes, and Tailscale access. kubeconfig-readonly Create/check read-only kubeconfig material. secrets-init Initialize SOPS/age secret tooling. secrets-check Validate repo-managed secret prerequisites. tailnet-policy-check Validate Tailscale ACL policy as code. fix-debian-docker-root Repair Debian Docker root placement. Apps And Services apps Deploy application stack only. website-translation-model Prepare website translation model support. website-ollama-listen Configure website Ollama access. install-gitea-runner [TOKEN] Install the Gitea Actions runner. openwrt Deploy/check OpenWrt lab config. Security Learning security-scan Run the security scan bundle. security-prepare Prepare defensive security tools. security-zap Run OWASP ZAP checks. security-k8s Run Kubernetes security checks. security-host Run host security checks. security-trivy Run Trivy scans. security-secrets Run secret leak checks. security-nuclei Run Nuclei web checks. security-web Run web security checks. security-logs Review security-relevant logs. security-runtime Check runtime security sensors. security-attack-path Print prioritized attack-path findings. prompt-injection-lab {list|run|show} Run local prompt-injection defense drills. red-blue {plan|run|ledger} Run or plan safe red-team/blue-team loop. AI And Indexing ai-index Build the local homelab RAG index. ai-check Query/check the local AI index. ask [--citations] QUESTION... Find relevant docs/runbooks/commands. ai-evals {list|run|show} Run deterministic Jeannie/RAG eval cases. ai-scheduler {simulate|recommend NAME} Simulate AI workload placement policy. ai-memory {check} Check local RAG index provenance freshness. model-observe {prompts|run|report} Track model behavior over stable prompts. Destructive nuke Guarded cluster state destruction path. EOF } if [[ "${JEANNIE_LIBRARY_MODE:-false}" == "true" ]]; then # shellcheck disable=SC2317 return 0 2>/dev/null || exit 0 fi case "${1:-}" in __up-task) up_task "${2:-}" ;; "" | help | -h | --help) print_usage ;; up) record_change_journal "up" "$@" up ;; plan) plan_homelab "${2:-all}" ;; rebuild-cluster) record_change_journal "rebuild-cluster" "$@" rebuild_cluster ;; stop-cluster) record_change_journal "stop-cluster" "$@" stop_cluster ;; start-cluster) record_change_journal "start-cluster" "$@" start_cluster ;; status) status_report "${@:2}" ;; capacity) capacity_report "$@" ;; capacity-advisor) capacity_advisor "$@" ;; capacity-limits) capacity_limits "$@" ;; recover-plan) recover_plan ;; gitops-status) gitops_status ;; platform) record_change_journal "platform" "$@" require_debian_server "platform" jeannie_log_start "platform" jeannie_step_plan 1 run_step "Platform OpenTofu apply" platform_apply echo "Log: ${JEANNIE_LOG_FILE}" ;; edge) record_change_journal "edge" "$@" edge_apply ;; promote) promote "$@" ;; cert-check) cert_check ;; release-snapshot) record_change_journal "release-snapshot" "$@" release_snapshot ;; backup-status) backup_status ;; synthetic-checks) synthetic_checks ;; resource-budget) resource_budget "$@" ;; control-plane) control_plane "$@" ;; artifact-cache) artifact_cache "$@" ;; blockchain-devnet) blockchain_devnet "$@" ;; blockchain-test) blockchain_test "$@" ;; blockchain-wallet) blockchain_wallet "$@" ;; golden-ledger) golden_ledger "$@" ;; route-inventory) route_inventory ;; explain) explain "$@" ;; recover-power) recover_power "$@" ;; heal) heal "$@" ;; incident) incident_commander "$@" ;; safety-case) safety_case "$@" ;; agent-sandbox) agent_sandbox "$@" ;; scorecard) scorecard ;; grafana-dashboards) grafana_dashboards "$@" ;; workers) workers_manage "$@" ;; change-journal) change_journal "$@" ;; map) homelab_map "$@" ;; validate) validate_homelab ;; access-audit) access_audit ;; kubeconfig-readonly) kubeconfig_readonly ;; apps) record_change_journal "apps" "$@" require_debian_server "apps" jeannie_log_start "apps" jeannie_step_plan 1 run_step "Applications" apps echo "Log: ${JEANNIE_LOG_FILE}" ;; website-translation-model) website_translation_model ;; website-ollama-listen) website_ollama_listen ;; ollama-setup) ollama_setup ;; deploy-gitea) record_change_journal "deploy-gitea" "$@" deploy_gitea ;; deploy-heimdall) record_change_journal "deploy-heimdall" "$@" deploy_heimdall ;; deploy-matrix) record_change_journal "deploy-matrix" "$@" deploy_matrix ;; deploy-omniroute) record_change_journal "deploy-omniroute" "$@" deploy_omniroute ;; deploy-hermes) record_change_journal "deploy-hermes" "$@" deploy_hermes ;; rpi-services) record_change_journal "rpi-services" "$@" deploy_rpi_services ;; bootstrap-gitea-repo) bootstrap_gitea_repo ;; backup-gitea) backup_gitea ;; drill-restore) drill_restore ;; drill-gitea-restore) drill_gitea_restore ;; drill-pihole-restore) drill_pihole_restore ;; install-gitea-runner) install_gitea_runner "${2:-}" ;; move-prometheus-stack-workers) move_prometheus_stack_workers ;; doctor-versions) doctor_versions "${@:2}" ;; doctor-edge) doctor_edge "${@:2}" ;; doctor-gitea) doctor_gitea "${@:2}" ;; doctor-rpi) doctor_rpi "${@:2}" ;; doctor-cluster) doctor_cluster "${@:2}" ;; preflight) homelab_preflight \"full\" ;; doctor-preapply) doctor_preapply ;; inventory-check) inventory_check ;; state-backup) backup_tofu_state ;; fix-debian-docker-root) fix_debian_docker_root ;; secrets-init) secrets_init ;; secrets-check) secrets_check ;; tailnet-policy-check) tailnet_policy_check ;; ai-index) ai_index ;; ai-check) ai_check ;; ask) ask_homelab "$@" ;; ai-evals) ai_evals "$@" ;; ai-scheduler) ai_scheduler "$@" ;; ai-memory) ai_memory "$@" ;; model-observe) model_observe "$@" ;; impact) impact "$@" ;; review-last-change) review_last_change "$@" ;; security-scan) security_scan ;; security-prepare) security_prepare ;; security-zap) security_zap ;; security-k8s) security_k8s ;; security-host) security_host ;; security-trivy) security_trivy ;; security-secrets) security_secrets ;; security-nuclei) security_nuclei ;; security-web) security_web ;; security-logs) security_logs ;; security-runtime) security_runtime ;; security-attack-path) security_attack_path "$@" ;; prompt-injection-lab) prompt_injection_lab "$@" ;; red-blue) red_blue_loop "$@" ;; openwrt) openwrt ;; nuke) record_change_journal "nuke" "$@" require_debian_server "nuke" jeannie_log_start "nuke" jeannie_step_plan 1 run_step "Nuke homelab cluster state" nuke echo "Log: ${JEANNIE_LOG_FILE}" ;; *) printf 'Unknown command: %s\n\n' "$1" >&2 print_usage >&2 exit 1 ;; esac