@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,210 @@
1
+ <#
2
+ .SYNOPSIS
3
+ Native Windows launcher for Hermes WebUI - PowerShell equivalent
4
+ of start.sh, bypassing bootstrap.py's platform refusal.
5
+
6
+ .DESCRIPTION
7
+ Mirrors start.sh's discovery: load optional .env, find Python,
8
+ locate the hermes-agent install, set sensible env defaults, then
9
+ invoke server.py directly. The bootstrap.py path is skipped
10
+ because it currently raises on platform.system() == 'Windows';
11
+ server.py itself runs cleanly on native Windows.
12
+
13
+ Assumes Python + hermes-agent + the WebUI Python deps are already
14
+ installed natively on Windows - same assumption start.sh makes
15
+ when invoked outside a fresh bootstrap. For first-time setup, the
16
+ native Windows path is to install Python 3.11+, then create a
17
+ Windows venv (`python -m venv venv`) and `pip install -r
18
+ requirements.txt` from the hermes-agent root in PowerShell - this
19
+ script then finds `venv\Scripts\python.exe` automatically. A venv
20
+ created inside WSL2 is a Linux virtual environment (`venv/bin/python`)
21
+ and cannot be used by native Windows Python, so the bootstrap.py-
22
+ inside-WSL2 path produces a venv `start.ps1` can't invoke.
23
+
24
+ .PARAMETER Port
25
+ TCP port the WebUI binds to. Overrides HERMES_WEBUI_PORT env.
26
+ Default: 8787.
27
+
28
+ .PARAMETER BindHost
29
+ Bind address. Overrides HERMES_WEBUI_HOST env.
30
+ Default: 127.0.0.1.
31
+
32
+ .EXAMPLE
33
+ .\start.ps1
34
+ # Bind to 127.0.0.1:8787, foreground.
35
+
36
+ .EXAMPLE
37
+ .\start.ps1 -Port 9000
38
+ # Bind to 127.0.0.1:9000.
39
+
40
+ .EXAMPLE
41
+ $env:HERMES_WEBUI_HOST = '0.0.0.0'
42
+ .\start.ps1
43
+ # Bind to all interfaces (set a password first via env or Settings).
44
+
45
+ .LINK
46
+ https://github.com/nesquena/hermes-webui/issues/1952
47
+ #>
48
+
49
+ [CmdletBinding()]
50
+ param(
51
+ [int]$Port = 0,
52
+ [string]$BindHost = ''
53
+ )
54
+
55
+ $ErrorActionPreference = 'Stop'
56
+ $RepoRoot = Split-Path -Parent $PSCommandPath
57
+
58
+ # === Load .env (mirroring start.sh's filtering) ========================
59
+ $envFile = Join-Path $RepoRoot '.env'
60
+ if (Test-Path $envFile) {
61
+ foreach ($line in Get-Content $envFile -Encoding UTF8) {
62
+ $trimmed = $line.Trim()
63
+ if (-not $trimmed -or $trimmed.StartsWith('#') -or -not $trimmed.Contains('=')) { continue }
64
+ $kv = $trimmed -split '=', 2
65
+ $key = ($kv[0].Trim() -replace '^export\s+', '')
66
+ # Filter out shell-readonly vars (UID, GID, EUID, EGID, PPID) per start.sh
67
+ if ($key -in @('UID', 'GID', 'EUID', 'EGID', 'PPID')) { continue }
68
+ if ($key -notmatch '^[A-Za-z_][A-Za-z0-9_]*$') { continue }
69
+ # Explicit $null check — an env var explicitly set to '' should still
70
+ # be considered "set" and NOT overridden by .env (empty string is
71
+ # falsey in PowerShell, so a plain truthy check would mis-skip).
72
+ if ($null -ne [Environment]::GetEnvironmentVariable($key)) { continue }
73
+ $val = $kv[1]
74
+ if ($val -match '^"(.*)"$') { $val = $Matches[1] }
75
+ elseif ($val -match "^'(.*)'$") { $val = $Matches[1] }
76
+ [Environment]::SetEnvironmentVariable($key, $val)
77
+ }
78
+ }
79
+
80
+ # === Find Python (matches start.sh order) ==============================
81
+ $Python = $env:HERMES_WEBUI_PYTHON
82
+ if (-not $Python) {
83
+ foreach ($candidate in @('python3', 'python', 'py')) {
84
+ $cmd = Get-Command $candidate -ErrorAction SilentlyContinue
85
+ if ($cmd) { $Python = $cmd.Source; break }
86
+ }
87
+ }
88
+ if (-not $Python) {
89
+ Write-Error 'Python 3 is required to run server.py (set HERMES_WEBUI_PYTHON or add python to PATH).'
90
+ exit 1
91
+ }
92
+
93
+ # === Find Hermes Agent dir (server.py imports from it) =================
94
+ # When HERMES_WEBUI_AGENT_DIR is set we still validate it on disk —
95
+ # an explicit override pointing at a missing dir should fail FAST
96
+ # with a clear message, not silently progress into a python3 launch
97
+ # that's about to crash on missing imports. Smoke-test feedback on
98
+ # PR #2783: nesquena/hermes-webui requested this guard.
99
+ $AgentDir = $env:HERMES_WEBUI_AGENT_DIR
100
+ if ($AgentDir -and -not (Test-Path (Join-Path $AgentDir 'hermes_cli') -PathType Container)) {
101
+ Write-Error "HERMES_WEBUI_AGENT_DIR is set to '$AgentDir' but no hermes_cli/ folder exists there. Unset the variable to fall back to auto-discovery, or fix the path."
102
+ exit 1
103
+ }
104
+ if (-not $AgentDir) {
105
+ # Build candidate list incrementally — ${env:ProgramFiles(x86)} is null on
106
+ # 32-bit Windows and in some constrained environments, and Join-Path throws
107
+ # on a null Path. Skip any system-wide root that isn't set so the launcher
108
+ # stays robust across Windows variants. USERPROFILE is always set so it
109
+ # stays unguarded; the dev-checkout sibling is path-derived, not env-based.
110
+ $candidates = @()
111
+ $candidates += (Join-Path $env:USERPROFILE '.hermes\hermes-agent')
112
+ foreach ($root in @($env:LOCALAPPDATA, ${env:ProgramW6432}, ${env:ProgramFiles}, ${env:ProgramFiles(x86)})) {
113
+ if ($root) { $candidates += (Join-Path $root 'hermes\hermes-agent') }
114
+ }
115
+ $candidates += (Join-Path (Split-Path -Parent $RepoRoot) 'hermes-agent')
116
+ # De-dup: when running in a WOW64 (32-bit-on-64-bit) PowerShell process,
117
+ # $env:ProgramFiles is redirected to C:\Program Files (x86), so without
118
+ # $env:ProgramW6432 (the canonical 64-bit override) we'd miss the real
119
+ # C:\Program Files\hermes\hermes-agent AND duplicate the x86 entry.
120
+ # Select-Object -Unique collapses any collisions regardless of cause.
121
+ $candidates = $candidates | Select-Object -Unique
122
+ foreach ($c in $candidates) {
123
+ if (Test-Path (Join-Path $c 'hermes_cli') -PathType Container) { $AgentDir = $c; break }
124
+ }
125
+ }
126
+ if (-not $AgentDir) {
127
+ $searched = $candidates -join ', '
128
+ Write-Error "hermes-agent not found. Searched: $searched. Set HERMES_WEBUI_AGENT_DIR explicitly to override."
129
+ exit 1
130
+ }
131
+
132
+ # === Prefer the agent's venv Python if available =======================
133
+ $agentVenvPython = Join-Path $AgentDir 'venv\Scripts\python.exe'
134
+ if (Test-Path $agentVenvPython) {
135
+ $Python = $agentVenvPython
136
+ }
137
+
138
+ # === Resolve bind + state defaults =====================================
139
+ $BindHostFinal = if ($BindHost) { $BindHost } elseif ($env:HERMES_WEBUI_HOST) { $env:HERMES_WEBUI_HOST } else { '127.0.0.1' }
140
+ $PortFinal = if ($Port) {
141
+ $Port
142
+ } elseif ($env:HERMES_WEBUI_PORT) {
143
+ # TryParse + range guard on the env var. A plain [int] cast on the
144
+ # env var throws InvalidCastException with no actionable context when
145
+ # the env var is set to a non-integer (typo, accidental shell
146
+ # expansion, etc.) — surface a targeted error message instead.
147
+ $parsedPort = 0
148
+ if (-not [int]::TryParse($env:HERMES_WEBUI_PORT, [ref]$parsedPort)) {
149
+ Write-Error "HERMES_WEBUI_PORT='$($env:HERMES_WEBUI_PORT)' is not a valid integer port. Unset the variable to use the default (8787), or set it to a number 1-65535."
150
+ exit 1
151
+ }
152
+ if ($parsedPort -lt 1 -or $parsedPort -gt 65535) {
153
+ Write-Error "HERMES_WEBUI_PORT=$parsedPort is out of TCP-port range. Must be 1-65535."
154
+ exit 1
155
+ }
156
+ $parsedPort
157
+ } else {
158
+ 8787
159
+ }
160
+ $env:HERMES_WEBUI_HOST = $BindHostFinal
161
+ $env:HERMES_WEBUI_PORT = "$PortFinal"
162
+ if (-not $env:HERMES_HOME) {
163
+ if ($env:LOCALAPPDATA) {
164
+ $env:HERMES_HOME = Join-Path $env:LOCALAPPDATA 'hermes'
165
+ } else {
166
+ $env:HERMES_HOME = Join-Path $env:USERPROFILE '.hermes'
167
+ }
168
+ }
169
+ if (-not $env:HERMES_WEBUI_STATE_DIR) {
170
+ $env:HERMES_WEBUI_STATE_DIR = Join-Path $env:HERMES_HOME 'webui'
171
+ }
172
+
173
+ # === Ensure dirs exist =================================================
174
+ New-Item -ItemType Directory -Force -Path $env:HERMES_HOME | Out-Null
175
+ New-Item -ItemType Directory -Force -Path $env:HERMES_WEBUI_STATE_DIR | Out-Null
176
+
177
+ # === Launch (foreground, matches start.sh) =============================
178
+ Write-Host "[start.ps1] Hermes WebUI native Windows launcher" -ForegroundColor Cyan
179
+ Write-Host "[start.ps1] Python: $Python"
180
+ Write-Host "[start.ps1] Agent dir: $AgentDir"
181
+ Write-Host "[start.ps1] State dir: $env:HERMES_WEBUI_STATE_DIR"
182
+ Write-Host "[start.ps1] Binding: ${BindHostFinal}:${PortFinal}"
183
+ Write-Host ""
184
+
185
+ $serverPath = Join-Path $RepoRoot 'server.py'
186
+ if (-not (Test-Path $serverPath)) {
187
+ Write-Error "server.py not found at $serverPath - is this the hermes-webui repo root?"
188
+ exit 1
189
+ }
190
+
191
+ # Capture exit code, let finally{} run Pop-Location, exit AFTER the try.
192
+ # Plain `exit $LASTEXITCODE` inside the try block can prevent the finally
193
+ # from running in some termination paths (especially when dot-sourced or
194
+ # in interactive sessions), leaving the caller's working directory stuck
195
+ # at $RepoRoot.
196
+ $script:serverExitCode = 0
197
+ Push-Location $RepoRoot
198
+ try {
199
+ # @args was non-functional here — PowerShell does NOT populate $args when the
200
+ # script declares [CmdletBinding()] with an explicit param() block (Copilot's
201
+ # finding on PR #2807). Dropped rather than added a ValueFromRemainingArguments
202
+ # parameter, because the existing tracked use case is the launcher running
203
+ # server.py with the env-var-driven config — no pass-through args are needed.
204
+ # If pass-through becomes a requirement later, add a [Parameter(ValueFromRemainingArguments=$true)] [string[]]$ServerArgs and splat that.
205
+ & $Python $serverPath
206
+ $script:serverExitCode = $LASTEXITCODE
207
+ } finally {
208
+ Pop-Location
209
+ }
210
+ exit $script:serverExitCode
@@ -0,0 +1,65 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+
4
+ # If invoked as root (e.g. via `sudo ./start.sh` or accidental root shell
5
+ # inside the container), re-exec as the unprivileged hermeswebui user so the
6
+ # WebUI process never owns root-only file modes on bind-mounted state.
7
+ # Outside containers the EUID==0 case is rare; inside the production image
8
+ # the entrypoint drops to hermeswebui itself, so this is a defensive guard.
9
+ # Sourced from PR #1686 (@binhpt310) — Cluster 1 (operational hardening),
10
+ # extracted to a focused follow-up after the parent PR was deferred over a
11
+ # separate sibling-repo build-context concern unrelated to this fix.
12
+ #
13
+ # Four preconditions to fire (all must hold):
14
+ # - EUID == 0
15
+ # - hermeswebui user actually exists (id lookup)
16
+ # - sudo is on PATH (production image does not ship sudo, so this is the
17
+ # load-bearing no-op guard for the canonical container path)
18
+ # - sudo -u hermeswebui passes without prompting (NOPASSWD precheck)
19
+ # The NOPASSWD precheck via `sudo -n -u hermeswebui true` makes this a silent
20
+ # fall-through on host machines where the developer's hermeswebui user
21
+ # requires a password — better than exiting non-zero with `sudo: a password
22
+ # is required` and surprising the user who didn't ask for sudo behavior.
23
+ if [[ ${EUID:-$(id -u)} -eq 0 ]] && id hermeswebui >/dev/null 2>&1 \
24
+ && command -v sudo >/dev/null 2>&1 \
25
+ && sudo -n -u hermeswebui true 2>/dev/null; then
26
+ exec sudo -n -u hermeswebui "$0" "$@"
27
+ fi
28
+
29
+ REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
30
+
31
+ if [[ -f "${REPO_ROOT}/.env" ]]; then
32
+ # Filter out shell-readonly vars (UID, GID, EUID, EGID, PPID) before
33
+ # `source`ing. docker-compose.yml's macOS instructions document
34
+ # `echo "UID=$(id -u)" >> .env` to set host UID/GID, which then crashes
35
+ # `start.sh` with "UID: readonly variable" when bash tries to assign to
36
+ # those names. Filtering them out lets the .env file carry those entries
37
+ # for docker-compose's variable substitution while keeping local invocation
38
+ # of start.sh working. The regression guard at
39
+ # tests/test_bootstrap_dotenv.py:181 still passes — the line below contains
40
+ # both `source` and `.env`.
41
+ # Sourced from PR #1686 (@binhpt310) — Cluster 1 (operational hardening),
42
+ # extracted to a focused follow-up after the parent PR was deferred.
43
+ _hermes_env_filtered="$(mktemp "${TMPDIR:-/tmp}/hermes-webui-env.XXXXXX")"
44
+ grep -vE '^[[:space:]]*(export[[:space:]]+)?(UID|GID|EUID|EGID|PPID)=' "${REPO_ROOT}/.env" > "${_hermes_env_filtered}" || true
45
+ set -a
46
+ # shellcheck source=/dev/null
47
+ source "${_hermes_env_filtered}"
48
+ set +a
49
+ rm -f "${_hermes_env_filtered}"
50
+ unset _hermes_env_filtered
51
+ fi
52
+
53
+ PYTHON="${HERMES_WEBUI_PYTHON:-}"
54
+ if [[ -z "${PYTHON}" ]]; then
55
+ if command -v python3 >/dev/null 2>&1; then
56
+ PYTHON="$(command -v python3)"
57
+ elif command -v python >/dev/null 2>&1; then
58
+ PYTHON="$(command -v python)"
59
+ else
60
+ echo "[XX] Python 3 is required to run bootstrap.py" >&2
61
+ exit 1
62
+ fi
63
+ fi
64
+
65
+ exec "${PYTHON}" "${REPO_ROOT}/bootstrap.py" --no-browser "$@"