openclaw-bot-review-dashboard

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

OpenClaw Bot Review Dashboard

OpenClaw Bot 审查仪表板

Skill by ara.so — Hermes Skills collection.
ara.so 开发的Skill — 属于Hermes Skills集合。

What It Does

功能介绍

OpenClaw Bot Review Dashboard is a Next.js-based web interface that provides real-time monitoring for OpenClaw agents across multiple platforms (Feishu, Discord, etc.). It reads directly from
~/.openclaw/openclaw.json
and local session files to display:
  • Bot/agent status with model bindings and platform health
  • Model configurations with context windows and capabilities
  • Session management with token usage tracking
  • Statistics and trends (token consumption, response times)
  • Skill inventory (built-in, extension, custom)
  • Alert rules with notification support
  • Gateway health monitoring with auto-polling
  • Pixel-art office visualization of agents
No database required — all data is derived from OpenClaw's local configuration.
OpenClaw Bot Review Dashboard 是基于Next.js的Web界面,可实时监控多平台(飞书、Discord等)的OpenClaw Agent。它直接读取
~/.openclaw/openclaw.json
和本地会话文件,展示以下内容:
  • Bot/Agent状态,含模型绑定与平台健康情况
  • 模型配置,含上下文窗口与功能特性
  • 会话管理,含令牌使用追踪
  • 统计数据与趋势(令牌消耗、响应时间)
  • Skill库存(内置、扩展、自定义)
  • 带通知支持的告警规则
  • 带自动轮询的网关健康监控
  • Agent的像素风办公场景可视化
无需数据库 — 所有数据均来自OpenClaw的本地配置。

Installation

安装步骤

Standard Setup

标准配置

bash
undefined
bash
undefined

Clone the repository

克隆仓库

Install dependencies

安装依赖

npm install
npm install

Start development server

启动开发服务器

npm run start

The dashboard will be available at `http://localhost:3000`.
npm run start

仪表板将在 `http://localhost:3000` 地址可用。

Production Build

生产环境构建

bash
undefined
bash
undefined

Build for production

构建生产版本

npm run build
npm run build

Start production server

启动生产服务器

npm run start
undefined
npm run start
undefined

Docker Deployment

Docker部署

bash
undefined
bash
undefined

Build Docker image

构建Docker镜像

docker build -t openclaw-dashboard .
docker build -t openclaw-dashboard .

Run container with default OpenClaw path (~/.openclaw)

使用默认OpenClaw路径(~/.openclaw)运行容器

docker run -d --name openclaw-dashboard
-p 3000:3000
-v $HOME/.openclaw:/root/.openclaw:ro
openclaw-dashboard
docker run -d --name openclaw-dashboard
-p 3000:3000
-v $HOME/.openclaw:/root/.openclaw:ro
openclaw-dashboard

Run with custom OpenClaw config path

使用自定义OpenClaw配置路径运行

docker run -d --name openclaw-dashboard
-p 3000:3000
-e OPENCLAW_HOME=/opt/openclaw
-v /path/to/openclaw:/opt/openclaw:ro
openclaw-dashboard
undefined
docker run -d --name openclaw-dashboard
-p 3000:3000
-e OPENCLAW_HOME=/opt/openclaw
-v /path/to/openclaw:/opt/openclaw:ro
openclaw-dashboard
undefined

Requirements

环境要求

  • Node.js: 18+ required
  • OpenClaw: Must be installed with config at
    ~/.openclaw/openclaw.json
  • Platforms: Works with Feishu, Discord, and other OpenClaw-supported platforms
  • Node.js: 需要18+版本
  • OpenClaw: 必须已安装,且配置文件位于
    ~/.openclaw/openclaw.json
  • 平台: 支持飞书、Discord及其他OpenClaw兼容平台

Configuration

配置说明

Environment Variables

环境变量

bash
undefined
bash
undefined

Custom OpenClaw config path

自定义OpenClaw配置路径

