@bitseek/hermes-webui 0.1.0-beta.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (233) hide show
  1. package/README.md +213 -0
  2. package/bin/hermes-webui.mjs +588 -0
  3. package/package.json +25 -0
  4. package/scripts/sync-vendor.mjs +74 -0
  5. package/templates/launchd/com.bitseek.hermes-webui.plist +21 -0
  6. package/templates/systemd/hermes-webui.service +13 -0
  7. package/templates/windows/hermes-webui-task.ps1 +3 -0
  8. package/vendor/agent-frontend-shell/.bitseek-source.json +6 -0
  9. package/vendor/agent-frontend-shell/.dockerignore +7 -0
  10. package/vendor/agent-frontend-shell/.env.docker.example +89 -0
  11. package/vendor/agent-frontend-shell/.env.example +34 -0
  12. package/vendor/agent-frontend-shell/.github/FUNDING.yml +3 -0
  13. package/vendor/agent-frontend-shell/.github/workflows/browser-smoke.yml +42 -0
  14. package/vendor/agent-frontend-shell/.github/workflows/docker-smoke.yml +233 -0
  15. package/vendor/agent-frontend-shell/.github/workflows/native-windows-startup.yml +132 -0
  16. package/vendor/agent-frontend-shell/.github/workflows/release.yml +57 -0
  17. package/vendor/agent-frontend-shell/.github/workflows/tests.yml +88 -0
  18. package/vendor/agent-frontend-shell/.vscode/launch.json +59 -0
  19. package/vendor/agent-frontend-shell/.vscode/settings.json +13 -0
  20. package/vendor/agent-frontend-shell/AGENTS.md +80 -0
  21. package/vendor/agent-frontend-shell/ARCHITECTURE.md +1658 -0
  22. package/vendor/agent-frontend-shell/BUGS.md +52 -0
  23. package/vendor/agent-frontend-shell/CHANGELOG.md +7295 -0
  24. package/vendor/agent-frontend-shell/CONTRIBUTING.md +205 -0
  25. package/vendor/agent-frontend-shell/CONTRIBUTORS.md +107 -0
  26. package/vendor/agent-frontend-shell/DESIGN.md +173 -0
  27. package/vendor/agent-frontend-shell/Dockerfile +91 -0
  28. package/vendor/agent-frontend-shell/LICENSE +21 -0
  29. package/vendor/agent-frontend-shell/README-CUSTOM.md +76 -0
  30. package/vendor/agent-frontend-shell/README.md +705 -0
  31. package/vendor/agent-frontend-shell/ROADMAP.md +351 -0
  32. package/vendor/agent-frontend-shell/SPRINTS.md +147 -0
  33. package/vendor/agent-frontend-shell/TESTING.md +1932 -0
  34. package/vendor/agent-frontend-shell/THEMES.md +170 -0
  35. package/vendor/agent-frontend-shell/api/__init__.py +1 -0
  36. package/vendor/agent-frontend-shell/api/agent_health.py +392 -0
  37. package/vendor/agent-frontend-shell/api/agent_sessions.py +782 -0
  38. package/vendor/agent-frontend-shell/api/auth.py +592 -0
  39. package/vendor/agent-frontend-shell/api/background.py +87 -0
  40. package/vendor/agent-frontend-shell/api/clarify.py +238 -0
  41. package/vendor/agent-frontend-shell/api/commands.py +124 -0
  42. package/vendor/agent-frontend-shell/api/compression_anchor.py +134 -0
  43. package/vendor/agent-frontend-shell/api/config.py +5178 -0
  44. package/vendor/agent-frontend-shell/api/dashboard_probe.py +255 -0
  45. package/vendor/agent-frontend-shell/api/extensions.py +253 -0
  46. package/vendor/agent-frontend-shell/api/gateway_chat.py +435 -0
  47. package/vendor/agent-frontend-shell/api/gateway_watcher.py +230 -0
  48. package/vendor/agent-frontend-shell/api/goals.py +608 -0
  49. package/vendor/agent-frontend-shell/api/helpers.py +474 -0
  50. package/vendor/agent-frontend-shell/api/kanban_bridge.py +1255 -0
  51. package/vendor/agent-frontend-shell/api/metering.py +194 -0
  52. package/vendor/agent-frontend-shell/api/models.py +4210 -0
  53. package/vendor/agent-frontend-shell/api/oauth.py +770 -0
  54. package/vendor/agent-frontend-shell/api/onboarding.py +1046 -0
  55. package/vendor/agent-frontend-shell/api/passkeys.py +365 -0
  56. package/vendor/agent-frontend-shell/api/profiles.py +1499 -0
  57. package/vendor/agent-frontend-shell/api/providers.py +2175 -0
  58. package/vendor/agent-frontend-shell/api/request_diagnostics.py +160 -0
  59. package/vendor/agent-frontend-shell/api/rollback.py +320 -0
  60. package/vendor/agent-frontend-shell/api/routes.py +13990 -0
  61. package/vendor/agent-frontend-shell/api/run_journal.py +284 -0
  62. package/vendor/agent-frontend-shell/api/runner_client.py +156 -0
  63. package/vendor/agent-frontend-shell/api/runtime_adapter.py +431 -0
  64. package/vendor/agent-frontend-shell/api/session_discoverability.py +640 -0
  65. package/vendor/agent-frontend-shell/api/session_events.py +45 -0
  66. package/vendor/agent-frontend-shell/api/session_lifecycle.py +208 -0
  67. package/vendor/agent-frontend-shell/api/session_ops.py +207 -0
  68. package/vendor/agent-frontend-shell/api/session_recovery.py +655 -0
  69. package/vendor/agent-frontend-shell/api/skill_usage.py +32 -0
  70. package/vendor/agent-frontend-shell/api/startup.py +128 -0
  71. package/vendor/agent-frontend-shell/api/state_sync.py +187 -0
  72. package/vendor/agent-frontend-shell/api/streaming.py +7048 -0
  73. package/vendor/agent-frontend-shell/api/system_health.py +167 -0
  74. package/vendor/agent-frontend-shell/api/terminal.py +410 -0
  75. package/vendor/agent-frontend-shell/api/turn_journal.py +214 -0
  76. package/vendor/agent-frontend-shell/api/updates.py +1261 -0
  77. package/vendor/agent-frontend-shell/api/upload.py +322 -0
  78. package/vendor/agent-frontend-shell/api/usage.py +26 -0
  79. package/vendor/agent-frontend-shell/api/workspace.py +867 -0
  80. package/vendor/agent-frontend-shell/api/workspace_git.py +1261 -0
  81. package/vendor/agent-frontend-shell/api/worktrees.py +357 -0
  82. package/vendor/agent-frontend-shell/bootstrap.py +492 -0
  83. package/vendor/agent-frontend-shell/ctl.sh +427 -0
  84. package/vendor/agent-frontend-shell/docker-compose.custom.yml +26 -0
  85. package/vendor/agent-frontend-shell/docker-compose.three-container.yml +168 -0
  86. package/vendor/agent-frontend-shell/docker-compose.two-container.yml +147 -0
  87. package/vendor/agent-frontend-shell/docker-compose.yml +57 -0
  88. package/vendor/agent-frontend-shell/docker_init.bash +459 -0
  89. package/vendor/agent-frontend-shell/docs/CONTRACTS.md +207 -0
  90. package/vendor/agent-frontend-shell/docs/EXTENSIONS.md +212 -0
  91. package/vendor/agent-frontend-shell/docs/ISSUES.md +23 -0
  92. package/vendor/agent-frontend-shell/docs/UIUX-GUIDE.md +196 -0
  93. package/vendor/agent-frontend-shell/docs/advanced-chat-setup.md +83 -0
  94. package/vendor/agent-frontend-shell/docs/docker.md +337 -0
  95. package/vendor/agent-frontend-shell/docs/onboarding-agent-checklist.md +207 -0
  96. package/vendor/agent-frontend-shell/docs/onboarding.md +202 -0
  97. package/vendor/agent-frontend-shell/docs/remote-access.md +75 -0
  98. package/vendor/agent-frontend-shell/docs/rfcs/README.md +53 -0
  99. package/vendor/agent-frontend-shell/docs/rfcs/agent-source-boundary.md +70 -0
  100. package/vendor/agent-frontend-shell/docs/rfcs/canonical-session-resolution.md +124 -0
  101. package/vendor/agent-frontend-shell/docs/rfcs/hermes-run-adapter-contract.md +1079 -0
  102. package/vendor/agent-frontend-shell/docs/rfcs/turn-journal.md +195 -0
  103. package/vendor/agent-frontend-shell/docs/rfcs/webui-run-state-consistency-contract.md +157 -0
  104. package/vendor/agent-frontend-shell/docs/supervisor.md +280 -0
  105. package/vendor/agent-frontend-shell/docs/troubleshooting.md +132 -0
  106. package/vendor/agent-frontend-shell/docs/ui-ux/index.html +863 -0
  107. package/vendor/agent-frontend-shell/docs/ui-ux/two-stage-proposal.html +768 -0
  108. package/vendor/agent-frontend-shell/docs/why-hermes.md +489 -0
  109. package/vendor/agent-frontend-shell/docs/workspace-git.md +92 -0
  110. package/vendor/agent-frontend-shell/docs/wsl-autostart.md +126 -0
  111. package/vendor/agent-frontend-shell/eslint.runtime-guard.config.mjs +35 -0
  112. package/vendor/agent-frontend-shell/extensions/bitseek-design-system.md +330 -0
  113. package/vendor/agent-frontend-shell/extensions/branding/assets/apple-touch-icon.png +0 -0
  114. package/vendor/agent-frontend-shell/extensions/branding/assets/empty-logo.svg +739 -0
  115. package/vendor/agent-frontend-shell/extensions/branding/assets/favicon-192.png +0 -0
  116. package/vendor/agent-frontend-shell/extensions/branding/assets/favicon-32.png +0 -0
  117. package/vendor/agent-frontend-shell/extensions/branding/assets/favicon-512.png +0 -0
  118. package/vendor/agent-frontend-shell/extensions/branding/assets/favicon-512.svg +745 -0
  119. package/vendor/agent-frontend-shell/extensions/branding/assets/favicon.ico +0 -0
  120. package/vendor/agent-frontend-shell/extensions/branding/assets/favicon.svg +745 -0
  121. package/vendor/agent-frontend-shell/extensions/branding/assets/titlebar-icon-v2.svg +751 -0
  122. package/vendor/agent-frontend-shell/extensions/branding/assets/titlebar-icon-v3.svg +739 -0
  123. package/vendor/agent-frontend-shell/extensions/branding/assets/titlebar-icon.svg +745 -0
  124. package/vendor/agent-frontend-shell/extensions/branding/branding.js +112 -0
  125. package/vendor/agent-frontend-shell/extensions/branding/config.json +14 -0
  126. package/vendor/agent-frontend-shell/extensions/branding/manifest.json +53 -0
  127. package/vendor/agent-frontend-shell/extensions/index.js +67 -0
  128. package/vendor/agent-frontend-shell/extensions/loader/hermes-loader.js +77 -0
  129. package/vendor/agent-frontend-shell/extensions/manifest.json +16 -0
  130. package/vendor/agent-frontend-shell/extensions/pages/ai-teammates/page.css +333 -0
  131. package/vendor/agent-frontend-shell/extensions/pages/ai-teammates/page.js +487 -0
  132. package/vendor/agent-frontend-shell/extensions/pages/manifest.json +6 -0
  133. package/vendor/agent-frontend-shell/extensions/pages/registry.css +56 -0
  134. package/vendor/agent-frontend-shell/extensions/pages/registry.js +302 -0
  135. package/vendor/agent-frontend-shell/extensions/themes/bitseek/index.css +93 -0
  136. package/vendor/agent-frontend-shell/extensions/themes/bitseek/index.js +98 -0
  137. package/vendor/agent-frontend-shell/install.sh +63 -0
  138. package/vendor/agent-frontend-shell/mcp_server.py +567 -0
  139. package/vendor/agent-frontend-shell/package.json +12 -0
  140. package/vendor/agent-frontend-shell/pyproject.toml +56 -0
  141. package/vendor/agent-frontend-shell/pytest.ini +3 -0
  142. package/vendor/agent-frontend-shell/requirements.txt +5 -0
  143. package/vendor/agent-frontend-shell/server.py +624 -0
  144. package/vendor/agent-frontend-shell/start.ps1 +210 -0
  145. package/vendor/agent-frontend-shell/start.sh +65 -0
  146. package/vendor/agent-frontend-shell/static/apple-touch-icon.png +0 -0
  147. package/vendor/agent-frontend-shell/static/boot.js +1990 -0
  148. package/vendor/agent-frontend-shell/static/commands.js +1402 -0
  149. package/vendor/agent-frontend-shell/static/favicon-192.png +0 -0
  150. package/vendor/agent-frontend-shell/static/favicon-32.png +0 -0
  151. package/vendor/agent-frontend-shell/static/favicon-512.png +0 -0
  152. package/vendor/agent-frontend-shell/static/favicon-512.svg +18 -0
  153. package/vendor/agent-frontend-shell/static/favicon.ico +0 -0
  154. package/vendor/agent-frontend-shell/static/favicon.svg +20 -0
  155. package/vendor/agent-frontend-shell/static/i18n.js +15389 -0
  156. package/vendor/agent-frontend-shell/static/icons.js +92 -0
  157. package/vendor/agent-frontend-shell/static/index.html +1506 -0
  158. package/vendor/agent-frontend-shell/static/login.js +177 -0
  159. package/vendor/agent-frontend-shell/static/manifest.json +53 -0
  160. package/vendor/agent-frontend-shell/static/messages.js +3521 -0
  161. package/vendor/agent-frontend-shell/static/onboarding.js +800 -0
  162. package/vendor/agent-frontend-shell/static/panels.js +7995 -0
  163. package/vendor/agent-frontend-shell/static/pwa-startup.js +83 -0
  164. package/vendor/agent-frontend-shell/static/sessions.js +5165 -0
  165. package/vendor/agent-frontend-shell/static/style.css +4774 -0
  166. package/vendor/agent-frontend-shell/static/sw.js +173 -0
  167. package/vendor/agent-frontend-shell/static/terminal.js +632 -0
  168. package/vendor/agent-frontend-shell/static/ui.js +8997 -0
  169. package/vendor/agent-frontend-shell/static/vendor/js-yaml/4.1.0/js-yaml.min.js +2 -0
  170. package/vendor/agent-frontend-shell/static/vendor/katex/0.16.22/fonts/KaTeX_AMS-Regular.ttf +0 -0
  171. package/vendor/agent-frontend-shell/static/vendor/katex/0.16.22/fonts/KaTeX_AMS-Regular.woff +0 -0
  172. package/vendor/agent-frontend-shell/static/vendor/katex/0.16.22/fonts/KaTeX_AMS-Regular.woff2 +0 -0
  173. package/vendor/agent-frontend-shell/static/vendor/katex/0.16.22/fonts/KaTeX_Caligraphic-Bold.ttf +0 -0
  174. package/vendor/agent-frontend-shell/static/vendor/katex/0.16.22/fonts/KaTeX_Caligraphic-Bold.woff +0 -0
  175. package/vendor/agent-frontend-shell/static/vendor/katex/0.16.22/fonts/KaTeX_Caligraphic-Bold.woff2 +0 -0
  176. package/vendor/agent-frontend-shell/static/vendor/katex/0.16.22/fonts/KaTeX_Caligraphic-Regular.ttf +0 -0
  177. package/vendor/agent-frontend-shell/static/vendor/katex/0.16.22/fonts/KaTeX_Caligraphic-Regular.woff +0 -0
  178. package/vendor/agent-frontend-shell/static/vendor/katex/0.16.22/fonts/KaTeX_Caligraphic-Regular.woff2 +0 -0
  179. package/vendor/agent-frontend-shell/static/vendor/katex/0.16.22/fonts/KaTeX_Fraktur-Bold.ttf +0 -0
  180. package/vendor/agent-frontend-shell/static/vendor/katex/0.16.22/fonts/KaTeX_Fraktur-Bold.woff +0 -0
  181. package/vendor/agent-frontend-shell/static/vendor/katex/0.16.22/fonts/KaTeX_Fraktur-Bold.woff2 +0 -0
  182. package/vendor/agent-frontend-shell/static/vendor/katex/0.16.22/fonts/KaTeX_Fraktur-Regular.ttf +0 -0
  183. package/vendor/agent-frontend-shell/static/vendor/katex/0.16.22/fonts/KaTeX_Fraktur-Regular.woff +0 -0
  184. package/vendor/agent-frontend-shell/static/vendor/katex/0.16.22/fonts/KaTeX_Fraktur-Regular.woff2 +0 -0
  185. package/vendor/agent-frontend-shell/static/vendor/katex/0.16.22/fonts/KaTeX_Main-Bold.ttf +0 -0
  186. package/vendor/agent-frontend-shell/static/vendor/katex/0.16.22/fonts/KaTeX_Main-Bold.woff +0 -0
  187. package/vendor/agent-frontend-shell/static/vendor/katex/0.16.22/fonts/KaTeX_Main-Bold.woff2 +0 -0
  188. package/vendor/agent-frontend-shell/static/vendor/katex/0.16.22/fonts/KaTeX_Main-BoldItalic.ttf +0 -0
  189. package/vendor/agent-frontend-shell/static/vendor/katex/0.16.22/fonts/KaTeX_Main-BoldItalic.woff +0 -0
  190. package/vendor/agent-frontend-shell/static/vendor/katex/0.16.22/fonts/KaTeX_Main-BoldItalic.woff2 +0 -0
  191. package/vendor/agent-frontend-shell/static/vendor/katex/0.16.22/fonts/KaTeX_Main-Italic.ttf +0 -0
  192. package/vendor/agent-frontend-shell/static/vendor/katex/0.16.22/fonts/KaTeX_Main-Italic.woff +0 -0
  193. package/vendor/agent-frontend-shell/static/vendor/katex/0.16.22/fonts/KaTeX_Main-Italic.woff2 +0 -0
  194. package/vendor/agent-frontend-shell/static/vendor/katex/0.16.22/fonts/KaTeX_Main-Regular.ttf +0 -0
  195. package/vendor/agent-frontend-shell/static/vendor/katex/0.16.22/fonts/KaTeX_Main-Regular.woff +0 -0
  196. package/vendor/agent-frontend-shell/static/vendor/katex/0.16.22/fonts/KaTeX_Main-Regular.woff2 +0 -0
  197. package/vendor/agent-frontend-shell/static/vendor/katex/0.16.22/fonts/KaTeX_Math-BoldItalic.ttf +0 -0
  198. package/vendor/agent-frontend-shell/static/vendor/katex/0.16.22/fonts/KaTeX_Math-BoldItalic.woff +0 -0
  199. package/vendor/agent-frontend-shell/static/vendor/katex/0.16.22/fonts/KaTeX_Math-BoldItalic.woff2 +0 -0
  200. package/vendor/agent-frontend-shell/static/vendor/katex/0.16.22/fonts/KaTeX_Math-Italic.ttf +0 -0
  201. package/vendor/agent-frontend-shell/static/vendor/katex/0.16.22/fonts/KaTeX_Math-Italic.woff +0 -0
  202. package/vendor/agent-frontend-shell/static/vendor/katex/0.16.22/fonts/KaTeX_Math-Italic.woff2 +0 -0
  203. package/vendor/agent-frontend-shell/static/vendor/katex/0.16.22/fonts/KaTeX_SansSerif-Bold.ttf +0 -0
  204. package/vendor/agent-frontend-shell/static/vendor/katex/0.16.22/fonts/KaTeX_SansSerif-Bold.woff +0 -0
  205. package/vendor/agent-frontend-shell/static/vendor/katex/0.16.22/fonts/KaTeX_SansSerif-Bold.woff2 +0 -0
  206. package/vendor/agent-frontend-shell/static/vendor/katex/0.16.22/fonts/KaTeX_SansSerif-Italic.ttf +0 -0
  207. package/vendor/agent-frontend-shell/static/vendor/katex/0.16.22/fonts/KaTeX_SansSerif-Italic.woff +0 -0
  208. package/vendor/agent-frontend-shell/static/vendor/katex/0.16.22/fonts/KaTeX_SansSerif-Italic.woff2 +0 -0
  209. package/vendor/agent-frontend-shell/static/vendor/katex/0.16.22/fonts/KaTeX_SansSerif-Regular.ttf +0 -0
  210. package/vendor/agent-frontend-shell/static/vendor/katex/0.16.22/fonts/KaTeX_SansSerif-Regular.woff +0 -0
  211. package/vendor/agent-frontend-shell/static/vendor/katex/0.16.22/fonts/KaTeX_SansSerif-Regular.woff2 +0 -0
  212. package/vendor/agent-frontend-shell/static/vendor/katex/0.16.22/fonts/KaTeX_Script-Regular.ttf +0 -0
  213. package/vendor/agent-frontend-shell/static/vendor/katex/0.16.22/fonts/KaTeX_Script-Regular.woff +0 -0
  214. package/vendor/agent-frontend-shell/static/vendor/katex/0.16.22/fonts/KaTeX_Script-Regular.woff2 +0 -0
  215. package/vendor/agent-frontend-shell/static/vendor/katex/0.16.22/fonts/KaTeX_Size1-Regular.ttf +0 -0
  216. package/vendor/agent-frontend-shell/static/vendor/katex/0.16.22/fonts/KaTeX_Size1-Regular.woff +0 -0
  217. package/vendor/agent-frontend-shell/static/vendor/katex/0.16.22/fonts/KaTeX_Size1-Regular.woff2 +0 -0
  218. package/vendor/agent-frontend-shell/static/vendor/katex/0.16.22/fonts/KaTeX_Size2-Regular.ttf +0 -0
  219. package/vendor/agent-frontend-shell/static/vendor/katex/0.16.22/fonts/KaTeX_Size2-Regular.woff +0 -0
  220. package/vendor/agent-frontend-shell/static/vendor/katex/0.16.22/fonts/KaTeX_Size2-Regular.woff2 +0 -0
  221. package/vendor/agent-frontend-shell/static/vendor/katex/0.16.22/fonts/KaTeX_Size3-Regular.ttf +0 -0
  222. package/vendor/agent-frontend-shell/static/vendor/katex/0.16.22/fonts/KaTeX_Size3-Regular.woff +0 -0
  223. package/vendor/agent-frontend-shell/static/vendor/katex/0.16.22/fonts/KaTeX_Size3-Regular.woff2 +0 -0
  224. package/vendor/agent-frontend-shell/static/vendor/katex/0.16.22/fonts/KaTeX_Size4-Regular.ttf +0 -0
  225. package/vendor/agent-frontend-shell/static/vendor/katex/0.16.22/fonts/KaTeX_Size4-Regular.woff +0 -0
  226. package/vendor/agent-frontend-shell/static/vendor/katex/0.16.22/fonts/KaTeX_Size4-Regular.woff2 +0 -0
  227. package/vendor/agent-frontend-shell/static/vendor/katex/0.16.22/fonts/KaTeX_Typewriter-Regular.ttf +0 -0
  228. package/vendor/agent-frontend-shell/static/vendor/katex/0.16.22/fonts/KaTeX_Typewriter-Regular.woff +0 -0
  229. package/vendor/agent-frontend-shell/static/vendor/katex/0.16.22/fonts/KaTeX_Typewriter-Regular.woff2 +0 -0
  230. package/vendor/agent-frontend-shell/static/vendor/katex/0.16.22/katex.min.css +1 -0
  231. package/vendor/agent-frontend-shell/static/vendor/katex/0.16.22/katex.min.js +1 -0
  232. package/vendor/agent-frontend-shell/static/vendor/smd.min.js +29 -0
  233. package/vendor/agent-frontend-shell/static/workspace.js +680 -0
