chore: import upstream snapshot with attribution
@@ -0,0 +1,163 @@
|
||||
# Android에서 프로세스 라이브 상태 유지
|
||||
|
||||
OpenClaw는 서버로 동작하므로 Android의 전원 관리 및 프로세스 종료 기능이 안정적인 운영을 방해할 수 있습니다. 이 가이드에서는 프로세스를 안정적으로 유지하기 위한 모든 설정을 다룹니다.
|
||||
|
||||
## 개발자 옵션 활성화
|
||||
|
||||
1. **설정** > **휴대전화 정보** (또는 **디바이스 정보**)
|
||||
2. **빌드 번호**를 7번 연속 탭
|
||||
3. "개발자 모드가 활성화되었습니다" 메시지 확인
|
||||
4. 잠금화면 비밀번호가 설정되어 있으면 입력
|
||||
|
||||
> 일부 기기에서는 **설정** > **휴대전화 정보** > **소프트웨어 정보** 안에 빌드 번호가 있습니다.
|
||||
|
||||
## 충전 중 화면 켜짐 유지 (Stay Awake)
|
||||
|
||||
1. **설정** > **개발자 옵션** (위에서 활성화한 메뉴)
|
||||
2. **화면 켜짐 유지** (Stay awake) 옵션을 **ON**
|
||||
3. 이제 USB 또는 무선 충전 중에는 화면이 자동으로 꺿지지 않습니다
|
||||
|
||||
> 충전기를 분리하면 일반 화면 꺿짐 설정이 적용됩니다. 서버를 장시간 운영할 때는 충전기를 연결해두세요.
|
||||
|
||||
## 충전 제한 설정 (필수)
|
||||
|
||||
폰을 24시간 충전 상태로 두면 배터리가 펽창할 수 있습니다. 최대 충전량을 80%로 제한하면 배터리 수명과 안전성이 크게 향상됩니다.
|
||||
|
||||
- **삼성**: **설정** > **배터리** > **배터리 보호** → **최대 80%** 선택
|
||||
- **Google Pixel**: **설정** > **배터리** > **배터리 보호** → ON
|
||||
|
||||
> 제조사마다 메뉴 이름이 다를 수 있습니다. "배터리 보호" 또는 "충전 제한"으로 검색하세요. 해당 기능이 없는 기기에서는 충전기를 수동으로 관리하거나 스마트 플러그를 활용할 수 있습니다.
|
||||
|
||||
## 배터리 최적화에서 Termux 제외
|
||||
|
||||
1. Android **설정** > **배터리** (또는 **배터리 및 기기 관리**)
|
||||
2. **배터리 최적화** (또는 **앱 절전**) 메뉴 진입
|
||||
3. 앱 목록에서 **Termux** 를 찾아서 **최적화하지 않음** (또는 **제한 없음**) 선택
|
||||
|
||||
> 메뉴 경로는 제조사(삼성, LG 등)와 Android 버전에 따라 다를 수 있습니다. "배터리 최적화 제외" 또는 "앱 절전 해제"로 검색하면 해당 기기의 정확한 경로를 찾을 수 있습니다.
|
||||
|
||||
## Phantom Process Killer 비활성화 (Android 12+)
|
||||
|
||||
Android 12 이상에는 **Phantom Process Killer**라는 기능이 포함되어 있어, 백그라운드 프로세스를 자동으로 종료합니다. 이로 인해 Termux에서 실행 중인 `openclaw gateway`, `sshd`, `ttyd` 등이 예고 없이 종료될 수 있습니다.
|
||||
|
||||
## 증상
|
||||
|
||||
Termux에서 다음과 같은 메시지가 보이면 Android가 프로세스를 강제 종료한 것입니다:
|
||||
|
||||
```
|
||||
[Process completed (signal 9) - press Enter]
|
||||
```
|
||||
|
||||
<img src="images/signal9/01-signal9-killed.png" width="300" alt="Process completed signal 9">
|
||||
|
||||
Signal 9 (SIGKILL)는 어떤 프로세스도 가로채거나 차단할 수 없습니다 — Android가 OS 수준에서 종료한 것입니다.
|
||||
|
||||
## 요구사항
|
||||
|
||||
- **Android 12 이상** (Android 11 이하는 해당 없음)
|
||||
- **Termux**에 `android-tools` 설치 (OpenClaw on Android에 포함)
|
||||
|
||||
## 1단계: Wake Lock 활성화
|
||||
|
||||
알림 바를 내려서 Termux 알림을 찾으세요. **Acquire wakelock**을 탭하면 Android가 Termux를 중단시키는 것을 방지할 수 있습니다.
|
||||
|
||||
<p>
|
||||
<img src="images/signal9/02-termux-acquire-wakelock.png" width="300" alt="Acquire wakelock 탭">
|
||||
<img src="images/signal9/03-termux-wakelock-held.png" width="300" alt="Wake lock held">
|
||||
</p>
|
||||
|
||||
활성화되면 알림에 **"wake lock held"**가 표시되고 버튼이 **Release wakelock**으로 바뀝니다.
|
||||
|
||||
> Wake lock만으로는 Phantom Process Killer를 완전히 막을 수 없습니다. 아래 단계를 계속 진행하세요.
|
||||
|
||||
## 2단계: 무선 디버깅 활성화
|
||||
|
||||
1. **설정** > **개발자 옵션**으로 이동
|
||||
2. **무선 디버깅** (Wireless debugging)을 찾아서 활성화
|
||||
3. 확인 다이얼로그가 나타나면 — **"이 네트워크에서 항상 허용"**을 체크하고 **허용** 탭
|
||||
|
||||
<img src="images/signal9/04-wireless-debugging-allow.png" width="300" alt="무선 디버깅 허용">
|
||||
|
||||
## 3단계: ADB 설치 (아직 설치하지 않은 경우)
|
||||
|
||||
Termux에서 `android-tools`를 설치합니다:
|
||||
|
||||
```bash
|
||||
pkg install -y android-tools
|
||||
```
|
||||
|
||||
> OpenClaw on Android를 설치했다면 `android-tools`가 이미 포함되어 있습니다.
|
||||
|
||||
## 4단계: ADB 페어링
|
||||
|
||||
1. **무선 디버깅** 설정에서 **페어링 코드로 기기 페어링** (Pair device with pairing code) 탭
|
||||
2. **Wi-Fi 페어링 코드**와 **IP 주소 및 포트**가 표시된 다이얼로그가 나타남
|
||||
|
||||
<img src="images/signal9/05-pairing-code-dialog.png" width="300" alt="페어링 코드 다이얼로그">
|
||||
|
||||
3. Termux에서 화면에 표시된 포트와 코드를 사용하여 페어링 명령을 실행합니다:
|
||||
|
||||
```bash
|
||||
adb pair localhost:<페어링_포트> <페어링_코드>
|
||||
```
|
||||
|
||||
예시:
|
||||
|
||||
```bash
|
||||
adb pair localhost:39555 269556
|
||||
```
|
||||
|
||||
<img src="images/signal9/06-adb-pair-success.png" width="600" alt="adb pair 성공">
|
||||
|
||||
`Successfully paired`가 표시되면 성공입니다.
|
||||
|
||||
## 5단계: ADB 연결
|
||||
|
||||
페어링 후 **무선 디버깅** 메인 화면으로 돌아가세요. 상단에 표시된 **IP 주소 및 포트**를 확인합니다 — 이 포트는 페어링 포트와 다릅니다.
|
||||
|
||||
<img src="images/signal9/07-wireless-debugging-paired.png" width="300" alt="무선 디버깅 페어링 완료">
|
||||
|
||||
Termux에서 메인 화면에 표시된 포트로 연결합니다:
|
||||
|
||||
```bash
|
||||
adb connect localhost:<연결_포트>
|
||||
```
|
||||
|
||||
예시:
|
||||
|
||||
```bash
|
||||
adb connect localhost:35541
|
||||
```
|
||||
|
||||
`connected to localhost:35541`이 표시되면 성공입니다.
|
||||
|
||||
> 페어링 포트와 연결 포트는 다릅니다. `adb connect`에는 무선 디버깅 메인 화면에 표시된 포트를 사용하세요.
|
||||
|
||||
## 6단계: Phantom Process Killer 비활성화
|
||||
|
||||
다음 명령을 실행하여 Phantom Process Killer를 비활성화합니다:
|
||||
|
||||
```bash
|
||||
adb shell "settings put global settings_enable_monitor_phantom_procs false"
|
||||
```
|
||||
|
||||
설정이 적용되었는지 확인합니다:
|
||||
|
||||
```bash
|
||||
adb shell "settings get global settings_enable_monitor_phantom_procs"
|
||||
```
|
||||
|
||||
출력이 `false`이면 Phantom Process Killer가 성공적으로 비활성화된 것입니다.
|
||||
|
||||
<img src="images/signal9/08-adb-disable-ppk-done.png" width="600" alt="Phantom Process Killer 비활성화 완료">
|
||||
|
||||
## 참고 사항
|
||||
|
||||
- 이 설정은 **재부팅해도 유지**됩니다 — 한 번만 하면 됩니다
|
||||
- 이 과정을 완료한 후 무선 디버깅을 켜둘 필요는 없습니다. 꺼도 됩니다
|
||||
- 일반 앱 동작에는 영향을 주지 않습니다 — Termux의 백그라운드 프로세스가 종료되는 것만 방지합니다
|
||||
- 폰을 초기화하면 이 과정을 다시 수행해야 합니다
|
||||
|
||||
## 추가 참고
|
||||
|
||||
일부 제조사(삼성, 샤오미, 화웨이 등)는 자체적으로 공격적인 배터리 최적화를 적용하여 백그라운드 앱을 종료시킬 수 있습니다. Phantom Process Killer를 비활성화한 후에도 프로세스가 종료되는 경우, [dontkillmyapp.com](https://dontkillmyapp.com)에서 기기별 가이드를 확인하세요.
|
||||
@@ -0,0 +1,163 @@
|
||||
# Keeping Processes Alive on Android
|
||||
|
||||
OpenClaw runs as a server, so Android's power management and process killing can interfere with stable operation. This guide covers all the settings needed to keep your processes running reliably.
|
||||
|
||||
## Enable Developer Options
|
||||
|
||||
1. Go to **Settings** > **About phone** (or **Device information**)
|
||||
2. Tap **Build number** 7 times
|
||||
3. You'll see "Developer mode has been enabled"
|
||||
4. Enter your lock screen password if prompted
|
||||
|
||||
> On some devices, Build number is under **Settings** > **About phone** > **Software information**.
|
||||
|
||||
## Stay Awake While Charging
|
||||
|
||||
1. Go to **Settings** > **Developer options** (the menu you just enabled)
|
||||
2. Turn on **Stay awake**
|
||||
3. The screen will now stay on whenever the device is charging (USB or wireless)
|
||||
|
||||
> The screen will still turn off normally when unplugged. Keep the charger connected when running the server for extended periods.
|
||||
|
||||
## Set Charge Limit (Required)
|
||||
|
||||
Keeping a phone plugged in 24/7 at 100% can cause battery swelling. Limiting the maximum charge to 80% greatly improves battery lifespan and safety.
|
||||
|
||||
- **Samsung**: **Settings** > **Battery** > **Battery Protection** → Select **Maximum 80%**
|
||||
- **Google Pixel**: **Settings** > **Battery** > **Battery Protection** → ON
|
||||
|
||||
> Menu names vary by manufacturer. Search for "battery protection" or "charge limit" in your settings. If your device doesn't have this feature, consider managing the charger manually or using a smart plug.
|
||||
|
||||
## Disable Battery Optimization for Termux
|
||||
|
||||
1. Go to Android **Settings** > **Battery** (or **Battery and device care**)
|
||||
2. Open **Battery optimization** (or **App power management**)
|
||||
3. Find **Termux** and set it to **Not optimized** (or **Unrestricted**)
|
||||
|
||||
> The exact menu path varies by manufacturer (Samsung, LG, etc.) and Android version. Search your settings for "battery optimization" to find it.
|
||||
|
||||
## Disable Phantom Process Killer (Android 12+)
|
||||
|
||||
Android 12 and above includes a feature called **Phantom Process Killer** that automatically terminates background processes. This can cause Termux processes like `openclaw gateway`, `sshd`, and `ttyd` to be killed without warning.
|
||||
|
||||
## Symptoms
|
||||
|
||||
If you see this message in Termux, Android has forcibly killed the process:
|
||||
|
||||
```
|
||||
[Process completed (signal 9) - press Enter]
|
||||
```
|
||||
|
||||
<img src="images/signal9/01-signal9-killed.png" width="300" alt="Process completed signal 9">
|
||||
|
||||
Signal 9 (SIGKILL) cannot be caught or blocked by any process — Android terminated it at the OS level.
|
||||
|
||||
## Requirements
|
||||
|
||||
- **Android 12 or higher** (Android 11 and below are not affected)
|
||||
- **Termux** with `android-tools` installed (included in OpenClaw on Android)
|
||||
|
||||
## Step 1: Acquire Wake Lock
|
||||
|
||||
Pull down the notification bar and find the Termux notification. Tap **Acquire wakelock** to prevent Android from suspending Termux.
|
||||
|
||||
<p>
|
||||
<img src="images/signal9/02-termux-acquire-wakelock.png" width="300" alt="Tap Acquire wakelock">
|
||||
<img src="images/signal9/03-termux-wakelock-held.png" width="300" alt="Wake lock held">
|
||||
</p>
|
||||
|
||||
Once activated, the notification will show **"wake lock held"** and the button changes to **Release wakelock**.
|
||||
|
||||
> Wake lock alone is not enough to prevent Phantom Process Killer. Continue with the steps below.
|
||||
|
||||
## Step 2: Enable Wireless Debugging
|
||||
|
||||
1. Go to **Settings** > **Developer options**
|
||||
2. Find and enable **Wireless debugging**
|
||||
3. A confirmation dialog will appear — check **"Always allow on this network"** and tap **Allow**
|
||||
|
||||
<img src="images/signal9/04-wireless-debugging-allow.png" width="300" alt="Allow wireless debugging">
|
||||
|
||||
## Step 3: Install ADB (if not already installed)
|
||||
|
||||
In Termux, install `android-tools`:
|
||||
|
||||
```bash
|
||||
pkg install -y android-tools
|
||||
```
|
||||
|
||||
> If you installed OpenClaw on Android, `android-tools` is already included.
|
||||
|
||||
## Step 4: Pair with ADB
|
||||
|
||||
1. In **Wireless debugging** settings, tap **Pair device with pairing code**
|
||||
2. A dialog will show the **Wi-Fi pairing code** and **IP address & Port**
|
||||
|
||||
<img src="images/signal9/05-pairing-code-dialog.png" width="300" alt="Pairing code dialog">
|
||||
|
||||
3. In Termux, run the pairing command using the port and code shown on screen:
|
||||
|
||||
```bash
|
||||
adb pair localhost:<PAIRING_PORT> <PAIRING_CODE>
|
||||
```
|
||||
|
||||
Example:
|
||||
|
||||
```bash
|
||||
adb pair localhost:39555 269556
|
||||
```
|
||||
|
||||
<img src="images/signal9/06-adb-pair-success.png" width="600" alt="adb pair success">
|
||||
|
||||
You should see `Successfully paired`.
|
||||
|
||||
## Step 5: Connect with ADB
|
||||
|
||||
After pairing, go back to the **Wireless debugging** main screen. Note the **IP address & Port** shown at the top — this is different from the pairing port.
|
||||
|
||||
<img src="images/signal9/07-wireless-debugging-paired.png" width="300" alt="Wireless debugging paired">
|
||||
|
||||
In Termux, connect using the port shown on the main screen:
|
||||
|
||||
```bash
|
||||
adb connect localhost:<CONNECTION_PORT>
|
||||
```
|
||||
|
||||
Example:
|
||||
|
||||
```bash
|
||||
adb connect localhost:35541
|
||||
```
|
||||
|
||||
You should see `connected to localhost:35541`.
|
||||
|
||||
> The pairing port and connection port are different. Use the port shown on the Wireless debugging main screen for `adb connect`.
|
||||
|
||||
## Step 6: Disable Phantom Process Killer
|
||||
|
||||
Now run the following command to disable Phantom Process Killer:
|
||||
|
||||
```bash
|
||||
adb shell "settings put global settings_enable_monitor_phantom_procs false"
|
||||
```
|
||||
|
||||
Verify the setting:
|
||||
|
||||
```bash
|
||||
adb shell "settings get global settings_enable_monitor_phantom_procs"
|
||||
```
|
||||
|
||||
If the output is `false`, Phantom Process Killer has been successfully disabled.
|
||||
|
||||
<img src="images/signal9/08-adb-disable-ppk-done.png" width="600" alt="Phantom Process Killer disabled">
|
||||
|
||||
## Notes
|
||||
|
||||
- This setting **persists across reboots** — you only need to do this once
|
||||
- You do **not** need to keep Wireless debugging enabled after completing these steps. You can turn it off
|
||||
- This does not affect normal app behavior — it only prevents Android from killing background processes in Termux
|
||||
- If you factory reset your phone, you will need to repeat this process
|
||||
|
||||
## Further Reading
|
||||
|
||||
Some manufacturers (Samsung, Xiaomi, Huawei, etc.) apply additional aggressive battery optimization that can kill background apps. If you still experience process termination after disabling Phantom Process Killer, check [dontkillmyapp.com](https://dontkillmyapp.com) for device-specific guides.
|
||||
@@ -0,0 +1,9 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 108 108">
|
||||
<circle cx="54" cy="54" r="54" fill="#111827"/>
|
||||
<g transform="rotate(-25 54 54)">
|
||||
<path fill="#FFF" d="M31,22 C28,44,28,64,31,86 C34,64,34,44,31,22Z"/>
|
||||
<path fill="#FFF" d="M43,16 C40,40,40,64,43,92 C46,64,46,40,43,16Z"/>
|
||||
<path fill="#FFF" d="M55,16 C52,40,52,64,55,92 C58,64,58,40,55,16Z"/>
|
||||
<path fill="#FFF" d="M67,22 C64,44,64,64,67,86 C70,64,70,44,67,22Z"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 459 B |
|
After Width: | Height: | Size: 397 KiB |
|
After Width: | Height: | Size: 2.6 MiB |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 120 120"><defs><linearGradient id="a" x1="0%" x2="100%" y1="0%" y2="100%"><stop offset="0%" stop-color="#ff4d4d"/><stop offset="100%" stop-color="#991b1b"/></linearGradient></defs><path fill="url(#a)" d="M60 10c-30 0-45 25-45 45s15 40 30 45v10h10v-10s5 2 10 0v10h10v-10c15-5 30-25 30-45S90 10 60 10"/><path fill="url(#a)" d="M20 45C5 40 0 50 5 60s15 5 20-5c3-7 0-10-5-10M100 45c15-5 20 5 15 15s-15 5-20-5c-3-7 0-10 5-10"/><path stroke="#ff4d4d" stroke-linecap="round" stroke-width="3" d="M45 15Q35 5 30 8M75 15Q85 5 90 8"/><circle cx="45" cy="35" r="6" fill="#050810"/><circle cx="75" cy="35" r="6" fill="#050810"/><circle cx="46" cy="34" r="2.5" fill="#00e5cc"/><circle cx="76" cy="34" r="2.5" fill="#00e5cc"/></svg>
|
||||
|
After Width: | Height: | Size: 782 B |
|
After Width: | Height: | Size: 40 KiB |
|
After Width: | Height: | Size: 162 KiB |
|
After Width: | Height: | Size: 109 KiB |
|
After Width: | Height: | Size: 225 KiB |
|
After Width: | Height: | Size: 128 KiB |
|
After Width: | Height: | Size: 1.6 MiB |
|
After Width: | Height: | Size: 1.6 MiB |
|
After Width: | Height: | Size: 143 KiB |
|
After Width: | Height: | Size: 121 KiB |
|
After Width: | Height: | Size: 40 KiB |
|
After Width: | Height: | Size: 113 KiB |
|
After Width: | Height: | Size: 70 KiB |
|
After Width: | Height: | Size: 336 KiB |
|
After Width: | Height: | Size: 90 KiB |
|
After Width: | Height: | Size: 201 KiB |
|
After Width: | Height: | Size: 97 KiB |
@@ -0,0 +1,258 @@
|
||||
# Playwright Install Option Implementation Plan
|
||||
|
||||
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
|
||||
|
||||
**Goal:** Add Playwright as an optional tool in `oa --install`, with automatic Chromium dependency resolution, environment variable setup, and usage guide.
|
||||
|
||||
**Architecture:** New `scripts/install-playwright.sh` follows the existing delegated-script pattern (like `install-chromium.sh`). `install-tools.sh` gets a new menu entry right after Chromium. The install script checks Chromium dependency, installs `playwright-core` via npm, sets Playwright environment variables in `.bashrc`, and prints a usage guide.
|
||||
|
||||
**Tech Stack:** Bash, npm (playwright-core), Termux environment
|
||||
|
||||
---
|
||||
|
||||
### Task 1: Create `scripts/install-playwright.sh`
|
||||
|
||||
**Files:**
|
||||
- Create: `scripts/install-playwright.sh`
|
||||
|
||||
- [ ] **Step 1: Create the install script**
|
||||
|
||||
```bash
|
||||
#!/usr/bin/env bash
|
||||
# install-playwright.sh - Install Playwright for browser automation
|
||||
# Usage: bash install-playwright.sh [install|update]
|
||||
#
|
||||
# What it does:
|
||||
# 1. Ensure Chromium is installed (dependency)
|
||||
# 2. Install playwright-core via npm global
|
||||
# 3. Set Playwright environment variables in .bashrc
|
||||
# 4. Print usage guide
|
||||
#
|
||||
# This script is WARN-level: failure does not abort the parent installer.
|
||||
set -euo pipefail
|
||||
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
BOLD='\033[1m'
|
||||
NC='\033[0m'
|
||||
|
||||
MODE="${1:-install}"
|
||||
|
||||
# ── Helper ────────────────────────────────────
|
||||
|
||||
fail_warn() {
|
||||
echo -e "${YELLOW}[WARN]${NC} $1"
|
||||
exit 0
|
||||
}
|
||||
|
||||
# ── Detect Chromium binary path ───────────────
|
||||
|
||||
detect_chromium_bin() {
|
||||
for bin in "$PREFIX/bin/chromium-browser" "$PREFIX/bin/chromium"; do
|
||||
if [ -x "$bin" ]; then
|
||||
echo "$bin"
|
||||
return 0
|
||||
fi
|
||||
done
|
||||
return 1
|
||||
}
|
||||
|
||||
# ── Pre-checks ────────────────────────────────
|
||||
|
||||
if [ -z "${PREFIX:-}" ]; then
|
||||
fail_warn "Not running in Termux (\$PREFIX not set)"
|
||||
fi
|
||||
|
||||
if ! command -v npm &>/dev/null; then
|
||||
fail_warn "npm not found — Node.js is required for Playwright"
|
||||
fi
|
||||
|
||||
# ── Step 1: Ensure Chromium is installed ──────
|
||||
|
||||
if ! CHROMIUM_BIN=$(detect_chromium_bin); then
|
||||
echo "Chromium is required for Playwright. Installing..."
|
||||
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
||||
if [ -f "$SCRIPT_DIR/install-chromium.sh" ]; then
|
||||
if ! bash "$SCRIPT_DIR/install-chromium.sh" install; then
|
||||
fail_warn "Chromium installation failed — cannot proceed with Playwright"
|
||||
fi
|
||||
else
|
||||
fail_warn "install-chromium.sh not found — install Chromium first"
|
||||
fi
|
||||
|
||||
if ! CHROMIUM_BIN=$(detect_chromium_bin); then
|
||||
fail_warn "Chromium binary not found after installation"
|
||||
fi
|
||||
fi
|
||||
|
||||
echo -e "${GREEN}[OK]${NC} Chromium found: $CHROMIUM_BIN"
|
||||
|
||||
# ── Step 2: Install playwright-core ───────────
|
||||
|
||||
if [ "$MODE" = "install" ]; then
|
||||
# Check if already installed
|
||||
if npm list -g playwright-core &>/dev/null; then
|
||||
echo -e "${GREEN}[SKIP]${NC} playwright-core already installed"
|
||||
else
|
||||
echo "Installing playwright-core..."
|
||||
if ! npm install -g playwright-core; then
|
||||
fail_warn "Failed to install playwright-core"
|
||||
fi
|
||||
echo -e "${GREEN}[OK]${NC} playwright-core installed"
|
||||
fi
|
||||
elif [ "$MODE" = "update" ]; then
|
||||
echo "Updating playwright-core..."
|
||||
if ! npm install -g playwright-core@latest; then
|
||||
fail_warn "Failed to update playwright-core"
|
||||
fi
|
||||
echo -e "${GREEN}[OK]${NC} playwright-core updated"
|
||||
fi
|
||||
|
||||
# ── Step 3: Set environment variables ─────────
|
||||
|
||||
BASHRC="$HOME/.bashrc"
|
||||
PW_MARKER_START="# >>> Playwright >>>"
|
||||
PW_MARKER_END="# <<< Playwright <<<"
|
||||
|
||||
PW_BLOCK="${PW_MARKER_START}
|
||||
export PLAYWRIGHT_CHROMIUM_EXECUTABLE_PATH=\"$CHROMIUM_BIN\"
|
||||
export PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD=1
|
||||
${PW_MARKER_END}"
|
||||
|
||||
touch "$BASHRC"
|
||||
if grep -qF "$PW_MARKER_START" "$BASHRC"; then
|
||||
sed -i "/${PW_MARKER_START//\//\\/}/,/${PW_MARKER_END//\//\\/}/d" "$BASHRC"
|
||||
fi
|
||||
echo "" >> "$BASHRC"
|
||||
echo "$PW_BLOCK" >> "$BASHRC"
|
||||
|
||||
echo -e "${GREEN}[OK]${NC} Environment variables set in .bashrc"
|
||||
echo " PLAYWRIGHT_CHROMIUM_EXECUTABLE_PATH=$CHROMIUM_BIN"
|
||||
echo " PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD=1"
|
||||
|
||||
# ── Step 4: Usage guide ──────────────────────
|
||||
|
||||
echo ""
|
||||
echo -e "${BOLD} Playwright is ready!${NC}"
|
||||
echo ""
|
||||
echo " To use in your project:"
|
||||
echo ""
|
||||
echo " npm install playwright-core # add to your project"
|
||||
echo ""
|
||||
echo " Example code:"
|
||||
echo ""
|
||||
echo " const { chromium } = require('playwright-core');"
|
||||
echo ""
|
||||
echo " const browser = await chromium.launch();"
|
||||
echo " const page = await browser.newPage();"
|
||||
echo " await page.goto('https://example.com');"
|
||||
echo " await page.screenshot({ path: 'screenshot.png' });"
|
||||
echo " await browser.close();"
|
||||
echo ""
|
||||
echo -e " ${YELLOW}[NOTE]${NC} Environment variables are set. No need to specify"
|
||||
echo " executablePath or --no-sandbox manually."
|
||||
echo ""
|
||||
echo " To apply environment variables in current session:"
|
||||
echo " source ~/.bashrc"
|
||||
echo ""
|
||||
```
|
||||
|
||||
Write this to `scripts/install-playwright.sh`.
|
||||
|
||||
- [ ] **Step 2: Make the script executable**
|
||||
|
||||
Run: `chmod +x scripts/install-playwright.sh`
|
||||
|
||||
---
|
||||
|
||||
### Task 2: Add Playwright to `install-tools.sh`
|
||||
|
||||
**Files:**
|
||||
- Modify: `install-tools.sh:79` (tool detection)
|
||||
- Modify: `install-tools.sh:118` (flag declaration)
|
||||
- Modify: `install-tools.sh:124` (user prompt — after Chromium)
|
||||
- Modify: `install-tools.sh:135-137` (anything_selected check)
|
||||
- Modify: `install-tools.sh:152` (NEEDS_TARBALL condition)
|
||||
- Modify: `install-tools.sh:202-208` (installation phase — after Chromium)
|
||||
|
||||
- [ ] **Step 1: Add Playwright to tool detection**
|
||||
|
||||
After line 79 (`check_tool "Chromium" "chromium-browser"`), detect playwright-core via npm:
|
||||
|
||||
```bash
|
||||
# Playwright detection — check via npm since it's a global npm package
|
||||
if npm list -g playwright-core &>/dev/null 2>&1; then
|
||||
TOOL_STATUS["Playwright"]="installed"
|
||||
echo -e " ${GREEN}[INSTALLED]${NC} Playwright"
|
||||
else
|
||||
TOOL_STATUS["Playwright"]="not_installed"
|
||||
echo -e " ${YELLOW}[NOT INSTALLED]${NC} Playwright"
|
||||
fi
|
||||
```
|
||||
|
||||
- [ ] **Step 2: Add flag declaration**
|
||||
|
||||
After `INSTALL_CHROMIUM=false` (line 118), add:
|
||||
|
||||
```bash
|
||||
INSTALL_PLAYWRIGHT=false
|
||||
```
|
||||
|
||||
- [ ] **Step 3: Add user prompt after Chromium prompt**
|
||||
|
||||
After the Chromium prompt line (line 124), add:
|
||||
|
||||
```bash
|
||||
if [ "${TOOL_STATUS[Playwright]}" = "not_installed" ] && ask_yn " Install Playwright (browser automation library, requires Chromium)?"; then INSTALL_PLAYWRIGHT=true; fi
|
||||
```
|
||||
|
||||
- [ ] **Step 4: Add to anything_selected check**
|
||||
|
||||
Add `INSTALL_PLAYWRIGHT` to the for loop on line 135-137:
|
||||
|
||||
```bash
|
||||
for var in INSTALL_TMUX INSTALL_TTYD INSTALL_DUFS INSTALL_ANDROID_TOOLS \
|
||||
INSTALL_CHROMIUM INSTALL_PLAYWRIGHT INSTALL_CODE_SERVER INSTALL_OPENCODE INSTALL_CLAUDE_CODE \
|
||||
INSTALL_GEMINI_CLI INSTALL_CODEX_CLI; do
|
||||
```
|
||||
|
||||
- [ ] **Step 5: Add NEEDS_TARBALL condition**
|
||||
|
||||
On line 152, add `INSTALL_PLAYWRIGHT` to the condition:
|
||||
|
||||
```bash
|
||||
if [ "$INSTALL_CODE_SERVER" = true ] || [ "$INSTALL_OPENCODE" = true ] || [ "$INSTALL_CHROMIUM" = true ] || [ "$INSTALL_PLAYWRIGHT" = true ]; then
|
||||
```
|
||||
|
||||
- [ ] **Step 6: Add installation block after Chromium**
|
||||
|
||||
After the Chromium installation block (after line 208), add:
|
||||
|
||||
```bash
|
||||
if [ "$INSTALL_PLAYWRIGHT" = true ]; then
|
||||
if bash "$RELEASE_TMP/scripts/install-playwright.sh" install; then
|
||||
echo -e "${GREEN}[OK]${NC} Playwright installed"
|
||||
else
|
||||
echo -e "${YELLOW}[WARN]${NC} Playwright installation failed (non-critical)"
|
||||
fi
|
||||
fi
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Task 3: Verify
|
||||
|
||||
- [ ] **Step 1: Syntax check install-playwright.sh**
|
||||
|
||||
Run: `bash -n scripts/install-playwright.sh`
|
||||
Expected: no output (no syntax errors)
|
||||
|
||||
- [ ] **Step 2: Syntax check install-tools.sh**
|
||||
|
||||
Run: `bash -n install-tools.sh`
|
||||
Expected: no output (no syntax errors)
|
||||
|
||||
- [ ] **Step 3: Verify Playwright detection logic handles missing npm gracefully**
|
||||
|
||||
Run: `grep -n "npm list -g playwright-core" install-tools.sh`
|
||||
Expected: the detection line appears in the tool detection section
|
||||
@@ -0,0 +1,77 @@
|
||||
# Termux SSH 접속 가이드
|
||||
|
||||
폰의 Termux에 컴퓨터에서 SSH로 접속하면, 컴퓨터 키보드로 모든 명령어를 입력할 수 있습니다.
|
||||
|
||||
## 준비물
|
||||
|
||||
- 폰과 컴퓨터가 **같은 Wi-Fi 네트워크**에 연결되어 있어야 합니다
|
||||
|
||||
## 1단계: openssh 설치
|
||||
|
||||
폰에서 Termux 앱을 열고 입력합니다:
|
||||
|
||||
```bash
|
||||
pkg install -y openssh
|
||||
```
|
||||
|
||||
설치가 완료될 때까지 기다리세요 (1~2분).
|
||||
|
||||
## 2단계: 비밀번호 설정
|
||||
|
||||
```bash
|
||||
passwd
|
||||
```
|
||||
|
||||
비밀번호를 입력합니다 (예: `1234`):
|
||||
|
||||
```
|
||||
New password: 1234 ← 입력
|
||||
Retype new password: 1234 ← 같은 비밀번호 다시 입력
|
||||
```
|
||||
|
||||
> 비밀번호 입력 시 화면에 아무것도 표시되지 않는 것이 정상입니다. 그냥 입력하고 Enter를 누르면 됩니다.
|
||||
|
||||
## 3단계: SSH 서버 시작
|
||||
|
||||
> **중요**: `sshd`는 SSH가 아닌, 폰의 Termux 앱에서 직접 실행하세요.
|
||||
|
||||
```bash
|
||||
sshd
|
||||
```
|
||||
|
||||
아무 메시지 없이 프롬프트(`$`)가 다시 나오면 정상입니다.
|
||||
|
||||
<img src="images/termux_tab_2.png" width="300" alt="sshd 실행 화면">
|
||||
|
||||
## 4단계: IP 주소 확인
|
||||
|
||||
```bash
|
||||
ifconfig
|
||||
```
|
||||
|
||||
`wlan0` 항목을 찾으세요:
|
||||
|
||||
```
|
||||
wlan0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
|
||||
inet 192.168.45.139 netmask 255.255.255.0
|
||||
```
|
||||
|
||||
`inet` 뒤의 숫자가 폰의 IP 주소입니다 (위 예시에서는 `192.168.45.139`).
|
||||
|
||||
## 5단계: 컴퓨터에서 SSH 접속
|
||||
|
||||
컴퓨터 터미널(맥: 터미널, 윈도우: PowerShell 또는 명령 프롬프트)을 열고 입력합니다. IP 주소는 4단계에서 확인한 값으로 변경하세요:
|
||||
|
||||
```bash
|
||||
ssh -p 8022 192.168.45.139
|
||||
```
|
||||
|
||||
- `Are you sure you want to continue connecting?` → `yes` 입력
|
||||
- `Password:` → 2단계에서 설정한 비밀번호 입력 (예: `1234`)
|
||||
|
||||
접속 성공하면 Termux의 `$` 프롬프트가 나타납니다. 이제부터 컴퓨터 키보드로 모든 Termux 명령어를 입력할 수 있습니다.
|
||||
|
||||
## 참고 사항
|
||||
|
||||
- Termux의 SSH 포트는 **8022**입니다 (일반 리눅스의 22가 아님)
|
||||
- Termux 앱을 종료하면 SSH 서버도 꺼집니다. 다시 접속하려면 폰에서 Termux를 열고 `sshd`를 실행하세요
|
||||
@@ -0,0 +1,77 @@
|
||||
# Termux SSH Setup Guide
|
||||
|
||||
By connecting to Termux via SSH from your computer, you can type all commands using your computer keyboard.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- Both phone and computer must be on the **same Wi-Fi network**
|
||||
|
||||
## Step 1: Install openssh
|
||||
|
||||
Open the Termux app on your phone and type:
|
||||
|
||||
```bash
|
||||
pkg install -y openssh
|
||||
```
|
||||
|
||||
Wait for the installation to complete (1-2 minutes).
|
||||
|
||||
## Step 2: Set Password
|
||||
|
||||
```bash
|
||||
passwd
|
||||
```
|
||||
|
||||
Enter a password (e.g., `1234`):
|
||||
|
||||
```
|
||||
New password: 1234 ← type
|
||||
Retype new password: 1234 ← type the same password again
|
||||
```
|
||||
|
||||
> It's normal that nothing shows on screen while typing the password. Just type it and press Enter.
|
||||
|
||||
## Step 3: Start SSH Server
|
||||
|
||||
> **Important**: Run `sshd` directly in the Termux app on your phone, not via SSH.
|
||||
|
||||
```bash
|
||||
sshd
|
||||
```
|
||||
|
||||
If the prompt (`$`) returns with no error message, it's working.
|
||||
|
||||
<img src="images/termux_tab_2.png" width="300" alt="sshd running in Termux">
|
||||
|
||||
## Step 4: Find the Phone's IP Address
|
||||
|
||||
```bash
|
||||
ifconfig
|
||||
```
|
||||
|
||||
Look for the `wlan0` section:
|
||||
|
||||
```
|
||||
wlan0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
|
||||
inet 192.168.45.139 netmask 255.255.255.0
|
||||
```
|
||||
|
||||
The number after `inet` is your phone's IP address (in this example, `192.168.45.139`).
|
||||
|
||||
## Step 5: Connect via SSH from Computer
|
||||
|
||||
Open a terminal on your computer (Mac: Terminal, Windows: PowerShell or Command Prompt) and type. Replace the IP address with the one you found in Step 4:
|
||||
|
||||
```bash
|
||||
ssh -p 8022 192.168.45.139
|
||||
```
|
||||
|
||||
- `Are you sure you want to continue connecting?` → type `yes`
|
||||
- `Password:` → enter the password you set in Step 2 (e.g., `1234`)
|
||||
|
||||
Once connected, you'll see the Termux `$` prompt. From now on, you can type all Termux commands using your computer keyboard.
|
||||
|
||||
## Notes
|
||||
|
||||
- Termux uses SSH port **8022** (not the standard Linux port 22)
|
||||
- If you close the Termux app, the SSH server stops. To reconnect, open Termux on the phone and run `sshd`
|
||||
@@ -0,0 +1,304 @@
|
||||
# 트러블슈팅
|
||||
|
||||
Termux에서 OpenClaw 사용 중 발생할 수 있는 문제와 해결 방법을 정리합니다.
|
||||
|
||||
## 게이트웨이가 시작되지 않음: "gateway already running" 또는 "Port is already in use"
|
||||
|
||||
```
|
||||
Gateway failed to start: gateway already running (pid XXXXX); lock timeout after 5000ms
|
||||
Port 18789 is already in use.
|
||||
```
|
||||
|
||||
### 원인
|
||||
|
||||
이전 게이트웨이 프로세스가 비정상 종료되면서 잠금 파일이 남아있거나, 프로세스가 좀비 상태로 남아있는 경우 발생합니다. 주로 다음 상황에서 일어납니다:
|
||||
|
||||
- SSH 연결이 끊어지면서 게이트웨이 프로세스가 고아(orphan) 상태로 남음
|
||||
- `Ctrl+Z`(일시정지)로 중단한 경우 프로세스가 종료되지 않고 백그라운드에 남음
|
||||
- Termux가 Android에 의해 강제 종료된 경우
|
||||
|
||||
> **참고**: 게이트웨이를 종료할 때는 반드시 `Ctrl+C`를 사용하세요. `Ctrl+Z`는 프로세스를 일시정지시킬 뿐 종료하지 않습니다.
|
||||
|
||||
### 해결 방법
|
||||
|
||||
#### 1단계: 남아있는 프로세스 확인 및 종료
|
||||
|
||||
```bash
|
||||
ps aux | grep -E "node|openclaw" | grep -v grep
|
||||
```
|
||||
|
||||
프로세스가 보이면 PID를 확인하고 종료:
|
||||
|
||||
```bash
|
||||
kill -9 <PID>
|
||||
```
|
||||
|
||||
#### 2단계: 잠금 파일 삭제
|
||||
|
||||
```bash
|
||||
rm -rf $PREFIX/tmp/openclaw-*
|
||||
```
|
||||
|
||||
#### 3단계: 게이트웨이 재시작
|
||||
|
||||
```bash
|
||||
openclaw gateway
|
||||
```
|
||||
|
||||
### 그래도 안 되면
|
||||
|
||||
위 과정으로도 해결되지 않으면 Termux 앱을 완전히 종료했다가 다시 열고 `openclaw gateway`를 실행하세요. 폰을 재시작하면 확실하게 모든 상태가 초기화됩니다.
|
||||
|
||||
## 게이트웨이 연결 끊김: "gateway not connected"
|
||||
|
||||
```
|
||||
send failed: Error: gateway not connected
|
||||
disconnected | error
|
||||
```
|
||||
|
||||
### 원인
|
||||
|
||||
게이트웨이 프로세스가 종료되었거나 SSH 세션이 끊어진 경우 발생합니다.
|
||||
|
||||
### 해결 방법
|
||||
|
||||
게이트웨이를 실행했던 SSH 세션을 확인하세요. 세션이 끊어졌다면 다시 SSH 접속 후 게이트웨이를 시작합니다:
|
||||
|
||||
```bash
|
||||
openclaw gateway
|
||||
```
|
||||
|
||||
"gateway already running" 에러가 나오면 위의 [게이트웨이가 시작되지 않음](#게이트웨이가-시작되지-않음-gateway-already-running-또는-port-is-already-in-use) 섹션을 참고하세요.
|
||||
|
||||
## SSH 접속 실패: "Connection refused"
|
||||
|
||||
```
|
||||
ssh: connect to host 192.168.45.139 port 8022: Connection refused
|
||||
```
|
||||
|
||||
### 원인
|
||||
|
||||
Termux의 SSH 서버(`sshd`)가 실행되지 않은 상태입니다. Termux 앱을 종료하거나 폰을 재시작하면 sshd가 꺼집니다.
|
||||
|
||||
### 해결 방법
|
||||
|
||||
폰에서 Termux 앱을 열고 `sshd`를 실행하세요. 폰에서 직접 타이핑하거나 adb로 전송:
|
||||
|
||||
```bash
|
||||
adb shell input text 'sshd'
|
||||
```
|
||||
```bash
|
||||
adb shell input keyevent 66
|
||||
```
|
||||
|
||||
IP가 변경되었을 수 있으니 확인:
|
||||
|
||||
```bash
|
||||
adb shell input text 'ifconfig'
|
||||
```
|
||||
```bash
|
||||
adb shell input keyevent 66
|
||||
```
|
||||
|
||||
> 매번 수동으로 `sshd`를 실행하기 번거로우면 `~/.bashrc` 맨 아래에 `sshd 2>/dev/null`을 추가하면 Termux 시작 시 자동으로 SSH 서버가 켜집니다.
|
||||
|
||||
## `openclaw --version` 실패
|
||||
|
||||
### 원인
|
||||
|
||||
환경변수가 로드되지 않은 상태입니다.
|
||||
|
||||
### 해결 방법
|
||||
|
||||
```bash
|
||||
source ~/.bashrc
|
||||
```
|
||||
|
||||
또는 Termux 앱을 완전히 종료했다가 다시 여세요.
|
||||
|
||||
## "Cannot find module glibc-compat.js" 에러
|
||||
|
||||
```
|
||||
Error: Cannot find module '/data/data/com.termux/files/home/.openclaw-lite/patches/glibc-compat.js'
|
||||
```
|
||||
|
||||
> **참고**: 이 문제는 v1.0.0 이전(Bionic) 설치에서만 발생합니다. v1.0.0+(glibc)에서는 `glibc-compat.js`가 node 래퍼 스크립트에 의해 로딩되므로 `NODE_OPTIONS`를 사용하지 않습니다.
|
||||
|
||||
### 원인
|
||||
|
||||
`~/.bashrc`의 `NODE_OPTIONS` 환경변수가 이전 설치 경로(`.openclaw-lite`)를 참조하고 있습니다. 프로젝트명이 "OpenClaw Lite"였던 이전 버전에서 업데이트한 경우 발생합니다.
|
||||
|
||||
### 해결 방법
|
||||
|
||||
업데이터를 실행하면 환경변수 블록이 갱신됩니다:
|
||||
|
||||
```bash
|
||||
oa --update && source ~/.bashrc
|
||||
```
|
||||
|
||||
또는 수동으로 수정:
|
||||
|
||||
```bash
|
||||
sed -i 's/\.openclaw-lite/\.openclaw-android/g' ~/.bashrc && source ~/.bashrc
|
||||
```
|
||||
|
||||
## 업데이트 중 "systemctl --user unavailable: spawn systemctl ENOENT" 에러
|
||||
|
||||
```
|
||||
Gateway service check failed: Error: systemctl --user unavailable: spawn systemctl ENOENT
|
||||
```
|
||||
|
||||
### 원인
|
||||
|
||||
`openclaw update` 실행 후, OpenClaw이 `systemctl`로 게이트웨이 서비스를 재시작하려고 합니다. Termux에는 systemd가 없으므로 `systemctl` 바이너리를 찾을 수 없어 `ENOENT` 에러가 발생합니다.
|
||||
|
||||
### 영향
|
||||
|
||||
**이 에러는 무해합니다.** 업데이트 자체는 이미 성공적으로 완료되었으며, 자동 서비스 재시작만 실패한 것입니다. OpenClaw은 최신 상태로 업데이트되어 있습니다.
|
||||
|
||||
### 해결 방법
|
||||
|
||||
수동으로 게이트웨이를 시작하면 됩니다:
|
||||
|
||||
```bash
|
||||
openclaw gateway
|
||||
```
|
||||
|
||||
업데이트 전에 게이트웨이가 실행 중이었다면 기존 프로세스를 먼저 종료해야 할 수 있습니다. 위의 [게이트웨이가 시작되지 않음](#게이트웨이가-시작되지-않음-gateway-already-running-또는-port-is-already-in-use) 섹션을 참고하세요.
|
||||
|
||||
## `openclaw update` 중 sharp 빌드 실패
|
||||
|
||||
```
|
||||
npm error gyp ERR! not ok
|
||||
Update Result: ERROR
|
||||
Reason: global update
|
||||
```
|
||||
|
||||
### 원인
|
||||
|
||||
**v1.0.0+(glibc)**: `sharp` 모듈은 프리빌트 바이너리(`@img/sharp-linux-arm64`)를 사용하며 glibc 환경에서 네이티브로 로딩됩니다. 이 에러는 드문 — 주로 프리빌트 바이너리가 누락되거나 손상된 경우입니다.
|
||||
|
||||
**v1.0.0 이전(Bionic)**: `openclaw update`가 npm을 서브프로세스로 실행할 때, Termux 전용 빌드 환경변수(`CXXFLAGS`, `GYP_DEFINES`)가 서브프로세스 환경에서 사용 불가하여 네이티브 모듈 컴파일이 실패합니다.
|
||||
|
||||
### 영향
|
||||
|
||||
**이 에러는 무해합니다.** OpenClaw 자체는 정상적으로 업데이트되었으며, `sharp` 모듈(이미지 처리용)만 리빌드에 실패한 것입니다. OpenClaw는 sharp 없이도 정상적으로 작동합니다.
|
||||
|
||||
### 해결 방법
|
||||
|
||||
업데이트 후 아래 스크립트로 sharp를 수동 빌드하세요:
|
||||
|
||||
```bash
|
||||
bash ~/.openclaw-android/scripts/build-sharp.sh
|
||||
```
|
||||
|
||||
또는 `openclaw update` 대신 `oa --update`를 사용하면 sharp를 자동으로 처리합니다:
|
||||
|
||||
```bash
|
||||
oa --update && source ~/.bashrc
|
||||
```
|
||||
|
||||
## `clawdhub` 실행 시 "Cannot find package 'undici'" 에러
|
||||
|
||||
```
|
||||
Error [ERR_MODULE_NOT_FOUND]: Cannot find package 'undici' imported from /data/data/com.termux/files/usr/lib/node_modules/clawdhub/dist/http.js
|
||||
```
|
||||
|
||||
### 원인
|
||||
|
||||
Node.js v24+ Termux 환경에서는 `undici` 패키지가 Node.js에 번들되지 않습니다. `clawdhub`가 HTTP 요청에 `undici`를 사용하지만 찾을 수 없어 실패합니다.
|
||||
|
||||
### 해결 방법
|
||||
|
||||
업데이터를 실행하면 `clawdhub`와 `undici` 의존성이 자동으로 설치됩니다:
|
||||
|
||||
```bash
|
||||
oa --update && source ~/.bashrc
|
||||
```
|
||||
|
||||
또는 수동으로 수정:
|
||||
|
||||
```bash
|
||||
cd $(npm root -g)/clawdhub && npm install undici
|
||||
```
|
||||
|
||||
## "not supported on android" 에러
|
||||
|
||||
```
|
||||
Gateway status failed: Error: Gateway service install not supported on android
|
||||
```
|
||||
|
||||
> **참고**: 이 문제는 v1.0.0 이전(Bionic) 설치에서만 발생합니다. v1.0.0+(glibc)에서는 Node.js가 `process.platform`을 `'linux'`으로 보고하므로 이 에러가 발생하지 않습니다.
|
||||
|
||||
### 원인
|
||||
|
||||
**v1.0.0 이전(Bionic)**: `glibc-compat.js`의 `process.platform` 오버라이드가 적용되지 않은 상태입니다. `NODE_OPTIONS`가 설정되지 않았기 때문입니다.
|
||||
|
||||
### 해결 방법
|
||||
|
||||
어떤 Node.js가 사용되고 있는지 확인:
|
||||
|
||||
```bash
|
||||
node -e "console.log(process.platform)"
|
||||
```
|
||||
|
||||
`android`가 출력되면 glibc node 래퍼가 사용되지 않고 있는 것입니다. 환경변수를 로드하세요:
|
||||
|
||||
```bash
|
||||
source ~/.bashrc
|
||||
```
|
||||
|
||||
여전히 `android`가 출력되면, 최신 버전으로 업데이트하세요 (v1.0.0+는 glibc를 사용하여 이 문제를 영구적으로 해결합니다):
|
||||
|
||||
```bash
|
||||
oa --update && source ~/.bashrc
|
||||
```
|
||||
|
||||
## `openclaw update` 시 node-llama-cpp 빌드 에러
|
||||
|
||||
```
|
||||
[node-llama-cpp] Cloning ggml-org/llama.cpp (local bundle)
|
||||
npm error 48%
|
||||
Update Result: ERROR
|
||||
```
|
||||
|
||||
### 원인
|
||||
|
||||
OpenClaw이 npm으로 업데이트할 때, `node-llama-cpp`의 postinstall 스크립트가 `llama.cpp` 소스를 clone하고 컴파일을 시도합니다. Termux의 빌드 툴체인(`cmake`, `clang`)이 Bionic으로 링크되어 있고 Node.js는 glibc로 실행되므로 — 두 환경이 네이티브 컴파일에 호환되지 않아 실패합니다.
|
||||
|
||||
### 영향
|
||||
|
||||
**이 에러는 무해합니다.** 프리빌트 `node-llama-cpp` 바이너리(`@node-llama-cpp/linux-arm64`)가 이미 설치되어 있으며 glibc 환경에서 정상 작동합니다. 실패한 소스 빌드가 프리빌트 바이너리를 덮어쓰지 않습니다.
|
||||
|
||||
node-llama-cpp는 선택적 로컬 임베딩에 사용됩니다. 프리빌트 바이너리가 로딩되지 않으면 OpenClaw이 원격 임베딩 프로바이더(OpenAI, Gemini 등)로 자동 fallback합니다.
|
||||
|
||||
### 해결 방법
|
||||
|
||||
조치가 필요 없습니다. 이 에러는 안전하게 무시할 수 있습니다. 프리빌트 바이너리가 정상 작동하는지 확인하려면:
|
||||
|
||||
```bash
|
||||
node -e "require('$(npm root -g)/openclaw/node_modules/@node-llama-cpp/linux-arm64/bins/linux-arm64/llama-addon.node'); console.log('OK')"
|
||||
```
|
||||
|
||||
## OpenCode 설치 시 EACCES 권한 에러
|
||||
|
||||
```
|
||||
EACCES: Permission denied while installing opencode-ai
|
||||
Failed to install 118 packages
|
||||
```
|
||||
|
||||
### 원인
|
||||
|
||||
Bun이 패키지 설치 시 하드링크와 심링크를 생성하려고 시도합니다. Android 파일시스템이 이러한 작업을 제한하여 의존성 패키지에서 `EACCES` 에러가 발생합니다.
|
||||
|
||||
### 영향
|
||||
|
||||
**이 에러는 무해합니다.** 메인 바이너리(`opencode`)는 의존성 링크 실패에도 불구하고 정상적으로 설치됩니다. ld.so 결합과 proot 래퍼가 실행을 처리합니다.
|
||||
|
||||
### 해결 방법
|
||||
|
||||
조치가 필요 없습니다. OpenCode가 정상 작동하는지 확인:
|
||||
|
||||
```bash
|
||||
opencode --version
|
||||
```
|
||||
@@ -0,0 +1,304 @@
|
||||
# Troubleshooting
|
||||
|
||||
Common issues and solutions when using OpenClaw on Termux.
|
||||
|
||||
## Gateway won't start: "gateway already running" or "Port is already in use"
|
||||
|
||||
```
|
||||
Gateway failed to start: gateway already running (pid XXXXX); lock timeout after 5000ms
|
||||
Port 18789 is already in use.
|
||||
```
|
||||
|
||||
### Cause
|
||||
|
||||
A previous gateway process was terminated abnormally, leaving behind a lock file or a zombie process. This typically happens when:
|
||||
|
||||
- SSH connection drops, leaving the gateway process orphaned
|
||||
- `Ctrl+Z` (suspend) was used instead of `Ctrl+C` (terminate), leaving the process alive in the background
|
||||
- Termux was force-killed by Android
|
||||
|
||||
> **Note**: Always use `Ctrl+C` to stop the gateway. `Ctrl+Z` only suspends the process — it does not terminate it.
|
||||
|
||||
### Solution
|
||||
|
||||
#### Step 1: Find and kill remaining processes
|
||||
|
||||
```bash
|
||||
ps aux | grep -E "node|openclaw" | grep -v grep
|
||||
```
|
||||
|
||||
If processes are listed, note the PID and kill them:
|
||||
|
||||
```bash
|
||||
kill -9 <PID>
|
||||
```
|
||||
|
||||
#### Step 2: Remove lock files
|
||||
|
||||
```bash
|
||||
rm -rf $PREFIX/tmp/openclaw-*
|
||||
```
|
||||
|
||||
#### Step 3: Restart the gateway
|
||||
|
||||
```bash
|
||||
openclaw gateway
|
||||
```
|
||||
|
||||
### If it still doesn't work
|
||||
|
||||
If the above steps don't help, fully close and reopen the Termux app, then run `openclaw gateway`. Rebooting the phone will reliably clear all state.
|
||||
|
||||
## Gateway disconnected: "gateway not connected"
|
||||
|
||||
```
|
||||
send failed: Error: gateway not connected
|
||||
disconnected | error
|
||||
```
|
||||
|
||||
### Cause
|
||||
|
||||
The gateway process has stopped or the SSH session was disconnected.
|
||||
|
||||
### Solution
|
||||
|
||||
Check the SSH session where the gateway was running. If the session was disconnected, reconnect via SSH and start the gateway:
|
||||
|
||||
```bash
|
||||
openclaw gateway
|
||||
```
|
||||
|
||||
If you get a "gateway already running" error, see the [Gateway won't start](#gateway-wont-start-gateway-already-running-or-port-is-already-in-use) section above.
|
||||
|
||||
## SSH connection failed: "Connection refused"
|
||||
|
||||
```
|
||||
ssh: connect to host 192.168.45.139 port 8022: Connection refused
|
||||
```
|
||||
|
||||
### Cause
|
||||
|
||||
The Termux SSH server (`sshd`) is not running. Closing the Termux app or rebooting the phone stops sshd.
|
||||
|
||||
### Solution
|
||||
|
||||
Open the Termux app on the phone and run `sshd`. Either type directly on the phone or send via adb:
|
||||
|
||||
```bash
|
||||
adb shell input text 'sshd'
|
||||
```
|
||||
```bash
|
||||
adb shell input keyevent 66
|
||||
```
|
||||
|
||||
The IP address may have changed, so verify:
|
||||
|
||||
```bash
|
||||
adb shell input text 'ifconfig'
|
||||
```
|
||||
```bash
|
||||
adb shell input keyevent 66
|
||||
```
|
||||
|
||||
> To start sshd automatically, add `sshd 2>/dev/null` to the end of your `~/.bashrc` file so the SSH server starts whenever Termux opens.
|
||||
|
||||
## `openclaw --version` fails
|
||||
|
||||
### Cause
|
||||
|
||||
Environment variables are not loaded.
|
||||
|
||||
### Solution
|
||||
|
||||
```bash
|
||||
source ~/.bashrc
|
||||
```
|
||||
|
||||
Or fully close and reopen the Termux app.
|
||||
|
||||
## "Cannot find module glibc-compat.js" error
|
||||
|
||||
```
|
||||
Error: Cannot find module '/data/data/com.termux/files/home/.openclaw-lite/patches/glibc-compat.js'
|
||||
```
|
||||
|
||||
> **Note**: This issue only affects pre-1.0.0 (Bionic) installations. In v1.0.0+ (glibc), `glibc-compat.js` is loaded by the node wrapper script, not `NODE_OPTIONS`.
|
||||
|
||||
### Cause
|
||||
|
||||
The `NODE_OPTIONS` environment variable in `~/.bashrc` still references the old installation path (`.openclaw-lite`). This happens when updating from an older version where the project was named "OpenClaw Lite".
|
||||
|
||||
### Solution
|
||||
|
||||
Run the updater to refresh the environment variable block:
|
||||
|
||||
```bash
|
||||
oa --update && source ~/.bashrc
|
||||
```
|
||||
|
||||
Or manually fix it:
|
||||
|
||||
```bash
|
||||
sed -i 's/\.openclaw-lite/\.openclaw-android/g' ~/.bashrc && source ~/.bashrc
|
||||
```
|
||||
|
||||
## "systemctl --user unavailable: spawn systemctl ENOENT" during update
|
||||
|
||||
```
|
||||
Gateway service check failed: Error: systemctl --user unavailable: spawn systemctl ENOENT
|
||||
```
|
||||
|
||||
### Cause
|
||||
|
||||
After running `openclaw update`, OpenClaw tries to restart the gateway service using `systemctl`. Since Termux doesn't have systemd, the `systemctl` binary doesn't exist and the command fails with `ENOENT`.
|
||||
|
||||
### Impact
|
||||
|
||||
**This error is harmless.** The update itself has already completed successfully — only the automatic service restart failed. Your OpenClaw installation is up to date.
|
||||
|
||||
### Solution
|
||||
|
||||
Simply start the gateway manually:
|
||||
|
||||
```bash
|
||||
openclaw gateway
|
||||
```
|
||||
|
||||
If the gateway was already running before the update, you may need to stop the old process first. See the [Gateway won't start](#gateway-wont-start-gateway-already-running-or-port-is-already-in-use) section above.
|
||||
|
||||
## sharp build fails during `openclaw update`
|
||||
|
||||
```
|
||||
npm error gyp ERR! not ok
|
||||
Update Result: ERROR
|
||||
Reason: global update
|
||||
```
|
||||
|
||||
### Cause
|
||||
|
||||
**v1.0.0+ (glibc)**: The `sharp` module uses prebuilt binaries (`@img/sharp-linux-arm64`) that load natively under the glibc environment. This error is rare — it typically means the prebuilt binary is missing or corrupted.
|
||||
|
||||
**Pre-1.0.0 (Bionic)**: When `openclaw update` ran npm as a subprocess, the Termux-specific build environment variables (`CXXFLAGS`, `GYP_DEFINES`) were not available in the subprocess context, causing the native module compilation to fail.
|
||||
|
||||
### Impact
|
||||
|
||||
**This error is non-critical.** OpenClaw itself has been updated successfully — only the `sharp` module (used for image processing) failed to rebuild. OpenClaw works normally without it.
|
||||
|
||||
### Solution
|
||||
|
||||
After the update, manually rebuild `sharp` using the provided script:
|
||||
|
||||
```bash
|
||||
bash ~/.openclaw-android/scripts/build-sharp.sh
|
||||
```
|
||||
|
||||
Alternatively, use `oa --update` instead of `openclaw update` — it handles sharp automatically:
|
||||
|
||||
```bash
|
||||
oa --update && source ~/.bashrc
|
||||
```
|
||||
|
||||
## `clawdhub` fails with "Cannot find package 'undici'"
|
||||
|
||||
```
|
||||
Error [ERR_MODULE_NOT_FOUND]: Cannot find package 'undici' imported from /data/data/com.termux/files/usr/lib/node_modules/clawdhub/dist/http.js
|
||||
```
|
||||
|
||||
### Cause
|
||||
|
||||
Node.js v24+ on Termux doesn't bundle the `undici` package, which `clawdhub` depends on for HTTP requests.
|
||||
|
||||
### Solution
|
||||
|
||||
Run the updater to automatically install `clawdhub` and its `undici` dependency:
|
||||
|
||||
```bash
|
||||
oa --update && source ~/.bashrc
|
||||
```
|
||||
|
||||
Or fix it manually:
|
||||
|
||||
```bash
|
||||
cd $(npm root -g)/clawdhub && npm install undici
|
||||
```
|
||||
|
||||
## "not supported on android" error
|
||||
|
||||
```
|
||||
Gateway status failed: Error: Gateway service install not supported on android
|
||||
```
|
||||
|
||||
> **Note**: This issue only affects pre-1.0.0 (Bionic) installations. In v1.0.0+ (glibc), Node.js natively reports `process.platform` as `'linux'`, so this error does not occur.
|
||||
|
||||
### Cause
|
||||
|
||||
**Pre-1.0.0 (Bionic)**: The `process.platform` override in `glibc-compat.js` is not being applied because `NODE_OPTIONS` is not set.
|
||||
|
||||
### Solution
|
||||
|
||||
Check which Node.js is being used:
|
||||
|
||||
```bash
|
||||
node -e "console.log(process.platform)"
|
||||
```
|
||||
|
||||
If it prints `android`, the glibc node wrapper is not being used. Load the environment:
|
||||
|
||||
```bash
|
||||
source ~/.bashrc
|
||||
```
|
||||
|
||||
If it still prints `android`, update to the latest version (v1.0.0+ uses glibc and resolves this permanently):
|
||||
|
||||
```bash
|
||||
oa --update && source ~/.bashrc
|
||||
```
|
||||
|
||||
## `openclaw update` fails with node-llama-cpp build error
|
||||
|
||||
```
|
||||
[node-llama-cpp] Cloning ggml-org/llama.cpp (local bundle)
|
||||
npm error 48%
|
||||
Update Result: ERROR
|
||||
```
|
||||
|
||||
### Cause
|
||||
|
||||
When OpenClaw updates via npm, `node-llama-cpp`'s postinstall script attempts to clone and compile `llama.cpp` from source. This fails on Termux because the build toolchain (`cmake`, `clang`) is linked against Bionic, while Node.js runs under glibc — the two are incompatible for native compilation.
|
||||
|
||||
### Impact
|
||||
|
||||
**This error is harmless.** The prebuilt `node-llama-cpp` binaries (`@node-llama-cpp/linux-arm64`) are already installed and work correctly under the glibc environment. The failed source build does not overwrite them.
|
||||
|
||||
Node-llama-cpp is used for optional local embeddings. If the prebuilt binaries don't load, OpenClaw automatically falls back to remote embedding providers (OpenAI, Gemini, etc.).
|
||||
|
||||
### Solution
|
||||
|
||||
No action needed. The error can be safely ignored. To verify that the prebuilt binaries are working:
|
||||
|
||||
```bash
|
||||
node -e "require('$(npm root -g)/openclaw/node_modules/@node-llama-cpp/linux-arm64/bins/linux-arm64/llama-addon.node'); console.log('OK')"
|
||||
```
|
||||
|
||||
## OpenCode install shows EACCES permission errors
|
||||
|
||||
```
|
||||
EACCES: Permission denied while installing opencode-ai
|
||||
Failed to install 118 packages
|
||||
```
|
||||
|
||||
### Cause
|
||||
|
||||
Bun attempts to create hardlinks and symlinks when installing packages. Android's filesystem restricts these operations, causing `EACCES` errors for dependency packages.
|
||||
|
||||
### Impact
|
||||
|
||||
**These errors are harmless.** The main binary (`opencode`) is installed correctly despite the dependency link failures. The ld.so concatenation and proot wrapper handle execution.
|
||||
|
||||
### Solution
|
||||
|
||||
No action needed. Verify that OpenCode works:
|
||||
|
||||
```bash
|
||||
opencode --version
|
||||
```
|
||||