docs(v2): add /add-dashboard skill with resource-based pusher
Self-contained skill: SKILL.md has instructions, resources/ holds the dashboard-pusher.ts that gets copied to src/ at install time. No src/ changes until the skill is applied. npm package: @nanoco/nanoclaw-dashboard Repo: https://github.com/qwibitai/nanoclaw-dashboard Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
138
.claude/skills/add-dashboard/SKILL.md
Normal file
138
.claude/skills/add-dashboard/SKILL.md
Normal file
@@ -0,0 +1,138 @@
|
||||
---
|
||||
name: add-dashboard
|
||||
description: Add a monitoring dashboard to NanoClaw v2. Installs @nanoco/nanoclaw-dashboard and a pusher that sends periodic JSON snapshots.
|
||||
---
|
||||
|
||||
# /add-dashboard — NanoClaw Dashboard
|
||||
|
||||
Adds a local monitoring dashboard showing agent groups, sessions, channels, users, token usage, context windows, message activity, and real-time logs.
|
||||
|
||||
## Architecture
|
||||
|
||||
```
|
||||
NanoClaw (pusher) Dashboard (npm package)
|
||||
┌──────────┐ POST JSON ┌──────────────┐
|
||||
│ collects │ ────────────────→ │ /api/ingest │
|
||||
│ DB data │ every 60s │ in-memory │
|
||||
│ tails │ ────────────────→ │ /api/logs/ │
|
||||
│ log file │ every 2s │ push │
|
||||
└──────────┘ │ serves UI │
|
||||
└──────────────┘
|
||||
```
|
||||
|
||||
## Steps
|
||||
|
||||
### 1. Install the npm package
|
||||
|
||||
```bash
|
||||
npm install @nanoco/nanoclaw-dashboard
|
||||
```
|
||||
|
||||
### 2. Copy the pusher module
|
||||
|
||||
Copy the resource file into src:
|
||||
|
||||
```
|
||||
.claude/skills/add-dashboard/resources/dashboard-pusher.ts → src/dashboard-pusher.ts
|
||||
```
|
||||
|
||||
### 3. Add exports to src/db/index.ts
|
||||
|
||||
Add these two export blocks if not already present:
|
||||
|
||||
```typescript
|
||||
// After the messaging-groups exports, add:
|
||||
export {
|
||||
getMessagingGroupsByAgentGroup,
|
||||
} from './messaging-groups.js';
|
||||
|
||||
// Before the credentials exports, add:
|
||||
export {
|
||||
createDestination,
|
||||
getDestinations,
|
||||
getDestinationByName,
|
||||
getDestinationByTarget,
|
||||
hasDestination,
|
||||
deleteDestination,
|
||||
} from './agent-destinations.js';
|
||||
```
|
||||
|
||||
### 4. Wire into src/index.ts
|
||||
|
||||
Add the `readEnvFile` import at the top if not already present:
|
||||
|
||||
```typescript
|
||||
import { readEnvFile } from './env.js';
|
||||
```
|
||||
|
||||
Add after step 7 (OneCLI approval handler), before the `log.info('NanoClaw v2 running')` line:
|
||||
|
||||
```typescript
|
||||
// 8. Dashboard (optional)
|
||||
const dashboardEnv = readEnvFile(['DASHBOARD_SECRET', 'DASHBOARD_PORT']);
|
||||
const dashboardSecret = process.env.DASHBOARD_SECRET || dashboardEnv.DASHBOARD_SECRET;
|
||||
const dashboardPort = parseInt(process.env.DASHBOARD_PORT || dashboardEnv.DASHBOARD_PORT || '3100', 10);
|
||||
if (dashboardSecret) {
|
||||
const { startDashboard } = await import('@nanoco/nanoclaw-dashboard');
|
||||
const { startDashboardPusher } = await import('./dashboard-pusher.js');
|
||||
startDashboard({ port: dashboardPort, secret: dashboardSecret });
|
||||
startDashboardPusher({ port: dashboardPort, secret: dashboardSecret, intervalMs: 60000 });
|
||||
} else {
|
||||
log.info('Dashboard disabled (no DASHBOARD_SECRET)');
|
||||
}
|
||||
```
|
||||
|
||||
### 5. Add environment variables to .env
|
||||
|
||||
```
|
||||
DASHBOARD_SECRET=<generate-a-random-secret>
|
||||
DASHBOARD_PORT=3100
|
||||
```
|
||||
|
||||
Generate the secret: `node -e "console.log('nc-' + require('crypto').randomBytes(16).toString('hex'))"`
|
||||
|
||||
### 6. Build and restart
|
||||
|
||||
```bash
|
||||
npm run build
|
||||
systemctl --user restart nanoclaw # Linux
|
||||
# or: launchctl kickstart -k gui/$(id -u)/com.nanoclaw # macOS
|
||||
```
|
||||
|
||||
### 7. Verify
|
||||
|
||||
```bash
|
||||
curl -s http://localhost:3100/api/status
|
||||
curl -s -H "Authorization: Bearer <secret>" http://localhost:3100/api/overview
|
||||
```
|
||||
|
||||
Open `http://localhost:3100/dashboard` in a browser.
|
||||
|
||||
## Dashboard Pages
|
||||
|
||||
| Page | Shows |
|
||||
|------|-------|
|
||||
| Overview | Stats, token usage + cache hit rate, context windows, activity chart |
|
||||
| Agent Groups | Sessions, wirings, destinations, members, admins |
|
||||
| Sessions | Status, container state, context window usage bars |
|
||||
| Channels | Live/offline status, messaging groups, sender policies |
|
||||
| Messages | Per-session inbound/outbound messages |
|
||||
| Users | Privilege hierarchy: owner > admin > member |
|
||||
| Logs | Real-time log streaming with level filter |
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
- **"No data yet"**: Wait 60s for first push, or check logs for push errors
|
||||
- **401 errors**: Verify `DASHBOARD_SECRET` matches in `.env`
|
||||
- **Port conflict**: Change `DASHBOARD_PORT` in `.env`
|
||||
- **No logs**: Check `logs/nanoclaw.log` exists
|
||||
|
||||
## Removal
|
||||
|
||||
```bash
|
||||
npm uninstall @nanoco/nanoclaw-dashboard
|
||||
rm src/dashboard-pusher.ts
|
||||
# Remove the dashboard block from src/index.ts
|
||||
# Remove DASHBOARD_SECRET and DASHBOARD_PORT from .env
|
||||
npm run build
|
||||
```
|
||||
Reference in New Issue
Block a user