claw2ui

Generate interactive web pages (dashboards, charts, tables, reports) and serve them via public URL. Use this skill when the user explicitly asks for data vis...

MIT-0 · Free to use, modify, and redistribute. No attribution required.
0 · 53 · 0 current installs · 0 all-time installs
MIT-0
Security Scan
VirusTotalVirusTotal
Pending
View report →
OpenClawOpenClaw
Benign
medium confidence
Purpose & Capability
The name/description match the declared requirements: a Node-based CLI (claw2ui) and optional cloudflared for fixed domains. One inconsistency: the registry metadata shows required env vars as serialized '[object Object]' (likely a packaging/metadata bug) even though the SKILL.md clearly documents only two optional env vars (CLAWBOARD_TUNNEL_NAME and CLAWBOARD_TUNNEL_URL). This looks like a formatting bug, not mismatch of intent.
Instruction Scope
SKILL.md is an instruction-only skill that tells the agent to install/use the claw2ui CLI, register with a remote server or run a local server, and publish pages (including admin operations). The doc explicitly requires user confirmation before publishing and warns not to include secrets. The surface is consistent with the stated purpose, but publishing creates public URLs — there is an inherent risk of accidental data exposure if the agent or user embeds secrets or PII despite the guidance.
Install Mechanism
Install steps use npm (npm install -g claw2ui) and an optional Homebrew formula (cloudflared). These are standard and traceable (npm package and GitHub repo are referenced). No arbitrary downloads from untrusted hosts are specified. Note that global npm installs have standard supply-chain risks; inspect the package or trust its publisher before installing.
Credentials
The skill does not request unrelated secrets. The documented env vars are optional and relate to fixed-domain tunnel setup. The skill/CLI stores tokens locally (e.g., ~/.claw2ui.json) when registering with a remote server — that local credential storage is normal but worth knowing. The registry's broken env var serialization is confusing and should be clarified before automated provisioning.
Persistence & Privilege
always:false and user-invocable:true (default) — no forced permanent inclusion. The skill will operate as an autonomous-invokable skill (platform default). Combined with the ability to publish public pages and save tokens locally, autonomous invocation increases blast radius somewhat, so ensure the agent asks for confirmation before publishing (SKILL.md instructs this).
Assessment
This skill is coherent with its purpose (generating and publishing interactive pages). Before installing: 1) verify and trust the npm package/author (inspect package source if you can) because npm installs run code on your machine; 2) prefer the documented remote server mode if you don't want to run a local server or expose your machine; 3) never let the agent publish pages containing secrets, API keys, or PII — SKILL.md warns about this, but it's a manual safeguard you must enforce; 4) note the registry metadata bug that shows env vars as '[object Object]' — confirm the actual env vars (CLAWBOARD_TUNNEL_NAME / CLAWBOARD_TUNNEL_URL) before automating provisioning; and 5) if you will use admin commands, protect admin tokens and only run those from trusted environments.

Like a lobster shell, security has layers — review code before you run it.

Current versionv1.0.5
Download zip
latestvk97chybh3xfp7ttsgvyzgej1cd830678

License

MIT-0
Free to use, modify, and redistribute. No attribution required.

Runtime requirements

📊 Clawdis
Binsnode, claw2ui
Env[object Object], [object Object]

Install

Install cloudflared (optional, for fixed-domain tunnels)
Bins: cloudflared
brew install cloudflared

SKILL.md

Claw2UI - Agent-to-UI Bridge

Generate interactive web pages from declarative JSON specs and serve them via cloudflared tunnel. Pages include Tailwind CSS, Alpine.js, and Chart.js out of the box.

Source & verification: GitHub · npm · License: MIT

Data Safety

Every published page is accessible via a public URL. Follow these rules:

  • Never include secrets, credentials, API keys, tokens, PII, or internal endpoints in page content
  • Sanitize all user-provided data before embedding it in pages — the html component is sanitized server-side, but avoid passing raw untrusted input to other components
  • Always confirm with the user before publishing. Do not publish pages without explicit user approval
  • Use TTL for ephemeral or sensitive data so pages auto-expire: --ttl 3600000 (1 hour)
  • Review content before publishing — check that no sensitive information leaks through table rows, stat values, or chart labels

Setup

Claw2UI supports two modes: remote (connect to an existing server) and local (run your own server).

Remote Mode (Recommended for most users)

Connect to a shared Claw2UI server. No tunnel or server setup needed.

npm install -g claw2ui
claw2ui register --server https://0xsegfaulted-claw2ui.hf.space
# Done! Token saved to ~/.claw2ui.json automatically.

