#!/usr/bin/env bash set -euo pipefail usage() { cat <<'USAGE' Usage: scripts/resolve-machine-alias.sh [--hostname ] [--field alias|suffix|agent-id|all] [--tool ] Defaults: --hostname: current host shortname (hostname -s) --field: all --tool: openclaw Reads mapping from policies/MACHINE-ALIASES.yaml. USAGE } HOSTNAME_INPUT="$(hostname -s 2>/dev/null || hostname)" FIELD="all" TOOL="openclaw" while [[ $# -gt 0 ]]; do case "$1" in --hostname) HOSTNAME_INPUT="${2:-}" shift 2 ;; --field) FIELD="${2:-}" shift 2 ;; --tool) TOOL="${2:-}" shift 2 ;; -h|--help) usage exit 0 ;; *) echo "ERROR: unknown arg: $1" >&2 usage exit 1 ;; esac done case "$FIELD" in alias|suffix|agent-id|all) ;; *) echo "ERROR: --field must be one of alias|suffix|agent-id|all" >&2 exit 1 ;; esac REPO_ROOT="$(git rev-parse --show-toplevel 2>/dev/null || true)" if [[ -z "$REPO_ROOT" ]]; then echo "ERROR: run inside collective-memory-repo" >&2 exit 2 fi MAP_FILE="$REPO_ROOT/policies/MACHINE-ALIASES.yaml" if [[ ! -f "$MAP_FILE" ]]; then echo "ERROR: mapping file not found: $MAP_FILE" >&2 exit 2 fi trim() { local s="$1" s="${s#${s%%[![:space:]]*}}" s="${s%${s##*[![:space:]]}}" printf '%s' "$s" } contains_csv_value() { local csv="$1" local needle="$2" IFS=',' read -r -a parts <<< "$csv" for p in "${parts[@]}"; do if [[ "$(trim "$p")" == "$needle" ]]; then return 0 fi done return 1 } record_hostname="" record_aliases="" record_suffix="" matched_alias="" matched_suffix="" matched_hostname="" found="false" finalize_record() { if [[ "$found" == "true" || -z "$record_hostname" ]]; then return fi if [[ "$HOSTNAME_INPUT" == "$record_hostname" ]]; then found="true" elif contains_csv_value "$record_aliases" "$HOSTNAME_INPUT"; then found="true" fi if [[ "$found" == "true" ]]; then matched_hostname="$record_hostname" matched_suffix="$record_suffix" if contains_csv_value "$record_aliases" "$HOSTNAME_INPUT"; then matched_alias="$HOSTNAME_INPUT" else IFS=',' read -r first_alias _ <<< "$record_aliases" matched_alias="$(trim "$first_alias")" fi fi } while IFS= read -r raw_line || [[ -n "$raw_line" ]]; do line="${raw_line%%#*}" line="$(trim "$line")" [[ -z "$line" ]] && continue if [[ "$line" =~ ^-[[:space:]]hostname:[[:space:]]*(.+)$ ]]; then finalize_record record_hostname="$(trim "${BASH_REMATCH[1]}")" record_aliases="" record_suffix="" continue fi if [[ "$line" =~ ^aliases:[[:space:]]*(.+)$ ]]; then record_aliases="$(trim "${BASH_REMATCH[1]}")" continue fi if [[ "$line" =~ ^default_agent_suffix:[[:space:]]*(.+)$ ]]; then record_suffix="$(trim "${BASH_REMATCH[1]}")" continue fi done < "$MAP_FILE" finalize_record if [[ "$found" != "true" ]]; then # fallback: use normalized hostname directly fallback_suffix="$(printf '%s' "$HOSTNAME_INPUT" | tr '[:upper:]' '[:lower:]' | tr -cs 'a-z0-9-' '-')" fallback_suffix="${fallback_suffix#-}" fallback_suffix="${fallback_suffix%-}" [[ -z "$fallback_suffix" ]] && fallback_suffix="host" matched_hostname="$HOSTNAME_INPUT" matched_alias="$fallback_suffix" matched_suffix="$fallback_suffix" fi agent_id="${TOOL}-${matched_suffix}" case "$FIELD" in alias) printf '%s\n' "$matched_alias" ;; suffix) printf '%s\n' "$matched_suffix" ;; agent-id) printf '%s\n' "$agent_id" ;; all) cat <