From cadbe1e5d3a781e89dc12c8ba3d9dff66f615fde Mon Sep 17 00:00:00 2001 From: nesquena-hermes Date: Sun, 7 Jun 2026 18:59:01 -0700 Subject: [PATCH] =?UTF-8?q?Release=20v0.51.325=20=E2=80=94=20Release=20KO?= =?UTF-8?q?=20(in-app=20Help=20tab,=20#3518)=20(#3806)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit #3518 (@rodboev): in-app Help tab in Settings (docs + GitHub issues links), redesigned as polished icon-led cards. UX-approved by Nathan. Full suite 8242, CI 11/11. Co-authored-by: rodboev --- CHANGELOG.md | 5 ++ static/i18n.js | 104 +++++++++++++++++++++++++++++++ static/index.html | 40 ++++++++++++ static/panels.js | 6 +- static/style.css | 11 ++++ tests/test_issue3227_help_tab.py | 48 ++++++++++++++ 6 files changed, 211 insertions(+), 3 deletions(-) create mode 100644 tests/test_issue3227_help_tab.py diff --git a/CHANGELOG.md b/CHANGELOG.md index f0a34730..5340aded 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,11 @@ ## [Unreleased] +## [v0.51.325] — 2026-06-08 — Release KO (in-app Help tab) + +### Added +- **A Help tab in Settings** with quick links to the documentation (get-hermes.ai) and the GitHub issues page, presented as icon-led resource cards. Translated across all 13 locales. (#3518, @rodboev) + ## [v0.51.324] — 2026-06-07 — Release KN (i18n — translate settings + gateway-status labels) ### Added diff --git a/static/i18n.js b/static/i18n.js index 62550997..c0778181 100644 --- a/static/i18n.js +++ b/static/i18n.js @@ -575,6 +575,14 @@ const LOCALES = { plugins_provider_no_hooks: 'Provider plugin — no agent-visibility hooks', plugins_load_failed: 'Failed to load plugins: ', settings_tab_system: 'System', + settings_tab_help: 'Help', + settings_help_meta: 'Resources and support for Hermes WebUI.', + settings_help_docs_label: 'Documentation', + settings_help_docs_desc: 'Guides, configuration reference, and the full Hermes WebUI README.', + settings_help_docs_link: 'Open Documentation', + settings_help_issue_label: 'Having an issue?', + settings_help_issue_desc: 'Search existing reports or open a new one on GitHub.', + settings_help_issue_link: 'Open GitHub Issues', settings_title: 'Settings', settings_save_btn: 'Save Settings', settings_label_model: 'Default Model', @@ -1940,6 +1948,14 @@ const LOCALES = { plugins_provider_no_hooks: 'Provider plugin — no agent-visibility hooks', // TODO: translate plugins_load_failed: 'Failed to load plugins: ', // TODO: translate settings_tab_system: 'Sistema', + settings_tab_help: 'Help', + settings_help_meta: 'Resources and support for Hermes WebUI.', + settings_help_docs_label: 'Documentation', + settings_help_docs_desc: 'Guides, configuration reference, and the full Hermes WebUI README.', + settings_help_docs_link: 'Open Documentation', + settings_help_issue_label: 'Having an issue?', + settings_help_issue_desc: 'Search existing reports or open a new one on GitHub.', + settings_help_issue_link: 'Open GitHub Issues', settings_title: 'Impostazioni', settings_save_btn: 'Salva Impostazioni', settings_label_model: 'Modello Predefinito', @@ -3297,6 +3313,14 @@ const LOCALES = { plugins_provider_no_hooks: 'プロバイダープラグイン — エージェント可視フックなし', plugins_load_failed: 'プラグインの読み込みに失敗しました: ', settings_tab_system: 'システム', + settings_tab_help: 'Help', + settings_help_meta: 'Resources and support for Hermes WebUI.', + settings_help_docs_label: 'Documentation', + settings_help_docs_desc: 'Guides, configuration reference, and the full Hermes WebUI README.', + settings_help_docs_link: 'Open Documentation', + settings_help_issue_label: 'Having an issue?', + settings_help_issue_desc: 'Search existing reports or open a new one on GitHub.', + settings_help_issue_link: 'Open GitHub Issues', settings_title: '設定', settings_save_btn: '設定を保存', settings_label_model: 'デフォルトモデル', @@ -5248,6 +5272,14 @@ const LOCALES = { plugins_provider_no_hooks: 'Provider plugin — no agent-visibility hooks', // TODO: translate plugins_load_failed: 'Failed to load plugins: ', // TODO: translate settings_tab_system: 'System', + settings_tab_help: 'Help', + settings_help_meta: 'Resources and support for Hermes WebUI.', + settings_help_docs_label: 'Documentation', + settings_help_docs_desc: 'Guides, configuration reference, and the full Hermes WebUI README.', + settings_help_docs_link: 'Open Documentation', + settings_help_issue_label: 'Having an issue?', + settings_help_issue_desc: 'Search existing reports or open a new one on GitHub.', + settings_help_issue_link: 'Open GitHub Issues', status_updated: 'Updated', status_ephemeral: 'Ephemeral snapshot — not saved to transcript history.', status_no_tokens: 'No token data', @@ -6530,6 +6562,14 @@ const LOCALES = { plugins_provider_no_hooks: 'Provider plugin — no agent-visibility hooks', // TODO: translate plugins_load_failed: 'Failed to load plugins: ', // TODO: translate settings_tab_system: 'System', + settings_tab_help: 'Help', + settings_help_meta: 'Resources and support for Hermes WebUI.', + settings_help_docs_label: 'Documentation', + settings_help_docs_desc: 'Guides, configuration reference, and the full Hermes WebUI README.', + settings_help_docs_link: 'Open Documentation', + settings_help_issue_label: 'Having an issue?', + settings_help_issue_desc: 'Search existing reports or open a new one on GitHub.', + settings_help_issue_link: 'Open GitHub Issues', status_updated: 'Updated', status_ephemeral: 'Ephemeral snapshot — not saved to transcript history.', status_no_tokens: 'No token data', @@ -7528,6 +7568,14 @@ const LOCALES = { plugins_provider_no_hooks: 'Provider plugin — no agent-visibility hooks', // TODO: translate plugins_load_failed: 'Failed to load plugins: ', // TODO: translate settings_tab_system: 'System', + settings_tab_help: 'Help', + settings_help_meta: 'Resources and support for Hermes WebUI.', + settings_help_docs_label: 'Documentation', + settings_help_docs_desc: 'Guides, configuration reference, and the full Hermes WebUI README.', + settings_help_docs_link: 'Open Documentation', + settings_help_issue_label: 'Having an issue?', + settings_help_issue_desc: 'Search existing reports or open a new one on GitHub.', + settings_help_issue_link: 'Open GitHub Issues', status_updated: 'Updated', status_ephemeral: 'Ephemeral snapshot — not saved to transcript history.', status_no_tokens: 'No token data', @@ -9116,6 +9164,14 @@ const LOCALES = { settings_tab_preferences: '偏好', settings_tab_plugins: '插件', settings_tab_system: '系统', + settings_tab_help: 'Help', + settings_help_meta: 'Resources and support for Hermes WebUI.', + settings_help_docs_label: 'Documentation', + settings_help_docs_desc: 'Guides, configuration reference, and the full Hermes WebUI README.', + settings_help_docs_link: 'Open Documentation', + settings_help_issue_label: 'Having an issue?', + settings_help_issue_desc: 'Search existing reports or open a new one on GitHub.', + settings_help_issue_link: 'Open GitHub Issues', status_updated: '已更新', status_ephemeral: '临时快照 — 不会保存到对话记录。', status_no_tokens: '无令牌数据', @@ -9831,6 +9887,14 @@ const LOCALES = { plugins_provider_no_hooks: '供應商外掛,沒有 Agent 可見的掛鉤', plugins_load_failed: '載入外掛失敗:', settings_tab_system: '系統', + settings_tab_help: 'Help', + settings_help_meta: 'Resources and support for Hermes WebUI.', + settings_help_docs_label: 'Documentation', + settings_help_docs_desc: 'Guides, configuration reference, and the full Hermes WebUI README.', + settings_help_docs_link: 'Open Documentation', + settings_help_issue_label: 'Having an issue?', + settings_help_issue_desc: 'Search existing reports or open a new one on GitHub.', + settings_help_issue_link: 'Open GitHub Issues', settings_title: '設定', settings_save_btn: '儲存設定', settings_label_model: '預設模型', @@ -11078,6 +11142,14 @@ const LOCALES = { plugins_provider_no_hooks: 'Provider plugin — no agent-visibility hooks', // TODO: translate plugins_load_failed: 'Failed to load plugins: ', // TODO: translate settings_tab_system: 'Sistema', + settings_tab_help: 'Help', + settings_help_meta: 'Resources and support for Hermes WebUI.', + settings_help_docs_label: 'Documentation', + settings_help_docs_desc: 'Guides, configuration reference, and the full Hermes WebUI README.', + settings_help_docs_link: 'Open Documentation', + settings_help_issue_label: 'Having an issue?', + settings_help_issue_desc: 'Search existing reports or open a new one on GitHub.', + settings_help_issue_link: 'Open GitHub Issues', settings_title: 'Configurações', settings_save_btn: 'Salvar Configurações', settings_label_model: 'Modelo Padrão', @@ -12336,6 +12408,14 @@ const LOCALES = { plugins_provider_no_hooks: 'Provider plugin — no agent-visibility hooks', // TODO: translate plugins_load_failed: 'Failed to load plugins: ', // TODO: translate settings_tab_system: '시스템', + settings_tab_help: 'Help', + settings_help_meta: 'Resources and support for Hermes WebUI.', + settings_help_docs_label: 'Documentation', + settings_help_docs_desc: 'Guides, configuration reference, and the full Hermes WebUI README.', + settings_help_docs_link: 'Open Documentation', + settings_help_issue_label: 'Having an issue?', + settings_help_issue_desc: 'Search existing reports or open a new one on GitHub.', + settings_help_issue_link: 'Open GitHub Issues', settings_title: '설정', settings_save_btn: '설정 저장', settings_label_model: '기본 모델', @@ -13611,6 +13691,14 @@ const LOCALES = { plugins_provider_no_hooks: 'Provider plugin — no agent-visibility hooks', // TODO: translate plugins_load_failed: 'Failed to load plugins: ', // TODO: translate settings_tab_system: 'Système', + settings_tab_help: 'Help', + settings_help_meta: 'Resources and support for Hermes WebUI.', + settings_help_docs_label: 'Documentation', + settings_help_docs_desc: 'Guides, configuration reference, and the full Hermes WebUI README.', + settings_help_docs_link: 'Open Documentation', + settings_help_issue_label: 'Having an issue?', + settings_help_issue_desc: 'Search existing reports or open a new one on GitHub.', + settings_help_issue_link: 'Open GitHub Issues', settings_title: 'Paramètres', settings_save_btn: 'Enregistrer les paramètres', settings_label_model: 'Modèle par défaut', @@ -14987,6 +15075,14 @@ const LOCALES = { plugins_provider_no_hooks: 'Sağlayıcı eklentisi — agent görünürlük kancası yok', plugins_load_failed: 'Eklentiler yüklenemedi: ', settings_tab_system: 'Sistem', + settings_tab_help: 'Help', + settings_help_meta: 'Resources and support for Hermes WebUI.', + settings_help_docs_label: 'Documentation', + settings_help_docs_desc: 'Guides, configuration reference, and the full Hermes WebUI README.', + settings_help_docs_link: 'Open Documentation', + settings_help_issue_label: 'Having an issue?', + settings_help_issue_desc: 'Search existing reports or open a new one on GitHub.', + settings_help_issue_link: 'Open GitHub Issues', settings_title: 'Ayarlar', settings_save_btn: 'Ayarları Kaydet', settings_label_model: 'Varsayılan Model', @@ -16355,6 +16451,14 @@ const LOCALES = { plugins_provider_no_hooks: 'Wtyczka dostawcy — brak haków widocznych dla agenta', plugins_load_failed: 'Nie udało się załadować wtyczek: ', settings_tab_system: 'System', + settings_tab_help: 'Pomoc', + settings_help_meta: 'Zasoby i wsparcie dla Hermes WebUI.', + settings_help_docs_label: 'Dokumentacja', + settings_help_docs_desc: 'Przewodniki, dokumentacja konfiguracji i pełny plik README Hermes WebUI.', + settings_help_docs_link: 'Otwórz dokumentację', + settings_help_issue_label: 'Masz problem?', + settings_help_issue_desc: 'Przeszukaj istniejące zgłoszenia lub utwórz nowe w serwisie GitHub.', + settings_help_issue_link: 'Otwórz zgłoszenia GitHub', settings_title: 'Ustawienia', settings_save_btn: 'Zapisz ustawienia', settings_label_model: 'Domyślny model', diff --git a/static/index.html b/static/index.html index 5f3ee283..5a8a9010 100644 --- a/static/index.html +++ b/static/index.html @@ -366,6 +366,10 @@ System +
@@ -1349,6 +1353,42 @@ +
+
+
+
Help
+ +
+
+
+
+ +
+
Documentation
+
Guides, configuration reference, and the full Hermes WebUI README.
+ + Open Documentation + + +
+
+
+ +
+
Having an issue?
+
Search existing reports or open a new one on GitHub.
+ + Open GitHub Issues + + +
+
+
+
diff --git a/static/panels.js b/static/panels.js index 061e9afa..bc1d2ad0 100644 --- a/static/panels.js +++ b/static/panels.js @@ -5911,7 +5911,7 @@ function switchSettingsSection(name){ }); } } - let section=(name==='appearance'||name==='preferences'||name==='providers'||name==='plugins'||name==='system')?name:'conversation'; + let section=(name==='appearance'||name==='preferences'||name==='providers'||name==='plugins'||name==='system'||name==='help')?name:'conversation'; // Deep-linking to the Plugins pane when the tab is hidden (no plugins // installed, #3457) falls back to Conversation. Resolve this BEFORE toggling // panes/sidebar/dropdown below so every downstream selection uses the @@ -5923,13 +5923,13 @@ function switchSettingsSection(name){ } _settingsSection=section; _currentSettingsSection=section; - const map={conversation:'Conversation',appearance:'Appearance',preferences:'Preferences',providers:'Providers',plugins:'Plugins',system:'System'}; + const map={conversation:'Conversation',appearance:'Appearance',preferences:'Preferences',providers:'Providers',plugins:'Plugins',system:'System',help:'Help'}; // Sidebar menu items document.querySelectorAll('#settingsMenu .side-menu-item').forEach(it=>{ it.classList.toggle('active', it.dataset.settingsSection===section); }); // Panes in main - ['conversation','appearance','preferences','providers','plugins','system'].forEach(key=>{ + ['conversation','appearance','preferences','providers','plugins','system','help'].forEach(key=>{ const pane=$('settingsPane'+map[key]); if(pane) pane.classList.toggle('active', key===section); }); diff --git a/static/style.css b/static/style.css index 103c06a1..fc6f14c8 100644 --- a/static/style.css +++ b/static/style.css @@ -1557,6 +1557,17 @@ .sm-btn{flex:1;padding:8px 0;border-radius:8px;font-size:11px;font-weight:500;background:var(--input-bg);border:1px solid var(--border);color:var(--muted);cursor:pointer;transition:all .15s;text-align:center;letter-spacing:.02em;} .sm-btn:hover{background:rgba(255,255,255,0.09);color:var(--text);border-color:rgba(255,255,255,.15);} .sm-btn:disabled{opacity:.45;cursor:not-allowed;} + /* Help tab (Settings → Help): icon-led resource cards (#3518) */ + .help-cards{display:flex;flex-direction:column;gap:12px;margin-top:14px;} + .help-card{display:flex;gap:14px;align-items:flex-start;padding:16px;border:1px solid var(--border2);border-radius:10px;background:var(--input-bg);transition:border-color .15s,background .15s;} + .help-card:hover{border-color:var(--accent);} + .help-card-icon{flex:0 0 38px;width:38px;height:38px;display:flex;align-items:center;justify-content:center;border-radius:9px;background:var(--accent-soft,rgba(255,255,255,.06));color:var(--accent);} + .help-card-body{min-width:0;flex:1;} + .help-card-title{font-size:13.5px;font-weight:650;color:var(--text);margin-bottom:3px;} + .help-card-desc{font-size:12px;color:var(--muted);line-height:1.45;margin-bottom:11px;} + .help-card-link{display:inline-flex;align-items:center;gap:6px;text-decoration:none;padding:7px 13px;border-radius:7px;font-size:12px;font-weight:600;background:var(--input-bg);border:1px solid var(--border);color:var(--text);transition:all .15s;} + .help-card-link:hover{background:var(--accent);border-color:var(--accent);color:var(--accent-text,#1a1a1a);} + .help-card-link svg{flex:0 0 auto;opacity:.8;} .main{flex:1;display:flex;flex-direction:column;overflow:hidden;min-width:0;min-height:0;background:var(--main-bg);} .topbar{padding:12px 20px;border-bottom:1px solid var(--border);background:var(--topbar-bg);backdrop-filter:blur(12px);display:flex;align-items:center;justify-content:space-between;flex-shrink:0;position:relative;z-index:10;} .topbar-title{font-size:15px;font-weight:600;letter-spacing:-.01em;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;} diff --git a/tests/test_issue3227_help_tab.py b/tests/test_issue3227_help_tab.py new file mode 100644 index 00000000..5f4a6039 --- /dev/null +++ b/tests/test_issue3227_help_tab.py @@ -0,0 +1,48 @@ +from pathlib import Path + +ROOT = Path(__file__).resolve().parents[1] +INDEX_HTML = (ROOT / "static" / "index.html").read_text(encoding="utf-8") +PANELS_JS = (ROOT / "static" / "panels.js").read_text(encoding="utf-8") +I18N_JS = (ROOT / "static" / "i18n.js").read_text(encoding="utf-8") + +LOCALE_COUNT = 13 # en, it, ja, ru, es, de, zh, zh-TW, pt, ko, fr, tr, pl + + +def test_help_nav_button_present(): + assert 'data-settings-section="help"' in INDEX_HTML + assert "switchSettingsSection('help')" in INDEX_HTML + assert 'data-i18n="settings_tab_help"' in INDEX_HTML + + +def test_help_pane_present(): + assert 'id="settingsPaneHelp"' in INDEX_HTML + assert 'href="https://get-hermes.ai/"' in INDEX_HTML + assert 'href="https://github.com/nesquena/hermes-webui/issues"' in INDEX_HTML + + +def test_help_pane_links_are_outbound(): + assert 'target="_blank"' in INDEX_HTML + assert 'rel="noopener noreferrer"' in INDEX_HTML + + +def test_panels_js_allowlist_includes_help(): + assert "name==='help'" in PANELS_JS + + +def test_panels_js_map_includes_help(): + assert "help:'Help'" in PANELS_JS + + +def test_panels_js_foreach_includes_help(): + assert "'help'" in PANELS_JS + assert "settingsPaneHelp" not in PANELS_JS or 'settingsPane'+'{map[key]}' not in PANELS_JS + # Simpler: confirm the forEach array string contains help + assert ",'help'," in PANELS_JS or ",'help']" in PANELS_JS + + +def test_i18n_help_keys_present_in_all_locales(): + assert I18N_JS.count("settings_tab_help") == LOCALE_COUNT + assert I18N_JS.count("settings_help_docs_label") == LOCALE_COUNT + assert I18N_JS.count("settings_help_issue_label") == LOCALE_COUNT + assert I18N_JS.count("settings_help_docs_link") == LOCALE_COUNT + assert I18N_JS.count("settings_help_issue_link") == LOCALE_COUNT