Files
nanoclaw/.claude/skills/add-dashboard/SKILL.md
gavrielc 22498ae69c fix: remaining npm→pnpm gaps + dockerignore for pnpm symlinks
- container/.dockerignore (new): exclude agent-runner/node_modules and
  agent-runner/dist so COPY agent-runner/ ./ doesn't clobber the
  pnpm-installed node_modules with host directories. Under npm's flat
  layout this was forgiving; under pnpm's symlink layout it's a hard
  conflict (overlay2 cannot copy onto a symlink target).
- setup/{groups,service}.ts: execSync('pnpm run build') not npm.
- setup/index.ts: usage string.
- scripts/*.ts: usage comments + seed-discord final log.
- .claude/settings.json: permission allowlist entries.
- .claude/skills/{add-whatsapp-v2,add-dashboard}/SKILL.md: docs.
- container/skills/{frontend-engineer,vercel-cli,self-customize}/SKILL.md:
  agent-facing docs still told the container agent to run npm.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-17 09:53:00 +03:00

4.1 KiB

name, description
name description
add-dashboard 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

pnpm 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:

// 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:

import { readEnvFile } from './env.js';

Add after step 7 (OneCLI approval handler), before the log.info('NanoClaw v2 running') line:

  // 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

pnpm run build
systemctl --user restart nanoclaw   # Linux
# or: launchctl kickstart -k gui/$(id -u)/com.nanoclaw  # macOS

7. Verify

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

pnpm 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
pnpm run build