Skip to content

Commit c4fa722

Browse files
committed
feat: add Chromium support, build-sharp, pre-commit hook, markdownlint config
- scripts/install-chromium.sh: headless Chromium browser automation for OCA - scripts/build-sharp.sh: WASM-first sharp image processing for ARM64 - .githooks/pre-commit: ShellCheck lint on staged .sh files - .markdownlint-cli2.yaml: markdown lint config for docs
1 parent fe40729 commit c4fa722

File tree

4 files changed

+292
-0
lines changed

4 files changed

+292
-0
lines changed

.githooks/pre-commit

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
#!/usr/bin/env bash
2+
# Pre-commit hook — basic quality checks before every commit
3+
4+
set -e
5+
6+
RED='\033[0;31m'
7+
GREEN='\033[0;32m'
8+
YELLOW='\033[1;33m'
9+
NC='\033[0m'
10+
11+
echo "Running pre-commit checks..."
12+
13+
# 1. ShellCheck on staged .sh files
14+
STAGED_SH=$(git diff --cached --name-only --diff-filter=ACM | grep '\.sh$' || true)
15+
16+
if [ -n "$STAGED_SH" ] && command -v shellcheck &>/dev/null; then
17+
echo "$STAGED_SH" | while IFS= read -r file; do
18+
if shellcheck --severity=warning "$file"; then
19+
echo -e "${GREEN}[OK]${NC} shellcheck: $file"
20+
else
21+
echo -e "${RED}[FAIL]${NC} shellcheck failed: $file"
22+
exit 1
23+
fi
24+
done
25+
fi
26+
27+
# 2. No trailing whitespace in staged shell scripts
28+
if [ -n "$STAGED_SH" ]; then
29+
while IFS= read -r file; do
30+
if grep -qP '\s+$' "$file" 2>/dev/null; then
31+
echo -e "${YELLOW}[WARN]${NC} Trailing whitespace in: $file"
32+
fi
33+
done <<< "$STAGED_SH"
34+
fi
35+
36+
echo -e "${GREEN}[OK]${NC} Pre-commit checks passed"

.markdownlint-cli2.yaml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"default": true,
3+
"MD013": false,
4+
"MD033": false,
5+
"MD041": false,
6+
"MD024": { "allow_different_nesting": true }
7+
}

