Spaces:
Paused
Paused
Clawd Computer: web-based homebase computer (ttyd + nginx + toolbelt)
Browse files- Dockerfile +47 -0
- README.md +41 -4
- nginx.conf +41 -0
- supervisord.conf +17 -0
- web/index.html +136 -0
- welcome.sh +16 -0
Dockerfile
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Clawd Computer — a real web-based computer for the Clawd agents
|
| 2 |
+
FROM debian:bookworm-slim
|
| 3 |
+
|
| 4 |
+
ENV DEBIAN_FRONTEND=noninteractive \
|
| 5 |
+
HOME=/home/user \
|
| 6 |
+
PATH=/home/user/.local/bin:/usr/local/bin:$PATH \
|
| 7 |
+
PYTHONUNBUFFERED=1
|
| 8 |
+
|
| 9 |
+
# Core userland + tools the agents reach for
|
| 10 |
+
RUN apt-get update && apt-get install -y --no-install-recommends \
|
| 11 |
+
ca-certificates curl wget git jq ripgrep nano vim less \
|
| 12 |
+
build-essential python3 python3-pip python3-venv \
|
| 13 |
+
nginx supervisor ttyd locales tini \
|
| 14 |
+
&& sed -i 's/# en_US.UTF-8 UTF-8/en_US.UTF-8 UTF-8/' /etc/locale.gen && locale-gen \
|
| 15 |
+
&& rm -rf /var/lib/apt/lists/*
|
| 16 |
+
|
| 17 |
+
ENV LANG=en_US.UTF-8 LC_ALL=en_US.UTF-8
|
| 18 |
+
|
| 19 |
+
# Node.js 20 (NodeSource)
|
| 20 |
+
RUN curl -fsSL https://deb.nodesource.com/setup_20.x | bash - \
|
| 21 |
+
&& apt-get install -y --no-install-recommends nodejs \
|
| 22 |
+
&& rm -rf /var/lib/apt/lists/*
|
| 23 |
+
|
| 24 |
+
# Hugging Face CLI
|
| 25 |
+
RUN pip3 install --no-cache-dir --break-system-packages huggingface_hub
|
| 26 |
+
|
| 27 |
+
# Non-root user (HF Spaces run as uid 1000)
|
| 28 |
+
RUN useradd -m -u 1000 user || true
|
| 29 |
+
|
| 30 |
+
# nginx must be writable/runnable by uid 1000
|
| 31 |
+
RUN mkdir -p /var/lib/nginx /var/log/nginx /run \
|
| 32 |
+
&& chown -R user:user /var/lib/nginx /var/log/nginx /run /etc/nginx
|
| 33 |
+
|
| 34 |
+
COPY --chown=user:user nginx.conf /etc/nginx/nginx.conf
|
| 35 |
+
COPY --chown=user:user supervisord.conf /etc/supervisor/conf.d/supervisord.conf
|
| 36 |
+
COPY --chown=user:user web/ /home/user/web/
|
| 37 |
+
COPY --chown=user:user welcome.sh /home/user/welcome.sh
|
| 38 |
+
|
| 39 |
+
RUN chmod +x /home/user/welcome.sh
|
| 40 |
+
|
| 41 |
+
USER user
|
| 42 |
+
WORKDIR /home/user/app
|
| 43 |
+
|
| 44 |
+
EXPOSE 7860
|
| 45 |
+
|
| 46 |
+
ENTRYPOINT ["/usr/bin/tini", "--"]
|
| 47 |
+
CMD ["/usr/bin/supervisord", "-c", "/etc/supervisor/conf.d/supervisord.conf"]
|
README.md
CHANGED
|
@@ -1,10 +1,47 @@
|
|
| 1 |
---
|
| 2 |
title: Clawd Computer
|
| 3 |
-
emoji:
|
| 4 |
colorFrom: purple
|
| 5 |
-
colorTo:
|
| 6 |
sdk: docker
|
| 7 |
-
|
|
|
|
|
|
|
|
|
|
| 8 |
---
|
| 9 |
|
| 10 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
---
|
| 2 |
title: Clawd Computer
|
| 3 |
+
emoji: 🐾
|
| 4 |
colorFrom: purple
|
| 5 |
+
colorTo: indigo
|
| 6 |
sdk: docker
|
| 7 |
+
app_port: 7860
|
| 8 |
+
pinned: true
|
| 9 |
+
license: mit
|
| 10 |
+
short_description: Web-based computer + live terminal for Clawd agents
|
| 11 |
---
|
| 12 |
|
| 13 |
+
# 🐾 Clawd Computer
|
| 14 |
+
|
| 15 |
+
A **real, browser-accessible computer** for the [Clawd](https://huggingface.co/solanaclawd) agents — the homebase on Hugging Face.
|
| 16 |
+
|
| 17 |
+
It is a Docker Space that boots a full Debian userland with a live web terminal (`ttyd`) and a landing console served by `nginx`. Pre-loaded with the tools the agents reach for: Python, Node.js, git, the Hugging Face `hf` CLI, ripgrep, jq, and more.
|
| 18 |
+
|
| 19 |
+
## What's inside
|
| 20 |
+
|
| 21 |
+
| Layer | Tool |
|
| 22 |
+
|-------|------|
|
| 23 |
+
| Web terminal | [`ttyd`](https://github.com/tsl0922/ttyd) → bash |
|
| 24 |
+
| Reverse proxy | `nginx` (serves landing + websocket-proxies the terminal) |
|
| 25 |
+
| Process manager | `supervisord` |
|
| 26 |
+
| Runtime | Python 3, Node.js 20, git, curl, jq, ripgrep, `hf` CLI |
|
| 27 |
+
|
| 28 |
+
## Layout
|
| 29 |
+
|
| 30 |
+
- `/` — the homebase landing console
|
| 31 |
+
- `/terminal/` — the live interactive terminal
|
| 32 |
+
|
| 33 |
+
## Run it locally
|
| 34 |
+
|
| 35 |
+
```bash
|
| 36 |
+
docker build -t clawd-computer .
|
| 37 |
+
docker run -p 7860:7860 clawd-computer
|
| 38 |
+
# open http://localhost:7860
|
| 39 |
+
```
|
| 40 |
+
|
| 41 |
+
## Secrets
|
| 42 |
+
|
| 43 |
+
Set `HF_TOKEN` (and any other keys) in the Space **Settings → Secrets**. They are injected as environment variables at runtime and are available inside the terminal.
|
| 44 |
+
|
| 45 |
+
---
|
| 46 |
+
|
| 47 |
+
Part of the **Clawd** homebase on Hugging Face. 🐾
|
nginx.conf
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
worker_processes 1;
|
| 2 |
+
error_log /var/log/nginx/error.log warn;
|
| 3 |
+
pid /run/nginx.pid;
|
| 4 |
+
|
| 5 |
+
events { worker_connections 1024; }
|
| 6 |
+
|
| 7 |
+
http {
|
| 8 |
+
include /etc/nginx/mime.types;
|
| 9 |
+
default_type application/octet-stream;
|
| 10 |
+
access_log /var/log/nginx/access.log;
|
| 11 |
+
sendfile on;
|
| 12 |
+
|
| 13 |
+
map $http_upgrade $connection_upgrade {
|
| 14 |
+
default upgrade;
|
| 15 |
+
'' close;
|
| 16 |
+
}
|
| 17 |
+
|
| 18 |
+
server {
|
| 19 |
+
listen 7860;
|
| 20 |
+
server_name _;
|
| 21 |
+
|
| 22 |
+
root /home/user/web;
|
| 23 |
+
index index.html;
|
| 24 |
+
|
| 25 |
+
# Homebase landing
|
| 26 |
+
location / {
|
| 27 |
+
try_files $uri $uri/ =404;
|
| 28 |
+
}
|
| 29 |
+
|
| 30 |
+
# Live web terminal (ttyd on 7681)
|
| 31 |
+
location /terminal/ {
|
| 32 |
+
proxy_pass http://127.0.0.1:7681/;
|
| 33 |
+
proxy_http_version 1.1;
|
| 34 |
+
proxy_set_header Upgrade $http_upgrade;
|
| 35 |
+
proxy_set_header Connection $connection_upgrade;
|
| 36 |
+
proxy_set_header Host $host;
|
| 37 |
+
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
| 38 |
+
proxy_read_timeout 86400;
|
| 39 |
+
}
|
| 40 |
+
}
|
| 41 |
+
}
|
supervisord.conf
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
[supervisord]
|
| 2 |
+
nodaemon=true
|
| 3 |
+
user=user
|
| 4 |
+
logfile=/var/log/nginx/supervisord.log
|
| 5 |
+
pidfile=/run/supervisord.pid
|
| 6 |
+
|
| 7 |
+
[program:ttyd]
|
| 8 |
+
command=ttyd -p 7681 -i 127.0.0.1 -W -t fontSize=15 -t 'theme={"background":"#11071f"}' bash -lc "cd /home/user/app && /home/user/welcome.sh && exec bash"
|
| 9 |
+
autorestart=true
|
| 10 |
+
stdout_logfile=/var/log/nginx/ttyd.log
|
| 11 |
+
stderr_logfile=/var/log/nginx/ttyd.err.log
|
| 12 |
+
|
| 13 |
+
[program:nginx]
|
| 14 |
+
command=nginx -g "daemon off;"
|
| 15 |
+
autorestart=true
|
| 16 |
+
stdout_logfile=/var/log/nginx/nginx.out.log
|
| 17 |
+
stderr_logfile=/var/log/nginx/nginx.err.log
|
web/index.html
ADDED
|
@@ -0,0 +1,136 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<!DOCTYPE html>
|
| 2 |
+
<html lang="en">
|
| 3 |
+
<head>
|
| 4 |
+
<meta charset="UTF-8" />
|
| 5 |
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
| 6 |
+
<title>Clawd Computer 🐾</title>
|
| 7 |
+
<style>
|
| 8 |
+
:root {
|
| 9 |
+
--bg: #0a0612;
|
| 10 |
+
--panel: #150a26;
|
| 11 |
+
--panel-2: #1d0f33;
|
| 12 |
+
--accent: #a779ff;
|
| 13 |
+
--accent-2: #6c4bd6;
|
| 14 |
+
--text: #ece6ff;
|
| 15 |
+
--muted: #9a8cc0;
|
| 16 |
+
--border: #2a1a47;
|
| 17 |
+
}
|
| 18 |
+
* { box-sizing: border-box; margin: 0; padding: 0; }
|
| 19 |
+
body {
|
| 20 |
+
font-family: ui-monospace, "SF Mono", "JetBrains Mono", Menlo, monospace;
|
| 21 |
+
background: radial-gradient(1200px 600px at 70% -10%, #2a1252 0%, var(--bg) 60%);
|
| 22 |
+
color: var(--text);
|
| 23 |
+
min-height: 100vh;
|
| 24 |
+
display: flex;
|
| 25 |
+
flex-direction: column;
|
| 26 |
+
}
|
| 27 |
+
header {
|
| 28 |
+
padding: 22px 28px;
|
| 29 |
+
display: flex;
|
| 30 |
+
align-items: center;
|
| 31 |
+
gap: 14px;
|
| 32 |
+
border-bottom: 1px solid var(--border);
|
| 33 |
+
background: rgba(21,10,38,0.6);
|
| 34 |
+
backdrop-filter: blur(8px);
|
| 35 |
+
}
|
| 36 |
+
header .logo { font-size: 30px; }
|
| 37 |
+
header h1 { font-size: 18px; letter-spacing: 0.5px; }
|
| 38 |
+
header h1 span { color: var(--accent); }
|
| 39 |
+
header .spacer { flex: 1; }
|
| 40 |
+
header a.badge {
|
| 41 |
+
color: var(--muted); text-decoration: none; font-size: 13px;
|
| 42 |
+
border: 1px solid var(--border); padding: 6px 12px; border-radius: 8px;
|
| 43 |
+
transition: 0.2s;
|
| 44 |
+
}
|
| 45 |
+
header a.badge:hover { color: var(--text); border-color: var(--accent); }
|
| 46 |
+
main {
|
| 47 |
+
flex: 1;
|
| 48 |
+
display: grid;
|
| 49 |
+
grid-template-columns: 300px 1fr;
|
| 50 |
+
gap: 18px;
|
| 51 |
+
padding: 18px 22px 22px;
|
| 52 |
+
}
|
| 53 |
+
@media (max-width: 820px) { main { grid-template-columns: 1fr; } }
|
| 54 |
+
.sidebar { display: flex; flex-direction: column; gap: 14px; }
|
| 55 |
+
.card {
|
| 56 |
+
background: linear-gradient(160deg, var(--panel) 0%, var(--panel-2) 100%);
|
| 57 |
+
border: 1px solid var(--border);
|
| 58 |
+
border-radius: 14px;
|
| 59 |
+
padding: 16px 18px;
|
| 60 |
+
}
|
| 61 |
+
.card h2 { font-size: 12px; text-transform: uppercase; letter-spacing: 1px; color: var(--muted); margin-bottom: 10px; }
|
| 62 |
+
.card p { font-size: 13px; color: var(--text); line-height: 1.6; }
|
| 63 |
+
.pill { display:inline-block; font-size:11px; color:var(--accent); background:rgba(167,121,255,0.12);
|
| 64 |
+
border:1px solid var(--accent-2); padding:3px 9px; border-radius:20px; margin:3px 4px 0 0; }
|
| 65 |
+
.terminal-wrap {
|
| 66 |
+
border: 1px solid var(--border);
|
| 67 |
+
border-radius: 14px;
|
| 68 |
+
overflow: hidden;
|
| 69 |
+
background: #11071f;
|
| 70 |
+
display: flex;
|
| 71 |
+
flex-direction: column;
|
| 72 |
+
min-height: 520px;
|
| 73 |
+
}
|
| 74 |
+
.term-bar {
|
| 75 |
+
display: flex; align-items: center; gap: 8px;
|
| 76 |
+
padding: 10px 14px; background: #1a0d30; border-bottom: 1px solid var(--border);
|
| 77 |
+
}
|
| 78 |
+
.term-bar .dot { width: 11px; height: 11px; border-radius: 50%; }
|
| 79 |
+
.d1 { background:#ff5f56; } .d2 { background:#ffbd2e; } .d3 { background:#27c93f; }
|
| 80 |
+
.term-bar .title { margin-left: 8px; font-size: 12px; color: var(--muted); }
|
| 81 |
+
iframe { border: 0; width: 100%; flex: 1; min-height: 480px; background:#11071f; }
|
| 82 |
+
footer { padding: 14px 28px; border-top: 1px solid var(--border); color: var(--muted); font-size: 12px; text-align:center; }
|
| 83 |
+
footer a { color: var(--accent); text-decoration: none; }
|
| 84 |
+
</style>
|
| 85 |
+
</head>
|
| 86 |
+
<body>
|
| 87 |
+
<header>
|
| 88 |
+
<span class="logo">🐾</span>
|
| 89 |
+
<h1>Clawd <span>Computer</span></h1>
|
| 90 |
+
<div class="spacer"></div>
|
| 91 |
+
<a class="badge" href="https://huggingface.co/solanaclawd" target="_blank">solanaclawd org ↗</a>
|
| 92 |
+
<a class="badge" href="/terminal/" target="_blank">open terminal ↗</a>
|
| 93 |
+
</header>
|
| 94 |
+
|
| 95 |
+
<main>
|
| 96 |
+
<div class="sidebar">
|
| 97 |
+
<div class="card">
|
| 98 |
+
<h2>Homebase</h2>
|
| 99 |
+
<p>A real, browser-accessible computer for the Clawd agents — running on Hugging Face Spaces.</p>
|
| 100 |
+
</div>
|
| 101 |
+
<div class="card">
|
| 102 |
+
<h2>Toolbelt</h2>
|
| 103 |
+
<div>
|
| 104 |
+
<span class="pill">python3</span><span class="pill">node 20</span>
|
| 105 |
+
<span class="pill">git</span><span class="pill">hf cli</span>
|
| 106 |
+
<span class="pill">jq</span><span class="pill">ripgrep</span>
|
| 107 |
+
<span class="pill">bash</span><span class="pill">curl</span>
|
| 108 |
+
</div>
|
| 109 |
+
</div>
|
| 110 |
+
<div class="card">
|
| 111 |
+
<h2>Quick start</h2>
|
| 112 |
+
<p>In the terminal →<br>
|
| 113 |
+
<code>hf auth whoami</code><br>
|
| 114 |
+
<code>hf models ls --author solanaclawd</code><br>
|
| 115 |
+
<code>python3 --version</code></p>
|
| 116 |
+
</div>
|
| 117 |
+
<div class="card">
|
| 118 |
+
<h2>Secrets</h2>
|
| 119 |
+
<p>Set <code>HF_TOKEN</code> in <em>Settings → Secrets</em>. It's injected as an env var in the terminal.</p>
|
| 120 |
+
</div>
|
| 121 |
+
</div>
|
| 122 |
+
|
| 123 |
+
<div class="terminal-wrap">
|
| 124 |
+
<div class="term-bar">
|
| 125 |
+
<span class="dot d1"></span><span class="dot d2"></span><span class="dot d3"></span>
|
| 126 |
+
<span class="title">clawd@homebase: ~/app</span>
|
| 127 |
+
</div>
|
| 128 |
+
<iframe src="/terminal/" title="Clawd Computer terminal"></iframe>
|
| 129 |
+
</div>
|
| 130 |
+
</main>
|
| 131 |
+
|
| 132 |
+
<footer>
|
| 133 |
+
🐾 Clawd Computer · part of the <a href="https://huggingface.co/solanaclawd">Clawd</a> homebase on Hugging Face
|
| 134 |
+
</footer>
|
| 135 |
+
</body>
|
| 136 |
+
</html>
|
welcome.sh
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env bash
|
| 2 |
+
cat <<'BANNER'
|
| 3 |
+
____ _ _ ____ _
|
| 4 |
+
/ ___| | __ ___ ____| | / ___|___ _ __ ___ _ __ _ _| |_ ___ _ __
|
| 5 |
+
| | | |/ _` \ \ /\ / / _` | | | / _ \| '_ ` _ \| '_ \| | | | __/ _ \ '__|
|
| 6 |
+
| |___| | (_| |\ V V / (_| | | |__| (_) | | | | | | |_) | |_| | || __/ |
|
| 7 |
+
\____|_|\__,_| \_/\_/ \__,_| \____\___/|_| |_| |_| .__/ \__,_|\__\___|_|
|
| 8 |
+
|_|
|
| 9 |
+
BANNER
|
| 10 |
+
echo ""
|
| 11 |
+
echo " 🐾 Welcome to the Clawd Computer — homebase on Hugging Face"
|
| 12 |
+
echo " ----------------------------------------------------------"
|
| 13 |
+
echo " Pre-installed: python3 · node $(node -v 2>/dev/null) · git · hf · jq · rg"
|
| 14 |
+
echo " HF CLI: run 'hf auth whoami' (set HF_TOKEN in Space secrets)"
|
| 15 |
+
echo " Org: https://huggingface.co/solanaclawd"
|
| 16 |
+
echo ""
|