export OPENCLAW_HOME=/opt/openclaw
export OPENCLAW_HOME=/opt/openclaw

Port configuration (default: 3000)

端口配置(默认:3000)

export PORT=3000
export PORT=3000

Start with custom config

使用自定义配置启动

OPENCLAW_HOME=/opt/openclaw npm run start
undefined
OPENCLAW_HOME=/opt/openclaw npm run start
undefined

Directory Structure

目录结构

The dashboard expects the following OpenClaw directory structure:
~/.openclaw/
├── openclaw.json          # Main configuration file
├── sessions/              # Session data per agent
│   ├── agent1/
│   │   ├── session1.json
│   │   └── session2.json
│   └── agent2/
└── skills/                # Installed skills
仪表板期望OpenClaw目录结构如下:
~/.openclaw/
├── openclaw.json          # 主配置文件
├── sessions/              # 各Agent的会话数据
│   ├── agent1/
│   │   ├── session1.json
│   │   └── session2.json
│   └── agent2/
└── skills/                # 已安装的Skill

OpenClaw Configuration

OpenClaw配置

The dashboard reads from
openclaw.json
:
json
{
  "agents": [
    {
      "name": "my-agent",
      "emoji": "🤖",
      "model": "gpt-4",
      "platforms": {
        "feishu": {
          "app_id": "${FEISHU_APP_ID}",
          "app_secret": "${FEISHU_APP_SECRET}"
        }
      }
    }
  ],
  "models": {
    "gpt-4": {
      "provider": "openai",
      "api_key": "${OPENAI_API_KEY}",
      "context_window": 8192,
      "max_output": 4096
    }
  },
  "gateway": {
    "enabled": true,
    "port": 8080
  }
}
仪表板读取
openclaw.json
中的内容:
json
{
  "agents": [
    {
      "name": "my-agent",
      "emoji": "🤖",
      "model": "gpt-4",
      "platforms": {
        "feishu": {
          "app_id": "${FEISHU_APP_ID}",
          "app_secret": "${FEISHU_APP_SECRET}"
        }
      }
    }
  ],
  "models": {
    "gpt-4": {
      "provider": "openai",
      "api_key": "${OPENAI_API_KEY}",
      "context_window": 8192,
      "max_output": 4096
    }
  },
  "gateway": {
    "enabled": true,
    "port": 8080
  }
}

Key Features and Usage

核心功能与使用方法

Bot Dashboard

Bot仪表板

View all agents at a glance:
typescript
// The dashboard automatically reads from ~/.openclaw/openclaw.json
// Each bot card shows:
// - Name and emoji
// - Bound model
// - Platform status (Feishu, Discord, etc.)
// - Session count
// - Gateway health indicator
概览所有Agent:
typescript
// 仪表板自动读取~/.openclaw/openclaw.json
// 每个Bot卡片展示:
// - 名称与表情符号
// - 绑定的模型
// - 平台状态(飞书、Discord等)
// - 会话数量
// - 网关健康指示器

Model Management

模型管理

Monitor all configured models:
typescript
// Models page displays:
// - Provider (OpenAI, Anthropic, etc.)
// - Model name and version
// - Context window size
// - Max output tokens
// - Reasoning support
// - Per-model connectivity test
监控所有已配置的模型:
typescript
// 模型页面展示:
// - 提供商(OpenAI、Anthropic等)
// - 模型名称与版本
// - 上下文窗口大小
// - 最大输出令牌数
// - 推理支持
// - 单模型连通性测试

Session Monitoring

会话监控

Track active sessions per agent:
typescript
// Sessions are automatically detected from:
// ~/.openclaw/sessions/{agent-name}/*.json

// Each session shows:
// - Type (DM, group, cron)
// - Platform
// - Token usage
// - Last activity
// - Connectivity test button
追踪每个Agent的活跃会话:
typescript
// 会话自动从以下路径检测:
// ~/.openclaw/sessions/{agent-name}/*.json