scripts/build-sharp.sh

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
#!/usr/bin/env bash
2+
# build-sharp.sh - Enable sharp image processing on Android (Termux)
3+
#
4+
# Strategy:
5+
# 1. Check if sharp already works → skip
6+
# 2. Install WebAssembly fallback (@img/sharp-wasm32)
7+
# Native sharp binaries are built for glibc Linux. Android's Bionic libc
8+
# cannot dlopen glibc-linked .node addons, so the prebuilt linux-arm64
9+
# binding never loads. The WASM build uses Emscripten and runs entirely
10+
# in V8 — zero native dependencies.
11+
# 3. If WASM fails → attempt native rebuild as last resort
12+
set -euo pipefail
13+
14+
GREEN='\033[0;32m'
15+
YELLOW='\033[1;33m'
16+
RED='\033[0;31m'
17+
NC='\033[0m'
18+
19+
echo "=== Building sharp (image processing) ==="
20+
echo ""
21+
22+
# Ensure required environment variables are set (for standalone use)
23+
export TMPDIR="${TMPDIR:-$PREFIX/tmp}"
24+
export TMP="$TMPDIR"
25+
export TEMP="$TMPDIR"
26+
export CONTAINER="${CONTAINER:-1}"
27+
28+
# Locate openclaw install directory
29+
OPENCLAW_DIR="$(npm root -g)/openclaw"
30+
31+
if [ ! -d "$OPENCLAW_DIR" ]; then
32+
echo -e "${RED}[FAIL]${NC} OpenClaw directory not found: $OPENCLAW_DIR"
33+
exit 0
34+
fi
35+
36+
# Skip rebuild if sharp is already working
37+
if [ -d "$OPENCLAW_DIR/node_modules/sharp" ]; then
38+
if node -e "require('$OPENCLAW_DIR/node_modules/sharp')" 2>/dev/null; then
39+
echo -e "${GREEN}[OK]${NC} sharp is already working — skipping rebuild"
40+
exit 0
41+
fi
42+
fi
43+
44+
# ── Strategy 1: WebAssembly fallback (recommended for Android) ──────────
45+
46+
echo "Installing sharp WebAssembly runtime..."
47+
if (cd "$OPENCLAW_DIR" && npm install @img/sharp-wasm32 --force --no-audit --no-fund 2>&1 | tail -3); then
48+
if node -e "require('$OPENCLAW_DIR/node_modules/sharp')" 2>/dev/null; then
49+
echo ""
50+
echo -e "${GREEN}[OK]${NC} sharp enabled via WebAssembly — image processing ready"
51+
exit 0
52+
else
53+
echo -e "${YELLOW}[WARN]${NC} WASM package installed but sharp still not loading"
54+
fi
55+
else
56+
echo -e "${YELLOW}[WARN]${NC} Failed to install WASM package"
57+
fi
58+
59+
# ── Strategy 2: Native rebuild (last resort) ────────────────────────────
60+
61+
echo ""
62+
echo "Attempting native rebuild as fallback..."
63+
64+
echo "Installing build dependencies..."
65+
if ! pkg install -y libvips binutils; then
66+
echo -e "${YELLOW}[WARN]${NC} Failed to install build dependencies"
67+
echo " Image processing will not be available, but OCA will work normally."
68+
exit 0
69+
fi
70+
echo -e "${GREEN}[OK]${NC} libvips and binutils installed"
71+
72+
# Create ar symlink if missing (Termux provides llvm-ar but not ar)
73+
if [ ! -e "$PREFIX/bin/ar" ] && [ -x "$PREFIX/bin/llvm-ar" ]; then
74+
ln -s "$PREFIX/bin/llvm-ar" "$PREFIX/bin/ar"
75+
echo -e "${GREEN}[OK]${NC} Created ar → llvm-ar symlink"
76+
fi
77+
78+
echo "Installing node-gyp..."
79+
if ! npm install -g node-gyp; then
80+
echo -e "${YELLOW}[WARN]${NC} Failed to install node-gyp"
81+
echo " Image processing will not be available, but OCA will work normally."
82+
exit 0
83+
fi
84+
echo -e "${GREEN}[OK]${NC} node-gyp installed"
85+
86+
# Set build environment for Termux
87+
if [ ! -f "$HOME/.oca/.glibc-arch" ]; then
88+
export CFLAGS="-Wno-error=implicit-function-declaration"
89+
export CXXFLAGS="-include $HOME/.oca/patches/termux-compat.h"
90+
export GYP_DEFINES="OS=linux android_ndk_path=$PREFIX"
91+
fi
92+
export CPATH="$PREFIX/include/glib-2.0:$PREFIX/lib/glib-2.0/include"
93+
94+
echo "Rebuilding sharp in $OPENCLAW_DIR..."
95+
echo "This may take several minutes..."
96+
echo ""
97+
98+
if (cd "$OPENCLAW_DIR" && npm rebuild sharp); then
99+
echo ""
100+
echo -e "${GREEN}[OK]${NC} sharp built successfully — image processing enabled"
101+
else
102+
echo ""
103+
echo -e "${YELLOW}[WARN]${NC} sharp could not be enabled (non-critical)"
104+
echo " Image processing will not be available, but OCA will work normally."
105+
echo " You can retry later: bash ~/.oca/scripts/build-sharp.sh"
106+
fi

