@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.
Files changed (49) hide show
  1. package/CHANGELOG.md +35 -0
  2. package/LICENSE +21 -0
  3. package/README.md +378 -0
  4. package/clawspark +2715 -0
  5. package/configs/models.yaml +108 -0
  6. package/configs/skill-packs.yaml +44 -0
  7. package/configs/skills.yaml +37 -0
  8. package/install.sh +387 -0
  9. package/lib/common.sh +249 -0
  10. package/lib/detect-hardware.sh +156 -0
  11. package/lib/diagnose.sh +636 -0
  12. package/lib/render-diagram.sh +47 -0
  13. package/lib/sandbox-commands.sh +415 -0
  14. package/lib/secure.sh +244 -0
  15. package/lib/select-model.sh +442 -0
  16. package/lib/setup-browser.sh +138 -0
  17. package/lib/setup-dashboard.sh +228 -0
  18. package/lib/setup-inference.sh +128 -0
  19. package/lib/setup-mcp.sh +142 -0
  20. package/lib/setup-messaging.sh +242 -0
  21. package/lib/setup-models.sh +121 -0
  22. package/lib/setup-openclaw.sh +808 -0
  23. package/lib/setup-sandbox.sh +188 -0
  24. package/lib/setup-skills.sh +113 -0
  25. package/lib/setup-systemd.sh +224 -0
  26. package/lib/setup-tailscale.sh +188 -0
  27. package/lib/setup-voice.sh +101 -0
  28. package/lib/skill-audit.sh +449 -0
  29. package/lib/verify.sh +177 -0
  30. package/package.json +57 -0
  31. package/scripts/release.sh +133 -0
  32. package/uninstall.sh +161 -0
  33. package/v2/README.md +50 -0
  34. package/v2/configs/providers.yaml +79 -0
  35. package/v2/configs/skills.yaml +36 -0
  36. package/v2/install.sh +116 -0
  37. package/v2/lib/common.sh +285 -0
  38. package/v2/lib/detect-hardware.sh +119 -0
  39. package/v2/lib/select-runtime.sh +273 -0
  40. package/v2/lib/setup-extras.sh +95 -0
  41. package/v2/lib/setup-openclaw.sh +187 -0
  42. package/v2/lib/setup-provider.sh +131 -0
  43. package/v2/lib/verify.sh +133 -0
  44. package/web/index.html +1835 -0
  45. package/web/install.sh +387 -0
  46. package/web/logo-hero.svg +11 -0
  47. package/web/logo-icon.svg +12 -0
  48. package/web/logo.svg +17 -0
  49. package/web/vercel.json +8 -0
@@ -0,0 +1,95 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+
4
+ setup_v2_extras() {
5
+ log_info "Preparing v2 extras..."
6
+ _source_legacy_module_v2 "setup-skills.sh"
7
+ _source_legacy_module_v2 "setup-voice.sh"
8
+ _source_legacy_module_v2 "setup-messaging.sh"
9
+ _source_legacy_module_v2 "secure.sh"
10
+
11
+ mkdir -p "${CLAWSPARK_DIR}"
12
+ _install_v2_cli_assets
13
+ _seed_skills_config_v2
14
+ _prepare_messaging_choice_v2
15
+
16
+ log_info "Installing skills for v2..."
17
+ setup_skills || log_warn "Skill installation had issues -- continuing."
18
+
19
+ log_info "Configuring voice for v2..."
20
+ setup_voice || log_warn "Voice setup had issues -- continuing."
21
+
22
+ log_info "Configuring messaging for v2..."
23
+ setup_messaging || log_warn "Messaging setup had issues -- continuing."
24
+
25
+ log_info "Applying security hardening for v2..."
26
+ secure_setup || log_warn "Security hardening had issues -- continuing."
27
+
28
+ if declare -F _start_node_host >/dev/null; then
29
+ if check_command systemctl && systemctl is-active --quiet clawspark-nodehost.service 2>/dev/null; then
30
+ log_info "Node host already running via systemd."
31
+ else
32
+ log_info "Starting node host..."
33
+ _start_node_host || log_warn "Node host failed to start -- OpenClaw will still run without exec tools."
34
+ fi
35
+ fi
36
+
37
+ log_success "v2 extras complete."
38
+ }
39
+
40
+ _install_v2_cli_assets() {
41
+ if [[ -f "${CLAWSPARK_REPO_DIR}/clawspark" ]]; then
42
+ cp "${CLAWSPARK_REPO_DIR}/clawspark" "${CLAWSPARK_DIR}/clawspark"
43
+ chmod +x "${CLAWSPARK_DIR}/clawspark"
44
+ sudo cp "${CLAWSPARK_REPO_DIR}/clawspark" /usr/local/bin/clawspark 2>/dev/null || true
45
+ sudo chmod +x /usr/local/bin/clawspark 2>/dev/null || true
46
+ fi
47
+
48
+ rm -rf "${CLAWSPARK_DIR}/lib" "${CLAWSPARK_DIR}/configs"
49
+ cp -r "${CLAWSPARK_REPO_DIR}/lib" "${CLAWSPARK_DIR}/"
50
+ cp -r "${CLAWSPARK_REPO_DIR}/configs" "${CLAWSPARK_DIR}/"
51
+
52
+ if [[ -f "${CLAWSPARK_REPO_DIR}/uninstall.sh" ]]; then
53
+ cp "${CLAWSPARK_REPO_DIR}/uninstall.sh" "${CLAWSPARK_DIR}/uninstall.sh"
54
+ fi
55
+
56
+ log_info "Installed CLI assets into ${CLAWSPARK_DIR}"
57
+ }
58
+
59
+ _source_legacy_module_v2() {
60
+ local module="$1"
61
+ local module_path="${CLAWSPARK_REPO_DIR}/lib/${module}"
62
+
63
+ if [[ ! -f "${module_path}" ]]; then
64
+ log_warn "Legacy module not found: ${module}"
65
+ return 0
66
+ fi
67
+
68
+ # shellcheck source=/dev/null
69
+ source "${module_path}"
70
+ }
71
+
72
+ _seed_skills_config_v2() {
73
+ local bundled="${SCRIPT_DIR}/configs/skills.yaml"
74
+ local target="${CLAWSPARK_DIR}/skills.yaml"
75
+
76
+ if [[ -f "${bundled}" && ! -f "${target}" ]]; then
77
+ cp "${bundled}" "${target}"
78
+ log_info "Seeded v2 skills config: ${target}"
79
+ fi
80
+ }
81
+
82
+ _prepare_messaging_choice_v2() {
83
+ if [[ -n "${FLAG_MESSAGING:-}" ]]; then
84
+ FLAG_MESSAGING=$(to_lower "${FLAG_MESSAGING}")
85
+ elif [[ "${CLAWSPARK_DEFAULTS}" == "true" ]]; then
86
+ FLAG_MESSAGING="skip"
87
+ else
88
+ local msg_opts=("WhatsApp" "Telegram" "Both" "Skip")
89
+ FLAG_MESSAGING=$(prompt_choice "Connect a messaging platform? (Web UI is always available)" msg_opts 3)
90
+ FLAG_MESSAGING=$(to_lower "${FLAG_MESSAGING}")
91
+ fi
92
+
93
+ export FLAG_MESSAGING
94
+ log_info "Messaging preference: ${FLAG_MESSAGING}"
95
+ }
@@ -0,0 +1,187 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+
4
+ setup_openclaw_v2() {
5
+ log_info "Installing and configuring OpenClaw for v2..."
6
+ _ensure_node_v2
7
+ _install_openclaw_v2
8
+ _write_openclaw_config_v2
9
+ _run_onboard_v2
10
+ log_success "OpenClaw v2 configuration complete."
11
+ }
12
+
13
+ _ensure_node_v2() {
14
+ local required_major=22
15
+ if check_command node; then
16
+ local node_ver major
17
+ node_ver=$(node -v 2>/dev/null | sed 's/^v//')
18
+ major=$(echo "${node_ver}" | cut -d. -f1)
19
+ if (( major >= required_major )); then
20
+ log_success "Node.js v${node_ver} satisfies >= ${required_major}."
21
+ return 0
22
+ fi
23
+ fi
24
+
25
+ log_info "Installing Node.js ${required_major}.x..."
26
+ if check_command apt-get; then
27
+ (curl -fsSL "https://deb.nodesource.com/setup_${required_major}.x" | sudo -E bash - && sudo apt-get install -y nodejs) >> "${CLAWSPARK_V2_LOG}" 2>&1 &
28
+ spinner $! "Installing Node.js..."
29
+ elif check_command brew; then
30
+ (brew install "node@${required_major}") >> "${CLAWSPARK_V2_LOG}" 2>&1 &
31
+ spinner $! "Installing Node.js..."
32
+ else
33
+ log_error "No supported package manager found for Node.js install."
34
+ return 1
35
+ fi
36
+
37
+ if ! check_command node; then
38
+ log_error "Node.js installation failed."
39
+ return 1
40
+ fi
41
+ }
42
+
43
+ _install_openclaw_v2() {
44
+ if check_command openclaw; then
45
+ log_success "OpenClaw already installed."
46
+ return 0
47
+ fi
48
+
49
+ log_info "Installing OpenClaw globally via npm..."
50
+ (npm install -g openclaw@latest 2>>"${CLAWSPARK_V2_LOG}" || sudo npm install -g openclaw@latest) >> "${CLAWSPARK_V2_LOG}" 2>&1 &
51
+ spinner $! "Installing OpenClaw..."
52
+ hash -r 2>/dev/null || true
53
+
54
+ if ! check_command openclaw; then
55
+ log_error "OpenClaw install failed."
56
+ return 1
57
+ fi
58
+ }
59
+
60
+ _write_openclaw_config_v2() {
61
+ local config_dir="${HOME}/.openclaw"
62
+ local config_file="${config_dir}/openclaw.json"
63
+ local auth_token
64
+
65
+ mkdir -p "${config_dir}"
66
+ chmod 700 "${config_dir}"
67
+
68
+ auth_token=$(openssl rand -hex 32 2>/dev/null || head -c 64 /dev/urandom | od -An -tx1 | tr -d ' \n')
69
+ [[ -f "${config_file}" ]] || echo '{}' > "${config_file}"
70
+
71
+ openclaw config set gateway.mode local >> "${CLAWSPARK_V2_LOG}" 2>&1 || true
72
+ openclaw config set gateway.port 18789 >> "${CLAWSPARK_V2_LOG}" 2>&1 || true
73
+ openclaw config set gateway.auth.token "${auth_token}" >> "${CLAWSPARK_V2_LOG}" 2>&1 || true
74
+ openclaw config set tools.profile full >> "${CLAWSPARK_V2_LOG}" 2>&1 || true
75
+ openclaw config set agents.defaults.memorySearch.enabled false >> "${CLAWSPARK_V2_LOG}" 2>&1 || true
76
+ openclaw config set agents.defaults.workspace "${HOME}/workspace" >> "${CLAWSPARK_V2_LOG}" 2>&1 || true
77
+
78
+ local default_model_ref
79
+ default_model_ref=$(_provider_model_ref_v2 "${PRIMARY_PROVIDER}" "${SELECTED_MODEL_ID}")
80
+ openclaw config set agents.defaults.model "${default_model_ref}" >> "${CLAWSPARK_V2_LOG}" 2>&1 || true
81
+
82
+ python3 - "${config_file}" "${PRIMARY_PROVIDER}" "${SELECTED_MODEL_ID}" "${RUNTIME_MODE}" "${FALLBACK_PROVIDER:-}" "${FALLBACK_MODEL_ID:-}" "${CUSTOM_PROVIDER_NAME:-}" <<'PY'
83
+ import json, sys
84
+ path, provider, model, runtime_mode, fallback_provider, fallback_model, custom_provider_name = sys.argv[1:8]
85
+ with open(path, 'r', encoding='utf-8') as fh:
86
+ cfg = json.load(fh)
87
+
88
+ cfg.setdefault('tools', {})
89
+ cfg['tools']['profile'] = 'full'
90
+ cfg.setdefault('gateway', {})
91
+ cfg['gateway']['mode'] = 'local'
92
+ cfg.setdefault('agents', {}).setdefault('defaults', {})
93
+
94
+ def provider_ref(p, m):
95
+ if p == 'ollama':
96
+ return f'ollama/{m}'
97
+ if p == 'openai':
98
+ return f'openai/{m}'
99
+ if p == 'anthropic':
100
+ return f'anthropic/{m}'
101
+ if p == 'openrouter':
102
+ return f'openai/{m}'
103
+ if p == 'google':
104
+ return f'openai/{m}'
105
+ if p == 'custom':
106
+ return f'openai/{m}'
107
+ return m
108
+
109
+ cfg['agents']['defaults']['model'] = provider_ref(provider, model)
110
+ cfg['clawsparkV2'] = {
111
+ 'runtimeMode': runtime_mode,
112
+ 'primaryProvider': provider,
113
+ 'primaryModel': model,
114
+ }
115
+ if fallback_provider and fallback_model:
116
+ cfg['clawsparkV2']['fallbackProvider'] = fallback_provider
117
+ cfg['clawsparkV2']['fallbackModel'] = fallback_model
118
+ if provider == 'custom' and custom_provider_name:
119
+ cfg['clawsparkV2']['customProviderName'] = custom_provider_name
120
+
121
+ cfg.setdefault('models', {})
122
+ cfg['models'].setdefault('providers', {})
123
+
124
+ if provider == 'ollama':
125
+ cfg['models']['providers']['ollama'] = {
126
+ 'baseUrl': 'http://127.0.0.1:11434/v1',
127
+ 'api': 'openai-completions'
128
+ }
129
+ elif provider in ('openai', 'openrouter', 'google'):
130
+ provider_key = 'openai'
131
+ cfg['models']['providers'][provider_key] = {
132
+ 'api': 'openai-completions'
133
+ }
134
+ elif provider == 'custom':
135
+ cfg['models']['providers']['openai'] = {
136
+ 'api': 'openai-completions'
137
+ }
138
+ elif provider == 'anthropic':
139
+ cfg['models']['providers']['anthropic'] = {
140
+ 'api': 'anthropic-messages'
141
+ }
142
+
143
+ with open(path, 'w', encoding='utf-8') as fh:
144
+ json.dump(cfg, fh, indent=2)
145
+ PY
146
+
147
+ echo "${auth_token}" > "${config_dir}/.gateway-token"
148
+ chmod 600 "${config_dir}/.gateway-token"
149
+ }
150
+
151
+ _provider_model_ref_v2() {
152
+ local provider="$1"
153
+ local model="$2"
154
+ case "${provider}" in
155
+ ollama) printf 'ollama/%s' "${model}" ;;
156
+ openai) printf 'openai/%s' "${model}" ;;
157
+ anthropic) printf 'anthropic/%s' "${model}" ;;
158
+ openrouter) printf 'openai/%s' "${model}" ;;
159
+ google) printf 'openai/%s' "${model}" ;;
160
+ custom) printf 'openai/%s' "${model}" ;;
161
+ *) printf '%s' "${model}" ;;
162
+ esac
163
+ }
164
+
165
+ _run_onboard_v2() {
166
+ local env_file="${HOME}/.openclaw/gateway.env"
167
+ if [[ -f "${env_file}" ]]; then
168
+ set +e
169
+ set -a
170
+ source "${env_file}" 2>/dev/null
171
+ set +a
172
+ set -e
173
+ fi
174
+
175
+ openclaw onboard \
176
+ --non-interactive \
177
+ --accept-risk \
178
+ --auth-choice skip \
179
+ --skip-daemon \
180
+ --skip-channels \
181
+ --skip-skills \
182
+ --skip-ui \
183
+ --skip-health \
184
+ >> "${CLAWSPARK_V2_LOG}" 2>&1 || {
185
+ log_warn "openclaw onboard returned non-zero. This may be acceptable on reruns."
186
+ }
187
+ }
@@ -0,0 +1,131 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+
4
+ setup_provider_v2() {
5
+ log_info "Preparing inference backend..."
6
+ mkdir -p "${HOME}/.openclaw"
7
+
8
+ if [[ "${PRIMARY_PROVIDER}" == "ollama" ]]; then
9
+ setup_ollama_backend_v2
10
+ else
11
+ log_info "API backend selected; local inference install skipped."
12
+ INFERENCE_API_URL="${API_BASE_URL}"
13
+ export INFERENCE_API_URL
14
+ fi
15
+
16
+ _write_gateway_env_v2
17
+ log_success "Provider backend ready."
18
+ }
19
+
20
+ setup_ollama_backend_v2() {
21
+ if ! check_command ollama; then
22
+ log_info "Ollama not found — installing..."
23
+ if [[ "$(uname)" == "Darwin" ]]; then
24
+ if check_command brew; then
25
+ (brew install ollama) >> "${CLAWSPARK_V2_LOG}" 2>&1 &
26
+ spinner $! "Installing Ollama..."
27
+ else
28
+ curl -fsSL https://ollama.com/install.sh | sh >> "${CLAWSPARK_V2_LOG}" 2>&1 || true
29
+ fi
30
+ else
31
+ curl -fsSL https://ollama.com/install.sh | sh >> "${CLAWSPARK_V2_LOG}" 2>&1 || true
32
+ fi
33
+ hash -r 2>/dev/null || true
34
+ fi
35
+
36
+ if ! check_command ollama; then
37
+ log_error "Ollama install failed."
38
+ return 1
39
+ fi
40
+
41
+ if ! curl -sf http://127.0.0.1:11434/ &>/dev/null; then
42
+ log_info "Starting Ollama service..."
43
+ if check_command systemctl && systemctl is-enabled ollama &>/dev/null; then
44
+ sudo systemctl start ollama >> "${CLAWSPARK_V2_LOG}" 2>&1 || true
45
+ else
46
+ nohup ollama serve >> "${CLAWSPARK_V2_DIR}/ollama.log" 2>&1 &
47
+ echo $! > "${CLAWSPARK_V2_DIR}/ollama.pid"
48
+ fi
49
+ fi
50
+
51
+ local attempt=0
52
+ while (( attempt < 30 )); do
53
+ if curl -sf http://127.0.0.1:11434/ &>/dev/null; then
54
+ break
55
+ fi
56
+ attempt=$(( attempt + 1 ))
57
+ sleep 1
58
+ done
59
+
60
+ if ! curl -sf http://127.0.0.1:11434/ &>/dev/null; then
61
+ log_error "Ollama is not responding."
62
+ return 1
63
+ fi
64
+
65
+ if ! ollama list 2>/dev/null | grep -qF "${SELECTED_MODEL_ID}"; then
66
+ log_info "Pulling local model ${SELECTED_MODEL_ID}..."
67
+ if ! ollama pull "${SELECTED_MODEL_ID}" 2>&1 | tee -a "${CLAWSPARK_V2_LOG}"; then
68
+ log_error "Failed to pull ${SELECTED_MODEL_ID}"
69
+ return 1
70
+ fi
71
+ else
72
+ log_success "Local model already available."
73
+ fi
74
+
75
+ INFERENCE_API_URL="http://127.0.0.1:11434/v1"
76
+ export INFERENCE_API_URL
77
+ }
78
+
79
+ _write_gateway_env_v2() {
80
+ local env_file="${HOME}/.openclaw/gateway.env"
81
+ mkdir -p "$(dirname "${env_file}")"
82
+ : > "${env_file}"
83
+
84
+ local npm_prefix_bin
85
+ npm_prefix_bin="$(npm config get prefix 2>/dev/null)/bin"
86
+ local computed_path="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
87
+ [[ -d "${npm_prefix_bin}" ]] && computed_path="${npm_prefix_bin}:${computed_path}"
88
+ [[ -d "${HOME}/.npm-global/bin" ]] && computed_path="${HOME}/.npm-global/bin:${computed_path}"
89
+ [[ -d "/snap/bin" ]] && computed_path="${computed_path}:/snap/bin"
90
+
91
+ printf 'PATH=%s\n' "${computed_path}" >> "${env_file}"
92
+ printf 'OPENCLAW_GATEWAY_OPENAI_COMPAT=true\n' >> "${env_file}"
93
+ printf 'CLAWSPARK_V2_RUNTIME_MODE=%s\n' "${RUNTIME_MODE}" >> "${env_file}"
94
+ printf 'CLAWSPARK_V2_PRIMARY_PROVIDER=%s\n' "${PRIMARY_PROVIDER}" >> "${env_file}"
95
+
96
+ case "${PRIMARY_PROVIDER}" in
97
+ ollama)
98
+ printf 'OLLAMA_API_KEY=ollama\n' >> "${env_file}"
99
+ printf 'OLLAMA_BASE_URL=http://127.0.0.1:11434\n' >> "${env_file}"
100
+ ;;
101
+ openai)
102
+ printf 'OPENAI_API_KEY=%s\n' "${API_KEY}" >> "${env_file}"
103
+ printf 'OPENAI_BASE_URL=%s\n' "${API_BASE_URL}" >> "${env_file}"
104
+ ;;
105
+ anthropic)
106
+ printf 'ANTHROPIC_API_KEY=%s\n' "${API_KEY}" >> "${env_file}"
107
+ printf 'ANTHROPIC_BASE_URL=%s\n' "${API_BASE_URL}" >> "${env_file}"
108
+ ;;
109
+ openrouter)
110
+ printf 'OPENROUTER_API_KEY=%s\n' "${API_KEY}" >> "${env_file}"
111
+ printf 'OPENROUTER_BASE_URL=%s\n' "${API_BASE_URL}" >> "${env_file}"
112
+ ;;
113
+ google)
114
+ printf 'GOOGLE_API_KEY=%s\n' "${API_KEY}" >> "${env_file}"
115
+ printf 'GOOGLE_BASE_URL=%s\n' "${API_BASE_URL}" >> "${env_file}"
116
+ ;;
117
+ custom)
118
+ printf 'CUSTOM_AI_API_KEY=%s\n' "${API_KEY}" >> "${env_file}"
119
+ printf 'CUSTOM_AI_BASE_URL=%s\n' "${API_BASE_URL}" >> "${env_file}"
120
+ printf 'CUSTOM_AI_PROVIDER_NAME=%s\n' "${CUSTOM_PROVIDER_NAME:-Custom AI}" >> "${env_file}"
121
+ ;;
122
+ esac
123
+
124
+ if [[ -n "${FALLBACK_PROVIDER:-}" ]]; then
125
+ printf 'CLAWSPARK_V2_FALLBACK_PROVIDER=%s\n' "${FALLBACK_PROVIDER}" >> "${env_file}"
126
+ printf 'CLAWSPARK_V2_FALLBACK_MODEL=%s\n' "${FALLBACK_MODEL_ID}" >> "${env_file}"
127
+ fi
128
+
129
+ chmod 600 "${env_file}"
130
+ log_info "gateway.env written for ${PRIMARY_PROVIDER}"
131
+ }
@@ -0,0 +1,133 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+
4
+ verify_v2_installation() {
5
+ log_info "Running v2 verification checks..."
6
+ hr
7
+
8
+ local pass=0
9
+ local fail=0
10
+
11
+ _check_pass() {
12
+ printf ' %s✓%s %s\n' "${GREEN}" "${RESET}" "$1"
13
+ pass=$(( pass + 1 ))
14
+ }
15
+
16
+ _check_fail() {
17
+ printf ' %s✗%s %s\n' "${RED}" "${RESET}" "$1"
18
+ fail=$(( fail + 1 ))
19
+ }
20
+
21
+ _check_pass "Runtime mode: ${RUNTIME_MODE}"
22
+ _check_pass "Primary provider: ${PRIMARY_PROVIDER}"
23
+ _check_pass "Default model: ${SELECTED_MODEL_ID}"
24
+
25
+ if check_command openclaw; then
26
+ _check_pass "OpenClaw installed: $(openclaw --version 2>/dev/null || echo unknown)"
27
+ else
28
+ _check_fail "OpenClaw not installed"
29
+ fi
30
+
31
+ if [[ "${PRIMARY_PROVIDER}" == "ollama" ]]; then
32
+ if curl -sf http://127.0.0.1:11434/ &>/dev/null; then
33
+ _check_pass "Ollama API responding"
34
+ else
35
+ _check_fail "Ollama API not responding"
36
+ fi
37
+
38
+ if check_command ollama && ollama list 2>/dev/null | grep -qF "${SELECTED_MODEL_ID}"; then
39
+ _check_pass "Local model available in Ollama"
40
+ else
41
+ _check_fail "Local model missing in Ollama"
42
+ fi
43
+ else
44
+ local env_file="${HOME}/.openclaw/gateway.env"
45
+ if [[ -f "${env_file}" ]]; then
46
+ _check_pass "gateway.env written for API provider"
47
+ else
48
+ _check_fail "gateway.env missing"
49
+ fi
50
+
51
+ case "${PRIMARY_PROVIDER}" in
52
+ openai)
53
+ grep -q '^OPENAI_API_KEY=' "${env_file}" 2>/dev/null && _check_pass "OpenAI API key configured" || _check_fail "OpenAI API key missing"
54
+ ;;
55
+ anthropic)
56
+ grep -q '^ANTHROPIC_API_KEY=' "${env_file}" 2>/dev/null && _check_pass "Anthropic API key configured" || _check_fail "Anthropic API key missing"
57
+ ;;
58
+ openrouter)
59
+ grep -q '^OPENROUTER_API_KEY=' "${env_file}" 2>/dev/null && _check_pass "OpenRouter API key configured" || _check_fail "OpenRouter API key missing"
60
+ ;;
61
+ google)
62
+ grep -q '^GOOGLE_API_KEY=' "${env_file}" 2>/dev/null && _check_pass "Google API key configured" || _check_fail "Google API key missing"
63
+ ;;
64
+ custom)
65
+ grep -q '^CUSTOM_AI_API_KEY=' "${env_file}" 2>/dev/null && _check_pass "Custom AI API key configured" || _check_fail "Custom AI API key missing"
66
+ grep -q '^CUSTOM_AI_BASE_URL=' "${env_file}" 2>/dev/null && _check_pass "Custom AI base URL configured" || _check_fail "Custom AI base URL missing"
67
+ grep -q '^CUSTOM_AI_PROVIDER_NAME=' "${env_file}" 2>/dev/null && _check_pass "Custom AI label configured" || _check_fail "Custom AI label missing"
68
+ ;;
69
+ esac
70
+ fi
71
+
72
+ local config_file="${HOME}/.openclaw/openclaw.json"
73
+ if [[ -f "${config_file}" ]]; then
74
+ _check_pass "OpenClaw config present"
75
+ else
76
+ _check_fail "OpenClaw config missing"
77
+ fi
78
+
79
+ if [[ -f "${CLAWSPARK_DIR}/skills.yaml" ]]; then
80
+ _check_pass "v2 skills config present"
81
+ else
82
+ _check_fail "v2 skills config missing"
83
+ fi
84
+
85
+ if [[ -f "${HOME}/.openclaw/skills/local-whisper/config.json" ]]; then
86
+ _check_pass "Voice config present"
87
+ else
88
+ _check_fail "Voice config missing"
89
+ fi
90
+
91
+ if [[ -f "${CLAWSPARK_DIR}/token" ]]; then
92
+ _check_pass "Security token generated"
93
+ else
94
+ _check_fail "Security token missing"
95
+ fi
96
+
97
+ if [[ "${FLAG_MESSAGING:-skip}" == "skip" || "${MESSAGING_CHOICE:-skip}" == "skip" ]]; then
98
+ _check_pass "Messaging setup skipped"
99
+ else
100
+ _check_pass "Messaging configured: ${MESSAGING_CHOICE:-${FLAG_MESSAGING}}"
101
+ fi
102
+
103
+ if [[ -f "${CLAWSPARK_DIR}/gateway.pid" ]]; then
104
+ local gateway_pid
105
+ gateway_pid=$(cat "${CLAWSPARK_DIR}/gateway.pid" 2>/dev/null || echo "")
106
+ if [[ -n "${gateway_pid}" ]] && kill -0 "${gateway_pid}" 2>/dev/null; then
107
+ _check_pass "Gateway process running"
108
+ else
109
+ _check_fail "Gateway process not running"
110
+ fi
111
+ else
112
+ _check_fail "Gateway PID file missing"
113
+ fi
114
+
115
+ if [[ -f "${CLAWSPARK_DIR}/node.pid" ]]; then
116
+ local node_pid
117
+ node_pid=$(cat "${CLAWSPARK_DIR}/node.pid" 2>/dev/null || echo "")
118
+ if [[ -n "${node_pid}" ]] && kill -0 "${node_pid}" 2>/dev/null; then
119
+ _check_pass "Node host running"
120
+ else
121
+ _check_fail "Node host not running"
122
+ fi
123
+ else
124
+ _check_fail "Node host PID file missing"
125
+ fi
126
+
127
+ printf '\n'
128
+ if (( fail == 0 )); then
129
+ log_success "All ${pass} verification checks passed."
130
+ else
131
+ log_warn "${pass} checks passed, ${fail} failed."
132
+ fi
133
+ }