`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).
32 lines
754 B
TypeScript
32 lines
754 B
TypeScript
declare global {
|
|
interface Window {
|
|
__HERMES_INITIAL_PROFILE__?: string;
|
|
}
|
|
}
|
|
|
|
export function dashboardInitialProfile(): string {
|
|
if (typeof window === "undefined") return "";
|
|
return window.__HERMES_INITIAL_PROFILE__ ?? "";
|
|
}
|
|
|
|
export function initialProfileScope(
|
|
searchParams: URLSearchParams,
|
|
bootstrapProfile = dashboardInitialProfile(),
|
|
): string {
|
|
const urlProfile = searchParams.get("profile");
|
|
return urlProfile === null ? bootstrapProfile : urlProfile;
|
|
}
|
|
|
|
export function shouldAdoptActiveProfile(
|
|
urlProfile: string | null,
|
|
bootstrapProfile: string,
|
|
currentProfile: string,
|
|
activeProfile: string,
|
|
): boolean {
|
|
return (
|
|
urlProfile === null &&
|
|
!bootstrapProfile &&
|
|
activeProfile !== currentProfile
|
|
);
|
|
}
|