scripts/install-chromium.sh

Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
1+
#!/usr/bin/env bash
2+
# install-chromium.sh - Install Chromium for OCA browser automation
3+
# Usage: bash install-chromium.sh [install|update]
4+
#
5+
# What it does:
6+
# 1. Install x11-repo (Termux X11 packages repository)
7+
# 2. Install chromium package
8+
# 3. Configure OpenClaw browser settings in openclaw.json
9+
# 4. Verify installation
10+
#
11+
# Browser automation allows OpenClaw to control a headless Chromium browser
12+
# for web scraping, screenshots, and automated browsing tasks.
13+
#
14+
# This script is WARN-level: failure does not abort the parent installer.
15+
set -euo pipefail
16+
17+
GREEN='\033[0;32m'
18+
YELLOW='\033[1;33m'
19+
NC='\033[0m'
20+
21+
MODE="${1:-install}"
22+
23+
# ── Helper ────────────────────────────────────
24+
25+
fail_warn() {
26+
echo -e "${YELLOW}[WARN]${NC} $1"
27+
exit 0
28+
}
29+
30+
# ── Detect Chromium binary path ───────────────
31+
32+
detect_chromium_bin() {
33+
for bin in "$PREFIX/bin/chromium-browser" "$PREFIX/bin/chromium"; do
34+
if [ -x "$bin" ]; then
35+
echo "$bin"
36+
return 0
37+
fi
38+
done
39+
return 1
40+
}
41+
42+
# ── Pre-checks ────────────────────────────────
43+
44+
if [ -z "${PREFIX:-}" ]; then
45+
fail_warn "Not running in Termux (\$PREFIX not set)"
46+
fi
47+
48+
# ── Check current installation ────────────────
49+
50+
SKIP_PKG_INSTALL=false
51+
if CHROMIUM_BIN=$(detect_chromium_bin); then
52+
if [ "$MODE" = "install" ]; then
53+
echo -e "${GREEN}[SKIP]${NC} Chromium already installed ($CHROMIUM_BIN)"
54+
SKIP_PKG_INSTALL=true
55+
fi
56+
fi
57+
58+
# ── Step 1: Install x11-repo + Chromium ───────
59+
60+
if [ "$SKIP_PKG_INSTALL" = false ]; then
61+
echo "Installing x11-repo (Termux X11 packages)..."
62+
if ! pkg install -y x11-repo; then
63+
fail_warn "Failed to install x11-repo"
64+
fi
65+
echo -e "${GREEN}[OK]${NC} x11-repo installed"
66+
67+
echo "Installing Chromium..."
68+
echo " (This is a large package (~400MB) — may take several minutes)"
69+
if ! pkg install -y chromium; then
70+
fail_warn "Failed to install Chromium"
71+
fi
72+
echo -e "${GREEN}[OK]${NC} Chromium installed"
73+
fi
74+
75+
# ── Step 2: Detect binary path ────────────────
76+
77+
if ! CHROMIUM_BIN=$(detect_chromium_bin); then
78+
fail_warn "Chromium binary not found after installation"
79+
fi
80+
81+
# ── Step 3: Configure OpenClaw browser settings
82+
83+
echo "Configuring OpenClaw browser settings..."
84+
85+
if command -v node &>/dev/null; then
86+
export CHROMIUM_BIN
87+
if node << 'NODESCRIPT'
88+
const fs = require('fs');
89+
const path = require('path');
90+
91+
const configDir = path.join(process.env.HOME, '.openclaw');
92+
const configPath = path.join(configDir, 'openclaw.json');
93+
94+
let config = {};
95+
try {
96+
config = JSON.parse(fs.readFileSync(configPath, 'utf8'));
97+
} catch {
98+
// File doesn't exist or invalid — start fresh
99+
}
100+
101+
if (!config.browser) config.browser = {};
102+
config.browser.executablePath = process.env.CHROMIUM_BIN;
103+
if (config.browser.headless === undefined) config.browser.headless = true;
104+
if (config.browser.noSandbox === undefined) config.browser.noSandbox = true;
105+
106+
fs.mkdirSync(configDir, { recursive: true });
107+
fs.writeFileSync(configPath, JSON.stringify(config, null, 2) + '\n');
108+
console.log(' Written to ' + configPath);
109+
NODESCRIPT
110+
then
111+
echo -e "${GREEN}[OK]${NC} openclaw.json browser settings configured"
112+
else
113+
echo -e "${YELLOW}[WARN]${NC} Could not update openclaw.json automatically"
114+
echo " Add this to ~/.openclaw/openclaw.json manually:"
115+
echo " \"browser\": {\"executablePath\": \"$CHROMIUM_BIN\", \"headless\": true, \"noSandbox\": true}"
116+
fi
117+
else
118+
echo -e "${YELLOW}[INFO]${NC} Node.js not available — manual browser configuration needed"
119+
echo " After running 'openclaw onboard', add to ~/.openclaw/openclaw.json:"
120+
echo " \"browser\": {\"executablePath\": \"$CHROMIUM_BIN\", \"headless\": true, \"noSandbox\": true}"
121+
fi
122+
123+
# ── Step 4: Verify ────────────────────────────
124+
125+
echo ""
126+
if [ -x "$CHROMIUM_BIN" ]; then
127+
CHROMIUM_VER=$("$CHROMIUM_BIN" --version 2>/dev/null || echo "unknown version")
128+
echo -e "${GREEN}[OK]${NC} $CHROMIUM_VER"
129+
echo " Binary: $CHROMIUM_BIN"
130+
echo ""
131+
echo -e "${YELLOW}[NOTE]${NC} Chromium uses ~300-500MB RAM at runtime."
132+
echo " Devices with less than 4GB RAM may experience slowdowns."
133+
else
134+
fail_warn "Chromium verification failed — binary not executable"
135+
fi
136+
137+
# ── Step 5: Ensure image processing works ────
138+
139+
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
140+
if [ -f "$SCRIPT_DIR/build-sharp.sh" ]; then
141+
echo ""
142+
bash "$SCRIPT_DIR/build-sharp.sh" || true
143+
fi

0 commit comments

Comments
 (0)