If you received a token manually from the server admin:

claw2ui init --server https://0xsegfaulted-claw2ui.hf.space --token <your-token>

Local Mode (Run your own server)

Clone the repo or install globally, then start the server:

claw2ui status                          # Check if server is running
claw2ui start                           # Start server + tunnel
claw2ui start --no-tunnel               # Start without tunnel (localhost only)

Fixed Domain (Named Tunnel)

For a permanent URL instead of random quick tunnels. Requires: Cloudflare account + cloudflared.

# One-time setup:
# cloudflared tunnel login
# cloudflared tunnel create claw2ui
# cloudflared tunnel route dns claw2ui board.yourdomain.com

export CLAWBOARD_TUNNEL_NAME=claw2ui
export CLAWBOARD_TUNNEL_URL=https://board.yourdomain.com
claw2ui start

Server Admin: Token Management

Generate tokens for other users to connect to your server:

claw2ui token create                    # Generate a new token (run from project dir)
claw2ui token list                      # List all config tokens
claw2ui token revoke <token>            # Remove a config token

Registered tokens (from /api/register) can be managed via the admin API:

# List registered tokens (requires admin token)
curl -H "Authorization: Bearer <admin-token>" https://board.example.com/api/tokens

# Revoke by short ID
curl -X POST -H "Authorization: Bearer <admin-token>" https://board.example.com/api/tokens/<id>/revoke

CLI Tool

All operations go through the claw2ui CLI. Install via npm install -g claw2ui (npm registry).

Commands

# Connection (remote users)
claw2ui register --server <url>         # Self-service registration with a remote server
claw2ui init --server <url> --token <t> # Manual remote server config

# Publish a page
claw2ui publish --spec-file /tmp/page.json --title "Dashboard"
claw2ui publish --html "<h1>Hello</h1>" --title "Test"
claw2ui publish --ttl 3600000 --spec-file /tmp/page.json --title "Temp"     # With TTL (ms)

# Manage pages (admin/privileged only)
claw2ui list                            # List all pages
claw2ui delete <page-id>                # Delete a page

# Server lifecycle (local mode only)
claw2ui status                          # Check if server is running
claw2ui start                           # Start server + tunnel

# Token management (server admin only, run from project dir)
claw2ui token create                    # Generate a new config token
claw2ui token list                      # List config tokens
claw2ui token revoke <token>            # Remove a config token

Workflow

Step 1: Ensure Connection

# Remote: register once (token saved to ~/.claw2ui.json)
claw2ui register --server https://0xsegfaulted-claw2ui.hf.space

# Local: ensure server is running
claw2ui status
# If not running:
claw2ui start

Step 2: Build the A2UI Spec

Write the spec to a temp file. Always wrap content in a container.

cat > /tmp/claw2ui_page.json << 'SPECEOF'
{
  "title": "Page Title",
  "components": [
    { "type": "container", "children": [
      { "type": "header", "props": { "title": "Title", "subtitle": "Description" } },
      ...more components...
    ]}
  ]
}
SPECEOF

Step 3: Confirm with User

Before publishing, tell the user what will be published and confirm they want to proceed. The page will be accessible via a public URL. Example:

"I've prepared a dashboard with [summary of content]. Ready to publish it to a public URL? (Use --ttl 3600000 for auto-expiry in 1 hour.)"

Step 4: Publish

Only after user confirmation:

claw2ui publish --spec-file /tmp/claw2ui_page.json --title "Dashboard"
# For sensitive/temporary data, always set a TTL:
claw2ui publish --spec-file /tmp/claw2ui_page.json --title "Dashboard" --ttl 3600000

Outputs the public URL.

Step 5: Share the URL

Include the URL in your response to the user.

Available Components

Layout

  • container - Always use as the outermost wrapper. Centers content with max-width.
  • row - Grid row. Props: cols (number of columns, e.g. 3), gap (spacing)
  • column - Grid column. Props: span (how many columns to occupy)
  • card - Card with border/shadow. Props: title, subtitle
  • tabs - Tabbed sections. Props: tabs: [{ id: "t1", label: "Tab 1", children: [...] }]
  • accordion - Collapsible sections. Props: items: [{ title: "Section", children: [...] }]
  • list - Flex list. Props: direction (vertical/horizontal), gap, align
  • modal - Dialog popup. Props: title. First child = trigger button, rest = content.

