Ë
    ãß²j¨Á  ã                   óÂ  — U d Z ddlZddlZddlZddlZddlZddlZddlZddlZddl	Z	ddl
Z
ddlZddlZddlZddlmZ ddlmZ ddlmZ ddlmZ ddlmZ ddlmZ dd	lmZmZmZmZmZm Z m!Z!m"Z"m#Z# dd
l$m%Z%m&Z&m'Z'm(Z(m)Z) ddl*m+Z+m,Z,  ejZ                  «       dk(  Z. ej^                  e0«      Z1dZ2 ejf                  «       Z4da5 ejl                  d«      Z7dqd„Z8e2fde9de:fd„Z;drd„Z<de=de=fd„Z>de=de=fd„Z?de=de=fd„Z@de=de=fd„ZAde=de=fd„ZBde=deCfd„ZDde=de=fd„ZEdeFddfd„ZGdeFddfd „ZH eI«       d!œd"ee=e=f   d#eFd$eCd%eIddf
d&„ZJdeFdeFfd'„ZKd%eIdeFfd(„ZLdsd)eFdz  d*eFdz  deFfd+„ZMdd,œd-eCdeFe=e=f   fd.„ZNdeFd-eCdeFfd/„ZO	 dsd0d0ddd1œd2d3d4eCd5eCd6d3d7eCdeFe=e=f   fd8„ZP	 dsddd9œd2d3d:d;d-eCdeFe=e=f   fd<„ZQd:d=deCfd>„ZRdsdeFd:d;deFfd?„ZSd@dAdeTe=   fdB„ZUde=fdC„ZVdaWdDeXdE<   deTe=   fdF„ZYdeTe=   fdG„ZZdHe=dIeTe=   de=fdJ„Z[dHe=de=fdK„Z\ eIh dL£«      Z]de=fdM„Z^dNZ_ e`«       ZaeaabdOeXdP<   de=dz  fdQ„ZcdHe=de=fdR„ZddeTe=   fdS„ZedeTe=   fdT„ZfdHe=de=fdU„ZgdeFddfdV„ZhdWeFde=dz  fdX„ZideFdeFfdY„Zj eek«      jÙ                  «       jÚ                  dZ   ZneeXd[<    e+en eek«      jß                  «       jÚ                  dZ    e«       «      Zpeqed\f   eXd]<    ere
d^e
jæ                  «      e
jæ                  k7  xs	  ete
d_«      ZueCeXd`<   dZveTe   dz  eXda<   deqeTe=   eCf   fdb„ZwdeTe=   fdc„Zxdde=deeTe=   de=fdf„Zydge:dhe9deCfdi„ZzdjeTdge:ddfdk„Z{drdl„Z|drdm„Z}drdn„Z~ G do„ dpe«      Zy)tuE   Local execution environment â€” spawn-per-call with session snapshot.é    N)ÚMapping)ÚPath©Úget_process_hermes_home)ÚBaseEnvironment)Ú_pipe_stdin)Úwindows_hide_flags)	Ú_ALWAYS_STRIP_KEYSÚ_HERMES_PROVIDER_ENV_BLOCKLISTÚ!_HERMES_PROVIDER_ENV_FORCE_PREFIXÚ_is_hermes_internal_secretÚ_is_provider_env_blocklistedÚ_is_terminal_first_party_envÚ$_matches_terminal_first_party_prefixÚ_plugin_terminal_env_strip_keysÚstrip_profile_gate_env)Ú_bash_probe_details_cacheÚ_bash_startsÚ_git_bash_aslr_helpÚ_looks_like_msys_spawn_failureÚ_mandatory_aslr_enabled)Ú_build_hermes_repo_root_aliasesÚ2_strip_hermes_owned_pythonpath_and_runtime_markersÚWindowsé   Fz,^(hermes_bg_[A-Za-z0-9_-]+)\.(log|pid|exit)$Úreturnc                  óH   — 	 ddl m}   | «       dz  dz  S # t        $ r Y yw xY w)z;Return HERMES_HOME/cache/terminal, or None if unresolvable.r   ©Úget_hermes_homeÚcacheÚterminalN)Úhermes_constantsr   Ú	Exceptionr   s    ú=/home/ubuntu/.hermes/hermes-agent/tools/environments/local.pyÚ_default_terminal_temp_dirr%   4   s/   € ðÝ4ÙÓ  7Ñ*¨ZÑ7Ð7øÜò Ùðús   ‚ •	! !Úmax_age_hoursc                 ó8  — ddl m} t        «       }|€yt        j                  «       | dz  z
  }	 t	        |j                  «       «      }i }i }|D ]�  }	 |j                  «       j                  x||<   }t        j                  |j                  «      x}	sŒEt        |j                  |	j                  d«      d«      |«      ||	j                  d«      <   Œƒ d}
|j                  «       D ]…  \  }}t        j                  |j                  «      }	|	r||	j                  d«         |k\  rŒ? |||«      rŒI	 |j!                  «       rt#        j$                  |d¬«      n|j'                  «        |
dz  }
Œ‡ |
S # t        $ r Y yw xY w# t        $ r Y �Œ;w xY w# t        $ r Y Œ´w xY w)u?  Delete session temp artifacts idle for *max_age_hours* (no write anywhere in a
    directory's subtree; the kwarg name is the ``cleanup_*_cache`` signature the gateway
    housekeeping loop calls every entry with); return count.
    Only the managed default dir is pruned â€” never a user-pointed ``terminal.temp_dir``.r   )Úsubtree_touched_sincei  é   g        T)Úignore_errors)Úhermes_constants_scratchr(   r%   ÚtimeÚlistÚiterdirÚOSErrorÚstatÚst_mtimeÚ_BG_GROUP_REÚmatchÚnameÚmaxÚgetÚgroupÚitemsÚis_dirÚshutilÚrmtreeÚunlink)r&   r(   ÚrootÚcutoffÚentriesÚmtimesÚgroup_newestÚfÚmtÚmÚremoveds              r$   Úcleanup_terminal_temp_cacherF   =   s‘  € õ
 ?ä%Ó'€DØ€|ØÜ�Y‰Y‹[˜M¨DÑ0Ñ1€FðÜ�t—|‘|“~Ó&ˆð !#€FØ%'€LØò Rˆð	ØŸV™V›X×.Ñ.Ð.ˆF�1‰I˜ô ×"Ñ" 1§6¡6Ó*Ð*ˆ1Ñ*Ü'*¨<×+;Ñ+;¸A¿G¹GÀA»JÈÓ+LÈbÓ'QˆL˜Ÿ™ ›Ò$ðRð €GØ—‘“ò ‰ˆˆ2Ü×Ñ˜qŸv™vÓ&ˆÙØ˜AŸG™G A›JÑ'¨6Ò1ØÙ" 1 fÔ-Øð	Ø45·H±H´JŒF�M‰M˜!¨4Õ0ÀAÇHÁHÃJøØ�q‰L‰Gðð €Nøô5 ò Ùðûô ò 	Úð	ûô  ò 	Ùð	ús5   ¯E. ÁE=Ä.<FÅ.	E:Å9E:Å=	F
Æ	F
Æ	FÆFc                  óÌ   — t         5  t        r
	 ddd«       ydaddd«       	 t        «        y# 1 sw Y   ŒxY w# t        $ r } t        j                  d| «       Y d} ~ yd} ~ ww xY w)z@Best-effort prune, at most once per process (CLI-only installs).NTzTerminal temp prune failed: %s)Ú_terminal_temp_prune_lockÚ_terminal_temp_pruned_oncerF   r#   ÚloggerÚdebug)Úexcs    r$   Ú_prune_terminal_temp_oncerM   g   sb   € ô 
#ñ *Ý%Ø÷*ð *ð &*Ð"÷*ð<Ü#Õ%÷*ð *ûô ò <Ü�‰Ð5°s×;Ñ;ûð<ús!   ‡.˜.£
: ®7º	A#ÁAÁA#Úcwdc                 óú   — t         xr | xr t        j                  d| «      }|s| S |j                  d«      xs dj	                  dd«      }|j                  d«      j                  «       › d|xs t        d«      › �S )	zí``/c/Users/x`` / ``/cygdrive/c/..`` / ``/mnt/c/..`` -> native ``C:\Users\x`` so
    ``isdir``/``Popen(cwd=)`` find it. No-op off Windows, for empty input and for
    multi-segment POSIX paths like ``/home/x``; idempotent on native paths.z)^/(?:(?:cygdrive|mnt)/)?([a-zA-Z])(/.*)?$é   Ú ú/ú\r)   ú:é\   )Ú_IS_WINDOWSÚrer3   r7   ÚreplaceÚupperÚchr©rN   rD   Útails      r$   Ú_msys_to_windows_pathr]   u   ss   € ô 	Ò[˜Ò[¤§¡Ð)UÐWZÓ [€AÙØˆ
Ø�G‰G�A‹JÒ˜"×%Ñ% c¨4Ó0€DØ�g‰g�a‹j×ÑÓ Ð!  4¢?¬3¨r«7Ð"3Ð4Ð4ó    c                 óT  — | rt         j                  j                  | «      nt        j                  «       }t        r"t        |«      }t        j                  |«      r|S t         j                  j                  |«      r|S t         j                  j                  |«      }t        j                  «       }t         j                  j                  |«      sWt        |«      j                  t        |«      j                  }}|r+t        |«      t        |«      k  r|t        |«       d |k(  r|S |S )zðResolve the initial cwd to an absolute host path. A relative ``TERMINAL_CWD``
    naming the launch directory would otherwise make the wrapper ``cd`` *inside*
    the project; anchor it once so ``Popen(cwd=)`` and the in-shell ``cd`` agree.N)ÚosÚpathÚ
expanduserÚgetcwdrV   r]   ÚntpathÚisabsÚabspathÚisdirr   ÚpartsÚlen)rN   ÚexpandedÚ	candidateÚcurrentÚwantedÚhaves         r$   Ú_resolve_local_initial_cwdro   €   sÒ   € ñ +.Œr�w‰w×!Ñ! #Ô&´2·9±9³;€HÝÜ(¨Ó2ˆô �<‰<˜Ô!ØˆOÜ	‡w�w‡}�}�XÔØˆÜ—‘—‘ Ó)€IÜ�i‰i‹k€Gä�7‰7�=‰=˜Ô#Ü˜H“~×+Ñ+¬T°'«]×-@Ñ-@�ˆÙ”c˜&“k¤S¨£YÒ.°4¼¸V»¸¸Ð3FÈ&Ò3PØˆNØÐr^   c                 ó   — t         xr | xr t        j                  d| «      }|s| S |j                  d«      xs dj	                  dd«      j                  d«      }d|j                  d«      j                  «       › d|› �S )z|Native ``C:\Users\x`` -> Git Bash ``/c/Users/x`` so ``builtin cd`` resolves
    it. No-op off Windows / for non-drive paths.z^([a-zA-Z]):[\\/]*(.*)$rP   rQ   rS   rR   r)   )rV   rW   r3   r7   rX   ÚlstripÚlowerr[   s      r$   Ú_windows_to_msys_pathrs   —   sv   € ô 	ÒI˜ÒI¤§¡Ð)CÀSÓ I€AÙØˆ
Ø�G‰G�A‹JÒ˜"×%Ñ% d¨CÓ0×7Ñ7¸Ó<€DØˆq�w‰w�q‹z×ÑÓ!Ð" ! D 6Ð*Ð*r^   ra   c                 óL   — t         r| rt        | «      j                  dd«      S | S )zñ*path* safe to embed in a Git Bash script: ``C:\Users\x`` / ``C:/Users/x``
    become ``/c/Users/x`` (MSYS argument conversion mangles ``C:/`` forms) and
    leftover backslashes are normalized so bash does not eat ``\U``. No-op off Windows.rS   rR   )rV   rs   rX   ©ra   s    r$   Ú_bash_safe_pathrv   ¡   s(   € õ >IÉTÔ  Ó&×.Ñ.¨t°SÓ9Ð[ÐW[Ð[r^   c                 ó>   — ddl }|j                  t        | «      «      S )zFQuote *path* for safe interpolation into a Git Bash script on Windows.r   N)ÚshlexÚquoterv   )ra   rx   s     r$   Ú_quote_bash_pathrz   ¨   s   € ãØ�;‰;” tÓ,Ó-Ð-r^   c                 óŒ   — t         j                  j                  | «      xr$ t        j                  | t         j                  «      S )z›True when *path* is a directory this process can actually chdir into
    (``isdir`` alone passes ``/root`` for a non-root user; ``Popen(cwd=)`` then dies).)r`   ra   rg   ÚaccessÚX_OKru   s    r$   Ú_cwd_usabler~   ®   s+   € ô �7‰7�=‰=˜ÓÒ;¤2§9¡9¨T´2·7±7Ó#;Ð;r^   c           
      óð  — t        | «      } | rt        | «      r| S | rKt        j                  j	                  | «      r,t
        j                  d|  t        t        dd„ «      «       «       | rt        j                  j                  | «      nd}|rSt        |«      sHt        j                  j                  |«      }||k(  rt        j                  «       S |}|rt        |«      sŒH|xs t        j                  «       S )u=  ``cwd`` if enterable, else the nearest usable ancestor, else
    ``tempfile.gettempdir()``. MSYS paths are normalized first on Windows so a valid
    ``pwd -P`` result is not rejected. Lets ``_run_bash`` recover from a deleted or
    inaccessible cwd instead of ``Popen`` raising and wedging every later call.

    Used by ``_run_bash`` to recover when the configured cwd is gone â€” most commonly because a previous tool
    call deleted its own working directory (issue #17558) â€” or inaccessible to this user, e.g. ``/root``
    leaking from a root-launched CLI session into a non-root gateway's cron jobs (issue #65583). Without
    this guard, ``subprocess.Popen(..., cwd=...)`` raises ``FileNotFoundError``/``PermissionError`` before
    bash starts, wedging every subsequent terminal call until the gateway restarts.
    uð   Configured terminal cwd %r exists but is not accessible to this user (uid=%s) â€” falling back to the nearest usable directory. If this is a gateway/cron process, check for root-owned paths leaking into terminal.cwd / TERMINAL_CWD (#65583).Úgetuidc                   ó   — y)Nú?© rƒ   r^   r$   ú<lambda>z#_resolve_safe_cwd.<locals>.<lambda>Ê   ó   � r^   rQ   )r]   r~   r`   ra   rg   rJ   ÚwarningÚgetattrÚdirnameÚtempfileÚ
gettempdir)rN   ÚparentÚnext_parents      r$   Ú_resolve_safe_cwdr�   ´   sÈ   € ô   Ó
$€CÙ
Œ{˜3ÔØˆ
Ù
Œr�w‰w�}‰}˜SÔ!Ü�‰ðð
 Ð3”œ˜X¡{Ó3Ó5ô	7ñ &)ŒR�W‰W�_‰_˜SÔ!¨b€FÙ
