fix: support CLI sessions in /api/list file browser (#204)

* feat: optional HTTPS/TLS support via cert and key env vars

Add optional HTTPS support controlled by two env vars:
  HERMES_WEBUI_TLS_CERT=/path/to/cert.pem
  HERMES_WEBUI_TLS_KEY=/path/to/key.pem

- Wraps server socket with ssl.SSLContext (min TLSv1.2)
- Dynamic scheme detection for startup messages (http:// vs https://)
- Graceful fallback to HTTP if cert loading fails — server never crashes
  due to bad TLS config, just prints a warning and continues
- Auth cookie Secure flag already set when HTTPS is detected via getpeercert
- 6 end-to-end tests: config flags, HTTPS handshake, HTTP still works,
  fallback on bad paths

Addresses #191 (HTTPS support issue).

* fix: use current branch upstream for update checks, not repo default branch

The update checker in api/updates.py always compared HEAD against
origin/master (or origin/main), which produced false 'N updates
available' alerts when the user is on a feature branch and master has
moved forward with unrelated commits.

Now uses git rev-parse --abbrev-ref @{upstream} to get the current
branch's tracking branch for both the behind-count check and the
apply-update pull command. Falls back to the default branch if no
upstream is set (brand-new local branch with no tracking config).

Fixes #200.

* fix: support CLI sessions in /api/list file browser

_handle_list_dir() only checked WebUI in-memory sessions, returning
'Session not found' for CLI sessions imported from the agent's state.db.
Now falls back to get_cli_sessions() to find the workspace path for
CLI sessions that aren't loaded in WebUI memory.

Fixes: workspace pane showing empty for CLI sessions.
This commit is contained in:
Cyprian Kowalczyk
2026-04-09 21:18:38 -04:00
committed by GitHub
parent f90be60e31
commit be92e59bdb

View File

@@ -862,11 +862,25 @@ def _handle_list_dir(handler, parsed):
qs = parse_qs(parsed.query)
sid = qs.get('session_id', [''])[0]
if not sid: return bad(handler, 'session_id is required')
try: s = get_session(sid)
except KeyError: return bad(handler, 'Session not found', 404)
try:
s = get_session(sid)
workspace = s.workspace
except KeyError:
# Fallback for CLI sessions not loaded in WebUI memory
try:
cli_meta = None
for cs in get_cli_sessions():
if cs['session_id'] == sid:
cli_meta = cs
break
if not cli_meta:
return bad(handler, 'Session not found', 404)
workspace = cli_meta.get('workspace', '')
except Exception:
return bad(handler, 'Session not found', 404)
try:
return j(handler, {
'entries': list_dir(Path(s.workspace), qs.get('path', ['.'])[0]),
'entries': list_dir(Path(workspace), qs.get('path', ['.'])[0]),
'path': qs.get('path', ['.'])[0],
})
except (FileNotFoundError, ValueError) as e: