@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,83 @@
1
+ # Advanced chat setup
2
+
3
+ Two optional features for self-hosted Hermes WebUI deployments. **Most users need neither** — the defaults (in-process chat, no prefill) work out of the box.
4
+
5
+ ## Session recall prefill
6
+
7
+ WebUI can attach ephemeral prefill messages to new browser-originated
8
+ agent turns. This is useful when a deployment already has a local recall or
9
+ router script for Joplin, Obsidian, Notion, llm-wiki, or another third-party
10
+ notes source and wants browser chat to know where durable context lives.
11
+
12
+ Prefer a compact router-style prefill (for example, "Joplin has the durable
13
+ project context; use the available notes/search tools before answering
14
+ detail-dependent questions") instead of dumping the full note corpus into every
15
+ new browser session. The prefill should point the agent toward retrieval; the
16
+ notes/search tools should provide the specific facts on demand.
17
+
18
+ Static JSON remains supported through `prefill_messages_file` or
19
+ `HERMES_PREFILL_MESSAGES_FILE`. For dynamic recall, opt in explicitly with a
20
+ WebUI-specific script hook:
21
+
22
+ ```yaml
23
+ webui_prefill_messages_script:
24
+ - python3
25
+ - /path/to/notes_recall.py
26
+ webui_prefill_messages_script_timeout: 5
27
+ ```
28
+
29
+ or:
30
+
31
+ ```bash
32
+ HERMES_WEBUI_PREFILL_MESSAGES_SCRIPT="python3 /path/to/notes_recall.py" \
33
+ HERMES_WEBUI_PREFILL_MESSAGES_SCRIPT_TIMEOUT=5 \
34
+ ./ctl.sh restart
35
+ ```
36
+
37
+ The script may print either an OpenAI-style JSON message list, a JSON object with
38
+ a `messages` list, or plain text; plain text is wrapped as one `user` prefill
39
+ message so dynamic recall text becomes ordinary context instead of an extra
40
+ system instruction. If the hook must provide system-level guidance, emit JSON
41
+ messages with an explicit `role: "system"` entry instead. Script output is capped
42
+ at 256 KiB before parsing. Parsed prefill context is then bounded by
43
+ `webui_prefill_context_max_chars` or `HERMES_WEBUI_PREFILL_CONTEXT_MAX_CHARS`
44
+ (default: 12,000 characters; set to `0` to disable). When a dynamic script
45
+ exceeds the budget and a compact static prefill file is configured, WebUI falls
46
+ back to that file. If no compact fallback is available, WebUI injects a short
47
+ retrieval instruction instead of sending the oversized note/body payload with
48
+ every new browser turn. The browser only receives a compact status event
49
+ (`source`, `label`, message count, compaction metadata, and redacted errors),
50
+ never the prefill message bodies.
51
+
52
+ ## Gateway-backed browser chat
53
+
54
+ By default, browser chat runs through WebUI's in-process legacy runtime. Advanced
55
+ self-hosted deployments can opt into routing new browser turns through a running
56
+ Hermes Gateway API server while preserving the existing WebUI `/api/chat/start`
57
+ and `/api/chat/stream` browser contract:
58
+
59
+ ```bash
60
+ HERMES_WEBUI_CHAT_BACKEND=gateway \
61
+ HERMES_WEBUI_GATEWAY_BASE_URL=http://127.0.0.1:8642 \
62
+ HERMES_WEBUI_GATEWAY_API_KEY=... \
63
+ ./ctl.sh restart
64
+ ```
65
+
66
+ `HERMES_WEBUI_CHAT_BACKEND` is intentionally strict: only `gateway`,
67
+ `api_server`, or `api-server` enable the bridge. Generic truthy values such as
68
+ `1` or `true` are ignored so existing deployments do not change execution
69
+ ownership accidentally. If `HERMES_WEBUI_GATEWAY_API_KEY` is omitted, WebUI falls
70
+ back to `API_SERVER_KEY` when present. When Gateway returns HTTP 401, WebUI
71
+ reports a `gateway_auth_error` that points at this WebUI↔Gateway key mismatch
72
+ rather than showing the Gateway's generic provider-style "Invalid API key" body.
73
+ `/api/health/agent` also includes a redacted `gateway_chat` block so operators can
74
+ see whether gateway mode, base URL, and API-key presence are configured without
75
+ exposing the key value. That `gateway_chat` field is an operator diagnostic
76
+ payload only; it is not currently rendered as a user-facing health banner in the
77
+ browser UI.
78
+
79
+ The bridge is best used by operators who already run Hermes Gateway/API Server
80
+ locally and want browser-originated chat to use the same runtime/tool path as
81
+ messaging surfaces. Attachments, cancellation, approvals, and clarify prompts
82
+ still follow WebUI's current compatibility path and may not match every messaging
83
+ surface until the runtime-adapter migration is complete.
@@ -0,0 +1,337 @@
1
+ # Hermes WebUI — Docker setup guide
2
+
3
+ This is the comprehensive Docker reference. For a 5-minute quickstart, see the [README Docker section](../README.md#docker).
4
+
5
+ ## TL;DR — pick one
6
+
7
+ | Setup | When to use | File |
8
+ |---|---|---|
9
+ | **Single-container** (recommended) | You just want chat working. WebUI runs the agent in-process. | `docker-compose.yml` |
10
+ | **Two-container** | You want isolation between gateway (CLI/Telegram/cron) and chat UI. | `docker-compose.two-container.yml` |
11
+ | **Three-container** | Two-container PLUS the dashboard for monitoring. | `docker-compose.three-container.yml` |
12
+ | **All-in-one image** (community fork — third-party, not maintained by us) | Podman 3.4 / multi-arch / supervisord-style preference. | [sunnysktsang/hermes-suite](https://github.com/sunnysktsang/hermes-suite) — see [#1399](https://github.com/nesquena/hermes-webui/issues/1399) for the original discussion |
13
+
14
+ If something stops working, **start with the single-container setup** — it's the simplest path and fixes most permission/UID/path-mismatch issues by construction.
15
+
16
+ ## Production image security model
17
+
18
+ The production Docker image is hardened for the normal single-tenant container threat model:
19
+ Hermes WebUI assumes one operator controls the container, mounted Hermes home, and workspace.
20
+ The image does **not** install `sudo`, does not add runtime users to a sudo group, and does not
21
+ grant `NOPASSWD` escalation. If an agent/tool process gains a shell as `hermeswebui`, it should
22
+ not be able to become root with a passwordless sudo command.
23
+
24
+ The entrypoint still starts as `root` for a narrow init phase because Docker bind mounts often need
25
+ UID/GID alignment and ownership preparation before the app can read `~/.hermes`, `/workspace`,
26
+ `/app`, and `/uv_cache`. After that setup, `docker_init.bash` re-execs itself as the unprivileged
27
+ `hermeswebui` user and starts the server there. Init scratch files under `/tmp/hermeswebui_init`
28
+ are owner-only (`0700` directory, `0600` files), not world-writable.
29
+
30
+ For multi-tenant or hostile-container environments, rebuild with your own runtime user, mount policy,
31
+ and supervisor assumptions. Development images that need package-manager convenience should add
32
+ those tools in a dev-only Dockerfile instead of reintroducing passwordless sudo to production.
33
+
34
+ ## 5-minute quickstart (single container)
35
+
36
+ ```bash
37
+ git clone https://github.com/nesquena/hermes-webui
38
+ cd hermes-webui
39
+ cp .env.docker.example .env
40
+ # Edit .env if needed (most users can skip this on Linux)
41
+ docker compose up -d
42
+ open http://localhost:8787
43
+ ```
44
+
45
+ That's it for a real personal Docker install. Your existing `~/.hermes`
46
+ directory is mounted, your `~/workspace` is browsable, and the WebUI
47
+ auto-detects your UID/GID from the mounted volume.
48
+
49
+ The single-container setup runs the WebUI only. It can create cron jobs and run
50
+ them manually from the Tasks panel. In Docker, scheduled jobs require the Hermes gateway daemon
51
+ to tick while you are away. If System Settings shows `Gateway not configured`,
52
+ use `docker-compose.two-container.yml`,
53
+ `docker-compose.three-container.yml`, or run `hermes gateway` separately before
54
+ relying on offline scheduled runs. See [Scheduled jobs and the gateway daemon](#scheduled-jobs-and-the-gateway-daemon) below for the full background and verification steps.
55
+
56
+ For troubleshooting, reinstall, or onboarding reproduction trials, do not mount
57
+ your real `~/.hermes` unless you intentionally want to test real state. Use an
58
+ isolated Hermes home and follow
59
+ [`docs/onboarding-agent-checklist.md`](onboarding-agent-checklist.md) instead.
60
+
61
+ > **Linux note**: run Compose as the user who owns the Hermes home. The command
62
+ > `sudo docker compose up -d` can make Compose expand `${HOME}` as `/root`, so
63
+ > the default `${HOME}/.hermes` bind mount becomes `/root/.hermes` instead of
64
+ > your user's real Hermes directory. Prefer adding your user to the `docker group`
65
+ > and running `docker compose up -d`; if you must preserve the caller environment
66
+ > for a one-off root run, use `sudo -E docker compose up -d` and verify the
67
+ > rendered mount with `docker compose config` first.
68
+
69
+ ## Scheduled jobs and the gateway daemon
70
+
71
+ **Symptom**: Cron jobs created in the Tasks panel never fire. System Settings shows the orange "Gateway not configured" pill, and the Tasks panel shows the same banner above the job list.
72
+
73
+ **Cause**: Scheduled cron ticks are not driven by the WebUI itself. The gateway daemon ticks the scheduler every 60 seconds; without one running, scheduled jobs sit idle. "Run now" / "Trigger" buttons still work because the WebUI handles those in-process.
74
+
75
+ **Fix**: Run a gateway container alongside the WebUI. The two-container compose file is the recommended path:
76
+
77
+ ```bash
78
+ cp .env.docker.example .env
79
+ docker compose -f docker-compose.two-container.yml up -d
80
+ ```
81
+
82
+ The three-container layout adds the dashboard but is otherwise the same shape. If you must stay single-container, you can run `hermes gateway` inside the container as a long-lived background process, but the compose split is sturdier.
83
+
84
+ **Verify**: Once the gateway is up, the System Settings pill should turn green and the Tasks banner disappear. From the host:
85
+
86
+ ```bash
87
+ docker compose -f docker-compose.two-container.yml exec hermes-agent hermes gateway status
88
+ ```
89
+
90
+ If the service name differs in your compose file, `docker compose -f docker-compose.two-container.yml ps` lists the running services.
91
+
92
+ Refs #2785.
93
+
94
+ ## What goes wrong (and how to fix it)
95
+
96
+ ### 1. "Permission denied" at startup
97
+
98
+ **Symptom**: Container starts but immediately crashes, logs show:
99
+ ```
100
+ PermissionError: [Errno 13] Permission denied: '/home/hermeswebui/.hermes/...'
101
+ ```
102
+
103
+ **Cause**: The container's user (UID 1000 by default) can't read your bind-mounted directory because your host files are owned by a different UID.
104
+
105
+ **Fix**: Set `UID` and `GID` in `.env` to match your host:
106
+ ```bash
107
+ echo "UID=$(id -u)" >> .env
108
+ echo "GID=$(id -g)" >> .env
109
+ docker compose down && docker compose up -d
110
+ ```
111
+
112
+ On macOS, host UIDs start at 501. On Linux, the first interactive user is usually UID 1000.
113
+
114
+ > **macOS Docker Desktop**: if UID mapping still misbehaves after the env fix, try toggling **Settings → General → File sharing implementation** between VirtioFS and gRPC-FUSE. Different implementations preserve UIDs across the host/container boundary differently.
115
+
116
+ ### 2. ".env file mode 0640 → permission denied" (#1389)
117
+
118
+ **Symptom**: You set `HERMES_HOME_MODE=0640` (or some other group-readable mode) on your host `.env` file, container starts, then errors out:
119
+ ```
120
+ [security] fixed permissions on .env (0o640 -> 0600)
121
+ failed to load .env: open .env: permission denied
122
+ ```
123
+
124
+ **Cause**: WebUI's `fix_credential_permissions()` startup hook enforces 0600 by default. This is the right thing for a clean install but conflicts with operator-set modes.
125
+
126
+ **Fix**: Set one of these env vars in your `.env`:
127
+ - `HERMES_SKIP_CHMOD=1` — bypass the fixer entirely
128
+ - `HERMES_HOME_MODE=0640` — allow group bits, only strip world-readable
129
+
130
+ Both are documented in `api/startup.py::fix_credential_permissions()`.
131
+
132
+ > ⚠️ **Multi-container warning**: `HERMES_HOME_MODE` has DIFFERENT semantics in the agent image vs. the WebUI:
133
+ > - **WebUI**: credential FILE mode threshold (`0640` allows group bits on `.env`)
134
+ > - **Agent**: `HERMES_HOME` *directory* mode (default `0700`)
135
+ >
136
+ > `0640` on a directory has no owner-execute bit, so the agent can't traverse its own home → bricked. For multi-container setups, use `HERMES_HOME_MODE=0750` (group-traversable) or `0701` (x-only). The compose files have per-service comments that match each side's semantics.
137
+
138
+ ### 3. "Workspace appears empty even though my files are there"
139
+
140
+ **Symptom**: WebUI loads but `/workspace` shows no files.
141
+
142
+ **Cause**: Same as #1 — UID mismatch on the bind mount.
143
+
144
+ **Fix**: Same as #1 — match host UID/GID via `.env`.
145
+
146
+ ### 4. "Two-container setup: WebUI can't find agent source" (#858)
147
+
148
+ **Symptom**: WebUI logs at startup:
149
+ ```
150
+ !! WARNING: hermes-agent source not found.
151
+ !! Looked in: /home/hermeswebui/.hermes/hermes-agent
152
+ !! /opt/hermes
153
+ ```
154
+
155
+ **Cause**: The agent's source (`/opt/hermes` inside the agent container) needs to be exposed to the WebUI container via a shared volume. The two-container compose file does this via `hermes-agent-src` named volume, but if you're using bind mounts incorrectly the path won't resolve.
156
+
157
+ **Fix**: Use the named volumes that ship with `docker-compose.two-container.yml` — don't replace them with bind mounts unless you know what you're doing. The agent container writes its source to `/opt/hermes`, and the WebUI mounts that volume at `/home/hermeswebui/.hermes/hermes-agent`.
158
+
159
+ If you must use a bind mount: pick a host path, then mount it to `/opt/hermes` in the agent container AND `/home/hermeswebui/.hermes/hermes-agent` in the WebUI container.
160
+
161
+ ### 5. "Tools (git, node, etc.) missing in two-container setup" (#681)
162
+
163
+ **Symptom**: You ask the agent to run `git status` in chat and it errors with `command not found`.
164
+
165
+ **Cause**: This is **architectural, not a bug**. In the two-container setup, agent processes started by the WebUI run **inside the WebUI container**, not the agent container. The WebUI image doesn't include git/node by design (it's a UI image, not a tool host).
166
+
167
+ **Workarounds**:
168
+ - **Single-container setup** (`docker-compose.yml`) — everything in one container, no boundary
169
+ - **Custom WebUI image** — extend the `Dockerfile` to install the tools you need
170
+ - **Combined image** ([sunnysktsang/hermes-suite](https://github.com/sunnysktsang/hermes-suite)) — community fork that ships agent+webui+dashboard in one container
171
+
172
+ ### 6. "config.yaml not loaded"
173
+
174
+ **Symptom**: You have a `config.yaml` in your host `~/.hermes/`, but the WebUI shows "no model configured" or doesn't pick up your custom providers.
175
+
176
+ **Cause**: Either the file isn't readable (UID/GID issue, see #1) or it's not in the expected path inside the container.
177
+
178
+ **Fix**:
179
+ - Verify: `docker exec hermes-webui ls -la /home/hermeswebui/.hermes/config.yaml`
180
+ - If it doesn't exist: your host bind mount is pointing at the wrong directory.
181
+ - If it exists but is unreadable: see #1 for the UID/GID fix.
182
+
183
+ ### 7. "On Podman: can't share .hermes between containers"
184
+
185
+ **Symptom**: Two-container setup works on Docker but fails on Podman with permission errors no matter what UID/GID you set.
186
+
187
+ **Cause**: Podman 3.4 (Ubuntu 22.04 default) has limited support for `userns_mode: keep-id` across multiple containers — files written by one container appear with a different UID in the other.
188
+
189
+ **Fix**: Either upgrade to Podman 4+ (which fixes this), or use the [single-container setup](#5-minute-quickstart-single-container), or use the [community all-in-one image](https://github.com/sunnysktsang/hermes-suite).
190
+
191
+ ### 8. "API base URL set to localhost fails from Docker" (#3012)
192
+
193
+ **Symptom**: A provider, local model server, webhook, or custom API works on the host at `http://localhost:<port>`, but fails when the same URL is configured in Hermes WebUI running in Docker.
194
+
195
+ **Cause**: Inside a container, `localhost` means *that container*, not your laptop/host. The WebUI process cannot reach host services through `127.0.0.1` unless the service is running inside the same container.
196
+
197
+ **Fix**: Point Docker-hosted WebUI at the host gateway name instead:
198
+
199
+ - Docker Desktop on macOS/Windows: `http://host.docker.internal:<port>`
200
+ - Podman: `http://host.containers.internal:<port>`
201
+ - Linux Docker Engine: either publish the host service on the Docker bridge address, or add a host-gateway alias to your compose service:
202
+
203
+ ```yaml
204
+ services:
205
+ hermes-webui:
206
+ extra_hosts:
207
+ - "host.docker.internal:host-gateway"
208
+ ```
209
+
210
+ Then configure the URL as `http://host.docker.internal:<port>`. Also ensure the host service binds to an address reachable from containers (not only a loopback interface the Docker bridge cannot reach) and that your host firewall allows the connection.
211
+
212
+ ## Multi-container architecture
213
+
214
+ The two- and three-container setups use **named Docker volumes** (not bind mounts) by default for a reason: named volumes solve the UID/GID problem by construction. Docker creates the volume's root directory with the correct ownership, all containers reading/writing to it see the same files, no host-side permission setup required.
215
+
216
+ ```
217
+ ┌─────────────────────────────────┐
218
+ │ hermes-home (volume) │
219
+ │ (config, sessions, state, ...) │
220
+ └─────────────────────────────────┘
221
+ ↑ ↑
222
+ │ rw │ rw
223
+ │ │
224
+ ┌──────────────┐ │ │ ┌──────────────┐
225
+ │ hermes-agent │────┘ └────│ hermes-webui │
226
+ │ (port 8642) │ │ (port 8787) │
227
+ └──────────────┘ └──────────────┘
228
+ │ ↑
229
+ │ rw │ ro
230
+ ↓ │
231
+ ┌─────────────────────────┐ │
232
+ │ hermes-agent-src (vol) │─────────────────────┘
233
+ │ (agent's Python source) │
234
+ └─────────────────────────┘
235
+ ```
236
+
237
+ The WebUI container doesn't ship with the agent's Python deps — at startup it runs `uv pip install /home/hermeswebui/.hermes/hermes-agent` to install them from the shared volume. The WebUI mount is read-only; the agent container is the only writer.
238
+
239
+ ## Upgrading the agent container
240
+
241
+ The `hermes-agent-src` named volume is initialised from the agent image's `/opt/hermes` on first `up`. Docker reuses the volume verbatim on every subsequent `up` — **even after `docker pull` of a newer agent image**. The cached volume content masks the new image's source tree, so a fresh `docker pull` of `nousresearch/hermes-agent:latest` does not by itself give you the new agent code, dependencies, or entrypoint.
242
+
243
+ This is the root cause of [#1416](https://github.com/nesquena/hermes-webui/issues/1416): the symptom looked like a missing entrypoint, but the entrypoint was actually present in the new image and hidden behind the stale named volume.
244
+
245
+ To upgrade the agent image cleanly, drop the source volume before recreating:
246
+
247
+ ```bash
248
+ # Two-container setup
249
+ docker compose -f docker-compose.two-container.yml down
250
+ docker volume rm <project>_hermes-agent-src
251
+ docker compose -f docker-compose.two-container.yml pull
252
+ docker compose -f docker-compose.two-container.yml up -d
253
+
254
+ # Three-container setup
255
+ docker compose -f docker-compose.three-container.yml down
256
+ docker volume rm <project>_hermes-agent-src
257
+ docker compose -f docker-compose.three-container.yml pull
258
+ docker compose -f docker-compose.three-container.yml up -d
259
+ ```
260
+
261
+ Replace `<project>` with your Compose project name (the parent directory by default; check with `docker volume ls`). The `hermes-home` volume (config, sessions, state) is left untouched — only `hermes-agent-src` (the agent's installed Python source) is recreated.
262
+
263
+ > The single-container setup (`docker-compose.yml`) does not use `hermes-agent-src` and is not affected by this upgrade pattern — pulling a newer WebUI image and `docker compose up -d --force-recreate` is sufficient.
264
+
265
+ ## What the multi-container setup isolates (and what it doesn't)
266
+
267
+ The two- and three-container setups give you **process, network, and resource isolation** between the gateway and the chat UI:
268
+
269
+ - Each service has its own PID namespace and lifecycle — the agent process can crash without taking down the chat UI and vice versa.
270
+ - The gateway API (port 8642) is bound by the agent service only; the WebUI cannot bind it. Other containers reach the gateway via the `hermes-net` Docker network.
271
+ - Resource limits (`deploy.resources.limits` in `docker-compose.three-container.yml`) apply per service, so you can cap the agent independently of the dashboard.
272
+ - Restart policies, log streams, and container health checks are scoped per service.
273
+
274
+ What multi-container does **not** isolate:
275
+
276
+ - **Filesystem boundary.** Both services share `hermes-home` (config, sessions, state), and the WebUI mounts the agent's installed source from `hermes-agent-src`. The WebUI mount is read-only (since v0.51.84), but the agent service still has write access, and both services share the home volume.
277
+ - **UID/GID boundary.** Both services default to `${UID:-1000}` so files written by one are readable by the other. If you align them to different UIDs you'll get permission errors on the shared volume.
278
+ - **Trust boundary on the agent source.** The WebUI installs Python dependencies from the shared `hermes-agent-src` volume at startup. The read-only mount means a compromised WebUI cannot rewrite the agent source, but it does run code from that volume.
279
+
280
+ If you need **filesystem isolation** between the chat UI and the agent (e.g. you don't trust the WebUI to read agent state), the multi-container setup is not enough — run the agent on a separate host and connect the WebUI to it via the gateway HTTP API. If you don't need any boundary, the single-container setup is simpler.
281
+
282
+ The direct source mount is a compatibility bridge, not the long-term API contract. The current source/API boundary inventory and decoupling task list live in [`docs/rfcs/agent-source-boundary.md`](rfcs/agent-source-boundary.md) for [#2453](https://github.com/nesquena/hermes-webui/issues/2453). If you customize the compose files with bind mounts, keep the WebUI-side agent source mount read-only unless you are intentionally doing local development; `docker_init.bash` warns at startup when that path is writable.
283
+
284
+ ## Bind-mount migration (advanced)
285
+
286
+ If you really need to bind-mount an existing host `~/.hermes` (e.g. you're keeping config in dotfiles, sharing with a non-Docker `hermes` install, etc.):
287
+
288
+ ```yaml
289
+ volumes:
290
+ hermes-home:
291
+ driver: local
292
+ driver_opts:
293
+ type: none
294
+ o: bind
295
+ device: /home/youruser/.hermes
296
+ hermes-agent-src:
297
+ driver: local
298
+ driver_opts:
299
+ type: none
300
+ o: bind
301
+ device: /opt/hermes-agent-source
302
+ ```
303
+
304
+ **Critical requirements**:
305
+
306
+ 1. The host directory MUST be readable by your container UID. Run `id -u` on the host and ensure `~/.hermes` is owned by that UID (or readable via group bits).
307
+ 2. ALL containers sharing the volume must run as the SAME UID/GID. Set `UID=$(id -u)` and `GID=$(id -g)` in `.env`.
308
+ 3. If you run Compose with sudo, do not rely on `${HOME}` defaults: `sudo` often changes `$HOME` to `/root`, so `${HERMES_HOME:-${HOME}/.hermes}` becomes `/root/.hermes`. Prefer running Docker as your user; otherwise pass absolute paths with `sudo -E`, for example `HERMES_HOME=/home/youruser/.hermes HERMES_WORKSPACE=/home/youruser/workspace sudo -E docker compose up -d`, and confirm the rendered bind mount with `docker compose config`.
309
+ 4. If your host `.env` is mode 0640, set `HERMES_SKIP_CHMOD=1` or `HERMES_HOME_MODE=0640` so the startup hook doesn't try to enforce 0600.
310
+
311
+ ## Reference
312
+
313
+ - [`docker-compose.yml`](../docker-compose.yml) — single container (recommended)
314
+ - [`docker-compose.two-container.yml`](../docker-compose.two-container.yml) — agent + webui
315
+ - [`docker-compose.three-container.yml`](../docker-compose.three-container.yml) — agent + dashboard + webui
316
+ - [`.env.docker.example`](../.env.docker.example) — environment variable template
317
+ - [`Dockerfile`](../Dockerfile) — single-container build
318
+ - [`docker_init.bash`](../docker_init.bash) — container entrypoint script
319
+
320
+ ## Related issues
321
+
322
+ - #1416 — agent-image upgrade requires removing `hermes-agent-src` named volume (see [Upgrading the agent container](#upgrading-the-agent-container))
323
+ - #1389 — `HERMES_HOME_MODE` override (fixed in v0.50.254 — agent honors `HERMES_SKIP_CHMOD` and `HERMES_HOME_MODE`)
324
+ - #1399 — UID alignment in compose files (fixed in v0.50.260 via PR #1428 + this guide)
325
+ - #3012 — host `localhost` API URLs fail from Docker containers (use `host.docker.internal` / `host.containers.internal`)
326
+ - #3006 — `sudo docker compose` can mount `/root/.hermes` instead of the user's Hermes home
327
+ - #858 — two-container `/opt/hermes` path confusion
328
+ - #681 — tools running in WebUI container, not agent container (architectural)
329
+ - #668 — auto-detect UID/GID from mounted volume
330
+ - #569 — UID/GID detection priority order
331
+
332
+ If you hit a new failure mode not covered here, please [open an issue](https://github.com/nesquena/hermes-webui/issues/new) with:
333
+
334
+ 1. Which compose file you used
335
+ 2. The error from `docker logs hermes-webui`
336
+ 3. `docker exec hermes-webui id` output
337
+ 4. `docker exec hermes-webui ls -la /home/hermeswebui/.hermes` output
@@ -0,0 +1,207 @@
1
+ # Agent-assisted onboarding checklist
2
+
3
+ This checklist is for an AI assistant helping a human install, reinstall, or
4
+ debug Hermes WebUI onboarding. It does not replace the human first-run wizard.
5
+ Use it before running bootstrap commands, inspecting logs, or recommending a
6
+ cleanup path.
7
+
8
+ If you are an AI assistant, read this file before assisting with onboarding,
9
+ bootstrap, provider setup, reinstall, or first-run support.
10
+
11
+ ## Role split
12
+
13
+ The human operator owns:
14
+
15
+ - choosing the install path
16
+ - choosing the provider and model
17
+ - entering API keys, OAuth codes, and passwords
18
+ - approving any cleanup of a real Hermes home
19
+ - approving any external exposure outside localhost
20
+
21
+ The assistant owns:
22
+
23
+ - using isolated trial directories unless the human explicitly says otherwise
24
+ - checking non-secret status endpoints and logs
25
+ - explaining which step passed or failed
26
+ - collecting redacted evidence for Discord or GitHub support
27
+ - stopping before destructive cleanup, credential handling, or public exposure
28
+
29
+ ## Hard safety rules
30
+
31
+ - Do not delete, move, or overwrite the real `~/.hermes` directory unless the
32
+ human explicitly asks for that exact action.
33
+ - Do not print API keys, OAuth tokens, cookies, full `.env` files, full
34
+ `auth.json` files, or password hashes.
35
+ - Do not modify real cron jobs, real sessions, real profiles, or real memory
36
+ files during an onboarding trial.
37
+ - Do not expose WebUI on a public interface without password protection and
38
+ explicit human approval.
39
+ - Do not proxy or tunnel local service checks such as `localhost`,
40
+ `127.0.0.1`, private LAN addresses, or Docker container loopback paths.
41
+
42
+ ## Pre-flight
43
+
44
+ Confirm the basic context:
45
+
46
+ ```bash
47
+ pwd
48
+ git branch --show-current
49
+ git rev-parse --short HEAD
50
+ python3 --version
51
+ ```
52
+
53
+ Check whether repo-local environment overrides will affect bootstrap:
54
+
55
+ ```bash
56
+ test -f .env && grep -n 'HERMES_HOME\|HERMES_WEBUI_STATE_DIR\|HERMES_WEBUI_PORT\|HERMES_WEBUI_HOST' .env
57
+ ```
58
+
59
+ If `.env` exists, do not print the full file. Inspect only the specific
60
+ non-secret keys needed to understand the active Hermes home, WebUI state
61
+ directory, port, or host.
62
+
63
+ ## Isolated local trial
64
+
65
+ Use an isolated Hermes home and WebUI state directory for a reinstall or support
66
+ trial. This keeps the test away from the operator's real memory, sessions,
67
+ profiles, credentials, and cron state.
68
+
69
+ ```bash
70
+ mkdir -p ~/hermes-onboarding-test
71
+ HERMES_HOME=~/hermes-onboarding-test/.hermes \
72
+ HERMES_WEBUI_STATE_DIR=~/hermes-onboarding-test/webui \
73
+ HERMES_WEBUI_PORT=8789 \
74
+ python3 bootstrap.py
75
+ ```
76
+
77
+ Open:
78
+
79
+ ```text
80
+ http://127.0.0.1:8789
81
+ ```
82
+
83
+ The bootstrap writes a port-specific log under the selected WebUI state
84
+ directory:
85
+
86
+ ```text
87
+ ~/hermes-onboarding-test/webui/bootstrap-8789.log
88
+ ```
89
+
90
+ For daemon-style installs, `ctl.sh` writes the daemon log to the active
91
+ `HERMES_HOME` by default:
92
+
93
+ ```text
94
+ ~/.hermes/webui.log
95
+ ```
96
+
97
+ When using the isolated trial environment, prefer the bootstrap command above
98
+ unless the human specifically wants to validate `ctl.sh`.
99
+
100
+ ## Non-secret evidence commands
101
+
102
+ After the server starts, collect status without secrets:
103
+
104
+ ```bash
105
+ curl -sS http://127.0.0.1:8789/health
106
+ curl -sS http://127.0.0.1:8789/api/onboarding/status
107
+ find ~/hermes-onboarding-test -maxdepth 3 -type f | sort
108
+ tail -n 120 ~/hermes-onboarding-test/webui/bootstrap-8789.log
109
+ ```
110
+
111
+ When summarizing `/api/onboarding/status`, focus on:
112
+
113
+ - `completed`
114
+ - `system.hermes_found`
115
+ - `system.imports_ok`
116
+ - `system.config_path`
117
+ - `system.config_exists`
118
+ - `system.setup_state`
119
+ - `system.provider_configured`
120
+ - `system.provider_ready`
121
+ - `system.chat_ready`
122
+ - `system.current_provider`
123
+ - `system.current_model`
124
+ - `system.current_base_url`
125
+ - `system.env_path`
126
+
127
+ Do not paste the full payload if it contains unexpected sensitive local paths
128
+ or values. Redact paths and provider details when the human asks for a public
129
+ GitHub or Discord support report.
130
+
131
+ ## Pass criteria
132
+
133
+ A local onboarding trial passes when:
134
+
135
+ - `/health` returns successfully.
136
+ - `/api/onboarding/status` returns JSON.
137
+ - The wizard appears when `completed` is false.
138
+ - The wizard stays out of the way when `completed` is true or
139
+ `HERMES_WEBUI_SKIP_ONBOARDING=1` is intentionally set.
140
+ - `system.hermes_found` and `system.imports_ok` match the expected bootstrap
141
+ state.
142
+ - `system.provider_ready` and `system.chat_ready` become true after the human
143
+ completes a provider path that should support chat.
144
+ - `system.config_path` and `system.env_path` point inside the intended isolated
145
+ `HERMES_HOME` during a trial.
146
+ - WebUI files are written under the intended `HERMES_WEBUI_STATE_DIR`.
147
+
148
+ If the human chooses a provider that must be completed in the CLI, passing can
149
+ mean the wizard correctly points them to `hermes model` or `hermes auth` rather
150
+ than trying to collect unsupported credentials in the browser.
151
+
152
+ ## Failure triage
153
+
154
+ If the server does not start:
155
+
156
+ - check the bootstrap log
157
+ - check for a port conflict on `8789`
158
+ - confirm Python can run `bootstrap.py`
159
+ - confirm `.env` is not overriding the isolated directories or port
160
+
161
+ If onboarding reports `agent_unavailable`:
162
+
163
+ - confirm the bootstrap found or installed Hermes Agent
164
+ - check whether the running Python can import `run_agent.AIAgent`
165
+ - use `docs/troubleshooting.md`, especially the `AIAgent not available` flow
166
+
167
+ If onboarding reports `provider_incomplete`:
168
+
169
+ - confirm whether the provider is API-key based, OAuth based, or local
170
+ - let the human enter credentials or run the CLI auth flow
171
+ - do not ask the human to paste secrets into chat
172
+
173
+ If a local model server does not probe successfully:
174
+
175
+ - from native macOS/Linux, use `http://127.0.0.1:<port>/v1` when the server is
176
+ on the same host
177
+ - from Docker Desktop, use `http://host.docker.internal:<port>/v1`
178
+ - from another LAN machine, use the server's LAN IP and `/v1`
179
+ - remember that `localhost` inside a container is the container itself
180
+
181
+ If password or reverse-proxy behavior is confusing:
182
+
183
+ - keep the first pass on `127.0.0.1`
184
+ - require password protection before exposing WebUI beyond localhost
185
+ - include the reverse proxy shape in the support report without pasting tokens
186
+ or cookies
187
+
188
+ ## Final support report
189
+
190
+ Use this shape when reporting results to the human, Discord, or GitHub:
191
+
192
+ ```text
193
+ Install path:
194
+ OS / Python:
195
+ Repo commit:
196
+ Command used:
197
+ WebUI URL:
198
+ State isolation:
199
+ Health result:
200
+ Onboarding status summary:
201
+ Files created or changed:
202
+ Log excerpt:
203
+ Pass/fail:
204
+ Next recommended action:
205
+ ```
206
+
207
+ Redact secrets and private paths before posting publicly.