diff --git a/.env.example b/.env.example index c80aea1..9cd884d 100644 --- a/.env.example +++ b/.env.example @@ -1,18 +1,35 @@ # HangmanLab.Server.T2 — Plugin Configuration # Copy to .env and fill in values. This file is gitignored. +# Values are written to openclaw config via 'openclaw config set'. # ── OpenClaw ───────────────────────────────────────────────────────────────── OPENCLAW_PATH=~/.openclaw -# ── HarborForge Plugin ─────────────────────────────────────────────────────── +# ── HarborForge Plugin (harbor-forge) ──────────────────────────────────────── HF_BACKEND_URL=https://hf-api.hangman-lab.top HF_API_KEY= HF_MONITOR_IDENTIFIER= +HF_MONITOR_PORT= +HF_REPORT_INTERVAL=30 +HF_CALENDAR_API_KEY= -# ── Yonexus.Server ─────────────────────────────────────────────────────────── -YONEXUS_PORT=18900 -YONEXUS_SECRET= - -# ── ContractorAgent ────────────────────────────────────────────────────────── +# ── ContractorAgent (contractor-agent) ─────────────────────────────────────── CONTRACTOR_BRIDGE_PORT=18800 CONTRACTOR_BRIDGE_API_KEY= + +# ── Dirigent (dirigent) ────────────────────────────────────────────────────── +DIRIGENT_MODERATOR_BOT_TOKEN= +DIRIGENT_SIDECAR_PORT= +DIRIGENT_NO_REPLY_PROVIDER= +DIRIGENT_NO_REPLY_MODEL= +DIRIGENT_SCHEDULE_IDENTIFIER= + +# ── PaddedCell (padded-cell) ───────────────────────────────────────────────── +PADDEDCELL_SECRET_MGR_PATH= +PADDEDCELL_OPENCLAW_PATH= + +# ── Yonexus.Server (yonexus-server) ────────────────────────────────────────── +YONEXUS_PORT=18900 +YONEXUS_NOTIFY_BOT_TOKEN= +YONEXUS_ADMIN_USER_ID= +YONEXUS_PUBLIC_WS_URL= diff --git a/scripts/setup-plugins.sh b/scripts/setup-plugins.sh index 5f5389e..41f74cd 100755 --- a/scripts/setup-plugins.sh +++ b/scripts/setup-plugins.sh @@ -16,6 +16,30 @@ ok() { printf "${GREEN} ✓${NC} %s\n" "$*"; } warn() { printf "${YELLOW} ⚠${NC} %s\n" "$*"; } err() { printf "${RED} ✗${NC} %s\n" "$*"; } +oc_set_str() { + local key="$1" val="$2" + if [[ -n "$val" ]]; then + openclaw config set "$key" "\"$val\"" --json + ok "config: $key" + fi +} + +oc_set_num() { + local key="$1" val="$2" + if [[ -n "$val" ]]; then + openclaw config set "$key" "$val" --json + ok "config: $key = $val" + fi +} + +oc_set_bool() { + local key="$1" val="$2" + if [[ -n "$val" ]]; then + openclaw config set "$key" "$val" --json + ok "config: $key = $val" + fi +} + usage() { cat </dev/null; then + return 0 + fi + if [[ "$action" == "install" ]] && [[ -f "$dir/package.json" ]]; then + if grep -q "\"install-plugin\"" "$dir/package.json" 2>/dev/null; then log " Running npm run install-plugin" - (cd "$dir" && npm run install-plugin) || { - err "$name install failed" - return 1 - } - ok "$name installed" - elif [[ -f "$dir/package.json" ]] && grep -q '"postinstall"' "$dir/package.json" 2>/dev/null; then + (cd "$dir" && npm run install-plugin) + return $? + elif grep -q "\"postinstall\"" "$dir/package.json" 2>/dev/null; then log " Running npm run postinstall" - (cd "$dir" && npm run postinstall) || { - err "$name install failed" - return 1 - } - ok "$name installed" - else - warn "No install script found for $name — submodule present but not auto-installable" + (cd "$dir" && npm run postinstall) + return $? fi fi + warn "No install script found for $name" + return 0 } -# ── Main ───────────────────────────────────────────────────────────────────── +# ── Plugin config mapping ──────────────────────────────────────────────────── +# Maps .env variables → openclaw config keys via 'openclaw config set'. +# Each plugin's config lives under plugins.entries..config.* + +configure_plugin() { + local name="$1" + if [[ "$SKIP_CONFIG" == true ]]; then return; fi + + log " Writing openclaw config" + case "$name" in + HarborForge.OpenclawPlugin) + local P="plugins.entries.harbor-forge.config" + oc_set_str "$P.backendUrl" "${HF_BACKEND_URL:-}" + oc_set_str "$P.apiKey" "${HF_API_KEY:-}" + oc_set_str "$P.identifier" "${HF_MONITOR_IDENTIFIER:-}" + oc_set_num "$P.monitor_port" "${HF_MONITOR_PORT:-}" + oc_set_num "$P.reportIntervalSec" "${HF_REPORT_INTERVAL:-}" + oc_set_str "$P.calendarApiKey" "${HF_CALENDAR_API_KEY:-}" + oc_set_bool "$P.enabled" "true" + ;; + + ContractorAgent) + local P="plugins.entries.contractor-agent.config" + oc_set_num "$P.bridgePort" "${CONTRACTOR_BRIDGE_PORT:-}" + oc_set_str "$P.bridgeApiKey" "${CONTRACTOR_BRIDGE_API_KEY:-}" + ;; + + Dirigent) + local P="plugins.entries.dirigent.config" + oc_set_str "$P.moderatorBotToken" "${DIRIGENT_MODERATOR_BOT_TOKEN:-}" + oc_set_num "$P.sideCarPort" "${DIRIGENT_SIDECAR_PORT:-}" + oc_set_str "$P.noReplyProvider" "${DIRIGENT_NO_REPLY_PROVIDER:-}" + oc_set_str "$P.noReplyModel" "${DIRIGENT_NO_REPLY_MODEL:-}" + oc_set_str "$P.scheduleIdentifier" "${DIRIGENT_SCHEDULE_IDENTIFIER:-}" + ;; + + PaddedCell) + local P="plugins.entries.padded-cell.config" + oc_set_str "$P.secretMgrPath" "${PADDEDCELL_SECRET_MGR_PATH:-}" + oc_set_str "$P.openclawProfilePath" "${PADDEDCELL_OPENCLAW_PATH:-}" + oc_set_bool "$P.enabled" "true" + ;; + + Yonexus.Server) + local P="plugins.entries.yonexus-server.config" + oc_set_str "$P.notifyBotToken" "${YONEXUS_NOTIFY_BOT_TOKEN:-}" + oc_set_str "$P.adminUserId" "${YONEXUS_ADMIN_USER_ID:-}" + oc_set_num "$P.listenPort" "${YONEXUS_PORT:-}" + oc_set_str "$P.publicWsUrl" "${YONEXUS_PUBLIC_WS_URL:-}" + ;; + + *) + warn "No config mapping for $name" + ;; + esac +} + +# ── Main loop ──────────────────────────────────────────────────────────────── + +run_plugin() { + local name="$1" + local dir="$PLUGINS_DIR/$name" + + echo + if [[ "$UNINSTALL" == true ]]; then + log "[uninstall] $name" + run_install_script "$name" "$dir" "uninstall" + return $? + fi + + log "[install] $name" + install_deps "$dir" + run_install_script "$name" "$dir" "install" || return $? + configure_plugin "$name" + ok "$name done" +} FAILURES=0