@@ -0,0 +1,705 @@
1
+ # Hermes Web UI
2
+
3
+ [Hermes Agent](https://hermes-agent.nousresearch.com/) is a sophisticated autonomous agent that lives on your server, accessed via a terminal or messaging apps, that remembers what it learns and gets more capable the longer it runs.
4
+
5
+ Hermes WebUI is a lightweight, dark-themed web app interface in your browser for [Hermes Agent](https://hermes-agent.nousresearch.com/).
6
+ Full parity with the CLI experience - everything you can do from a terminal,
7
+ you can do from this UI. No build step, no framework, no bundler. Just Python
8
+ and vanilla JS.
9
+
10
+ Layout: three-panel. Left sidebar for sessions and navigation, center for chat,
11
+ right for workspace file browsing. Model, profile, and workspace controls live in
12
+ the **composer footer** — always visible while composing. A circular context ring
13
+ shows token usage at a glance. All settings and session tools are in the
14
+ **Hermes Control Center** (launcher at the sidebar bottom).
15
+
16
+ <img width="2448" height="1748" alt="Hermes Web UI — three-panel layout" src="https://github.com/user-attachments/assets/6bf8af4c-209d-441e-8b92-6515d7a0c369" />
17
+
18
+ <table>
19
+ <tr>
20
+ <td width="50%" align="center">
21
+ <img width="2940" height="1848" alt="Light mode with full profile support" src="https://github.com/user-attachments/assets/4ef3a59c-7a66-4705-b4e7-cb9148fe4c47" />
22
+ <br /><sub>Light mode with full profile support</sub>
23
+ </td>
24
+ <td width="50%" align="center">
25
+ <img alt="Customize your settings, configure a password" src="https://github.com/user-attachments/assets/941f3156-21e3-41fd-bcc8-f975d5000cb8" />
26
+ <br /><sub>Customize your settings, configure a password</sub>
27
+ </td>
28
+ </tr>
29
+ </table>
30
+
31
+ <table>
32
+ <tr>
33
+ <td width="50%" align="center">
34
+ <img alt="Workspace file browser with inline preview" src="docs/images/ui-workspace.png" />
35
+ <br /><sub>Workspace file browser with inline preview</sub>
36
+ </td>
37
+ <td width="50%" align="center">
38
+ <img alt="Session projects, tags, and tool call cards" src="docs/images/ui-sessions.png" />
39
+ <br /><sub>Session projects, tags, and tool call cards</sub>
40
+ </td>
41
+ </tr>
42
+ </table>
43
+
44
+ This gives you nearly **1:1 parity with Hermes CLI from a convenient web UI** which you can access securely through an SSH tunnel from your Hermes setup. Single command to start this up, and a single command to SSH tunnel for access on your computer. Every single part of the web UI uses your existing Hermes agent and existing models, without requiring any additional setup.
45
+
46
+ ---
47
+
48
+ ## Contents
49
+
50
+ - [Why Hermes](#why-hermes) — what it is and how it compares
51
+ - [Quick start](#quick-start) — clone + `bootstrap.py` / `start.sh` / `ctl.sh`
52
+ - [Features](#features) — chat, sessions, workspace, voice, profiles, security, themes, panels, mobile
53
+ - [Configuration & access](#configuration--access) — auto-discovery, overrides, remote/Tailscale/phone, manual launch
54
+ - [Docker](#docker) — single- and multi-container deploys
55
+ - [Running tests](#running-tests)
56
+ - [Architecture](#architecture) — backend/frontend layout, state dir
57
+ - [Docs](#docs) — the full documentation index
58
+ - [Contributors](#contributors)
59
+
60
+ ---
61
+
62
+ ## Why Hermes
63
+
64
+ Most AI tools reset every session. They don't know who you are, what you worked on, or what
65
+ conventions your project follows. You re-explain yourself every time.
66
+
67
+ Hermes retains context across sessions, runs scheduled jobs while you're offline, and gets
68
+ smarter about your environment the longer it runs. It uses your existing Hermes agent setup,
69
+ your existing models, and requires no additional configuration to start.
70
+
71
+ What makes it different from other agentic tools:
72
+
73
+ - **Persistent memory** — user profile, agent notes, and a skills system that saves reusable
74
+ procedures; Hermes learns your environment and does not have to relearn it
75
+ - **Self-hosted scheduling** — cron jobs that fire while you're offline and deliver results to
76
+ Telegram, Discord, Slack, Signal, email, and more
77
+ - **10+ messaging platforms** — the same agent available in the terminal is reachable from your phone
78
+ - **Self-improving skills** — Hermes writes and saves its own skills automatically from experience;
79
+ no marketplace to browse, no plugins to install
80
+ - **Provider-agnostic** — OpenAI, Anthropic, Google, DeepSeek, OpenRouter, and more
81
+ - **Orchestrates other agents** — can spawn Claude Code or Codex for heavy coding tasks and bring
82
+ the results back into its own memory
83
+ - **Self-hosted** — your conversations, your memory, your hardware
84
+
85
+ **vs. the field** *(landscape is actively shifting — see [docs/why-hermes.md](docs/why-hermes.md) for the full breakdown)*:
86
+
87
+ | | OpenClaw | Claude Code | Codex CLI | OpenCode | Hermes |
88
+ |---|---|---|---|---|---|
89
+ | Persistent memory (auto) | Yes | Partial† | Partial | Partial | Yes |
90
+ | Scheduled jobs (self-hosted) | Yes | No‡ | No | No | Yes |
91
+ | Messaging app access | Yes (15+ platforms) | Partial (Telegram/Discord preview) | No | No | Yes (10+) |
92
+ | Web UI (self-hosted) | Dashboard only | No | No | Yes | Yes |
93
+ | Self-improving skills | Partial | No | No | No | Yes |
94
+ | Python / ML ecosystem | No (Node.js) | No | No | No | Yes |
95
+ | Provider-agnostic | Yes | No (Claude only) | Yes | Yes | Yes |
96
+ | Open source | Yes (MIT) | No | Yes | Yes | Yes |
97
+
98
+ † Claude Code has CLAUDE.md / MEMORY.md project context and rolling auto-memory, but not full automatic cross-session recall
99
+ ‡ Claude Code has cloud-managed scheduling (Anthropic infrastructure) and session-scoped `/loop`; no self-hosted cron
100
+
101
+ **The closest competitor is OpenClaw** — both are always-on, self-hosted, open-source agents
102
+ with memory, cron, and messaging. The key differences: Hermes writes and saves its own skills
103
+ automatically as a core behavior (OpenClaw's skill system centers on a community marketplace);
104
+ Hermes is more stable across updates (OpenClaw has documented release regressions and ClawHub
105
+ has had security incidents involving malicious skills); and Hermes runs natively in the Python
106
+ ecosystem. See [docs/why-hermes.md](docs/why-hermes.md) for the full side-by-side.
107
+
108
+ ---
109
+
110
+ ## Quick start
111
+
112
+ Run the repo bootstrap:
113
+
114
+ ```bash
115
+ git clone https://github.com/nesquena/hermes-webui.git hermes-webui
116
+ cd hermes-webui
117
+ python3 bootstrap.py
118
+ ```
119
+
120
+ Or keep using the shell launcher:
121
+
122
+ ```bash
123
+ ./start.sh
124
+ ```
125
+
126
+ For self-hosted VM or homelab installs, `ctl.sh` wraps the common daemon lifecycle commands without requiring `fuser` or `pkill`:
127
+
128
+ ```bash
129
+ ./ctl.sh start # background daemon, PID at ~/.hermes/webui.pid
130
+ ./ctl.sh status # PID, uptime, bound host/port, log path, /health
131
+ ./ctl.sh logs --lines 100 # tail ~/.hermes/webui.log
132
+ ./ctl.sh restart
133
+ ./ctl.sh stop
134
+ ```
135
+
136
+ `ctl.sh start` runs the bootstrap in foreground/no-browser mode behind the daemon wrapper, writes logs to `~/.hermes/webui.log`, and respects `.env` plus inline overrides such as `HERMES_WEBUI_HOST=0.0.0.0 ./ctl.sh start`.
137
+
138
+ ### Advanced: dynamic recall prefill & Gateway-backed chat
139
+
140
+ Two optional, self-hosted-deployment features — attaching dynamic **session-recall prefill** to browser turns (Joplin/Obsidian/Notion/llm-wiki routers), and routing browser chat through a running **Hermes Gateway** — are documented in [`docs/advanced-chat-setup.md`](docs/advanced-chat-setup.md). Most users need neither.
141
+
142
+ The bootstrap will:
143
+
144
+ 1. Detect Hermes Agent and, if missing, attempt the official installer (`curl -fsSL https://raw.githubusercontent.com/NousResearch/hermes-agent/main/scripts/install.sh | bash`).
145
+ 2. Find or create a Python environment with the WebUI dependencies.
146
+ 3. Start the web server and wait for `/health`.
147
+ 4. Open the browser unless you pass `--no-browser`.
148
+ 5. Drop you into a first-run onboarding wizard inside the WebUI.
149
+
150
+ > Native Windows is not supported for this bootstrap yet. Use Linux, macOS, or WSL2.
151
+ > For Windows / WSL auto-start at login, see [`docs/wsl-autostart.md`](docs/wsl-autostart.md).
152
+
153
+ A community-maintained native Windows setup is documented at [@markwang2658/hermes-windows-native-guide](https://github.com/markwang2658/hermes-windows-native-guide) (companion setup repo: [@markwang2658/hermes-windows-native](https://github.com/markwang2658/hermes-windows-native)). Notes from the community report in [#1952](https://github.com/nesquena/hermes-webui/issues/1952):
154
+
155
+ - **Memory:** community-measured ~330 MB native vs ~1080 MB with WSL2+Docker (varies by configuration).
156
+ - **What works:** chat, workspace browser, session management, all themes.
157
+ - **Known limitations:** some POSIX-style file paths surface in the workspace browser; bash-assuming agent tools may not work natively.
158
+ - **Native Windows setup:** install Python 3.11+, then from the hermes-agent root in PowerShell: `python -m venv venv` → `pip install -r requirements.txt` → `pwsh .\start.ps1` (it auto-discovers `venv\Scripts\python.exe`).
159
+ - **WSL2 relationship:** not a prerequisite — a WSL2-built venv (`venv/bin/python`, ELF) isn't invokable by native Windows Python, so use the native setup above. WSL2 stays useful as a parallel install if you want the full `bootstrap.py` + Linux runtime.
160
+
161
+ If provider setup is still incomplete after install, the onboarding wizard will point you to finish it with `hermes model` instead of trying to replicate the full CLI setup in-browser.
162
+ For a step-by-step walkthrough of the wizard, provider choices, local model server Base URLs, and safe re-runs, see [`docs/onboarding.md`](docs/onboarding.md).
163
+ If an AI assistant is helping with install, reinstall, bootstrap, provider setup, or first-run support, have it read [`docs/onboarding-agent-checklist.md`](docs/onboarding-agent-checklist.md) before running commands or inspecting logs.
164
+
165
+ ---
166
+
167
+ ## Features
168
+
169
+ ### Chat and agent
170
+ - Streaming responses via SSE (tokens appear as they are generated)
171
+ - Multi-provider model support -- any Hermes API provider (OpenAI, Anthropic, Google, DeepSeek, Nous Portal, OpenRouter, MiniMax, Xiaomi MiMo, Z.AI); dynamic model dropdown populated from configured keys
172
+ - Send a message while one is processing -- it queues automatically
173
+ - Edit any past user message inline and regenerate from that point
174
+ - Retry the last assistant response with one click
175
+ - Cancel a running task directly from the composer footer (Stop button next to Send)
176
+ - Tool call cards inline -- each shows the tool name, args, and result snippet; expand/collapse all toggle for multi-tool turns
177
+ - Subagent delegation cards -- child agent activity shown with distinct icon and indented border
178
+ - Mermaid diagram rendering inline (flowcharts, sequence diagrams, gantt charts)
179
+ - Thinking/reasoning display -- collapsible gold-themed cards for Claude extended thinking and o3 reasoning blocks
180
+ - Approval card for dangerous shell commands (allow once / session / always / deny)
181
+ - SSE auto-reconnect on network blips (SSH tunnel resilience)
182
+ - File attachments persist across page reloads and are stored outside the active workspace by default (`~/.hermes/webui/attachments/<session_id>/`, or `HERMES_WEBUI_ATTACHMENT_DIR/<session_id>/` when configured)
183
+ - Message timestamps (HH:MM next to each message, full date on hover)
184
+ - Code block copy button with "Copied!" feedback
185
+ - Syntax highlighting via Prism.js (Python, JS, bash, JSON, SQL, and more)
186
+ - Safe HTML rendering in AI responses (bold, italic, code converted to markdown)
187
+ - rAF-throttled token streaming for smoother rendering during long responses
188
+ - Context usage indicator in composer footer -- token count, cost, and fill bar (model-aware)
189
+
190
+ ### Sessions
191
+ - Create, rename, duplicate, delete, search by title and message content
192
+ - Session actions via `⋯` dropdown per session — pin, move to project, archive, duplicate, delete
193
+ - Pin/star sessions to the top of the sidebar (gold indicator)
194
+ - Archive sessions (hide without deleting, toggle to show)
195
+ - Session projects -- named groups with colors for organizing sessions
196
+ - Session tags -- add #tag to titles for colored chips and click-to-filter
197
+ - Grouped by Today / Yesterday / Earlier in the sidebar (collapsible date groups)
198
+ - Download as Markdown transcript, full JSON export, or import from JSON
199
+ - Sessions persist across page reloads and SSH tunnel reconnects
200
+ - Browser tab title reflects the active session name
201
+ - CLI session bridge -- CLI sessions from hermes-agent's SQLite store appear in the sidebar with a gold "cli" badge; click to import with full history and reply normally
202
+ - Token/cost display -- input tokens, output tokens, estimated cost shown per conversation (toggle in Settings or `/usage` command)
203
+
204
+ ### Workspace file browser
205
+ - Directory tree with expand/collapse (single-click toggles, double-click navigates)
206
+ - Breadcrumb navigation with clickable path segments
207
+ - Preview text, code, Markdown (rendered), and images inline
208
+ - Chat links using `workspace://path/to/file` open files in the right-side preview pane
209
+ - Edit, create, delete, and rename files; create folders
210
+ - Binary file download (auto-detected from server)
211
+ - File preview auto-closes on directory navigation (with unsaved-edit guard)
212
+ - Git detection -- branch name and dirty file count badge in workspace header
213
+ - Right panel is drag-resizable
214
+ - Syntax highlighted code preview (Prism.js)
215
+
216
+ ### Voice input
217
+ - Microphone button in the composer (Web Speech API)
218
+ - Tap to record, tap again or send to stop
219
+ - Live interim transcription appears in the textarea
220
+ - Auto-stops after ~2s of silence
221
+ - Appends to existing textarea content (doesn't replace)
222
+ - Hidden when browser doesn't support Web Speech API (Chrome, Edge, Safari)
223
+
224
+ ### Profiles
225
+ - Profile chip in the **composer footer** -- dropdown showing all profiles with gateway status and model info
226
+ - Gateway status dots (green = running), model info, skill count per profile
227
+ - Profiles management panel -- create, switch, and delete profiles from the sidebar
228
+ - Clone config from active profile on create
229
+ - Optional custom endpoint fields on create -- Base URL and API key written into the profile's `config.yaml` at creation time, so Ollama, LMStudio, and other local endpoints can be configured without editing files manually
230
+ - Seamless switching -- no server restart; reloads config, skills, memory, cron, models
231
+ - Per-session profile tracking (records which profile was active at creation)
232
+
233
+ ### Authentication and security
234
+ - Optional password auth -- off by default, zero friction for localhost
235
+ - Enable via `HERMES_WEBUI_PASSWORD` env var or Settings panel
236
+ - Optional passkeys/WebAuthn -- register from Settings -> System after signing in with a password; the login page only shows passkey sign-in after at least one passkey exists
237
+ - After registering at least one passkey, Settings -> System can remove the password and keep passkey-only sign-in enabled. Password auth remains the bootstrap/recovery path until you choose to go passwordless; passkeys are same-origin and stored locally in the WebUI state directory
238
+ - Signed HMAC HTTP-only cookie with 24h TTL
239
+ - Minimal dark-themed login page at `/login`
240
+ - Security headers on all responses (X-Content-Type-Options, X-Frame-Options, Referrer-Policy)
241
+ - 20MB POST body size limit
242
+ - CDN resources pinned with SRI integrity hashes
243
+
244
+ ### Themes
245
+ - Appearance is split into two axes: Theme (`system`, `dark`, `light`) and Skin
246
+ (`default`, `ares`, `mono`, `slate`, `poseidon`, `sisyphus`, `charizard`,
247
+ `sienna`, `catppuccin`, `nous`, `geist-contrast` / Geist Contrast)
248
+ - Switch via Settings -> Appearance (instant live preview) or `/theme <theme-or-skin>`
249
+ - Persists across reloads (server-side in settings.json + localStorage for flicker-free loading)
250
+ - Skins use `data-skin` plus CSS variables; dark mode resolves through the
251
+ `.dark` class, not a `data-theme` custom-theme axis — see [THEMES.md](THEMES.md)
252
+
253
+ ### Settings and configuration
254
+ - **Hermes Control Center** (sidebar launcher button) -- Conversation tab (export/import/clear), Preferences tab (model, send key, theme, language, all toggles), System tab (version, password)
255
+ - Send key: Enter (default) or Ctrl/Cmd+Enter
256
+ - Show/hide CLI sessions toggle (enabled by default)
257
+ - Token usage display toggle (off by default, also via `/usage` command)
258
+ - Control Center always opens on the Conversation tab; resets on close
259
+ - Unsaved changes guard -- discard/save prompt when closing with unpersisted changes
260
+ - Cron completion alerts -- toast notifications and unread badge on Tasks tab
261
+ - Background agent error alerts -- banner when a non-active session encounters an error
262
+
263
+ ### Slash commands
264
+ - Type `/` in the composer for autocomplete dropdown
265
+ - Built-in: `/help`, `/clear`, `/compress [focus topic]`, `/compact` (alias), `/model <name>`, `/workspace <name>`, `/new`, `/usage`, `/theme`
266
+ - Arrow keys navigate, Tab/Enter select, Escape closes
267
+ - Unrecognized commands pass through to the agent
268
+
269
+ ### Panels
270
+ - **Chat** -- session list, search, pin, archive, projects, new conversation
271
+ - **Tasks** -- view, create, edit, run, pause/resume, delete cron jobs; run history; completion alerts
272
+ - **Skills** -- list all skills by category, search, preview, create/edit/delete; linked files viewer
273
+ - **Memory** -- view and edit MEMORY.md and USER.md inline
274
+ - **Profiles** -- create, switch, delete agent profiles; clone config
275
+ - **Todos** -- live task list from the current session
276
+ - **Spaces** -- add, rename, remove workspaces; quick-switch from topbar
277
+
278
+ ### Mobile responsive
279
+ - Hamburger sidebar -- slide-in overlay on mobile (<640px)
280
+ - Sidebar top tabs stay available on mobile; no fixed bottom nav stealing chat height
281
+ - Files slide-over panel from right edge
282
+ - Touch targets minimum 44px on all interactive elements
283
+ - Full-height chat/composer on phones without bottom-nav spacing
284
+ - Desktop layout completely unchanged
285
+
286
+ ---
287
+
288
+ ## Configuration & access
289
+
290
+ `start.sh` auto-detects almost everything; the subsections below cover the knobs for when it can't, and how to reach the UI remotely.
291
+
292
+ ### What start.sh discovers automatically
293
+
294
+ | Thing | How it finds it |
295
+ |---|---|
296
+ | Hermes agent dir | `HERMES_WEBUI_AGENT_DIR` env, then `$HERMES_HOME/hermes-agent` (Windows default `%LOCALAPPDATA%\hermes\hermes-agent`, POSIX default `~/.hermes/hermes-agent`), then sibling `../hermes-agent` |
297
+ | Python executable | Agent venv first, then `.venv` in this repo, then system `python3` |
298
+ | State directory | `HERMES_WEBUI_STATE_DIR` env, then `$HERMES_HOME/webui` (Windows default `%LOCALAPPDATA%\hermes\webui`, POSIX default `~/.hermes/webui`) |
299
+ | Default workspace | `HERMES_WEBUI_DEFAULT_WORKSPACE` env, then `~/workspace`, then state dir |
300
+ | Port | `HERMES_WEBUI_PORT` env or first argument, default `8787` |
301
+
302
+ If discovery finds everything, nothing else is required.
303
+
304
+ ---
305
+
306
+ ### Overrides (only needed if auto-detection misses)
307
+
308
+ ```bash
309
+ export HERMES_WEBUI_AGENT_DIR=/path/to/hermes-agent
310
+ export HERMES_WEBUI_PYTHON=/path/to/python
311
+ export HERMES_WEBUI_PORT=9000
312
+ export HERMES_WEBUI_AUTO_INSTALL=1 # enable auto-install of agent deps (disabled by default)
313
+ ./start.sh
314
+ ```
315
+
316
+ Or inline:
317
+
318
+ ```bash
319
+ HERMES_WEBUI_AGENT_DIR=/custom/path ./start.sh 9000
320
+ ```
321
+
322
+ Full list of environment variables:
323
+
324
+ | Variable | Default | Description |
325
+ |---|---|---|
326
+ | `HERMES_WEBUI_AGENT_DIR` | auto-discovered | Path to the hermes-agent checkout |
327
+ | `HERMES_WEBUI_PYTHON` | auto-discovered | Python executable |
328
+ | `HERMES_WEBUI_HOST` | `127.0.0.1` | Bind address (`0.0.0.0` for all IPv4, `::` for all IPv6, `::1` for IPv6 loopback) |
329
+ | `HERMES_WEBUI_PORT` | `8787` | Port |
330
+ | `HERMES_WEBUI_STATE_DIR` | `$HERMES_HOME/webui` (Windows default `%LOCALAPPDATA%\hermes\webui`, POSIX default `~/.hermes/webui`) | Where sessions and state are stored |
331
+ | `HERMES_WEBUI_DEFAULT_WORKSPACE` | `~/workspace` | Default workspace |
332
+ | `HERMES_WEBUI_DEFAULT_MODEL` | *(provider default)* | Optional model override; leave unset to use the active Hermes provider default |
333
+ | `HERMES_WEBUI_PASSWORD` | *(unset)* | Set to enable password authentication |
334
+ | `HERMES_WEBUI_CSP_CONNECT_EXTRA` | *(unset)* | Optional space-separated `http(s)://` or `ws(s)://` origins to append to the report-only CSP `connect-src` directive for reverse-proxy or tunnel deployments |
335
+ | `HERMES_WEBUI_EXTENSION_DIR` | *(unset)* | Optional local directory served at `/extensions/`; must point to an existing directory before extension injection is enabled |
336
+ | `HERMES_WEBUI_EXTENSION_SCRIPT_URLS` | *(unset)* | Optional comma-separated same-origin script URLs to inject; see [WebUI Extensions](docs/EXTENSIONS.md) |
337
+ | `HERMES_WEBUI_EXTENSION_STYLESHEET_URLS` | *(unset)* | Optional comma-separated same-origin stylesheet URLs to inject; see [WebUI Extensions](docs/EXTENSIONS.md) |
338
+ | `HERMES_HOME` | Windows: `%LOCALAPPDATA%\hermes`; POSIX: `~/.hermes` | Base directory for Hermes state (affects all paths) |
339
+ | `HERMES_CONFIG_PATH` | `$HERMES_HOME/config.yaml` | Path to Hermes config file |
340
+
341
+ ---
342
+
343
+ ### Remote access (SSH tunnel, Tailscale, phone)
344
+
345
+ The server binds to `127.0.0.1` by default. To reach it from another machine use an SSH tunnel (`ssh -N -L 8787:127.0.0.1:8787 user@host`, which `start.sh` prints for you over SSH), or join your server and phone to a [Tailscale](https://tailscale.com) network and browse to `http://<server-tailscale-ip>:8787` with `HERMES_WEBUI_HOST=0.0.0.0` + `HERMES_WEBUI_PASSWORD` set. Full walkthrough (incl. a community ARM64-Android field report): [`docs/remote-access.md`](docs/remote-access.md).
346
+
347
+ ### Manual launch (without start.sh)
348
+
349
+ If you prefer to launch the server directly:
350
+
351
+ ```bash
352
+ cd /path/to/hermes-agent # or wherever sys.path can find Hermes modules
353
+ HERMES_WEBUI_PORT=8787 venv/bin/python /path/to/hermes-webui/server.py
354
+ ```
355
+
356
+ Note: use the agent venv Python (or any Python environment that has the Hermes agent dependencies installed). System Python will be missing `openai`, `httpx`, and other required packages.
357
+
358
+ Health check:
359
+
360
+ ```bash
361
+ curl http://127.0.0.1:8787/health
362
+ ```
363
+
364
+ ---
365
+
366
+ ## Docker
367
+
368
+ **Pre-built images** (amd64 + arm64) are published to GHCR on every release.
369
+
370
+ For a comprehensive setup guide covering all 3 compose files, common failure modes, and bind-mount migration, see [`docs/docker.md`](docs/docker.md). The README covers the 5-minute happy path.
371
+
372
+ ### 5-minute quickstart (single container)
373
+
374
+ The simplest setup: one WebUI container that runs the agent in-process.
375
+
376
+ ```bash
377
+ git clone https://github.com/nesquena/hermes-webui
378
+ cd hermes-webui
379
+ cp .env.docker.example .env
380
+ # Edit .env if your host UID isn't 1000 (e.g. macOS where UIDs start at 501)
381
+ docker compose up -d
382
+ # Open http://localhost:8787
383
+ ```
384
+
385
+ Run Compose as the user who owns your Hermes home. `sudo docker compose up -d` can make `${HOME}` expand to the root user's home, so Docker mounts the wrong `.hermes` directory instead of your real `~/.hermes` and the WebUI starts with `config.yaml (not found, using defaults)`. Prefer adding your user to the Docker group and running `docker compose up -d`; if you must use sudo, set absolute paths first, for example `HERMES_HOME=/home/you/.hermes HERMES_WORKSPACE=/home/you/workspace sudo -E docker compose up -d`, then verify with `docker compose config`.
386
+
387
+ The container auto-detects your UID/GID from the mounted `~/.hermes` volume so files written by the agent stay readable by you on the host.
388
+
389
+ To enable password protection (required if you expose the port outside `127.0.0.1`):
390
+
391
+ ```bash
392
+ echo "HERMES_WEBUI_PASSWORD=change-me-to-something-strong" >> .env
393
+ docker compose up -d --force-recreate
394
+ ```
395
+
396
+ ### Manual `docker run` (no compose)
397
+
398
+ ```bash
399
+ docker pull ghcr.io/nesquena/hermes-webui:latest
400
+ docker run -d \
401
+ -e WANTED_UID=$(id -u) -e WANTED_GID=$(id -g) \
402
+ -v ~/.hermes:/home/hermeswebui/.hermes \
403
+ -e HERMES_WEBUI_STATE_DIR=/home/hermeswebui/.hermes/webui \
404
+ -v ~/workspace:/workspace \
405
+ -p 127.0.0.1:8787:8787 \
406
+ ghcr.io/nesquena/hermes-webui:latest
407
+ ```
408
+
409
+ ### Build locally
410
+
411
+ ```bash
412
+ docker build -t hermes-webui .
413
+ docker run -d \
414
+ -e WANTED_UID=$(id -u) -e WANTED_GID=$(id -g) \
415
+ -v ~/.hermes:/home/hermeswebui/.hermes \
416
+ -e HERMES_WEBUI_STATE_DIR=/home/hermeswebui/.hermes/webui \
417
+ -v ~/workspace:/workspace \
418
+ -p 127.0.0.1:8787:8787 \
419
+ hermes-webui
420
+ ```
421
+
422
+ ### Multi-container setups
423
+
424
+ If you want the agent and WebUI in separate containers (for isolation, or because you're already running an agent gateway elsewhere):
425
+
426
+ ```bash
427
+ # Agent + WebUI
428
+ docker compose -f docker-compose.two-container.yml up -d
429
+
430
+ # Agent + Dashboard + WebUI
431
+ docker compose -f docker-compose.three-container.yml up -d
432
+ ```
433
+
434
+ Both compose files use **named Docker volumes** by default, which solves the UID/GID problem by construction. If you need bind mounts to share an existing host directory, see [`docs/docker.md`](docs/docker.md) for the full migration recipe.
435
+
436
+ > **Known limitation (#681)**: in the two-container setup, tools triggered from the WebUI run in the **WebUI container**, not the agent container. If you need git/node/etc. on the WebUI's filesystem, either use the single-container setup, extend the WebUI Dockerfile, or use the community [all-in-one image](https://github.com/sunnysktsang/hermes-suite).
437
+ >
438
+ > **Source boundary note (#2453)**: the multi-container setup mounts `hermes-agent-src` read-only into the WebUI by default. This prevents WebUI-side source rewrites but is still an implementation-coupling bridge, not a stable Agent API boundary. See [`docs/rfcs/agent-source-boundary.md`](docs/rfcs/agent-source-boundary.md) for the current source/API decoupling inventory.
439
+
440
+ ### Common failure modes
441
+
442
+ | Symptom | Likely cause | Fix |
443
+ |---|---|---|
444
+ | `PermissionError` at startup | UID mismatch on bind mount | Set `UID=$(id -u)` in `.env` |
445
+ | `.env: permission denied` (#1389) | `fix_credential_permissions()` enforced 0600 | Set `HERMES_SKIP_CHMOD=1` in `.env` |
446
+ | Workspace appears empty | UID mismatch on `/workspace` mount | Set `UID=$(id -u)` in `.env` |
447
+ | `git: command not found` in chat | Two-container architectural limit (#681) | Use single-container or extend Dockerfile |
448
+ | WebUI can't find agent source | `hermes-agent-src` volume misconfigured | Use the named volumes from compose files as-is |
449
+ | Podman shared `.hermes` fails | Podman 3.4 `keep-id` limitation | Use Podman 4+ or single-container |
450
+ | Host API at `localhost` fails from WebUI | Container `localhost` means the container, not your host (#3012) | Use `http://host.docker.internal:<port>` on Docker Desktop, or `http://host.containers.internal:<port>` on Podman |
451
+ | WebUI can't see `~/.hermes` after `sudo docker compose` | `${HOME}` expanded to the root user's home (#3006) | Run Compose as your user, or pass absolute `HERMES_HOME`/`HERMES_WORKSPACE` with `sudo -E` |
452
+
453
+ For the deep dive on each of these, see [`docs/docker.md`](docs/docker.md).
454
+
455
+ > **Note:** By default, Docker Compose binds to `127.0.0.1` (localhost only).
456
+ > To expose on a network, change the port to `"8787:8787"` in `docker-compose.yml`
457
+ > and set `HERMES_WEBUI_PASSWORD` to enable authentication.
458
+
459
+ ---
460
+
461
+ ## Running tests
462
+
463
+ Tests discover the repo and the Hermes agent dynamically -- no hardcoded paths.
464
+
465
+ ```bash
466
+ cd hermes-webui
467
+ pytest tests/ -v --timeout=60
468
+ ```
469
+
470
+ Or using the agent venv explicitly:
471
+
472
+ ```bash
473
+ /path/to/hermes-agent/venv/bin/python -m pytest tests/ -v
474
+ ```
475
+
476
+ Tests run against an isolated server with a separate state directory.
477
+ Production data and real cron jobs are never touched. Current snapshot:
478
+ **~7,150 tests collected** across **~700 test files**, run in CI on Python 3.11,
479
+ 3.12, and 3.13 (3 parallel shards each).
480
+
481
+ ---
482
+
483
+ ## Architecture
484
+
485
+ No build step, no framework, no bundler — a Python standard-library HTTP server
486
+ and vanilla JS. The backend lives in `api/`, the frontend in `static/`.
487
+
488
+ **Backend (`api/`)**
489
+
490
+ ```
491
+ server.py HTTP routing shell + auth middleware
492
+ api/
493
+ auth.py Optional password authentication, signed cookies, passkeys
494
+ config.py Discovery, globals, model detection, reloadable config
495
+ helpers.py HTTP helpers, security headers
496
+ models.py Session model + CRUD + CLI/state.db bridge
497
+ onboarding.py First-run onboarding wizard, OAuth provider support
498
+ profiles.py Profile state management, hermes_cli wrapper
499
+ routes.py All GET + POST route handlers (if/elif dispatch, no decorators)
500
+ state_sync.py /insights sync — message_count to state.db
501
+ streaming.py SSE engine, run_agent, cancellation, compression
502
+ updates.py Self-update check and release notes
503
+ upload.py Multipart parser, file upload handler
504
+ workspace.py File ops, workspace helpers, git detection
505
+ ```
506
+
507
+ **Frontend (`static/`)**
508
+
509
+ ```
510
+ index.html HTML template
511
+ style.css All CSS incl. mobile responsive, themes + skins
512
+ ui.js DOM helpers, renderMd, tool cards, context indicator
513
+ workspace.js File preview, file ops, git badge, central api() fetch wrapper
514
+ sessions.js Session CRUD, collapsible groups, search, reload recovery
515
+ messages.js send(), SSE handlers, live streaming, session recovery
516
+ panels.js Cron, skills, memory, profiles, settings (Control Center)
517
+ commands.js Slash command autocomplete
518
+ boot.js Mobile nav, voice input, theme/skin boot, bfcache handler
519
+ ```
520
+
521
+ **Tests + packaging**
522
+
523
+ ```
524
+ tests/ Pytest suite (~7,150 tests; isolated server/state fixtures)
525
+ pyproject.toml Tooling config (ruff lint gate) — not a packaged distribution
526
+ Dockerfile python:3.12-slim container image
527
+ docker-compose.yml Compose with named volume and optional auth
528
+ .github/workflows/ CI: ruff + sharded pytest, browser smoke, Docker smoke,
529
+ multi-arch Docker build + GitHub Release on tag
530
+ ```
531
+
532
+ State lives outside the repo at `~/.hermes/webui/` by default
533
+ (sessions, workspaces, settings, projects, last_workspace). Override with `HERMES_WEBUI_STATE_DIR`.
534
+ Full design notes and the endpoint catalog are in [`ARCHITECTURE.md`](ARCHITECTURE.md).
535
+
536
+ ---
537
+
538
+ ## Docs
539
+
540
+ **Start here**
541
+ - [`docs/why-hermes.md`](docs/why-hermes.md) — why Hermes, the mental model, and a detailed comparison to Claude Code / Codex / OpenCode / Cursor
542
+ - [`docs/onboarding.md`](docs/onboarding.md) — first-run wizard, provider setup, local model server Base URLs, and safe re-runs
543
+ - [`docs/troubleshooting.md`](docs/troubleshooting.md) — diagnostic flows for common failures (e.g. "AIAgent not available")
544
+
545
+ **Using & customizing**
546
+ - [`THEMES.md`](THEMES.md) — theme + skin system, custom theme guide
547
+ - [`docs/workspace-git.md`](docs/workspace-git.md) — the workspace Git controls
548
+ - [`docs/EXTENSIONS.md`](docs/EXTENSIONS.md) — administrator-controlled WebUI extension injection
549
+
550
+ **Deploying & operating**
551
+ - [`docs/remote-access.md`](docs/remote-access.md) — SSH tunnel, Tailscale, and phone access (incl. a community ARM64-Android field report)
552
+ - [`docs/advanced-chat-setup.md`](docs/advanced-chat-setup.md) — optional dynamic recall-prefill and Gateway-backed browser chat for self-hosted deployments
553
+ - [`docs/docker.md`](docs/docker.md) — Docker compose setup, common failures, and bind-mount migration
554
+ - [`docs/supervisor.md`](docs/supervisor.md) — launchd, systemd, supervisord, runit, and s6 process-supervisor setup
555
+ - [`docs/wsl-autostart.md`](docs/wsl-autostart.md) — WSL2 auto-start at Windows login
556
+ - [`docs/onboarding-agent-checklist.md`](docs/onboarding-agent-checklist.md) — safety rules and pass/fail checks for assistant-led install/reinstall support
557
+
558
+ **Contributing & design**
559
+ - [`CONTRIBUTING.md`](CONTRIBUTING.md) — contribution style, PR expectations, and local verification
560
+ - [`ARCHITECTURE.md`](ARCHITECTURE.md) — system design, all API endpoints, implementation notes
561
+ - [`TESTING.md`](TESTING.md) — manual browser test plan and automated coverage reference
562
+ - [`DESIGN.md`](DESIGN.md) — design tokens and the calm-console direction
563
+ - [`docs/UIUX-GUIDE.md`](docs/UIUX-GUIDE.md) — UI/UX principles sourced from the design docs and visual inventories
564
+ - [`docs/CONTRACTS.md`](docs/CONTRACTS.md) — project contract/RFC/design index for contributors and agents
565
+ - [`docs/rfcs/README.md`](docs/rfcs/README.md) — RFC index for larger architecture and durability proposals
566
+
567
+ **Release history & plan**
568
+ - [`CHANGELOG.md`](CHANGELOG.md) — release notes per version
569
+ - [`ROADMAP.md`](ROADMAP.md) — feature roadmap and sprint history
570
+ - [`SPRINTS.md`](SPRINTS.md) — forward sprint plan with CLI + Claude parity targets
571
+ - [`CONTRIBUTORS.md`](CONTRIBUTORS.md) — the full community credit roll
572
+
573
+ ---
574
+
575
+ ## Contributors
576
+
577
+ Hermes WebUI is built with help from the open-source community. Every PR — whether merged directly, absorbed into a batch release, or salvaged from a larger proposal — shapes the project, and we're grateful to everyone who has taken the time to contribute.
578
+
579
+ Over **190 contributors** have shipped code that landed in a release tag. The full,
580
+ continuously-updated credit roll — including everyone with one or two PRs and the
581
+ special-thanks roll for design and architectural work — lives in
582
+ [`CONTRIBUTORS.md`](CONTRIBUTORS.md). A snapshot of the most prolific contributors:
583
+
584
+ ### Top contributors (by PR count, including absorbed/batch-released work)
585
+
586
+ | # | Contributor | PRs | First → latest release |
587
+ |---|---|---:|---|
588
+ | 1 | [@franksong2702](https://github.com/franksong2702) | 148 | `v0.49.3` → `v0.51.153` |
589
+ | 2 | [@Michaelyklam](https://github.com/Michaelyklam) | 117 | `v0.50.240` → `v0.51.139` |
590
+ | 3 | [@bergeouss](https://github.com/bergeouss) | 70 | `v0.48.0` → `v0.51.46` |
591
+ | 4 | [@ai-ag2026](https://github.com/ai-ag2026) | 67 | `v0.50.279` → `v0.51.190` |
592
+ | 5 | [@dso2ng](https://github.com/dso2ng) | 25 | `v0.50.227` → `v0.51.153` |
593
+ | 6 | [@AJV20](https://github.com/AJV20) | 24 | `v0.51.93` → `v0.51.188` |
594
+ | 7 | [@starship-s](https://github.com/starship-s) | 19 | `v0.50.123` → `v0.51.153` |
595
+ | 8 | [@jasonjcwu](https://github.com/jasonjcwu) | 16 | `v0.50.227` → `v0.51.132` |
596
+ | 9 | [@dobby-d-elf](https://github.com/dobby-d-elf) | 15 | `v0.51.38` → `v0.51.161` |
597
+ | 10 | [@Jordan-SkyLF](https://github.com/Jordan-SkyLF) | 12 | `v0.50.18` → `v0.51.66` |
598
+
599
+ See [`CONTRIBUTORS.md`](CONTRIBUTORS.md) for the full ranked list of all 194 contributors, including everyone with one or two PRs and the special-thanks roll for design and architectural contributions.
600
+
601
+ ### Notable contributions
602
+
603
+ **[@franksong2702](https://github.com/franksong2702)** — Most prolific external contributor (148 PRs, `v0.49.3` → `v0.51.153`)
604
+ Across the longest tenure of any external contributor: the session title guard (#301), breadcrumb workspace navigation (#302), embedded workspace terminal (#1099), worktree-backed session creation (#2053), onboarding documentation (#2052), composer footer container queries, streaming-session sidebar exemption (#1327), session sidecar repair, cron output preservation (#1295), profile default workspace persistence, manual `/compress` async start/status endpoints (#2128), worktree status surface (#2109) + guarded remove (#2156) for the lifecycle umbrella #2057, session post-render dedup (#2166), native-WebUI fast path (#2170), tail-window response trim (#2171), stale-stream guard extension (#2158), CSP report collector (#2160), and a long tail of polish across mobile/responsive, the session sidebar, and the workspace state machine.
605
+
606
+ **[@Michaelyklam](https://github.com/Michaelyklam)** — Most prolific contributor of recent releases (117 PRs, `v0.50.240` → `v0.51.139`)
607
+ Production Docker hardening (#1921, drops sudo-capable staging user), profile-scoped skills endpoints (#1903), gateway PID resolution under profile-scoped HERMES_HOME (#1901), profile-aware AIAgent cache (#1898/#1904), backslash LaTeX delimiters (#1848), Codex quota error surfacing (#1770), shell-route HTML 503 (#1836), stale Kanban client recovery (#1828), context auto-compression toast lifetime (#1988), `/goal` command (#1866), Kanban detail-view scrolling (#1916), CLI session tool metadata preservation (#1778), Traditional Chinese kanban locale backfill (#1979), v0.51.51 mobile Insights bucketing/layout (#2120/#2121), Hermes run adapter RFC (#2105 for #1925), fork-from-here absolute index (#2198 for #2184), opencode-go custom-provider overlap routing (#2204 for #1894).
608
+
609
+ **[@bergeouss](https://github.com/bergeouss)** — Provider management UI + Docker hardening (70 PRs, `v0.48.0` → `v0.51.46`)
610
+ Provider management UI for adding/editing custom providers from Settings, OAuth provider status detection (#1552), two-container Docker setup, profile isolation hardening (per-profile `.env` secrets), the bulk of what users see when they touch Settings → Providers, Reveal-in-Finder context menu (#1551), gateway status card (#1552), auto-assign session to active project filter (#1550), "What's new?" link in update banner (#1549), OpenRouter free-tier live fetch (#1548), credential pool 401 self-heal (#1553), inline provider chip + group model count in model picker (#1644).
611
+
612
+ **[@ai-ag2026](https://github.com/ai-ag2026)** — Session recovery + audit infrastructure (67 PRs, `v0.50.279` → `v0.51.190`)
613
+ Autonomous-AI contributor (Hermes Agent-driven) focused on durability: `state.db`-backed sidecar reconciliation (#2041), orphan `.json.bak` recovery on startup (#2035), read-only session recovery audit endpoints (#2036, #2040), active run lifecycle in `/health` (#2039), crash-safe turn-journal RFC at `docs/rfcs/turn-journal.md` (#2042), append-only turn-journal helper (#2059), lifecycle events layer (#2062), `Content-Security-Policy-Report-Only` header (#2084), per-cron toast toggle (#2100), fork-session compression lineage isolation (#2014).
614
+
615
+ **[@dso2ng](https://github.com/dso2ng)** — Session lineage + diagnostics (25 PRs, `v0.50.227` → `v0.51.153`)
616
+ `/api/session/lineage-report/<sid>` endpoint for bounded session graph diagnostics (#2012), stale Mermaid render error cleanup (#1337), `session_source="fork"` continuation-chain isolation (#2063), lazy lineage-report fetch on sidebar badge expand (#2130), and a long tail of frontend reliability fixes around session loading.
617
+
618
+ **[@jasonjcwu](https://github.com/jasonjcwu)** — Composer + transcript polish (16 PRs, `v0.50.227` → `v0.51.132`)
619
+ Sidebar collapse via active-rail click (#2054, fuses #1884 + #1924), composer chip lightbox (#1758), title fixes for tool-heavy first turns, silent compress-status during session switch (#2185), concurrent-send loss fix (#2186), in-transcript steer message badges (#2187), and a string of frontend polish fixes.
620
+
621
+ **[@Jordan-SkyLF](https://github.com/Jordan-SkyLF)** — Live streaming + UX polish (12 PRs, `v0.50.18` → `v0.51.66`)
622
+ Original sprint of workspace fallback resolution, live reasoning cards (#366, #367, #394–#397), then a recent burst: manual "Refresh usage" button on the Provider quota card (#2150), cancelled-turn status classification (#2151), Firefox sidebar scroll stabilization (#2200), early provisional session titles (#2202), target-aware "What's new?" update-banner links (#2207), and MCP tools overflow fix in Settings (#2210).
623
+
624
+ **[@aronprins](https://github.com/aronprins)** — `v0.50.0` UI overhaul (PR #242, plus 9 follow-ups)
625
+ The biggest single contribution to the project: a complete UI redesign that moved model/profile/workspace controls into the composer footer, replaced the gear-icon settings panel with the Hermes Control Center (tabbed modal), removed the activity bar in favor of inline composer status, redesigned the session list with a `⋯` action dropdown, and added the workspace panel state machine. Plus chat transcript redesign (#587), sidebar declutter (#584), three-column layout refactor (#899), light/dark theme + accent skins (#627), and shared `confirm()`/`prompt()` dialog replacement (PR #251 extracted from #242).
626
+
627
+ **[@iRonin](https://github.com/iRonin)** — Security hardening sprint (PRs #196–#204)
628
+ Six consecutive, focused security PRs: session memory leak fix (expired token pruning), CSP + Permissions-Policy headers, 30-second slow-client connection timeout, optional HTTPS/TLS support via environment variables, upstream branch tracking fix for self-update, and CLI session support in the file-browser API. The kind of focused, high-quality security work that makes a self-hosted tool trustworthy.
629
+
630
+ **[@lucasrc](https://github.com/lucasrc)** — Auth-hardening trilogy (PRs #2191, #2192, #2193)
631
+ Three coordinated security PRs that all landed in v0.51.57: thread-safe login rate limiter with PBKDF2 key separation, password-hash cache invalidation on Settings save, and the full 64-char HMAC-SHA256 session signature with a backwards-compatible migration bridge. The kind of cleanly-decomposed security work that's reviewable as three independent pieces.
632
+
633
+ **[@LumenYoung](https://github.com/LumenYoung)** — Streaming hot-path correctness (8 PRs, `v0.51.47` → `v0.51.99`)
634
+ The original stale-stream writeback guard (#2136 — the bug class the next two releases extended), gateway-state alive-null classification (#2075), compression-banner anchor alignment (#2182), and context-progress ring auto-refresh on compression complete (#2188). Each PR opened a small surgical fix in one of the most fragile subsystems in the codebase.
635
+
636
+ **[@dobby-d-elf](https://github.com/dobby-d-elf)** — Frontend reliability + motion polish (15 PRs, `v0.51.38` → `v0.51.161`)
637
+ Workspace fallback on deleted directories (#2138), iPhone PWA bottom-scroll fix (#2143), the new "Activity: X tools" composer footer shimmer animation (#2203), and follow-up animation tuning (#2212).
638
+
639
+ **[@JKJameson](https://github.com/JKJameson)** — Composer + session polish (10 PRs)
640
+ Persistent composer draft per session (#1956), and a long tail of polish across the composer and session sidebar.
641
+
642
+ **[@gabogabucho](https://github.com/gabogabucho)** — Spanish locale + onboarding wizard
643
+ Full Spanish (`es`) locale covering all UI strings, plus the one-shot bootstrap onboarding wizard that guides new users through provider setup on first launch.
644
+
645
+ **[@deboste](https://github.com/deboste)** — Reverse-proxy auth + mobile responsive layout (PRs #3, #4, #5)
646
+ Three of the very first community PRs: fixed EventSource/fetch to use URL origin for reverse-proxy setups, corrected model provider routing from config, and added mobile responsive layout with dvh viewport fix. Early foundation work.
647
+
648
+ **[@indigokarasu](https://github.com/indigokarasu)** — Visual redesign proposal (PR #213)
649
+ A CSS-only redesign of the full UI — proper design tokens, an icon rail sidebar replacing the emoji tab strip, consistent form cards, breadcrumb nav, and 7 built-in themes as custom properties. The PR didn't merge as-is but shaped the design language and theme architecture that shipped in v0.50.0.
650
+
651
+ **[@zenc-cp](https://github.com/zenc-cp)** — Anti-hallucination guard for the ReAct loop (PR #133)
652
+ A three-layer approach (ephemeral anti-hallucination prompt, live token filtering, session-history cleanup) that the streaming pipeline still uses.
653
+
654
+ **[@Hinotoi-agent](https://github.com/Hinotoi-agent)** — Profile + session security (PRs #351, #2048)
655
+ Profile `.env` secret isolation fix (PR #351) preventing API key leakage between profiles, and session-import workspace validation (PR #2048) blocking a crafted-JSON file-read against `/`.
656
+
657
+ **[@Sanjays2402](https://github.com/Sanjays2402)** — Endless-scroll + Start-jump race fix (PR #1949)
658
+ A generation-token + mutex pair fixing the v0.51.30 race between endless-scroll prefetch and Start-jump's `_ensureAllMessagesLoaded`. The naive same-flag-check approach (proposed in #1942 and #1962) was a no-op for the post-await race — Sanjays2402's fix was the correct shape.
659
+
660
+ **[@fxd-jason](https://github.com/fxd-jason)** — Real-time approval + clarify via SSE (PRs #1350, #1355)
661
+ Replaced 1.5s HTTP polling with SSE long-connections for both approval and clarify, cutting latency from up to 1.5s to near-instant. Got all the correctness details right (atomic subscribe + snapshot, notify-inside-lock, head-of-queue payload, trailing event re-emission).
662
+
663
+ **[@happy5318](https://github.com/happy5318)** — Custom provider model dedup (PR #1947)
664
+ Fixed the same model from different named custom providers being silently deduplicated in the picker, with Opus catching a race in the original tests that needed augmentation.
665
+
666
+ **[@NocGeek](https://github.com/NocGeek)** — Streaming scroll + manual cron output persistence (7 PRs)
667
+ Streaming scroll viewport stability when tool/queue cards insert (#1360), manual cron-run output and metadata persistence (#1372, split from held #1352).
668
+
669
+ **[@DavidSchuchert](https://github.com/DavidSchuchert)** — German translation (PR #190)
670
+ Complete German locale (`de`) covering all UI strings, settings labels, commands, and system messages — and stress-tested the i18n system, exposing several elements that weren't yet translatable and getting them fixed as part of the same PR.
671
+
672
+ **[@Bobby9228](https://github.com/Bobby9228)** — Mobile Profiles button (PR #265)
673
+ Added the Profiles entry to the mobile navigation flow, making profile switching reachable on phones.
674
+
675
+ **[@kevin-ho](https://github.com/kevin-ho)** — OLED theme (PR #168)
676
+ The 7th built-in theme: pure black backgrounds with warm accents tuned to reduce burn-in risk.
677
+
678
+ **[@andrewy-wizard](https://github.com/andrewy-wizard)** — Chinese localization (PR #177)
679
+ Initial Simplified Chinese (`zh`) locale. One of the first non-English locales.
680
+
681
+ **[@DelightRun](https://github.com/DelightRun)** — `session_search` fix for WebUI sessions (PR #356)
682
+ Tracked down the missing `SessionDB` injection in the streaming path that was silently breaking the tool for every WebUI session.
683
+
684
+ **[@lawrencel1ng](https://github.com/lawrencel1ng)** — Bandit security fixes (PR #354)
685
+ Systematic bandit-scan fixes: URL scheme validation before `urlopen`, MD5 `usedforsecurity=False`, and 40+ bare `except: pass` blocks replaced with proper logging.
686
+
687
+ **[@shaoxianbilly](https://github.com/shaoxianbilly)** — Unicode filename downloads (PR #378)
688
+ Proper `Content-Disposition` with RFC 5987 `filename*=UTF-8''...` encoding so non-ASCII filenames download without crashing.
689
+
690
+ **[@lx3133584](https://github.com/lx3133584)** — CSRF fix for reverse proxy (PR #360)
691
+ A real-world blocker for anyone hosting behind Nginx Proxy Manager or similar on a port other than 80/443.
692
+
693
+ **[@betamod](https://github.com/betamod)** — Security audit (PR #171)
694
+ A comprehensive CSRF / SSRF / XSS / env-race-condition audit that shipped in v0.39.0.
695
+
696
+ **[@TaraTheStar](https://github.com/TaraTheStar)** — Bot name + thinking blocks + login refactor (PRs #132, #176, #181)
697
+ Configurable assistant display name, thinking/reasoning block display, and a login page refactor.
698
+
699
+ ---
700
+
701
+ ## Repo
702
+
703
+ ```
704
+ git@github.com:nesquena/hermes-webui.git
705
+ ```