œ VÔ,Ü—g‘g—o‘o fÓ-ˆØ˜&Ò Ü×&Ñ&Ó(Ð(Øˆñ	 œ VÕ,ð
 Ò*”X×(Ñ(Ó*Ð*r^   Úenvc                 ó`   — ddl m}m} 	  |«       x}r|| d<    || «       y# t        $ r Y Œw xY w)zQBridge the context-local HERMES_HOME override, then the subprocess HOME contract.r   )Úapply_subprocess_home_envÚget_hermes_home_overrideÚHERMES_HOMEN)r"   r�   r‘   r#   )rŽ   r�   r‘   Úvalues       r$   Ú_apply_profile_homer”   Õ   s@   € çTðÙ,Ó.Ð.ˆ5Ð.Ø!&ˆC�Ññ ˜cÕ"øô ò Ùðús   Š! ¡	-¬-c                 óî   — 	 ddl m}m}m}  |«       }|j                  «       D ]A  \  }}|j                  «       }||ur|€dn
t        |«      | |<   Œ-|sŒ0| j                  |d«       ŒC y# t        $ r Y yw xY w)u™  Bridge gateway session ContextVars (HERMES_SESSION_*) into a child env.
    Cross-session leak guard: the vars' last-writer-wins ``os.environ`` mirror may
    belong to another turn on a concurrent multi-session host, so once the session
    context is engaged ContextVars are authoritative â€” a bound value (incl. "") wins
    and an _UNSET var is STRIPPED, not inherited. An unengaged CLI keeps the mirror.r   )Ú_UNSETÚ_VAR_MAPÚsession_context_engagedNrQ   )	Úgateway.session_contextr–   r—   r˜   r#   r8   r6   ÚstrÚpop)rŽ   r–   r—   r˜   Ú_engagedÚvar_nameÚvarr“   s           r$   Ú_inject_session_context_envrŸ   à   s|   € ðßUÑUñ 'Ó(€HØ!Ÿ™Ó)ò $‰ˆ�#Ø—‘“	ˆØ˜ÑØ"' -™B´S¸³ZˆC�ŠMÚØ�G‰G�H˜dÕ#ñ$øô ò Ùðús   ‚
A( Á(	A4Á3A4)Úplugin_stripr8   ÚoutÚunwrap_forcer    c                ó¶  — 	 ddl m}m} t	        d„ |D «       «      }| j                  «       D ]–  \  }}|j                  t        «      r&|sŒ|t        t        «      d }t        |«      s|||<   ŒAt        |«      s|j                  «       |v rŒ_t        |«      }	 ||«      }
t        |«      r|
s|	sŒ‚|
r|	s	 |||«      }|€Œ’|||<   Œ˜ y# t        $ r	 d„ d„ }}Y ŒÍw xY w)a‹  Copy *items* into *out*, dropping Hermes-managed secrets. ``_HERMES_FORCE_<NAME>``
    unwraps to ``NAME`` when ``unwrap_force`` (caller extras / terminal env), else is
    dropped. Blocklisted names survive only via env_passthrough registration or as
    context-entitled first-party ``BUZZ_*`` vars; the latter are used directly, never
    scope-resolved (UnscopedSecretError under multiplex).r   )Úis_env_passthroughÚresolve_passthrough_valuec                  ó   — y)NFrƒ   )Ú_s    r$   r„   z$_filter_secret_env.<locals>.<lambda>þ   r…   r^   c                 ó   — |S ©Nrƒ   )Ú_nÚfbs     r$   r„   z$_filter_secret_env.<locals>.<lambda>þ   s   € Ð[]€ r^   c              3   ó<   K  — | ]  }|j                  «       –— Œ y ­wr©   ©rY   ©Ú.0Úks     r$   ú	<genexpr>z%_filter_secret_env.<locals>.<genexpr>ÿ   s   è ø€ Ò#D°! A§G¡G§IÑ#Dùó   ‚N)Útools.env_passthroughr¤   r¥   r#   Ú	frozensetr8   Ú
startswithr   ri   r   rY   r   r   )r8   r¡   r¢   r    r¤   r¥   Úplugin_strip_foldedÚkeyr“   Úfirst_partyÚpassthroughs              r$   Ú_filter_secret_envrº   ó   sì   € ð_ßWô $Ñ#D°|Ô#DÓDÐØ—k‘k“mò ‰
ˆˆUØ�>‰>Ô;Ô<ÙØØ”cÔ;Ó<Ð=Ð>ˆCÜ-¨cÔ2Ø ��C‘ØÜ% cÔ*¨c¯i©i«kÐ=PÑ.PØÜ2°3Ó7ˆÙ(¨Ó-ˆÜ'¨Ô,±kÁ[ØÙ™{Ù-¨c°5Ó9ˆEØÑØˆC�ŠHñ#øô ò _Ù9HÑL]Ð5Òð_ús   ‚C ÃCÃCc                 óv   — t        | «       t        | «       t        | «       t        | «       ddlm}  || «      S )zÚGuards shared by every spawn surface: profile-home propagation, session-context
    bridging, Hermes-owned PYTHONPATH + venv-marker strip, MSYS defaults, delegate_task
    Kanban scrub. Returns the (possibly new) dict.r   ©Údelegated_child_subprocess_env)r”   rŸ   r   Ú%_apply_windows_msys_bash_env_defaultsÚagent.delegation_contextr½   )rŽ   r½   s     r$   Ú_finalize_child_envrÀ     s2   € ô ˜ÔÜ Ô$Ü6°sÔ;Ü)¨#Ô.ÝGÙ)¨#Ó.Ð.r^   c                 ó  ‡— i }| D ]  \  }}t        |||‰¬«       Œ ddlm} |j                  ˆfd„ ||«      j	                  «       D «       «       t        |«      }|�$t         ||j                  |d«      «      «      ||<   t        |«      S )zøFilter each ``(items, unwrap_force)`` in *parts* into one env, rewrite PATH via
    *fix_path* (always prepending the hermes install dir so bare ``hermes`` resolves
    for children of a systemd/cron-launched gateway), then apply the shared guards.)r¢   r    r   )Úscoped_passthrough_additionsc              3   ó6   •K  — | ]  \  }}|‰vsŒ||f–— Œ y ­wr©   rƒ   )r¯   r°   Úvr    s      €r$   r±   z _scrubbed_env.<locals>.<genexpr>,  s!   øè ø€ Òe™$˜!˜QÈqÐXdÒOd��1ŒvÑeùs   ƒ�	rQ   )	rº   r³   rÂ   Úupdater8   Ú_path_env_keyÚ_prepend_hermes_bin_dirr6   rÀ   )rh   r    Úfix_pathr¡   r8   r¢   rÂ   Úpath_keys    `      r$   Ú_scrubbed_envrÊ      s�   ø€ ð €CØ$ò ]Ñˆˆ|Ü˜5 #°LÈ|Ö\ð]õ CØ‡J�JÓeÑ">¸sÓ"C×"IÑ"IÓ"KÔeÔeÜ˜SÓ!€Hð ÐÜ/±¸¿¹ÀÈ2Ó9NÓ0OÓPˆˆH‰Ü˜sÓ#Ð#r^   Úbase_envÚ	extra_envc                 óJ   — t        | xs i df|xs i dfgt        «       d„ «      S )z–Filter Hermes-managed secrets from a subprocess environment (background/PTY
    spawn path, search workers, computer-use driver, user-script runners).FTc                 ó   — | S r©   rƒ   ©Úps    r$   r„   z*_sanitize_subprocess_env.<locals>.<lambda>:  s   € Àa€ r^   )rÊ   r   )rË   rÌ   s     r$   Ú_sanitize_subprocess_envrÑ   6  s4   € ô ˜8š> r¨5Ð1°I²OÀÀTÐ3JÐKÜ8Ó:¹KóIð Ir^   ©Úinherit_credentialsrÓ   c                 óŽ   — t        t        j                  j                  «       | ¬«      }|j	                  dd«       t        |«      S )uø  Sanitized env for the **non-terminal** spawn surface (browser, ACP/CLI executors,
    computer-use driver, TUI Node host). Tier 1 (``_ALWAYS_STRIP_KEYS``, plugin keys,
    force-prefixed hints, dynamic internal secrets) is always removed; Tier 2 (the
    provider/tool blocklist) unless ``inherit_credentials`` â€” pass that **only** for
    children that legitimately need LLM credentials (user-blessed claude/codex/gemini
    CLI, TUI Node host). Terminal/execute_code use ``_sanitize_subprocess_env``.rÒ   Ú
