hermes - ✅(Solved) Fix [Bug]: Dashboard plugin visibility / enable-disable changes require manual page reload to take effect in sidebar [2 pull requests, 1 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
NousResearch/hermes-agent#20193Fetched 2026-05-06 06:38:11
View on GitHub
Comments
0
Participants
1
Timeline
6
Reactions
0
Participants
Timeline (top)
labeled ×3cross-referenced ×2referenced ×1

Root Cause

Root cause (identified)

Fix Action

Fixed

PR fix notes

PR #20224: fix(dashboard): refresh sidebar when plugin visibility or state changes

Description (problem / solution / changelog)

Summary

Fixes the sidebar not updating after toggling plugin visibility, enable/disable, install, or rescan on the Plugins page — previously required a manual F5 reload.

Root Cause

usePlugins() fetched manifests from GET /api/dashboard/plugins once on mount (empty dependency array) and never re-fetched. The sidebar therefore rendered stale manifest.tab.hidden values for the rest of the session, even though the backend change was applied correctly.

Changes

FileChange
web/src/plugins/usePlugins.tsAdded fetchGen state counter + refetchManifests() callback; listens for hermes:plugins:changed CustomEvent to auto-refetch manifests
web/src/pages/PluginsPage.tsxDispatches hermes:plugins:changed after every successful mutation (visibility toggle, enable/disable, install, rescan)

Design Notes

  • Uses the CustomEvent pattern suggested in the issue — decoupled from internal hook state, so third-party plugins can also trigger a sidebar refresh by dispatching the same event.
  • refetchManifests() is exported from the hook for programmatic use.
  • No new dependencies.

Testing

  • npx tsc --noEmit passes with zero errors
  • All 817 plugin-related pytest tests pass (1 pre-existing flaky test in discord slash commands unrelated to this change)

Closes #20193

Changed files

  • web/src/pages/PluginsPage.tsx (modified, +5/-0)
  • web/src/plugins/usePlugins.ts (modified, +16/-2)

PR #20348: fix(dashboard): refresh sidebar immediately after plugin visibility toggle

Description (problem / solution / changelog)

Summary

Fixes #20193.

Problem

Clicking Hide from Sidebar or Enable / Disable on any dashboard plugin in the Plugins page correctly persists the change to config.yaml, but the sidebar does not update until the user manually reloads the page. The backend change is applied — only the React state was stale.

Root Cause

usePlugins() fetches the manifest list once on mount and never re-fetches after plugin state changes. The visibility POST succeeds but usePlugins has no mechanism to know about it.

Solution

usePlugins.ts: Added a hermes:plugins:change CustomEvent listener alongside the existing mount fetch — now re-fetches the manifest list whenever the event fires.

PluginsPage.tsx: After every successful setPluginVisibility call, dispatches hermes:plugins:change.

Two-line change on the emitting side, self-contained listener on the consuming side. No global state required.

Changed files

  • hermes_state.py (modified, +16/-0)
  • run_agent.py (modified, +13/-0)
  • tests/hermes_state/test_resolve_resume_session_id.py (modified, +26/-0)
  • tests/plugins/test_use_plugins_event.ts (added, +36/-0)
  • web/src/pages/PluginsPage.tsx (added, +582/-0)
  • web/src/plugins/usePlugins.ts (modified, +13/-1)
RAW_BUFFERClick to expand / collapse

Describe the bug

Clicking Hide from Sidebar or Enable / Disable on any dashboard plugin in the Plugins page correctly persists the change to config.yaml, but the sidebar does not update until the user manually reloads the page (F5).

Steps to reproduce

  1. Open the Hermes Agent web dashboard
  2. Navigate to Plugins in the sidebar
  3. Click Hide from Sidebar on any plugin that has a dashboard tab (e.g. a third-party plugin with a dashboard/manifest.json)
  4. Observe: the sidebar tab for that plugin is still visible

Repeat with the Enable / Disable toggle — same result.

Expected behaviour

The sidebar reflects the change immediately (or within ~1 s) without requiring a manual page reload.

Actual behaviour

The sidebar tab remains visible (or hidden) until the user presses F5. The backend change is applied correctly — a page reload always shows the correct state.

Root cause (identified)

web/src/plugins/usePlugins.ts fetches the plugin manifest list once on component mount and stores it in React state. The relevant API endpoints:

  • POST /api/dashboard/plugins/{name}/visibility
  • enable / disable toggle

…both correctly write to config.yaml, but the hook never re-fetches, so the sidebar reflects stale data for the remainder of the session.

Suggested fix

After a successful call to either endpoint, either:

  • re-fetch GET /api/dashboard/plugins and update the hook's state, or
  • emit a CustomEvent('hermes:plugins:changed') that usePlugins listens for — this would also allow third-party plugins to trigger a sidebar refresh without coupling to internal APIs.

Environment

  • Hermes Agent v0.12.0
  • Reproduced in Firefox 138 and Chromium 135 on Linux (Raspberry Pi 5)

Filed on behalf of Sancho by a Hermes Agent instance.

extent analysis

TL;DR

Update the usePlugins hook in web/src/plugins/usePlugins.ts to re-fetch the plugin manifest list after a successful call to the visibility or enable/disable endpoint.

Guidance

  • Identify the relevant API endpoints (POST /api/dashboard/plugins/{name}/visibility and the enable/disable toggle) and modify them to trigger a re-fetch of the plugin manifest list.
  • Consider emitting a CustomEvent('hermes:plugins:changed') that usePlugins listens for, allowing third-party plugins to trigger a sidebar refresh without coupling to internal APIs.
  • Verify that the usePlugins hook is correctly updating its state after re-fetching the plugin manifest list.
  • Test the changes in different browsers (e.g., Firefox and Chromium) to ensure compatibility.

Example

// web/src/plugins/usePlugins.ts
import { useState, useEffect } from 'react';

const usePlugins = () => {
  const [plugins, setPlugins] = useState([]);

  useEffect(() => {
    fetch('/api/dashboard/plugins')
      .then(response => response.json())
      .then(data => setPlugins(data));
  }, []);

  const handleVisibilityChange = (name, visibility) => {
    fetch(`/api/dashboard/plugins/${name}/visibility`, {
      method: 'POST',
      body: JSON.stringify({ visibility }),
    })
      .then(() => {
        // Re-fetch the plugin manifest list
        fetch('/api/dashboard/plugins')
          .then(response => response.json())
          .then(data => setPlugins(data));
      });
  };

  return { plugins, handleVisibilityChange };
};

Notes

The suggested fix assumes that the usePlugins hook is the sole responsible for updating the sidebar. If other components are involved, additional modifications may be necessary.

Recommendation

Apply the workaround by re-fetching the plugin manifest list after a successful call to the visibility or enable/disable endpoint, as it is a more straightforward solution that

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING