`hermes dashboard` from a named profile re-execs as `-p default dashboard --open-profile P`, but `--open-profile` only reached the one URL `_maybe_open_browser()` opened. A `/chat?resume=<id>` deep link without `?profile=` initialised `ProfileProvider` with the empty (launch) scope, so the embedded chat ran in the default profile — no MCP servers, wrong model/skills — while the switcher showed P. No error, no indication. The server now records `initial_profile` on `app.state` and injects it into the SPA bootstrap as `window.__HERMES_INITIAL_PROFILE__` (escaped for the script context); the Vite dev proxy forwards it. `ProfileProvider` uses it only when the URL carries no `profile` param: an explicit `?profile=` (including an explicit empty one) still wins, and the sticky-active-profile alignment no longer replaces a launch-preselected scope. Closes #73085. Salvage of #73260 (cherry-pick of 99e341cdef0 resolved onto the split web_server_dashboard.py; start_server assertion dropped as a change-detector).
48 lines
1.5 KiB
Python
48 lines
1.5 KiB
Python
from fastapi import FastAPI
|
|
from starlette.testclient import TestClient
|
|
|
|
from hermes_cli import web_server
|
|
|
|
|
|
def test_spa_bootstrap_includes_dashboard_initial_profile(tmp_path, monkeypatch):
|
|
dist = tmp_path / "web_dist"
|
|
(dist / "assets").mkdir(parents=True)
|
|
(dist / "index.html").write_text(
|
|
"<html><head></head><body>Dashboard</body></html>",
|
|
encoding="utf-8",
|
|
)
|
|
monkeypatch.setattr(web_server, "WEB_DIST", dist)
|
|
monkeypatch.delenv("HERMES_SERVE_HEADLESS", raising=False)
|
|
|
|
app = FastAPI()
|
|
app.state.initial_profile = "worker_x"
|
|
web_server.mount_spa(app)
|
|
|
|
response = TestClient(app).get("/chat?resume=session-1")
|
|
|
|
assert response.status_code == 200
|
|
assert 'window.__HERMES_INITIAL_PROFILE__="worker_x";' in response.text
|
|
|
|
|
|
def test_spa_bootstrap_escapes_initial_profile_for_script_context(
|
|
tmp_path, monkeypatch
|
|
):
|
|
dist = tmp_path / "web_dist"
|
|
(dist / "assets").mkdir(parents=True)
|
|
(dist / "index.html").write_text(
|
|
"<html><head></head><body>Dashboard</body></html>",
|
|
encoding="utf-8",
|
|
)
|
|
monkeypatch.setattr(web_server, "WEB_DIST", dist)
|
|
monkeypatch.delenv("HERMES_SERVE_HEADLESS", raising=False)
|
|
|
|
app = FastAPI()
|
|
app.state.initial_profile = "bad</script><script>alert(1)</script>"
|
|
web_server.mount_spa(app)
|
|
|
|
response = TestClient(app).get("/chat")
|
|
|
|
assert response.status_code == 200
|
|
assert "bad<\\/script><script>alert(1)<\\/script>" in response.text
|
|
assert "bad</script><script>alert(1)</script>" not in response.text
|