hermes-bsd/tests/fixtures/plugins/example-dashboard/dashboard/plugin_api.py

25 lines
1 KiB
Python
Raw Permalink Normal View History

feat(dashboard): nous-blue theme, bulk sessions, schedule picker (#37383) * feat(dashboard): nous-blue theme, bulk sessions, schedule picker Batch of related dashboard improvements gathered on austin/fix/dashboard-changes: * Nous Blue theme — faithful port of the LENS_5I overlay system onto the existing DashboardTheme. Lifts the foreground inversion layer to z-index 200 to fix the long-standing hover / loading visual artifact, adds an explicit swatchColors slot so the theme picker shows the post-inversion preview, and migrates the legacy "lens-5i" theme key from localStorage / API to "nous-blue" on first read. * Theme-aware series colors: new --series-input-token / --series-output-token CSS vars consumed by Analytics + Models charts; ToolCall + ModelInfoCard switched to semantic --color-success for diff lines and the Tools capability badge. * Analytics + Models headers: consolidate period selector + refresh next to the page title and drop the redundant period badge. * Bulk session management — "Delete empty (N)" button + per-row checkboxes with shift-click range select and a bulk-delete action bar. Backed by SessionDB.delete_sessions() / delete_empty_sessions() plus POST /api/sessions/bulk-delete and DELETE /api/sessions/empty (registered before the templated /api/sessions/{session_id} family so they don't get shadowed). Hard cap of 500 IDs per bulk request. Full pytest coverage. * Cron page — human-readable schedule picker (every-interval / daily / weekly / monthly / once / custom) replaces the raw cron expression input; the job list now renders "Weekly on Mon, Wed, Fri at 14:30" instead of "30 14 * * 1,3,5". English-only ordinals for monthly schedules so non-English locales don't get incorrect suffixes. * example-dashboard plugin moved from plugins/ to tests/fixtures/ so stock installs no longer ship the demo. Tests install it dynamically via a pytest fixture that also reorders the FastAPI routes. * i18n: 40+ new keys for the bulk-select UI and schedule picker/describer translated across all 16 locales. Co-authored-by: Cursor <cursoragent@cursor.com> * refactor(dashboard): dedupe memory provider picker The memory provider <Select> lived on both /system and /plugins, writing the same config.yaml field through two different endpoints with no cross-page refresh. Remove the picker from /system in favor of a read-only status row + link to /plugins, where it pairs with the context-engine picker under "Plugin providers". /system retains the destructive admin controls (file sizes, Reset MEMORY.md / USER.md / all). The api.setMemoryProvider client and PUT /api/memory/provider backend endpoint are left in place for CLI / script callers. Co-authored-by: Cursor <cursoragent@cursor.com> * docs(dashboard): address Copilot review on PR #37383 - Backdrop layer-stack comment claimed LENS_5I-style themes override --component-backdrop-bg-blend-mode to multiply, but our only LENS_5I-style theme (nous-blue) keeps the default difference. Reword to describe what the code actually does and present the var as a forward-looking extension hook. - /api/sessions/bulk-delete docstring promised the response would echo back the list of deleted IDs, but the implementation only returns {ok, deleted}. Tighten the docstring to match the wire format; the client already knows what it asked to delete, so the IDs aren't needed. Co-authored-by: Cursor <cursoragent@cursor.com> * fix(dashboard): address copilot review on cron describe + bulk-select checkbox - schedule.ts: restrict `describeCronExpression` to strictly 5-field cron expressions. The backend `parse_schedule` also accepts the 6-field `min hour dom month dow year` form, and humanising those by destructuring only the first five fields would silently drop the year (e.g. ``0 9 * * * 2099`` rendered as "Daily at 09:00"). 6+ field expressions now fall through to the raw-string fallback so the user sees what's actually scheduled. - SessionsPage.tsx (SessionRow): wire the bulk-select Checkbox's ``onClick`` directly instead of attaching it to a parent ``<span>`` with a no-op ``onCheckedChange``. Radix forwards onClick to the underlying ``<button role=checkbox>``, so the same handler now drives both mouse clicks (preserving shift-key state for range select) and keyboard activation (Space on the focused checkbox, which the browser synthesises as a click on the <button>). Improves a11y / keyboard UX without changing the controlled-selection model. - SessionsPage.tsx: also extend ``SessionRowProps`` with the new ``onRename`` / ``onExport`` props introduced on main so the row's destructured prop types resolve after the merge. Co-authored-by: Cursor <cursoragent@cursor.com> --------- Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-02 12:37:40 -04:00
"""Example dashboard plugin — backend API routes (test fixture).
This plugin lives under ``tests/fixtures/plugins/`` so it is NOT shipped as
part of the bundled-plugins set; a stock hermes-agent install does not see
an "Example" tab in its sidebar. The ``_install_example_plugin`` pytest
fixture in ``tests/hermes_cli/test_web_server.py`` copies this directory
into ``$HERMES_HOME/plugins/example-dashboard/`` and forces the dashboard
plugin discovery cache to rescan, so tests that need a stable, side-effect-
free GET endpoint to verify plugin API auth + static-asset behaviour can
hit ``/api/plugins/example/hello`` (and ``/dashboard-plugins/example/
manifest.json``) without depending on any production-facing plugin.
Mounted at /api/plugins/example/ by the dashboard plugin system.
"""
from fastapi import APIRouter
router = APIRouter()
@router.get("/hello")
async def hello():
"""Simple greeting endpoint to demonstrate plugin API routes."""
return {"message": "Hello from the example plugin!", "plugin": "example", "version": "1.0.0"}