@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
package/web/install.sh ADDED
@@ -0,0 +1,387 @@
1
+ #!/usr/bin/env bash
2
+ # install.sh — clawspark one-click installer.
3
+ # Sets up OpenClaw with a local LLM on NVIDIA DGX Spark, Jetson, or RTX hardware.
4
+ #
5
+ # Quick start:
6
+ # curl -fsSL https://clawspark.hitechclaw.com/install.sh | bash
7
+ #
8
+ # Or clone and run:
9
+ # git clone https://github.com/thanhan92-f1/clawspark && cd clawspark && bash install.sh
10
+ set -euo pipefail
11
+
12
+ # ── Bootstrap: if piped from curl, clone the repo and re-exec ─────────────
13
+ SCRIPT_DIR=""
14
+ if [[ -n "${BASH_SOURCE[0]:-}" ]]; then
15
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" &>/dev/null && pwd 2>/dev/null || true)"
16
+ fi
17
+
18
+ if [[ -z "${SCRIPT_DIR}" ]] || [[ ! -d "${SCRIPT_DIR}/lib" ]]; then
19
+ # Running via curl pipe -- no lib/ available, need to clone
20
+ CLONE_DIR="$(mktemp -d)/clawspark"
21
+ echo "Downloading clawspark..."
22
+ if command -v git &>/dev/null; then
23
+ git clone --depth 1 https://github.com/thanhan92-f1/clawspark.git "${CLONE_DIR}" 2>/dev/null
24
+ else
25
+ # Fallback: download tarball if git is not available
26
+ mkdir -p "${CLONE_DIR}"
27
+ curl -fsSL https://github.com/thanhan92-f1/clawspark/archive/refs/heads/main.tar.gz \
28
+ | tar xz --strip-components=1 -C "${CLONE_DIR}"
29
+ fi
30
+ # Re-exec from the cloned repo, reconnecting stdin to the terminal
31
+ # so interactive prompts work (curl pipe leaves stdin at EOF).
32
+ # Prefer Homebrew bash on macOS (system bash is 3.2, too old).
33
+ _REEXEC_BASH="bash"
34
+ if [[ "$(uname)" == "Darwin" ]]; then
35
+ if [[ -x /opt/homebrew/bin/bash ]]; then
36
+ _REEXEC_BASH=/opt/homebrew/bin/bash
37
+ elif [[ -x /usr/local/bin/bash ]]; then
38
+ _REEXEC_BASH=/usr/local/bin/bash
39
+ fi
40
+ fi
41
+ exec "${_REEXEC_BASH}" "${CLONE_DIR}/install.sh" "$@" </dev/tty
42
+ fi
43
+
44
+ # ── Parse command-line flags ────────────────────────────────────────────────
45
+ CLAWSPARK_DEFAULTS="${CLAWSPARK_DEFAULTS:-false}"
46
+ AIR_GAP="false"
47
+ FLAG_MODEL=""
48
+ FLAG_MESSAGING=""
49
+ DEPLOY_MODE=""
50
+
51
+ while [[ $# -gt 0 ]]; do
52
+ case "$1" in
53
+ --defaults)
54
+ CLAWSPARK_DEFAULTS="true"
55
+ shift ;;
56
+ --air-gap|--airgap)
57
+ AIR_GAP="true"
58
+ shift ;;
59
+ --model=*)
60
+ FLAG_MODEL="${1#*=}"
61
+ shift ;;
62
+ --messaging=*)
63
+ FLAG_MESSAGING="${1#*=}"
64
+ shift ;;
65
+ -h|--help)
66
+ cat <<HELP
67
+ Usage: install.sh [OPTIONS]
68
+
69
+ Options:
70
+ --defaults Skip all interactive prompts (use defaults)
71
+ --air-gap Enable air-gap mode after setup
72
+ --model=<id> Ollama model ID to use (e.g. qwen3.5:35b-a3b)
73
+ --messaging=<type> whatsapp | telegram | both | skip
74
+ -h, --help Show this help
75
+ HELP
76
+ exit 0 ;;
77
+ *)
78
+ echo "Unknown option: $1" >&2
79
+ exit 1 ;;
80
+ esac
81
+ done
82
+
83
+ export CLAWSPARK_DEFAULTS AIR_GAP FLAG_MODEL FLAG_MESSAGING DEPLOY_MODE
84
+
85
+ # ── Require bash 4.2+ (macOS ships 3.2 which lacks nameref, ${var,,}, etc.) ─
86
+ if [[ "${BASH_VERSINFO[0]}" -lt 4 ]] || { [[ "${BASH_VERSINFO[0]}" -eq 4 ]] && [[ "${BASH_VERSINFO[1]}" -lt 2 ]]; }; then
87
+ echo ""
88
+ echo "ERROR: Bash 4.2+ is required (you have ${BASH_VERSION})."
89
+ echo ""
90
+ if [[ "$(uname)" == "Darwin" ]]; then
91
+ echo "macOS ships with bash 3.2. Install modern bash with Homebrew:"
92
+ echo ""
93
+ echo " brew install bash"
94
+ echo ""
95
+ echo "Then re-run the installer with:"
96
+ echo ""
97
+ echo " /opt/homebrew/bin/bash <(curl -fsSL https://clawspark.hitechclaw.com/install.sh)"
98
+ echo ""
99
+ else
100
+ echo "Please install bash 4.2+ and re-run the installer."
101
+ fi
102
+ exit 1
103
+ fi
104
+
105
+ # ── Prepare clawspark directory ─────────────────────────────────────────────
106
+ CLAWSPARK_DIR="${HOME}/.clawspark"
107
+ mkdir -p "${CLAWSPARK_DIR}"
108
+ CLAWSPARK_LOG="${CLAWSPARK_DIR}/install.log"
109
+ : > "${CLAWSPARK_LOG}" # truncate / create log
110
+
111
+ # ── Source library modules ──────────────────────────────────────────────────
112
+ _source_lib() {
113
+ local lib_dir="${SCRIPT_DIR}/lib"
114
+
115
+ if [[ ! -d "${lib_dir}" ]]; then
116
+ echo "ERROR: Cannot find lib/ directory at ${lib_dir}" >&2
117
+ exit 1
118
+ fi
119
+
120
+ local f
121
+ for f in \
122
+ common.sh \
123
+ detect-hardware.sh \
124
+ select-model.sh \
125
+ setup-inference.sh \
126
+ setup-openclaw.sh \
127
+ setup-skills.sh \
128
+ setup-messaging.sh \
129
+ setup-voice.sh \
130
+ setup-tailscale.sh \
131
+ setup-dashboard.sh \
132
+ setup-models.sh \
133
+ setup-mcp.sh \
134
+ setup-browser.sh \
135
+ setup-sandbox.sh \
136
+ setup-systemd.sh \
137
+ secure.sh \
138
+ verify.sh \
139
+ ; do
140
+ if [[ -f "${lib_dir}/${f}" ]]; then
141
+ # shellcheck source=/dev/null
142
+ source "${lib_dir}/${f}"
143
+ else
144
+ echo "ERROR: Missing library file: ${lib_dir}/${f}" >&2
145
+ exit 1
146
+ fi
147
+ done
148
+
149
+ # Store lib location for the CLI tool later
150
+ CLAWSPARK_LIB_DIR="${lib_dir}"
151
+ }
152
+
153
+ _source_lib
154
+
155
+ # ── Error trap ──────────────────────────────────────────────────────────────
156
+ _on_error() {
157
+ local exit_code=$?
158
+ local line_no=$1
159
+ log_error "Installation failed at line ${line_no} (exit code ${exit_code})."
160
+ log_error "Check the log for details: ${CLAWSPARK_LOG}"
161
+ printf '\n %sIf this looks like a bug, please open an issue at:%s\n' "${YELLOW}" "${RESET}"
162
+ printf ' https://github.com/thanhan92-f1/clawspark/issues\n\n'
163
+ exit "${exit_code}"
164
+ }
165
+ trap '_on_error ${LINENO}' ERR
166
+
167
+ # ── Detect if stdin is a terminal (for curl-pipe support) ───────────────────
168
+ if [[ ! -t 0 ]]; then
169
+ # Piped from curl — force defaults mode if user can't interact
170
+ if [[ ! -t 1 ]]; then
171
+ CLAWSPARK_DEFAULTS="true"
172
+ fi
173
+ fi
174
+
175
+ # ── ASCII banner ────────────────────────────────────────────────────────────
176
+ _show_banner() {
177
+ printf '%s' "${RED}"
178
+ cat <<'BANNER'
179
+
180
+ ___ _ ___ __ __ ___ ___ ___ ___ _ __
181
+ / __|| | / \\ \ /\ / / / __|| _ \ / \ | _ \| |/ /
182
+ | (__ | |__ | (_) |\ V V / \__ \| _/ | (_) || /| <
183
+ \___||____| |\___/ \_/\_/ |___/|_| \___/ |_|_\|_|\_\
184
+ |_|
185
+ BANNER
186
+ printf '%s' "${RESET}"
187
+ printf '%s' "${CYAN}"
188
+ cat <<'CLAW'
189
+ _____
190
+ / \
191
+ / () () \
192
+ | .____. |
193
+ \ \__/ /
194
+ ___ \______/ ___
195
+ / '-..__ __..-'' \
196
+ / .--._ '' _.---. \
197
+ | / ___\ /___ \ |
198
+ | | ( \ / ) | |
199
+ \ \ '---'/\\'---' / /
200
+ '.\_ / \ _/.'
201
+ '---' '---'
202
+ CLAW
203
+ printf '%s' "${RESET}"
204
+ printf '\n'
205
+ printf ' %s%sOne-click AI agent setup for NVIDIA hardware%s\n' "${BOLD}" "${BLUE}" "${RESET}"
206
+ printf ' %sPowered by OpenClaw + Ollama%s\n\n' "${CYAN}" "${RESET}"
207
+ hr
208
+ }
209
+
210
+ # ── Step 1: Banner ─────────────────────────────────────────────────────────
211
+ log_info "Step 1/19: Welcome"
212
+ _show_banner
213
+
214
+ # ════════════════════════════════════════════════════════════════════════════
215
+ # INSTALLATION FLOW
216
+ # ════════════════════════════════════════════════════════════════════════════
217
+
218
+ # ── Cache sudo credentials upfront so the install never pauses for password ──
219
+ if sudo -v 2>/dev/null; then
220
+ log_info "sudo credentials cached."
221
+ # Keep sudo alive in background for the duration of the install
222
+ ( while true; do sudo -n true 2>/dev/null; sleep 50; done ) &
223
+ SUDO_KEEPALIVE_PID=$!
224
+ trap 'kill ${SUDO_KEEPALIVE_PID} 2>/dev/null; _on_error ${LINENO}' ERR
225
+ trap 'kill ${SUDO_KEEPALIVE_PID} 2>/dev/null' EXIT
226
+ else
227
+ log_warn "sudo not available. Some steps (firewall, systemd) will be skipped."
228
+ fi
229
+
230
+ # ── Step 2: Hardware detection ──────────────────────────────────────────────
231
+ log_info "Step 2/19: Detecting hardware"
232
+ detect_hardware
233
+
234
+ # ── Step 3: Model selection ─────────────────────────────────────────────────
235
+ log_info "Step 3/19: Selecting model"
236
+ select_model
237
+
238
+ # ── Step 4: Deployment mode ─────────────────────────────────────────────────
239
+ log_info "Step 4/19: Deployment mode"
240
+ if [[ -z "${DEPLOY_MODE}" ]]; then
241
+ if prompt_yn "Use cloud APIs as fallback? (requires API key)" "n"; then
242
+ DEPLOY_MODE="hybrid"
243
+ else
244
+ DEPLOY_MODE="local"
245
+ fi
246
+ fi
247
+ export DEPLOY_MODE
248
+ log_info "Deploy mode: ${DEPLOY_MODE}"
249
+
250
+ # ── Step 5: Messaging preference ───────────────────────────────────────────
251
+ log_info "Step 5/19: Messaging preference"
252
+ if [[ -z "${FLAG_MESSAGING}" ]]; then
253
+ msg_opts=("WhatsApp" "Telegram" "Both" "Skip")
254
+ FLAG_MESSAGING=$(prompt_choice "Connect a messaging platform? (Web UI is always available)" msg_opts 3)
255
+ fi
256
+ # Lowercase for consistent matching downstream
257
+ FLAG_MESSAGING=$(to_lower "${FLAG_MESSAGING}")
258
+ export FLAG_MESSAGING
259
+ log_info "Messaging: ${FLAG_MESSAGING}"
260
+
261
+ hr
262
+ printf '\n %s%sBeginning installation...%s\n\n' "${BOLD}" "${GREEN}" "${RESET}"
263
+
264
+ # ── Step 6: Inference engine ────────────────────────────────────────────────
265
+ log_info "Step 6/19: Setting up inference engine"
266
+ setup_inference
267
+
268
+ # ── Step 7: OpenClaw ────────────────────────────────────────────────────────
269
+ log_info "Step 7/19: Installing OpenClaw"
270
+ setup_openclaw
271
+
272
+ # ── Install the clawspark CLI early so it is available for troubleshooting ──
273
+ if [[ -f "${SCRIPT_DIR}/clawspark" ]]; then
274
+ sudo cp "${SCRIPT_DIR}/clawspark" /usr/local/bin/clawspark 2>/dev/null || {
275
+ cp "${SCRIPT_DIR}/clawspark" "${CLAWSPARK_DIR}/clawspark" 2>/dev/null || true
276
+ }
277
+ sudo chmod +x /usr/local/bin/clawspark 2>/dev/null || true
278
+ fi
279
+ if [[ -d "${SCRIPT_DIR}/lib" ]]; then
280
+ cp -r "${SCRIPT_DIR}/lib" "${CLAWSPARK_DIR}/"
281
+ fi
282
+ if [[ -d "${SCRIPT_DIR}/configs" ]]; then
283
+ cp -r "${SCRIPT_DIR}/configs" "${CLAWSPARK_DIR}/"
284
+ fi
285
+
286
+ # ── Step 8: Skills ──────────────────────────────────────────────────────────
287
+ log_info "Step 8/19: Installing skills"
288
+ setup_skills
289
+
290
+ # ── Step 9: Voice ──────────────────────────────────────────────────────────
291
+ log_info "Step 9/19: Setting up voice"
292
+ setup_voice
293
+
294
+ # ── Step 10: Messaging ─────────────────────────────────────────────────────
295
+ log_info "Step 10/19: Setting up messaging"
296
+ setup_messaging
297
+
298
+ # ── Step 11: Tailscale ─────────────────────────────────────────────────────
299
+ log_info "Step 11/19: Setting up Tailscale"
300
+ setup_tailscale
301
+
302
+ # ── Step 12: Dashboard ─────────────────────────────────────────────────────
303
+ log_info "Step 12/19: Setting up dashboard"
304
+ setup_dashboard || log_warn "Dashboard setup had issues -- continuing with install."
305
+
306
+ # ── Step 13: Vision & multi-model ──────────────────────────────────────────
307
+ log_info "Step 13/19: Configuring vision and multi-model support"
308
+ setup_models || log_warn "Model configuration had issues -- continuing."
309
+
310
+ # ── Step 14: MCP servers (diagrams, memory, reasoning) ───────────────────
311
+ log_info "Step 14/19: Setting up MCP servers"
312
+ setup_mcp || log_warn "MCP setup had issues -- continuing."
313
+
314
+ # ── Step 15: Browser automation ────────────────────────────────────────────
315
+ log_info "Step 15/19: Setting up browser automation"
316
+ setup_browser || log_warn "Browser setup had issues -- continuing."
317
+
318
+ # ── Step 16: Docker sandbox ────────────────────────────────────────────────
319
+ log_info "Step 16/19: Setting up Docker sandbox"
320
+ setup_sandbox || log_warn "Sandbox setup had issues -- continuing."
321
+
322
+ # ── Step 17: Systemd services ──────────────────────────────────────────────
323
+ log_info "Step 17/19: Creating systemd services for auto-start on boot"
324
+ setup_systemd_services || log_warn "Systemd setup had issues -- services will use PID management."
325
+
326
+ # ── Step 18: Security ──────────────────────────────────────────────────────
327
+ log_info "Step 18/19: Applying security"
328
+ secure_setup
329
+
330
+ # ── Start node host (after all config changes are done) ───────────────────
331
+ # Skip if systemd already started the node host (step 16)
332
+ if check_command systemctl && systemctl is-active --quiet clawspark-nodehost.service 2>/dev/null; then
333
+ log_info "Node host already running via systemd."
334
+ else
335
+ log_info "Starting node host..."
336
+ _start_node_host || log_warn "Node host failed to start -- you can start it with: clawspark start"
337
+ fi
338
+
339
+ # ── Step 18: Verification ──────────────────────────────────────────────────
340
+ log_info "Step 19/19: Verifying installation"
341
+ verify_installation
342
+
343
+ # ── Final CLI refresh (picks up any changes made during install) ──────────
344
+ if [[ -f "${SCRIPT_DIR}/clawspark" ]]; then
345
+ sudo cp "${SCRIPT_DIR}/clawspark" /usr/local/bin/clawspark 2>/dev/null || true
346
+ sudo chmod +x /usr/local/bin/clawspark 2>/dev/null || true
347
+ fi
348
+ [[ -d "${SCRIPT_DIR}/lib" ]] && cp -r "${SCRIPT_DIR}/lib" "${CLAWSPARK_DIR}/"
349
+ [[ -d "${SCRIPT_DIR}/configs" ]] && cp -r "${SCRIPT_DIR}/configs" "${CLAWSPARK_DIR}/"
350
+
351
+ # ── Final message ───────────────────────────────────────────────────────────
352
+ printf '\n'
353
+ hr
354
+ printf '\n'
355
+ printf ' %s%s' "${GREEN}" "${BOLD}"
356
+ cat <<'DONE'
357
+ __ __ _ _ _ _ _
358
+ \ \ / /___ _ _ ( )_ _ ___ __ _| | | ___ ___ | |_| |
359
+ \ V // _ \| || | |/| '_/ -_) / _` | | | (_-</ -_)| _|_|
360
+ |_| \___/ \_,_| |_| \___| \__,_|_|_| /__/\___| \__(_)
361
+ DONE
362
+ printf '%s\n' "${RESET}"
363
+
364
+ _final_urls=()
365
+ _final_urls+=("Chat UI: http://localhost:18789/__openclaw__/canvas/")
366
+ _final_urls+=("Dashboard: http://localhost:8900")
367
+ if [[ -f "${CLAWSPARK_DIR}/tailscale.url" ]]; then
368
+ _final_urls+=("Tailscale: $(cat "${CLAWSPARK_DIR}/tailscale.url")")
369
+ fi
370
+
371
+ print_box \
372
+ "${BOLD}Next Steps${RESET}" \
373
+ "" \
374
+ "${_final_urls[@]}" \
375
+ "" \
376
+ "1. Open the Chat UI in your browser to talk to your agent" \
377
+ "2. Or send a message via WhatsApp or Telegram" \
378
+ "3. Manage your setup: ${CYAN}clawspark status${RESET}" \
379
+ "4. Install skill packs: ${CYAN}clawspark skills pack research${RESET}" \
380
+ "5. Switch models: ${CYAN}clawspark model list${RESET}" \
381
+ "6. Enable sandbox: ${CYAN}clawspark sandbox on${RESET}" \
382
+ "7. View logs: ${CYAN}clawspark logs${RESET}" \
383
+ "" \
384
+ "Services auto-start on boot (systemd)." \
385
+ "Full log: ${CLAWSPARK_LOG}"
386
+
387
+ printf '\n %sHappy hacking!%s\n\n' "${CYAN}" "${RESET}"
@@ -0,0 +1,11 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 256" width="256" height="256">
2
+ <!-- No background - transparent for website use -->
3
+
4
+ <!-- C shape -->
5
+ <path d="M 158 48 C 110 35, 48 65, 48 128 C 48 191, 110 221, 158 208"
6
+ stroke="#76B900" stroke-width="22" stroke-linecap="round" fill="none"/>
7
+
8
+ <!-- Bolt inside the C -->
9
+ <polygon points="145,72 120,122 142,122 118,178 152,128 130,128 155,72"
10
+ fill="#E85D3A"/>
11
+ </svg>
@@ -0,0 +1,12 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 256" width="256" height="256">
2
+ <!-- Background -->
3
+ <rect width="256" height="256" rx="40" fill="#0d1117"/>
4
+
5
+ <!-- C shape -->
6
+ <path d="M 158 48 C 110 35, 48 65, 48 128 C 48 191, 110 221, 158 208"
7
+ stroke="#76B900" stroke-width="22" stroke-linecap="round" fill="none"/>
8
+
9
+ <!-- Bolt inside the C -->
10
+ <polygon points="145,72 120,122 142,122 118,178 152,128 130,128 155,72"
11
+ fill="#E85D3A"/>
12
+ </svg>
package/web/logo.svg ADDED
@@ -0,0 +1,17 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" width="512" height="512">
2
+ <!-- Background -->
3
+ <rect width="512" height="512" rx="80" fill="#0d1117"/>
4
+
5
+ <!-- C shape - bold, open on the right -->
6
+ <path d="M 300 120 C 220 100, 120 140, 120 250 C 120 360, 220 400, 300 380"
7
+ stroke="#76B900" stroke-width="36" stroke-linecap="round" fill="none"/>
8
+
9
+ <!-- Bolt inside the C -->
10
+ <polygon points="270,160 230,245 265,245 225,340 285,255 250,255 290,160"
11
+ fill="#E85D3A"/>
12
+
13
+ <!-- Text -->
14
+ <text x="256" y="460" text-anchor="middle" font-family="system-ui, -apple-system, 'Segoe UI', sans-serif" font-weight="700" font-size="48" letter-spacing="3">
15
+ <tspan fill="#76B900">claw</tspan><tspan fill="#E85D3A">spark</tspan>
16
+ </text>
17
+ </svg>
@@ -0,0 +1,8 @@
1
+ {
2
+ "rewrites": [
3
+ {
4
+ "source": "/install.sh",
5
+ "destination": "https://raw.githubusercontent.com/thanhan92-f1/clawspark/main/install.sh"
6
+ }
7
+ ]
8
+ }