mirror of
https://github.com/rcourtman/Pulse.git
synced 2026-07-10 00:14:38 +00:00
Manifest-backed MCP tools, prompts, and resources with surface affordance contracts; agent capability manifest and governance projection; API contract tests and capability route projection; operations-loop and intelligence-funnel telemetry; release-control subsystem documentation, registry, and tooling; licensing and configuration.
348 lines
9.9 KiB
Bash
348 lines
9.9 KiB
Bash
#!/usr/bin/env bash
|
|
|
|
# Shared helpers for the managed local Pulse development runtime.
|
|
|
|
hot_dev_pulse_process_count() {
|
|
local pattern="${1:-^\./pulse$}"
|
|
local count=0
|
|
local pid
|
|
|
|
if ! command -v pgrep >/dev/null 2>&1; then
|
|
printf '0\n'
|
|
return 0
|
|
fi
|
|
|
|
while IFS= read -r pid; do
|
|
[[ -n "${pid}" ]] || continue
|
|
count=$((count + 1))
|
|
done < <(pgrep -f "${pattern}" 2>/dev/null || true)
|
|
|
|
printf '%s\n' "${count}"
|
|
}
|
|
|
|
hot_dev_detect_lan_ip() {
|
|
local detected=""
|
|
|
|
if command -v hostname >/dev/null 2>&1 && hostname -I >/dev/null 2>&1; then
|
|
detected="$(hostname -I 2>/dev/null | awk '{print $1}')"
|
|
fi
|
|
|
|
if [[ -z "${detected}" ]] && command -v ipconfig >/dev/null 2>&1; then
|
|
detected="$(ipconfig getifaddr en0 2>/dev/null || true)"
|
|
fi
|
|
|
|
printf '%s\n' "${detected}"
|
|
}
|
|
|
|
hot_dev_detect_all_ipv4s() {
|
|
if [[ "$(uname -s)" == "Darwin" ]]; then
|
|
ifconfig 2>/dev/null | awk '/inet / {print $2}' | grep -v "^127\." || true
|
|
return 0
|
|
fi
|
|
|
|
hostname -I 2>/dev/null || true
|
|
}
|
|
|
|
hot_dev_truthy() {
|
|
local value
|
|
value="$(printf '%s\n' "${1:-}" | tr '[:upper:]' '[:lower:]')"
|
|
|
|
case "${value}" in
|
|
1|true|yes|y|on)
|
|
return 0
|
|
;;
|
|
esac
|
|
|
|
return 1
|
|
}
|
|
|
|
hot_dev_lan_enabled() {
|
|
hot_dev_truthy "${PULSE_DEV_LAN:-false}"
|
|
}
|
|
|
|
hot_dev_lab_agents_enabled() {
|
|
hot_dev_truthy "${PULSE_DEV_LAB_AGENTS:-false}"
|
|
}
|
|
|
|
hot_dev_lab_agent_mode_file_enabled() {
|
|
local mode_file="${HOT_DEV_LAB_MODE_FILE:-}"
|
|
|
|
[[ -n "${mode_file}" && -r "${mode_file}" ]] || return 1
|
|
grep -Eq '^[[:space:]]*PULSE_DEV_LAB_AGENTS[[:space:]]*=[[:space:]]*true[[:space:]]*$' "${mode_file}"
|
|
}
|
|
|
|
hot_dev_remember_lab_agent_mode() {
|
|
local mode_file="${HOT_DEV_LAB_MODE_FILE:-}"
|
|
|
|
[[ -n "${mode_file}" ]] || return 0
|
|
mkdir -p "$(dirname "${mode_file}")"
|
|
{
|
|
printf '# Managed by Pulse hot-dev. Remove this file or set PULSE_DEV_LAB_AGENTS=false to return to loopback-only dev.\n'
|
|
printf 'PULSE_DEV_LAB_AGENTS=true\n'
|
|
} > "${mode_file}"
|
|
}
|
|
|
|
hot_dev_clear_remembered_lab_agent_mode() {
|
|
local mode_file="${HOT_DEV_LAB_MODE_FILE:-}"
|
|
|
|
[[ -n "${mode_file}" ]] || return 0
|
|
rm -f "${mode_file}" 2>/dev/null || true
|
|
}
|
|
|
|
hot_dev_apply_remembered_lab_agent_mode() {
|
|
if [[ -n "${PULSE_DEV_LAB_AGENTS+x}" ]]; then
|
|
if hot_dev_lab_agents_enabled; then
|
|
hot_dev_remember_lab_agent_mode
|
|
else
|
|
hot_dev_clear_remembered_lab_agent_mode
|
|
fi
|
|
return 0
|
|
fi
|
|
|
|
if [[ -n "${PULSE_DEV_LAN+x}" ]] && ! hot_dev_lan_enabled; then
|
|
hot_dev_clear_remembered_lab_agent_mode
|
|
return 0
|
|
fi
|
|
|
|
if hot_dev_lab_agent_mode_file_enabled; then
|
|
PULSE_DEV_LAB_AGENTS=true
|
|
export PULSE_DEV_LAB_AGENTS
|
|
if declare -F log_warn >/dev/null 2>&1; then
|
|
log_warn "Remembered lab-agent mode is enabled for this workspace. Starting with LAN agent access; set PULSE_DEV_LAB_AGENTS=false once to return to loopback-only dev."
|
|
fi
|
|
fi
|
|
}
|
|
|
|
hot_dev_apply_lab_agent_defaults() {
|
|
hot_dev_apply_remembered_lab_agent_mode
|
|
|
|
if ! hot_dev_lab_agents_enabled; then
|
|
return 0
|
|
fi
|
|
|
|
PULSE_DEV_LAN=true
|
|
PULSE_ENABLE_PROXMOX_GUEST_DOCKER_DETECTION=true
|
|
PULSE_ENABLE_PROXMOX_GUEST_DOCKER_INVENTORY=true
|
|
|
|
export PULSE_DEV_LAB_AGENTS PULSE_DEV_LAN
|
|
export PULSE_ENABLE_PROXMOX_GUEST_DOCKER_DETECTION PULSE_ENABLE_PROXMOX_GUEST_DOCKER_INVENTORY
|
|
}
|
|
|
|
hot_dev_configure_network_defaults() {
|
|
FRONTEND_PORT="${FRONTEND_PORT:-${PORT:-5173}}"
|
|
PORT="${PORT:-${FRONTEND_PORT}}"
|
|
|
|
hot_dev_apply_lab_agent_defaults
|
|
|
|
if [[ -z "${LAN_IP:-}" ]]; then
|
|
LAN_IP="$(hot_dev_detect_lan_ip)"
|
|
fi
|
|
LAN_IP="${LAN_IP:-0.0.0.0}"
|
|
|
|
if hot_dev_lan_enabled; then
|
|
FRONTEND_DEV_HOST="${FRONTEND_DEV_HOST:-0.0.0.0}"
|
|
PULSE_DEV_API_HOST="${PULSE_DEV_API_HOST:-${LAN_IP}}"
|
|
BIND_ADDRESS="${BIND_ADDRESS:-0.0.0.0}"
|
|
else
|
|
FRONTEND_DEV_HOST="${FRONTEND_DEV_HOST:-127.0.0.1}"
|
|
PULSE_DEV_API_HOST="${PULSE_DEV_API_HOST:-127.0.0.1}"
|
|
BIND_ADDRESS="${BIND_ADDRESS:-127.0.0.1}"
|
|
fi
|
|
FRONTEND_DEV_PORT="${FRONTEND_DEV_PORT:-${FRONTEND_PORT}}"
|
|
PULSE_DEV_API_PORT="${PULSE_DEV_API_PORT:-7655}"
|
|
|
|
if [[ -z "${PULSE_DEV_API_URL:-}" ]]; then
|
|
PULSE_DEV_API_URL="http://${PULSE_DEV_API_HOST}:${PULSE_DEV_API_PORT}"
|
|
fi
|
|
|
|
if [[ -z "${PULSE_DEV_WS_URL:-}" ]]; then
|
|
if [[ "${PULSE_DEV_API_URL}" == http://* ]]; then
|
|
PULSE_DEV_WS_URL="ws://${PULSE_DEV_API_URL#http://}"
|
|
elif [[ "${PULSE_DEV_API_URL}" == https://* ]]; then
|
|
PULSE_DEV_WS_URL="wss://${PULSE_DEV_API_URL#https://}"
|
|
else
|
|
PULSE_DEV_WS_URL="${PULSE_DEV_API_URL}"
|
|
fi
|
|
fi
|
|
|
|
ALL_IPS="${ALL_IPS:-$(hot_dev_detect_all_ipv4s)}"
|
|
|
|
ALLOWED_ORIGINS="http://${PULSE_DEV_API_HOST:-127.0.0.1}:${FRONTEND_DEV_PORT:-7655}"
|
|
ALLOWED_ORIGINS="${ALLOWED_ORIGINS},http://localhost:${FRONTEND_DEV_PORT:-7655},http://127.0.0.1:${FRONTEND_DEV_PORT:-7655}"
|
|
ALLOWED_ORIGINS="${ALLOWED_ORIGINS},http://localhost:5173,http://127.0.0.1:5173"
|
|
if [[ "${FRONTEND_DEV_HOST:-}" == "0.0.0.0" ]]; then
|
|
ALLOWED_ORIGINS="${ALLOWED_ORIGINS},http://0.0.0.0:${FRONTEND_DEV_PORT:-7655},http://0.0.0.0:5173"
|
|
fi
|
|
|
|
if hot_dev_lan_enabled; then
|
|
local ip
|
|
for ip in ${ALL_IPS:-}; do
|
|
if [[ "${ip}" =~ ^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
|
|
if [[ "${ip}" != "127.0.0.1" ]]; then
|
|
ALLOWED_ORIGINS="${ALLOWED_ORIGINS},http://${ip}:${FRONTEND_DEV_PORT:-7655}"
|
|
ALLOWED_ORIGINS="${ALLOWED_ORIGINS},http://${ip}:5173"
|
|
fi
|
|
fi
|
|
done
|
|
fi
|
|
|
|
export FRONTEND_PORT PORT
|
|
export LAN_IP ALL_IPS
|
|
export PULSE_DEV_LAN PULSE_DEV_LAB_AGENTS
|
|
export FRONTEND_DEV_HOST FRONTEND_DEV_PORT
|
|
export PULSE_DEV_API_HOST PULSE_DEV_API_PORT PULSE_DEV_API_URL PULSE_DEV_WS_URL
|
|
export BIND_ADDRESS ALLOWED_ORIGINS
|
|
}
|
|
|
|
hot_dev_normalize_host() {
|
|
local host="${1:-}"
|
|
|
|
host="${host#[}"
|
|
host="${host%]}"
|
|
printf '%s\n' "${host}" | tr '[:upper:]' '[:lower:]'
|
|
}
|
|
|
|
hot_dev_url_host() {
|
|
local url="${1:-}"
|
|
local host_port host
|
|
|
|
[[ -n "${url}" ]] || return 0
|
|
|
|
host_port="${url}"
|
|
if [[ "${host_port}" == *"://"* ]]; then
|
|
host_port="${host_port#*://}"
|
|
fi
|
|
host_port="${host_port%%/*}"
|
|
host_port="${host_port%%\?*}"
|
|
host_port="${host_port%%#*}"
|
|
|
|
if [[ "${host_port}" == \[*\]* ]]; then
|
|
host="${host_port#\[}"
|
|
host="${host%%\]*}"
|
|
else
|
|
host="${host_port%%:*}"
|
|
fi
|
|
|
|
hot_dev_normalize_host "${host}"
|
|
}
|
|
|
|
hot_dev_host_is_loopback() {
|
|
local host
|
|
host="$(hot_dev_normalize_host "${1:-}")"
|
|
|
|
[[ -n "${host}" ]] || return 1
|
|
|
|
case "${host}" in
|
|
localhost|127.*|::1|0:0:0:0:0:0:0:1)
|
|
return 0
|
|
;;
|
|
esac
|
|
|
|
return 1
|
|
}
|
|
|
|
hot_dev_bind_address_is_loopback() {
|
|
hot_dev_host_is_loopback "${1:-}"
|
|
}
|
|
|
|
hot_dev_browser_host_for_bind() {
|
|
local host="${1:-}"
|
|
local normalized
|
|
|
|
normalized="$(hot_dev_normalize_host "${host}")"
|
|
case "${normalized}" in
|
|
""|0.0.0.0|::)
|
|
printf '127.0.0.1\n'
|
|
return 0
|
|
;;
|
|
esac
|
|
|
|
printf '%s\n' "${host}"
|
|
}
|
|
|
|
hot_dev_local_browser_url() {
|
|
local host="${1:-${FRONTEND_DEV_HOST:-127.0.0.1}}"
|
|
local port="${2:-${FRONTEND_DEV_PORT:-5173}}"
|
|
|
|
printf 'http://%s:%s\n' "$(hot_dev_browser_host_for_bind "${host}")" "${port}"
|
|
}
|
|
|
|
hot_dev_lan_browser_url() {
|
|
local bind_host="${1:-${FRONTEND_DEV_HOST:-127.0.0.1}}"
|
|
local port="${2:-${FRONTEND_DEV_PORT:-5173}}"
|
|
local lan_ip="${3:-${LAN_IP:-}}"
|
|
|
|
if hot_dev_bind_address_is_loopback "${bind_host}"; then
|
|
return 0
|
|
fi
|
|
if [[ -z "${lan_ip}" || "${lan_ip}" == "0.0.0.0" ]]; then
|
|
return 0
|
|
fi
|
|
|
|
printf 'http://%s:%s\n' "${lan_ip}" "${port}"
|
|
}
|
|
|
|
hot_dev_host_matches_local_interface() {
|
|
local host="${1:-}"
|
|
local candidate
|
|
local system_hostname=""
|
|
local short_hostname=""
|
|
|
|
host="$(hot_dev_normalize_host "${host}")"
|
|
[[ -n "${host}" ]] || return 1
|
|
|
|
if [[ -n "${LAN_IP:-}" ]] && [[ "${host}" == "$(hot_dev_normalize_host "${LAN_IP}")" ]]; then
|
|
return 0
|
|
fi
|
|
|
|
for candidate in ${ALL_IPS:-}; do
|
|
if [[ "${host}" == "$(hot_dev_normalize_host "${candidate}")" ]]; then
|
|
return 0
|
|
fi
|
|
done
|
|
|
|
system_hostname="$(hostname 2>/dev/null || true)"
|
|
system_hostname="$(hot_dev_normalize_host "${system_hostname}")"
|
|
short_hostname="${system_hostname%%.*}"
|
|
|
|
if [[ -n "${system_hostname}" && "${host}" == "${system_hostname}" ]]; then
|
|
return 0
|
|
fi
|
|
if [[ -n "${short_hostname}" && "${host}" == "${short_hostname}" ]]; then
|
|
return 0
|
|
fi
|
|
|
|
return 1
|
|
}
|
|
|
|
hot_dev_reconcile_agent_bind_address() {
|
|
local bind_address="${BIND_ADDRESS:-}"
|
|
local labels="PULSE_AGENT_CONNECT_URL PULSE_AGENT_URL PULSE_PUBLIC_URL"
|
|
local label url host
|
|
|
|
[[ -n "${bind_address}" ]] || return 0
|
|
hot_dev_bind_address_is_loopback "${bind_address}" || return 0
|
|
|
|
for label in ${labels}; do
|
|
url="${!label-}"
|
|
host="$(hot_dev_url_host "${url}")"
|
|
[[ -n "${host}" ]] || continue
|
|
hot_dev_host_is_loopback "${host}" && continue
|
|
hot_dev_host_matches_local_interface "${host}" || continue
|
|
|
|
if ! hot_dev_lan_enabled; then
|
|
if declare -F log_warn >/dev/null 2>&1; then
|
|
log_warn "${label}=${url} points at this machine, but hot-dev is local-only by default. Leaving BIND_ADDRESS=${bind_address}; set PULSE_DEV_LAN=true to expose this dev backend to installed agents."
|
|
fi
|
|
return 0
|
|
fi
|
|
|
|
BIND_ADDRESS="0.0.0.0"
|
|
export BIND_ADDRESS
|
|
|
|
if declare -F log_warn >/dev/null 2>&1; then
|
|
log_warn "${label}=${url} points at this machine, but BIND_ADDRESS=${bind_address} only accepts local connections. Exposing the dev backend on 0.0.0.0 so installed agents can report metrics."
|
|
fi
|
|
return 0
|
|
done
|
|
}
|