From cf60ebbdfd264c3fc067b9e3230df8752c50d2ec Mon Sep 17 00:00:00 2001 From: Teknium <127238744+teknium1@users.noreply.github.com> Date: Thu, 3 Sep 2026 03:12:31 -0700 Subject: [PATCH] =?UTF-8?q?refactor(tui=5Fgateway):=20W4=20wave2=20pass=20?= =?UTF-8?q?19=20=E2=80=94=20readiness=20scope=20inlined,=20secret=20mirror?= =?UTF-8?q?ing=20unified?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tui_gateway/methods_config.py | 49 ++++++++++++++------------------- tui_gateway/methods_profiles.py | 44 ++++++++++++----------------- 2 files changed, 38 insertions(+), 55 deletions(-) diff --git a/tui_gateway/methods_config.py b/tui_gateway/methods_config.py index 57b61d15c7..f469215435 100644 --- a/tui_gateway/methods_config.py +++ b/tui_gateway/methods_config.py @@ -39,8 +39,8 @@ def _(rid, params: dict) -> dict: policy = _repo_discovery_policy() with pdb.connect_closing() as conn: _reconcile_repo_discovery(pdb, conn, policy, _repo_discovery_policy_key(policy)) - # `scan=true` (remote-gateway desktop): its native scan only sees its own - # filesystem, so the host scans the policy roots so zero-session repos surface. + # `scan=true` (remote-gateway desktop): its native scan only sees its own filesystem, + # so the host scans the policy roots so zero-session repos surface. if params.get("scan") and policy["enabled"]: _scan_discovered_repos_remote(conn, policy) repos = _discover_repos_payload(db, conn=conn, include_cached=policy["enabled"]) @@ -83,9 +83,9 @@ def _stamped_project_tree(db, params, **kwargs): @_projects_handler("projects.tree") def _(rid, params: dict) -> dict: - """Project -> repo -> lane overview with counts + a few preview sessions per project, plus - the flat set of session ids claimed by any project (excluded from flat Recents). Lanes carry - no session rows here; drill-in uses ``projects.project_sessions``.""" + """Project -> repo -> lane overview with counts + a few preview sessions per project, plus the + flat set of session ids claimed by any project (excluded from flat Recents). Lanes carry no + session rows; drill-in uses ``projects.project_sessions``.""" with _profile_db(params) as db: if db is None: return _ok(rid, {"projects": [], "active_id": None, "scoped_session_ids": []}) @@ -241,32 +241,23 @@ def _(rid, params: dict) -> dict: # ── setup readiness -def _readiness_profile_scope(params: dict): - """``(profile, scope)`` for the readiness RPCs' optional ``profile``: ``scope`` binds that - profile's HERMES_HOME + ``.env`` secret scope (ContextVars: concurrent checks stay isolated); - no param -> ``("", nullcontext())``. Unknown profile raises ``FileNotFoundError`` — never - quietly answer for the launch profile instead.""" +def _readiness_check(rid, params, probe): + """Shared shell of setup.status / setup.runtime_check. ``probe(profile, scoped)`` runs inside the + optional ``profile`` param's HERMES_HOME + ``.env`` secret scope (ContextVars: concurrent checks + stay isolated); ``scoped`` is the ``{"profile": ...}`` payload stamp (``{}`` for the launch + profile). An unknown profile answers ``ok=False`` (never a JSON-RPC error, never a quiet answer + for the launch profile instead).""" import contextlib profile = str(params.get("profile") or "").strip() if isinstance(params, dict) else "" - if not profile: - return "", contextlib.nullcontext() - from hermes_cli import profiles as profiles_mod - if not profiles_mod.profile_exists(profile): - raise FileNotFoundError(f"Profile '{profile}' does not exist on this backend.") - home = _profile_home(profile) - if home is None: - return profile, contextlib.nullcontext() - return profile, _session_profile_runtime_scope({"profile_home": str(home)}) - - -def _readiness_check(rid, params, probe): - """Shared shell of setup.status / setup.runtime_check: ``probe(profile, scoped)`` runs inside - the profile scope (``scoped`` = the ``{"profile": ...}`` payload stamp, ``{}`` for the launch - profile); an unknown profile answers ``ok=False`` (never a JSON-RPC error).""" - try: - profile, scope = _readiness_profile_scope(params) - except FileNotFoundError as e: - return _ok(rid, {"ok": False, "profile": params.get("profile"), "error": str(e)}) + scope = contextlib.nullcontext() + if profile: + from hermes_cli import profiles as profiles_mod + if not profiles_mod.profile_exists(profile): + return _ok(rid, {"ok": False, "profile": params.get("profile"), + "error": f"Profile '{profile}' does not exist on this backend."}) + home = _profile_home(profile) + if home is not None: + scope = _session_profile_runtime_scope({"profile_home": str(home)}) with scope: payload = probe(profile, {"profile": profile} if profile else {}) return _ok(rid, payload) diff --git a/tui_gateway/methods_profiles.py b/tui_gateway/methods_profiles.py index 21afa60c94..ad5377e06d 100644 --- a/tui_gateway/methods_profiles.py +++ b/tui_gateway/methods_profiles.py @@ -232,9 +232,10 @@ def _(rid, params: dict) -> dict: return _ok(rid, {"profiles": out, "bot_mode_protocol": True}) -def _copy_secret_file(src, dst, wanted: bool) -> bool: - """Copy ``src`` -> ``dst`` (0600) when ``src`` exists and ``wanted``; True if copied.""" - if not (src.is_file() and wanted): +def _mirror_secret(path, launch_home, name: str, wanted) -> bool: + """Copy the launch ``name`` file into the profile (0600) when it exists and ``wanted(src, dst)``.""" + src, dst = launch_home / name, path / name + if not (src.is_file() and wanted(src, dst)): return False import shutil shutil.copy2(src, dst) @@ -243,25 +244,9 @@ def _copy_secret_file(src, dst, wanted: bool) -> bool: return True -def _mirror_env(path, launch_home) -> bool: - """Copy the launch .env only over the seeded comment-only stub (never a clone's secrets).""" - def has_content(env_path) -> bool: - lines = env_path.read_text(encoding="utf-8", errors="replace").splitlines() - return any(s and not s.startswith("#") for s in map(str.strip, lines)) - src, dst = launch_home / ".env", path / ".env" - return _copy_secret_file(src, dst, has_content(src) and not _try(lambda: has_content(dst), False)) - - -def _mirror_auth(path, launch_home) -> bool: - """Copy the launch auth.json when absent (skipped under ``share_auth``: a copy forks token - state and the first refresh in either store strands the other).""" - src, dst = launch_home / "auth.json", path / "auth.json" - if not _copy_secret_file(src, dst, not dst.exists()): - return False - # Drop single-use OAuth grants (first refresh strands every sibling); they read from - # the root grant via the pool fallback. API keys stay. - _best_effort(lambda: _lazy("hermes_cli.auth", "strip_cloned_single_use_oauth_grants")(path)) - return True +def _env_has_content(env_path) -> bool: + lines = env_path.read_text(encoding="utf-8", errors="replace").splitlines() + return any(s and not s.startswith("#") for s in map(str.strip, lines)) def _mirror_voice_sections(path) -> bool: @@ -309,9 +294,16 @@ def _mirror_launch_credentials(path, params: dict) -> dict: if not is_truthy_value(params.get("mirror_credentials", True)): return mirrored launch_home = get_hermes_home() - mirrored["env"] = _try(lambda: _mirror_env(path, launch_home), False) - if not share_auth: - mirrored["auth"] = _try(lambda: _mirror_auth(path, launch_home), False) + # .env: only over the seeded comment-only stub (never a clone's secrets). + mirrored["env"] = _try(lambda: _mirror_secret(path, launch_home, ".env", lambda src, dst: ( + _env_has_content(src) and not _try(lambda: _env_has_content(dst), False))), False) + if not share_auth: # a copy forks token state: the first refresh in either store strands the other + mirrored["auth"] = _try(lambda: _mirror_secret(path, launch_home, "auth.json", + lambda src, dst: not dst.exists()), False) + if mirrored["auth"]: + # Drop single-use OAuth grants (first refresh strands every sibling); they read from the + # root grant via the pool fallback. API keys stay. + _best_effort(lambda: _lazy("hermes_cli.auth", "strip_cloned_single_use_oauth_grants")(path)) mirrored["voice"] = _mirror_voice_sections(path) return mirrored @@ -465,9 +457,9 @@ def _configure_model(profile_dir, params, applied): """Apply a ``model`` + ``provider`` pin, or return a confirm message and write NOTHING (client resends with ``confirm_expensive_model``). A failing guard = no warning (as _apply_model_switch).""" model, provider = _model_provider_params(params) - confirm_message = None if not (model and provider): return None + confirm_message = None if not is_truthy_value(params.get("confirm_expensive_model", False)): warn = _lazy("hermes_cli.model_selection_guards", "combined_selection_warning") confirm_message = _try(lambda: getattr(warn(model, provider=provider or None), "message", None), None)