]> ### 0.1.31 - Fix /api/array/parity/status showing no/stale activity: read live state from `mdcmd status` instead of the unreliable GraphQL parityCheckStatus; existing fields (running/progress/speed/errors) now reflect reality, plus new paused/correcting/action/position/size/speedHuman/lastCheck (#14, thanks @rodaballo) ### 0.1.30 - Fix .txz package chowning host paths (/, /usr, /usr/local, ...) to UID 1001 on install, breaking sshd StrictModes key auth (#13) - Build now uses `tar --owner=root --group=root --numeric-owner` so directory metadata is always root:root - Postinstall heals existing systems by chowning the affected host paths back to root:root (no-op on healthy systems) ### 0.1.29 - Fix POST /api/docker/containers rejecting valid registry-prefixed image references like `host:port/path:tag` and digest refs like `image@sha256:...` (#12) ### 0.1.28 - Align plugin min Unraid version with documented requirement: min=7.0.0, drop legacy max constraint (#11, thanks @mstrhakr) ### 0.1.27 - Add memory stats (total, used, free, percent) to /api/system/info and /api/system/metrics - Add CPU load averages (1m, 5m, 15m) to /api/system/info and /api/system/metrics - Add disk usage (used, free, percent) to /api/disks endpoints via df - Make /api/system/metrics a lightweight endpoint for polling (memory + CPU load only) ### 0.1.26 - Security: fix command injection in syslog and notification endpoints (execSync to execFileAsync) - Security: fix path traversal in notification archive/delete and docker template filename - Security: restrict CORS to local network origins only - Security: stop exposing Unraid API key in settings page HTML - Security: remove internal error details from API error responses - Security: add rate limiting on API authentication (10 attempts/min per IP) - Security: add input validation on docker:create parameters (image, ports, volumes, env, network) - Security: validate share update fields (floor, splitLevel, comment) - Security: set restrictive file permissions on config, permissions, and log files - Security: enforce strict boolean types in permission saves - Security: require WebGUI authentication on activity log PHP endpoints - Security: move CSRF token from global JS variable to data attribute ### 0.1.25 - Add Unraid WebUI Port setting for non-standard port configurations - GraphQL URL is now constructed automatically from the port (no more manual URL editing) ### 0.1.24 - Remove GraphQL URL from settings (hardcode to http://localhost/graphql) - Prevents misconfiguration that caused 500 errors on all GraphQL-based endpoints ### 0.1.23 - Fix /api/health reporting version "0.1.0" instead of actual installed version - Version now read from .plg file automatically on each release ### 0.1.22 - Fix Docker inspect, logs, and all actions (start/stop/restart/pause/unpause) failing with 400 Bad Request - Switch all Docker operations from GraphQL to CLI (docker inspect, docker logs, docker start, etc.) - Switch all VM operations from GraphQL to virsh CLI - Fix OpenAI function calling compatibility (add properties to parameter-less tool schemas) - Fix global TLS bypass in OpenClaw plugin (scoped https.Agent instead of process-wide env var) - Fix XML injection in docker:create template generation - Restrict volume pre-creation to /mnt/ paths only - Add ADMIN API key requirement to docs - Correct README route paths (/api/array/status, /api/array/parity/status) ### 0.1.21 - Add version number, GitHub link, and buy me a coffee to dashboard - Fix CA template category and support URL ### 0.1.20 - Add human-readable size fields (freeHuman, sizeHuman) to shares, disks, and array responses ### 0.1.19 - Keep service running when array stops (most tools work without the array) - Add Unraid API key setup step to documentation ### 0.1.18 - Fix CI typecheck for openclaw-plugin tsconfig rootDir ### 0.1.17 - HTTPS with auto-generated self-signed TLS certificate - Share editing (PATCH /api/shares/:name) - OpenClaw plugin published to npm ### 0.1.6 - Fix VMs query: remove non-existent fields (coreCount, ramAllocation, primaryGPU, description, autoStart) - Auto-restart service on plugin upgrade ### 0.1.4 - Fix all GraphQL queries to match Unraid 7 actual schema - Resolved 400 Bad Request errors on system, shares, array, disks, notifications, users endpoints - Stub network and logs endpoints (no root queries available in Unraid 7) ### 0.1.3 - Initial public release - REST API gateway for AI agents on Unraid - Full resource:action permission matrix with WebGUI management - Docker, VM, Array, System, Shares, Notifications, Network management - SHA-256 API key authentication - Activity logging with JSONL format - Single-page tabbed UI (Dashboard, Settings, Permissions, Activity Log) **UnraidClaw** is a permission-enforcing REST API gateway that lets AI agents manage your Unraid server. It proxies requests to Unraid's built-in GraphQL API with fine-grained access control, so you can safely expose Docker, VMs, Array, Shares, System, Notifications, and Network management to AI tools. **Features:** - Full resource:action permission matrix configurable from the WebGUI - SHA-256 API key authentication - Activity logging with JSONL format - Tabbed settings UI (Dashboard, Settings, Permissions, Activity Log) - Requires Node.js 22+ (built-in on Unraid 7.x) #!/bin/bash # Check if Node.js is available (check multiple common paths) NODE_BIN="" for p in /usr/local/bin/node /usr/bin/node; do if [ -x "$p" ]; then NODE_BIN="$p" break fi done if [ -z "$NODE_BIN" ]; then NODE_BIN=$(which node 2>/dev/null || true) fi NODE_VERSION=$($NODE_BIN --version 2>/dev/null | sed 's/v//') if [ -z "$NODE_VERSION" ]; then echo "ERROR: Node.js is not installed." echo "For Unraid 6.x, install Node.js via NerdPack." echo "Unraid 7.x should have Node.js built-in." echo "Searched: /usr/local/bin/node, /usr/bin/node, PATH" exit 1 fi NODE_MAJOR=$(echo "$NODE_VERSION" | cut -d. -f1) if [ "$NODE_MAJOR" -lt 22 ]; then echo "WARNING: Node.js v${NODE_VERSION} detected. v22+ recommended." echo "Some features may not work correctly." fi echo "Node.js v${NODE_VERSION} detected. OK." &pkgURL; &md5; #!/bin/bash PLUGIN="&name;" CFG_DIR="/boot/config/plugins/${PLUGIN}" mkdir -p "$CFG_DIR" # Heal host paths chowned to UID 1001 by v0.1.27-v0.1.29 (issue #13). # These are always root-owned on Unraid; this is a no-op on healthy systems. chown root:root / /usr /usr/local /usr/local/emhttp /usr/local/sbin /etc /etc/rc.d 2>/dev/null || true # Create default config if not present if [ ! -f "${CFG_DIR}/unraidclaw.cfg" ]; then cat > "${CFG_DIR}/unraidclaw.cfg" << 'CFGEOF' SERVICE="disable" PORT="9876" HOST="0.0.0.0" API_KEY_HASH="" GRAPHQL_URL="http://localhost/graphql" UNRAID_API_KEY="" LOG_FILE="/boot/config/plugins/unraidclaw/activity.jsonl" MAX_LOG_SIZE="10485760" CFGEOF echo "Created default config." fi # Create default permissions if not present if [ ! -f "${CFG_DIR}/permissions.json" ]; then echo '{}' > "${CFG_DIR}/permissions.json" echo "Created default permissions." fi # Make scripts executable chmod +x /etc/rc.d/rc.${PLUGIN} 2>/dev/null chmod +x /usr/local/emhttp/plugins/${PLUGIN}/event/* 2>/dev/null # Restart service if it was running, or start if enabled CONFIG="${CFG_DIR}/unraidclaw.cfg" if /etc/rc.d/rc.${PLUGIN} status >/dev/null 2>/dev/null; then echo "Restarting ${PLUGIN} service after upgrade..." /etc/rc.d/rc.${PLUGIN} restart elif [ -f "$CONFIG" ]; then SERVICE=$(grep -oP 'SERVICE="\K[^"]+' "$CONFIG") if [ "$SERVICE" = "enable" ]; then /etc/rc.d/rc.${PLUGIN} start fi fi echo "&name; v&version; installed." #!/bin/bash PLUGIN="&name;" # Stop service /etc/rc.d/rc.${PLUGIN} stop 2>/dev/null # Remove package removepkg ${PLUGIN}-&version;-x86_64-1 2>/dev/null # Remove plugin files (keep config on flash for re-install) rm -rf /usr/local/emhttp/plugins/${PLUGIN} rm -f /etc/rc.d/rc.${PLUGIN} echo "&name; removed." echo "Config files preserved in /boot/config/plugins/${PLUGIN}/" echo "To fully remove, delete /boot/config/plugins/${PLUGIN}/ manually."