PYTHONUTF8Ú1)Ú_scrub_credentialsr`   ÚenvironÚcopyÚ
setdefaultrÀ   )rÓ   rŽ   s     r$   Úhermes_subprocess_envrÛ   =  s5   € ô œRŸZ™ZŸ_™_Ó.ÐDWÔ
X€CØ‡N�N�< Ô%Ü˜sÓ#Ð#r^   c                óî   — t        d„ t        t        «       z  D «       «      }t        | «      D ]E  }|j	                  «       |v s.|st        |«      s!|j                  t        «      st        |«      sŒC| |= ŒG | S )z`Tier 1 (always) and, unless ``inherit_credentials``, Tier 2 provider/tool credentials, in place.c              3   ó<   K  — | ]  }|j                  «       –— Œ y ­wr©   r­   r®   s     r$   r±   z%_scrub_credentials.<locals>.<genexpr>M  s   è ø€ Òi¨1˜QŸW™WŸYÑiùr²   )	r´   r
   r   r-   rY   r   rµ   r   r   )rŽ   rÓ   Ústrip_foldedr·   s       r$   r×   r×   I  sm   € ô ÑiÔ1CÔFeÓFgÑ1gÔiÓi€LÜ�C‹yò ˆØ�I‰I‹K˜<Ñ'Ù+Ô0LÈSÔ0QØ—>‘>Ô"CÔDÜ-¨cÕ2Ø�C‘ðð €Jr^   T)Úinherit_profile_homeÚscrub_secretsÚextraÚstrip_launch_profileÚbasezMapping[str, str] | Nonerß   rà   rá   râ   c                ó  — | �t        | «      nt        j                  j                  «       }|rt	        |«       |rt        ||rt        |«      «      S d«      S |rt        |«       |r|j                  |«       ddlm	}  ||«      S )a»  Single factory for child-process envs. ``base=None`` snapshots ``os.environ``.
    ``scrub_secrets=True`` -> :func:`_sanitize_subprocess_env` (profile home inherent,
    ``inherit_profile_home`` ignored). ``scrub_secrets=False`` keeps the base
    byte-for-byte (git credential flows, ``bws``/``op``); ``inherit_profile_home``
    bridges HERMES_HOME + HOME and ``extra`` is applied last so caller overrides win.
    ``strip_launch_profile`` drops the LAUNCH profile's ``.env`` residue from the base first
    (:func:`strip_launch_profile_env`; a no-op unless a routed home is active) so a child that
    acts for a routed profile sees only that profile's declared names, never the launch profile's.Nr   r¼   )
