openclaw-bot-review-dashboard
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseOpenClaw Bot Review Dashboard
OpenClaw Bot 审查仪表板
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 and local session files to display:
~/.openclaw/openclaw.json- 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
undefinedbash
undefinedClone the repository
克隆仓库
git clone https://github.com/xmanrui/OpenClaw-bot-review.git
cd OpenClaw-bot-review
git clone https://github.com/xmanrui/OpenClaw-bot-review.git
cd OpenClaw-bot-review
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
undefinedbash
undefinedBuild for production
构建生产版本
npm run build
npm run build
Start production server
启动生产服务器
npm run start
undefinednpm run start
undefinedDocker Deployment
Docker部署
bash
undefinedbash
undefinedBuild 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
-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
-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
-p 3000:3000
-e OPENCLAW_HOME=/opt/openclaw
-v /path/to/openclaw:/opt/openclaw:ro
openclaw-dashboard
undefineddocker run -d --name openclaw-dashboard
-p 3000:3000
-e OPENCLAW_HOME=/opt/openclaw
-v /path/to/openclaw:/opt/openclaw:ro
openclaw-dashboard
-p 3000:3000
-e OPENCLAW_HOME=/opt/openclaw
-v /path/to/openclaw:/opt/openclaw:ro
openclaw-dashboard
undefinedRequirements
环境要求
- 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
undefinedbash
undefinedCustom 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
undefinedOPENCLAW_HOME=/opt/openclaw npm run start
undefinedDirectory 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/ # 已安装的SkillOpenClaw Configuration
OpenClaw配置
The dashboard reads from :
openclaw.jsonjson
{
"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.jsonjson
{
"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 cornertypescript
// 可用刷新间隔:
// - 手动(无自动刷新)
// - 10秒
// - 30秒
// - 1分钟
// - 5分钟
// - 10分钟
// 从右上角下拉菜单选择Theme and Language
主题与语言
typescript
// Theme toggle: Light / Dark mode
// Available in sidebar
// Language toggle: English / 中文
// Available in top navigationtypescript
// 主题切换:亮色/暗色模式
// 在侧边栏中设置
// 语言切换:英文/中文
// 在顶部导航栏中设置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
undefinedVerify 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
undefinedexport OPENCLAW_HOME=/path/to/openclaw
npm run start
undefinedGateway Health Shows Unhealthy
网关健康状态显示异常
Problem: Gateway indicator shows red or unreachable.
Solution:
bash
undefined问题:网关指示器显示红色或无法访问。
解决方案:
bash
undefinedCheck 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
undefinedtail -f ~/.openclaw/logs/gateway.log
undefinedPlatform Test Fails
平台测试失败
Problem: Clicking "Test Feishu" or "Test Discord" returns error.
Solution:
bash
undefined问题:点击“测试飞书”或“测试Discord”返回错误。
解决方案:
bash
undefinedVerify 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变量
undefinedundefinedSessions Not Showing
会话未显示
Problem: Session count shows 0 or sessions page is empty.
Solution:
bash
undefined问题:会话数显示为0或会话页面为空。
解决方案:
bash
undefinedCheck 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 .
undefinedcat ~/.openclaw/sessions/my-agent/session1.json | jq .
undefinedDocker Container Can't Read Config
Docker容器无法读取配置
Problem: Docker container shows "Config not found" error.
Solution:
bash
undefined问题:Docker容器显示“未找到配置”错误。
解决方案:
bash
undefinedMount OpenClaw directory correctly
正确挂载OpenClaw目录
docker run -d --name openclaw-dashboard
-p 3000:3000
-v $HOME/.openclaw:/root/.openclaw:ro
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
-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
-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
-p 3000:3000
-e OPENCLAW_HOME=/data/openclaw
-v /opt/openclaw:/data/openclaw:ro
openclaw-dashboard
Check logs
查看日志
docker logs openclaw-dashboard
undefineddocker logs openclaw-dashboard
undefinedAuto-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
undefinedBuild Fails
检查是否已设置刷新间隔
—
在浏览器开发者工具中执行:
Problem: errors.
npm run buildSolution:
bash
undefinedlocalStorage.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
undefinedCheck for TypeScript errors
构建失败
npm run type-check
问题:执行报错。
npm run build解决方案:
bash
undefinedBuild with verbose output
清除缓存并重新安装依赖
npm run build -- --debug
undefinedrm -rf node_modules package-lock.json
npm install
Additional Resources
使用Node 18+版本
node --version # 应为v18.0.0或更高
—
检查TypeScript错误
—
npm run type-check
—
启用详细输出构建
—
npm run build -- --debug
undefined—