// 每个会话展示:
// - 类型(私信、群组、定时任务)
// - 所属平台
// - 令牌使用情况
// - 最后活跃时间
// - 连通性测试按钮

Auto-Refresh Configuration

自动刷新配置

typescript
// Available refresh intervals:
// - Manual (no auto-refresh)
// - 10 seconds
// - 30 seconds
// - 1 minute
// - 5 minutes
// - 10 minutes

// Select from dropdown in top-right corner
typescript
// 可用刷新间隔:
// - 手动(无自动刷新)
// - 10秒
// - 30秒
// - 1分钟
// - 5分钟
// - 10分钟

// 从右上角下拉菜单选择

Theme and Language

主题与语言

typescript
// Theme toggle: Light / Dark mode
// Available in sidebar

// Language toggle: English / 中文
// Available in top navigation
typescript
// 主题切换:亮色/暗色模式
// 在侧边栏中设置

// 语言切换:英文/中文
// 在顶部导航栏中设置

API Routes

API路由

The dashboard includes Next.js API routes for reading OpenClaw data:
仪表板包含Next.js API路由用于读取OpenClaw数据:

Get All Bots

获取所有Bot

typescript
// pages/api/bots.ts
import type { NextApiRequest, NextApiResponse } from 'next';
import { readOpenClawConfig } from '@/lib/openclaw';

export default async function handler(
  req: NextApiRequest,
  res: NextApiResponse
) {
  if (req.method !== 'GET') {
    return res.status(405).json({ error: 'Method not allowed' });
  }

  try {
    const config = await readOpenClawConfig();
    const bots = config.agents.map(agent => ({
      name: agent.name,
      emoji: agent.emoji,
      model: agent.model,
      platforms: Object.keys(agent.platforms || {}),
      sessionCount: getSessionCount(agent.name),
    }));
    
    res.status(200).json({ bots });
  } catch (error) {
    res.status(500).json({ error: 'Failed to read config' });
  }
}
typescript
// pages/api/bots.ts
import type { NextApiRequest, NextApiResponse } from 'next';
import { readOpenClawConfig } from '@/lib/openclaw';

export default async function handler(
  req: NextApiRequest,
  res: NextApiResponse
) {
  if (req.method !== 'GET') {
    return res.status(405).json({ error: 'Method not allowed' });
  }

  try {
    const config = await readOpenClawConfig();
    const bots = config.agents.map(agent => ({
      name: agent.name,
      emoji: agent.emoji,
      model: agent.model,
      platforms: Object.keys(agent.platforms || {}),
      sessionCount: getSessionCount(agent.name),
    }));
    
    res.status(200).json({ bots });
  } catch (error) {
    res.status(500).json({ error: 'Failed to read config' });
  }
}

Get Models

获取模型

typescript
// pages/api/models.ts
export default async function handler(
  req: NextApiRequest,
  res: NextApiResponse
) {
  const config = await readOpenClawConfig();
  const models = Object.entries(config.models).map(([name, model]) => ({
    name,
    provider: model.provider,
    contextWindow: model.context_window,
    maxOutput: model.max_output,
    reasoning: model.reasoning_support || false,
  }));
  
  res.status(200).json({ models });
}
typescript
// pages/api/models.ts
export default async function handler(
  req: NextApiRequest,
  res: NextApiResponse
) {
  const config = await readOpenClawConfig();
  const models = Object.entries(config.models).map(([name, model]) => ({
    name,
    provider: model.provider,
    contextWindow: model.context_window,
    maxOutput: model.max_output,
    reasoning: model.reasoning_support || false,
  }));
  
  res.status(200).json({ models });
}

Test Platform Connection

测试平台连接