Údictr`   rØ   rÙ   Ústrip_launch_profile_envrÑ   r”   rÅ   r¿   r½   )rã   rß   rà   rá   râ   rŽ   r½   s          r$   Úbuild_subprocess_envrç   W  sp   € ð )-Ð(8œ$˜tœ*¼b¿j¹j¿o¹oÓ>O€CÙÜ  Ô%ÙÜ'¨¹E¬T°%«[ÓLÐLÀtÓLÐLÙÜ˜CÔ ÙØ�
‰
�5ÔÝGÙ)¨#Ó.Ð.r^   )Útarget_homerÓ   rè   zstr | Path | Nonec                ó¨  — ddl m}m}m}m} ddlm}m} | �t        | «      nt        |¬«      }	t        |xs  |«       xs d«      }
|
r1|
|	d<    ||	«       t        |
«      rt        |	|
«       t        |	d¬«       |rW|
r |t        |
«      «      }n |«       }|€ |«       r	 |dd«      ‚|	j                  d	„ |xs i j!                  «       D «       «       |	S )
u³  Child env for a process that acts FOR the active (possibly served) profile: ``hermes -p X``
    workers, ``key_cmd`` helpers, browser drivers. The process env is the LAUNCH profile's. When the
    target is a ROUTED home (not the launch profile's â€” under multiplex or a Desktop/dashboard backend
    serving ``?profile=`` with the flag off) the launch ``.env`` residue and bridged ``TERMINAL_*`` are
    dropped (``strip_launch_profile_env``) AND every provider/tool credential is scrubbed from the base
    regardless of provenance: a key systemd / Compose / the shell injected into the launch process was
    never recorded in ``.env`` or a source snapshot, so a name-based strip cannot see it and the target
    overlay cannot remove it. ``inherit_credentials=True`` is for children that legitimately run with
    the profile's credentials (they run the agent or mint its token): the target profile's own secrets
    (its ``.env`` + hydrated sources, what a standalone ``hermes -p X`` loads itself) are overlaid â€” never
    a sibling profile's. Under multiplex with neither a target nor a bound scope the call raises
    (``get_secret``'s fail-closed contract): minting with the launch environ would sign in as the wrong
    profile. ``False`` keeps the provider scrub; the caller re-adds the few keys the child needs via
    ``get_secret``. ``target_home`` defaults to the active override; ``base`` replaces the
    ``hermes_subprocess_env`` snapshot.r   )ÚUnscopedSecretErrorÚbuild_profile_secret_scopeÚcurrent_secret_scopeÚis_multiplex_active)Úapply_scratch_tmp_envr‘   rÒ   rQ   r’   Fa  served_profile_child_env(inherit_credentials=True) called with no target home and no profile secret scope bound while multiplexing is on; the child would inherit the launch profile's credentials. Bind the profile scope (or pass target_home) at the spawn site.c              3   ó0   K  — | ]  \  }}|€Œ	||f–— Œ y ­wr©   rƒ   )r¯   r°   rÄ   s      r$   r±   z+served_profile_child_env.<locals>.<genexpr>˜  s   è ø€ ÒO™d˜a ÀÁ�A�q”6ÑOùs   ‚
�	)Úagent.secret_scoperê   rë   rì   rí   r"   rî   r‘   rå   rÛ   rš   Ú_is_routed_homeræ   r×   r   rÅ   r8   )rã   rè   rÓ   rê   rë   rì   rí   rî   r‘   rŽ   ÚtargetÚsecretss               r$   Úserved_profile_child_envrô   p  sÖ   € ÷&dó dçPØÐ(Œ$ˆtŒ*Ô.CÐXkÔ.l€CÜ�Ò@Ñ 8Ó :Ò@¸bÓA€FÙØ#ˆˆMÑÙ˜cÔ"Ü˜6Ô"Ü$ S¨&Ô1Ü˜s¸Õ>ÙÙÙ0´°f³Ó>‰Gá*Ó,ˆGØˆÑ#6Ô#8Ù)Øð tóuð uð 	�
‰
ÑO w¢}°"×&;Ñ&;Ó&=ÔOÔOØ€Jr^   z
str | Pathc                 óŒ   — ddl m} 	 t        | «      j                  «        |«       j                  «       k7  S # t        $ r Y yw xY w)zATrue when ``target_home`` is not the process's own (launch) home.r   r   T)r"   r   r   Úresolver/   )rè   r   s     r$   rñ   rñ   œ  sB   € å8ðÜ�KÓ ×(Ñ(Ó*Ñ.EÓ.G×.OÑ.OÓ.QÑQÐQøÜò Ùðús   ˆ.7 ·	AÁAc                 óì  — ddl m}m} ddlm}m} |xs  |«       }|rt        |«      s| S  |«       }ddlm} t         ||dz  «      «      t        |j                  «       «      z  D �	ch c]G  }	 ||	j                  «       «      r|	j                  «       j                  d«      r|	j                  «       ’ŒI }
}	| D �cg c]  }|j                  «       |
v sŒ|‘Œ c}D ]  }	| |	= Œ t        | «      S c c}	w c c}w )a"  Drop the LAUNCH profile's residue from a child env built for another served profile.
    ``os.environ`` holds the default profile's ``.env`` and its bridged ``TERMINAL_*`` settings;
    the secret scrub removes credentials but not settings (``HERMES_MODEL``, ``TERMINAL_ENV``,
    ``HERMES_LANGUAGE``...), so a standalone ``hermes -p X`` worker and a served one saw different
    envs. The child re-loads X's own ``.env`` and bridges X's config itself. ``target_home``
    defaults to the active home override; no-op when there is no target or the target IS the
    launch profile. The authority test is "does this task serve a routed home", not "is the
    gateway-wide multiplex flag on": the Desktop/dashboard backend serves ``?profile=B`` by
    installing a HERMES_HOME override without that flag.r   )Ú_is_global_envÚload_env_file)r‘   r   )ÚTERMINAL_CONFIG_ENV_MAPz.envÚ	TERMINAL_)rð   rø   rù   r"   r‘   r   rñ   Úhermes_cli.configrú   ÚsetÚvaluesrY   rµ   r   )rŽ   rè   rø   rù   r‘   r   rò   Úlaunch_homerú   r·   Úresidue_namesr°   s               r$   ræ   ræ   ¥  sç   € ÷ AßRØÒ6Ñ4Ó6€FÙœ¨Ô0Øˆ
Ù)Ó+€KÝ9ô 	‰M˜+¨Ñ.Ó/Ó0´3Ð7N×7UÑ7UÓ7WÓ3XÑXöSØá˜cŸi™i›kÔ*¨c¯i©i«k×.DÑ.DÀ[Ô.Qð 	�	‰	�ðS€Mð Sð Ö=�a !§'¡'£)¨}Ò"<’Ò=ò ˆØ�‰Hðô
 " #Ó&Ð&ùòSùò >s   Á(AC,Â:C1ÃC1Úcustomz
str | Nonec           
      ó(  — t         j                  j                  } |dd«      }|xr" t         j                  j	                  |ddd«      |xr# t         j                  j	                  |dddd«      t         j                  j	                   |dd«      d	d«      t         j                  j	                   |d
d«      d	d«      |xr" t         j                  j	                  |dd	d«      g}| xs dgd„ |D «       ¢}t        t        j                  d„ |D «       «      «      }t        j                  d«      }|rb||vr^t         j                  j                  |«      j                  «       }d|v sd|v rt        j                  d|«       |S |j                  |«       |S )u&  Ordered bash.exe candidates on Windows: HERMES_GIT_BASH_PATH, our portable Git
    under %LOCALAPPDATA%\hermes\git (PortableGit ``bin`` and MinGit ``usr\bin``),
    known Git-for-Windows dirs, then PATH last â€” ``shutil.which`` may return WSL's
    bash, which fails silently on Windows paths.ÚLOCALAPPDATArQ   ÚhermesÚgitÚbinÚusrÚProgramFileszC:\Program FilesÚGitzProgramFiles(x86)zC:\Program Files (x86)ÚProgramsc              3   ób   K  — | ]'  }|sŒt         j                  j                  |d «      –— Œ) y­w)zbash.exeN)r`   ra   Újoin)r¯   Úrs     r$   r±   z+_windows_bash_candidates.<locals>.<genexpr>Õ  s!   è ø€ ÒK¸1Êœ2Ÿ7™7Ÿ<™<¨¨:×6ÑKùs   ‚/Š%/c              3   óf   K  — | ])  }|sŒt         j                  j                  |«      sŒ&|–— Œ+ y ­wr©   ©r`   ra   Úisfile)r¯   Úcs     r$   r±   z+_windows_bash_candidates.<locals>.<genexpr>Ö  s!   è ø€ Ò#N¨!²a¼B¿G¹G¿N¹NÈ1Õ<M¤AÑ#Nùs   ‚1Š1ª1ÚbashÚsystem32Úwindowsappsz"Skipping WSL/system bash.exe at %s)r`   rØ   r6   ra   r  r-   rå   Úfromkeysr:   ÚwhichÚnormpathrr   rJ   rK   Úappend)r  ÚgetenvÚladÚrootsÚrawÚ
candidatesÚfoundÚnorms           r$   Ú_windows_bash_candidatesr   Ç  sV  € ô
 �Z‰Z�^‰^€FÙ
� Ó
$€CàÒ9”—‘—‘˜S (¨E°5Ó9ØÒ@”—‘—‘˜S (¨E°5¸%Ó@Ü
�‰�‰‘V˜NÐ,?Ó@À%ÈÓOÜ
�‰�‰‘VÐ/Ð1JÓKÈUÐTYÓZØÒ;”—‘—‘˜S *¨e°UÓ;ð€Eð Š<�RÐ
LÑKÀÔKÐ
L€CÜ”d—m‘mÑ#N¨sÔ#NÓNÓO€JÜ�L‰L˜Ó €EÙ�˜jÑ(ô �w‰w×Ñ Ó&×,Ñ,Ó.ˆØ˜Ñ °$Ñ!6Ü�L‰LÐ=¸uÔEð Ðð ×Ñ˜eÔ$ØÐr^   c                  ó^  ‡— t         sOt        j                  d«      xs8 t        d„ dD «       d«      xs# t        j
                  j                  d«      xs dS t        j
                  j                  d«      } t        | «      }|D ]N  }t        |«      sŒ|| k7  r8| r6t        j                  j                  | «      rt        j                  d| |«       |c S  |rNd	j                  ˆfd
„|D «       «      }t        «       du st        |«      rt!        t#        |d   |«      «      ‚|d   S t!        d«      ‚)z Find bash for command execution.r  c              3   ó`   K  — | ]&  }t         j                  j                  |«      sŒ#|–— Œ( y ­wr©   r  ©r¯   rÐ   s     r$   r±   z_find_bash.<locals>.<genexpr>ç  s    è ø€ ÒX˜qÄbÇgÁgÇnÁnÐUVÕFWœÑXùó   ‚$.§.)z/usr/bin/bashz	/bin/bashNÚSHELLz/bin/shÚHERMES_GIT_BASH_PATHz8HERMES_GIT_BASH_PATH=%s fails to start; using %s insteadÚ
c              3   óR   •K  — | ]  }t        j                  |«      xŠsŒ‰–— Œ  y ­wr©   )r   r6   )r¯   r  Údetails     €r$   r±   z_find_bash.<locals>.<genexpr>ô  s/   øè ø€ ò "XØÔ5N×5RÑ5RÐSTÓ5UÐ+U¨6Ñ+UŒFñ"Xùs   ƒ' 'Tr   z®Git Bash not found. Hermes Agent requires Git for Windows on Windows.
Install it from: https://git-scm.com/download/win
Or set HERMES_GIT_BASH_PATH to your bash.exe location.)rV   r:   r  Únextr`   rØ   r6   r   r   ra   r  rJ   r†   r  r   r   ÚRuntimeErrorr   )r  r  rk   Úprobe_detailsr)  s       @r$   Ú
_find_bashr-  ã  s&  ø€ åÜ—‘˜VÓ$ò 8ÜÑXÐ$BÔXÐZ^Ó_ò8ä—:‘:—>‘> 'Ó*ò8à.7ð	9ô �Z‰Z�^‰^Ð2Ó3€FÜ)¨&Ó1€Jð  ò ˆ	Ü˜	Õ"Ø˜FÒ"¡v´"·'±'·.±.ÀÔ2HÜ—‘ØNÐPVÐXaôcàÒðñ ØŸ	™	ó "XØ&ô"Xó Xˆä"Ó$¨Ñ,Ô0NÈ}Ô0]ÜÔ2°:¸a±=À-ÓPÓQÐQð ˜!‰}ÐÜ
ð	AóBð Br^   zlist[str] | NoneÚ_git_bash_bin_dirs_cachec                  ó>   — t         €t        r
t        «       ng a t         S )a4  Git Bash's coreutils dirs in ``/etc/profile`` order (mingw first so coreutils
    beat System32 lookalikes); ``[]`` off Windows. A non-login ``bash -c`` (fallback
    when ``bash -l`` is broken) never sources ``/etc/profile``, so without these
    ``cat``/``mktemp``/``mv`` are missing and commands exit 127.)r.  rV   Ú_compute_git_bash_bin_dirsrƒ   r^   r$   Ú_git_bash_bin_dirsr1    s   € ô  Ð'ÝCNÔ#=Ô#?ÐTVÐ Ü#Ð#r^   c                  óº  ‡— 	 t        «       } t        j                  j	                  t        j                  j	                  | «      «      }t        j                  j                  |«      j                  «       dk(  rt        j                  j	                  |«      n|Šd}ˆfd„|D «       }t        t        j                  d„ |D «       «      «      S # t        $ r g cY S w xY w)Nr  )zmingw64/binzmingw32/binzusr/local/binzusr/binr  c              3   ó|   •K  — | ]3  }t        j                  j                  ‰g|j                  d «      ¢­Ž –— Œ5 y­w)rR   N)r`   ra   r  Úsplit)r¯   Úsubr=   s     €r$   r±   z-_compute_git_bash_bin_dirs.<locals>.<genexpr>  s+   øè ø€ Ò@°CŒB�G‰G�L‰L˜Ð/ §	¡	¨#£Ö/Ñ@ùs   ƒ9<c              3   ó`   K  — | ]&  }t         j                  j                  |«      sŒ#|–— Œ( y ­wr©   )r`   ra   rg   )r¯   Úds     r$   r±   z-_compute_git_bash_bin_dirs.<locals>.<genexpr>  s   è ø€ ÒB A´·±·±¸qÕ1AœaÑBùr$  )
