diff --git a/scripts/install-goose-v149-canary-103.sh b/scripts/install-goose-v149-canary-103.sh new file mode 100755 index 0000000..b8fbc45 --- /dev/null +++ b/scripts/install-goose-v149-canary-103.sh @@ -0,0 +1,139 @@ +#!/usr/bin/env bash +# Install Goose v1.49 canary on 103 loopback :18015 (does not touch stable 18006-18014). +set -euo pipefail + +ROOT="$(cd "$(dirname "$0")/.." && pwd)" +NATIVE_ROOT="${GOOSE_NATIVE_ROOT:-/Users/john/Project/tkmind_go-native}" +GOOSED_V149_ROOT="${GOOSE_V149_ROOT:-/Users/john/Project/tkmind_go-v149}" +PORT="${GOOSE_V149_CANARY_PORT:-18015}" +LABEL="${GOOSE_V149_CANARY_LABEL:-cn.tkmind.goose-v149-canary}" +LAUNCHD_DIR="${HOME}/Library/LaunchAgents" +PLIST="${LAUNCHD_DIR}/${LABEL}.plist" +GUI="gui/$(id -u)" +STAMP="${GOOSE_V149_RELEASE_STAMP:-$(date +%Y%m%d-v149-m1)}" +RELEASE_BIN="${NATIVE_ROOT}/releases/goose-${STAMP}" +RUN_SCRIPT="${NATIVE_ROOT}/run-goose-v149-${PORT}.sh" +ENV_FILE="${NATIVE_ROOT}/.env.${PORT}" +SOURCE_ENV="${NATIVE_ROOT}/.env.18006" + +usage() { + cat </dev/null || true + rm -f "${PLIST}" "${RUN_SCRIPT}" "${ENV_FILE}" + echo "[goose-v149-canary-103] uninstalled ${LABEL} on :${PORT}" +} + +if [[ "${1:-}" == "--uninstall" ]]; then + uninstall + exit 0 +fi + +if [[ ! -x "${GOOSED_V149_ROOT}/target/release/goose" ]]; then + echo "[goose-v149-canary-103] missing binary: ${GOOSED_V149_ROOT}/target/release/goose" >&2 + echo "Build on 103: cd Memind-git && GOOSE_V149_BUILD_MODE=codemode bash scripts/build-goosed-v149-local.sh" >&2 + exit 1 +fi + +if [[ ! -f "${SOURCE_ENV}" ]]; then + echo "[goose-v149-canary-103] missing ${SOURCE_ENV}" >&2 + exit 1 +fi + +for blocked in 18006 18007 18008 18009 18010 18011 18012 18013 18014 8081; do + if [[ "${PORT}" == "${blocked}" ]]; then + echo "[goose-v149-canary-103] refusing stable/production port ${PORT}" >&2 + exit 1 + fi +done + +mkdir -p "${NATIVE_ROOT}/releases" "${NATIVE_ROOT}/state/${PORT}"/{config,data,state,cache} +install -m 755 "${GOOSED_V149_ROOT}/target/release/goose" "${RELEASE_BIN}" + +cp "${SOURCE_ENV}" "${ENV_FILE}" +{ + echo "" + echo "# goose-v149-canary-${PORT} overrides ($(date -u +%Y-%m-%dT%H:%M:%SZ))" + echo "GOOSE_PORT=${PORT}" + echo "GOOSE_BIN=${RELEASE_BIN}" + echo "XDG_CONFIG_HOME=${NATIVE_ROOT}/state/${PORT}/config" + echo "XDG_DATA_HOME=${NATIVE_ROOT}/state/${PORT}/data" + echo "XDG_STATE_HOME=${NATIVE_ROOT}/state/${PORT}/state" + echo "XDG_CACHE_HOME=${NATIVE_ROOT}/state/${PORT}/cache" + echo "MEMORY_BACKEND=legacy" + echo "MEMORY_VECTOR_ENABLED=0" + echo "MEMORY_AGENT_INJECTION_MODE=off" + echo "MEMORY_LIFECYCLE_ENABLED=0" + echo "MEMORY_CANDIDATE_ENABLED=0" +} >> "${ENV_FILE}" + +cat > "${RUN_SCRIPT}" <<'RUNEOF' +#!/usr/bin/env bash +set -euo pipefail +export PATH="/opt/homebrew/opt/node@24/bin:/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin" +PORT="__PORT__" +ROOT="__NATIVE_ROOT__" +cd "${ROOT}" +set -a +# shellcheck source=/dev/null +source "${ROOT}/.env.${PORT}" +set +a +exec env "CUSTOM_DEEPSEEK-CP_API_KEY=${DEEPSEEK_API_KEY:-}" \ + "${GOOSE_BIN:?missing GOOSE_BIN}" serve \ + --host "${GOOSE_HOST:-127.0.0.1}" \ + --port "${PORT}" \ + --tls +RUNEOF +sed -i '' "s|__PORT__|${PORT}|g; s|__NATIVE_ROOT__|${NATIVE_ROOT}|g" "${RUN_SCRIPT}" +chmod +x "${RUN_SCRIPT}" + +cat > "${PLIST}" < + + + + Label + ${LABEL} + ProgramArguments + + ${RUN_SCRIPT} + + RunAtLoad + + KeepAlive + + StandardOutPath + ${NATIVE_ROOT}/state/${PORT}/goose-v149-canary.log + StandardErrorPath + ${NATIVE_ROOT}/state/${PORT}/goose-v149-canary.err.log + + +EOF + +launchctl bootout "${GUI}/${LABEL}" 2>/dev/null || true +launchctl bootstrap "${GUI}" "${PLIST}" +launchctl enable "${GUI}/${LABEL}" 2>/dev/null || true + +sleep 2 +if curl -kfsS --connect-timeout 5 "https://127.0.0.1:${PORT}/status" >/dev/null; then + echo "[goose-v149-canary-103] ok https://127.0.0.1:${PORT}/status" +else + echo "[goose-v149-canary-103] WARN: /status not ready; check ${NATIVE_ROOT}/state/${PORT}/goose-v149-canary.err.log" >&2 + exit 1 +fi + +"${RELEASE_BIN}" --version | head -1 +echo "[goose-v149-canary-103] release=${RELEASE_BIN} label=${LABEL}" diff --git a/scripts/switch-goose-v149-canary-103.sh b/scripts/switch-goose-v149-canary-103.sh new file mode 100755 index 0000000..026e7a2 --- /dev/null +++ b/scripts/switch-goose-v149-canary-103.sh @@ -0,0 +1,116 @@ +#!/usr/bin/env bash +# Toggle Goose v1.49 canary routing on 103 stable Portal (.env). +set -euo pipefail + +ROOT="$(cd "$(dirname "$0")/.." && pwd)" +ENV_FILE="${GOOSE_V149_CANARY_ENV_FILE:-/Users/john/Project/Memind/.env}" +MARKER_BEGIN='# GOOSE_V149_CANARY_BEGIN' +MARKER_END='# GOOSE_V149_CANARY_END' +STABLE_TARGET="${TKMIND_API_TARGET_STABLE:-https://127.0.0.1:18006}" +V149_TARGET="${TKMIND_API_TARGET_V149:-https://127.0.0.1:18015}" +PORTAL_LABEL="${MEMIND_PORTAL_LABEL:-cn.tkmind.memind-portal}" +GUI="gui/$(id -u)" + +usage() { + cat < + +Commands: + on [all|users] Route Portal to v1.49 canary (${V149_TARGET}) + off|rollback Remove canary block from ${ENV_FILE} + status Show active block + +users mode example (唐 only): + TKMIND_GOOSE_CANARY_WECHAT_USER_IDS=wx_ul610et8 bash scripts/switch-goose-v149-canary-103.sh on users +EOF +} + +backup_env() { + cp "${ENV_FILE}" "${ENV_FILE}.bak-goose-v149-canary-$(date +%Y%m%d-%H%M%S)" +} + +remove_canary_block() { + awk -v begin="${MARKER_BEGIN}" -v end="${MARKER_END}" ' + $0 == begin { skip=1; next } + $0 == end { skip=0; next } + skip == 0 { print } + ' "${ENV_FILE}" > "${ENV_FILE}.tmp" + mv "${ENV_FILE}.tmp" "${ENV_FILE}" +} + +write_canary_block() { + local mode="$1" + backup_env + remove_canary_block + { + echo "${MARKER_BEGIN}" + echo "TKMIND_GOOSE_CANARY=${mode}" + echo "TKMIND_API_TARGET_STABLE=${STABLE_TARGET}" + echo "TKMIND_API_TARGET_V149=${V149_TARGET}" + if [[ "${mode}" == "all" ]]; then + echo "TKMIND_API_TARGET=${V149_TARGET}" + elif [[ "${mode}" == "users" ]]; then + echo "TKMIND_API_TARGET=${STABLE_TARGET}" + echo "TKMIND_API_TARGETS=${STABLE_TARGET},${V149_TARGET}" + [[ -n "${TKMIND_GOOSE_CANARY_USER_IDS:-}" ]] && echo "TKMIND_GOOSE_CANARY_USER_IDS=${TKMIND_GOOSE_CANARY_USER_IDS}" + [[ -n "${TKMIND_GOOSE_CANARY_USERNAMES:-}" ]] && echo "TKMIND_GOOSE_CANARY_USERNAMES=${TKMIND_GOOSE_CANARY_USERNAMES}" + [[ -n "${TKMIND_GOOSE_CANARY_WECHAT_USER_IDS:-}" ]] && echo "TKMIND_GOOSE_CANARY_WECHAT_USER_IDS=${TKMIND_GOOSE_CANARY_WECHAT_USER_IDS}" + fi + echo "MEMORY_BACKEND=legacy" + echo "MEMORY_VECTOR_ENABLED=0" + echo "MEMORY_AGENT_INJECTION_MODE=off" + echo "MEMORY_LIFECYCLE_ENABLED=0" + echo "MEMORY_CANDIDATE_ENABLED=0" + echo "${MARKER_END}" + } >> "${ENV_FILE}" +} + +restart_portal() { + launchctl kickstart -k "${GUI}/${PORTAL_LABEL}" 2>/dev/null || launchctl bootstrap "${GUI}" "${HOME}/Library/LaunchAgents/${PORTAL_LABEL}.plist" + sleep 2 + curl -fsS --connect-timeout 5 http://127.0.0.1:8081/api/status +} + +cmd="${1:-}" +case "${cmd}" in + on) + mode="${2:-users}" + if [[ ! -f "${ENV_FILE}" ]]; then + echo "Missing ${ENV_FILE}" >&2 + exit 1 + fi + if [[ "${mode}" == "users" && -z "${TKMIND_GOOSE_CANARY_USER_IDS:-}${TKMIND_GOOSE_CANARY_USERNAMES:-}${TKMIND_GOOSE_CANARY_WECHAT_USER_IDS:-}" ]]; then + echo "users mode requires identity allowlist env vars" >&2 + exit 2 + fi + write_canary_block "${mode}" + echo "[goose-v149-canary-103] enabled mode=${mode} in ${ENV_FILE}" + restart_portal + echo "[goose-v149-canary-103] Portal restarted" + ;; + off|rollback) + backup_env + remove_canary_block + restart_portal + echo "[goose-v149-canary-103] disabled; Portal on stable pool" + ;; + status) + if grep -q "${MARKER_BEGIN}" "${ENV_FILE}" 2>/dev/null; then + awk -v begin="${MARKER_BEGIN}" -v end="${MARKER_END}" ' + $0 == begin { show=1; next } + $0 == end { show=0; next } + show == 1 { print } + ' "${ENV_FILE}" + else + echo "[goose-v149-canary-103] no active block" + fi + ;; + -h|--help|help|'') + usage + ;; + *) + echo "Unknown command: ${cmd}" >&2 + usage + exit 2 + ;; +esac