typescript
// pages/api/test/platform.ts
export default async function handler(
  req: NextApiRequest,
  res: NextApiResponse
) {
  const { platform, agentName } = req.query;
  
  try {
    const result = await testPlatformConnection(
      platform as string,
      agentName as string
    );
    res.status(200).json({ success: result.success, message: result.message });
  } catch (error) {
    res.status(500).json({ success: false, error: error.message });
  }
}
typescript
// pages/api/test/platform.ts
export default async function handler(
  req: NextApiRequest,
  res: NextApiResponse
) {
  const { platform, agentName } = req.query;
  
  try {
    const result = await testPlatformConnection(
      platform as string,
      agentName as string
    );
    res.status(200).json({ success: result.success, message: result.message });
  } catch (error) {
    res.status(500).json({ success: false, error: error.message });
  }
}

Gateway Health Check

网关健康检查

typescript
// pages/api/gateway/health.ts
export default async function handler(
  req: NextApiRequest,
  res: NextApiResponse
) {
  const config = await readOpenClawConfig();
  
  if (!config.gateway?.enabled) {
    return res.status(200).json({ healthy: false, reason: 'disabled' });
  }
  
  try {
    const port = config.gateway.port || 8080;
    const response = await fetch(`http://localhost:${port}/health`);
    const healthy = response.ok;
    
    res.status(200).json({ healthy, port });
  } catch (error) {
    res.status(200).json({ healthy: false, reason: 'unreachable' });
  }
}
typescript
// pages/api/gateway/health.ts
export default async function handler(
  req: NextApiRequest,
  res: NextApiResponse
) {
  const config = await readOpenClawConfig();
  
  if (!config.gateway?.enabled) {
    return res.status(200).json({ healthy: false, reason: 'disabled' });
  }
  
  try {
    const port = config.gateway.port || 8080;
    const response = await fetch(`http://localhost:${port}/health`);
    const healthy = response.ok;
    
    res.status(200).json({ healthy, port });
  } catch (error) {
    res.status(200).json({ healthy: false, reason: 'unreachable' });
  }
}

Common Patterns

通用实现模式

Reading OpenClaw Config

读取OpenClaw配置

typescript
// lib/openclaw.ts
import fs from 'fs/promises';
import path from 'path';
import os from 'os';

export interface OpenClawConfig {
  agents: Agent[];
  models: Record<string, Model>;
  gateway?: Gateway;
}

export async function readOpenClawConfig(): Promise<OpenClawConfig> {
  const openclawHome = process.env.OPENCLAW_HOME || 
    path.join(os.homedir(), '.openclaw');
  
  const configPath = path.join(openclawHome, 'openclaw.json');
  
  try {
    const content = await fs.readFile(configPath, 'utf-8');
    return JSON.parse(content);
  } catch (error) {
    throw new Error(`Failed to read OpenClaw config: ${error.message}`);
  }
}
typescript
// lib/openclaw.ts
import fs from 'fs/promises';
import path from 'path';
import os from 'os';

export interface OpenClawConfig {
  agents: Agent[];
  models: Record<string, Model>;
  gateway?: Gateway;
}

export async function readOpenClawConfig(): Promise<OpenClawConfig> {
  const openclawHome = process.env.OPENCLAW_HOME || 
    path.join(os.homedir(), '.openclaw');
  
  const configPath = path.join(openclawHome, 'openclaw.json');
  
  try {
    const content = await fs.readFile(configPath, 'utf-8');
    return JSON.parse(content);
  } catch (error) {
    throw new Error(`Failed to read OpenClaw config: ${error.message}`);
  }
}

Reading Session Data

读取会话数据

typescript
// lib/sessions.ts
export async function getAgentSessions(agentName: string) {
  const openclawHome = process.env.OPENCLAW_HOME || 
    path.join(os.homedir(), '.openclaw');
  
  const sessionsDir = path.join(openclawHome, 'sessions', agentName);
  
  try {
    const files = await fs.readdir(sessionsDir);
    const sessions = await Promise.all(
      files
        .filter(f => f.endsWith('.json'))
        .map(async file => {
          const content = await fs.readFile(
            path.join(sessionsDir, file),
            'utf-8'
          );
          return JSON.parse(content);
        })
    );
    
    return sessions;
  } catch (error) {
    return [];
  }
}
typescript
// lib/sessions.ts
export async function getAgentSessions(agentName: string) {
  const openclawHome = process.env.OPENCLAW_HOME || 
    path.join(os.homedir(), '.openclaw');
  
  const sessionsDir = path.join(openclawHome, 'sessions', agentName);
  
  try {
    const files = await fs.readdir(sessionsDir);
    const sessions = await Promise.all(
      files
        .filter(f => f.endsWith('.json'))
        .map(async file => {
          const content = await fs.readFile(
            path.join(sessionsDir, file),
            'utf-8'
          );
          return JSON.parse(content);
        })
    );
    
    return sessions;
  } catch (error) {
    return [];
  }
}

Testing Platform Connection

测试平台连接

typescript
// lib/test.ts
export async function testPlatformConnection(
  platform: string,
  agentName: string
): Promise<{ success: boolean; message: string }> {
  const config = await readOpenClawConfig();
  const agent = config.agents.find(a => a.name === agentName);
  
  if (!agent) {
    return { success: false, message: 'Agent not found' };
  }
  
  const platformConfig = agent.platforms?.[platform];
  if (!platformConfig) {
    return { success: false, message: `${platform} not configured` };
  }
  
  if (platform === 'feishu') {
    // Test Feishu API
    try {
      const response = await fetch('https://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
          app_id: process.env[platformConfig.app_id] || platformConfig.app_id,
          app_secret: process.env[platformConfig.app_secret] || platformConfig.app_secret,
        }),
      });
      
      const data = await response.json();
      return {
        success: data.code === 0,
        message: data.code === 0 ? 'Connected' : data.msg,
      };
    } catch (error) {
      return { success: false, message: error.message };
    }
  }
  
  return { success: false, message: 'Platform test not implemented' };
}
typescript
// lib/test.ts
export async function testPlatformConnection(
  platform: string,
  agentName: string
): Promise<{ success: boolean; message: string }> {
  const config = await readOpenClawConfig();
  const agent = config.agents.find(a => a.name === agentName);
  
  if (!agent) {
    return { success: false, message: 'Agent未找到' };
  }
  
  const platformConfig = agent.platforms?.[platform];
  if (!platformConfig) {
    return { success: false, message: `${platform}未配置` };
  }
  
  if (platform === 'feishu') {
    // 测试飞书API
    try {
      const response = await fetch('https://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
          app_id: process.env[platformConfig.app_id] || platformConfig.app_id,
          app_secret: process.env[platformConfig.app_secret] || platformConfig.app_secret,
        }),
      });
      
      const data = await response.json();
      return {
        success: data.code === 0,
        message: data.code === 0 ? '连接成功' : data.msg,
      };
    } catch (error) {
      return { success: false, message: error.message };
    }
  }
  
  return { success: false, message: '平台测试未实现' };
}

Component Example: Bot Card

组件示例:Bot卡片

typescript
// components/BotCard.tsx
import { useState } from 'react';

interface BotCardProps {
  bot: {
    name: string;
    emoji: string;
    model: string;
    platforms: string[];
    sessionCount: number;
  };
}

export default function BotCard({ bot }: BotCardProps) {
  const [isTestingPlatform, setIsTestingPlatform] = useState(false);
  
  const testPlatform = async (platform: string) => {
    setIsTestingPlatform(true);
    try {
      const res = await fetch(
        `/api/test/platform?platform=${platform}&agentName=${bot.name}`
      );
      const data = await res.json();
      alert(data.message);
    } finally {
      setIsTestingPlatform(false);
    }
  };
  
  return (
    <div className="border rounded-lg p-4 shadow-sm hover:shadow-md transition">
      <div className="flex items-center gap-2 mb-2">
        <span className="text-3xl">{bot.emoji}</span>
        <h3 className="text-lg font-semibold">{bot.name}</h3>
      </div>
      
      <div className="text-sm text-gray-600 dark:text-gray-400">
        <p>Model: {bot.model}</p>
        <p>Sessions: {bot.sessionCount}</p>
      </div>
      
      <div className="mt-3 flex gap-2">
        {bot.platforms.map(platform => (
          <button
            key={platform}
            onClick={() => testPlatform(platform)}
            disabled={isTestingPlatform}
            className="px-2 py-1 text-xs bg-blue-500 text-white rounded hover:bg-blue-600 disabled:opacity-50"
          >
            Test {platform}
          </button>
        ))}
      </div>
    </div>
  );
}
typescript
// components/BotCard.tsx
import { useState } from 'react';

