From e68332ca1cfdd8f44a342736e7631322974eb014 Mon Sep 17 00:00:00 2001
From: Matteo Bolognini <90386956+matteo-bolognini@users.noreply.github.com>
Date: Fri, 6 Feb 2026 15:45:00 +0000
Subject: [PATCH 1/5] Initial commit EA + Skills EA
---
support/openclaw_detection.sh | 248 +++++++++++++++++++++++++++
support/openclaw_skills_detection.sh | 96 +++++++++++
2 files changed, 344 insertions(+)
create mode 100644 support/openclaw_detection.sh
create mode 100644 support/openclaw_skills_detection.sh
diff --git a/support/openclaw_detection.sh b/support/openclaw_detection.sh
new file mode 100644
index 0000000..20fc735
--- /dev/null
+++ b/support/openclaw_detection.sh
@@ -0,0 +1,248 @@
+#!/bin/bash
+####################################################################################################
+#
+# Copyright (c) 2022, Jamf Software, LLC. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+# * Neither the name of the JAMF Software, LLC nor the
+# names of its contributors may be used to endorse or promote products
+# derived from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY JAMF SOFTWARE, LLC "AS IS" AND ANY
+# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED. IN NO EVENT SHALL JAMF SOFTWARE, LLC BE LIABLE FOR ANY
+# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+####################################################################################################
+
+################################################################################
+# Detects OpenClaw installations including:
+# - CLI binary (npm/pnpm global install)
+# - LaunchAgent services (current and legacy)
+# - macOS companion app
+# - Configuration directories
+# - Running processes/gateway
+# - Docker containers
+################################################################################
+
+# Initialize detection arrays
+declare -a findings
+
+# Function to check if a command exists
+command_exists() {
+ command -v "$1" >/dev/null 2>&1
+}
+
+# Function to check Docker containers
+check_docker() {
+ if command_exists docker; then
+ # Check for running OpenClaw containers
+ if docker ps --format '{{.Names}}' 2>/dev/null | grep -qi openclaw; then
+ container_names=$(docker ps --format '{{.Names}}' 2>/dev/null | grep -i openclaw | tr '\n' ', ' | sed 's/,$//')
+ findings+=("Docker-Running:${container_names}")
+ fi
+
+ # Check for stopped OpenClaw containers
+ if docker ps -a --format '{{.Names}}' 2>/dev/null | grep -qi openclaw; then
+ all_containers=$(docker ps -a --format '{{.Names}}' 2>/dev/null | grep -i openclaw | wc -l | tr -d ' ')
+ if [[ $all_containers -gt 0 ]]; then
+ findings+=("Docker-Containers:${all_containers}")
+ fi
+ fi
+ fi
+}
+
+# Function to check for CLI installation
+check_cli() {
+ # Check common npm global bin locations
+ local npm_prefix=""
+
+ if command_exists npm; then
+ npm_prefix=$(npm prefix -g 2>/dev/null)
+ if [[ -f "${npm_prefix}/bin/openclaw" ]]; then
+ # Get version if possible
+ local version=$("${npm_prefix}/bin/openclaw" --version 2>/dev/null | head -1)
+ findings+=("CLI-NPM:${npm_prefix}/bin/openclaw")
+ [[ -n "$version" ]] && findings+=("Version:${version}")
+ fi
+ fi
+
+ # Check standard locations
+ if [[ -f "/usr/local/bin/openclaw" ]]; then
+ findings+=("CLI-Binary:/usr/local/bin/openclaw")
+ fi
+
+ # Check if openclaw command is available in PATH
+ if command_exists openclaw && [[ ! " ${findings[@]} " =~ " CLI-" ]]; then
+ local openclaw_path=$(which openclaw 2>/dev/null)
+ findings+=("CLI-Path:${openclaw_path}")
+ fi
+}
+
+# Function to check macOS app
+check_macos_app() {
+ if [[ -d "/Applications/OpenClaw.app" ]]; then
+ # Get app version from Info.plist if available
+ local app_version=""
+ if [[ -f "/Applications/OpenClaw.app/Contents/Info.plist" ]]; then
+ app_version=$(/usr/libexec/PlistBuddy -c "Print :CFBundleShortVersionString" "/Applications/OpenClaw.app/Contents/Info.plist" 2>/dev/null)
+ fi
+ findings+=("App:/Applications/OpenClaw.app")
+ [[ -n "$app_version" ]] && findings+=("AppVersion:${app_version}")
+ fi
+
+ # Check user Applications folders
+ for user_home in /Users/*; do
+ [[ ! -d "$user_home" ]] && continue
+ [[ "$user_home" == "/Users/Shared" ]] && continue
+
+ if [[ -d "${user_home}/Applications/OpenClaw.app" ]]; then
+ local username=$(basename "$user_home")
+ findings+=("App-User:${username}")
+ fi
+ done
+}
+
+# Function to check LaunchAgents
+check_launch_agents() {
+ for user_home in /Users/*; do
+ [[ ! -d "$user_home" ]] && continue
+ [[ "$user_home" == "/Users/Shared" ]] && continue
+
+ local username=$(basename "$user_home")
+ local launch_agents_dir="${user_home}/Library/LaunchAgents"
+
+ # Check current naming convention
+ if [[ -f "${launch_agents_dir}/bot.molt.gateway.plist" ]]; then
+ # Check if it's loaded
+ local is_loaded=$(sudo -u "$username" launchctl list 2>/dev/null | grep -c "bot.molt.gateway")
+ if [[ $is_loaded -gt 0 ]]; then
+ findings+=("LaunchAgent-Active:${username}")
+ else
+ findings+=("LaunchAgent-Installed:${username}")
+ fi
+ fi
+
+ # Check legacy naming convention
+ if [[ -f "${launch_agents_dir}/com.openclaw.gateway.plist" ]]; then
+ findings+=("LaunchAgent-Legacy:${username}")
+ fi
+
+ # Check for profile-based agents (bot.molt.*)
+ local profile_agents=$(find "${launch_agents_dir}" -name "bot.molt.*.plist" 2>/dev/null | wc -l | tr -d ' ')
+ if [[ $profile_agents -gt 0 ]]; then
+ findings+=("LaunchAgent-Profiles:${username}:${profile_agents}")
+ fi
+ done
+}
+
+# Function to check configuration directories
+check_config_dirs() {
+ local found_configs=0
+
+ for user_home in /Users/*; do
+ [[ ! -d "$user_home" ]] && continue
+ [[ "$user_home" == "/Users/Shared" ]] && continue
+
+ local username=$(basename "$user_home")
+ local config_dir="${user_home}/.openclaw"
+
+ if [[ -d "$config_dir" ]]; then
+ found_configs=$((found_configs + 1))
+
+ # Check for main config file
+ if [[ -f "${config_dir}/openclaw.json" ]]; then
+ findings+=("Config:${username}")
+
+ # Check workspace
+ if [[ -d "${config_dir}/workspace" ]]; then
+ findings+=("Workspace:${username}")
+ fi
+
+ # Check for credentials
+ if [[ -f "${config_dir}/credentials/profiles.json" ]]; then
+ findings+=("Credentials:${username}")
+ fi
+ fi
+ fi
+
+ # Check for workspace directory (could be separate)
+ if [[ -d "${user_home}/openclaw/workspace" ]]; then
+ findings+=("Workspace-Alt:${username}")
+ fi
+ done
+
+ [[ $found_configs -gt 0 ]] && findings+=("ConfigDirs:${found_configs}")
+}
+
+# Function to check running processes
+check_processes() {
+ # Check for openclaw processes
+ if pgrep -f "openclaw" >/dev/null 2>&1; then
+ local process_count=$(pgrep -f "openclaw" | wc -l | tr -d ' ')
+ findings+=("Process-Running:${process_count}")
+
+ # Check if Gateway is running on default port
+ if lsof -i :18789 >/dev/null 2>&1; then
+ findings+=("Gateway-Port:18789")
+ fi
+ fi
+
+ # Check for node processes that might be running openclaw
+ if pgrep -f "node.*openclaw" >/dev/null 2>&1; then
+ local node_count=$(pgrep -f "node.*openclaw" | wc -l | tr -d ' ')
+ [[ $node_count -gt 0 ]] && findings+=("Node-Process:${node_count}")
+ fi
+}
+
+# Function to check for source installation
+check_source_install() {
+ for user_home in /Users/*; do
+ [[ ! -d "$user_home" ]] && continue
+ [[ "$user_home" == "/Users/Shared" ]] && continue
+
+ local username=$(basename "$user_home")
+
+ # Check common locations for git clone
+ for dir in "${user_home}/openclaw" "${user_home}/Documents/openclaw" "${user_home}/Projects/openclaw" "${user_home}/src/openclaw"; do
+ if [[ -d "$dir" ]] && [[ -f "$dir/package.json" ]]; then
+ # Verify it's actually openclaw by checking package.json
+ if grep -q '"name": "openclaw"' "$dir/package.json" 2>/dev/null; then
+ findings+=("Source:${username}:${dir}")
+ fi
+ fi
+ done
+ done
+}
+
+# Run all checks
+check_docker
+check_cli
+check_macos_app
+check_launch_agents
+check_config_dirs
+check_processes
+check_source_install
+
+# Format and return results
+if [[ ${#findings[@]} -eq 0 ]]; then
+ echo "Not Installed"
+else
+ # Join findings with semicolon separator
+ result=$(IFS=';'; echo "${findings[*]}")
+ echo "${result}"
+fi
+
+exit 0
diff --git a/support/openclaw_skills_detection.sh b/support/openclaw_skills_detection.sh
new file mode 100644
index 0000000..9cf8a20
--- /dev/null
+++ b/support/openclaw_skills_detection.sh
@@ -0,0 +1,96 @@
+#!/bin/bash
+
+####################################################################################################
+#
+# Copyright (c) 2022, Jamf Software, LLC. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+# * Neither the name of the JAMF Software, LLC nor the
+# names of its contributors may be used to endorse or promote products
+# derived from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY JAMF SOFTWARE, LLC "AS IS" AND ANY
+# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED. IN NO EVENT SHALL JAMF SOFTWARE, LLC BE LIABLE FOR ANY
+# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+####################################################################################################
+
+
+# Function to find openclaw directory
+find_openclaw_dir() {
+ # Get the current console user
+ CURRENT_USER=$(stat -f "%Su" /dev/console 2>/dev/null || who | awk '/console/ {print $1}' | head -n 1)
+
+ # If we can't determine user, try logname or $USER
+ if [ -z "$CURRENT_USER" ]; then
+ CURRENT_USER=$(logname 2>/dev/null || echo "$USER")
+ fi
+
+ # Get user's home directory
+ if [ -n "$CURRENT_USER" ]; then
+ USER_HOME=$(eval echo "~$CURRENT_USER")
+ else
+ USER_HOME="$HOME"
+ fi
+
+ # Define openclaw config path
+ OPENCLAW_DIR="${USER_HOME}/.openclaw"
+
+ echo "$OPENCLAW_DIR"
+}
+
+# Main execution
+OPENCLAW_DIR=$(find_openclaw_dir)
+OPENCLAW_JSON="${OPENCLAW_DIR}/openclaw.json"
+
+# Check if openclaw is installed
+if [ ! -d "$OPENCLAW_DIR" ]; then
+ echo "Not Installed"
+ exit 0
+fi
+
+# Check if config file exists
+if [ ! -f "$OPENCLAW_JSON" ]; then
+ echo "Config File Not Found"
+ exit 0
+fi
+
+# Check if jq is available
+if ! command -v jq &> /dev/null; then
+ echo "jq Not Available"
+ exit 0
+fi
+
+# Extract enabled skills
+ENABLED_SKILLS=$(cat "$OPENCLAW_JSON" | jq -r '.skills.entries | to_entries | .[] | select(.value.enabled).key' 2>/dev/null)
+
+# Check if extraction was successful
+if [ $? -ne 0 ]; then
+ echo "Error Parsing JSON"
+ exit 0
+fi
+
+# Check if any skills were found
+if [ -z "$ENABLED_SKILLS" ]; then
+ echo "No Enabled Skills"
+ exit 0
+fi
+
+# Format output: Convert newline-separated skills to comma-separated
+SKILLS_LIST=$(echo "$ENABLED_SKILLS" | tr '\n' ',' | sed 's/,$//')
+
+echo "$SKILLS_LIST"
+exit 0
From 0d8a1dc03b52b31c805ce0c17f84138d652b5f03 Mon Sep 17 00:00:00 2001
From: Matteo Bolognini <90386956+matteo-bolognini@users.noreply.github.com>
Date: Fri, 6 Feb 2026 15:56:24 +0000
Subject: [PATCH 2/5] Adding proper Copyright headers
---
support/openclaw_detection copy.sh | 241 +++++++++++++++++++++++++++++
1 file changed, 241 insertions(+)
create mode 100644 support/openclaw_detection copy.sh
diff --git a/support/openclaw_detection copy.sh b/support/openclaw_detection copy.sh
new file mode 100644
index 0000000..da5d12e
--- /dev/null
+++ b/support/openclaw_detection copy.sh
@@ -0,0 +1,241 @@
+#!/bin/bash
+####################################################################################################
+# Jamf Source Available License
+# Copyright 2025, Jamf Software LLC.
+# Persons receiving this software are permitted to use, adapt, and share it for
+# purposes associated with the function of their licensed Jamf products so long
+# as the Jamf copyright and these terms are included in any copies or derivitive
+# works.
+#
+# THIS SOFTWARE IS PROVIDED "AS-IS," WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL JAMF
+# SOFTWARE, LLC OR ANY OF ITS AFFILIATES BE LIABLE FOR ANY CLAIM, DAMAGES OR
+# OTHER LIABILITY, WHETHER IN CONTRACT, TORT, OR OTHERWISE, ARISING FROM, OUT OF
+# OR IN CONNECTION WITH THE SOFTWARE OR THE USE OF OR OTHER DEALINGS IN THE
+# SOFTWARE, INCLUDING BUT NOT LIMITED TO DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+# CONSEQUENTIAL OR PUNITIVE DAMAGES AND OTHER DAMAGES SUCH AS LOSS OF USE,
+# PROFITS, SAVINGS, TIME OR DATA, BUSINESS INTERRUPTION, OR PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES.
+#
+####################################################################################################
+
+################################################################################
+# Detects OpenClaw installations including:
+# - CLI binary (npm/pnpm global install)
+# - LaunchAgent services (current and legacy)
+# - macOS companion app
+# - Configuration directories
+# - Running processes/gateway
+# - Docker containers
+################################################################################
+
+# Initialize detection arrays
+declare -a findings
+
+# Function to check if a command exists
+command_exists() {
+ command -v "$1" >/dev/null 2>&1
+}
+
+# Function to check Docker containers
+check_docker() {
+ if command_exists docker; then
+ # Check for running OpenClaw containers
+ if docker ps --format '{{.Names}}' 2>/dev/null | grep -qi openclaw; then
+ container_names=$(docker ps --format '{{.Names}}' 2>/dev/null | grep -i openclaw | tr '\n' ', ' | sed 's/,$//')
+ findings+=("Docker-Running:${container_names}")
+ fi
+
+ # Check for stopped OpenClaw containers
+ if docker ps -a --format '{{.Names}}' 2>/dev/null | grep -qi openclaw; then
+ all_containers=$(docker ps -a --format '{{.Names}}' 2>/dev/null | grep -i openclaw | wc -l | tr -d ' ')
+ if [[ $all_containers -gt 0 ]]; then
+ findings+=("Docker-Containers:${all_containers}")
+ fi
+ fi
+ fi
+}
+
+# Function to check for CLI installation
+check_cli() {
+ # Check common npm global bin locations
+ local npm_prefix=""
+
+ if command_exists npm; then
+ npm_prefix=$(npm prefix -g 2>/dev/null)
+ if [[ -f "${npm_prefix}/bin/openclaw" ]]; then
+ # Get version if possible
+ local version=$("${npm_prefix}/bin/openclaw" --version 2>/dev/null | head -1)
+ findings+=("CLI-NPM:${npm_prefix}/bin/openclaw")
+ [[ -n "$version" ]] && findings+=("Version:${version}")
+ fi
+ fi
+
+ # Check standard locations
+ if [[ -f "/usr/local/bin/openclaw" ]]; then
+ findings+=("CLI-Binary:/usr/local/bin/openclaw")
+ fi
+
+ # Check if openclaw command is available in PATH
+ if command_exists openclaw && [[ ! " ${findings[@]} " =~ " CLI-" ]]; then
+ local openclaw_path=$(which openclaw 2>/dev/null)
+ findings+=("CLI-Path:${openclaw_path}")
+ fi
+}
+
+# Function to check macOS app
+check_macos_app() {
+ if [[ -d "/Applications/OpenClaw.app" ]]; then
+ # Get app version from Info.plist if available
+ local app_version=""
+ if [[ -f "/Applications/OpenClaw.app/Contents/Info.plist" ]]; then
+ app_version=$(/usr/libexec/PlistBuddy -c "Print :CFBundleShortVersionString" "/Applications/OpenClaw.app/Contents/Info.plist" 2>/dev/null)
+ fi
+ findings+=("App:/Applications/OpenClaw.app")
+ [[ -n "$app_version" ]] && findings+=("AppVersion:${app_version}")
+ fi
+
+ # Check user Applications folders
+ for user_home in /Users/*; do
+ [[ ! -d "$user_home" ]] && continue
+ [[ "$user_home" == "/Users/Shared" ]] && continue
+
+ if [[ -d "${user_home}/Applications/OpenClaw.app" ]]; then
+ local username=$(basename "$user_home")
+ findings+=("App-User:${username}")
+ fi
+ done
+}
+
+# Function to check LaunchAgents
+check_launch_agents() {
+ for user_home in /Users/*; do
+ [[ ! -d "$user_home" ]] && continue
+ [[ "$user_home" == "/Users/Shared" ]] && continue
+
+ local username=$(basename "$user_home")
+ local launch_agents_dir="${user_home}/Library/LaunchAgents"
+
+ # Check current naming convention
+ if [[ -f "${launch_agents_dir}/bot.molt.gateway.plist" ]]; then
+ # Check if it's loaded
+ local is_loaded=$(sudo -u "$username" launchctl list 2>/dev/null | grep -c "bot.molt.gateway")
+ if [[ $is_loaded -gt 0 ]]; then
+ findings+=("LaunchAgent-Active:${username}")
+ else
+ findings+=("LaunchAgent-Installed:${username}")
+ fi
+ fi
+
+ # Check legacy naming convention
+ if [[ -f "${launch_agents_dir}/com.openclaw.gateway.plist" ]]; then
+ findings+=("LaunchAgent-Legacy:${username}")
+ fi
+
+ # Check for profile-based agents (bot.molt.*)
+ local profile_agents=$(find "${launch_agents_dir}" -name "bot.molt.*.plist" 2>/dev/null | wc -l | tr -d ' ')
+ if [[ $profile_agents -gt 0 ]]; then
+ findings+=("LaunchAgent-Profiles:${username}:${profile_agents}")
+ fi
+ done
+}
+
+# Function to check configuration directories
+check_config_dirs() {
+ local found_configs=0
+
+ for user_home in /Users/*; do
+ [[ ! -d "$user_home" ]] && continue
+ [[ "$user_home" == "/Users/Shared" ]] && continue
+
+ local username=$(basename "$user_home")
+ local config_dir="${user_home}/.openclaw"
+
+ if [[ -d "$config_dir" ]]; then
+ found_configs=$((found_configs + 1))
+
+ # Check for main config file
+ if [[ -f "${config_dir}/openclaw.json" ]]; then
+ findings+=("Config:${username}")
+
+ # Check workspace
+ if [[ -d "${config_dir}/workspace" ]]; then
+ findings+=("Workspace:${username}")
+ fi
+
+ # Check for credentials
+ if [[ -f "${config_dir}/credentials/profiles.json" ]]; then
+ findings+=("Credentials:${username}")
+ fi
+ fi
+ fi
+
+ # Check for workspace directory (could be separate)
+ if [[ -d "${user_home}/openclaw/workspace" ]]; then
+ findings+=("Workspace-Alt:${username}")
+ fi
+ done
+
+ [[ $found_configs -gt 0 ]] && findings+=("ConfigDirs:${found_configs}")
+}
+
+# Function to check running processes
+check_processes() {
+ # Check for openclaw processes
+ if pgrep -f "openclaw" >/dev/null 2>&1; then
+ local process_count=$(pgrep -f "openclaw" | wc -l | tr -d ' ')
+ findings+=("Process-Running:${process_count}")
+
+ # Check if Gateway is running on default port
+ if lsof -i :18789 >/dev/null 2>&1; then
+ findings+=("Gateway-Port:18789")
+ fi
+ fi
+
+ # Check for node processes that might be running openclaw
+ if pgrep -f "node.*openclaw" >/dev/null 2>&1; then
+ local node_count=$(pgrep -f "node.*openclaw" | wc -l | tr -d ' ')
+ [[ $node_count -gt 0 ]] && findings+=("Node-Process:${node_count}")
+ fi
+}
+
+# Function to check for source installation
+check_source_install() {
+ for user_home in /Users/*; do
+ [[ ! -d "$user_home" ]] && continue
+ [[ "$user_home" == "/Users/Shared" ]] && continue
+
+ local username=$(basename "$user_home")
+
+ # Check common locations for git clone
+ for dir in "${user_home}/openclaw" "${user_home}/Documents/openclaw" "${user_home}/Projects/openclaw" "${user_home}/src/openclaw"; do
+ if [[ -d "$dir" ]] && [[ -f "$dir/package.json" ]]; then
+ # Verify it's actually openclaw by checking package.json
+ if grep -q '"name": "openclaw"' "$dir/package.json" 2>/dev/null; then
+ findings+=("Source:${username}:${dir}")
+ fi
+ fi
+ done
+ done
+}
+
+# Run all checks
+check_docker
+check_cli
+check_macos_app
+check_launch_agents
+check_config_dirs
+check_processes
+check_source_install
+
+# Format and return results
+if [[ ${#findings[@]} -eq 0 ]]; then
+ echo "Not Installed"
+else
+ # Join findings with semicolon separator
+ result=$(IFS=';'; echo "${findings[*]}")
+ echo "${result}"
+fi
+
+exit 0
From 09146c4039b7bd5401d79fe3fefba4e2c2bbe1a7 Mon Sep 17 00:00:00 2001
From: Matteo Bolognini <90386956+matteo-bolognini@users.noreply.github.com>
Date: Fri, 6 Feb 2026 16:00:23 +0000
Subject: [PATCH 3/5] Attempt 3
---
support/openclaw_detection.sh | 41 +++++++++++++++--------------------
1 file changed, 18 insertions(+), 23 deletions(-)
diff --git a/support/openclaw_detection.sh b/support/openclaw_detection.sh
index 20fc735..85e732e 100644
--- a/support/openclaw_detection.sh
+++ b/support/openclaw_detection.sh
@@ -1,29 +1,24 @@
#!/bin/bash
####################################################################################################
+# Jamf Source Available License
+# Copyright 2025, Jamf Software LLC.
+# This work is licensed under the terms of the Jamf Source Available License:
+# https://github.com/jamf/scripts/blob/main/LICENCE.md
+# Persons receiving this software are permitted to use, adapt, and share it for
+# purposes associated with the function of their licensed Jamf products so long
+# as the Jamf copyright and these terms are included in any copies or derivitive
+# works.
#
-# Copyright (c) 2022, Jamf Software, LLC. All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions are met:
-# * Redistributions of source code must retain the above copyright
-# notice, this list of conditions and the following disclaimer.
-# * Redistributions in binary form must reproduce the above copyright
-# notice, this list of conditions and the following disclaimer in the
-# documentation and/or other materials provided with the distribution.
-# * Neither the name of the JAMF Software, LLC nor the
-# names of its contributors may be used to endorse or promote products
-# derived from this software without specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY JAMF SOFTWARE, LLC "AS IS" AND ANY
-# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-# DISCLAIMED. IN NO EVENT SHALL JAMF SOFTWARE, LLC BE LIABLE FOR ANY
-# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
-# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+# THIS SOFTWARE IS PROVIDED "AS-IS," WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL JAMF
+# SOFTWARE, LLC OR ANY OF ITS AFFILIATES BE LIABLE FOR ANY CLAIM, DAMAGES OR
+# OTHER LIABILITY, WHETHER IN CONTRACT, TORT, OR OTHERWISE, ARISING FROM, OUT OF
+# OR IN CONNECTION WITH THE SOFTWARE OR THE USE OF OR OTHER DEALINGS IN THE
+# SOFTWARE, INCLUDING BUT NOT LIMITED TO DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+# CONSEQUENTIAL OR PUNITIVE DAMAGES AND OTHER DAMAGES SUCH AS LOSS OF USE,
+# PROFITS, SAVINGS, TIME OR DATA, BUSINESS INTERRUPTION, OR PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES.
#
####################################################################################################
From 112eb33326ad939c66fe90cc6a3d7460f8d23bc5 Mon Sep 17 00:00:00 2001
From: Matteo Bolognini <90386956+matteo-bolognini@users.noreply.github.com>
Date: Fri, 6 Feb 2026 16:03:23 +0000
Subject: [PATCH 4/5] Take 4
---
support/openclaw_detection copy.sh | 23 +++--------------------
1 file changed, 3 insertions(+), 20 deletions(-)
diff --git a/support/openclaw_detection copy.sh b/support/openclaw_detection copy.sh
index da5d12e..78cdbc8 100644
--- a/support/openclaw_detection copy.sh
+++ b/support/openclaw_detection copy.sh
@@ -1,24 +1,7 @@
#!/bin/bash
-####################################################################################################
-# Jamf Source Available License
-# Copyright 2025, Jamf Software LLC.
-# Persons receiving this software are permitted to use, adapt, and share it for
-# purposes associated with the function of their licensed Jamf products so long
-# as the Jamf copyright and these terms are included in any copies or derivitive
-# works.
-#
-# THIS SOFTWARE IS PROVIDED "AS-IS," WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-# FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL JAMF
-# SOFTWARE, LLC OR ANY OF ITS AFFILIATES BE LIABLE FOR ANY CLAIM, DAMAGES OR
-# OTHER LIABILITY, WHETHER IN CONTRACT, TORT, OR OTHERWISE, ARISING FROM, OUT OF
-# OR IN CONNECTION WITH THE SOFTWARE OR THE USE OF OR OTHER DEALINGS IN THE
-# SOFTWARE, INCLUDING BUT NOT LIMITED TO DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
-# CONSEQUENTIAL OR PUNITIVE DAMAGES AND OTHER DAMAGES SUCH AS LOSS OF USE,
-# PROFITS, SAVINGS, TIME OR DATA, BUSINESS INTERRUPTION, OR PROCUREMENT OF
-# SUBSTITUTE GOODS OR SERVICES.
-#
-####################################################################################################
+# Copyright , Jamf Software LLC
+# This work is licensed under the terms of the Jamf Source Available License:
+# https://github.com/jamf/scripts/blob/main/LICENCE.md
################################################################################
# Detects OpenClaw installations including:
From b6869d7cfbaedf22a3fe459ecb88a7fd88bf4612 Mon Sep 17 00:00:00 2001
From: Matteo Bolognini <90386956+matteo-bolognini@users.noreply.github.com>
Date: Fri, 6 Feb 2026 16:04:18 +0000
Subject: [PATCH 5/5] 5th
---
support/openclaw_detection copy.sh | 9 +++++++--
support/openclaw_detection.sh | 22 ++++------------------
2 files changed, 11 insertions(+), 20 deletions(-)
diff --git a/support/openclaw_detection copy.sh b/support/openclaw_detection copy.sh
index 78cdbc8..0244c6d 100644
--- a/support/openclaw_detection copy.sh
+++ b/support/openclaw_detection copy.sh
@@ -1,7 +1,12 @@
#!/bin/bash
-# Copyright , Jamf Software LLC
-# This work is licensed under the terms of the Jamf Source Available License:
+###########################################################################################################################
+#
+# Copyright 2025, Jamf Software LLC.
+# This work is licensed under the terms of the Jamf Source Available License
# https://github.com/jamf/scripts/blob/main/LICENCE.md
+#
+###########################################################################################################################
+#
################################################################################
# Detects OpenClaw installations including:
diff --git a/support/openclaw_detection.sh b/support/openclaw_detection.sh
index 85e732e..0244c6d 100644
--- a/support/openclaw_detection.sh
+++ b/support/openclaw_detection.sh
@@ -1,26 +1,12 @@
#!/bin/bash
-####################################################################################################
-# Jamf Source Available License
+###########################################################################################################################
+#
# Copyright 2025, Jamf Software LLC.
-# This work is licensed under the terms of the Jamf Source Available License:
+# This work is licensed under the terms of the Jamf Source Available License
# https://github.com/jamf/scripts/blob/main/LICENCE.md
-# Persons receiving this software are permitted to use, adapt, and share it for
-# purposes associated with the function of their licensed Jamf products so long
-# as the Jamf copyright and these terms are included in any copies or derivitive
-# works.
#
-# THIS SOFTWARE IS PROVIDED "AS-IS," WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-# FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL JAMF
-# SOFTWARE, LLC OR ANY OF ITS AFFILIATES BE LIABLE FOR ANY CLAIM, DAMAGES OR
-# OTHER LIABILITY, WHETHER IN CONTRACT, TORT, OR OTHERWISE, ARISING FROM, OUT OF
-# OR IN CONNECTION WITH THE SOFTWARE OR THE USE OF OR OTHER DEALINGS IN THE
-# SOFTWARE, INCLUDING BUT NOT LIMITED TO DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
-# CONSEQUENTIAL OR PUNITIVE DAMAGES AND OTHER DAMAGES SUCH AS LOSS OF USE,
-# PROFITS, SAVINGS, TIME OR DATA, BUSINESS INTERRUPTION, OR PROCUREMENT OF
-# SUBSTITUTE GOODS OR SERVICES.
+###########################################################################################################################
#
-####################################################################################################
################################################################################
# Detects OpenClaw installations including: