Svrnty plugin for nesquena/hermes-webui — single repo for every backend + brand mod (per hermes/docs/SVRNTY-PLUGIN-PROTOCOL.md)
Go to file
Svrnty 9ce6bfc08f fix(adwright + plugin): font 404s + status humanization + compound refresh + poll deadline
Bundles four Tranche-A polish fixes that ship together:

1. **Font 404s** — CSS @font-face URLs were /extensions/fonts/* but the
   plugin loader serves static under /plugins/svrnty/*. Updated paths
   to match register_static prefix.

2. **Humanized status enum** — _humanStatus() maps proto canonical strings
   (CYCLE_STATUS_PREVIEW_READY, VARIANT_STATUS_ACTIVE, etc.) to
   user-facing labels ("Preview ready", "Active"). Applied to Cycles
   row, Overview timeline, and variant detail.

3. **Compound Overview refresh** — refresh-overview now dispatches both
   refresh-cycles AND list-recipes via _COMPOUND_ACTIONS map. Without
   this, KPI Recipes stayed at 0 until user visited Targeting tab.
   Added per-action user-facing toast labels (_ACTION_LABELS) so the
   user sees "Loading recipes…" instead of just hermes-webui's raw
   "Queued: /adwright list-recipes" banner.

4. **Poll deadline race** — compound actions fired two sub-actions
   back-to-back; sub1's poll response was nulling pendingTool before
   sub2 could be ingested. _pollOnce now (a) resets deadline on each
   successful update (sign of progress) and (b) only stops polling
   when the response matches the CURRENT pendingTool (not the captured
   local var from earlier in the recursive fire).

Verified live: Overview now shows Cycles=1, Recipes=10, Spend=$0/$200,
timeline=Cycle #1 — Preview ready. Console clean (0 errors, was 3
font 404s).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-24 17:47:56 -04:00
.github/workflows feat(plugin): initial scaffold — plugin loader entry + AST + CI workflows (P1.B/C/D) 2026-05-23 09:59:45 -04:00
routes fix(plugin): umbrella.py registration broke /api/umbrella — sprint 2026-05-25 Wave 7 D12 2026-05-24 16:50:19 -04:00
scripts feat(plugin): STT migration via audio_attachment_processor hook (L1-L6) 2026-05-23 10:14:29 -04:00
static fix(adwright + plugin): font 404s + status humanization + compound refresh + poll deadline 2026-05-24 17:47:56 -04:00
svrnty_hermes_webui_plugin feat(plugin): initial scaffold — plugin loader entry + AST + CI workflows (P1.B/C/D) 2026-05-23 09:59:45 -04:00
tests docs: ship 6 polish fixes — manifest sync + LICENSE + CHANGELOG + .env.example + README + integration test 2026-05-23 11:02:28 -04:00
.env.example docs: ship 6 polish fixes — manifest sync + LICENSE + CHANGELOG + .env.example + README + integration test 2026-05-23 11:02:28 -04:00
.gitignore feat(plugin): initial scaffold — plugin loader entry + AST + CI workflows (P1.B/C/D) 2026-05-23 09:59:45 -04:00
CHANGELOG.md docs: ship 6 polish fixes — manifest sync + LICENSE + CHANGELOG + .env.example + README + integration test 2026-05-23 11:02:28 -04:00
CLAUDE.md feat(plugin): Adwright + BTE Command Center panels (v0.4.0) 2026-05-24 12:12:27 -04:00
CONNECTION-MAP.md feat(bte panel): wire grid to live /api/query/assetDtos (replaces 404'd assetGrid) 2026-05-24 14:15:22 -04:00
CONTRIBUTING.md docs(contributing): 5 recipes + decision flowchart for adding features 2026-05-23 10:41:17 -04:00
LICENSE docs: ship 6 polish fixes — manifest sync + LICENSE + CHANGELOG + .env.example + README + integration test 2026-05-23 11:02:28 -04:00
Makefile feat(plugin): Phase 2 partial — vault_status migrated + brand skin moved + eval suite (P2.B/C, P3.A/B) 2026-05-23 10:02:47 -04:00
manifest.yaml feat(plugin): sidebar nav buttons for Adwright + BTE (v0.5.0) 2026-05-24 12:45:01 -04:00
plugin.py feat(umbrella): cortex-os umbrella graph viz panel — Phase 2.E 2026-05-24 12:43:29 -04:00
pyproject.toml feat(plugin): initial scaffold — plugin loader entry + AST + CI workflows (P1.B/C/D) 2026-05-23 09:59:45 -04:00
README.md docs(claude+readme): standardize CLAUDE.md, sync loader API method count 6 → 7 2026-05-23 11:46:44 -04:00

svrnty-hermes-webui-plugin

THE single repo holding every Svrnty modification to nesquena/hermes-webui. Loaded at runtime via the plugin loader hook patched into the fork.

Protocol contract: hermes/docs/SVRNTY-PLUGIN-PROTOCOL.md — read this before contributing.

Adding features? Read CONTRIBUTING.md for the 5 recipes + decision flowchart.

Install

# 1. Install the plugin in the same venv as hermes-webui
pip install -e ~/workspaces/hermes/svrnty-hermes-webui-plugin

# 2. Tell hermes-webui to load it
export HERMES_WEBUI_PYTHON_PLUGIN=svrnty_hermes_webui_plugin
# or set in docker-compose.override.yml under environment:

# 3. Restart hermes-webui — endpoints under /api/* + assets under /plugins/svrnty/* land

Without HERMES_WEBUI_PYTHON_PLUGIN, hermes-webui runs vanilla (no Svrnty mods).

What's in here

Dir What
plugin.py Entry point — register(api) wires routes + static
routes/ One file per Svrnty /api/* endpoint (transcribe, vault_status, …)
static/ Brand skin: app.js, app.css, Montserrat fonts
CONNECTION-MAP.md AST-generated map of every upstream symbol this plugin touches
scripts/ Tooling — AST walker, upstream sync, boot smoke
tests/ Unit · integration · evals (each upstream-sync runs evals)
.github/workflows/ Plugin-tests · connection-map-check · upstream-drift CI

Public extension API

The plugin loader (one fork commit in hermes-webui) exposes exactly 7 methods:

api.register_route(path, method, handler)         # add /api/<path>
api.register_static(prefix, directory)            # serve files under /plugins/<prefix>/...
api.inject_script(url)                            # add <script> to index.html
api.inject_stylesheet(url)                        # add <link> to index.html
api.config_get(key, default)                      # safe upstream config read
api.logger(name)                                  # namespaced logger
api.register_audio_attachment_processor(fn)       # hook STT/voice attachment pipeline

Touching anything else in hermes-webui = a Rule 2 violation per the protocol. Document the escape hatch in CONNECTION-MAP.md under "forced internal dependencies".

Hygiene

  • make sync-upstream — one-command rebase against latest upstream + report
  • python scripts/ast-connection-map.py — regenerate the map
  • python scripts/boot-smoke.py — start + curl every plugin endpoint
  • pytest tests/ — full suite (unit + integration + evals)

Status

Component State
Loader hook in hermes-webui ✓ live (lone fork commit, 7-method API)
Plugin scaffold ✓ live (routes/static/tests/scripts/.github)
Migrated features (vault_status, transcribe, brand skin, voice-message mic) ✓ live
Automation (drift CI, AST connection map, sync command, eval suite) ✓ live (Gitea runner registered)
Upstream PR to nesquena/hermes-webui deferred — gated on 2+ release smoke (PRD Phase 4)
Forced internal dependencies 0 (plugin uses only public API)
Test suite 26/26 PASS (unit + evals)