feat(bootstrap): add shared session bootstrap and machine-alias resolver
This commit is contained in:
75
scripts/print-session-bootstrap.sh
Executable file
75
scripts/print-session-bootstrap.sh
Executable file
@@ -0,0 +1,75 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
usage() {
|
||||
cat <<'USAGE'
|
||||
Usage:
|
||||
scripts/print-session-bootstrap.sh [--tool <tool>] [--branch <branch>] [--task-id <id>] [--gateway-url <url>] [--hostname <name>]
|
||||
|
||||
Prints a ready-to-paste first message for Claude/Codex/Cursor/OpenClaw sessions.
|
||||
USAGE
|
||||
}
|
||||
|
||||
TOOL="codex"
|
||||
BRANCH="main"
|
||||
TASK_ID=""
|
||||
GATEWAY_URL="http://100.64.0.45:8787"
|
||||
HOSTNAME_INPUT=""
|
||||
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case "$1" in
|
||||
--tool)
|
||||
TOOL="${2:-}"
|
||||
shift 2
|
||||
;;
|
||||
--branch)
|
||||
BRANCH="${2:-}"
|
||||
shift 2
|
||||
;;
|
||||
--task-id)
|
||||
TASK_ID="${2:-}"
|
||||
shift 2
|
||||
;;
|
||||
--gateway-url)
|
||||
GATEWAY_URL="${2:-}"
|
||||
shift 2
|
||||
;;
|
||||
--hostname)
|
||||
HOSTNAME_INPUT="${2:-}"
|
||||
shift 2
|
||||
;;
|
||||
-h|--help)
|
||||
usage
|
||||
exit 0
|
||||
;;
|
||||
*)
|
||||
echo "ERROR: unknown arg: $1" >&2
|
||||
usage
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
REPO_ROOT="$(git rev-parse --show-toplevel)"
|
||||
ARGS=(--field all --tool "$TOOL")
|
||||
if [[ -n "$HOSTNAME_INPUT" ]]; then
|
||||
ARGS+=(--hostname "$HOSTNAME_INPUT")
|
||||
fi
|
||||
INFO="$($REPO_ROOT/scripts/resolve-machine-alias.sh "${ARGS[@]}")"
|
||||
|
||||
hostname_v="$(printf '%s\n' "$INFO" | awk -F= '$1=="hostname"{print $2}')"
|
||||
alias_v="$(printf '%s\n' "$INFO" | awk -F= '$1=="alias"{print $2}')"
|
||||
agent_id_v="$(printf '%s\n' "$INFO" | awk -F= '$1=="agent_id"{print $2}')"
|
||||
|
||||
cat <<OUT
|
||||
@/Users/lingyuzeng/project/collective-memory-repo/policies/SESSION-BOOTSTRAP.md
|
||||
machine_hostname=${hostname_v}
|
||||
machine_alias=${alias_v}
|
||||
agent_id=${agent_id_v}
|
||||
memory_branch=${BRANCH}
|
||||
memory_gateway=${GATEWAY_URL}
|
||||
OUT
|
||||
|
||||
if [[ -n "$TASK_ID" ]]; then
|
||||
echo "task_id=${TASK_ID}"
|
||||
fi
|
||||
177
scripts/resolve-machine-alias.sh
Executable file
177
scripts/resolve-machine-alias.sh
Executable file
@@ -0,0 +1,177 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
usage() {
|
||||
cat <<'USAGE'
|
||||
Usage:
|
||||
scripts/resolve-machine-alias.sh [--hostname <name>] [--field alias|suffix|agent-id|all] [--tool <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 <<OUT
|
||||
hostname=$matched_hostname
|
||||
alias=$matched_alias
|
||||
suffix=$matched_suffix
|
||||
agent_id=$agent_id
|
||||
OUT
|
||||
;;
|
||||
esac
|
||||
Reference in New Issue
Block a user