static-files
Host static files on subdomains with optional authentication. Use when you need to serve HTML, images, CSS, JS, or any static content on a dedicated subdomain. Supports file upload, basic auth, quota management, and automatic SSL via Caddy. Commands include sf sites (create/list/delete), sf upload (files/directories), sf files (list/delete).
Packaged view
This page reorganizes the original catalog entry around fit, installability, and workflow context first. The original raw source lives below.
Install command
npx @skill-hub/cli install openclaw-skills-kleo-static-files
Repository
Skill path: skills/awaaate/kleo-static-files
Host static files on subdomains with optional authentication. Use when you need to serve HTML, images, CSS, JS, or any static content on a dedicated subdomain. Supports file upload, basic auth, quota management, and automatic SSL via Caddy. Commands include sf sites (create/list/delete), sf upload (files/directories), sf files (list/delete).
Open repositoryBest for
Primary workflow: Write Technical Docs.
Technical facets: Full Stack, Tech Writer, Security.
Target audience: everyone.
License: Unknown.
Original source
Catalog source: SkillHub Club.
Repository owner: openclaw.
This is still a mirrored public skill entry. Review the repository before installing into production workflows.
What it helps with
- Install static-files into Claude Code, Codex CLI, Gemini CLI, or OpenCode workflows
- Review https://github.com/openclaw/skills before adding static-files to shared team environments
- Use static-files for development workflows
Works across
Favorites: 0.
Sub-skills: 0.
Aggregator: No.
Original source / Raw SKILL.md
---
name: static-files
description: >
Host static files on subdomains with optional authentication. Use when you need to
serve HTML, images, CSS, JS, or any static content on a dedicated subdomain. Supports
file upload, basic auth, quota management, and automatic SSL via Caddy. Commands
include sf sites (create/list/delete), sf upload (files/directories), sf files (list/delete).
---
# Static Files Hosting
Host static content on `*.{domain}` subdomains with automatic SSL.
## Quick Reference
```bash
# Create site
sf sites create mysite
# → https://mysite.498as.com
# Upload file
sf upload ./index.html mysite
# Upload directory
sf upload ./dist mysite
# Add authentication
sf sites auth mysite admin:secretpass123
# List files
sf files mysite
# Delete file
sf files mysite delete path/to/file.txt
# Delete site
sf sites delete mysite
```
## Environment Setup
```bash
export SF_API_URL=http://localhost:3000 # API endpoint
export SF_API_KEY=sk_xxxxx # Your API key
```
## Workflows
### Deploy a Static Website
```bash
# 1. Create the site
sf sites create docs
# 2. Upload the build directory
sf upload ./build docs
# 3. Verify
curl -I https://docs.498as.com
```
### Protected File Sharing
```bash
# 1. Create site with auth
sf sites create private
sf sites auth private user:strongpassword
# 2. Upload sensitive files
sf upload ./reports private
# 3. Share URL + credentials
# https://private.498as.com (user / strongpassword)
```
### Update Existing Files
```bash
# Overwrite existing file
sf upload ./new-version.pdf mysite --overwrite
# Or delete and re-upload
sf files mysite delete old-file.pdf
sf upload ./new-file.pdf mysite
```
## CLI Commands
### sites
| Command | Description |
|---------|-------------|
| `sf sites list` | List all sites |
| `sf sites create <name>` | Create new site |
| `sf sites delete <name>` | Delete site and all files |
| `sf sites auth <name> <user:pass>` | Set basic auth |
| `sf sites auth <name> --remove` | Remove auth |
### upload
```bash
sf upload <path> <site> [subdir] [--overwrite] [--json]
```
- `path`: File or directory to upload
- `site`: Target site name
- `subdir`: Optional subdirectory
- `--overwrite`: Replace existing files
- `--json`: Output JSON
### files
| Command | Description |
|---------|-------------|
| `sf files <site>` | List all files |
| `sf files <site> delete <path>` | Delete specific file |
### stats
```bash
sf stats # Global stats
sf stats <site> # Site-specific stats
```
## API Endpoints
Base: `$SF_API_URL` with `Authorization: Bearer $SF_API_KEY`
| Method | Path | Description |
|--------|------|-------------|
| GET | `/sites` | List sites |
| POST | `/sites` | Create site |
| DELETE | `/sites/{name}` | Delete site |
| PATCH | `/sites/{name}` | Update auth |
| GET | `/sites/{name}/files` | List files |
| POST | `/sites/{name}/files` | Upload file |
| DELETE | `/sites/{name}/files/{path}` | Delete file |
| GET | `/stats` | Global stats |
| GET | `/stats/{name}` | Site stats |
| GET | `/health` | Health check |
## Constraints
- **Site names**: lowercase, alphanumeric, hyphens only (max 63 chars)
- **File size**: 50MB default (configurable)
- **Quota**: 100MB per site default
- **Rate limit**: 100 requests/minute per API key
## Troubleshooting
### "Cannot connect to API"
```bash
# Check service status
systemctl status kleo-static-files
# Check if port is listening
curl http://localhost:3000/health
```
### "Invalid API key"
```bash
# Verify key is set
echo $SF_API_KEY
# Create new key if needed
bun run /opt/kleo-static-files/scripts/create-key.ts "new-key"
```
### "Quota exceeded"
```bash
# Check current usage
sf stats mysite
# Delete unused files
sf files mysite delete large-file.zip
```
### Site not accessible via HTTPS
```bash
# Verify DNS points to server
dig mysite.498as.com
# Check Caddy config
cat /etc/caddy/sites.d/static-files.caddy
# Resync Caddy
bun run /opt/kleo-static-files/scripts/sync-caddy.ts --reload
```
## Installation
### Server Installation (run once on host)
```bash
curl -fsSL https://raw.githubusercontent.com/498AS/kleo-static-files/main/install.sh | sudo bash
```
The installer outputs JSON with connection details between `KLEO_SF_CONFIG_BEGIN` and `KLEO_SF_CONFIG_END` markers. Parse this to get `api_url` and `api_key`.
### After Installation
```bash
export SF_API_URL=http://localhost:3000
export SF_API_KEY=sk_xxxxx # from installer output
```
### Check Status
```bash
sudo /opt/kleo-static-files/install.sh --status
```
See [references/install.md](references/install.md) for manual installation.
---
## Referenced Files
> The following files are referenced in this skill and included for context.
### references/install.md
```markdown
# Installation Guide
## Requirements
- Linux server (Ubuntu/Debian recommended)
- [Bun](https://bun.sh) runtime
- [Caddy](https://caddyserver.com) web server
- Git
## Quick Install
```bash
curl -fsSL https://raw.githubusercontent.com/498AS/kleo-static-files/main/install.sh | sudo bash
```
## Manual Install
### 1. Install Dependencies
```bash
# Bun
curl -fsSL https://bun.sh/install | bash
# Caddy (Ubuntu/Debian)
sudo apt install -y debian-keyring debian-archive-keyring apt-transport-https
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | sudo gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' | sudo tee /etc/apt/sources.list.d/caddy-stable.list
sudo apt update && sudo apt install caddy
```
### 2. Clone Repository
```bash
sudo git clone https://github.com/498AS/kleo-static-files.git /opt/kleo-static-files
cd /opt/kleo-static-files
bun install
```
### 3. Configure
Create `/opt/kleo-static-files/.env`:
```bash
SF_PORT=3000
SF_DOMAIN=yourdomain.com
SF_SITES_ROOT=/var/lib/kleo-static-files/sites
SF_DB_PATH=/var/lib/kleo-static-files/data/static-files.db
SF_CADDY_SNIPPET=/etc/caddy/sites.d/static-files.caddy
SF_BIND_IPS=YOUR_SERVER_IP
# Limits
SF_RATE_LIMIT_WINDOW=60000
SF_RATE_LIMIT_MAX=100
SF_MAX_FILE_MB=50
```
### 4. Create Directories
```bash
sudo mkdir -p /var/lib/kleo-static-files/{data,sites}
sudo mkdir -p /etc/caddy/sites.d
sudo mkdir -p /var/log/caddy
```
### 5. Update Caddyfile
Add to `/etc/caddy/Caddyfile`:
```caddy
import /etc/caddy/sites.d/*.caddy
```
### 6. Create Systemd Service
Create `/etc/systemd/system/kleo-static-files.service`:
```ini
[Unit]
Description=Kleo Static Files API
After=network.target caddy.service
[Service]
Type=simple
WorkingDirectory=/opt/kleo-static-files
EnvironmentFile=/opt/kleo-static-files/.env
ExecStart=/root/.bun/bin/bun run server/index.ts
ExecStartPost=/opt/kleo-static-files/scripts/sync-caddy.ts --reload
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
```
### 7. Start Service
```bash
sudo systemctl daemon-reload
sudo systemctl enable kleo-static-files
sudo systemctl start kleo-static-files
```
### 8. Create API Key
```bash
cd /opt/kleo-static-files
source .env
bun run scripts/create-key.ts "admin"
# Save the key!
```
## DNS Setup
For each subdomain to work, configure a wildcard DNS record:
| Type | Name | Value |
|------|------|-------|
| A | *.yourdomain.com | YOUR_SERVER_IP |
| AAAA | *.yourdomain.com | YOUR_IPV6 (optional) |
## Verification
```bash
# Check service
systemctl status kleo-static-files
# Check API
curl http://localhost:3000/health
# Test site creation
export SF_API_URL=http://localhost:3000
export SF_API_KEY=sk_your_key
sf sites create test
curl -I https://test.yourdomain.com
```
## Uninstall
```bash
sudo /opt/kleo-static-files/install.sh --uninstall
```
```
---
## Skill Companion Files
> Additional files collected from the skill directory layout.
### _meta.json
```json
{
"owner": "awaaate",
"slug": "kleo-static-files",
"displayName": "Kleo Static files",
"latest": {
"version": "1.0.0",
"publishedAt": 1769885567722,
"commit": "https://github.com/clawdbot/skills/commit/ec71a5e9000eda73893b312f110acb6410df15c6"
},
"history": []
}
```
### scripts/sf-helper.sh
```bash
#!/bin/bash
#
# sf-helper.sh - Static Files helper for AI agents
#
# Provides high-level operations that combine multiple sf commands.
#
# Usage: sf-helper.sh <command> [args]
#
set -e
# Ensure sf is available (it's just the CLI)
SF_CLI="${SF_CLI:-sf}"
# Check environment
check_env() {
if [ -z "$SF_API_URL" ] || [ -z "$SF_API_KEY" ]; then
echo "Error: SF_API_URL and SF_API_KEY must be set"
echo ""
echo "Example:"
echo " export SF_API_URL=http://localhost:3000"
echo " export SF_API_KEY=sk_xxxxx"
exit 1
fi
}
# Deploy a directory as a new site
# Usage: sf-helper.sh deploy <site-name> <directory> [--auth user:pass]
cmd_deploy() {
local site="$1"
local dir="$2"
local auth="$3"
if [ -z "$site" ] || [ -z "$dir" ]; then
echo "Usage: sf-helper.sh deploy <site-name> <directory> [user:pass]"
exit 1
fi
if [ ! -d "$dir" ]; then
echo "Error: Directory not found: $dir"
exit 1
fi
echo "Deploying $dir to $site..."
# Create site if it doesn't exist
if ! $SF_CLI sites list --json 2>/dev/null | grep -q "\"name\":\"$site\""; then
echo "Creating site: $site"
$SF_CLI sites create "$site"
fi
# Set auth if provided
if [ -n "$auth" ]; then
echo "Setting authentication..."
$SF_CLI sites auth "$site" "$auth"
fi
# Upload directory
echo "Uploading files..."
$SF_CLI upload "$dir" "$site" --overwrite
echo ""
echo "Deployed! URL: https://$site.$SF_DOMAIN"
}
# Clean deploy - delete existing files before uploading
# Usage: sf-helper.sh clean-deploy <site-name> <directory>
cmd_clean_deploy() {
local site="$1"
local dir="$2"
if [ -z "$site" ] || [ -z "$dir" ]; then
echo "Usage: sf-helper.sh clean-deploy <site-name> <directory>"
exit 1
fi
echo "Clean deploying $dir to $site..."
# Delete and recreate site
$SF_CLI sites delete "$site" 2>/dev/null || true
$SF_CLI sites create "$site"
# Upload
$SF_CLI upload "$dir" "$site"
echo ""
echo "Deployed! URL: https://$site.$SF_DOMAIN"
}
# Quick share - upload a single file and return URL
# Usage: sf-helper.sh share <file> [site-name]
cmd_share() {
local file="$1"
local site="${2:-quick-share}"
if [ -z "$file" ]; then
echo "Usage: sf-helper.sh share <file> [site-name]"
exit 1
fi
if [ ! -f "$file" ]; then
echo "Error: File not found: $file"
exit 1
fi
# Create site if needed
if ! $SF_CLI sites list --json 2>/dev/null | grep -q "\"name\":\"$site\""; then
$SF_CLI sites create "$site" >/dev/null
fi
# Upload and get URL
local filename=$(basename "$file")
$SF_CLI upload "$file" "$site" --overwrite >/dev/null
echo "https://$site.${SF_DOMAIN:-498as.com}/$filename"
}
# List all sites with their URLs
# Usage: sf-helper.sh list
cmd_list() {
local domain="${SF_DOMAIN:-498as.com}"
echo "Sites:"
echo ""
$SF_CLI sites list --json 2>/dev/null | \
grep -o '"name":"[^"]*"' | \
cut -d'"' -f4 | \
while read -r site; do
echo " https://$site.$domain"
done
}
# Show help
cmd_help() {
cat << EOF
sf-helper.sh - Static Files helper for AI agents
Commands:
deploy <site> <dir> [user:pass] Deploy directory to site
clean-deploy <site> <dir> Delete all files and deploy fresh
share <file> [site] Quick share a single file
list List all sites with URLs
Environment:
SF_API_URL API endpoint (required)
SF_API_KEY API key (required)
SF_DOMAIN Domain for URLs (default: 498as.com)
Examples:
sf-helper.sh deploy docs ./build
sf-helper.sh deploy private ./files admin:secret123
sf-helper.sh share ./report.pdf
sf-helper.sh clean-deploy mysite ./dist
EOF
}
# Main
check_env
case "${1:-help}" in
deploy) shift; cmd_deploy "$@" ;;
clean-deploy) shift; cmd_clean_deploy "$@" ;;
share) shift; cmd_share "$@" ;;
list) cmd_list ;;
help|--help|-h) cmd_help ;;
*) echo "Unknown command: $1"; cmd_help; exit 1 ;;
esac
```