r-  r#   r`   ra   rˆ   Úbasenamerr   r-   rå   r  )r  r‹   ÚsubsÚdirsr=   s       @r$   r0  r0    s£   ø€ ðÜ‹|ˆô �W‰W�_‰_œRŸW™WŸ_™_¨TÓ2Ó3€FÜ&(§g¡g×&6Ñ&6°vÓ&>×&DÑ&DÓ&FÈ%Ò&OŒ2�7‰7�?‰?˜6Ô"ÐU[€DØL€DÛ@¸4Ô@€DÜ”—‘ÑB¨ÔBÓBÓCÐCøô ò ØŠ	ðús   ƒ
C ÃCÃCÚexisting_pathr:  c                 óê   — | j                  t        j                  «      D �cg c]  }|sŒ|‘Œ	 }}|D �cg c]	  }||vsŒ|‘Œ }}|r#t        j                  j                  g |¢|¢«      S | S c c}w c c}w )z”Prepend *dirs* missing from *existing_path* (``os.pathsep``); an already-listed
    dir keeps its position; unchanged input when nothing is missing.)r4  r`   Úpathsepr  )r;  r:  Úer?   r7  Úmissings         r$   Ú_prepend_missing_path_entriesr@    sp   € ð (×-Ñ-¬b¯j©jÓ9Ö?�QºQŠqÐ?€GÐ?ØÖ3�Q !¨7Ò"2ŠqÐ3€GÐ3Ù4;Œ2�:‰:�?‰?Ð/˜WÐ/ wÐ/Ó0ÐNÀÐNùò @ùÚ3s   ¢A+ªA+´	A0¾A0c                 ó*   — t        | t        «       «      S )z|Prepend Git Bash's binary dirs if missing (no-op off Windows), so the
    non-login ``bash -c`` fallback can find coreutils.)r@  r1  )r;  s    r$   Ú_prepend_git_bash_dirsrB  #  s   € ô )¨Ô8JÓ8LÓMÐMr^   >   ÚshÚkshÚzshr  ÚdashÚmkshc                  ó(  — t         rdnt        j                  j                  d«      } | r`t        j                  j                  | «      rAt        j                  | t        j                  «      rt        | «      j                  t        v r| S t        «       S )u<  User's login shell for background spawning: ``$SHELL`` on POSIX when it is an
    executable sh-family shell, else ``_find_bash``. macOS's system bash 3.2 under
    ``-l`` with stdin ``/dev/null`` sources ``~/.bash_profile``, which often
    ``exec /bin/zsh -l`` and drops ``-c`` â€” the command silently never runs.rQ   r%  )rV   r`   rØ   r6   ra   r  r|   r}   r   r4   Ú_SPAWN_COMPATIBLE_SHELLSr-  )Ú
user_shells    r$   Ú_find_shellrK  0  s_   € õ
 #‘¬¯
©
¯©°wÓ(?€JÙ”r—w‘w—~‘~ jÔ1´b·i±iÀ
ÌBÏGÉGÔ6TÜ�ZÓ ×%Ñ%Ô)AÑAØÐÜ‹<Ðr^   za/opt/homebrew/bin:/opt/homebrew/sbin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/binzstr | None | objectÚ_HERMES_BIN_DIRc                  óš  — t         t        urt         S t        j                  d«      } t        j
                  rt        j
                  d   nd}t        j                  j                  |«      j                  «       }t        j                  r-t        j                  j                  t        j                  «      nd}t        rdnd}| r t        j                  j                  | «      }n·t        j                  j                  |«      rU|dk(  s|j                  d«      r?t        j                  j                  |«      r t        j                  j                  |«      }nC|r?t        j                  j                  t        j                  j!                  ||«      «      r|nd}|r't        j                  j#                  |«      r|a t         S da t         S )a<  Directory holding the ``hermes`` console-script, or None (cached). A gateway
    launched by systemd/cron/a desktop launcher lacks the install dir on PATH and bare
    ``hermes`` exits 127. Order: ``which``; absolute ``sys.argv[0]`` naming a real
    hermes executable; ``sys.executable``'s dir if it holds the shim.r  r   rQ   z
hermes.exezhermes.N)rL  Ú	_SENTINELr:   r  ÚsysÚargvr`   ra   r8  rr   Ú
executablerˆ   rV   re   rµ   r  r  rg   )r  Úargv0rã   Úexe_dirÚshimrk   s         r$   Ú_resolve_hermes_bin_dirrU  H  s&  € ô œiÑ'ÜÐÜ�L‰L˜Ó"€EÜŸ8š8ŒC�H‰H�QŠK¨€EÜ�7‰7×Ñ˜EÓ"×(Ñ(Ó*€DÜ14·²Œb�g‰g�o‰oœcŸn™nÔ-ÀR€GÝ&‰<¨H€DÙÜ—G‘G—O‘O EÓ*‰	Ü
�'‰'�-‰-˜Ô
 D¨HÒ$4¸¿¹È	Ô8RÜ—‘—‘˜uÔ%Ü—G‘G—O‘O EÓ*‰	á&¬2¯7©7¯>©>¼"¿'¹'¿,¹,ÀwÐPTÓ:UÔ+V‘GÐ\`ˆ	Ù#,´·±·±¸yÔ1I�i€OÜÐð PT€OÜÐr^   c                 ó@   — t        «       }t        | |r|g«      S g «      S )z?Prepend the hermes install dir to ``existing_path`` if missing.)rU  r@  )r;  Úbin_dirs     r$   rÇ   rÇ   `  s$   € ä%Ó'€GÜ(¨ÁW¸¸	ÓUÐUÐRTÓUÐUr^   c                  ó¸   — 	 ddl m} m} g  |«       ¢ | «       dz  ‘­D �cg c]  }|j                  «       sŒt	        |«      ‘Œ  c}S c c}w # t
        $ r g cY S w xY w)zÒExisting Hermes-managed runtime dirs: ``$HERMES_HOME/node`` (+``/bin``) and
    ``$HERMES_HOME/bin`` (managed ``uv``). Per call, not cached: home is
    profile-scoped and a managed tree can appear mid-process.r   )r   Úiter_hermes_node_dirsr  )r"   r   rY  r9   rš   r#   )r   rY  r7  s      r$   Ú_managed_runtime_path_entriesrZ  f  sX   € ðßKØ UÑ"7Ó"9Ð U¹?Ó;LÈuÑ;TÑ UÖd˜1ÐYZ×YaÑYaÕYc”�A•ÒdÐdùÒdøÜò ØŠ	ðús'   ‚A  A¶AÁA ÁA ÁAÁAc                  ó–   — t        j                  «       dz  dz  } 	 | j                  «       rt        | «      gS g S # t        $ r g cY S w xY w)u>  ``~/.local/bin`` when it exists â€” the pip --user / pipx / uv-tool install
    target. A backend launched by a non-interactive SSH session, systemd or a GUI
    launcher inherits a PATH without it (only the login shell adds it), so CLIs
    installed there were ``command not found`` from the terminal tool (#111778).z.localr  )r   Úhomer9   rš   r/   )Ú	local_bins    r$   Ú_user_local_bin_entriesr^  q  sQ   € ô
 —	‘	“˜hÑ&¨Ñ.€IðØ#,×#3Ñ#3Ô#5”�I“ÐÐ=¸2Ð=øÜò ð Š	ð	ús   œ: ¸: ºAÁAc                 ó$  — t         r| S t        j                  d„ | j                  d«      D «       «      }|j	                  t        j                  g t
        j                  d«      ¢t        «       ¢t        «       ¢«      «       dj                  |«      S )aK  Normalised POSIX PATH with missing sane entries appended: empty entries
    dropped (shells read them as cwd), duplicates collapsed (first wins), then
    missing ``_SANE_PATH`` / managed-runtime / ``~/.local/bin`` dirs appended so
    user entries keep precedence. Windows is a no-op passthrough (native ``;``
    PATH untouched).c              3   ó&   K  — | ]	  }|sŒ|–— Œ y ­wr©   rƒ   )r¯   Úentrys     r$   r±   z4_append_missing_sane_path_entries.<locals>.<genexpr>‰  s   è ø€ ÒQ eÊ5œEÑQùs   ‚ŠrT   )	rV   rå   r  r4  rÅ   Ú
