/ tools / browser_camofox_state.py
browser_camofox_state.py
 1  """Hermes-managed Camofox state helpers.
 2  
 3  Provides profile-scoped identity and state directory paths for Camofox
 4  persistent browser profiles.  When managed persistence is enabled, Hermes
 5  sends a deterministic userId derived from the active profile so that
 6  Camofox can map it to the same persistent browser profile directory
 7  across restarts.
 8  """
 9  
10  from __future__ import annotations
11  
12  import uuid
13  from pathlib import Path
14  from typing import Dict, Optional
15  
16  from hermes_constants import get_hermes_home
17  
18  CAMOFOX_STATE_DIR_NAME = "browser_auth"
19  CAMOFOX_STATE_SUBDIR = "camofox"
20  
21  
22  def get_camofox_state_dir() -> Path:
23      """Return the profile-scoped root directory for Camofox persistence."""
24      return get_hermes_home() / CAMOFOX_STATE_DIR_NAME / CAMOFOX_STATE_SUBDIR
25  
26  
27  def get_camofox_identity(task_id: Optional[str] = None) -> Dict[str, str]:
28      """Return the stable Hermes-managed Camofox identity for this profile.
29  
30      The user identity is profile-scoped (same Hermes profile = same userId).
31      The session key is scoped to the logical browser task so newly created
32      tabs within the same profile reuse the same identity contract.
33      """
34      scope_root = str(get_camofox_state_dir())
35      logical_scope = task_id or "default"
36      user_digest = uuid.uuid5(
37          uuid.NAMESPACE_URL,
38          f"camofox-user:{scope_root}",
39      ).hex[:10]
40      session_digest = uuid.uuid5(
41          uuid.NAMESPACE_URL,
42          f"camofox-session:{scope_root}:{logical_scope}",
43      ).hex[:16]
44      return {
45          "user_id": f"hermes_{user_digest}",
46          "session_key": f"task_{session_digest}",
47      }