From 4324f6bbc1b81759651431734758c815116b2076 Mon Sep 17 00:00:00 2001 From: Jason Date: Mon, 23 Mar 2026 18:28:48 +0800 Subject: [PATCH 1/2] fix(openclaw): handle stale plugins.allow and non-interactive tty in installer --- openclaw/install.sh | 38 ++++++++++++++++++++++++++++++-------- 1 file changed, 30 insertions(+), 8 deletions(-) diff --git a/openclaw/install.sh b/openclaw/install.sh index bd509fc4..5a5d73b2 100755 --- a/openclaw/install.sh +++ b/openclaw/install.sh @@ -80,17 +80,18 @@ setup_tty() { if [[ -t 0 ]]; then # stdin IS a terminal — use it directly TTY_FD=0 - elif [[ -e /dev/tty ]]; then - # stdin is piped (curl | bash) but /dev/tty is available + elif [[ "$NON_INTERACTIVE" == "true" ]]; then + # In non-interactive mode, do not require /dev/tty + TTY_FD=0 + elif [[ -r /dev/tty ]]; then + # stdin is piped (curl | bash) but /dev/tty is available and readable exec 3&2 - echo "Use --non-interactive or run directly: bash install.sh" >&2 - exit 1 - fi + echo "Error: No terminal available for interactive prompts." >&2 + echo "Use --non-interactive or run directly: bash install.sh" >&2 + exit 1 fi } @@ -787,11 +788,16 @@ install_plugin() { const configPath = process.env.INSTALLER_CONFIG_FILE; const config = JSON.parse(fs.readFileSync(configPath, 'utf8')); const entry = config?.plugins?.entries?.['claude-mem']; - if (entry || config?.plugins?.slots?.memory === 'claude-mem') { + const allowHasClaudeMem = Array.isArray(config?.plugins?.allow) && config.plugins.allow.includes('claude-mem'); + if (entry || config?.plugins?.slots?.memory === 'claude-mem' || allowHasClaudeMem) { // Save the config block so we can restore it after install process.stdout.write(JSON.stringify(entry?.config || {})); // Remove the stale entry so OpenClaw CLI can run if (entry) delete config.plugins.entries['claude-mem']; + // Also remove stale allowlist reference — this alone can block ALL CLI commands + if (Array.isArray(config?.plugins?.allow)) { + config.plugins.allow = config.plugins.allow.filter((x) => x !== 'claude-mem'); + } // Also remove the slot reference — if the slot points to a plugin // that isn't in entries, OpenClaw's config validator rejects ALL commands if (config?.plugins?.slots?.memory === 'claude-mem') { @@ -818,6 +824,22 @@ install_plugin() { exit 1 fi + # Ensure claude-mem is present in plugins.allow after successful install+enable. + # Some OpenClaw environments require explicit allowlisting for local plugins. + if [[ -f "$oc_config" ]]; then + INSTALLER_CONFIG_FILE="$oc_config" node -e " + const fs = require('fs'); + const configPath = process.env.INSTALLER_CONFIG_FILE; + const config = JSON.parse(fs.readFileSync(configPath, 'utf8')); + if (!config.plugins) config.plugins = {}; + if (!Array.isArray(config.plugins.allow)) config.plugins.allow = []; + if (!config.plugins.allow.includes('claude-mem')) { + config.plugins.allow.push('claude-mem'); + fs.writeFileSync(configPath, JSON.stringify(config, null, 2)); + } + " 2>/dev/null || true + fi + # Restore saved plugin config (workerPort, syncMemoryFile, observationFeed, etc.) # from any pre-existing installation that was temporarily removed above. if [[ -n "$saved_plugin_config" && "$saved_plugin_config" != "{}" ]]; then From b6f9950bb3c5fc92136ea17935590a896363fbbb Mon Sep 17 00:00:00 2001 From: JasonRD Date: Tue, 24 Mar 2026 09:14:27 +0800 Subject: [PATCH 2/2] fix(installer): make post-install allowlist write guaranteed - Remove '|| true' that was hiding write failures - Add fallback path when config doesn't exist yet (triggers materialization) - Add logging for allowlist operations - Report warnings on write failures instead of silent failure Addresses CodeRabbit review comment on PR #1457 --- openclaw/install.sh | 31 +++++++++++++++++++++++++++++-- 1 file changed, 29 insertions(+), 2 deletions(-) diff --git a/openclaw/install.sh b/openclaw/install.sh index 5a5d73b2..9c12326a 100755 --- a/openclaw/install.sh +++ b/openclaw/install.sh @@ -826,8 +826,9 @@ install_plugin() { # Ensure claude-mem is present in plugins.allow after successful install+enable. # Some OpenClaw environments require explicit allowlisting for local plugins. + # This write is guaranteed: if config doesn't exist, configure_memory_slot() will create it. if [[ -f "$oc_config" ]]; then - INSTALLER_CONFIG_FILE="$oc_config" node -e " + if ! INSTALLER_CONFIG_FILE="$oc_config" node -e " const fs = require('fs'); const configPath = process.env.INSTALLER_CONFIG_FILE; const config = JSON.parse(fs.readFileSync(configPath, 'utf8')); @@ -836,8 +837,34 @@ install_plugin() { if (!config.plugins.allow.includes('claude-mem')) { config.plugins.allow.push('claude-mem'); fs.writeFileSync(configPath, JSON.stringify(config, null, 2)); + console.log('Added claude-mem to plugins.allow'); + } else { + console.log('claude-mem already in plugins.allow'); } - " 2>/dev/null || true + " 2>&1; then + warn "Failed to write plugins.allow — claude-mem may need manual allowlisting" + fi + else + # Config doesn't exist yet; configure_memory_slot() will create it with plugins.allow + # We'll add claude-mem to the allowlist in a follow-up step after config is materialized + info "OpenClaw config not yet materialized; will ensure allowlist in post-install" + # Force config materialization by running a harmless OpenClaw command + if run_openclaw status --json >/dev/null 2>&1 && [[ -f "$oc_config" ]]; then + if ! INSTALLER_CONFIG_FILE="$oc_config" node -e " + const fs = require('fs'); + const configPath = process.env.INSTALLER_CONFIG_FILE; + const config = JSON.parse(fs.readFileSync(configPath, 'utf8')); + if (!config.plugins) config.plugins = {}; + if (!Array.isArray(config.plugins.allow)) config.plugins.allow = []; + if (!config.plugins.allow.includes('claude-mem')) { + config.plugins.allow.push('claude-mem'); + fs.writeFileSync(configPath, JSON.stringify(config, null, 2)); + console.log('Added claude-mem to plugins.allow (post-materialization)'); + } + " 2>&1; then + warn "Failed to write plugins.allow after materialization — configure manually" + fi + fi fi # Restore saved plugin config (workerPort, syncMemoryFile, observationFeed, etc.)