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.<id>.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.
This commit is contained in:
29
.env.example
29
.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=
|
||||
|
||||
@@ -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 <<EOF
|
||||
Usage: $(basename "$0") [options] [plugin ...]
|
||||
@@ -28,11 +52,13 @@ Options:
|
||||
--list List available plugins and exit
|
||||
--uninstall Uninstall plugins instead of installing
|
||||
--skip-deps Skip npm install step
|
||||
--skip-config Skip openclaw config set step
|
||||
-h, --help Show this help
|
||||
|
||||
Plugins: PaddedCell, ContractorAgent, Dirigent, HarborForge.OpenclawPlugin, Yonexus.Server
|
||||
|
||||
Sensitive configuration is read from .env (see .env.example for reference).
|
||||
Sensitive configuration is read from .env (see .env.example for reference)
|
||||
and written to openclaw config via 'openclaw config set'.
|
||||
EOF
|
||||
exit 0
|
||||
}
|
||||
@@ -41,6 +67,7 @@ EOF
|
||||
|
||||
UNINSTALL=false
|
||||
SKIP_DEPS=false
|
||||
SKIP_CONFIG=false
|
||||
SELECTED_PLUGINS=()
|
||||
|
||||
while [[ $# -gt 0 ]]; do
|
||||
@@ -49,6 +76,7 @@ while [[ $# -gt 0 ]]; do
|
||||
--list) ls "$PLUGINS_DIR"; exit 0 ;;
|
||||
--uninstall) UNINSTALL=true; shift ;;
|
||||
--skip-deps) SKIP_DEPS=true; shift ;;
|
||||
--skip-config) SKIP_CONFIG=true; shift ;;
|
||||
-h|--help) usage ;;
|
||||
-*) err "Unknown option: $1"; usage ;;
|
||||
*) SELECTED_PLUGINS+=("$1"); shift ;;
|
||||
@@ -93,7 +121,7 @@ for p in "${SELECTED_PLUGINS[@]}"; do
|
||||
fi
|
||||
done
|
||||
|
||||
# ── Per-plugin install/uninstall ─────────────────────────────────────────────
|
||||
# ── Per-plugin helpers ───────────────────────────────────────────────────────
|
||||
|
||||
install_deps() {
|
||||
local dir="$1"
|
||||
@@ -122,79 +150,109 @@ find_install_script() {
|
||||
done
|
||||
}
|
||||
|
||||
run_install_script() {
|
||||
local name="$1" dir="$2" action="$3"
|
||||
local script
|
||||
script=$(find_install_script "$dir")
|
||||
if [[ -n "$script" ]]; then
|
||||
log " Running $(basename "$script") --$action"
|
||||
node "$script" "--$action" || {
|
||||
err "$name script failed"
|
||||
return 1
|
||||
}
|
||||
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)
|
||||
return $?
|
||||
elif grep -q "\"postinstall\"" "$dir/package.json" 2>/dev/null; then
|
||||
log " Running npm run postinstall"
|
||||
(cd "$dir" && npm run postinstall)
|
||||
return $?
|
||||
fi
|
||||
fi
|
||||
warn "No install script found for $name"
|
||||
return 0
|
||||
}
|
||||
|
||||
# ── Plugin config mapping ────────────────────────────────────────────────────
|
||||
# Maps .env variables → openclaw config keys via 'openclaw config set'.
|
||||
# Each plugin's config lives under plugins.entries.<id>.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"
|
||||
local action="install"
|
||||
[[ "$UNINSTALL" == true ]] && action="uninstall"
|
||||
|
||||
echo
|
||||
log "[$action] $name"
|
||||
|
||||
if [[ "$UNINSTALL" == true ]]; then
|
||||
local script
|
||||
script=$(find_install_script "$dir")
|
||||
if [[ -n "$script" ]]; then
|
||||
node "$script" --uninstall || warn "$name uninstall script returned non-zero"
|
||||
else
|
||||
warn "No install script found for $name — skipping"
|
||||
fi
|
||||
return
|
||||
log "[uninstall] $name"
|
||||
run_install_script "$name" "$dir" "uninstall"
|
||||
return $?
|
||||
fi
|
||||
|
||||
# Install dependencies
|
||||
log "[install] $name"
|
||||
install_deps "$dir"
|
||||
|
||||
# Plugin-specific env setup (pass through to install scripts via env)
|
||||
case "$name" in
|
||||
HarborForge.OpenclawPlugin)
|
||||
export HF_BACKEND_URL="${HF_BACKEND_URL:-}"
|
||||
export HF_API_KEY="${HF_API_KEY:-}"
|
||||
export HF_MONITOR_IDENTIFIER="${HF_MONITOR_IDENTIFIER:-}"
|
||||
;;
|
||||
Yonexus.Server)
|
||||
export YONEXUS_PORT="${YONEXUS_PORT:-}"
|
||||
export YONEXUS_SECRET="${YONEXUS_SECRET:-}"
|
||||
;;
|
||||
ContractorAgent)
|
||||
export CONTRACTOR_BRIDGE_PORT="${CONTRACTOR_BRIDGE_PORT:-18800}"
|
||||
export CONTRACTOR_BRIDGE_API_KEY="${CONTRACTOR_BRIDGE_API_KEY:-}"
|
||||
;;
|
||||
esac
|
||||
|
||||
# Run install script
|
||||
local script
|
||||
script=$(find_install_script "$dir")
|
||||
if [[ -n "$script" ]]; then
|
||||
log " Running $(basename "$script")"
|
||||
node "$script" --install || {
|
||||
err "$name install script failed"
|
||||
return 1
|
||||
run_install_script "$name" "$dir" "install" || return $?
|
||||
configure_plugin "$name"
|
||||
ok "$name done"
|
||||
}
|
||||
ok "$name installed"
|
||||
else
|
||||
# Some plugins (like PaddedCell) may have a different layout
|
||||
if [[ -f "$dir/package.json" ]] && 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
|
||||
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"
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
# ── Main ─────────────────────────────────────────────────────────────────────
|
||||
|
||||
FAILURES=0
|
||||
|
||||
|
||||
Reference in New Issue
Block a user