_SANE_PATHrZ  r^  r  )r;  Úordereds     r$   Ú!_append_missing_sane_path_entriesrd  €  s€   € õ ØÐä�m‰mÑQ¨}×/BÑ/BÀ3Ó/GÔQÓQ€GØ‡N�N”4—=‘=ð ">¤:×#3Ñ#3°CÓ#8ð ">Ô;XÓ;Zð ">Ü#:Ó#<ð">ó ?ô @à�8‰8�GÓÐr^   c                 óZ   — t         r%| j                  dd«       | j                  dd«       yy)u‹  Disable MSYS argument path conversion (``/FO`` -> ``C:/.../git/FO`` breaks
    tasklist/schtasks/wmic/``cmd /c``). Git for Windows honors ``MSYS_NO_PATHCONV``;
    MSYS2/Cygwin bash honor ``MSYS2_ARG_CONV_EXCL`` â€” set both; users can override.

    Git Bash rewrites arguments that look like Unix paths (``/FO``, ``/TN``, ``/Create``) into
    ``C:/.../git/FO``-style paths, which breaks native Windows commands such as ``tasklist``, ``schtasks``,
    and ``wmic``. Hermes runs terminal commands through bash on Windows, so set the standard MSYS opt-out by
    default. Refs #56700.
    MSYS2-proper and Cygwin bash (which ``_find_bash`` can still return via the final ``shutil.which``
    fallback) ignore it and honor ``MSYS2_ARG_CONV_EXCL`` instead, so set both. ``*`` disables all argv
    conversion â€” the semantic equivalent of ``MSYS_NO_PATHCONV=1``. Also fixes ``cmd /c`` mangling (#56147).
    ÚMSYS_NO_PATHCONVrÖ   ÚMSYS2_ARG_CONV_EXCLÚ*N)rV   rÚ   ©rŽ   s    r$   r¾   r¾   �  s*   € õ Ø�‰Ð)¨3Ô/Ø�‰Ð,¨cÕ2ð r^   Úrun_envc                 ó8   — t         rt        d„ | D «       d«      S dS )z‚PATH env key to update without altering Windows casing (``Path`` vs ``PATH``);
    None when a Windows env has no PATH key at all.c              3   óH   K  — | ]  }|j                  «       d k(  sŒ|–— Œ y­w)ÚPATHNr­   r®   s     r$   r±   z _path_env_key.<locals>.<genexpr>¤  s   è ø€ Ò;�q q§w¡w£y°FÓ':”Ñ;ùs   ‚"›"Nrm  )rV   r*  )rj  s    r$   rÆ   rÆ   ¡  s!   € õ GRŒ4Ñ;˜GÔ;¸TÓBÐ]ÐW]Ð]r^   c                 ó–   — t        t        t        t        j                  j                  «       «      | z  «      dfgt        «       d„ «      S )ae  Build a run environment with a sane PATH and provider-var stripping. The process env is
    the LAUNCH profile's; under a routed home override its ``.env`` residue is dropped first
    (``strip_launch_profile_env``, a no-op for the launch profile) so the backend's own ``env``
    and the served profile's declared passthrough names are what the child sees.Tc                 ó*   — t        t        | «      «      S r©   )rB  rd  rÏ   s    r$   r„   z_make_run_env.<locals>.<lambda>­  s   € Ô#9Ô:[Ð\]Ó:^Ó#_€ r^   )rÊ   rå   ræ   r`   rØ   rÙ   r´   ri  s    r$   Ú_make_run_envrp  §  sB   € ô
 œ4Ô 8¼¿¹¿¹Ó9JÓ KÈcÑ QÓRÐTXÐYÐZÔ\eÓ\gÙ_óað ar^   rP   Ú_hermes_repo_root.Ú_hermes_repo_root_aliasesÚbase_prefixÚreal_prefixÚ_in_venvÚ_hermes_site_packagesc                  ó8  — 	 ddl m}   | «       xs i j                  d«      xs i }|j                  d«      xs g }t        |t        «      sg }|D �cg c]  }|sŒt        |«      ‘Œ c}t        |j                  dd«      «      fS c c}w # t        $ r g dfcY S w xY w)zx(shell_init_files, auto_source_bashrc) from config.yaml; defaults on any
    failure so terminal execution never breaks.r   )Úload_configr!   Úshell_init_filesÚauto_source_bashrcT)rü   rx  r6   Ú
isinstancer-   rš   Úboolr#   )rx  Úterminal_cfgÚfilesrB   s       r$   Ú _read_terminal_shell_init_configr  ¿  s–   € ðÝ1Ù#›Ò+¨×0Ñ0°Ó<ÒBÀˆØ× Ñ Ð!3Ó4Ò:¸ˆÜ˜%¤Ô&ØˆEØ %Ö+˜1ª”�A•Ò+¬T°,×2BÑ2BÐCWÐY]Ó2^Ó-_Ð_Ð_ùÒ+øÜò Ø�4ˆxŠðús*   ‚AB	 ÁBÁBÁ&B	 ÂB	 Â	BÂBc                  óR  — t        «       \  } }| xs |r
t        sg d¢ng }g }|D ]q  }	 t        j                  j	                  t        j                  j                  |«      «      }|r0t        j                  j                  |«      r|j                  |«       Œs |S # t        $ r Y Œ�w xY w)an  Files to source before the login-shell snapshot (``~``/``${VAR}`` expanded,
    missing dropped). ``auto_source_bashrc`` applies only without an explicit list:
    ~/.profile and ~/.bash_profile first (no interactivity guard; where
    n/nvm/asdf/pyenv add PATH), ~/.bashrc last (Debian's returns early when
    non-interactive, but guard-less bashrcs keep working).)z
~/.profilez~/.bash_profilez	~/.bashrc)	r  rV   r`   ra   Ú
expandvarsrb   r  r  r#   )ÚexplicitÚauto_bashrcr  Úresolvedr  ra   s         r$   Ú_resolve_shell_init_filesr…  Í  s£   € ô =Ó>Ñ€HˆkØò JÙ!,µ[ó MØFHð à€HØò ˆð	Ü—7‘7×%Ñ%¤b§g¡g×&8Ñ&8¸Ó&=Ó>ˆDÙœŸ™Ÿ™ tÔ,Ø—‘ Ô%øð	ð €Oøô ò 	Ùð	ús   ¨A.BÂ	B&Â%B&Ú
cmd_stringr~  c                 ó˜   — |s| S |D �cg c]  }|j                  dd«      ‘Œ }}dgd„ |D «       ¢}dj                  |«      dz   | z   S c c}w )zŸPrepend guarded, silent ``source <file>`` lines: ``set +e`` keeps going on
    errors, ``2>/dev/null`` hides noisy prompts, ``|| true`` neutralises the status.ú'z'\''zset +ec              3   ó.   K  — | ]  }d |› d|› d�–— Œ y­w)z[ -r 'z
' ] && . 'z' 2>/dev/null || trueNrƒ   r#  s     r$   r±   z&_prepend_shell_init.<locals>.<genexpr>ç  s    è ø€ ÒXÈa˜V A 3 j°°Ð3HÔIÑXùs   ‚r'  )rX   r  )r†  r~  rÐ   ÚsafeÚpreludes        r$   Ú_prepend_shell_initrŒ  á  s]   € ñ ØÐØ-2Ö3¨ˆA�I‰I�c˜7Õ#Ð3€DÐ3ØÐYÑXÐSWÔXÐY€GØ�9‰9�WÓ Ñ$ zÑ1Ð1ùò 4s   ‰AÚpgidÚtimeoutc                 ó.  — t        j                  «       |z   }	 	 | j                  «        	 t	        j
                  |d«       t        j                  «       |k\  ryt        j                  d«       ŒV# t        $ r Y ŒPw xY w# t        $ r Y yt        $ r Y ŒRw xY w)zËWait until the process group is gone, reaping the wrapper as we go (a dead
    but unreaped group leader still makes ``killpg(pgid, 0)`` succeed).
    POSIX-only; callers are behind the _IS_WINDOWS gate.Tr   Fgš™™™™™©?)	r,   Ú	monotonicÚpollr#   r`   ÚkillpgÚProcessLookupErrorÚPermissionErrorÚsleep)Úprocr�  rŽ  Údeadlines       r$   Ú_wait_for_group_exitr˜  ì  s�   € ô �~‰~Ó 'Ñ)€HØ
ð	Ø�I‰IŒKð	Ü�I‰I�d˜AÔô
 �>‰>Ó˜xÒ'ØÜ�
‰
�4Ôð øô ò 	Ùð	ûô "ò 	ÙÜò 	Ùð	ús(   šA/ «A> Á/	A;Á:A;Á>	BÂ	BÂBÚdescendantsc                 óÜ   — | D ]I  }	 |j                  «       sŒ	 t        j                  |j                  «      |k(  rŒ9	 |j                  «        ŒK y# t        $ r Y Œw xY w# t        $ r Y Œgw xY w)uñ   SIGKILL snapshotted survivors that escaped the process group via ``setsid``
    â€” after TERMâ†’KILL so in-group members keep their grace; psutil's identity-aware
    Process skips recycled PIDs. POSIX-only (see _IS_WINDOWS gate in caller).N)Ú
is_runningr`   ÚgetpgidÚpidr/   Úkillr#   )r™  r�  Úchilds      r$   Ú_sweep_escaped_descendantsr     s{   € ð ò ˆð
	Ø×#Ñ#Ô%ØðÜ—:‘:˜eŸi™iÓ(¨DÒ0Øð 1ð �J‰J�Lñøô ò Ùðûô ò 	Ùð	ús3   ‡A™"A¼AÁ	AÁAÁAÁAÁ	A+Á*A+c                 ó  — 	 t        j                  | j                  «      }	 ddl}|j                  | j                  «      j                  d¬«      }|t        j                  «       k(  rt        | |«       n¦	 t        j                  |t        j                  «       t        | |d«      stt        j                  |t        j                  «       t        | |d«       t!        j"                  t$        j&                  t(        «      5  | j+                  d¬	«       ddd«       t/        ||«       y# t        $ r t	        | dd«      x}€‚ Y �Œ#w xY w# t        $ r g }Y �Œw xY w# 1 sw Y   ŒHxY w# t        $ r Y ŒVt,        $ r t        | |«       Y Œlw xY w)
u6  TERM the group, wait, KILL, then sweep setsid escapees. Descendants are
    snapshotted BEFORE the first signal â€” once the wrapper dies they reparent to
    init â€” and we wait on the group, not the wrapper, which can exit before
    grandchildren under load. POSIX-only (_IS_WINDOWS handled by the caller).Ú_hermes_pgidNr   T)Ú	recursiveg      ð?ç       @gš™™™™™É?©rŽ  )r`   rœ  r�  r“  r‡   ÚpsutilÚProcessÚchildrenr#   ÚgetpgrpÚ_kill_known_pidsr’  ÚsignalÚSIGTERMr˜  ÚSIGKILLÚ
contextlibÚsuppressÚ
subprocessÚTimeoutExpiredr/   Úwaitr”  r   )r–  r�  r¦  r™  s       r$   Ú_kill_process_group_posixr³    sK  € ð
Ü�z‰z˜$Ÿ(™(Ó#ˆðÛØ—n‘n T§X¡XÓ.×7Ñ7À$Ð7ÓGˆð Œr�z‰z‹|Òô 	˜˜{Õ+ð	0Ü�I‰I�dœFŸN™NÔ+Ü'¨¨d°CÔ8Ü—	‘	˜$¤§¡Ô/Ü$ T¨4°Ô5Ü×(Ñ(¬×)BÑ)BÄGÓLñ +Ø—I‘I c�IÔ*÷+ô ˜{¨DÕ1øô; ò Ü˜D .°$Ó7Ð7ˆDÐ@Øò Aðûô ò Ø‹ðú÷+ð +ûä!ò 	ÙÜò 	0ô ˜T ;Ö/ð	0úsS   ‚D( ¢/E Á6B
E& Ä EÄE& Ä(EÅEÅEÅEÅE#ÅE& Å&	FÅ1FÆFc                 ó–   — | g|¢­D ]4  }t        j                  t        «      5  |j                  «        ddd«       Œ6 y# 1 sw Y   ŒAxY w)zPKILL the wrapper and its snapshotted descendants by PID (idempotent on zombies).N)r®  r¯  r#   rž  )r–  r™  rò   s      r$   rª  rª  :  sJ   € àÐ&˜+Ñ&ò ˆÜ× Ñ ¤Ó+ñ 	Ø�K‰KŒM÷	ð 	ñ÷	ð 	ús	   £?¿A	c                 ó<  — 	 ddl m}m}  || j                  d || j                  «      ¬«       t        j                  t        j                  t        «      5  | j                  d¬«       ddd«       y# t        $ r | j                  «        Y Œ_w xY w# 1 sw Y   yxY w)zLIdentity-checked terminate (start time guards against PID reuse), else kill.r   )Úget_process_start_timeÚterminate_pidT)ÚforceÚexpected_start_timer¤  r¥  N)Úgateway.statusr¶  r·  r�  r#   rž  r®  r¯  r°  r±  r/   r²  )r–  r¶  r·  s      r$   Ú_kill_process_windowsr»  A  s�   € ðßHÙ�d—h‘h dÑ@VÐW[×W_ÑW_Ó@`Õaô 
×	Ñ	œZ×6Ñ6¼Ó	@ñ Ø�	‰	˜#ˆ	Ô÷ð øô ò Ø�	‰	Žðú÷ð ús   ‚-A3 ÁBÁ3BÂBÂBc                   óî   ‡ — e Zd ZdZdZdZdZdeedf   fd„Z	ddede
d	efˆ fd
„Zdefd„Zededefd„«       Zdedefd„Zdd„Zddddœdedede
dedz  dej(                  f
d„Zd„ Zdefˆ fd„Zd„ Zˆ xZS )ÚLocalEnvironmentz©Run commands directly on the host: every execute() spawns a fresh bash;
    the session snapshot preserves env vars across calls; CWD persists via the
    stdout marker.Tr   .c                 ó„   — t        t        j                  | j                  z  «      }t	        t        d„ |D «       «      «      S )a™  First-party ``BUZZ_*`` names present in the env, excluded from the shared
        session snapshot. env_passthrough can never list them (it refuses blocklisted
        names), so under a multiplexed gateway profile A's BUZZ_PRIVATE_KEY would land
        in the snapshot and be sourced by profile B. Prefix-only and monotonic on
        purpose: conservative even when the context-gated carve-out is inactive.c              3   óV   K  — | ]!  }t        |t        «      rt        |«      r|–— Œ# y ­wr©   )r{  rš   r   )r¯   r4   s     r$   r±   zPLocalEnvironment._additional_profile_scoped_passthrough_names.<locals>.<genexpr>^  s,   è ø€ ò UØÜ˜$¤Ô$Ô)MÈdÔ)Sô ñUùs   ‚'))rå   r`   rØ   rŽ   ÚtupleÚsorted)ÚselfÚmergeds     r$   Ú,_additional_profile_scoped_passthrough_namesz=LocalEnvironment._additional_profile_scoped_passthrough_namesW  sA   € ô ”b—j‘j 4§8¡8Ñ+Ó,ˆÜ”Vñ UØ#ôUó Uó Vð 	Vr^   NrN   rŽ  rŽ   c                 ó\   •— t         ‰| �  t        |«      ||¬«       | j                  «        y )N)rN   rŽ  rŽ   )ÚsuperÚ__init__ro   Úinit_session)rÂ  rN   rŽ  rŽ   Ú	__class__s       €r$   rÇ  zLocalEnvironment.__init__b  s*   ø€ Ü‰ÑÔ7¸Ó<ÀgÐSVÐÔWØ×ÑÕr^   c                 óÂ  — t         rdt        «       xs  t        t        j                  «       «      dz  }|j                  dd¬«       t        «        t        |«      j                  dd«      S dt        dt        fd„}d	D ]�  }| j                  j                  |«      xs t        j                  j                  |«      }|sŒB|j                  d«      sŒT|d
k7  s t        j                  j                  |«      sŒy ||«      c S  	 t        «       }|j                  dd¬«       t        |«      }|j                  d«      rGt        j                   |t        j"                  t        j$                  z  «      rt        «         ||«      S t        j                  «       } ||j                  d«      r|«      S t        j                  j)                  |«      «      S # t&        $ r Y Œ[w xY w)a  Shell-safe writable temp dir. Precedence: ``TERMINAL_TEMP_DIR``, TMPDIR/TMP/TEMP
        (Termux has no system temp dir), ``HERMES_HOME/cache/terminal`` (real storage: a
        tmpfs system temp dir fills under Hermes load; pruned by ``cleanup_terminal_temp_cache``),
        ``tempfile.gettempdir()``; backend env before process env so terminal.env
        overrides work. Windows: ``%TEMP%`` often has spaces that break unquoted bash,
        so always the HERMES_HOME cache dir with forward slashes (bash- and Python-valid).Úhermes_terminalT)ÚparentsÚexist_okrS   rR   rÐ   r   c                 ó,   — | j                  d«      xs dS )NrR   )ÚrstriprÏ   s    r$   Ú_posixz-LocalEnvironment.get_temp_dir.<locals>._posixs  s   € Ø—8‘8˜C“=Ò' CÐ'r^   )ÚTERMINAL_TEMP_DIRÚTMPDIRÚTMPÚTEMPrÑ  )rV   r%   r   r‰   rŠ   ÚmkdirrM   rš   rX   rŽ   r6   r`   rØ   rµ   ra   rg   r|   ÚW_OKr}   r#   rf   )rÂ  Ú	cache_dirrÐ  Úenv_varrk   r„  Úfallbacks          r$   Úget_temp_dirzLocalEnvironment.get_temp_dirf  s†  € õ Ü3Ó5ò LÜ ¤×!4Ñ!4Ó!6Ó7Ð:KÑKð à�O‰O D°4ˆOÔ8Ü%Ô'Ü�y“>×)Ñ)¨$°Ó4Ð4ð	(”cð 	(œcó 	(àEò 	)ˆGØŸ™Ÿ™ WÓ-ÒH´·±·±ÀÓ1HˆIÚ˜Y×1Ñ1°#Õ6ØÐ2Ò2´b·g±g·m±mÀIÕ6NÙ˜iÓ(Ò(ð		)ð
	Ü2Ó4ˆIØ�O‰O D°4ˆOÔ8Ü˜9“~ˆHØ×"Ñ" 3Ô'¬B¯I©I°hÄÇÁÌ"Ï'É'Ñ@QÔ,RÜ)Ô+Ù˜hÓ'Ð'ô ×&Ñ&Ó(ˆÙ (×"5Ñ"5°cÔ":�hÓZÐZÄÇÁÇÁÐPXÓ@YÓZÐZøô	 ò 	Ùð	ús   ÄA?G Ç	GÇGc                 ó>   — t        j                  t        | «      «      S )z@Use native paths for Python, but Git Bash-friendly paths for cd.)r   Ú_quote_cwd_for_cdrs   )rN   s    r$   rÜ  z"LocalEnvironment._quote_cwd_for_cd‡  s   € ô ×0Ñ0Ô1FÀsÓ1KÓLÐLr^   ra   c                 ó   — t        |«      S )z?Rewrite native/mixed Windows paths before quoting for Git Bash.)rz   )rÂ  ra   s     r$   Ú_quote_shell_pathz"LocalEnvironment._quote_shell_pathŒ  s   € ä Ó%Ð%r^   c                 óÎ   — t        | j                  «      }|| j                  k(  ry|t        | j                  «      k7  r!t        j	                  d| j                  |«       || _        y)u  Swap ``self.cwd`` for a usable directory if it vanished or is inaccessible
        (e.g. a command ``rm -rf``'d its own cwd) â€” otherwise Popen raises before bash
        starts and every subsequent call fails. A benign MSYSâ†’Windows normalization
        is not warned about.NzaLocalEnvironment cwd %r is missing on disk; falling back to %r so terminal commands keep working.)r�   rN   r]   rJ   r†   )rÂ  Úsafe_cwds     r$   Ú_recover_cwdzLocalEnvironment._recover_cwd�  sW   € ô % T§X¡XÓ.ˆØ�t—x‘xÒØØÔ,¨T¯X©XÓ6Ò6Ü�N‰NðHà—‘˜(ô$ð ˆ�r^   Féx   )ÚloginrŽ  Ú
stdin_datar†  rã  rä  c                ód  — t        «       }|rt        |t        «       «      }|g|rdgng ¢d‘|‘}| j                  «        t	        j
                  |fdt        | j                  «      ddt        j                  t        j                  |�t        j                  nt        j                  d| j                  dœ	t        rdt        «       ini ¤Ž}t        sFt        j                  t         «      5  t#        j$                  |j&                  «      |_        d d d «       |�t+        ||«       |S # 1 sw Y   ŒxY w)Nz-lz-cTzutf-8rX   )	ÚtextrŽ   ÚencodingÚerrorsÚstdoutÚstderrÚstdinÚstart_new_sessionrN   Úcreationflags)r-  rŒ  r…  rá  r°  ÚPopenrp  rŽ   ÚPIPEÚSTDOUTÚDEVNULLrN   rV   r	   r®  r¯  r“  r`   rœ  r�  r¢  r   )rÂ  r†  rã  rŽ  rä  r  Úargsr–  s           r$   Ú	_run_bashzLocalEnvironment._run_bash¤  s  € ä‹|ˆñ Ü,¨ZÔ9RÓ9TÓUˆJØÐC¡%˜™¨RÐC°$ÐC¸
