Skip to content

refactor(web): dashboard typography & contrast pass (salvage #28832 + sanitize follow-up)#30714

Merged
teknium1 merged 2 commits into
mainfrom
hermes/hermes-0d4fd3e6
May 23, 2026
Merged

refactor(web): dashboard typography & contrast pass (salvage #28832 + sanitize follow-up)#30714
teknium1 merged 2 commits into
mainfrom
hermes/hermes-0d4fd3e6

Conversation

@teknium1

@teknium1 teknium1 commented May 23, 2026

Copy link
Copy Markdown
Contributor

Salvages PR #28832 onto current main plus a small follow-up so the new slashed plugin routes actually work end-to-end.

What's in this PR

Commit 1 — refactor(web): dashboard typography & contrast pass (Austin Pickett, squashed)

Squashes all 19 commits from #28832. Original authorship preserved via --author=.

  • Removes the global uppercase + font-mondwest from the App.tsx root.
  • Introduces text-display from @nous-research/ui@0.16.0 on intentional brand chrome (page titles, sidebar headings, segmented filters) so the brand-uppercase look is opt-in per element rather than global.
  • Replaces stacked-alpha text colors (text-muted-foreground/60, opacity-30 on nav headers, etc.) with semantic text tokens (text-text-primary/secondary/tertiary/disabled) so contrast stays WCAG-AA across all 7 built-in themes.
  • Raises every sub-12px arbitrary text size to text-xs where it was actual content.
  • Maps --color-muted-foreground--color-text-secondary in index.css so existing call sites land on the new contrast floor without per-file changes.
  • Bumps @nous-research/ui 0.14.00.16.0, regenerates web/package-lock.json, refreshes nix/web.nix fetchNpmDeps hash.
  • New "Typography & contrast rules" section in web/README.md.

Beyond the original typography pass, the PR also picked up:

  • hermes_cli/web_server.py — widens the 5 dashboard plugin routes to {name:path} and relaxes _validate_plugin_name (still rejects .. and \, strips leading/trailing /, allows internal /). Enables enable/disable on category-namespaced plugin keys like observability/langfuse and image_gen/openai that the FE was encodeURIComponent-ing.
  • web/src/lib/api.ts — adds a pluginPath() helper that preserves / segments when building the URL.
  • Sessions / Env / Keys page chrome polish and two new i18n keys (overview, showMore/showLess) across all 18 locales.

Commit 2 — fix(plugins): widen _sanitize_plugin_name for category-namespaced names

The dashboard plugin routes in commit 1 accept slashed names, but _sanitize_plugin_name (the deeper guard used by update/remove on installed plugins) still rejected forward slash. So dashboard update/remove on a slashed plugin returned "not found" even though the directory existed.

  • Adds an opt-in allow_subdir=True flag that permits internal / and strips leading/trailing /, while still rejecting .. and \ and still asserting the resolved target lives inside plugins_dir.
  • Opted in at the two read-paths that operate on installed plugins (_require_installed_plugin for CLI update/remove, _user_installed_plugin_dir for the dashboard equivalents).
  • Install path keeps the default allow_subdir=False — freshly cloned plugins always land top-level under ~/.hermes/plugins/<name>/.
  • 6 new unit tests covering the new flag's allow/reject matrix.

Validation

  • scripts/run_tests.sh tests/hermes_cli/test_plugins_cmd.py — 71/71 passed (65 existing + 6 new).
  • E2E with an isolated HERMES_HOME and a real ~/.hermes/plugins/observability/langfuse/ checkout:
    • _sanitize_plugin_name(..., allow_subdir=True) resolves slashed name to the correct path.
    • Install path (allow_subdir=False) still rejects slash.
    • _user_installed_plugin_dir("observability/langfuse") returns the dir; dashboard_remove_user_plugin("observability/langfuse") succeeds and removes the directory.
    • .., \\, foo/../../etc all still rejected with allow_subdir=True.
    • Leading slash stripped; resolved target stays inside plugins_dir.

Closes

Closes #28832 (squash-merged here with Austin's authorship preserved on commit 1).

Infographic

dashboard-typography-and-plugin-routing

austinpickett and others added 2 commits May 22, 2026 19:46
Removes the global `uppercase` + `font-mondwest` from the App.tsx root
that forced every page to opt-out, replaces stacked-alpha text colors
with semantic tokens for WCAG-AA contrast across all 7 themes, and
applies the new `text-display` utility from @nous-research/ui@0.16.0
on intentional brand chrome (page titles, sidebar headings, segmented
filters) only. Bumps every sub-12px arbitrary text size to text-xs.

Also widens the dashboard plugin routes (/api/dashboard/agent-plugins/
{name:path}/...) so category-namespaced plugins like observability/
langfuse and image_gen/openai can be enable/disabled from the dashboard
— previously the FE encodeURIComponent-ed the slash and the backend
{name} route rejected it. _validate_plugin_name still blocks .. and
backslash, and strips leading/trailing slash.

Touches sessions/env/keys page chrome and adds two new i18n keys
(`overview`, `showMore`/`showLess`) across all 18 locales.

Squashes 19 commits from PR #28832.

Co-authored-by: Hermes <noreply@nousresearch.com>
Follow-up to PR #28832 — the dashboard plugin routes now accept slashed
names like `observability/langfuse` and `image_gen/openai`, but
`_sanitize_plugin_name` still rejected forward slash and so dashboard
update + remove on those plugins fell through to '404 not found' even
though they exist on disk.

Adds an opt-in `allow_subdir=True` flag that:
- Permits internal forward slashes (category-namespaced plugin keys
  emitted by `_discover_all_plugins`).
- Strips leading and trailing slashes.
- Still rejects `..` and backslash, and still asserts the resolved
  target lives inside `plugins_dir`.

Opted in at the two read-paths that operate on installed plugins:
`_require_installed_plugin` (CLI update/remove) and
`_user_installed_plugin_dir` (dashboard update/remove). The install
path keeps the default (`allow_subdir=False`) because freshly-cloned
plugins always land top-level under `~/.hermes/plugins/<name>/`.

Adds 6 targeted unit tests covering the new flag's allow/reject matrix.
@teknium1 teknium1 requested a review from a team May 23, 2026 02:49
@github-actions

Copy link
Copy Markdown
Contributor

🔎 Lint report: hermes/hermes-0d4fd3e6 vs origin/main

ruff

Total: 0 on HEAD, 0 on base (➖ 0)

🆕 New issues: none

✅ Fixed issues: none

Unchanged: 0 pre-existing issues carried over.

ty (type checker)

Total: 8991 on HEAD, 8991 on base (➖ 0)

🆕 New issues: none

✅ Fixed issues: none

Unchanged: 4770 pre-existing issues carried over.

Diagnostics are surfaced as warnings — this check never fails the build.

@teknium1 teknium1 merged commit 8cf977c into main May 23, 2026
23 checks passed
@teknium1 teknium1 deleted the hermes/hermes-0d4fd3e6 branch May 23, 2026 02:50
@alt-glitch alt-glitch added type/refactor Code restructuring, no behavior change comp/gateway Gateway runner, session dispatch, delivery comp/plugins Plugin system and bundled plugins javascript Pull requests that update javascript code area/nix Nix flake, NixOS module, container packaging P3 Low — cosmetic, nice to have labels May 23, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/nix Nix flake, NixOS module, container packaging comp/gateway Gateway runner, session dispatch, delivery comp/plugins Plugin system and bundled plugins javascript Pull requests that update javascript code P3 Low — cosmetic, nice to have type/refactor Code restructuring, no behavior change

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants