Skip to main content

openclaw-studio-dashboard

Expert in OpenClaw Studio - web dashboard for managing OpenClaw Gateway, agents, chat, approvals, and jobs

Informações da origem

Repositório
reason-machines/hermes-skills
Última atividade na origem
17 de maio de 2026 às 17:49
Idioma detectado do SKILL.md
inglês
Estrelas
5
Forks
0

Opções de instalação

Por padrão, está selecionado o prompt que primeiro revisa a origem. Você pode mudar para um comando direto ou baixar uma cópia local.

Revise os arquivos de origem

Leia o SKILL.md e os arquivos complementares exibidos pelo SkillsMP antes de decidir se vai instalar.

Exibindo SKILL.md

SKILL.md
Instruções da origem · Visualização somente leitura
name
openclaw-studio-dashboard
description
Expert in OpenClaw Studio - web dashboard for managing OpenClaw Gateway, agents, chat, approvals, and jobs
triggers
["set up openclaw studio dashboard","connect studio to openclaw gateway","create agent in openclaw studio","configure openclaw studio upstream","manage openclaw agents with studio","deploy openclaw studio to production","troubleshoot openclaw studio connection","run openclaw studio locally"]
# OpenClaw Studio Dashboard > Skill by [ara.so](https://ara.so) — Hermes Skills collection. OpenClaw Studio is a clean web dashboard for OpenClaw Gateway that provides a unified interface to connect gateways, manage agents, chat, handle approvals, and configure jobs. Built with TypeScript/Next.js, it runs a server-owned control plane architecture with SSE streaming for real-time runtime events. ## What OpenClaw Studio Does - **Gateway Connection**: Connect to local or remote OpenClaw Gateway instances via WebSocket - **Agent Management**: Create, configure, and monitor AI agents with tool policies and sandbox settings - **Chat Interface**: Stream conversations with PI agents including tool calls and thinking traces - **Approval Workflows**: Manage exec approvals and runtime permissions - **Job Configuration**: Set up and monitor cron jobs - **Runtime Streaming**: Real-time event streaming over SSE with replay/history ## Installation & Startup ### Quick Start (Recommended) ```bash # Run latest version with npx npx -y openclaw-studio@latest # Opens on http://localhost:3000 # Default gateway URL: ws://localhost:18789 ``` ### From Source ```bash git clone https://github.com/grp06/openclaw-studio.git cd openclaw-studio npm install npm run dev ``` ### Setup Helper ```bash # Configure gateway URL/token without opening UI npm run studio:setup ``` ## Connection Architecture OpenClaw Studio uses a two-path architecture: 1. **Browser → Studio**: HTTP + SSE (`/api/runtime/*`, `/api/intents/*`) 2. **Studio → Gateway**: Server-owned WebSocket to upstream OpenClaw **Critical concept**: `ws://localhost:18789` means "gateway on the Studio host", not "gateway on your browser's machine". ## Configuration Patterns ### Deployment Scenarios #### A. Both Local (Same Computer) ```bash # Start Studio npx -y openclaw-studio@latest cd openclaw-studio npm run dev # Open http://localhost:3000 # In Studio UI: # - Upstream URL: ws://localhost:18789 # - Upstream Token: <your-gateway-token> ``` Get gateway token: ```bash openclaw config get gateway.auth.token ``` #### B. Gateway in Cloud, Studio Local **Option 1: Tailscale Serve (Recommended)** On gateway host: ```bash tailscale serve --yes --bg --https 443 http://127.0.0.1:18789 ``` In Studio (local laptop): - Upstream URL: `wss://<gateway-host>.ts.net` - Upstream Token: `<gateway-token>` **Option 2: SSH Tunnel** From laptop: ```bash ssh -L 18789:127.0.0.1:18789 user@<gateway-host> ``` In Studio: - Upstream URL: `ws://localhost:18789` - Upstream Token: `<gateway-token>` #### C. Both in Cloud (Always-On) On Studio VPS: ```bash # Start Studio npx -y openclaw-studio@latest cd openclaw-studio npm install npm run dev # If OpenClaw is on same VPS: # - Upstream URL: ws://localhost:18789 # - Upstream Token: <gateway-token> # Expose Studio over Tailscale tailscale serve --yes --bg --https 443 http://127.0.0.1:3000 # Access from anywhere: https://<studio-host>.ts.net ``` ### Environment Variables ```bash # Gateway connection (optional, can set in UI) NEXT_PUBLIC_GATEWAY_URL=ws://localhost:18789 # Studio access control (required for public binds) STUDIO_ACCESS_TOKEN=your-secure-token-here # OpenClaw state directory OPENCLAW_STATE_DIR=~/.openclaw # Bind host (default: 127.0.0.1) HOST=0.0.0.0 # Public bind - requires STUDIO_ACCESS_TOKEN ``` ### Configuration Files Studio settings are stored in `~/.openclaw/openclaw-studio/`: ``` ~/.openclaw/ ├── openclaw.json # OpenClaw Gateway config └── openclaw-studio/ ├── settings.json # Gateway URL/token └── runtime.db # Control-plane runtime DB ``` ## API & Key Commands ### Studio Setup ```bash # Development mode with auto-restart npm run dev # Production build npm run build npm run start # Turbo dev mode npm run dev:turbo # Verify/repair native dependencies npm run verify:native-runtime:repair npm run verify:native-runtime:check ``` ### TypeScript API Patterns #### Connecting to Gateway ```typescript // In Studio UI components import { useGatewayConnection } from '@/hooks/useGatewayConnection'; export function DashboardPage() { const { connected, connect, disconnect, status } = useGatewayConnection(); const handleConnect = async () => { try { await connect({ url: 'ws://localhost:18789', token: process.env.GATEWAY_TOKEN }); } catch (error) { console.error('Connection failed:', error); } }; return ( <div> <button onClick={handleConnect} disabled={connected}> {connected ? 'Connected' : 'Connect'} </button> <span>Status: {status}</span> </div> ); } ``` #### Streaming Runtime Events ```typescript // Server-side SSE streaming import { NextRequest } from 'next/server'; export async function GET(request: NextRequest) { const encoder = new TextEncoder(); const stream = new ReadableStream({ async start(controller) { // Subscribe to runtime events const subscription = runtimeStore.subscribe((event) => { const data = `data: ${JSON.stringify(event)}\n\n`; controller.enqueue(encoder.encode(data)); }); // Replay history const history = await runtimeStore.getHistory(); for (const event of history) { const data = `data: ${JSON.stringify(event)}\n\n`; controller.enqueue(encoder.encode(data)); } return () => subscription.unsubscribe(); } }); return new Response(stream, { headers: { 'Content-Type': 'text/event-stream', 'Cache-Control': 'no-cache', 'Connection': 'keep-alive' } }); } ``` #### Creating Agents ```typescript // Agent creation API interface AgentConfig { name: string; systemPrompt: string; toolPolicy: 'all' | 'allowlist' | 'denylist'; allowedTools?: string[]; sandboxEnabled: boolean; execApprovalRequired: boolean; } export async function createAgent(config: AgentConfig) { const response = await fetch('/api/intents/agent-create', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ agent_name: config.name, system_prompt: config.systemPrompt, tool_policy: config.toolPolicy, allowed_tools: config.allowedTools, sandbox_config: { enabled: config.sandboxEnabled, mounts: config.sandboxEnabled ? [ { host: '/tmp', container: '/workspace', readonly: false } ] : [] }, exec_approval_required: config.execApprovalRequired }) }); if (!response.ok) { const error = await response.json(); throw new Error(error.message || 'Failed to create agent'); } return response.json(); } ``` #### Chat with Streaming ```typescript // Client-side chat with SSE import { useEffect, useState } from 'react'; export function ChatInterface({ agentId }: { agentId: string }) { const [messages, setMessages] = useState<ChatMessage[]>([]); const [thinking, setThinking] = useState<string[]>([]); useEffect(() => { // Connect to runtime stream const eventSource = new EventSource('/api/runtime/stream'); eventSource.addEventListener('message', (event) => { const data = JSON.parse(event.data); switch (data.type) { case 'tool_call': setMessages(prev => [...prev, { role: 'assistant', content: `Using tool: ${data.tool_name}`, metadata: { type: 'tool', ...data } }]); break; case 'thinking': setThinking(prev => [...prev, data.content]); break; case 'transcript': setMessages(prev => [...prev, { role: data.role, content: data.content }]); setThinking([]); break; } }); return () => eventSource.close(); }, [agentId]); const sendMessage = async (content: string) => { await fetch('/api/intents/chat', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ agent_id: agentId, message: content }) }); }; return ( <div> {messages.map((msg, i) => ( <div key={i} className={`message ${msg.role}`}> {msg.content} </div> ))} {thinking.length > 0 && ( <div className="thinking"> {thinking.map((t, i) => <p key={i}>{t}</p>)} </div> )} <input onKeyPress={(e) => { if (e.key === 'Enter') { sendMessage(e.currentTarget.value); e.currentTarget.value = ''; } }} /> </div> ); } ``` ## Real-World Examples ### Example 1: Local Development Setup ```bash #!/bin/bash # setup-local-dev.sh # Start OpenClaw Gateway (in separate terminal) # openclaw gateway start # Get gateway token GATEWAY_TOKEN=$(openclaw config get gateway.auth.token) # Start Studio npx -y openclaw-studio@latest cd openclaw-studio # Configure via environment export NEXT_PUBLIC_GATEWAY_URL=ws://localhost:18789 npm run dev # Open http://localhost:3000 # Enter gateway token in UI ``` ### Example 2: Production Cloud Setup ```bash #!/bin/bash # deploy-studio-cloud.sh # On your VPS running OpenClaw Gateway cd /opt npx -y openclaw-studio@latest cd openclaw-studio # Install dependencies npm install # Build for production npm run build # Set access token for public access export STUDIO_ACCESS_TOKEN=$(openssl rand -hex 32) # Expose over Tailscale tailscale serve --yes --bg --https 443 http://127.0.0.1:3000 # Run production server npm run start echo "Studio available at: https://$(tailscale status --json | jq -r '.Self.DNSName')/" echo "Access token: $STUDIO_ACCESS_TOKEN" echo "Use: https://your-host.ts.net/?access_token=$STUDIO_ACCESS_TOKEN" ``` ### Example 3: Agent with Sandbox & Approvals ```typescript // create-secure-agent.ts import { createAgent } from './lib/agent-api'; async function createSecureCodeAgent() { const agent = await createAgent({ name: 'secure-code-assistant', systemPrompt: `You are a secure code assistant. Always ask before executing commands. Work within the sandboxed environment only.`, toolPolicy: 'allowlist', allowedTools: [ 'bash', 'read_file', 'write_file', 'search_files' ], sandboxEnabled: true, execApprovalRequired: true }); console.log('Agent created:', agent.id); return agent; } // Usage createSecureCodeAgent().catch(console.error); ``` ### Example 4: Cron Job Configuration ```typescript // configure-cron-job.ts interface CronJobConfig { agentId: string; schedule: string; task: string; enabled: boolean; } async function createCronJob(config: CronJobConfig) { const response = await fetch('/api/intents/job-create', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ agent_id: config.agentId, schedule: config.schedule,
Ver no GitHub
Este SKILL.md e muito grande, entao o SkillsMP mostra aqui apenas a primeira secao. Ver no GitHub