HERMES-GIELIE/api
nesquena-hermes 6f9d455348 fix(#2622): harden plugin asset isolation + server-side enable-gate + i18n key
Deep-review (Opus MUST-FIX + Codex kick-back) findings, all confirmed with repros:

1. Same-origin XSS via direct nav to a plugin's raw .html/.svg asset: the
   /dashboard-plugins/<name>/ route served plugin-controlled HTML with text/html
   at the WebUI origin and NO sandbox header (only the in-panel iframe + the
   page route were sandboxed). Verified: <script>alert(document.cookie)</script>
   in a plugin html ran same-origin. Fix: send 'Content-Security-Policy: sandbox
   allow-scripts allow-forms allow-popups' + 'X-Content-Type-Options: nosniff'
   on the asset response (null-origin, same as the page route).

2. 'Disabled' was UI-only: toggling a plugin off just hid the Open button; its
   page + asset URLs kept serving. Fix: new _dashboard_plugin_enabled() gates
   BOTH the asset route and the page route server-side (opt-in, default off,
   disabled => 404).

3. i18n: panels.js referenced t('plugins_enable_toggle') but the PR defined a
   mismatched English-only 'settings_plugins_enable_toggle' (dead key) — toggle
   label fell back to literal AND tripped the locale-parity gate. Renamed to
   plugins_enable_toggle and added to all 12 locales (zh-Hant gets Traditional
   啟用, not Simplified).
2026-06-02 03:12:58 +00:00
..
__init__.py
agent_health.py fix: probe remote gateway via HERMES_API_URL before local fallback (#3312) 2026-06-01 19:38:00 +00:00
agent_sessions.py fix: keep webui mirrored sessions out of cli filter 2026-05-28 00:51:12 +02:00
auth.py fix: harden WebUI bugfix sweep 2026-05-28 13:38:50 -04:00
background.py feat(commands): /background, /btw slash commands + undo button + reasoning chip 2026-04-24 01:24:51 +00:00
clarify.py feat: add distinct attention request sound 2026-05-30 19:40:40 +00:00
commands.py fix(security): drop unsafe-eval + add jsdelivr to CSP, sanitize plugin error 2026-05-11 17:53:02 +00:00
compression_anchor.py fix(sidebar): keep newer continuation visible over older snapshot 2026-05-28 13:38:06 -06:00
config.py feat(plugins): add WebUI dashboard plugin system with iframe isolation (#2622, @pix0127) 2026-06-02 02:48:11 +00:00
dashboard_probe.py fix: preserve IPv6 dashboard link brackets 2026-05-19 21:35:10 -04:00
extensions.py Opus pre-release follow-ups for PR #1445 2026-05-02 03:49:40 +00:00
gateway_chat.py fix: carry WebUI reply polish into gateway chat 2026-06-01 04:42:23 +00:00
gateway_watcher.py release: v0.50.241 (#1293) 2026-04-29 19:54:07 -07:00
goals.py fix(i18n): localize /goal runtime status strings 2026-05-10 15:21:24 +08:00
helpers.py fix(helpers): use ssl.SSLError instead of broad OSError in disconnect tuple 2026-05-31 01:56:39 +00:00
kanban_bridge.py perf(http): enable HTTP/1.1 keep-alive 2026-05-24 18:26:56 +00:00
metering.py fix: show TPS in assistant message headers 2026-05-04 21:26:43 +00:00
models.py fix(#3102): don't let persisted watermark permanently drop future state.db recovery rows 2026-06-01 18:14:48 +00:00
oauth.py fix(oauth): serialize Anthropic env fallback reads 2026-05-07 02:47:19 +00:00
onboarding.py Classify onboarding DNS probe failures consistently 2026-05-15 08:51:30 +08:00
passkeys.py feat: support passkey-only auth 2026-05-25 00:14:38 +00:00
paths.py fix(profiles): avoid config import cycle 2026-06-01 05:05:16 +00:00
plugins.py review(#2622): lint cleanup + harden two no-op tests 2026-06-02 02:51:07 +00:00
profiles.py fix(profiles): TOCTOU-safe _SKILLS_STATS_CACHE read via .get() (Opus pre-release nit on #3341) 2026-06-01 18:38:39 +00:00
providers.py fix: honor shared OpenCode key at runtime 2026-05-30 02:18:06 +00:00
request_diagnostics.py fix: add request wedge diagnostics 2026-05-08 15:37:08 +00:00
rollback.py v0.50.255: Opus follow-ups (4 fixes) + CHANGELOG 2026-05-01 17:19:53 +00:00
routes.py fix(#2622): harden plugin asset isolation + server-side enable-gate + i18n key 2026-06-02 03:12:58 +00:00
run_journal.py fix: filter interrupted recovery control text from visible transcript (#3321) 2026-06-01 20:07:16 +00:00
runner_client.py harden: runner client rejects non-http(s) base_url + no redirect-follow (#3073) 2026-05-31 17:49:26 +00:00
runtime_adapter.py Stage 398: PR #2696 — feat(runtime): add runner-local adapter selection (RuntimeAdapter slice 4c, feature-flagged) 2026-05-21 17:43:54 +00:00
session_discoverability.py Merge PR #3048 2026-05-28 17:47:33 +00:00
session_events.py sync session list from server events 2026-05-20 08:18:56 -06:00
session_lifecycle.py fix: align WebUI memory commits with CLI boundaries 2026-05-17 05:04:57 -06:00
session_ops.py fix(session): preserve sidecar truncation boundary 2026-05-25 21:21:15 +08:00
session_recovery.py fix(session): rebuild missing startup index 2026-05-20 23:43:30 +08:00
skill_usage.py fix: remove webui-side writer to avoid conflict with agent 2026-05-27 20:57:32 +08:00
startup.py fix: P0 hotfixes — API regression, code block parser, chmod override 2026-05-01 12:10:48 +00:00
state_sync.py fix: use Optional[T] for default None parameters in state_sync.py 2026-06-01 17:20:17 +00:00
streaming.py feat: add manual session title regeneration (#3223, @AJV20) 2026-06-01 21:39:51 +00:00
system_health.py feat: add VPS resource health panel 2026-05-05 17:30:56 +00:00
terminal.py fix(terminal): harden supervisor lifecycle and eliminate timeout race conditions 2026-05-25 20:45:17 +05:00
turn_journal.py fix: handle Windows media and turn journal edge cases 2026-05-30 11:15:35 +02:00
updates.py fix(updates): fall through when release tag is not ff-reachable 2026-05-31 16:18:06 +00:00
upload.py refine(hotfix): Opus SHOULD-FIX — drop redundant equality clause + tighten symlink test 2026-06-02 02:28:44 +00:00
usage.py fix: display canonical cache hit percentage 2026-05-19 02:27:12 -06:00
workspace.py fix: preserve tilde workspace suggestions 2026-05-30 11:35:05 +02:00
workspace_git.py fix(workspace): tighten git subprocess trust boundary 2026-05-20 11:02:45 +00:00
worktrees.py Harden worktree removal safeguards 2026-05-13 09:49:15 +08:00