@hitechclaw/clawspark 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +35 -0
- package/LICENSE +21 -0
- package/README.md +378 -0
- package/clawspark +2715 -0
- package/configs/models.yaml +108 -0
- package/configs/skill-packs.yaml +44 -0
- package/configs/skills.yaml +37 -0
- package/install.sh +387 -0
- package/lib/common.sh +249 -0
- package/lib/detect-hardware.sh +156 -0
- package/lib/diagnose.sh +636 -0
- package/lib/render-diagram.sh +47 -0
- package/lib/sandbox-commands.sh +415 -0
- package/lib/secure.sh +244 -0
- package/lib/select-model.sh +442 -0
- package/lib/setup-browser.sh +138 -0
- package/lib/setup-dashboard.sh +228 -0
- package/lib/setup-inference.sh +128 -0
- package/lib/setup-mcp.sh +142 -0
- package/lib/setup-messaging.sh +242 -0
- package/lib/setup-models.sh +121 -0
- package/lib/setup-openclaw.sh +808 -0
- package/lib/setup-sandbox.sh +188 -0
- package/lib/setup-skills.sh +113 -0
- package/lib/setup-systemd.sh +224 -0
- package/lib/setup-tailscale.sh +188 -0
- package/lib/setup-voice.sh +101 -0
- package/lib/skill-audit.sh +449 -0
- package/lib/verify.sh +177 -0
- package/package.json +57 -0
- package/scripts/release.sh +133 -0
- package/uninstall.sh +161 -0
- package/v2/README.md +50 -0
- package/v2/configs/providers.yaml +79 -0
- package/v2/configs/skills.yaml +36 -0
- package/v2/install.sh +116 -0
- package/v2/lib/common.sh +285 -0
- package/v2/lib/detect-hardware.sh +119 -0
- package/v2/lib/select-runtime.sh +273 -0
- package/v2/lib/setup-extras.sh +95 -0
- package/v2/lib/setup-openclaw.sh +187 -0
- package/v2/lib/setup-provider.sh +131 -0
- package/v2/lib/verify.sh +133 -0
- package/web/index.html +1835 -0
- package/web/install.sh +387 -0
- package/web/logo-hero.svg +11 -0
- package/web/logo-icon.svg +12 -0
- package/web/logo.svg +17 -0
- package/web/vercel.json +8 -0
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# lib/setup-tailscale.sh — Optional Tailscale setup for secure remote access
|
|
3
|
+
# to OpenClaw and ClawMetry from anywhere on your Tailnet.
|
|
4
|
+
# Uses `tailscale serve` as a reverse proxy -- does NOT restart the gateway.
|
|
5
|
+
set -euo pipefail
|
|
6
|
+
|
|
7
|
+
setup_tailscale() {
|
|
8
|
+
log_info "Tailscale setup (optional)..."
|
|
9
|
+
hr
|
|
10
|
+
|
|
11
|
+
# ── Ask if user wants Tailscale ──────────────────────────────────────────
|
|
12
|
+
if ! prompt_yn "Would you like to set up Tailscale for secure remote access?" "n"; then
|
|
13
|
+
log_info "Tailscale setup skipped."
|
|
14
|
+
return 0
|
|
15
|
+
fi
|
|
16
|
+
|
|
17
|
+
# ── Install Tailscale if not present ─────────────────────────────────────
|
|
18
|
+
if check_command tailscale; then
|
|
19
|
+
log_success "Tailscale is already installed."
|
|
20
|
+
else
|
|
21
|
+
log_info "Installing Tailscale..."
|
|
22
|
+
(curl -fsSL https://tailscale.com/install.sh | sh) >> "${CLAWSPARK_LOG}" 2>&1 &
|
|
23
|
+
spinner $! "Installing Tailscale..."
|
|
24
|
+
|
|
25
|
+
if ! check_command tailscale; then
|
|
26
|
+
log_error "Tailscale installation failed. Check ${CLAWSPARK_LOG}."
|
|
27
|
+
return 1
|
|
28
|
+
fi
|
|
29
|
+
log_success "Tailscale installed."
|
|
30
|
+
fi
|
|
31
|
+
|
|
32
|
+
# ── Connect to Tailnet ───────────────────────────────────────────────────
|
|
33
|
+
if tailscale status &>/dev/null; then
|
|
34
|
+
log_success "Tailscale is connected."
|
|
35
|
+
else
|
|
36
|
+
log_info "Tailscale is not connected. Starting Tailscale..."
|
|
37
|
+
sudo tailscale up 2>&1 | tee -a "${CLAWSPARK_LOG}" || {
|
|
38
|
+
log_error "Failed to connect Tailscale. Run 'sudo tailscale up' manually."
|
|
39
|
+
return 1
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
if tailscale status &>/dev/null; then
|
|
43
|
+
log_success "Tailscale connected."
|
|
44
|
+
else
|
|
45
|
+
log_error "Tailscale did not connect. Check 'tailscale status' for details."
|
|
46
|
+
return 1
|
|
47
|
+
fi
|
|
48
|
+
fi
|
|
49
|
+
|
|
50
|
+
# ── Get the Tailscale FQDN for this machine ───────────────────────────────
|
|
51
|
+
local ts_fqdn=""
|
|
52
|
+
# Method 1: tailscale status --json parsed with python3 (most reliable)
|
|
53
|
+
ts_fqdn=$(tailscale status --json 2>/dev/null | python3 -c "
|
|
54
|
+
import json, sys
|
|
55
|
+
data = json.load(sys.stdin)
|
|
56
|
+
self_key = data.get('Self', {})
|
|
57
|
+
dns_name = self_key.get('DNSName', '')
|
|
58
|
+
# DNSName ends with a trailing dot, strip it
|
|
59
|
+
print(dns_name.rstrip('.'))
|
|
60
|
+
" 2>/dev/null || echo "")
|
|
61
|
+
|
|
62
|
+
# Method 2: tailscale whois --self
|
|
63
|
+
if [[ -z "${ts_fqdn}" ]]; then
|
|
64
|
+
ts_fqdn=$(tailscale whois --self 2>/dev/null \
|
|
65
|
+
| grep -i 'Name:' | head -1 | awk '{print $2}' \
|
|
66
|
+
| sed 's/\.$//' || echo "")
|
|
67
|
+
fi
|
|
68
|
+
|
|
69
|
+
# Method 3: construct from IP
|
|
70
|
+
if [[ -z "${ts_fqdn}" ]]; then
|
|
71
|
+
local ts_ip
|
|
72
|
+
ts_ip=$(tailscale ip -4 2>/dev/null || echo "")
|
|
73
|
+
if [[ -n "${ts_ip}" ]]; then
|
|
74
|
+
ts_fqdn="${ts_ip}"
|
|
75
|
+
else
|
|
76
|
+
ts_fqdn="your-machine"
|
|
77
|
+
fi
|
|
78
|
+
fi
|
|
79
|
+
|
|
80
|
+
log_info "Tailscale FQDN: ${ts_fqdn}"
|
|
81
|
+
|
|
82
|
+
# ── Use tailscale serve as a reverse proxy ─────────────────────────────────
|
|
83
|
+
# This proxies HTTPS on the Tailnet to the local gateway on localhost:18789.
|
|
84
|
+
# The gateway and node host keep running unchanged -- no restart needed.
|
|
85
|
+
#
|
|
86
|
+
# tailscale serve can hang if Serve is not enabled on the tailnet (it prints
|
|
87
|
+
# a URL and waits). We check for that first and use a short timeout.
|
|
88
|
+
log_info "Setting up tailscale serve to proxy to OpenClaw gateway..."
|
|
89
|
+
|
|
90
|
+
# Check if tailscale serve is available on this tailnet
|
|
91
|
+
local serve_check
|
|
92
|
+
serve_check=$(timeout 5 sudo tailscale serve status 2>&1 || true)
|
|
93
|
+
if echo "${serve_check}" | grep -qi "not enabled"; then
|
|
94
|
+
log_warn "Tailscale Serve is not enabled on your tailnet."
|
|
95
|
+
local enable_url
|
|
96
|
+
enable_url=$(echo "${serve_check}" | grep -o 'https://[^ ]*' | head -1 || echo "")
|
|
97
|
+
if [[ -n "${enable_url}" ]]; then
|
|
98
|
+
log_info "Enable it at: ${enable_url}"
|
|
99
|
+
fi
|
|
100
|
+
log_info "After enabling, run: sudo tailscale serve --bg http://127.0.0.1:18789"
|
|
101
|
+
else
|
|
102
|
+
# Try to configure the proxy
|
|
103
|
+
local serve_ok=false
|
|
104
|
+
if timeout 10 sudo tailscale serve --bg --https 443 http://127.0.0.1:18789 >> "${CLAWSPARK_LOG}" 2>&1; then
|
|
105
|
+
serve_ok=true
|
|
106
|
+
elif timeout 10 sudo tailscale serve --bg http://127.0.0.1:18789 >> "${CLAWSPARK_LOG}" 2>&1; then
|
|
107
|
+
serve_ok=true
|
|
108
|
+
fi
|
|
109
|
+
|
|
110
|
+
if [[ "${serve_ok}" == "true" ]]; then
|
|
111
|
+
log_success "Tailscale serve configured (HTTPS -> localhost:18789)."
|
|
112
|
+
else
|
|
113
|
+
log_warn "tailscale serve could not be configured automatically."
|
|
114
|
+
log_info "You can set it up manually: sudo tailscale serve --bg http://127.0.0.1:18789"
|
|
115
|
+
fi
|
|
116
|
+
fi
|
|
117
|
+
|
|
118
|
+
# ── Allow the Tailscale origin in the OpenClaw gateway ────────────────────
|
|
119
|
+
# Without this, the Control UI rejects WebSocket connections from the
|
|
120
|
+
# Tailscale HTTPS URL with "origin not allowed".
|
|
121
|
+
local ts_url="https://${ts_fqdn}"
|
|
122
|
+
log_info "Adding ${ts_url} to gateway allowedOrigins..."
|
|
123
|
+
openclaw config set gateway.controlUi.allowedOrigins "[\"${ts_url}\"]" >> "${CLAWSPARK_LOG}" 2>&1 || {
|
|
124
|
+
log_warn "Could not set allowedOrigins. You may need to run:"
|
|
125
|
+
log_info " openclaw config set gateway.controlUi.allowedOrigins '[\"${ts_url}\"]'"
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
# Restart the gateway to pick up the new origin (but keep node host running)
|
|
129
|
+
local gateway_pid_file="${CLAWSPARK_DIR}/gateway.pid"
|
|
130
|
+
local gateway_log="${CLAWSPARK_DIR}/gateway.log"
|
|
131
|
+
if [[ -f "${gateway_pid_file}" ]]; then
|
|
132
|
+
local old_pid
|
|
133
|
+
old_pid=$(cat "${gateway_pid_file}")
|
|
134
|
+
if kill -0 "${old_pid}" 2>/dev/null; then
|
|
135
|
+
log_info "Restarting gateway to apply allowedOrigins..."
|
|
136
|
+
kill "${old_pid}" 2>/dev/null || true
|
|
137
|
+
sleep 2
|
|
138
|
+
local env_file="${HOME}/.openclaw/gateway.env"
|
|
139
|
+
if [[ -f "${env_file}" ]]; then set +e; set -a; source "${env_file}" 2>/dev/null; set +a; set -e; fi
|
|
140
|
+
nohup openclaw gateway run --bind loopback > "${gateway_log}" 2>&1 &
|
|
141
|
+
local gw_pid=$!
|
|
142
|
+
echo "${gw_pid}" > "${gateway_pid_file}"
|
|
143
|
+
sleep 2
|
|
144
|
+
if kill -0 "${gw_pid}" 2>/dev/null; then
|
|
145
|
+
log_success "Gateway restarted with Tailscale origin allowed (PID ${gw_pid})."
|
|
146
|
+
else
|
|
147
|
+
log_warn "Gateway restart failed. Run: clawspark restart"
|
|
148
|
+
fi
|
|
149
|
+
fi
|
|
150
|
+
fi
|
|
151
|
+
|
|
152
|
+
# Save the URL for the final install message
|
|
153
|
+
echo "${ts_url}" > "${CLAWSPARK_DIR}/tailscale.url"
|
|
154
|
+
|
|
155
|
+
# ── Build the tokenized remote URL ─────────────────────────────────────────
|
|
156
|
+
# Get the dashboard token so we can give the user a ready-to-use URL.
|
|
157
|
+
local dash_token=""
|
|
158
|
+
local dash_output
|
|
159
|
+
dash_output=$(openclaw dashboard --no-open 2>/dev/null || echo "")
|
|
160
|
+
if [[ -n "${dash_output}" ]]; then
|
|
161
|
+
dash_token=$(echo "${dash_output}" | grep -o 'token=[a-f0-9]*' | head -1 | cut -d= -f2 || echo "")
|
|
162
|
+
fi
|
|
163
|
+
|
|
164
|
+
local ts_chat_url="${ts_url}"
|
|
165
|
+
if [[ -n "${dash_token}" ]]; then
|
|
166
|
+
ts_chat_url="${ts_url}/#token=${dash_token}"
|
|
167
|
+
fi
|
|
168
|
+
|
|
169
|
+
# ── Print access information ─────────────────────────────────────────────
|
|
170
|
+
printf '\n'
|
|
171
|
+
print_box \
|
|
172
|
+
"${BOLD}Tailscale Remote Access${RESET}" \
|
|
173
|
+
"" \
|
|
174
|
+
"Open this URL on any device on your Tailnet:" \
|
|
175
|
+
" ${ts_chat_url}" \
|
|
176
|
+
"" \
|
|
177
|
+
"First time connecting from a new browser:" \
|
|
178
|
+
" 1. Open the URL above" \
|
|
179
|
+
" 2. If you see 'pairing required', run on this machine:" \
|
|
180
|
+
" openclaw devices list" \
|
|
181
|
+
" openclaw devices approve <request-id>" \
|
|
182
|
+
"" \
|
|
183
|
+
"Traffic is encrypted end-to-end via WireGuard."
|
|
184
|
+
printf '\n'
|
|
185
|
+
|
|
186
|
+
log_info "Remote URL: ${ts_chat_url}"
|
|
187
|
+
log_success "Tailscale setup complete."
|
|
188
|
+
}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# lib/setup-voice.sh — Installs Whisper-based voice skills and selects
|
|
3
|
+
# the appropriate model size for the detected hardware.
|
|
4
|
+
set -euo pipefail
|
|
5
|
+
|
|
6
|
+
setup_voice() {
|
|
7
|
+
log_info "Setting up voice capabilities..."
|
|
8
|
+
hr
|
|
9
|
+
|
|
10
|
+
# ── Pick Whisper model size based on platform ───────────────────────────
|
|
11
|
+
local whisper_model="base"
|
|
12
|
+
case "${HW_PLATFORM}" in
|
|
13
|
+
dgx-spark)
|
|
14
|
+
whisper_model="large-v3"
|
|
15
|
+
;;
|
|
16
|
+
jetson)
|
|
17
|
+
whisper_model="small"
|
|
18
|
+
;;
|
|
19
|
+
rtx)
|
|
20
|
+
if (( HW_GPU_VRAM_MB >= 24576 )); then
|
|
21
|
+
whisper_model="medium"
|
|
22
|
+
else
|
|
23
|
+
whisper_model="base"
|
|
24
|
+
fi
|
|
25
|
+
;;
|
|
26
|
+
*)
|
|
27
|
+
whisper_model="base"
|
|
28
|
+
;;
|
|
29
|
+
esac
|
|
30
|
+
|
|
31
|
+
log_info "Whisper model size: ${whisper_model} (for ${HW_PLATFORM})"
|
|
32
|
+
|
|
33
|
+
# ── Install local-whisper skill (skip if already installed by skills step)
|
|
34
|
+
local whisper_skill_dir="${HOME}/.openclaw/workspace/skills/local-whisper"
|
|
35
|
+
if [[ -d "${whisper_skill_dir}" ]]; then
|
|
36
|
+
log_info "local-whisper already installed (from skills step)."
|
|
37
|
+
else
|
|
38
|
+
printf ' %s→%s Installing local-whisper skill ... ' "${CYAN}" "${RESET}"
|
|
39
|
+
if npx --yes clawhub@latest install --force local-whisper >> "${CLAWSPARK_LOG}" 2>&1; then
|
|
40
|
+
printf '%s✓%s\n' "${GREEN}" "${RESET}"
|
|
41
|
+
else
|
|
42
|
+
printf '%s✗%s\n' "${RED}" "${RESET}"
|
|
43
|
+
log_warn "local-whisper installation failed — voice features may not work."
|
|
44
|
+
fi
|
|
45
|
+
fi
|
|
46
|
+
|
|
47
|
+
# ── Install WhatsApp voice integration if applicable ────────────────────
|
|
48
|
+
local messaging="${FLAG_MESSAGING:-${MESSAGING_CHOICE:-skip}}"
|
|
49
|
+
messaging=$(to_lower "${messaging}")
|
|
50
|
+
if [[ "${messaging}" == "whatsapp" || "${messaging}" == "both" ]]; then
|
|
51
|
+
local voice_skill_dir="${HOME}/.openclaw/workspace/skills/whatsapp-voice-chat-integration-open-source"
|
|
52
|
+
if [[ -d "${voice_skill_dir}" ]]; then
|
|
53
|
+
log_info "whatsapp-voice-chat-integration already installed (from skills step)."
|
|
54
|
+
else
|
|
55
|
+
printf ' %s→%s Installing whatsapp-voice-chat-integration-open-source ... ' "${CYAN}" "${RESET}"
|
|
56
|
+
if npx --yes clawhub@latest install --force whatsapp-voice-chat-integration-open-source >> "${CLAWSPARK_LOG}" 2>&1; then
|
|
57
|
+
printf '%s✓%s\n' "${GREEN}" "${RESET}"
|
|
58
|
+
else
|
|
59
|
+
printf '%s✗%s\n' "${RED}" "${RESET}"
|
|
60
|
+
log_warn "whatsapp-voice-chat-integration failed — voice notes may not work."
|
|
61
|
+
fi
|
|
62
|
+
fi
|
|
63
|
+
fi
|
|
64
|
+
|
|
65
|
+
# ── Configure Whisper model size ────────────────────────────────────────
|
|
66
|
+
local whisper_config_dir="${HOME}/.openclaw/skills/local-whisper"
|
|
67
|
+
mkdir -p "${whisper_config_dir}"
|
|
68
|
+
|
|
69
|
+
# Detect compute device: CUDA (NVIDIA), Metal (macOS), or CPU fallback
|
|
70
|
+
local whisper_device="cpu"
|
|
71
|
+
local whisper_compute="int8"
|
|
72
|
+
if check_command nvidia-smi && nvidia-smi &>/dev/null; then
|
|
73
|
+
whisper_device="cuda"
|
|
74
|
+
whisper_compute="float16"
|
|
75
|
+
elif [[ "$(uname)" == "Darwin" ]]; then
|
|
76
|
+
# macOS Apple Silicon uses Metal via CoreML/ANE acceleration
|
|
77
|
+
whisper_device="auto"
|
|
78
|
+
whisper_compute="int8"
|
|
79
|
+
fi
|
|
80
|
+
|
|
81
|
+
cat > "${whisper_config_dir}/config.json" <<WCEOF
|
|
82
|
+
{
|
|
83
|
+
"model": "${whisper_model}",
|
|
84
|
+
"language": "auto",
|
|
85
|
+
"device": "${whisper_device}",
|
|
86
|
+
"compute_type": "${whisper_compute}"
|
|
87
|
+
}
|
|
88
|
+
WCEOF
|
|
89
|
+
log_info "Whisper config written (model=${whisper_model})."
|
|
90
|
+
|
|
91
|
+
# ── Verification ────────────────────────────────────────────────────────
|
|
92
|
+
# A full transcription test requires an audio file; we just verify the
|
|
93
|
+
# config and skill presence.
|
|
94
|
+
if [[ -f "${whisper_config_dir}/config.json" ]]; then
|
|
95
|
+
log_success "Voice setup complete — Whisper ${whisper_model} configured."
|
|
96
|
+
else
|
|
97
|
+
log_warn "Whisper config file not found — voice may need manual setup."
|
|
98
|
+
fi
|
|
99
|
+
|
|
100
|
+
export WHISPER_MODEL="${whisper_model}"
|
|
101
|
+
}
|