[
  {
    "path": ".github/workflows/build-image.yml",
    "content": "name: Build and Push Docker Image\n\non:\n  workflow_dispatch:\n    inputs:\n      openclaw_version:\n        description: 'OpenClaw version to build (branch/tag)'\n        required: false\n        default: 'main'\n        type: string\n      push_image:\n        description: 'Push image to registry'\n        required: false\n        default: true\n        type: boolean\n  push:\n    branches:\n      - main\n    paths:\n      - 'Dockerfile'\n      - '.github/workflows/build-image.yml'\n  schedule:\n    # Build daily at 00:00 UTC to get latest OpenClaw updates\n    - cron: '0 0 * * *'\n\nenv:\n  REGISTRY: ghcr.io\n  IMAGE_NAME: ${{ github.repository_owner }}/openclaw-docker\n\njobs:\n  build:\n    runs-on: ubuntu-latest\n    permissions:\n      contents: read\n      packages: write\n\n    steps:\n      - name: Checkout repository\n        uses: actions/checkout@v4\n\n      - name: Set up Docker Buildx\n        uses: docker/setup-buildx-action@v3\n\n      - name: Log in to Container Registry\n        uses: docker/login-action@v3\n        with:\n          registry: ${{ env.REGISTRY }}\n          username: ${{ github.actor }}\n          password: ${{ secrets.GITHUB_TOKEN }}\n\n      - name: Extract metadata\n        id: meta\n        uses: docker/metadata-action@v5\n        with:\n          images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}\n          tags: |\n            type=raw,value=latest,enable={{is_default_branch}}\n            type=sha,prefix={{branch}}-\n            type=ref,event=branch\n            type=schedule,pattern={{date 'YYYYMMDD'}}\n\n      - name: Determine OpenClaw version\n        id: version\n        run: |\n          if [ \"${{ github.event_name }}\" = \"workflow_dispatch\" ]; then\n            VERSION=\"${{ inputs.openclaw_version }}\"\n          else\n            VERSION=$(cat .last-openclaw-version)\n          fi\n          echo \"openclaw_version=${VERSION}\" >> $GITHUB_OUTPUT\n          echo \"Building with OpenClaw version: ${VERSION}\"\n\n      - name: Build and push Docker image\n        uses: docker/build-push-action@v5\n        with:\n          context: .\n          file: ./Dockerfile\n          push: ${{ (github.event_name != 'workflow_dispatch') || inputs.push_image }}\n          tags: ${{ steps.meta.outputs.tags }}\n          labels: ${{ steps.meta.outputs.labels }}\n          build-args: |\n            OPENCLAW_VERSION=${{ steps.version.outputs.openclaw_version }}\n          cache-from: type=gha\n          cache-to: type=gha,mode=max\n          platforms: linux/amd64,linux/arm64\n\n      - name: Generate build summary\n        run: |\n          echo \"### 🦞 OpenClaw Docker Build Summary\" >> $GITHUB_STEP_SUMMARY\n          echo \"\" >> $GITHUB_STEP_SUMMARY\n          echo \"**OpenClaw Version:** \\`${{ steps.version.outputs.openclaw_version }}\\`\" >> $GITHUB_STEP_SUMMARY\n          echo \"**Image Tags:**\" >> $GITHUB_STEP_SUMMARY\n          echo '```' >> $GITHUB_STEP_SUMMARY\n          echo \"${{ steps.meta.outputs.tags }}\" >> $GITHUB_STEP_SUMMARY\n          echo '```' >> $GITHUB_STEP_SUMMARY\n          echo \"\" >> $GITHUB_STEP_SUMMARY\n          echo \"**Registry:** \\`${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}\\`\" >> $GITHUB_STEP_SUMMARY\n          echo \"\" >> $GITHUB_STEP_SUMMARY\n          if [ \"${{ github.event_name }}\" = \"workflow_dispatch\" ]; then\n            if [ \"${{ inputs.push_image }}\" = \"true\" ]; then\n              echo \"✅ Image pushed to registry\" >> $GITHUB_STEP_SUMMARY\n            else\n              echo \"ℹ️ Image built but not pushed (manual trigger with push disabled)\" >> $GITHUB_STEP_SUMMARY\n            fi\n          else\n            echo \"✅ Image pushed to registry\" >> $GITHUB_STEP_SUMMARY\n          fi\n"
  },
  {
    "path": ".github/workflows/openclaw-release-tracker.yml",
    "content": "name: OpenClaw Release Tracker\n\non:\n  schedule:\n    # Check for new OpenClaw releases every 6 hours\n    - cron: '0 */6 * * *'\n  workflow_dispatch:\n\njobs:\n  check-release:\n    runs-on: ubuntu-latest\n    permissions:\n      contents: write\n      packages: write\n      actions: write\n      \n    steps:\n      - name: Checkout repository\n        uses: actions/checkout@v4\n\n      - name: Check for new OpenClaw release\n        id: check_release\n        run: |\n          # Get the latest release from OpenClaw repository\n          LATEST_RELEASE=$(curl -s https://api.github.com/repos/openclaw/openclaw/releases/latest | jq -r '.tag_name // empty')\n          \n          # Get the latest commit from main branch if no releases\n          if [ -z \"$LATEST_RELEASE\" ]; then\n            LATEST_COMMIT=$(curl -s https://api.github.com/repos/openclaw/openclaw/commits/main | jq -r '.sha[:7]')\n            LATEST_RELEASE=\"main-${LATEST_COMMIT}\"\n          fi\n          \n          echo \"Latest OpenClaw version: ${LATEST_RELEASE}\"\n          echo \"latest_version=${LATEST_RELEASE}\" >> $GITHUB_OUTPUT\n          \n          # Check if we've already built this version\n          if [ -f \".last-openclaw-version\" ]; then\n            LAST_VERSION=$(cat .last-openclaw-version)\n            echo \"Last built version: ${LAST_VERSION}\"\n            \n            if [ \"$LATEST_RELEASE\" = \"$LAST_VERSION\" ]; then\n              echo \"new_release=false\" >> $GITHUB_OUTPUT\n              echo \"No new release found\"\n            else\n              echo \"new_release=true\" >> $GITHUB_OUTPUT\n              echo \"New release detected!\"\n            fi\n          else\n            echo \"new_release=true\" >> $GITHUB_OUTPUT\n            echo \"First run - will build\"\n          fi\n\n      - name: Update version tracker\n        if: steps.check_release.outputs.new_release == 'true'\n        run: |\n          echo \"${{ steps.check_release.outputs.latest_version }}\" > .last-openclaw-version\n          git config user.name \"github-actions[bot]\"\n          git config user.email \"github-actions[bot]@users.noreply.github.com\"\n          git add .last-openclaw-version\n          git diff --quiet && git diff --staged --quiet || git commit -m \"Update OpenClaw version tracker to ${{ steps.check_release.outputs.latest_version }}\"\n          git push\n\n      - name: Trigger build workflow\n        if: steps.check_release.outputs.new_release == 'true'\n        uses: actions/github-script@v7\n        with:\n          script: |\n            await github.rest.actions.createWorkflowDispatch({\n              owner: context.repo.owner,\n              repo: context.repo.repo,\n              workflow_id: 'build-image.yml',\n              ref: 'main',\n              inputs: {\n                openclaw_version: '${{ steps.check_release.outputs.latest_version }}',\n                push_image: 'true'\n              }\n            });\n            \n            console.log('✅ Triggered build workflow for new OpenClaw release: ${{ steps.check_release.outputs.latest_version }}');\n\n      - name: Create summary\n        if: always()\n        run: |\n          echo \"### 🦞 OpenClaw Release Check\" >> $GITHUB_STEP_SUMMARY\n          echo \"\" >> $GITHUB_STEP_SUMMARY\n          echo \"**Latest OpenClaw Version:** \\`${{ steps.check_release.outputs.latest_version }}\\`\" >> $GITHUB_STEP_SUMMARY\n          echo \"\" >> $GITHUB_STEP_SUMMARY\n          if [ \"${{ steps.check_release.outputs.new_release }}\" = \"true\" ]; then\n            echo \"✅ **New release detected!** Build workflow triggered.\" >> $GITHUB_STEP_SUMMARY\n          else\n            echo \"ℹ️ No new release. Docker image is up to date.\" >> $GITHUB_STEP_SUMMARY\n          fi\n"
  },
  {
    "path": ".gitignore",
    "content": "# Moltbot Docker\n\nBuild artifacts and temporary files\n"
  },
  {
    "path": ".last-openclaw-version",
    "content": "v2026.5.7\n"
  },
  {
    "path": "Dockerfile",
    "content": "FROM node:22-bookworm\n\nLABEL org.opencontainers.image.source=\"https://github.com/phioranex/openclaw-docker\"\nLABEL org.opencontainers.image.description=\"Pre-built OpenClaw (Clawbot) Docker image\"\nLABEL org.opencontainers.image.licenses=\"MIT\"\n\n# Install system dependencies (including Homebrew prerequisites)\nRUN apt-get update && apt-get install -y \\\n    git \\\n    curl \\\n    ca-certificates \\\n    unzip \\\n    build-essential \\\n    procps \\\n    file \\\n    sudo \\\n    jq \\\n    && rm -rf /var/lib/apt/lists/*\n\n# Install Bun (required for build)\nRUN curl -fsSL https://bun.sh/install | bash\nENV PATH=\"/root/.bun/bin:${PATH}\"\n\n# Install Homebrew (required for first-party skills)\n# Create linuxbrew user+group and grant sudo access (required for Homebrew package installations)\nRUN groupadd -f linuxbrew && \\\n    useradd -m -s /bin/bash -g linuxbrew linuxbrew && \\\n    echo 'linuxbrew ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers && \\\n    mkdir -p /home/linuxbrew/.linuxbrew && \\\n    chown -R linuxbrew:linuxbrew /home/linuxbrew/.linuxbrew\n# Download and install Homebrew manually (shallow clone to reduce image size)\n# Note: HOMEBREW_NO_AUTO_UPDATE is set below to disable updates\nRUN mkdir -p /home/linuxbrew/.linuxbrew/Homebrew && \\\n    git clone --depth 1 https://github.com/Homebrew/brew /home/linuxbrew/.linuxbrew/Homebrew && \\\n    mkdir -p /home/linuxbrew/.linuxbrew/bin && \\\n    ln -s /home/linuxbrew/.linuxbrew/Homebrew/bin/brew /home/linuxbrew/.linuxbrew/bin/brew && \\\n    chown -R linuxbrew:linuxbrew /home/linuxbrew/.linuxbrew && \\\n    chmod -R g+rwX /home/linuxbrew/.linuxbrew\n    \nENV PATH=\"/home/linuxbrew/.linuxbrew/bin:/home/linuxbrew/.linuxbrew/sbin:${PATH}\"\nENV HOMEBREW_NO_AUTO_UPDATE=1\nENV HOMEBREW_NO_INSTALL_CLEANUP=1\n\n# Enable corepack for pnpm\nRUN corepack enable\n\nWORKDIR /app\n\n# Clone and build OpenClaw - always fetch latest from main branch\nARG OPENCLAW_VERSION=main\nRUN git clone --depth 1 --branch ${OPENCLAW_VERSION} https://github.com/openclaw/openclaw.git . && \\\n    echo \"Building OpenClaw from branch: ${OPENCLAW_VERSION}\" && \\\n    git rev-parse HEAD > /app/openclaw-commit.txt\n\n# Install dependencies\nRUN pnpm install --frozen-lockfile\n\n# Build\nRUN OPENCLAW_A2UI_SKIP_MISSING=1 pnpm build\n# Force pnpm for UI build (Bun may fail on ARM/Synology architectures)\nRUN npm_config_script_shell=bash pnpm ui:install\nRUN npm_config_script_shell=bash pnpm ui:build\n\n# Clean up build artifacts to reduce image size\nRUN rm -rf .git node_modules/.cache\n\n# Create app user (node already exists in base image)\n# Add node user to linuxbrew group for Homebrew access\n# Fix permissions for global npm installs\nRUN mkdir -p /home/node/.openclaw /home/node/.openclaw/workspace \\\n    && chown -R node:node /home/node /app \\\n    && chmod -R 755 /home/node/.openclaw \\\n    && usermod -aG linuxbrew node \\\n    && chmod -R g+w /home/linuxbrew/.linuxbrew \\\n    && chown -R node:node /usr/local/lib/node_modules \\\n    && chown -R node:node /usr/local/bin\n\n# Install Playwright system dependencies (as root before switching to node user)\nRUN npx -y playwright@latest install-deps chromium\n\n# Copy SSL certificates to a location accessible by all users\nRUN mkdir -p /usr/local/share/ca-certificates && \\\n    cp /etc/ssl/certs/ca-certificates.crt /usr/local/share/ca-certificates/ca-certificates.crt && \\\n    chmod 755 /usr/local/share/ca-certificates && \\\n    chmod 644 /usr/local/share/ca-certificates/ca-certificates.crt\n\nUSER node\n\n# Install Playwright browsers for the node user\n# Use NODE_EXTRA_CA_CERTS to point to accessible certificate bundle\nRUN NODE_EXTRA_CA_CERTS=/usr/local/share/ca-certificates/ca-certificates.crt npx -y playwright@latest install chromium\n\nWORKDIR /home/node\n\nENV NODE_ENV=production\nENV PATH=\"/home/linuxbrew/.linuxbrew/bin:/home/linuxbrew/.linuxbrew/sbin:/app/node_modules/.bin:${PATH}\"\nENV HOMEBREW_NO_AUTO_UPDATE=1\nENV HOMEBREW_NO_INSTALL_CLEANUP=1\n\n# Default command\nENTRYPOINT [\"node\", \"/app/dist/index.js\"]\nCMD [\"--help\"]\n"
  },
  {
    "path": "LICENSE",
    "content": "MIT License\n\nCopyright (c) 2026 Phioranex Pvt Ltd\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n\n---\n\nNote: This repository provides Docker packaging for Moltbot.\nMoltbot itself is a separate project with its own license.\nSee: https://github.com/moltbot/moltbot\n"
  },
  {
    "path": "README.md",
    "content": "# OpenClaw (Clawbot) Docker Image\n\nPre-built Docker image for [OpenClaw](https://github.com/openclaw/openclaw) — run your AI assistant in seconds without building from source.\n\n> 🔄 **Always Up-to-Date:** This image automatically builds daily and checks for new OpenClaw releases every 6 hours, ensuring you always have the latest version.\n\n## One-Line Install (Recommended)\n\n### Linux / macOS\n\n```bash\nbash <(curl -fsSL https://raw.githubusercontent.com/phioranex/openclaw-docker/main/install.sh)\n```\n\n### Windows (PowerShell)\n\n```powershell\nirm https://raw.githubusercontent.com/phioranex/openclaw-docker/main/install.ps1 | iex\n```\n\n> **Note for Windows users:** Make sure Docker Desktop is installed and running. You can also use WSL2 with the Linux installation command.\n\nThis will:\n- ✅ Check prerequisites (Docker, Docker Compose)\n- ✅ Download necessary files\n- ✅ Pull the pre-built image\n- ✅ Run the onboarding wizard\n- ✅ Start the gateway\n\n### Install Options\n\n**Linux / macOS:**\n\n### Install Options\n\n**Linux / macOS:**\n\n```bash\n# Just pull the image (no setup)\nbash <(curl -fsSL https://raw.githubusercontent.com/phioranex/openclaw-docker/main/install.sh) --pull-only\n\n# Skip onboarding (if already configured)\nbash <(curl -fsSL https://raw.githubusercontent.com/phioranex/openclaw-docker/main/install.sh) --skip-onboard\n\n# Don't start gateway after setup\nbash <(curl -fsSL https://raw.githubusercontent.com/phioranex/openclaw-docker/main/install.sh) --no-start\n\n# Custom install directory\nbash <(curl -fsSL https://raw.githubusercontent.com/phioranex/openclaw-docker/main/install.sh) --install-dir /opt/openclaw\n```\n\n**Windows (PowerShell):**\n\n```powershell\n# Just pull the image (no setup)\nirm https://raw.githubusercontent.com/phioranex/openclaw-docker/main/install.ps1 | iex -PullOnly\n\n# Skip onboarding (if already configured)\nirm https://raw.githubusercontent.com/phioranex/openclaw-docker/main/install.ps1 | iex -SkipOnboard\n\n# Don't start gateway after setup\nirm https://raw.githubusercontent.com/phioranex/openclaw-docker/main/install.ps1 | iex -NoStart\n\n# Custom install directory\n$env:TEMP_INSTALL_SCRIPT = irm https://raw.githubusercontent.com/phioranex/openclaw-docker/main/install.ps1; Invoke-Expression $env:TEMP_INSTALL_SCRIPT -InstallDir \"C:\\openclaw\"\n```\n\n## Manual Install\n\n### Quick Start\n\n```bash\n# Pull the image\ndocker pull ghcr.io/phioranex/openclaw-docker:latest\n\n# Run onboarding (first time setup)\ndocker run -it --rm \\\n  -v ~/.openclaw:/home/node/.openclaw \\\n  -v ~/.openclaw/workspace:/home/node/.openclaw/workspace \\\n  ghcr.io/phioranex/openclaw-docker:latest onboard\n\n# Start the gateway\ndocker run -d \\\n  --name openclaw \\\n  --restart unless-stopped \\\n  -v ~/.openclaw:/home/node/.openclaw \\\n  -v ~/.openclaw/workspace:/home/node/.openclaw/workspace \\\n  -p 18789:18789 \\\n  ghcr.io/phioranex/openclaw-docker:latest gateway start --foreground\n```\n\n### Using Docker Compose\n\n```bash\n# Clone this repo\ngit clone https://github.com/phioranex/openclaw-docker.git\ncd openclaw-docker\n\n# Run onboarding\ndocker compose run --rm openclaw-cli onboard\n\n# Start the gateway\ndocker compose up -d openclaw-gateway\n```\n\n## Configuration\n\nDuring onboarding, you'll configure:\n- **AI Provider** (Anthropic Claude, OpenAI, etc.)\n- **Channels** (Telegram, WhatsApp, Discord, etc.)\n- **Gateway settings**\n\nConfig is stored in `~/.openclaw/` and persists across container restarts.\n\n## Available Tags\n\n| Tag | Description |\n|-----|-------------|\n| `latest` | Latest OpenClaw build (updated daily and on new releases) |\n| `vX.Y.Z` | Specific version (if available) |\n| `main` | Latest from main branch (cutting edge) |\n\n> **Note:** The `latest` tag is automatically rebuilt daily at 00:00 UTC and whenever OpenClaw releases a new version.\n\n## Volumes\n\n| Path | Purpose |\n|------|---------|\n| `/home/node/.openclaw` | Config and session data |\n| `/home/node/.openclaw/workspace` | Agent workspace |\n\n## Ports\n\n| Port | Purpose |\n|------|---------|\n| `18789` | Gateway API + Dashboard |\n\n## Links\n\n- [OpenClaw Website](https://openclaw.ai/)\n- [OpenClaw Docs](https://docs.openclaw.ai)\n- [OpenClaw GitHub](https://github.com/openclaw/openclaw)\n- [Discord Community](https://discord.gg/clawd)\n\n## Uninstallation\n\n### One-Line Uninstall\n\n**Linux / macOS:**\n\n```bash\nbash <(curl -fsSL https://raw.githubusercontent.com/phioranex/openclaw-docker/main/uninstall.sh)\n```\n\n**Windows (PowerShell):**\n\n```powershell\nirm https://raw.githubusercontent.com/phioranex/openclaw-docker/main/uninstall.ps1 | iex\n```\n\nThis will:\n- ✅ Stop and remove all containers\n- ✅ Ask before removing configuration and workspace data\n- ✅ Ask before removing Docker image\n- ✅ Ask before removing installation directory\n\n### Uninstall Options\n\n**Linux / macOS:**\n\n```bash\n# Keep configuration and workspace data\nbash <(curl -fsSL https://raw.githubusercontent.com/phioranex/openclaw-docker/main/uninstall.sh) --keep-data\n\n# Keep Docker image (useful if reinstalling later)\nbash <(curl -fsSL https://raw.githubusercontent.com/phioranex/openclaw-docker/main/uninstall.sh) --keep-image\n\n# Skip all confirmation prompts\nbash <(curl -fsSL https://raw.githubusercontent.com/phioranex/openclaw-docker/main/uninstall.sh) --force\n\n# Custom install directory\nbash <(curl -fsSL https://raw.githubusercontent.com/phioranex/openclaw-docker/main/uninstall.sh) --install-dir /opt/openclaw\n```\n\n**Windows (PowerShell):**\n\n```powershell\n# Keep configuration and workspace data\n& ([scriptblock]::Create((irm https://raw.githubusercontent.com/phioranex/openclaw-docker/main/uninstall.ps1))) -KeepData\n\n# Keep Docker image (useful if reinstalling later)\n& ([scriptblock]::Create((irm https://raw.githubusercontent.com/phioranex/openclaw-docker/main/uninstall.ps1))) -KeepImage\n\n# Skip all confirmation prompts\n& ([scriptblock]::Create((irm https://raw.githubusercontent.com/phioranex/openclaw-docker/main/uninstall.ps1))) -Force\n\n# Custom install directory\n& ([scriptblock]::Create((irm https://raw.githubusercontent.com/phioranex/openclaw-docker/main/uninstall.ps1))) -InstallDir \"C:\\openclaw\"\n```\n\n### Manual Uninstall\n\nIf you prefer to uninstall manually:\n\n```bash\n# Stop and remove containers\ndocker stop openclaw-gateway openclaw-socat\ndocker rm openclaw-gateway openclaw-socat openclaw-cli\n\n# Remove data (optional)\nrm -rf ~/.openclaw\n\n# Remove Docker image (optional)\ndocker rmi ghcr.io/phioranex/openclaw-docker:latest\n\n# Remove installation directory (optional)\nrm -rf ~/openclaw\n```\n\n## Troubleshooting\n\n### Permission Issues on Synology NAS\n\nIf you encounter `EACCES: permission denied` errors when running on Synology NAS:\n\n1. **Option 1: Run install script with sudo (Recommended)**\n   ```bash\n   sudo bash <(curl -fsSL https://raw.githubusercontent.com/phioranex/openclaw-docker/main/install.sh)\n   ```\n   The script will automatically:\n   - Set proper ownership (UID 1000) for the container user\n   - Configure your user account to access the files\n   - Update docker-compose.yml to use the correct home directory\n\n2. **Option 2: Fix permissions manually**\n   ```bash\n   # RECOMMENDED: Set ownership to UID 1000 with group access (most secure)\n   sudo chown -R 1000:$(id -g) ~/.openclaw\n   sudo chmod -R u+rwX,g+rwX,o-rwx ~/.openclaw\n   \n   # Alternative: Make directory writable by owner and group (less secure)\n   chmod -R 775 ~/.openclaw\n   \n   # LAST RESORT ONLY: World-writable (least secure, use only if above options fail)\n   # chmod -R 777 ~/.openclaw\n   ```\n\n3. **Option 3: Use host user mapping**\n   Edit `docker-compose.yml` and uncomment the `user: \"1000:1000\"` line in both services:\n   ```yaml\n   user: \"1000:1000\"  # Uncomment this line\n   ```\n\n### Telegram Bot Connection Issues\n\nIf the Telegram bot cannot find your username or numeric ID:\n\n1. Ensure your container has internet access:\n   ```bash\n   docker exec openclaw-gateway ping -c 3 api.telegram.org\n   ```\n\n2. Check if firewall or network restrictions are blocking Telegram API access\n\n3. Verify your Telegram bot token is correct in `~/.openclaw/openclaw.json`\n\n### Docker Permission Issues (Image Pull)\n\nIf you need root/sudo to pull Docker images:\n\n1. Add your user to the docker group:\n   ```bash\n   sudo usermod -aG docker $USER\n   ```\n\n2. Log out and log back in for the changes to take effect\n\n3. Alternatively, use `sudo` when running the install script\n\n### Installing Skills (npm global packages)\n\nThe container is configured to allow the `node` user to install global npm packages without permission issues. You can install skills using:\n\n```bash\n# If using docker compose\ndocker compose exec openclaw-gateway npm install -g @package/name\n\n# If using standalone container\ndocker exec -it <container_name> npm install -g @package/name\n\n# Find your container name with:\ndocker ps\n```\n\nIf you're using `user: \"1000:1000\"` in docker-compose.yml, global npm installs will work without any additional configuration.\n\n## YouTube Tutorial\n\n📺 Watch the installation tutorial: [Coming Soon]\n\n## License\n\nThis Docker packaging is provided by [Phioranex](https://phioranex.com).\nOpenClaw itself is licensed under MIT — see the [original repo](https://github.com/openclaw/openclaw).\n"
  },
  {
    "path": "docker-compose.yml",
    "content": "services:\n  openclaw-gateway:\n    image: ghcr.io/phioranex/openclaw-docker:latest\n    container_name: openclaw-gateway\n    restart: unless-stopped\n    stdin_open: true\n    tty: true\n    # Uncomment the following line if running on Synology NAS or other systems with UID/GID issues\n    # user: \"1000:1000\"\n    volumes:\n      - ~/.openclaw:/home/node/.openclaw\n      - ~/.openclaw/workspace:/home/node/.openclaw/workspace\n    ports:\n      - \"18789:18789\"\n      - \"18790:18790\"\n    environment:\n      - NODE_ENV=production\n      - OPENCLAW_SKIP_SERVICE_CHECK=true\n    command: [\"gateway\"]\n  \n  socat-proxy:\n    image: alpine/socat\n    container_name: openclaw-socat\n    restart: unless-stopped\n    network_mode: \"service:openclaw-gateway\"\n    command: \"TCP-LISTEN:18790,fork,bind=0.0.0.0,reuseaddr TCP:127.0.0.1:18789\"\n\n  openclaw-cli:\n    image: ghcr.io/phioranex/openclaw-docker:latest\n    container_name: openclaw-cli\n    stdin_open: true\n    tty: true\n    # Uncomment the following line if running on Synology NAS or other systems with UID/GID issues\n    # user: \"1000:1000\"\n    volumes:\n      - ~/.openclaw:/home/node/.openclaw\n      - ~/.openclaw/workspace:/home/node/.openclaw/workspace\n    environment:\n      - NODE_ENV=production\n    entrypoint: [\"node\", \"/app/dist/index.js\"]\n    profiles:\n      - cli\n"
  },
  {
    "path": "install.ps1",
    "content": "#\n# OpenClaw (Clawbot) Docker Installer - Windows PowerShell Version\n# One-command setup for OpenClaw on Docker for Windows\n#\n# Usage:\n#   irm https://raw.githubusercontent.com/phioranex/openclaw-docker/main/install.ps1 | iex\n#\n# Or with options:\n#   & ([scriptblock]::Create((irm https://raw.githubusercontent.com/phioranex/openclaw-docker/main/install.ps1))) -NoStart\n#\n\nparam(\n    [string]$InstallDir = \"$env:USERPROFILE\\openclaw\",\n    [switch]$NoStart,\n    [switch]$SkipOnboard,\n    [switch]$PullOnly,\n    [switch]$Help\n)\n\n# Config\n$Image = \"ghcr.io/phioranex/openclaw-docker:latest\"\n$RepoUrl = \"https://github.com/phioranex/openclaw-docker\"\n$ComposeUrl = \"https://raw.githubusercontent.com/phioranex/openclaw-docker/main/docker-compose.yml\"\n\n# Error handling\n$ErrorActionPreference = \"Stop\"\n\n# Functions\nfunction Write-Banner {\n    Write-Host \"\"\n    Write-Host \"╔══════════════════════════════════════════════════════════════╗\" -ForegroundColor Red\n    Write-Host \"║                                                              ║\" -ForegroundColor Red\n    Write-Host \"║    ____                    _____ _                           ║\" -ForegroundColor Red\n    Write-Host \"║   / __ \\                  / ____| |                          ║\" -ForegroundColor Red\n    Write-Host \"║  | |  | |_ __   ___ _ __ | |    | | __ ___      __           ║\" -ForegroundColor Red\n    Write-Host \"║  | |  | | '_ \\ / _ \\ '_ \\| |    | |/ _`` \\ \\ /\\ / /           ║\" -ForegroundColor Red\n    Write-Host \"║  | |__| | |_) |  __/ | | | |____| | (_| |\\ V  V /            ║\" -ForegroundColor Red\n    Write-Host \"║   \\____/| .__/ \\___|_| |_|\\_____|_|\\__,_| \\_/\\_/             ║\" -ForegroundColor Red\n    Write-Host \"║         | |                                                  ║\" -ForegroundColor Red\n    Write-Host \"║         |_|                                                  ║\" -ForegroundColor Red\n    Write-Host \"║                                                              ║\" -ForegroundColor Red\n    Write-Host \"║              Docker Installer by Phioranex                   ║\" -ForegroundColor Red\n    Write-Host \"║                                                              ║\" -ForegroundColor Red\n    Write-Host \"╚══════════════════════════════════════════════════════════════╝\" -ForegroundColor Red\n    Write-Host \"\"\n}\n\nfunction Write-Step {\n    param([string]$Message)\n    Write-Host \"\"\n    Write-Host \"▶ $Message\" -ForegroundColor Blue\n}\n\nfunction Write-Success {\n    param([string]$Message)\n    Write-Host \"✓ $Message\" -ForegroundColor Green\n}\n\nfunction Write-Warning {\n    param([string]$Message)\n    Write-Host \"⚠ $Message\" -ForegroundColor Yellow\n}\n\nfunction Write-Error {\n    param([string]$Message)\n    Write-Host \"✗ $Message\" -ForegroundColor Red\n}\n\nfunction Test-Command {\n    param([string]$Command)\n    try {\n        Get-Command $Command -ErrorAction Stop | Out-Null\n        return $true\n    } catch {\n        return $false\n    }\n}\n\n# Show help\nif ($Help) {\n    Write-Host \"OpenClaw (Clawbot) Docker Installer - Windows\"\n    Write-Host \"\"\n    Write-Host \"Usage: install.ps1 [OPTIONS]\"\n    Write-Host \"\"\n    Write-Host \"Options:\"\n    Write-Host \"  -InstallDir DIR   Installation directory (default: ~\\openclaw)\"\n    Write-Host \"  -NoStart          Don't start the gateway after setup\"\n    Write-Host \"  -SkipOnboard      Skip onboarding wizard\"\n    Write-Host \"  -PullOnly         Only pull the image, don't set up\"\n    Write-Host \"  -Help             Show this help message\"\n    return\n}\n\n# Main script\nWrite-Banner\n\nWrite-Step \"Checking prerequisites...\"\n\n# Check Docker\nif (Test-Command docker) {\n    Write-Success \"docker found\"\n} else {\n    Write-Error \"docker not found\"\n    Write-Host \"\"\n    Write-Host \"Docker is required but not installed.\" -ForegroundColor Red\n    Write-Host \"Install Docker Desktop: https://docs.docker.com/desktop/install/windows-install/\" -ForegroundColor Yellow\n    return\n}\n\n# Check Docker Compose\n$ComposeCmd = \"\"\nif (docker compose version 2>$null) {\n    Write-Success \"Docker Compose found (plugin)\"\n    $ComposeCmd = \"docker compose\"\n} elseif (Test-Command docker-compose) {\n    Write-Success \"Docker Compose found (standalone)\"\n    $ComposeCmd = \"docker-compose\"\n} else {\n    Write-Error \"Docker Compose not found\"\n    Write-Host \"\"\n    Write-Host \"Docker Compose is required but not installed.\" -ForegroundColor Red\n    Write-Host \"It usually comes with Docker Desktop.\" -ForegroundColor Yellow\n    exit 1\n}\n\n# Check Docker is running\ntry {\n    docker info 2>$null | Out-Null\n    Write-Success \"Docker is running\"\n} catch {\n    Write-Error \"Docker is not running\"\n    Write-Host \"\"\n    Write-Host \"Please start Docker Desktop and try again.\" -ForegroundColor Red\n    exit 1\n}\n\n# Pull only mode\nif ($PullOnly) {\n    Write-Step \"Pulling OpenClaw image...\"\n    docker pull $Image\n    Write-Success \"Image pulled successfully!\"\n    Write-Host \"\"\n    Write-Host \"Done! Run the installer again without -PullOnly to complete setup.\" -ForegroundColor Green\n    exit 0\n}\n\nWrite-Step \"Setting up installation directory...\"\nNew-Item -ItemType Directory -Force -Path $InstallDir | Out-Null\nSet-Location $InstallDir\nWrite-Success \"Created $InstallDir\"\n\nWrite-Step \"Downloading docker-compose.yml...\"\nInvoke-WebRequest -Uri $ComposeUrl -OutFile \"docker-compose.yml\"\nWrite-Success \"Downloaded docker-compose.yml\"\n\nWrite-Step \"Creating data directories...\"\n$ConfigDir = \"$env:USERPROFILE\\.openclaw\"\n$WorkspaceDir = \"$env:USERPROFILE\\.openclaw\\workspace\"\nNew-Item -ItemType Directory -Force -Path $ConfigDir | Out-Null\nNew-Item -ItemType Directory -Force -Path $WorkspaceDir | Out-Null\nWrite-Success \"Created $ConfigDir (config)\"\nWrite-Success \"Created $WorkspaceDir (workspace)\"\n\nWrite-Step \"Pulling OpenClaw image...\"\ndocker pull $Image\nWrite-Success \"Image pulled successfully!\"\n\n# Onboarding\nif (-not $SkipOnboard) {\n    Write-Step \"Initializing OpenClaw configuration...\"\n    Write-Host \"Setting up configuration and workspace...\" -ForegroundColor Yellow\n    Write-Host \"\"\n    \n    Write-Step \"Running onboarding wizard...\"\n    Write-Host \"This will configure your AI provider and channels.\" -ForegroundColor Yellow\n    Write-Host \"Follow the prompts to complete setup.\" -ForegroundColor Yellow\n    Write-Host \"\"\n    \n    # Run onboarding\n    $composeParts = $ComposeCmd -split \" \", 2\n    if ($composeParts.Count -eq 2) {\n        & $composeParts[0] $composeParts[1] run -T --rm openclaw-cli onboard\n    } else {\n        & $composeParts[0] run -T --rm openclaw-cli onboard\n    }\n    if ($LASTEXITCODE -ne 0) {\n        Write-Warning \"Onboarding wizard was skipped or failed\"\n        Write-Host \"You can run it later with: cd $InstallDir && $ComposeCmd run --rm openclaw-cli onboard\" -ForegroundColor Yellow\n    } else {\n        Write-Success \"Onboarding complete!\"\n    }\n}\n\n# Start gateway\nif (-not $NoStart) {\n    Write-Step \"Starting OpenClaw gateway...\"\n    $composeParts = $ComposeCmd -split \" \", 2\n    if ($composeParts.Count -eq 2) {\n        & $composeParts[0] $composeParts[1] up -d openclaw-gateway\n    } else {\n        & $composeParts[0] up -d openclaw-gateway\n    }\n    \n    # Wait for gateway to be ready\n    Write-Host \"Waiting for gateway to start\" -NoNewline\n    for ($i = 0; $i -lt 30; $i++) {\n        try {\n            $response = Invoke-WebRequest -Uri \"http://localhost:18789/health\" -TimeoutSec 1 -ErrorAction SilentlyContinue\n            if ($response.StatusCode -eq 200) {\n                Write-Host \"\"\n                Write-Success \"Gateway is running!\"\n                break\n            }\n        } catch {\n            # Continue waiting\n        }\n        Write-Host \".\" -NoNewline\n        Start-Sleep -Seconds 1\n    }\n    \n    try {\n        $response = Invoke-WebRequest -Uri \"http://localhost:18789/health\" -TimeoutSec 1 -ErrorAction SilentlyContinue\n        if ($response.StatusCode -ne 200) {\n            throw\n        }\n    } catch {\n        Write-Host \"\"\n        Write-Warning \"Gateway may still be starting. Check logs with: docker logs openclaw-gateway\"\n    }\n}\n\n# Success message\nWrite-Host \"\"\nWrite-Host \"╔══════════════════════════════════════════════════════════════╗\" -ForegroundColor Green\nWrite-Host \"║                                                              ║\" -ForegroundColor Green\nWrite-Host \"║              🎉 OpenClaw installed successfully! 🎉           ║\" -ForegroundColor Green\nWrite-Host \"║                                                              ║\" -ForegroundColor Green\nWrite-Host \"╚══════════════════════════════════════════════════════════════╝\" -ForegroundColor Green\n\nWrite-Host \"\"\nWrite-Host \"Quick reference:\" -ForegroundColor White\nWrite-Host \"  Dashboard:      http://localhost:18789\" -ForegroundColor Cyan\nWrite-Host \"  Config:         $ConfigDir\" -ForegroundColor Cyan\nWrite-Host \"  Workspace:      $WorkspaceDir\" -ForegroundColor Cyan\nWrite-Host \"  Install dir:    $InstallDir\" -ForegroundColor Cyan\n\nWrite-Host \"\"\nWrite-Host \"Useful commands:\" -ForegroundColor White\nWrite-Host \"  View logs:      docker logs -f openclaw-gateway\" -ForegroundColor Cyan\nWrite-Host \"  Stop:           cd $InstallDir && $ComposeCmd down\" -ForegroundColor Cyan\nWrite-Host \"  Start:          cd $InstallDir && $ComposeCmd up -d openclaw-gateway\" -ForegroundColor Cyan\nWrite-Host \"  Restart:        cd $InstallDir && $ComposeCmd restart openclaw-gateway\" -ForegroundColor Cyan\nWrite-Host \"  CLI:            cd $InstallDir && $ComposeCmd run --rm openclaw-cli <command>\" -ForegroundColor Cyan\nWrite-Host \"  Update:         docker pull $Image && cd $InstallDir && $ComposeCmd up -d\" -ForegroundColor Cyan\n\nWrite-Host \"\"\nWrite-Host \"Documentation:  https://docs.openclaw.ai\" -ForegroundColor White\nWrite-Host \"Support:        https://discord.gg/clawd\" -ForegroundColor White\nWrite-Host \"Docker image:   $RepoUrl\" -ForegroundColor White\n\nWrite-Host \"\"\nWrite-Host \"Happy automating! 🤖🦞\" -ForegroundColor Yellow\nWrite-Host \"\"\n"
  },
  {
    "path": "install.sh",
    "content": "#!/bin/bash\n#\n# OpenClaw (Clawbot) Docker Installer\n# One-command setup for OpenClaw on Docker\n#\n# Usage:\n#   bash <(curl -fsSL https://raw.githubusercontent.com/phioranex/openclaw-docker/main/install.sh)\n#\n# Or with options:\n#   bash <(curl -fsSL https://raw.githubusercontent.com/phioranex/openclaw-docker/main/install.sh) --no-start\n#\n\nset -e\n\n# Colors\nRED='\\033[0;31m'\nGREEN='\\033[0;32m'\nYELLOW='\\033[1;33m'\nBLUE='\\033[0;34m'\nCYAN='\\033[0;36m'\nBOLD='\\033[1m'\nNC='\\033[0m' # No Color\n\n# Config\nINSTALL_DIR=\"${OPENCLAW_INSTALL_DIR:-$HOME/openclaw}\"\nIMAGE=\"ghcr.io/phioranex/openclaw-docker:latest\"\nREPO_URL=\"https://github.com/phioranex/openclaw-docker\"\nCOMPOSE_URL=\"https://raw.githubusercontent.com/phioranex/openclaw-docker/main/docker-compose.yml\"\n\n# Detect if we have a TTY (for Docker interactive mode)\nif [ -t 0 ]; then\n    DOCKER_TTY_FLAG=\"\"\nelse\n    DOCKER_TTY_FLAG=\"-T\"\nfi\n\n# Flags\nNO_START=false\nSKIP_ONBOARD=false\nPULL_ONLY=false\n\n# Parse arguments\nwhile [[ $# -gt 0 ]]; do\n    case $1 in\n        --no-start)\n            NO_START=true\n            shift\n            ;;\n        --skip-onboard)\n            SKIP_ONBOARD=true\n            shift\n            ;;\n        --pull-only)\n            PULL_ONLY=true\n            shift\n            ;;\n        --install-dir)\n            INSTALL_DIR=\"$2\"\n            shift 2\n            ;;\n        --help|-h)\n            echo \"OpenClaw (Clawbot) Docker Installer\"\n            echo \"\"\n            echo \"Usage: install.sh [OPTIONS]\"\n            echo \"\"\n            echo \"Options:\"\n            echo \"  --install-dir DIR   Installation directory (default: ~/openclaw)\"\n            echo \"  --no-start          Don't start the gateway after setup\"\n            echo \"  --skip-onboard      Skip onboarding wizard\"\n            echo \"  --pull-only         Only pull the image, don't set up\"\n            echo \"  --help, -h          Show this help message\"\n            exit 0\n            ;;\n        *)\n            echo -e \"${RED}Unknown option: $1${NC}\"\n            exit 1\n            ;;\n    esac\ndone\n\n# Functions\nprint_banner() {\n    echo -e \"${RED}\"\n    echo \"╔══════════════════════════════════════════════════════════════╗\"\n    echo \"║                                                              ║\"\n    echo \"║    ____                    _____ _                           ║\"\n    echo \"║   / __ \\\\\\\\                  / ____| |                          ║\"\n    echo \"║  | |  | |_ __   ___ _ __ | |    | | __ ___      __           ║\"\n    echo \"║  | |  | | '_ \\\\\\\\ / _ \\\\\\\\ '_ \\\\\\\\| |    | |/ _\\\\\\` \\\\\\\\ \\\\\\\\ /\\\\\\\\ / /           ║\"\n    echo \"║  | |__| | |_) |  __/ | | | |____| | (_| |\\\\\\\\ V  V /            ║\"\n    echo \"║   \\\\\\\\____/| .__/ \\\\\\\\___|_| |_|\\\\\\\\_____|_|\\\\\\\\__,_| \\\\\\\\_/\\\\\\\\_/             ║\"\n    echo \"║         | |                                                  ║\"\n    echo \"║         |_|                                                  ║\"\n    echo \"║                                                              ║\"\n    echo \"║              Docker Installer by Phioranex                   ║\"\n    echo \"║                                                              ║\"\n    echo \"╚══════════════════════════════════════════════════════════════╝\"\n    echo -e \"${NC}\"\n}\n\n# Get user's home directory, handling sudo correctly\nget_user_home() {\n    if [ -n \"$SUDO_USER\" ]; then\n        # Running with sudo - use the actual user's home\n        local user_home\n        user_home=$(getent passwd \"$SUDO_USER\" | cut -d: -f6)\n        if [ -z \"$user_home\" ]; then\n            # Fallback to eval if getent fails\n            user_home=$(eval echo ~\"$SUDO_USER\")\n        fi\n        echo \"$user_home\"\n    else\n        # Running normally\n        echo \"$HOME\"\n    fi\n}\n\nlog_step() {\n    echo -e \"\\n${BLUE}▶${NC} ${BOLD}$1${NC}\"\n}\n\nlog_success() {\n    echo -e \"${GREEN}✓${NC} $1\"\n}\n\nlog_warning() {\n    echo -e \"${YELLOW}⚠${NC} $1\"\n}\n\nlog_error() {\n    echo -e \"${RED}✗${NC} $1\"\n}\n\ncheck_command() {\n    if command -v \"$1\" &> /dev/null; then\n        log_success \"$1 found\"\n        return 0\n    else\n        log_error \"$1 not found\"\n        return 1\n    fi\n}\n\n# Main script\nprint_banner\n\nlog_step \"Checking prerequisites...\"\n\n# Check Docker\nif ! check_command docker; then\n    echo -e \"\\n${RED}Docker is required but not installed.${NC}\"\n    echo \"Install Docker: https://docs.docker.com/get-docker/\"\n    exit 1\nfi\n\n# Check Docker Compose\nif docker compose version &> /dev/null; then\n    log_success \"Docker Compose found (plugin)\"\n    COMPOSE_CMD=\"docker compose\"\nelif command -v docker-compose &> /dev/null; then\n    log_success \"Docker Compose found (standalone)\"\n    COMPOSE_CMD=\"docker-compose\"\nelse\n    log_error \"Docker Compose not found\"\n    echo -e \"\\n${RED}Docker Compose is required but not installed.${NC}\"\n    echo \"Install Docker Compose: https://docs.docker.com/compose/install/\"\n    exit 1\nfi\n\n# Check Docker is running and capture output for better error reporting\nDOCKER_INFO_OUTPUT=$(docker info 2>&1)\nDOCKER_INFO_EXIT=$?\n\nif [ $DOCKER_INFO_EXIT -ne 0 ]; then\n    log_error \"Docker is not running or you don't have permission to access it\"\n    \n    # Check if it's a permission issue\n    if [ \"$(id -u)\" -ne 0 ] && echo \"$DOCKER_INFO_OUTPUT\" | grep -qi \"permission denied\"; then\n        echo -e \"\\n${YELLOW}Tip: You may need to run this script with sudo or add your user to the docker group:${NC}\"\n        echo -e \"  ${CYAN}sudo usermod -aG docker \\$USER${NC}\"\n        echo -e \"  ${CYAN}(then log out and log back in)${NC}\"\n        echo -e \"\\n${YELLOW}Or run the installer with sudo:${NC}\"\n        echo -e \"  ${CYAN}sudo bash <(curl -fsSL https://raw.githubusercontent.com/phioranex/openclaw-docker/main/install.sh)${NC}\"\n    else\n        echo -e \"\\n${RED}Please start Docker and try again.${NC}\"\n    fi\n    exit 1\nfi\nlog_success \"Docker is running\"\n\n# Pull only mode\nif [ \"$PULL_ONLY\" = true ]; then\n    log_step \"Pulling OpenClaw image...\"\n    docker pull \"$IMAGE\"\n    log_success \"Image pulled successfully!\"\n    echo -e \"\\n${GREEN}Done!${NC} Run the installer again without --pull-only to complete setup.\"\n    exit 0\nfi\n\nlog_step \"Setting up installation directory...\"\nmkdir -p \"$INSTALL_DIR\"\ncd \"$INSTALL_DIR\"\nlog_success \"Created $INSTALL_DIR\"\n\nlog_step \"Downloading docker-compose.yml...\"\ncurl -fsSL \"$COMPOSE_URL\" -o docker-compose.yml\n\n# Update docker-compose.yml to use correct home directory when running with sudo\nif [ -n \"$SUDO_USER\" ]; then\n    USER_HOME=$(get_user_home)\n    # Replace ~/.openclaw with the actual user's home directory\n    if grep -q \"~/.openclaw\" docker-compose.yml; then\n        if sed -i.bak \"s|~/.openclaw|$USER_HOME/.openclaw|g\" docker-compose.yml; then\n            rm -f docker-compose.yml.bak\n            # Verify the replacement actually occurred\n            if ! grep -q \"~/.openclaw\" docker-compose.yml; then\n                log_success \"Updated docker-compose.yml for sudo user ($SUDO_USER)\"\n            else\n                log_warning \"sed replacement may have failed, check docker-compose.yml manually\"\n            fi\n        else\n            log_warning \"Failed to update docker-compose.yml paths\"\n        fi\n    else\n        log_warning \"docker-compose.yml doesn't contain '~/.openclaw', skipping path update\"\n    fi\nfi\n\nlog_success \"Downloaded docker-compose.yml\"\n\nlog_step \"Creating data directories...\"\n\n# Determine the correct home directory\nUSER_HOME=$(get_user_home)\nOPENCLAW_DIR=\"$USER_HOME/.openclaw\"\n\nmkdir -p \"$OPENCLAW_DIR\"\nmkdir -p \"$OPENCLAW_DIR/workspace\"\n\n# Fix permissions for container access\n# Docker container runs as node user (UID 1000, GID 1000)\n# Ensure the directory is writable by the container user\nif [ \"$(id -u)\" -eq 0 ]; then\n    # Running as root/sudo - set ownership to UID 1000 (node user in container)\n    # and grant group access to the actual user (if using sudo)\n    if [ -n \"$SUDO_USER\" ]; then\n        # Get the sudo user's primary group\n        SUDO_GID=$(id -g \"$SUDO_USER\")\n        # Set ownership: UID 1000 (container), GID to sudo user's group\n        chown -R 1000:\"$SUDO_GID\" \"$OPENCLAW_DIR\"\n        # Allow group read/write access\n        chmod -R u+rwX,g+rwX,o-rwx \"$OPENCLAW_DIR\"\n        log_success \"Set ownership to UID 1000 with group access for $SUDO_USER\"\n    else\n        # Running as actual root user, not via sudo\n        chown -R 1000:1000 \"$OPENCLAW_DIR\"\n        chmod -R 755 \"$OPENCLAW_DIR\"\n        log_success \"Set ownership to UID 1000 (container user)\"\n    fi\nelse\n    # Running as non-root user\n    # Try 775 first (safer than 777)\n    if chmod -R 775 \"$OPENCLAW_DIR\" 2>/dev/null; then\n        ACTUAL_PERMS=\"775\"\n        log_warning \"Running as non-root user, set permissions to 775\"\n    else\n        # Fallback to 777 if 775 fails (e.g., not the owner)\n        chmod -R 777 \"$OPENCLAW_DIR\"\n        ACTUAL_PERMS=\"777\"\n        log_warning \"Could not set 775 permissions (not owner?), using 777 instead\"\n    fi\n    log_warning \"For better security on Synology/NAS, consider running with sudo\"\nfi\n\nlog_success \"Created $OPENCLAW_DIR (config)\"\nlog_success \"Created $OPENCLAW_DIR/workspace (workspace)\"\n\nlog_step \"Pulling OpenClaw image...\"\ndocker pull \"$IMAGE\"\nlog_success \"Image pulled successfully!\"\n\n# Onboarding\nif [ \"$SKIP_ONBOARD\" = false ]; then\n    log_step \"Initializing OpenClaw configuration...\"\n    echo -e \"${YELLOW}Setting up configuration and workspace...${NC}\\n\"\n    \n    log_step \"Running onboarding wizard...\"\n    echo -e \"${YELLOW}This will configure your AI provider and channels.${NC}\"\n    echo -e \"${YELLOW}Follow the prompts to complete setup.${NC}\\n\"\n    \n    # Run onboarding interactively (works with bash process substitution)\n    if ! $COMPOSE_CMD run --rm openclaw-cli onboard; then\n        log_warning \"Onboarding was cancelled or failed\"\n        echo -e \"${YELLOW}You can run it later with:${NC} cd $INSTALL_DIR && $COMPOSE_CMD run --rm openclaw-cli onboard\"\n    else\n        log_success \"Onboarding complete!\"\n    fi\nfi\n\n# Start gateway\nif [ \"$NO_START\" = false ]; then\n    log_step \"Starting OpenClaw gateway...\"\n    $COMPOSE_CMD up -d openclaw-gateway\n    \n    # Wait for gateway to be ready\n    echo -n \"Waiting for gateway to start\"\n    for i in {1..30}; do\n        if curl -s http://localhost:18789/health &> /dev/null; then\n            echo \"\"\n            log_success \"Gateway is running!\"\n            break\n        fi\n        echo -n \".\"\n        sleep 1\n    done\n    \n    if ! curl -s http://localhost:18789/health &> /dev/null; then\n        echo \"\"\n        log_warning \"Gateway may still be starting. Check logs with: docker logs openclaw-gateway\"\n    fi\nfi\n\n# Success message\necho -e \"\\n${GREEN}╔══════════════════════════════════════════════════════════════╗${NC}\"\necho -e \"${GREEN}║                                                              ║${NC}\"\necho -e \"${GREEN}║              🎉 OpenClaw installed successfully! 🎉           ║${NC}\"\necho -e \"${GREEN}║                                                              ║${NC}\"\necho -e \"${GREEN}╚══════════════════════════════════════════════════════════════╝${NC}\"\n\necho -e \"\\n${BOLD}Quick reference:${NC}\"\necho -e \"  ${CYAN}Dashboard:${NC}      http://localhost:18790/?token=YOUR_TOKEN\"\necho -e \"  ${CYAN}GET TOKEN:${NC}      http://localhost:18790/?token=YOUR_TOKEN\"\necho -e \"  ${CYAN}Config:${NC}         ~/.openclaw/\"\necho -e \"  ${CYAN}Workspace:${NC}      cat ~/.openclaw/openclaw.json| grep '\"token\":' | grep -v '\"mode\"' | cut -d '\\\"' -f4\"\necho -e \"  ${CYAN}Install dir:${NC}    $INSTALL_DIR\"\n\necho -e \"\\n${BOLD}Useful commands:${NC}\"\necho -e \"  ${CYAN}View logs:${NC}      docker logs -f openclaw-gateway\"\necho -e \"  ${CYAN}Stop:${NC}           cd $INSTALL_DIR && $COMPOSE_CMD down\"\necho -e \"  ${CYAN}Start:${NC}          cd $INSTALL_DIR && $COMPOSE_CMD up -d openclaw-gateway\"\necho -e \"  ${CYAN}Restart:${NC}        cd $INSTALL_DIR && $COMPOSE_CMD restart openclaw-gateway\"\necho -e \"  ${CYAN}CLI:${NC}            cd $INSTALL_DIR && $COMPOSE_CMD run --rm openclaw-cli <command>\"\necho -e \"  ${CYAN}Update:${NC}         docker pull $IMAGE && cd $INSTALL_DIR && $COMPOSE_CMD up -d\"\n\necho -e \"\\n${BOLD}Documentation:${NC}  https://docs.openclaw.ai\"\necho -e \"${BOLD}Support:${NC}        https://discord.gg/clawd\"\necho -e \"${BOLD}Docker image:${NC}   $REPO_URL\"\n\necho -e \"\\n${YELLOW}Happy automating! 🤖🦞${NC}\\n\"\n"
  },
  {
    "path": "uninstall.ps1",
    "content": "#\n# OpenClaw (Clawbot) Docker Uninstaller - Windows PowerShell Version\n# Removes OpenClaw installation from your system\n#\n# Usage:\n#   irm https://raw.githubusercontent.com/phioranex/openclaw-docker/main/uninstall.ps1 | iex\n#\n# Or with options:\n#   & ([scriptblock]::Create((irm https://raw.githubusercontent.com/phioranex/openclaw-docker/main/uninstall.ps1))) -KeepData\n#\n\nparam(\n    [string]$InstallDir = \"$env:USERPROFILE\\openclaw\",\n    [switch]$KeepData,\n    [switch]$KeepImage,\n    [switch]$Force,\n    [switch]$Help\n)\n\n# Config\n$Image = \"ghcr.io/phioranex/openclaw-docker:latest\"\n\n# Error handling\n$ErrorActionPreference = \"Stop\"\n\n# Functions\nfunction Write-Banner {\n    Write-Host \"\"\n    Write-Host \"╔══════════════════════════════════════════════════════════════╗\" -ForegroundColor Red\n    Write-Host \"║                                                              ║\" -ForegroundColor Red\n    Write-Host \"║    ____                    _____ _                           ║\" -ForegroundColor Red\n    Write-Host \"║   / __ \\                  / ____| |                          ║\" -ForegroundColor Red\n    Write-Host \"║  | |  | |_ __   ___ _ __ | |    | | __ ___      __           ║\" -ForegroundColor Red\n    Write-Host \"║  | |  | | '_ \\ / _ \\ '_ \\| |    | |/ _`` \\ \\ /\\ / /           ║\" -ForegroundColor Red\n    Write-Host \"║  | |__| | |_) |  __/ | | | |____| | (_| |\\ V  V /            ║\" -ForegroundColor Red\n    Write-Host \"║   \\____/| .__/ \\___|_| |_|\\_____|_|\\__,_| \\_/\\_/             ║\" -ForegroundColor Red\n    Write-Host \"║         | |                                                  ║\" -ForegroundColor Red\n    Write-Host \"║         |_|                                                  ║\" -ForegroundColor Red\n    Write-Host \"║                                                              ║\" -ForegroundColor Red\n    Write-Host \"║            Docker Uninstaller by Phioranex                   ║\" -ForegroundColor Red\n    Write-Host \"║                                                              ║\" -ForegroundColor Red\n    Write-Host \"╚══════════════════════════════════════════════════════════════╝\" -ForegroundColor Red\n    Write-Host \"\"\n}\n\nfunction Write-Step {\n    param([string]$Message)\n    Write-Host \"\"\n    Write-Host \"▶ $Message\" -ForegroundColor Blue\n}\n\nfunction Write-Success {\n    param([string]$Message)\n    Write-Host \"✓ $Message\" -ForegroundColor Green\n}\n\nfunction Write-Warning {\n    param([string]$Message)\n    Write-Host \"⚠ $Message\" -ForegroundColor Yellow\n}\n\nfunction Write-ErrorMessage {\n    param([string]$Message)\n    Write-Host \"✗ $Message\" -ForegroundColor Red\n}\n\nfunction Confirm-Action {\n    param(\n        [string]$Prompt,\n        [string]$Default = \"n\"\n    )\n    \n    if ($Force) {\n        return $true\n    }\n    \n    if ($Default -eq \"y\") {\n        $PromptText = \"$Prompt [Y/n] \"\n    } else {\n        $PromptText = \"$Prompt [y/N] \"\n    }\n    \n    while ($true) {\n        Write-Host $PromptText -ForegroundColor Yellow -NoNewline\n        $response = Read-Host\n        if ([string]::IsNullOrEmpty($response)) {\n            $response = $Default\n        }\n        \n        switch -Regex ($response) {\n            '^[Yy]' { return $true }\n            '^[Nn]' { return $false }\n            default { Write-Host \"Please answer yes or no.\" }\n        }\n    }\n}\n\n# Show help\nif ($Help) {\n    Write-Host \"OpenClaw (Clawbot) Docker Uninstaller - Windows\"\n    Write-Host \"\"\n    Write-Host \"Usage: uninstall.ps1 [OPTIONS]\"\n    Write-Host \"\"\n    Write-Host \"Options:\"\n    Write-Host \"  -InstallDir DIR   Installation directory (default: ~\\openclaw)\"\n    Write-Host \"  -KeepData         Keep configuration and workspace data\"\n    Write-Host \"  -KeepImage        Keep Docker image\"\n    Write-Host \"  -Force            Skip confirmation prompts\"\n    Write-Host \"  -Help             Show this help message\"\n    return\n}\n\n# Main script\nWrite-Banner\n\nWrite-Host \"This will uninstall OpenClaw from your system.\" -ForegroundColor Yellow\nWrite-Host \"\"\n\n# Stop and remove containers\nWrite-Step \"Stopping and removing containers...\"\n\n$ContainersRemoved = $false\ntry {\n    $containers = docker ps -a --format \"{{.Names}}\" 2>$null\n    \n    if ($containers -match \"openclaw-gateway\") {\n        docker stop openclaw-gateway 2>$null | Out-Null\n        docker rm openclaw-gateway 2>$null | Out-Null\n        Write-Success \"Removed openclaw-gateway container\"\n        $ContainersRemoved = $true\n    }\n    \n    if ($containers -match \"openclaw-socat\") {\n        docker stop openclaw-socat 2>$null | Out-Null\n        docker rm openclaw-socat 2>$null | Out-Null\n        Write-Success \"Removed openclaw-socat container\"\n        $ContainersRemoved = $true\n    }\n    \n    if ($containers -match \"openclaw-cli\") {\n        docker rm openclaw-cli 2>$null | Out-Null\n        Write-Success \"Removed openclaw-cli container\"\n        $ContainersRemoved = $true\n    }\n} catch {\n    # Ignore errors\n}\n\nif (-not $ContainersRemoved) {\n    Write-Warning \"No OpenClaw containers found\"\n}\n\n# Remove data directories\n$ConfigDir = \"$env:USERPROFILE\\.openclaw\"\n\nif (-not $KeepData -and (Test-Path $ConfigDir)) {\n    Write-Step \"Data directories found at $ConfigDir\"\n    \n    if (Confirm-Action \"Remove configuration and workspace data? (This cannot be undone)\") {\n        Remove-Item -Path $ConfigDir -Recurse -Force -ErrorAction SilentlyContinue\n        Write-Success \"Removed data directory: $ConfigDir\"\n    } else {\n        Write-Warning \"Keeping data directory: $ConfigDir\"\n    }\n} elseif ($KeepData -and (Test-Path $ConfigDir)) {\n    Write-Warning \"Keeping data directory: $ConfigDir\"\n} elseif (-not (Test-Path $ConfigDir)) {\n    Write-Warning \"No data directory found at $ConfigDir\"\n}\n\n# Remove Docker image\nif (-not $KeepImage) {\n    try {\n        $images = docker images --format \"{{.Repository}}:{{.Tag}}\" 2>$null\n        \n        if ($images -match [regex]::Escape($Image)) {\n            Write-Step \"Docker image found: $Image\"\n            \n            if (Confirm-Action \"Remove Docker image? (You can re-download it later)\") {\n                try {\n                    docker rmi $Image 2>$null | Out-Null\n                    Write-Success \"Removed Docker image\"\n                } catch {\n                    Write-Warning \"Could not remove image (may be in use)\"\n                }\n            } else {\n                Write-Warning \"Keeping Docker image: $Image\"\n            }\n        } else {\n            Write-Warning \"No Docker image found: $Image\"\n        }\n    } catch {\n        Write-Warning \"Could not check for Docker image\"\n    }\n} else {\n    Write-Warning \"Keeping Docker image: $Image\"\n}\n\n# Remove installation directory\nif (Test-Path $InstallDir) {\n    Write-Step \"Installation directory found at $InstallDir\"\n    \n    if (Confirm-Action \"Remove installation directory?\") {\n        Remove-Item -Path $InstallDir -Recurse -Force -ErrorAction SilentlyContinue\n        Write-Success \"Removed installation directory: $InstallDir\"\n    } else {\n        Write-Warning \"Keeping installation directory: $InstallDir\"\n    }\n} else {\n    Write-Warning \"No installation directory found at $InstallDir\"\n}\n\n# Success message\nWrite-Host \"\"\nWrite-Host \"╔══════════════════════════════════════════════════════════════╗\" -ForegroundColor Green\nWrite-Host \"║                                                              ║\" -ForegroundColor Green\nWrite-Host \"║         OpenClaw has been uninstalled successfully! 👋        ║\" -ForegroundColor Green\nWrite-Host \"║                                                              ║\" -ForegroundColor Green\nWrite-Host \"╚══════════════════════════════════════════════════════════════╝\" -ForegroundColor Green\n\nif ($KeepData -or (Test-Path $ConfigDir)) {\n    Write-Host \"\"\n    Write-Host \"Data preserved:\" -ForegroundColor White\n    Write-Host \"  Config:         $ConfigDir\" -ForegroundColor Cyan\n    Write-Host \"  Workspace:      $ConfigDir\\workspace\" -ForegroundColor Cyan\n}\n\nWrite-Host \"\"\nWrite-Host \"To reinstall OpenClaw:\" -ForegroundColor White\nWrite-Host \"  irm https://raw.githubusercontent.com/phioranex/openclaw-docker/main/install.ps1 | iex\" -ForegroundColor Cyan\n\nWrite-Host \"\"\nWrite-Host \"Thank you for using OpenClaw! 🦞\" -ForegroundColor Yellow\nWrite-Host \"\"\n"
  },
  {
    "path": "uninstall.sh",
    "content": "#!/bin/bash\n#\n# OpenClaw (Clawbot) Docker Uninstaller\n# Removes OpenClaw installation from your system\n#\n# Usage:\n#   bash <(curl -fsSL https://raw.githubusercontent.com/phioranex/openclaw-docker/main/uninstall.sh)\n#\n# Or with options:\n#   bash <(curl -fsSL https://raw.githubusercontent.com/phioranex/openclaw-docker/main/uninstall.sh) --keep-data\n#\n\nset -e\n\n# Colors\nRED='\\033[0;31m'\nGREEN='\\033[0;32m'\nYELLOW='\\033[1;33m'\nBLUE='\\033[0;34m'\nCYAN='\\033[0;36m'\nBOLD='\\033[1m'\nNC='\\033[0m' # No Color\n\n# Config\nINSTALL_DIR=\"${OPENCLAW_INSTALL_DIR:-$HOME/openclaw}\"\nIMAGE=\"ghcr.io/phioranex/openclaw-docker:latest\"\n\n# Flags\nKEEP_DATA=false\nKEEP_IMAGE=false\nFORCE=false\n\n# Parse arguments\nwhile [[ $# -gt 0 ]]; do\n    case $1 in\n        --keep-data)\n            KEEP_DATA=true\n            shift\n            ;;\n        --keep-image)\n            KEEP_IMAGE=true\n            shift\n            ;;\n        --force|-f)\n            FORCE=true\n            shift\n            ;;\n        --install-dir)\n            INSTALL_DIR=\"$2\"\n            shift 2\n            ;;\n        --help|-h)\n            echo \"OpenClaw (Clawbot) Docker Uninstaller\"\n            echo \"\"\n            echo \"Usage: uninstall.sh [OPTIONS]\"\n            echo \"\"\n            echo \"Options:\"\n            echo \"  --install-dir DIR   Installation directory (default: ~/openclaw)\"\n            echo \"  --keep-data         Keep configuration and workspace data\"\n            echo \"  --keep-image        Keep Docker image\"\n            echo \"  --force, -f         Skip confirmation prompts\"\n            echo \"  --help, -h          Show this help message\"\n            exit 0\n            ;;\n        *)\n            echo -e \"${RED}Unknown option: $1${NC}\"\n            exit 1\n            ;;\n    esac\ndone\n\n# Functions\nprint_banner() {\n    echo -e \"${RED}\"\n    echo \"╔══════════════════════════════════════════════════════════════╗\"\n    echo \"║                                                              ║\"\n    echo \"║    ____                    _____ _                           ║\"\n    echo \"║   / __ \\\\\\\\                  / ____| |                          ║\"\n    echo \"║  | |  | |_ __   ___ _ __ | |    | | __ ___      __           ║\"\n    echo \"║  | |  | | '_ \\\\\\\\ / _ \\\\\\\\ '_ \\\\\\\\| |    | |/ _\\\\\\` \\\\\\\\ \\\\\\\\ /\\\\\\\\ / /           ║\"\n    echo \"║  | |__| | |_) |  __/ | | | |____| | (_| |\\\\\\\\ V  V /            ║\"\n    echo \"║   \\\\\\\\____/| .__/ \\\\\\\\___|_| |_|\\\\\\\\_____|_|\\\\\\\\__,_| \\\\\\\\_/\\\\\\\\_/             ║\"\n    echo \"║         | |                                                  ║\"\n    echo \"║         |_|                                                  ║\"\n    echo \"║                                                              ║\"\n    echo \"║            Docker Uninstaller by Phioranex                   ║\"\n    echo \"║                                                              ║\"\n    echo \"╚══════════════════════════════════════════════════════════════╝\"\n    echo -e \"${NC}\"\n}\n\n# Get user's home directory, handling sudo correctly\nget_user_home() {\n    if [ -n \"$SUDO_USER\" ]; then\n        # Running with sudo - use the actual user's home\n        local user_home\n        user_home=$(getent passwd \"$SUDO_USER\" | cut -d: -f6)\n        if [ -z \"$user_home\" ]; then\n            # Fallback to eval if getent fails\n            user_home=$(eval echo ~\"$SUDO_USER\")\n        fi\n        echo \"$user_home\"\n    else\n        # Running normally\n        echo \"$HOME\"\n    fi\n}\n\nlog_step() {\n    echo -e \"\\n${BLUE}▶${NC} ${BOLD}$1${NC}\"\n}\n\nlog_success() {\n    echo -e \"${GREEN}✓${NC} $1\"\n}\n\nlog_warning() {\n    echo -e \"${YELLOW}⚠${NC} $1\"\n}\n\nlog_error() {\n    echo -e \"${RED}✗${NC} $1\"\n}\n\nconfirm() {\n    if [ \"$FORCE\" = true ]; then\n        return 0\n    fi\n    \n    local prompt=\"$1\"\n    local default=\"${2:-n}\"\n    \n    if [ \"$default\" = \"y\" ]; then\n        prompt=\"$prompt [Y/n] \"\n    else\n        prompt=\"$prompt [y/N] \"\n    fi\n    \n    while true; do\n        read -p \"$(echo -e \"${YELLOW}$prompt${NC}\")\" -r response\n        response=${response:-$default}\n        case \"$response\" in\n            [Yy]* ) return 0;;\n            [Nn]* ) return 1;;\n            * ) echo \"Please answer yes or no.\";;\n        esac\n    done\n}\n\n# Main script\nprint_banner\n\necho -e \"${YELLOW}This will uninstall OpenClaw from your system.${NC}\"\necho \"\"\n\n# Stop and remove containers\nlog_step \"Stopping and removing containers...\"\n\nCONTAINERS_REMOVED=false\nif docker ps -a --format '{{.Names}}' | grep -q \"openclaw-gateway\"; then\n    docker stop openclaw-gateway 2>/dev/null || true\n    docker rm openclaw-gateway 2>/dev/null || true\n    log_success \"Removed openclaw-gateway container\"\n    CONTAINERS_REMOVED=true\nfi\n\nif docker ps -a --format '{{.Names}}' | grep -q \"openclaw-socat\"; then\n    docker stop openclaw-socat 2>/dev/null || true\n    docker rm openclaw-socat 2>/dev/null || true\n    log_success \"Removed openclaw-socat container\"\n    CONTAINERS_REMOVED=true\nfi\n\nif docker ps -a --format '{{.Names}}' | grep -q \"openclaw-cli\"; then\n    docker rm openclaw-cli 2>/dev/null || true\n    log_success \"Removed openclaw-cli container\"\n    CONTAINERS_REMOVED=true\nfi\n\nif [ \"$CONTAINERS_REMOVED\" = false ]; then\n    log_warning \"No OpenClaw containers found\"\nfi\n\n# Remove data directories\nUSER_HOME=$(get_user_home)\nOPENCLAW_DIR=\"$USER_HOME/.openclaw\"\n\nif [ \"$KEEP_DATA\" = false ] && [ -d \"$OPENCLAW_DIR\" ]; then\n    log_step \"Data directories found at $OPENCLAW_DIR\"\n    \n    if confirm \"Remove configuration and workspace data? (This cannot be undone)\"; then\n        rm -rf \"$OPENCLAW_DIR\"\n        log_success \"Removed data directory: $OPENCLAW_DIR\"\n    else\n        log_warning \"Keeping data directory: $OPENCLAW_DIR\"\n    fi\nelif [ \"$KEEP_DATA\" = true ] && [ -d \"$OPENCLAW_DIR\" ]; then\n    log_warning \"Keeping data directory: $OPENCLAW_DIR\"\nelif [ ! -d \"$OPENCLAW_DIR\" ]; then\n    log_warning \"No data directory found at $OPENCLAW_DIR\"\nfi\n\n# Remove Docker image\nif [ \"$KEEP_IMAGE\" = false ]; then\n    if docker images --format '{{.Repository}}:{{.Tag}}' | grep -q \"$IMAGE\"; then\n        log_step \"Docker image found: $IMAGE\"\n        \n        if confirm \"Remove Docker image? (You can re-download it later)\"; then\n            docker rmi \"$IMAGE\" 2>/dev/null || log_warning \"Could not remove image (may be in use)\"\n            log_success \"Removed Docker image\"\n        else\n            log_warning \"Keeping Docker image: $IMAGE\"\n        fi\n    else\n        log_warning \"No Docker image found: $IMAGE\"\n    fi\nelse\n    log_warning \"Keeping Docker image: $IMAGE\"\nfi\n\n# Remove installation directory\nif [ -d \"$INSTALL_DIR\" ]; then\n    log_step \"Installation directory found at $INSTALL_DIR\"\n    \n    if confirm \"Remove installation directory?\"; then\n        rm -rf \"$INSTALL_DIR\"\n        log_success \"Removed installation directory: $INSTALL_DIR\"\n    else\n        log_warning \"Keeping installation directory: $INSTALL_DIR\"\n    fi\nelse\n    log_warning \"No installation directory found at $INSTALL_DIR\"\nfi\n\n# Success message\necho -e \"\\n${GREEN}╔══════════════════════════════════════════════════════════════╗${NC}\"\necho -e \"${GREEN}║                                                              ║${NC}\"\necho -e \"${GREEN}║         OpenClaw has been uninstalled successfully! 👋        ║${NC}\"\necho -e \"${GREEN}║                                                              ║${NC}\"\necho -e \"${GREEN}╚══════════════════════════════════════════════════════════════╝${NC}\"\n\nif [ \"$KEEP_DATA\" = true ] || [ -d \"$OPENCLAW_DIR\" ]; then\n    echo -e \"\\n${BOLD}Data preserved:${NC}\"\n    echo -e \"  ${CYAN}Config:${NC}         $OPENCLAW_DIR\"\n    echo -e \"  ${CYAN}Workspace:${NC}      $OPENCLAW_DIR/workspace\"\nfi\n\necho -e \"\\n${BOLD}To reinstall OpenClaw:${NC}\"\necho -e \"  ${CYAN}bash <(curl -fsSL https://raw.githubusercontent.com/phioranex/openclaw-docker/main/install.sh)${NC}\"\n\necho -e \"\\n${YELLOW}Thank you for using OpenClaw! 🦞${NC}\\n\"\n"
  }
]