From 601262abec357626efcd324f0ec90a3c134a000c Mon Sep 17 00:00:00 2001 From: orion Date: Thu, 16 Apr 2026 08:02:54 +0000 Subject: [PATCH] refactor: setup-plugins writes config via openclaw config set Instead of just exporting env vars (which are ephemeral), the script now calls 'openclaw config set' to persist each plugin's sensitive fields (apiKey, tokens, ports, etc.) under plugins.entries..config. Config key mapping per plugin is derived from each plugin's openclaw.plugin.json configSchema. .env.example updated with all available variables and their corresponding plugin IDs. --- .env.example | 29 ++++-- scripts/setup-plugins.sh | 200 +++++++++++++++++++++++++-------------- 2 files changed, 152 insertions(+), 77 deletions(-) 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