interface BotCardProps {
  bot: {
    name: string;
    emoji: string;
    model: string;
    platforms: string[];
    sessionCount: number;
  };
}

export default function BotCard({ bot }: BotCardProps) {
  const [isTestingPlatform, setIsTestingPlatform] = useState(false);
  
  const testPlatform = async (platform: string) => {
    setIsTestingPlatform(true);
    try {
      const res = await fetch(
        `/api/test/platform?platform=${platform}&agentName=${bot.name}`
      );
      const data = await res.json();
      alert(data.message);
    } finally {
      setIsTestingPlatform(false);
    }
  };
  
  return (
    <div className="border rounded-lg p-4 shadow-sm hover:shadow-md transition">
      <div className="flex items-center gap-2 mb-2">
        <span className="text-3xl">{bot.emoji}</span>
        <h3 className="text-lg font-semibold">{bot.name}</h3>
      </div>
      
      <div className="text-sm text-gray-600 dark:text-gray-400">
        <p>模型:{bot.model}</p>
        <p>会话数:{bot.sessionCount}</p>
      </div>
      
      <div className="mt-3 flex gap-2">
        {bot.platforms.map(platform => (
          <button
            key={platform}
            onClick={() => testPlatform(platform)}
            disabled={isTestingPlatform}
            className="px-2 py-1 text-xs bg-blue-500 text-white rounded hover:bg-blue-600 disabled:opacity-50"
          >
            测试{platform}
          </button>
        ))}
      </div>
    </div>
  );
}

Troubleshooting

故障排查

Dashboard Not Loading Bots

仪表板无法加载Bot

Problem: Dashboard shows no bots or "Config not found" error.
Solution:
bash
undefined
问题:仪表板显示无Bot或“未找到配置”错误。
解决方案
bash
undefined

Verify OpenClaw config exists

验证OpenClaw配置文件存在

ls -la ~/.openclaw/openclaw.json
ls -la ~/.openclaw/openclaw.json

Check permissions

检查权限

chmod 644 ~/.openclaw/openclaw.json
chmod 644 ~/.openclaw/openclaw.json

If using custom path, set env var

如果使用自定义路径,设置环境变量

export OPENCLAW_HOME=/path/to/openclaw npm run start
undefined
export OPENCLAW_HOME=/path/to/openclaw npm run start
undefined

Gateway Health Shows Unhealthy

网关健康状态显示异常

Problem: Gateway indicator shows red or unreachable.
Solution:
bash
undefined
问题:网关指示器显示红色或无法访问。
解决方案
bash
undefined

Check if gateway is enabled in config

检查配置中网关是否启用

cat ~/.openclaw/openclaw.json | grep -A 3 gateway
cat ~/.openclaw/openclaw.json | grep -A 3 gateway

Verify gateway is running

验证网关是否在运行

netstat -an | grep 8080
netstat -an | grep 8080

Check OpenClaw gateway logs

查看OpenClaw网关日志

tail -f ~/.openclaw/logs/gateway.log
undefined
tail -f ~/.openclaw/logs/gateway.log
undefined

Platform Test Fails

平台测试失败

Problem: Clicking "Test Feishu" or "Test Discord" returns error.
Solution:
bash
undefined
问题:点击“测试飞书”或“测试Discord”返回错误。
解决方案
bash
undefined

Verify environment variables are set

验证环境变量已设置

