diff --git a/bin/ops-gitea.sh b/bin/ops-gitea.sh index 13f76ce9..187095e5 100755 --- a/bin/ops-gitea.sh +++ b/bin/ops-gitea.sh @@ -12,17 +12,47 @@ C='\033[36m' G='\033[32m' Y='\033[33m' -GITEA_URL="${GITEA_URL:-http://143.198.27.163:3000}" -CORE_REPOS="${CORE_REPOS:-Timmy_Foundation/the-nexus Timmy_Foundation/timmy-home Timmy_Foundation/timmy-config Timmy_Foundation/hermes-agent}" - -for token_file in "$HOME/.hermes/gitea_token_vps" "$HOME/.config/gitea/token" "$HOME/.config/gitea/codex-token"; do - if [ -f "$token_file" ]; then - TOKEN=$(cat "$token_file") - break +resolve_gitea_url() { + if [ -n "${GITEA_URL:-}" ]; then + printf '%s\n' "${GITEA_URL%/}" + return 0 fi -done + if [ -f "$HOME/.hermes/gitea_api" ]; then + python3 - "$HOME/.hermes/gitea_api" <<'PY' +from pathlib import Path +import sys -TOKEN="${TOKEN:-}" +raw = Path(sys.argv[1]).read_text().strip().rstrip("/") +print(raw[:-7] if raw.endswith("/api/v1") else raw) +PY + return 0 + fi + if [ -f "$HOME/.config/gitea/base-url" ]; then + tr -d '[:space:]' < "$HOME/.config/gitea/base-url" + return 0 + fi + echo "ERROR: set GITEA_URL or create ~/.hermes/gitea_api" >&2 + return 1 +} + +resolve_ops_token() { + local token_file + for token_file in \ + "$HOME/.config/gitea/timmy-token" \ + "$HOME/.hermes/gitea_token_vps" \ + "$HOME/.hermes/gitea_token_timmy"; do + if [ -f "$token_file" ]; then + tr -d '[:space:]' < "$token_file" + return 0 + fi + done + return 1 +} + +GITEA_URL="$(resolve_gitea_url)" +CORE_REPOS="${CORE_REPOS:-Timmy_Foundation/the-nexus Timmy_Foundation/timmy-home Timmy_Foundation/timmy-config Timmy_Foundation/hermes-agent}" +TOKEN="$(resolve_ops_token || true)" +[ -z "$TOKEN" ] && echo "WARN: no approved Timmy Gitea token found; feed will use unauthenticated API calls" >&2 echo -e "${B}${C} ◈ GITEA WORKFLOW${R} ${D}$(date '+%H:%M:%S')${R}" echo -e "${D}────────────────────────────────────────${R}" diff --git a/bin/ops-helpers.sh b/bin/ops-helpers.sh index f32cfba4..5817b368 100755 --- a/bin/ops-helpers.sh +++ b/bin/ops-helpers.sh @@ -5,15 +5,41 @@ # and do not revive deprecated bash worker loops. # ─────────────────────────────────────────────────────────────────────── -export GITEA="${GITEA:-http://143.198.27.163:3000}" +resolve_gitea_url() { + if [ -n "${GITEA:-}" ]; then + printf '%s\n' "${GITEA%/}" + return 0 + fi + if [ -f "$HOME/.hermes/gitea_api" ]; then + python3 - "$HOME/.hermes/gitea_api" <<'PY' +from pathlib import Path +import sys + +raw = Path(sys.argv[1]).read_text().strip().rstrip("/") +print(raw[:-7] if raw.endswith("/api/v1") else raw) +PY + return 0 + fi + if [ -f "$HOME/.config/gitea/base-url" ]; then + tr -d '[:space:]' < "$HOME/.config/gitea/base-url" + return 0 + fi + echo "ERROR: set GITEA or create ~/.hermes/gitea_api" >&2 + return 1 +} + +export GITEA="$(resolve_gitea_url)" export OPS_DEFAULT_REPO="${OPS_DEFAULT_REPO:-Timmy_Foundation/timmy-home}" export OPS_CORE_REPOS="${OPS_CORE_REPOS:-Timmy_Foundation/the-nexus Timmy_Foundation/timmy-home Timmy_Foundation/timmy-config Timmy_Foundation/hermes-agent}" ops-token() { local token_file - for token_file in "$HOME/.hermes/gitea_token_vps" "$HOME/.config/gitea/token" "$HOME/.config/gitea/codex-token"; do + for token_file in \ + "$HOME/.config/gitea/timmy-token" \ + "$HOME/.hermes/gitea_token_vps" \ + "$HOME/.hermes/gitea_token_timmy"; do if [ -f "$token_file" ]; then - cat "$token_file" + tr -d '[:space:]' < "$token_file" return 0 fi done @@ -264,3 +290,5 @@ ops-assign-codex() { ops-assign "$1" "codex-agent" "${2:-$OPS_DEFAULT_REPO}"; } ops-assign-groq() { ops-assign "$1" "groq" "${2:-$OPS_DEFAULT_REPO}"; } ops-assign-claude() { ops-assign "$1" "claude" "${2:-$OPS_DEFAULT_REPO}"; } ops-assign-ezra() { ops-assign "$1" "ezra" "${2:-$OPS_DEFAULT_REPO}"; } +ops-assign-perplexity() { ops-assign "$1" "perplexity" "${2:-$OPS_DEFAULT_REPO}"; } +ops-assign-kimiclaw() { ops-assign "$1" "KimiClaw" "${2:-$OPS_DEFAULT_REPO}"; } diff --git a/bin/ops-panel.sh b/bin/ops-panel.sh index 6f937cfd..3741a79b 100755 --- a/bin/ops-panel.sh +++ b/bin/ops-panel.sh @@ -18,17 +18,47 @@ OK="${G}●${R}" WARN="${Y}●${R}" FAIL="${RD}●${R}" -GITEA_URL="${GITEA_URL:-http://143.198.27.163:3000}" -CORE_REPOS="${CORE_REPOS:-Timmy_Foundation/the-nexus Timmy_Foundation/timmy-home Timmy_Foundation/timmy-config Timmy_Foundation/hermes-agent}" - -for token_file in "$HOME/.hermes/gitea_token_vps" "$HOME/.config/gitea/token" "$HOME/.config/gitea/codex-token"; do - if [ -f "$token_file" ]; then - TOKEN=$(cat "$token_file") - break +resolve_gitea_url() { + if [ -n "${GITEA_URL:-}" ]; then + printf '%s\n' "${GITEA_URL%/}" + return 0 fi -done + if [ -f "$HOME/.hermes/gitea_api" ]; then + python3 - "$HOME/.hermes/gitea_api" <<'PY' +from pathlib import Path +import sys -TOKEN="${TOKEN:-}" +raw = Path(sys.argv[1]).read_text().strip().rstrip("/") +print(raw[:-7] if raw.endswith("/api/v1") else raw) +PY + return 0 + fi + if [ -f "$HOME/.config/gitea/base-url" ]; then + tr -d '[:space:]' < "$HOME/.config/gitea/base-url" + return 0 + fi + echo "ERROR: set GITEA_URL or create ~/.hermes/gitea_api" >&2 + return 1 +} + +resolve_ops_token() { + local token_file + for token_file in \ + "$HOME/.config/gitea/timmy-token" \ + "$HOME/.hermes/gitea_token_vps" \ + "$HOME/.hermes/gitea_token_timmy"; do + if [ -f "$token_file" ]; then + tr -d '[:space:]' < "$token_file" + return 0 + fi + done + return 1 +} + +GITEA_URL="$(resolve_gitea_url)" +CORE_REPOS="${CORE_REPOS:-Timmy_Foundation/the-nexus Timmy_Foundation/timmy-home Timmy_Foundation/timmy-config Timmy_Foundation/hermes-agent}" +TOKEN="$(resolve_ops_token || true)" +[ -z "$TOKEN" ] && echo "WARN: no approved Timmy Gitea token found; panel will use unauthenticated API calls" >&2 echo "" echo -e " ${B}${M}◈ WORKFLOW OPERATIONS${R} ${D}$(date '+%a %b %d %H:%M:%S')${R}" @@ -75,6 +105,7 @@ import json import sys import urllib.error import urllib.request +from datetime import datetime, timedelta, timezone base = sys.argv[1].rstrip("/") token = sys.argv[2] @@ -155,7 +186,8 @@ for agent, label in queue_agents: print() unassigned = [issue for issue in issues if not issue.get("assignees")] -stale_prs = [pr for pr in pulls if pr.get("updated_at", "")[:10] < "2026-04-02"] +stale_cutoff = (datetime.now(timezone.utc) - timedelta(days=2)).strftime("%Y-%m-%d") +stale_prs = [pr for pr in pulls if pr.get("updated_at", "")[:10] < stale_cutoff] overloaded = [] for agent in ("allegro", "codex-agent", "groq", "claude", "ezra", "perplexity", "KimiClaw"): count = sum(