/add-dashboard
Add a monitoring dashboard to NanoClaw. Installs @nanoco/nanoclaw-dashboard and a pusher that sends periodic JSON snapshots.
Claude Code
$ npx -y skills add nanocoai/nanoclaw --skill add-dashboard --agent claude-code
Codex
$ npx skills add nanocoai/nanoclaw --skill add-dashboard -a codex -y
Cursor
$ npx skills add nanocoai/nanoclaw --skill add-dashboard -a cursor -y
Gemini CLI
$ npx skills add nanocoai/nanoclaw --skill add-dashboard -a gemini-cli -y
GitHub Copilot
$ npx skills add nanocoai/nanoclaw --skill add-dashboard -a github-copilot -y
OpenCode
$ npx skills add nanocoai/nanoclaw --skill add-dashboard -a opencode -y
Windsurf
$ npx skills add nanocoai/nanoclaw --skill add-dashboard -a windsurf -y
SKILL.md
add-dashboard.SKILL.mdname: add-dashboard
description: Add a monitoring dashboard to NanoClaw. 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 and its tests
Copy all three resource files into `src/`. The tests ship with the skill and run against the composed project — they're how you confirm the skill works and is wired in correctly.
.claude/skills/add-dashboard/resources/dashboard-pusher.ts → src/dashboard-pusher.ts
.claude/skills/add-dashboard/resources/dashboard-pusher.test.ts → src/dashboard-pusher.test.ts
.claude/skills/add-dashboard/resources/dashboard-wiring.test.ts → src/dashboard-wiring.test.ts
- `dashboard-pusher.test.ts` — behavior: starts the pusher, posts a real snapshot to a fake dashboard.
- `dashboard-wiring.test.ts` — the code edit in step 3: asserts (via the TS AST) that `index.ts` dynamically imports `./dashboard-pusher.js` and `await`s `startDashboard()` as colocated statements of `main()`, after DB init and before the boot-complete log. Delete or misplace the edit and this goes red.
3. Wire into src/index.ts
This is the skill's one integration point, and it's deliberately minimal and self-contained: all the startup logic lives in `dashboard-pusher.ts`, and the import is **colocated** with the call so the whole edit is a single block in one place — there's no separate top-of-file import to add (or to remember to remove).
Add this block inside `main()`, just before the `log.info('NanoClaw running')` line:
// Dashboard (optional; no-ops without DASHBOARD_SECRET)
const { startDashboard } = await import('./dashboard-pusher.js');
await startDashboard();`startDashboard()` reads `DASHBOARD_SECRET`/`DASHBOARD_PORT` itself and no-ops if the secret is unset, so nothing else in core needs to change.
4. 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'))"`
5. Build, test, and restart
Run from your NanoClaw project root:
pnpm run build
pnpm exec vitest run src/dashboard-pusher.test.ts src/dashboard-wiring.test.ts # behavior + wiring
source setup/lib/install-slug.sh
systemctl --user restart $(systemd_unit) # Linux
# or: launchctl kickstart -k gui/$(id -u)/$(launchd_label) # macOS
Run `build` **before** the tests: it's what guards the `@nanoco/nanoclaw-dashboard` dependency. `dashboard-pusher.ts` reaches the package through `await import('@nanoco/nanoclaw-dashboard')`, so if step 4 was skipped, `pnpm run build` fails with `TS2307: Cannot find module`. The behavior test deliberately *mocks* that package — its `startDashboard` binds a real dashboard port, a side effect we don't want in a test — so the test alone would pass with the dependency missing. Build is therefore the leg that verifies the dependency is installed; keep it ahead of the tests in the validate step.
6. Verify (runtime smoke check)
Once the service is restarted, confirm the dashboard is live:
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
Reverse the apply steps. Safe to re-run even if some pieces are already gone.
rm -f src/dashboard-pusher.ts src/dashboard-pusher.test.ts src/dashboard-wiring.test.ts
pnpm uninstall @nanoco/nanoclaw-dashboard 2>/dev/null || true
Then, by hand, remove the single dashboard block the skill added to `main()` in `src/index.ts` (the `// Dashboard (optional…)` comment, the `await import('./dashboard-pusher.js')` line, and the `await startDashboard();` call), and remove `DASHBOARD_SECRET` and `DASHBOARD_PORT` from `.env`.
pnpm run build
Read more
name: add-dashboard description: Add a monitoring dashboard to NanoClaw. 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 and its tests
Copy all three resource files into `src/`. The tests ship with the skill and run against the composed project — they're how you confirm the skill works and is wired in correctly.
.claude/skills/add-dashboard/resources/dashboard-pusher.ts → src/dashboard-pusher.ts .claude/skills/add-dashboard/resources/dashboard-pusher.test.ts → src/dashboard-pusher.test.ts .claude/skills/add-dashboard/resources/dashboard-wiring.test.ts → src/dashboard-wiring.test.ts
- `dashboard-pusher.test.ts` — behavior: starts the pusher, posts a real snapshot to a fake dashboard.
- `dashboard-wiring.test.ts` — the code edit in step 3: asserts (via the TS AST) that `index.ts` dynamically imports `./dashboard-pusher.js` and `await`s `startDashboard()` as colocated statements of `main()`, after DB init and before the boot-complete log. Delete or misplace the edit and this goes red.
3. Wire into src/index.ts
This is the skill's one integration point, and it's deliberately minimal and self-contained: all the startup logic lives in `dashboard-pusher.ts`, and the import is **colocated** with the call so the whole edit is a single block in one place — there's no separate top-of-file import to add (or to remember to remove).
Add this block inside `main()`, just before the `log.info('NanoClaw running')` line:
// Dashboard (optional; no-ops without DASHBOARD_SECRET)
const { startDashboard } = await import('./dashboard-pusher.js');
await startDashboard();`startDashboard()` reads `DASHBOARD_SECRET`/`DASHBOARD_PORT` itself and no-ops if the secret is unset, so nothing else in core needs to change.
4. 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'))"`
5. Build, test, and restart
Run from your NanoClaw project root:
pnpm run build pnpm exec vitest run src/dashboard-pusher.test.ts src/dashboard-wiring.test.ts # behavior + wiring source setup/lib/install-slug.sh systemctl --user restart $(systemd_unit) # Linux # or: launchctl kickstart -k gui/$(id -u)/$(launchd_label) # macOS
Run `build` **before** the tests: it's what guards the `@nanoco/nanoclaw-dashboard` dependency. `dashboard-pusher.ts` reaches the package through `await import('@nanoco/nanoclaw-dashboard')`, so if step 4 was skipped, `pnpm run build` fails with `TS2307: Cannot find module`. The behavior test deliberately *mocks* that package — its `startDashboard` binds a real dashboard port, a side effect we don't want in a test — so the test alone would pass with the dependency missing. Build is therefore the leg that verifies the dependency is installed; keep it ahead of the tests in the validate step.
6. Verify (runtime smoke check)
Once the service is restarted, confirm the dashboard is live:
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
Reverse the apply steps. Safe to re-run even if some pieces are already gone.
rm -f src/dashboard-pusher.ts src/dashboard-pusher.test.ts src/dashboard-wiring.test.ts pnpm uninstall @nanoco/nanoclaw-dashboard 2>/dev/null || true
Then, by hand, remove the single dashboard block the skill added to `main()` in `src/index.ts` (the `// Dashboard (optional…)` comment, the `await import('./dashboard-pusher.js')` line, and the `await startDashboard();` call), and remove `DASHBOARD_SECRET` and `DASHBOARD_PORT` from `.env`.
pnpm run build
A lightweight alternative to OpenClaw that runs in containers for security. Connects to WhatsApp, Telegram, Slack, Discord, Gmail and other messaging apps,, has memory, scheduled jobs, and runs directly on Anthropic's Agents SDK
Other skills on nanoclaw.
More skills from other plugins.
browser-use
Direct browser control via CDP for web interaction: automation, scraping, testing, screenshots, and site/app work. Also covers…
agent-browser
Browser automation CLI for AI agents. Use when the user needs to interact with websites, including navigating pages, filling…
opencli-adapter-author
Build or improve an OpenCLI JS adapter using observed site behavior, existing adapters and browser API evidence. For ad-hoc…
Questions about add-dashboard.
- Which coding agents can use add-dashboard?
- add-dashboard installs in Claude Code, Codex, Cursor, Gemini CLI, GitHub Copilot, OpenCode and Windsurf with the skills CLI, using each agent's flag shown on this page. Flowy's auto-invocation, which fires a skill when your prompt matches, runs in Claude Code only.

