From 6a12c3d0f9220623c1eb04b461f5cd17a1174bdd Mon Sep 17 00:00:00 2001 From: Bryan Johnson Date: Wed, 27 May 2026 18:07:53 -0700 Subject: [PATCH] v0.7.4: drop GitHub fallback from auto-update (single-source Gitea) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The v0.7.2 GitHub fallback is now functionally broken: the GitHub mirror is being made private, so anonymous raw fetches return 401/403. Rather than ship a silent-failure path to a dead URL, remove the fallback entirely. Changes: larry.sh - LARRY_BASE_URL_FALLBACK / LARRY_ORIGIN_DEFAULT_GITHUB removed - sync_from_manifest_with_fallback and _fetch_with_fallback retained by name (call-site compat) but are now single-source wrappers; on origin unreachable they warn "auto-update skipped this launch" and proceed with locally cached files (no crash) - status-line _origin_badge collapses to "" (default) or "custom" (user-pinned HTTPS URL); legacy github / fallback badges gone - /origin slash command simplified: /origin show effective origin + pin file /origin gitea pin to the default Gitea URL /origin auto clear the pin /origin pin to an arbitrary HTTPS mirror /origin github returns a clear error (mirror is private) - /help text updated to reflect single-source model - LARRY_VERSION 0.7.3 -> 0.7.4 install-larry.sh - LARRY_BASE_URL_FALLBACK removed; single-origin install path - fetch() dies with a clear error when origin unreachable: "install failed: cannot reach LARRY_BASE_URL=... — verify the URL or set LARRY_BASE_URL to a reachable mirror" - post-install fallback-warning block removed VERSION: 0.7.3 -> 0.7.4 Migration: stale $LARRY_HOME/.origin files containing the legacy keyword "github" are treated as invalid — Larry warns once at startup and reverts to the default Gitea origin. We deliberately do NOT auto-rewrite the file (so the user can choose) and do NOT translate it to the GitHub raw URL (which would just 401 on the next fetch). Verification: - bash -n larry.sh / install-larry.sh: pass - larry --version: prints 0.7.4 - LARRY_BASE_URL=https://invalid.example.invalid + stale .last-sync-version: logs "warn: ... unreachable, auto-update skipped this launch", no crash - /origin auto clears pin file; /origin (no arg) shows current effective origin and pin file; /origin persisted; /origin github returns clear error; /origin gitea re-pins to default - stale .origin containing "github" -> startup warn + revert to default Co-Authored-By: Claude Opus 4.7 --- VERSION | 2 +- install-larry.sh | 46 ++++------- larry.sh | 201 ++++++++++++++++++++--------------------------- 3 files changed, 102 insertions(+), 147 deletions(-) diff --git a/VERSION b/VERSION index f38fc53..0a1ffad 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.7.3 +0.7.4 diff --git a/install-larry.sh b/install-larry.sh index dc8e559..cff8d35 100755 --- a/install-larry.sh +++ b/install-larry.sh @@ -15,16 +15,16 @@ set -eu LARRY_HOME="${LARRY_HOME:-$HOME/.larry}" -# Canonical hosting (v0.7.2+): self-hosted Gitea at git.bjnoela.com is primary; -# bojj27/cloverleaf-larry on GitHub is the unauthenticated fallback used when -# Gitea is unreachable (DNS failure, repo set to private, server down, etc.). -# Override either via env if you fork or mirror elsewhere. +# Canonical hosting (v0.7.4): self-hosted Gitea at git.bjnoela.com is the +# single source. The v0.7.2 GitHub fallback was removed after the GitHub +# mirror was made private (anonymous raw fetches now 401/403, so the +# fallback was functionally broken). Override LARRY_BASE_URL via env if you +# fork or mirror elsewhere. # -# IMPORTANT: the Gitea repo must be set to PUBLIC for unauthenticated raw-URL -# reads to succeed. Until Bryan toggles repo visibility, the installer (and -# auto-update) will silently fall back to GitHub. +# IMPORTANT: the Gitea repo must be PUBLIC for unauthenticated raw-URL reads +# to succeed. If the install fetch fails, set LARRY_BASE_URL to a reachable +# mirror or check repo visibility on git.bjnoela.com. LARRY_BASE_URL="${LARRY_BASE_URL:-https://git.bjnoela.com/bryan/cloverleaf-larry/raw/branch/main}" -LARRY_BASE_URL_FALLBACK="${LARRY_BASE_URL_FALLBACK:-https://raw.githubusercontent.com/bojj27/cloverleaf-larry/main}" LARRY_BIN_DIR="${LARRY_BIN_DIR:-$HOME/bin}" C_RESET=$'\033[0m'; C_BOLD=$'\033[1m'; C_GREEN=$'\033[32m' @@ -76,34 +76,21 @@ ok "created $LARRY_HOME" # ───────────────────────────────────────────────────────────────────────────── SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]:-$0}")" 2>/dev/null && pwd)" || SCRIPT_DIR="" -# v0.7.2: install-larry.sh is the FIRST contact with the origin — it runs -# before larry.sh exists, so it has to do its own primary→fallback dance. -# Mirrors larry.sh's _fetch_with_fallback behavior; on every fetch, try -# primary first, then fallback if the primary curl exits non-zero or the -# resulting file is empty. Records the winning origin in $LAST_FETCH_ORIGIN -# so the post-install summary can tell Bryan which side served the install. -LAST_FETCH_ORIGIN="" +# v0.7.4 single-source: install-larry.sh is the FIRST contact with the +# origin — it runs before larry.sh exists, so it must succeed in one shot. +# No fallback; if $LARRY_BASE_URL is unreachable we die with a clear error +# telling the user to verify the URL or set an alternate mirror. fetch() { # $1 = remote relative path, $2 = local destination if [ -n "$LARRY_BASE_URL" ]; then say "fetching $1" if curl -fsSL --max-time 30 "$LARRY_BASE_URL/$1" -o "$2" 2>/dev/null && [ -s "$2" ]; then - LAST_FETCH_ORIGIN="primary" ok "$2" return 0 fi rm -f "$2" - if [ -n "${LARRY_BASE_URL_FALLBACK:-}" ] && [ "$LARRY_BASE_URL_FALLBACK" != "$LARRY_BASE_URL" ]; then - warn "primary unreachable for $1 — trying fallback" - if curl -fsSL --max-time 30 "$LARRY_BASE_URL_FALLBACK/$1" -o "$2" 2>/dev/null && [ -s "$2" ]; then - LAST_FETCH_ORIGIN="fallback" - ok "$2 (via fallback)" - return 0 - fi - rm -f "$2" - fi - die "failed to fetch $1 from primary or fallback" + die "install failed: cannot reach LARRY_BASE_URL=$LARRY_BASE_URL (fetching $1) — verify the URL or set LARRY_BASE_URL to a reachable mirror" elif [ -n "$SCRIPT_DIR" ] && [ -f "$SCRIPT_DIR/$1" ]; then cp "$SCRIPT_DIR/$1" "$2" && ok "copied $1 (local)" else @@ -210,12 +197,7 @@ fi # ───────────────────────────────────────────────────────────────────────────── echo "" say "install complete (no system changes were made; everything lives under $LARRY_HOME)" -if [ "$LAST_FETCH_ORIGIN" = "fallback" ]; then - warn "files were served from the FALLBACK origin (primary unreachable)." - warn " primary : $LARRY_BASE_URL" - warn " fallback: $LARRY_BASE_URL_FALLBACK" - warn " if you expected the primary to work, check repo visibility (Gitea repos default to private)." -fi +say "origin (single-source, v0.7.4): $LARRY_BASE_URL" echo "" echo "Next steps:" echo " 1) export ANTHROPIC_API_KEY=sk-ant-... (or larry will prompt on first run)" diff --git a/larry.sh b/larry.sh index 10e9073..6f3c838 100755 --- a/larry.sh +++ b/larry.sh @@ -11,17 +11,16 @@ # # Env vars: # LARRY_HOME where to cache config/sessions (default: ~/.larry) -# LARRY_BASE_URL primary root URL of the bundle on the server (default -# as of v0.7.2: https://git.bjnoela.com/bryan/cloverleaf-larry/raw/branch/main). +# LARRY_BASE_URL root URL of the bundle on the server (default +# as of v0.7.4: https://git.bjnoela.com/bryan/cloverleaf-larry/raw/branch/main). # Self-update pulls VERSION + MANIFEST from here and # refreshes every file listed in MANIFEST. -# LARRY_BASE_URL_FALLBACK -# secondary root URL used if the primary is unreachable -# (default: https://raw.githubusercontent.com/bojj27/cloverleaf-larry/main). -# v0.7.2: GitHub demoted from primary to fallback so the -# self-hosted Gitea origin (git.bjnoela.com) is the -# canonical source. Users can pin/override via the -# /origin slash command (see $LARRY_HOME/.origin). +# v0.7.4: single-source auto-update. The GitHub +# fallback added in v0.7.2 was dropped after the GitHub +# mirror was made private (anonymous raw fetches now +# 401/403, so the fallback was functionally broken). +# Users can pin/override via the /origin slash command +# (see $LARRY_HOME/.origin). # LARRY_UPDATE_URL (legacy override) full URL of latest larry.sh # LARRY_AGENTS_URL (legacy override) base URL for agents/ # LARRY_MODEL Claude model (default: claude-sonnet-4-6) @@ -54,42 +53,48 @@ set -o pipefail # ───────────────────────────────────────────────────────────────────────────── # Config # ───────────────────────────────────────────────────────────────────────────── -LARRY_VERSION="0.7.3" +LARRY_VERSION="0.7.4" LARRY_HOME="${LARRY_HOME:-$HOME/.larry}" # ───────────────────────────────────────────────────────────────────────────── -# Origin defaults (v0.7.2). Gitea is primary; GitHub is fallback. +# Origin defaults (v0.7.4 — single-source). # --------------------------------------------------------------------------- -# The /origin slash-command family (see dispatcher below) lets the user pin -# either origin or supply a custom URL. Persisted pins live at -# $LARRY_HOME/.origin and are applied just below. Env-var overrides still win -# over the pinned file (mirroring how LARRY_HOME / LARRY_MODEL etc. behave). +# v0.7.2 introduced a Gitea-primary, GitHub-fallback model. v0.7.4 drops the +# fallback: the GitHub mirror was made private, so anonymous raw-URL reads +# now 401/403 — the fallback path was a silent failure waiting to happen. +# Auto-update is now single-source (Gitea). If Gitea is unreachable the +# client keeps running on the locally cached files and tries again next +# launch. The Gitea push-mirror still fans changes out to GitHub for +# read-only public consumption. # -# IMPORTANT: the Gitea repo (git.bjnoela.com/bryan/cloverleaf-larry) MUST be -# set to PUBLIC for unauthenticated raw-URL reads to succeed. Until then the -# fallback path (GitHub) carries all real auto-update traffic. +# The /origin slash-command family (see dispatcher below) lets the user pin +# a custom URL. Persisted pins live at $LARRY_HOME/.origin and are applied +# just below. Env-var overrides still win over the pinned file (mirroring +# how LARRY_HOME / LARRY_MODEL etc. behave). +# +# Migration: stale .origin files containing the legacy keyword "github" are +# treated as invalid (warn + revert to default). Translating to the GitHub +# raw URL would just trip a 401/403 on the next fetch. # ───────────────────────────────────────────────────────────────────────────── LARRY_ORIGIN_DEFAULT_GITEA="https://git.bjnoela.com/bryan/cloverleaf-larry/raw/branch/main" -LARRY_ORIGIN_DEFAULT_GITHUB="https://raw.githubusercontent.com/bojj27/cloverleaf-larry/main" # Resolve a pinned origin file BEFORE applying env-var defaults so the env # overrides still take precedence. $LARRY_HOME may not exist yet on first # launch — guard accordingly. _larry_pin_primary="" -_larry_pin_fallback="" if [ -r "$LARRY_HOME/.origin" ]; then _larry_pin_raw=$(tr -d '[:space:]' < "$LARRY_HOME/.origin" 2>/dev/null) case "$_larry_pin_raw" in gitea) - _larry_pin_primary="$LARRY_ORIGIN_DEFAULT_GITEA" - _larry_pin_fallback="$LARRY_ORIGIN_DEFAULT_GITHUB" ;; + _larry_pin_primary="$LARRY_ORIGIN_DEFAULT_GITEA" ;; github) - # SWAP: github becomes primary, gitea fallback. - _larry_pin_primary="$LARRY_ORIGIN_DEFAULT_GITHUB" - _larry_pin_fallback="$LARRY_ORIGIN_DEFAULT_GITEA" ;; + # v0.7.4: GitHub is no longer a valid origin (repo went private). + # Warn and treat as no pin — caller will fall through to the Gitea + # default below. We deliberately do NOT auto-rewrite the file; the + # user should re-run /origin explicitly. + printf 'warn: %s/.origin pins legacy "github" origin; the GitHub mirror is private as of v0.7.4. Reverting to default (gitea). Run /origin auto to clear the pin.\n' "$LARRY_HOME" >&2 ;; https://*) - _larry_pin_primary="$_larry_pin_raw" - _larry_pin_fallback="$LARRY_ORIGIN_DEFAULT_GITEA" ;; + _larry_pin_primary="$_larry_pin_raw" ;; "") : ;; # empty file → treat as no pin *) printf 'warn: ignoring unrecognised value in %s/.origin: %s\n' "$LARRY_HOME" "$_larry_pin_raw" >&2 ;; @@ -98,12 +103,12 @@ if [ -r "$LARRY_HOME/.origin" ]; then fi LARRY_BASE_URL="${LARRY_BASE_URL:-${_larry_pin_primary:-$LARRY_ORIGIN_DEFAULT_GITEA}}" -LARRY_BASE_URL_FALLBACK="${LARRY_BASE_URL_FALLBACK:-${_larry_pin_fallback:-$LARRY_ORIGIN_DEFAULT_GITHUB}}" -unset _larry_pin_primary _larry_pin_fallback +unset _larry_pin_primary # Tracks which origin actually served the most recent self_update phase (set # by sync_from_manifest / phase-B fetch). Read by /origin and the status -# line's optional origin badge. Values: "" (none yet), "primary", "fallback". +# line's optional origin badge. In v0.7.4 the only non-empty value is +# "primary" (single-source); the slot is kept for status-line compatibility. _LARRY_LAST_ORIGIN="" _LARRY_LAST_ORIGIN_URL="" @@ -326,27 +331,25 @@ fetch_agents_or_warn # # Skip all of it via --no-update or LARRY_NO_UPDATE=1. # -# v0.7.2: every network step (manifest fetch in phase A, VERSION + larry.sh -# fetch in phase B) tries $LARRY_BASE_URL first and transparently falls back -# to $LARRY_BASE_URL_FALLBACK when the primary fails (curl exit non-zero, -# HTTP error, timeout, DNS failure). The label of whichever origin actually -# served the last byte is recorded in $_LARRY_LAST_ORIGIN[_URL] so /origin -# and the optional status-line badge can display it. +# v0.7.4: single-source auto-update. Every network step (manifest fetch in +# phase A, VERSION + larry.sh fetch in phase B) hits $LARRY_BASE_URL only. +# If it's unreachable (curl exit non-zero, HTTP error, timeout, DNS failure) +# the client logs a clear warn and proceeds with the locally cached files — +# no silent failover to a now-private GitHub mirror. # ───────────────────────────────────────────────────────────────────────────── -# _origin_label URL — short label ("gitea", "github", or the URL itself) used -# in human-facing log lines. Pure string match — no network. +# _origin_label URL — short label ("gitea" or the URL itself) used in +# human-facing log lines. Pure string match — no network. _origin_label() { case "$1" in - "$LARRY_ORIGIN_DEFAULT_GITEA") printf 'gitea' ;; - "$LARRY_ORIGIN_DEFAULT_GITHUB") printf 'github' ;; - *) printf '%s' "$1" ;; + "$LARRY_ORIGIN_DEFAULT_GITEA") printf 'gitea' ;; + *) printf '%s' "$1" ;; esac } # _record_origin SLOT URL — remember the origin (and its URL) that just -# served bytes. SLOT is "primary" or "fallback". Persists across the rest -# of the run so /origin and the status line can read it back. +# served bytes. SLOT is always "primary" in v0.7.4 (single-source); the +# slot arg is retained for status-line compatibility. _record_origin() { _LARRY_LAST_ORIGIN="$1" _LARRY_LAST_ORIGIN_URL="$2" @@ -401,27 +404,23 @@ sync_from_manifest() { return 0 } -# sync_from_manifest_with_fallback — try primary then fallback. Returns 0 if -# either succeeded, non-zero if BOTH unreachable. Wraps sync_from_manifest. +# sync_from_manifest_with_fallback — v0.7.4 retains the historical name for +# call-site compatibility but is now a single-source wrapper around +# sync_from_manifest. Returns 0 on success, non-zero if $LARRY_BASE_URL is +# unreachable (no silent failover — auto-update is just skipped this launch). sync_from_manifest_with_fallback() { if sync_from_manifest "$LARRY_BASE_URL"; then _record_origin primary "$LARRY_BASE_URL" return 0 fi - if [ -n "$LARRY_BASE_URL_FALLBACK" ] && [ "$LARRY_BASE_URL_FALLBACK" != "$LARRY_BASE_URL" ]; then - warn "$(_origin_label "$LARRY_BASE_URL") unreachable, falling back to $(_origin_label "$LARRY_BASE_URL_FALLBACK")" - if sync_from_manifest "$LARRY_BASE_URL_FALLBACK"; then - _record_origin fallback "$LARRY_BASE_URL_FALLBACK" - return 0 - fi - fi - warn "self-update skipped (both origins unreachable)" + warn "$(_origin_label "$LARRY_BASE_URL") unreachable, auto-update skipped this launch" return 1 } -# _fetch_with_fallback REL_PATH DEST [MAX_TIME] — curl with primary→fallback -# retry. Returns 0 if either pulled a non-empty file, non-zero otherwise. -# Records the winning origin slot in $_LARRY_LAST_ORIGIN. +# _fetch_with_fallback REL_PATH DEST [MAX_TIME] — v0.7.4 single-source fetch +# (name kept for call-site compatibility). Returns 0 if the file pulled +# non-empty, non-zero otherwise. Records the winning origin slot in +# $_LARRY_LAST_ORIGIN (always "primary" in single-source mode). _fetch_with_fallback() { local rel="$1" dest="$2" mt="${3:-15}" if curl -fsSL --max-time "$mt" "$LARRY_BASE_URL/$rel" -o "$dest" 2>/dev/null && [ -s "$dest" ]; then @@ -429,14 +428,6 @@ _fetch_with_fallback() { return 0 fi rm -f "$dest" - if [ -n "$LARRY_BASE_URL_FALLBACK" ] && [ "$LARRY_BASE_URL_FALLBACK" != "$LARRY_BASE_URL" ]; then - if curl -fsSL --max-time "$mt" "$LARRY_BASE_URL_FALLBACK/$rel" -o "$dest" 2>/dev/null && [ -s "$dest" ]; then - warn "$(_origin_label "$LARRY_BASE_URL") unreachable for $rel, served from $(_origin_label "$LARRY_BASE_URL_FALLBACK")" - _record_origin fallback "$LARRY_BASE_URL_FALLBACK" - return 0 - fi - rm -f "$dest" - fi return 1 } @@ -477,7 +468,7 @@ self_update() { [ "${LARRY_JUST_UPDATED:-0}" = "1" ] && return 0 [ -w "$self" ] || return 0 - # VERSION fetch with primary→fallback. + # VERSION fetch (single-source; v0.7.4). local ver_tmp="$LARRY_HOME/.VERSION.new" remote_ver="" if _fetch_with_fallback "VERSION" "$ver_tmp" 5; then remote_ver=$(tr -d '[:space:]' < "$ver_tmp" 2>/dev/null) @@ -2171,33 +2162,19 @@ _render_status_line_apikey() { "$C_DIM" "$ctx" "$dollars" "$_LARRY_TURNS" "$C_RESET" "$badge" } -# _origin_badge — light-touch v0.7.2 status-line segment. Returns a leading -# space + colored fragment when the origin is non-default, otherwise empty. -# Default = on defaults AND last-served by primary (or never served yet). +# _origin_badge — status-line segment (v0.7.4 single-source). Returns a +# leading space + colored fragment when the origin is non-default, otherwise +# empty. Badge values: +# "" on the default Gitea origin (no pin, no env override) +# "custom" pinned to a user-supplied HTTPS URL via /origin +# The legacy "github" pin and the gitea→github fallback indicator are gone +# in v0.7.4 (the fallback no longer exists). _origin_badge() { - # Suppress on default state. local pinned="" [ -r "$LARRY_HOME/.origin" ] && pinned=$(tr -d '[:space:]' < "$LARRY_HOME/.origin" 2>/dev/null) - if [ -z "$pinned" ] && { [ -z "$_LARRY_LAST_ORIGIN" ] || [ "$_LARRY_LAST_ORIGIN" = "primary" ]; }; then - return 0 - fi - # Pinned to github → " github" (dim). - if [ "$pinned" = "github" ]; then - printf ' %sgithub%s' "$C_DIM" "$C_RESET" - return 0 - fi - # Pinned to a custom URL → " custom". case "$pinned" in https://*) printf ' %scustom%s' "$C_DIM" "$C_RESET"; return 0 ;; esac - # Failed over from gitea→github (or other primary→fallback). - if [ "$_LARRY_LAST_ORIGIN" = "fallback" ]; then - printf ' %s%s→%s%s' "$C_RED$C_DIM" \ - "$(_origin_label "$LARRY_BASE_URL")" \ - "$(_origin_label "$LARRY_BASE_URL_FALLBACK")" \ - "$C_RESET" - return 0 - fi return 0 } @@ -3214,16 +3191,16 @@ Slash commands: /hl7-fields print component breakdown for a field (e.g. /hl7-fields PID.5 → Family, Given, ...) - Auto-update origin (v0.7.2): - /origin show current primary + fallback + which - served the last self-update - /origin gitea pin to git.bjnoela.com (default primary) - /origin github pin to GitHub raw (swap: github→primary) - /origin auto clear the pin (revert to gitea primary, - github fallback) + Auto-update origin (v0.7.4 — single-source): + /origin show current effective origin (pin or default) + /origin gitea pin to git.bjnoela.com (the default Gitea URL) + /origin auto clear the pin (revert to default) /origin pin to an arbitrary HTTPS base URL (useful for air-gapped mirrors / testing) Pin is persisted to \$LARRY_HOME/.origin and re-read on next launch. + Note: the v0.7.2 GitHub fallback was removed in v0.7.4 — the GitHub mirror + is private, so anonymous raw fetches no longer work. If Gitea is + unreachable, auto-update is skipped and you keep running on cached files. Mouse mode (v0.7.0): /mouse on|off toggle xterm mouse + bracketed-paste for the @@ -3464,7 +3441,7 @@ _LARRY_SLASH_CMDS_DESC=( [/hl7]=" print full field list for an HL7 segment (e.g. /hl7 PID)" [/hl7-fields]=" print component breakdown (e.g. /hl7-fields PID.5)" [/mouse]="on|off toggle xterm mouse mode for this session" - [/origin]="show/pin auto-update origin (gitea|github|auto|)" + [/origin]="show/pin auto-update origin (gitea|auto|) — v0.7.4 single-source" [/phi-auto]="on|off|confirm|status — runtime control for v0.7.3 auto PHI detection" ) @@ -4207,33 +4184,31 @@ main_loop() { continue ;; # v0.7.0: mouse mode toggle (xterm SGR mouse + bracketed paste). /origin|/origin\ *) - # v0.7.2: show/pin the auto-update origin. Pin is persisted - # to $LARRY_HOME/.origin and re-read on the NEXT launch (the - # current run keeps using the resolved $LARRY_BASE_URL). + # v0.7.4 single-source: show/pin the auto-update origin. + # Pin is persisted to $LARRY_HOME/.origin and re-read on the + # NEXT launch (the current run keeps using the resolved + # $LARRY_BASE_URL). The GitHub fallback was dropped — the + # "github" keyword is no longer valid (private mirror). local _arg; _arg=$(_slash_args "/origin" "$input") case "${_arg:-status}" in status) printf '%sauto-update origin:%s\n' "$C_BOLD" "$C_RESET" - printf ' %sprimary :%s %s %s(%s)%s\n' \ + printf ' %seffective:%s %s %s(%s)%s\n' \ "$C_BOLD" "$C_RESET" "$LARRY_BASE_URL" \ "$C_DIM" "$(_origin_label "$LARRY_BASE_URL")" "$C_RESET" - printf ' %sfallback:%s %s %s(%s)%s\n' \ - "$C_BOLD" "$C_RESET" "$LARRY_BASE_URL_FALLBACK" \ - "$C_DIM" "$(_origin_label "$LARRY_BASE_URL_FALLBACK")" "$C_RESET" - if [ -n "$_LARRY_LAST_ORIGIN" ]; then - printf ' %slast served by:%s %s %s(%s)%s\n' \ - "$C_BOLD" "$C_RESET" "$_LARRY_LAST_ORIGIN" \ - "$C_DIM" "$(_origin_label "$_LARRY_LAST_ORIGIN_URL")" "$C_RESET" + if [ -n "$_LARRY_LAST_ORIGIN_URL" ]; then + printf ' %slast served by:%s %s\n' \ + "$C_BOLD" "$C_RESET" "$(_origin_label "$_LARRY_LAST_ORIGIN_URL")" else printf ' %slast served by:%s %s(self-update did not run this session)%s\n' \ "$C_BOLD" "$C_RESET" "$C_DIM" "$C_RESET" fi if [ -r "$LARRY_HOME/.origin" ]; then - printf ' %spin file :%s %s/.origin → %s\n' \ + printf ' %spin file :%s %s/.origin → %s\n' \ "$C_BOLD" "$C_RESET" "$LARRY_HOME" \ "$(tr -d '[:space:]' < "$LARRY_HOME/.origin" 2>/dev/null)" else - printf ' %spin file :%s %s(none — using defaults)%s\n' \ + printf ' %spin file :%s %s(none — using default)%s\n' \ "$C_BOLD" "$C_RESET" "$C_DIM" "$C_RESET" fi ;; @@ -4243,26 +4218,24 @@ main_loop() { || err "could not write $LARRY_HOME/.origin" ;; github) - printf 'github\n' > "$LARRY_HOME/.origin" 2>/dev/null \ - && larry_say "pinned origin: github ($LARRY_ORIGIN_DEFAULT_GITHUB) — SWAP, github becomes primary, gitea fallback. Restart larry to apply." \ - || err "could not write $LARRY_HOME/.origin" + err "/origin github is no longer supported in v0.7.4 — the GitHub mirror is private. Use /origin gitea or /origin ." ;; auto) if [ -f "$LARRY_HOME/.origin" ]; then rm -f "$LARRY_HOME/.origin" \ - && larry_say "pin cleared. Restart larry to revert to defaults (gitea primary, github fallback)." \ + && larry_say "pin cleared. Restart larry to revert to the default (gitea)." \ || err "could not remove $LARRY_HOME/.origin" else - larry_say "no pin in place; already on defaults." + larry_say "no pin in place; already on the default." fi ;; https://*) printf '%s\n' "$_arg" > "$LARRY_HOME/.origin" 2>/dev/null \ - && larry_say "pinned origin: $_arg (gitea kept as fallback). Restart larry to apply." \ + && larry_say "pinned origin: $_arg. Restart larry to apply." \ || err "could not write $LARRY_HOME/.origin" ;; *) - err "usage: /origin [gitea|github|auto|] (no arg → status)" + err "usage: /origin [gitea|auto|] (no arg → status)" ;; esac continue ;;