ÐCˆØ×ÑÔÜ×ÑØðPØ¤¨t¯x©xÓ!8À7ÐS\Ü—?‘?¬:×+<Ñ+<Ø%/Ð%;”*—/’/Ä×ASÑASØ"¨¯©ñ	Põ
 ;F�Ô!3Ó!5Ñ6È2ñPˆõ Ü×$Ñ$Ô%7Ó8ñ 9Ü$&§J¡J¨t¯x©xÓ$8�Ô!÷9àÐ!Ü˜˜jÔ)Øˆ÷	9ð 9ús   Ã)%D&Ä&D/c                 óÐ   — 	 t        rt        nt        |«       y# t        $ rB t	        j
                  t        «      5  |j                  «        ddd«       Y y# 1 sw Y   Y yxY ww xY w)z-Kill the entire process group (all children).N)rV   r»  r³  r/   r®  r¯  r#   rž  )rÂ  r–  s     r$   Ú_kill_processzLocalEnvironment._kill_processº  sQ   € ð	Ý&1Õ"Ô7PÐRVÕWøÜò 	Ü×$Ñ$¤YÓ/ñ Ø—	‘	”÷÷ ó úð	ús&   ‚ š"A%¼AÁA%ÁA!	ÁA%Á!A%Úresultc                 ó8  •— | j                   }t        ‰| �	  |«       | j                   |k7  rot        | j                   «      }|r,t        j
                  j                  |«      r|| _         ||d<   y|| _         |j                  dd«       |j                  dd«       yy)u/  Base semantics plus: Git Bash ``pwd -P`` emits MSYS form on Windows â€”
        normalize to native and require the dir to exist, else ``_run_bash`` would
        warn every command. A stale path rolls back to the previous cwd, which this
        command did not observe, so ``cwd_observed`` is dropped.rN   Úcwd_observedN)rN   rÆ  Ú_extract_cwd_from_outputr]   r`   ra   rg   r›   )rÂ  rö  Úprev_cwdÚ
normalizedrÉ  s       €r$   rù  z)LocalEnvironment._extract_cwd_from_outputÂ  s   ø€ ð
 —8‘8ˆÜ‰Ñ(¨Ô0Ø�8‰8�xÒÜ.¨t¯x©xÓ8ˆJÙœbŸg™gŸm™m¨JÔ7Ø%�”Ø *��u’à#�”Ø—
‘
˜>¨4Ô0Ø—
‘
˜5 $Õ'ð  r^   c                 ó2  — ddl }	 |j                  | j                  › d�«      }| j                  | j                  g|¢­D ]9  }t	        j
                  t        «      5  t        j                  |«       ddd«       Œ; y# t        $ r g }Y Œew xY w# 1 sw Y   ŒWxY w)z‹Clean up temp files, including orphaned atomic-write snapshots
        (``snap.tmp.<bashpid>``) a failed/interrupted mv could leave behind.r   Nz.tmp.*)	ÚglobÚ_snapshot_pathr#   Ú	_cwd_filer®  r¯  r/   r`   r<   )rÂ  rý  ÚstalerB   s       r$   ÚcleanupzLocalEnvironment.cleanupÓ  s–   € ó 	ð	Ø—I‘I ×!4Ñ!4Ð 5°VÐ<Ó=ˆEð ×%Ñ% t§~¡~Ð>¸Ñ>ò 	ˆAÜ×$Ñ$¤WÓ-ñ Ü—	‘	˜!”÷ð ñ	øô ò 	ØŠEð	ú÷ð ús   †A< ÁBÁ<B
Â	B
ÂB	)rQ   é<   N©r   N)Ú__name__Ú
__module__Ú__qualname__Ú__doc__Ú_sudo_nopasswd_probe_supportedÚ_profile_scoped_passthroughÚis_localrÀ  rš   rÄ  Úintrå   rÇ  rÚ  ÚstaticmethodrÜ  rÞ  rá  r|  r°  rî  ró  rõ  rù  r  Ú__classcell__)rÉ  s   @r$   r½  r½  L  sð   ø„ ñð &*Ð"Ø"&Ðð €Hð	V¸eÀCÈÀH¹oó 	Vñ˜Cð ¨sð ¸dõ ð[˜có [ðB ðM˜sð M sò Mó ðMð& cð &¨có &óð( ;@ÐPSØ+/ò Cð °4ð È#ð Ø! D™jðØ4>×4DÑ4Dóò,ð(¨tõ (ö"r^   r½  )r   zPath | Noner  r©   )€r  r®  Úloggingrd   r`   ÚplatformrW   r:   r«  r°  rO  r‰   Ú	threadingr,   Úcollections.abcr   Úpathlibr   r"   r   Útools.environments.baser   Útools.environments.base_outputr   Úhermes_cli._subprocess_compatr	   Ú#tools.environments.local_env_policyr
   r   r   r   r   r   r   r   r   Ú&tools.environments.local_gitbash_prober   r   r   r   r   Ú#tools.environments.local_pythonpathr   r   ÚsystemrV   Ú	getLoggerr  rJ   ÚTERMINAL_TEMP_MAX_IDLE_HOURSÚLockrH   rI   Úcompiler2   r%   Úfloatr  rF   rM   rš   r]   ro   rs   rv   rz   r|  r~   r�   rå   r”   rŸ   r´   rº   rÀ   rÊ   rÑ   rÛ   r×   rç   rô   rñ   ræ   r-   r   r-  r.  Ú__annotations__r1  r0  r@  rB  rI  rK  rb  ÚobjectrN  rL  rU  rÇ   rZ  r^  rd  r¾   rÆ   rp  Ú__file__rö   rÌ  rq  Úabsoluterr  rÀ  r‡   ÚprefixÚhasattrru  rv  r  r…  rŒ  r˜  r   r³  rª  r»  r½  rƒ   r^   r$   ú<module>r%     s¾  ðÚ Kã Û Û Û 	Û Û 	Û Û Û Û 
Û Û Û Ý #Ý å 4Ý 3Ý 6Ý <÷c÷ cõ c÷=õ =÷Yð ˆh�o‰oÓ 9Ñ,€à	ˆ×	Ñ	˜8Ó	$€ð  "Ð Ø*˜IŸN™NÓ,Ð Ø"Ð ð ˆr�z‰zÐIÓJ€óð 8Tñ '¨uð 'ÐX[ó 'óT
<ð5˜sð 5 só 5ð Cð ¨Có ð.+˜sð + só +ð\˜#ð \ #ó \ð.˜3ð . 3ó .ð<�cð <˜dó <ð+˜3ð + 3ó +ðB#˜Tð # dó #ð$ Tð $¨dó $ñ* (›kòØ�3˜�8ÑðØ#'ðØ:>ðàðà.2óðB	/˜Tð 	/ dó 	/ð$ yð $¸tó $ñ,I t¨d¡{ð I¸tÀd¹{ð IÐVZó Ið :?ò 	$°$ð 	$À4ÈÈSÈÁ>ó 	$ð˜Dð ¸$ð À4ó ð (,ð/ØMQØÀDØ!&ò/Ø
$ð/ØFJð/àð/à'Að/ð ð/ð ,0°°S°©>ó/ð4 (,ð)ØSWØ %ò)Ø
$ð)Ø=Pð)àð)ð 
ˆ#ˆsˆ(�^ó)ðX ð °$ó ñ' $ð 'Ð5Hð 'ÐTXó 'ðD \ð °d¸3±ió ð8B�Có Bð< 04Ð Ð,Ó 3ð$˜D ™Ió $ð	D D¨¡Ió 	DðO°ð O¸DÀ¹Ið OÈ#ó OðN¨#ð N°#ó Nñ %Ò%QÓRÐ ð	�Só 	ðM€
ñ
 ‹H€	Ø)2€Ð&Ó 2ð  t¡ó ð0V¨3ð V°3ó Vð t¨C¡yó ð  c¡ó ð°Sð ¸Só ð3¨tð 3¸ó 3ð$^˜4ð ^ C¨$¡Jó ^ða�tð a ó añ ˜x›.×0Ñ0Ó2×:Ñ:¸1Ñ=Ð �4Ó =Ù.MØ‘t˜H“~×.Ñ.Ó0×8Ñ8¸Ñ;Ñ=TÓ=Vó/XÐ ˜5  s Ñ+ó Xá˜#˜}¨c¯j©jÓ9¸S¿Z¹ZÑGò 1Ù˜S -Ó0ð 	ˆ$ó 2à+/Ð �t˜D‘z DÑ(Ó /ð¨%°°S±	¸4°Ñ*@ó ð 4¨¡9ó ð(2 Cð 2°°S±	ð 2¸có 2ð Sð °5ð ¸Tó ð*¨Dð ¸ð Àó ó$$2óNóôR�õ Rr^   