Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 45 additions & 16 deletions openclaw/install.sh
Original file line number Diff line number Diff line change
Expand Up @@ -80,17 +80,24 @@ 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
exec 3</dev/tty
TTY_FD=3
else
# No terminal available at all
if [[ "$NON_INTERACTIVE" != "true" ]]; then
echo "Error: No terminal available for interactive prompts." >&2
elif [[ "$NON_INTERACTIVE" == "true" ]]; then
# Non-interactive mode never needs prompt input.
# Avoid touching /dev/tty in headless environments.
TTY_FD=0
elif [[ -r /dev/tty ]]; then
# stdin is piped (curl | bash) but /dev/tty may be available
if exec 3</dev/tty 2>/dev/null; then
TTY_FD=3
else
echo "Error: /dev/tty exists but is not readable." >&2
echo "Use --non-interactive or run directly: bash install.sh" >&2
exit 1
fi
else
# No terminal available at all
echo "Error: No terminal available for interactive prompts." >&2
echo "Use --non-interactive or run directly: bash install.sh" >&2
exit 1
fi
}

Expand Down Expand Up @@ -780,26 +787,33 @@ install_plugin() {
# We temporarily remove the entry and save the config so `plugins install` can run,
# then `plugins install` + `plugins enable` will re-create it properly.
local oc_config="${HOME}/.openclaw/openclaw.json"
local saved_plugin_config=""
local saved_plugin_config="{}"
local had_allow_claude_mem="false"
if [[ -f "$oc_config" ]]; then
saved_plugin_config=$(INSTALLER_CONFIG_FILE="$oc_config" node -e "
readarray -t __restore_state < <(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'));
const entry = config?.plugins?.entries?.['claude-mem'];
if (entry || config?.plugins?.slots?.memory === 'claude-mem') {
// 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
const allow = config?.plugins?.allow;
const hadAllow = Array.isArray(allow) && allow.includes('claude-mem');
const needsPatch = Boolean(entry) || config?.plugins?.slots?.memory === 'claude-mem' || hadAllow;
process.stdout.write(JSON.stringify(entry?.config || {}));
process.stdout.write('\n');
process.stdout.write(hadAllow ? 'true' : 'false');
if (needsPatch) {
if (entry) delete config.plugins.entries['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') {
delete config.plugins.slots.memory;
}
if (Array.isArray(config?.plugins?.allow)) {
config.plugins.allow = config.plugins.allow.filter((id) => id !== 'claude-mem');
}
fs.writeFileSync(configPath, JSON.stringify(config, null, 2));
}
" 2>/dev/null) || true
saved_plugin_config="${__restore_state[0]:-{}}"
had_allow_claude_mem="${__restore_state[1]:-false}"
fi

# Install the plugin using OpenClaw's CLI
Expand All @@ -818,6 +832,21 @@ install_plugin() {
exit 1
fi

# Re-apply allowlist entry if it existed before cleanup.
if [[ "$had_allow_claude_mem" == "true" ]]; 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 || warn "Could not restore claude-mem allowlist entry"
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
Expand Down