Svrnty plugin for nesquena/hermes-webui — single repo for every backend + brand mod (per hermes/docs/SVRNTY-PLUGIN-PROTOCOL.md)
Go to file
Svrnty d61f9e8d3f
Some checks failed
plugin-tests / test (push) Failing after 6s
feat(bte panel): wire grid to live /api/query/assetDtos (replaces 404'd assetGrid)
JP question: 'is there any way to see the generated images by the cmo inside the bte panel app'.

The Command Center PRD §5.4 specifies `/api/query/assetGrid` for the grid;
that endpoint isn't implemented yet on BTE. But `/api/query/assetDtos`
WORKS today and returns every brand-scoped asset including the ones CMO
just generated via bte_image_generate (asset ids 664787c4-... + dbe21e15-...).

Changes:
- routes/bte_proxy.py: allowlist /api/query/assetDtos + /api/assets/{id}/image
  (the latter so panel can render real PNG thumbnails — not just /thumb stubs)
- static/bte.js: _refreshGrid now POSTs assetDtos with {pageSize:48, sortBy:createdAt desc}.
  AssetDto rows normalized to panel's existing asset shape (id, thumbUrl,
  lifecycle, scores, prompt, dims). thumbUrl points at the live image bytes
  via the new proxy allowlist entry. _renderGrid stays untouched — same
  shape it expected.

Result: BTE panel grid now shows every Plan B asset including freshly-
generated CMO images. Polling stops when no in-flight renders remain.

When BTE Command Center §5.4 ships the real assetGrid endpoint, swap
the path back — frontend won't need any other change.

Karpathy 4 rules: smallest possible adapter (normalize one shape to another,
no abstraction added), surgical (one new allowlist entry, one function body
rewritten, no other panel logic touched), verified via curl that assetDtos
returns 10 assets including the CMO-generated ones before committing.
2026-05-24 14:15:22 -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 feat(bte panel): wire grid to live /api/query/assetDtos (replaces 404'd assetGrid) 2026-05-24 14:15:22 -04:00
scripts feat(plugin): STT migration via audio_attachment_processor hook (L1-L6) 2026-05-23 10:14:29 -04:00
static feat(bte panel): wire grid to live /api/query/assetDtos (replaces 404'd assetGrid) 2026-05-24 14:15:22 -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)