OSVauco/scripts/boot.sh

247 lines
11 KiB
Bash
Executable File

#!/usr/bin/env bash
# =============================================================================
# boot.sh — OSVauco daily VM session-starter
#
# Bruk: source ~/OSVauco/scripts/boot.sh
# Eller legg i ~/.bashrc:
# [[ $- == *i* && -z "$OSVAUCO_BOOTED" ]] && source ~/OSVauco/scripts/boot.sh
# =============================================================================
export OSVAUCO_BOOTED=1
OSVAUCO_DIR="${OSVAUCO_DIR:-$HOME/OSVauco}"
HANDOFF="$OSVAUCO_DIR/docs/HANDOFF.md"
ROADMAP="$OSVAUCO_DIR/docs/ROADMAP.md"
MASTERPLAN="$OSVAUCO_DIR/docs/MASTERPLAN.md"
RULEBOOK="$OSVAUCO_DIR/docs/AGENT_RULEBOOK.md"
SESSION_LOG="$OSVAUCO_DIR/docs/OSVAUCO_OPAX_SESSION_LOG.md"
# Locked values (matcher docs/AGENT_RULEBOOK.md + MASTERPLAN)
export GOOGLE_CLOUD_PROJECT="propane-will-491900-m5"
export GOOGLE_CLOUD_LOCATION="us-central1"
export VERTEX_AI_LOCATION="us-central1"
export OSVAUCO_SERVICE="osvauco-agent"
DIRECT_URL="https://osvauco-agent-zjbqp3prqq-uc.a.run.app"
DOMAIN_URL="https://opax.vauco.no"
GREEN="$(tput setaf 2 2>/dev/null || true)"
RED="$(tput setaf 1 2>/dev/null || true)"
YELLOW="$(tput setaf 3 2>/dev/null || true)"
CYAN="$(tput setaf 6 2>/dev/null || true)"
MAGENTA="$(tput setaf 5 2>/dev/null || true)"
WHITE="$(tput setaf 7 2>/dev/null || true)"
BOLD="$(tput bold 2>/dev/null || true)"
DIM="$(tput dim 2>/dev/null || true)"
NC="$(tput sgr0 2>/dev/null || true)"
SESSION_ID="$(date '+%Y%m%d-%H%M%S')"
export OSVAUCO_SESSION_ID="$SESSION_ID"
export OSVAUCO_SESSION_START="$(date '+%Y-%m-%d %H:%M %Z')"
ok() { printf " ${GREEN}${NC} %s\n" "$1"; }
warn() { printf " ${YELLOW}${NC} %s\n" "$1"; }
fail() { printf " ${RED}${NC} %s\n" "$1"; }
# =============================================================================
# HEADER — OS VAUCO
# =============================================================================
clear
printf "${CYAN}${BOLD}"
cat << 'LOGO'
___ ____ __ __ _ _ _ ____ ___
/ _ \/ ___| \ \ / /_ _| | | | | |/ ___|/ _ \
| | | \___ \ \ \ / / _` | | | | | | | | | | |
| |_| |___) | \ V / (_| | |__| |_| | |___| |_| |
\___/|____/ \_/ \__,_|____|\___/ \____|\___/
LOGO
printf "${NC}${DIM} Vauco OS · Operasjonsplatform · %s${NC}\n" "$(date '+%Y-%m-%d %H:%M')"
printf "${DIM} ──────────────────────────────────────────────────────${NC}\n\n"
# =============================================================================
# 1. AUTH & CREDENTIALS
# =============================================================================
printf "${BOLD}${CYAN}[ AUTH & CREDENTIALS ]${NC}\n"
# Informativ gcloud CLI-status. Starter aldri login og stopper ikke boot.
if gcloud auth print-access-token >/dev/null 2>&1; then
ACCT=$(gcloud auth list --filter=status:ACTIVE --format='value(account)' 2>/dev/null | head -1)
ok "gcloud CLI-bruker ($ACCT)"
else
warn "gcloud CLI ikke innlogget. Kjør 'gcloud auth login' for manuelle operasjoner."
fi
# Informativ ADC-status. Endrer aldri credentials eller miljøvariabler.
if [[ -n "${GOOGLE_APPLICATION_CREDENTIALS:-}" ]]; then
warn "GOOGLE_APPLICATION_CREDENTIALS er satt. Dette kan overstyre VM-ens standard credentials."
printf " ${DIM}Boot-scriptet endrer ikke denne. For å fjerne: unset GOOGLE_APPLICATION_CREDENTIALS${NC}\n"
else
ok "ADC/runtime: GOOGLE_APPLICATION_CREDENTIALS ikke satt. VM metadata/ADC vil bli brukt."
fi
# =============================================================================
# 2. PROJECT
# =============================================================================
printf "${BOLD}${CYAN}[ PROJECT ]${NC}\n"
CURRENT_PROJ=$(gcloud config get-value project 2>/dev/null)
if [[ "$CURRENT_PROJ" != "$GOOGLE_CLOUD_PROJECT" ]]; then
gcloud config set project "$GOOGLE_CLOUD_PROJECT" >/dev/null 2>&1
warn "Satt project → $GOOGLE_CLOUD_PROJECT"
else
ok "project = $GOOGLE_CLOUD_PROJECT"
fi
ok "region = $GOOGLE_CLOUD_LOCATION (LÅST)"
# =============================================================================
# 3. REPOSITORY STATUS
# =============================================================================
printf "${BOLD}${CYAN}[ REPOSITORY STATUS ]${NC}\n"
if [[ -d "$OSVAUCO_DIR/.git" ]]; then
cd "$OSVAUCO_DIR"
BRANCH=$(git branch --show-current 2>/dev/null || true)
if [[ -n "$BRANCH" ]]; then
ok "Aktiv branch: $BRANCH"
else
warn "Kunne ikke finne aktiv Git-branch"
fi
DIRTY=$(git status --porcelain 2>/dev/null | wc -l | tr -d ' ')
if [[ "$DIRTY" == "0" ]]; then
ok "Working tree: rent"
else
warn "Working tree: $DIRTY lokale endring(er) uten commit"
fi
LAST_COMMIT=$(git log -1 --oneline 2>/dev/null || true)
if [[ -n "$LAST_COMMIT" ]]; then
printf " ${DIM}Siste lokale commit: ${LAST_COMMIT}${NC}\n"
fi
printf " ${DIM}Remote-status kontrolleres ikke automatisk. Ved behov: git fetch origin && git status -sb${NC}\n"
else
fail "Repo ikke funnet på $OSVAUCO_DIR"
fi
# =============================================================================
# 4. LOCKED DEFS
# =============================================================================
printf "${BOLD}${CYAN}[ LOCKED ]${NC}\n"
printf " ${DIM}service=${NC}%s ${DIM}lb=${NC}34.98.77.173\n" "$OSVAUCO_SERVICE"
printf " ${DIM}url=${NC}%s\n" "$DOMAIN_URL"
printf " ${DIM}direct=${NC}%s\n" "$DIRECT_URL"
# =============================================================================
# 5. NESTE OPPGAVE (matcher både "NESTE OPPGAVE" og "Neste oppgave")
# =============================================================================
printf "${BOLD}${CYAN}[ NESTE OPPGAVE ]${NC}\n"
if [[ -f "$HANDOFF" ]]; then
NEXT=$(sed -n '/^##.*[Nn]este [Oo]ppgave/,/^## /p' "$HANDOFF" | sed '1d;$d' | sed '/^$/d' | head -12)
if [[ -n "$NEXT" ]]; then
printf "${GREEN}%s${NC}\n" "$NEXT"
else
warn "Ingen 'Neste oppgave'-seksjon funnet i HANDOFF.md"
fi
else
fail "HANDOFF.md mangler: $HANDOFF"
fi
# =============================================================================
# 6. ALIASER / HOTKEYS
# =============================================================================
alias pf='source $OSVAUCO_DIR/scripts/preflight.sh'
alias hc='bash $OSVAUCO_DIR/scripts/health-check.sh'
alias st='bash $OSVAUCO_DIR/scripts/smoke-test.sh'
alias at='bash $OSVAUCO_DIR/scripts/acceptance-test.sh'
alias opax='source $OSVAUCO_DIR/scripts/opax.sh'
alias opax2='source $OSVAUCO_DIR/scripts/opax2.sh'
alias ca='bash $OSVAUCO_DIR/scripts/cost-audit.sh'
alias cl='bash $OSVAUCO_DIR/scripts/cost-lens.sh'
alias cg='bash $OSVAUCO_DIR/scripts/cost-guard.sh'
alias costs='bash $OSVAUCO_DIR/scripts/cost-lens.sh'
alias ms='bash $OSVAUCO_DIR/scripts/sync-gdrive-mirror.sh'
alias logg='bash $OSVAUCO_DIR/scripts/opax-logg-slutt.sh'
alias rl='${PAGER:-less} $ROADMAP'
alias mp='${PAGER:-less} $MASTERPLAN'
alias ho='${PAGER:-less} $HANDOFF'
alias rb='${PAGER:-less} $RULEBOOK'
alias sl='${PAGER:-less} $SESSION_LOG'
alias osv='cd $OSVAUCO_DIR'
alias reboot-osv='unset OSVAUCO_BOOTED; source $OSVAUCO_DIR/scripts/boot.sh'
alias ghs='gh pr list && gh issue list'
alias trigger='bash $OSVAUCO_DIR/scripts/watch-build.sh'
# sol() — avslutt-funksjon
sol() {
printf "\n ${BOLD}${CYAN}Sesjonsavslutning${NC}\n"
printf " Hva ble gjort? (LØST / ULØST)\n > "; read -r DONE_DESC
[[ -z "$DONE_DESC" ]] && DONE_DESC="(ingen notat)"
printf " Uløste problemer? (Enter for ingen)\n > "; read -r UNSOLVED
[[ -z "$UNSOLVED" ]] && UNSOLVED="ingen"
cat >> "$SESSION_LOG" << EOF
### Sesjonsavslutning $OSVAUCO_SESSION_ID
- Start : $OSVAUCO_SESSION_START
- Slutt : $(date '+%Y-%m-%d %H:%M %Z')
- Gjort : $DONE_DESC
- Uløst : $UNSOLVED
EOF
ok "Logg oppdatert"
cd "$OSVAUCO_DIR"
git add docs/OSVAUCO_OPAX_SESSION_LOG.md 2>/dev/null
if ! git diff --cached --quiet; then
git commit -m "chore(session): logg $OSVAUCO_SESSION_ID$DONE_DESC" -q
git push origin "$(git branch --show-current)" -q && ok "Pushet → GitHub"
fi
}
export -f sol
# =============================================================================
# 7. QUICK COMMANDS-TABELL
# =============================================================================
printf "${DIM}────────────────────────────────────────────────────────────${NC}\n"
printf "${BOLD}HOTKEYS${NC}\n"
printf " %-8s %-22s %-8s %-22s\n" "opax" "Gemini 2.5 Pro TUI" "opax2" "Claude Opus 4.7 TUI"
printf " %-8s %-22s %-8s %-22s\n" "pf" "preflight" "hc" "health-check"
printf " %-8s %-22s %-8s %-22s\n" "st" "smoke-test" "at" "acceptance-test"
printf " %-8s %-22s %-8s %-22s\n" "ca" "cost-audit" "cl" "cost-lens"
printf " %-8s %-22s %-8s %-22s\n" "cg" "cost-guard" "costs" "cost-lens (alias)"
printf " %-8s %-22s %-8s %-22s\n" "mp" "vis MASTERPLAN" "rl" "vis ROADMAP"
printf " %-8s %-22s %-8s %-22s\n" "ho" "vis HANDOFF" "rb" "vis RULEBOOK"
printf " %-8s %-22s %-8s %-22s\n" "sl" "vis SESSION_LOG" "logg" "manuell logg-slutt"
printf " %-8s %-22s %-8s %-22s\n" "ghs" "gh PRs + issues" "ms" "mirror-sync (GDrive)"
printf " %-8s %-22s %-8s %-22s\n" "osv" "cd ~/OSVauco" "sol" "avslutt + commit"
printf " %-8s %-22s\n" "reboot-osv" "kjør boot.sh på nytt"
printf "${DIM}────────────────────────────────────────────────────────────${NC}\n"
# =============================================================================
# 8. NVM
# =============================================================================
export NVM_DIR="$HOME/.nvm"
[[ -s "$NVM_DIR/nvm.sh" ]] && source "$NVM_DIR/nvm.sh"
# =============================================================================
# 9. VALG: opax / opax2 / hopp over
# =============================================================================
printf "\n${BOLD}Hvilken TUI vil du starte?${NC}\n"
printf " ${CYAN}1${NC}) opax — Gemini 2.5 Pro (Vertex us-central1) ${DIM}[default]${NC}\n"
printf " ${MAGENTA}2${NC}) opax2 — Claude Opus 4.7 (Vertex us-central1)\n"
printf " ${DIM}3${NC}) hopp over (jobb i shell)\n"
printf " Velg [1/2/3]: "
read -r CHOICE
case "${CHOICE:-1}" in
1|"")
printf " ${GREEN}→ starter opax (Gemini 2.5 Pro)${NC}\n\n"
source "$OSVAUCO_DIR/scripts/opax.sh"
;;
2)
printf " ${MAGENTA}→ starter opax2 (Claude)${NC}\n\n"
source "$OSVAUCO_DIR/scripts/opax2.sh"
;;
*)
printf " ${DIM}OK — shell ready. Kjør 'opax' eller 'opax2' når du er klar.${NC}\n\n"
;;
esac