Data Display

  • stat - KPI metric card. Props: label, value, change (percent, positive = green), icon (emoji)

    • Great for key metrics at the top of a dashboard
    • Put 3-4 stats in a row with cols: 3 or cols: 4
  • table - Searchable, sortable table. Props:

    • columns: [{ key: "name", label: "Name", format?: "currency"|"percent"|"badge" }]
    • rows: [{ name: "value", ... }]
    • For badge format, add badgeMap: { "Active": "success", "Down": "error" }
  • chart - Chart.js chart. Props:

    • chartType: "line", "bar", "pie", "doughnut", "radar"
    • height: pixels (default 300)
    • data: standard Chart.js data format:
      {
        "labels": ["Jan", "Feb", "Mar"],
        "datasets": [{
          "label": "Revenue",
          "data": [100, 200, 150],
          "borderColor": "#3b82f6",
          "backgroundColor": "rgba(59, 130, 246, 0.1)",
          "tension": 0.3,
          "fill": true
        }]
      }
      

Input

  • button - Props: label, variant ("primary", "secondary", "danger", "outline")
  • text-field - Props: label, placeholder, value
  • select - Props: label, options: [{ value: "a", label: "Option A" }]
  • checkbox - Props: label, value (boolean)
  • choice-picker - Single/multi select. Props: label, options: [{value, label}], value: [selected], variant (mutuallyExclusive/multipleSelection), displayStyle (checkbox/chips)
  • slider - Range slider. Props: label, min, max, value
  • date-time-input - Date/time picker. Props: label, value (ISO 8601), enableDate, enableTime, min, max

Media & Text

  • icon - Material Icon. Props: name (e.g. "settings", "search"), size (px)
  • text - Text paragraph. Props: content, size ("sm", "base", "lg", "xl"), bold (boolean)
  • code - Code block. Props: content, language
  • html - Raw HTML (sanitized). Props: content
  • image - Props: src, alt
  • video - Video player. Props: url, poster
  • audio-player - Audio player. Props: url, description
  • divider - Horizontal line
  • spacer - Vertical space. Props: size (Tailwind spacing units, e.g. 4)

Navigation

  • header - Page header. Props: title, subtitle
  • link - Hyperlink. Props: href, label

Design Patterns

Dashboard Layout

container
  header (title + subtitle)
  row cols=3
    stat (metric 1)
    stat (metric 2)
    stat (metric 3)
  card (title: "Trend")
    chart (line chart)
  card (title: "Details")
    table (data table)

Report Layout

container
  header
  text (summary paragraph)
  tabs
    tab "Overview"
      row cols=2
        stat, stat
      chart
    tab "Details"
      table
    tab "Analysis"
      text (analysis content)

Comparison Layout

container
  header
  row cols=2
    card "Option A"
      stat, stat, text
    card "Option B"
      stat, stat, text
  table (detailed comparison)

Example: Complete Dashboard

{
  "title": "Sales Dashboard",
  "components": [
    { "type": "container", "children": [
      { "type": "header", "props": { "title": "Sales Dashboard", "subtitle": "Q1 2026 Overview" } },
      { "type": "row", "props": { "cols": 3, "gap": 4 }, "children": [
        { "type": "stat", "props": { "label": "Revenue", "value": "$1.2M", "change": 15.3, "icon": "💰" } },
        { "type": "stat", "props": { "label": "Orders", "value": "8,432", "change": 8.1, "icon": "📦" } },
        { "type": "stat", "props": { "label": "Customers", "value": "2,847", "change": -2.5, "icon": "👥" } }
      ]},
      { "type": "card", "props": { "title": "Revenue Trend" }, "children": [
        { "type": "chart", "props": {
          "chartType": "line", "height": 280,
          "data": {
            "labels": ["Jan", "Feb", "Mar"],
            "datasets": [{ "label": "Revenue", "data": [320000, 410000, 480000], "borderColor": "#3b82f6", "tension": 0.3, "fill": false }]
          }
        }}
      ]},
      { "type": "card", "props": { "title": "Top Products" }, "children": [
        { "type": "table", "props": {
          "columns": [
            { "key": "product", "label": "Product" },
            { "key": "revenue", "label": "Revenue", "format": "currency" },
            { "key": "status", "label": "Status", "format": "badge", "badgeMap": { "Active": "success", "Low Stock": "warning" } }
          ],
          "rows": [
            { "product": "Widget Pro", "revenue": 450000, "status": "Active" },
            { "product": "Gadget X", "revenue": 320000, "status": "Low Stock" }
          ]
        }}
      ]}
    ]}
  ]
}

Files

1 total
Select a file
Select a file to preview.

Comments

Loading comments…