echo $FEISHU_APP_ID echo $FEISHU_APP_SECRET
echo $FEISHU_APP_ID echo $FEISHU_APP_SECRET

Check if credentials are in openclaw.json

检查凭证是否在openclaw.json中

cat ~/.openclaw/openclaw.json | grep -A 5 feishu
cat ~/.openclaw/openclaw.json | grep -A 5 feishu

Ensure proper format (${VAR_NAME} or direct value)

确保格式正确(${VAR_NAME}或直接值)

Dashboard resolves process.env for ${} references

仪表板会解析${}引用的process.env变量

undefined
undefined

Sessions Not Showing

会话未显示

Problem: Session count shows 0 or sessions page is empty.
Solution:
bash
undefined
问题:会话数显示为0或会话页面为空。
解决方案
bash
undefined

Check sessions directory exists

检查会话目录是否存在

ls -la ~/.openclaw/sessions/
ls -la ~/.openclaw/sessions/

Verify agent has session files

验证Agent是否有会话文件

ls ~/.openclaw/sessions/my-agent/
ls ~/.openclaw/sessions/my-agent/

Check JSON file format

检查JSON文件格式

cat ~/.openclaw/sessions/my-agent/session1.json | jq .
undefined
cat ~/.openclaw/sessions/my-agent/session1.json | jq .
undefined

Docker Container Can't Read Config

Docker容器无法读取配置

Problem: Docker container shows "Config not found" error.
Solution:
bash
undefined
问题:Docker容器显示“未找到配置”错误。
解决方案
bash
undefined

Mount OpenClaw directory correctly

正确挂载OpenClaw目录

docker run -d --name openclaw-dashboard
-p 3000:3000
-v $HOME/.openclaw:/root/.openclaw:ro
openclaw-dashboard
docker run -d --name openclaw-dashboard
-p 3000:3000
-v $HOME/.openclaw:/root/.openclaw:ro
openclaw-dashboard

For custom path, use OPENCLAW_HOME

自定义路径请使用OPENCLAW_HOME

docker run -d --name openclaw-dashboard
-p 3000:3000
-e OPENCLAW_HOME=/data/openclaw
-v /opt/openclaw:/data/openclaw:ro
openclaw-dashboard
docker run -d --name openclaw-dashboard
-p 3000:3000
-e OPENCLAW_HOME=/data/openclaw
-v /opt/openclaw:/data/openclaw:ro
openclaw-dashboard

Check logs

查看日志

docker logs openclaw-dashboard
undefined
docker logs openclaw-dashboard
undefined

Auto-Refresh Not Working

自动刷新不生效

Problem: Dashboard doesn't update automatically.
Solution:
typescript
// Check if refresh interval is set
// In browser dev tools:
localStorage.getItem('dashboardRefreshInterval')

// Should return: '10s', '30s', '1m', '5m', or '10m'

// Clear and reset
localStorage.removeItem('dashboardRefreshInterval')
// Then select interval from dropdown again
问题:仪表板未自动更新。
解决方案
typescript
undefined

Build Fails

检查是否已设置刷新间隔

在浏览器开发者工具中执行:

Problem:
npm run build
errors.
Solution:
bash
undefined
localStorage.getItem('dashboardRefreshInterval')

Clear cache and reinstall

返回值应为:'10s', '30s', '1m', '5m' 或 '10m'

清除并重新设置

rm -rf node_modules package-lock.json npm install
localStorage.removeItem('dashboardRefreshInterval')

Use Node 18+

然后从下拉菜单重新选择间隔

node --version # Should be v18.0.0 or higher
undefined

Check for TypeScript errors

构建失败

npm run type-check
问题
npm run build
执行报错。
解决方案
bash
undefined

Build with verbose output

清除缓存并重新安装依赖

npm run build -- --debug
undefined
rm -rf node_modules package-lock.json npm install

Additional Resources

使用Node 18+版本

检查TypeScript错误

npm run type-check

启用详细输出构建

npm run build -- --debug
undefined

额外资源