feat(dashboard): complete admin panel — MCP catalog, enable/disable toggles, hook creation, system stats#36736
Conversation
mxnstrexgl
left a comment
There was a problem hiding this comment.
🤖 Automated PR Review
Security Scan
- ✓ No hardcoded secrets, injection sinks, unsafe deserialization, or dependency red flags found by this automated scan.
Code Quality
- ✓ No blocking code-quality issues found by this automated scan.
Summary
Status: APPROVE — security findings: 0, quality suggestions: 0.
Automated review; raw diff content intentionally omitted.
🔎 Lint report:
|
| Rule | Count |
|---|---|
invalid-argument-type |
1 |
First entries
hermes_cli/web_server.py:4066: [invalid-argument-type] invalid-argument-type: Argument to bound method `SessionDB.prune_sessions` is incorrect: Expected `str`, found `(str & ~AlwaysFalsy) | None`
✅ Fixed issues (1):
| Rule | Count |
|---|---|
invalid-assignment |
1 |
First entries
hermes_cli/web_server.py:4706: [invalid-assignment] invalid-assignment: Object of type `list[object]` is not assignable to `list[str]`
Unchanged: 4976 pre-existing issues carried over.
Diagnostics are surfaced as warnings — this check never fails the build.
…reate/delete, system stats
Backend for the comprehensive admin pass:
- MCP: GET /api/mcp/catalog (browse Nous-approved optional-mcps), POST
/api/mcp/catalog/install, PUT /api/mcp/servers/{name}/enabled
- Webhooks: PUT /api/webhooks/{name}/enabled; gateway rejects disabled routes
with 403 (hot-reloaded, no restart)
- Hooks: POST/DELETE /api/ops/hooks — create (with consent approval) + remove;
list now reports accurate allowlist status + valid events
- System: GET /api/system/stats — OS/arch/python/cpu + psutil memory/disk/
uptime/process, stdlib fallback
All gated by dashboard auth; secrets never returned.
… system stats - McpPage: catalog section (browse Nous-approved MCPs, one-click install with env prompts) + per-server enable/disable toggle with gateway-restart note - WebhooksPage: per-subscription enable/disable toggle (muted + badge when off) - SystemPage: new Host stats section (OS/arch/python/cpu/mem/disk/uptime/load), shell-hook create modal + delete, 'Create backup' label - api.ts: client methods + types for catalog, toggles, hook CRUD, system stats
…hook toggle Adds tests for the comprehensive pass: MCP enable/disable + catalog list + catalog-install-unknown, hook create/delete with consent, system stats shape, and webhook enable/disable. 26 tests total, all green.
…shots Updates the MCP/Webhooks/Pairing/System sections for catalog browse+install, enable/disable toggles, hook creation, and host system stats; adds the new endpoints to the API table; replaces the screenshots with live captures of the rebuilt pages (real data, no dummies) including the hook-create modal.
… ops Closes the last in-scope CLI gaps from the coverage audit: - Curator: GET /api/curator (status), PUT /api/curator/paused, POST /api/curator/run (background) - Portal: GET /api/portal (Nous auth + Tool Gateway routing, read-only) - Diagnostics: POST /api/ops/prompt-size, /api/ops/dump, /api/ops/config-migrate (backgrounded, tailed via action status) Host-bound commands (secrets/proxy/lsp/acp/computer-use/desktop/completion/ postinstall/uninstall/claw) remain CLI-only by design.
- SystemPage: Nous Portal status section (auth + Tool Gateway routing), Skill curator card (status + pause/resume + run now), and three new Operations buttons (prompt size, support dump, migrate config) - api.ts: client methods + CuratorStatus/PortalStatus types - tests: curator pause/resume, portal shape, system-stats shape, + auth-gate coverage for the new GET endpoints (31 tests total)
…System screenshots Updates the System section for the Nous Portal status, Skill curator controls, and the new prompt-size/dump/migrate operations; adds them to the API table; refreshes the System screenshots (now showing Portal + Curator) and adds a dedicated curator/gateway/memory capture.
…ints
Completes the existing tabs' backend depth (audit vs CLI):
- Sessions: GET /api/sessions/stats (store stats), GET /api/sessions/{id}/export,
POST /api/sessions/prune. /stats is registered before /{session_id} so the
literal path isn't captured by the parameterized route.
- Skills: GET /api/skills/hub/search — parallel multi-source hub search (threaded),
returns installable identifiers
- (rename via PATCH and cron-edit via PUT already existed; now surfaced in UI)
…rowse, cron edit Audited every existing tab against its CLI command and filled the gaps: - Sessions: store stats bar, per-row rename + export (JSON download), and a prune-old-sessions control (mirrors hermes sessions rename/export/prune/stats) - Skills: new 'Browse hub' view — search the skill hub across all sources, install by identifier with a live install log, and 'Update all' (mirrors hermes skills search/install/update) - Cron: per-job Edit modal (pre-filled) calling updateCronJob (hermes cron edit) - api.ts: renameSession/getSessionStats/exportSessionUrl/pruneSessions, updateCronJob, searchSkillsHub + types Models tab was already comprehensive (provider+model picker, dynamic per-provider lists, main + all 11 aux-task assignments, reset) — verified, no change needed.
… search
Adds the route-shadowing guard for /api/sessions/stats (must not be captured
by /api/sessions/{session_id}), rename/export/prune, and the empty-query
short-circuit for hub search. 36 tests total, all green.
Sessions: stats bar, rename, export, prune (+ screenshot). Skills: new Browse hub view for search/install/update (+ screenshot). Cron: edit action. API table updated with the new endpoints.
a1e1680 to
d9d8b2c
Compare
There was a problem hiding this comment.
Pull request overview
This PR completes the web dashboard admin panel by adding browser-based management for MCP catalog install + enable/disable, webhook enable/disable gating, shell hook create/delete, and expanded System observability (host stats, curator controls, portal status, and additional diagnostics), along with new session-management UX improvements.
Changes:
- Add MCP catalog browsing/installation plus per-server enable/disable toggles; add per-webhook enable/disable toggles enforced by the gateway.
- Add shell hook create/delete flows (with consent) and expand the System page with host stats, curator controls, portal status, and new backgrounded diagnostics.
- Enhance admin UX across the dashboard (sessions stats/rename/export/prune, cron job editing modal, skills hub browsing/search/install/update) and expand backend test coverage.
Reviewed changes
Copilot reviewed 11 out of 20 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| website/docs/user-guide/features/web-dashboard.md | Updates dashboard docs and API table to reflect newly completed admin surfaces and screenshots. |
| web/src/pages/WebhooksPage.tsx | Adds enable/disable UI for webhook subscriptions and visually marks disabled routes. |
| web/src/pages/SystemPage.tsx | Adds host stats, portal + curator sections, shell hook create/delete modal, and new diagnostics actions. |
| web/src/pages/SkillsPage.tsx | Adds a “Browse hub” view for hub search + install/update with streamed background logs. |
| web/src/pages/SessionsPage.tsx | Adds session stats bar, rename/export actions, and prune-old-sessions dialog. |
| web/src/pages/McpPage.tsx | Adds MCP enable/disable, catalog listing + install flow (with required env prompt), and diagnostics display. |
| web/src/pages/CronPage.tsx | Adds cron job edit modal and wires it to a new update endpoint. |
| web/src/lib/api.ts | Adds typed client methods and types for all new admin endpoints (MCP catalog/toggles, webhooks toggle, hooks create/delete, system stats, curator/portal, sessions mgmt, hub search, cron update). |
| tests/hermes_cli/test_dashboard_admin_endpoints.py | Expands backend contract tests for new admin endpoints and route-shape guarantees. |
| hermes_cli/web_server.py | Implements new admin endpoints (system stats, curator, portal, diagnostics, sessions stats/export/prune, MCP catalog/install + enabled toggles, webhook enabled toggle, hooks create/delete, hub search). |
| gateway/platforms/webhook.py | Enforces disabled webhook routes by rejecting incoming events with 403. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| try: | ||
| info["cpu_percent"] = psutil.cpu_percent(interval=0.1) | ||
| la = getattr(psutil, "getloadavg", None) | ||
| if la: | ||
| info["load_avg"] = list(la()) | ||
| except Exception: | ||
| pass |
| by_source: Dict[str, int] = {} | ||
| try: | ||
| for s in db.list_sessions_rich(limit=10000, include_archived=True): | ||
| src = str(s.get("source") or "cli") | ||
| by_source[src] = by_source.get(src, 0) + 1 | ||
| except Exception: | ||
| pass |
| const createHook = async () => { | ||
| if (!hookCommand.trim()) { | ||
| showToast("Command is required", "error"); | ||
| return; | ||
| } | ||
| setCreatingHook(true); | ||
| try { | ||
| await api.createHook({ | ||
| event: hookEvent, | ||
| command: hookCommand.trim(), | ||
| matcher: hookMatcher.trim() || undefined, | ||
| timeout: hookTimeout.trim() ? Number(hookTimeout) : undefined, | ||
| approve: hookApprove, | ||
| }); |
…oggles, hook creation, system stats (NousResearch#36736) * feat(dashboard): MCP catalog + enable/disable, webhook toggle, hook create/delete, system stats Backend for the comprehensive admin pass: - MCP: GET /api/mcp/catalog (browse Nous-approved optional-mcps), POST /api/mcp/catalog/install, PUT /api/mcp/servers/{name}/enabled - Webhooks: PUT /api/webhooks/{name}/enabled; gateway rejects disabled routes with 403 (hot-reloaded, no restart) - Hooks: POST/DELETE /api/ops/hooks — create (with consent approval) + remove; list now reports accurate allowlist status + valid events - System: GET /api/system/stats — OS/arch/python/cpu + psutil memory/disk/ uptime/process, stdlib fallback All gated by dashboard auth; secrets never returned. * feat(dashboard): MCP catalog UI, enable/disable toggles, hook create, system stats - McpPage: catalog section (browse Nous-approved MCPs, one-click install with env prompts) + per-server enable/disable toggle with gateway-restart note - WebhooksPage: per-subscription enable/disable toggle (muted + badge when off) - SystemPage: new Host stats section (OS/arch/python/cpu/mem/disk/uptime/load), shell-hook create modal + delete, 'Create backup' label - api.ts: client methods + types for catalog, toggles, hook CRUD, system stats * test(dashboard): cover catalog, toggles, hook CRUD, system stats, webhook toggle Adds tests for the comprehensive pass: MCP enable/disable + catalog list + catalog-install-unknown, hook create/delete with consent, system stats shape, and webhook enable/disable. 26 tests total, all green. * docs(dashboard): document the comprehensive admin pass + fresh screenshots Updates the MCP/Webhooks/Pairing/System sections for catalog browse+install, enable/disable toggles, hook creation, and host system stats; adds the new endpoints to the API table; replaces the screenshots with live captures of the rebuilt pages (real data, no dummies) including the hook-create modal. * feat(dashboard): curator, portal status, and prompt-size/dump/migrate ops Closes the last in-scope CLI gaps from the coverage audit: - Curator: GET /api/curator (status), PUT /api/curator/paused, POST /api/curator/run (background) - Portal: GET /api/portal (Nous auth + Tool Gateway routing, read-only) - Diagnostics: POST /api/ops/prompt-size, /api/ops/dump, /api/ops/config-migrate (backgrounded, tailed via action status) Host-bound commands (secrets/proxy/lsp/acp/computer-use/desktop/completion/ postinstall/uninstall/claw) remain CLI-only by design. * feat(dashboard): curator + portal + diagnostics UI, tests - SystemPage: Nous Portal status section (auth + Tool Gateway routing), Skill curator card (status + pause/resume + run now), and three new Operations buttons (prompt size, support dump, migrate config) - api.ts: client methods + CuratorStatus/PortalStatus types - tests: curator pause/resume, portal shape, system-stats shape, + auth-gate coverage for the new GET endpoints (31 tests total) * docs(dashboard): document curator, portal, and diagnostics + refresh System screenshots Updates the System section for the Nous Portal status, Skill curator controls, and the new prompt-size/dump/migrate operations; adds them to the API table; refreshes the System screenshots (now showing Portal + Curator) and adds a dedicated curator/gateway/memory capture. * feat(dashboard): session stats/export/prune + skills hub search endpoints Completes the existing tabs' backend depth (audit vs CLI): - Sessions: GET /api/sessions/stats (store stats), GET /api/sessions/{id}/export, POST /api/sessions/prune. /stats is registered before /{session_id} so the literal path isn't captured by the parameterized route. - Skills: GET /api/skills/hub/search — parallel multi-source hub search (threaded), returns installable identifiers - (rename via PATCH and cron-edit via PUT already existed; now surfaced in UI) * feat(dashboard): complete existing tabs — sessions mgmt, skills hub browse, cron edit Audited every existing tab against its CLI command and filled the gaps: - Sessions: store stats bar, per-row rename + export (JSON download), and a prune-old-sessions control (mirrors hermes sessions rename/export/prune/stats) - Skills: new 'Browse hub' view — search the skill hub across all sources, install by identifier with a live install log, and 'Update all' (mirrors hermes skills search/install/update) - Cron: per-job Edit modal (pre-filled) calling updateCronJob (hermes cron edit) - api.ts: renameSession/getSessionStats/exportSessionUrl/pruneSessions, updateCronJob, searchSkillsHub + types Models tab was already comprehensive (provider+model picker, dynamic per-provider lists, main + all 11 aux-task assignments, reset) — verified, no change needed. * test(dashboard): cover session stats/rename/export/prune + skills hub search Adds the route-shadowing guard for /api/sessions/stats (must not be captured by /api/sessions/{session_id}), rename/export/prune, and the empty-query short-circuit for hub search. 36 tests total, all green. * docs(dashboard): document enhanced Sessions, Skills hub, and Cron edit Sessions: stats bar, rename, export, prune (+ screenshot). Skills: new Browse hub view for search/install/update (+ screenshot). Cron: edit action. API table updated with the new endpoints.
Summary
Completes the dashboard admin panel so MCP, webhooks, shell hooks, and system observability are fully manageable from the browser — no CLI, no dummy data, no read-only gaps.
This is the comprehensive follow-up to #36704 after review feedback: every admin surface that was thin is now feature-complete, and the System page gains host observability.
What changed
MCP
optional-mcps/catalog and install entries one-click (prompts for required env vars inline). Same cataloghermes mcp catalog/installuse.enabledflag; takes effect next gateway restart) — disabled servers stay in config.Webhooks
gateway/platforms/webhook.py); hot-reloaded, no restart.Shell hooks
System
psutilwhen present, stdlib fallback otherwise.Pairing — confirmed feature-complete vs
hermes pairing(approve/revoke/clear); no change needed.Files
hermes_cli/web_server.py: catalog list/install, mcp + webhook enable toggles, hook create/delete,/api/system/statsgateway/platforms/webhook.py: reject disabled routes (403)web/src/lib/api.ts+McpPage.tsx/WebhooksPage.tsx/SystemPage.tsx: catalog UI, toggles, hook-create modal, host statstests/hermes_cli/test_dashboard_admin_endpoints.py: +10 tests (26 total)website/docs/.../web-dashboard.md: updated sections + API table + live screenshots of the rebuilt pages (real data)Validation
tsc -b+npm run buildUpdate — full CLI coverage pass
Ran a complete
hermes --helpaudit (53 commands) and closed the last in-scope gaps:hermes curator)hermes portal)Remaining CLI-only commands are host-bound by design (secrets/bw, proxy, lsp, acp, computer-use, postinstall, completion, uninstall, claw, debug-upload, send). 42 commands have dashboard parity; 11 are intentionally CLI-only. 31 admin tests green.
Infographic