Ë
    ãß²j²#  ã            
       ó¶  — d Z ddlZddlZddlZddlmZmZ  eh d£«      Z eh d£«      Z	dZ
dedefd	„Zdd
edefd„Zdd
edefd„Zdd
ededz  fd„Zdeez  ez  defd„Zdedz  dedz  fd„Zdedz  fd„Zdd
ededz  fd„Zdd
ededz  fd„Zdededefd„Zdededeez  fd„Z	 dddœd
ededz  deez  fd„Zdded
edeez  fd„Zddeded
ededz  fd„Zy)a¦  Path resolution for the file tools: task-aware base dir, ``~`` expansion, workspace-divergence warning.

Core invariant: the base directory anchoring relative paths is ALWAYS absolute
and derived from the task's terminal cwd, never from the process cwd unless no
other anchor exists (a relative/sentinel ``TERMINAL_CWD`` would silently anchor
edits to the agent process cwd, e.g. the main repo during a worktree session).
é    N)ÚPathÚPurePosixPath>   ú./Ú ÚcwdÚautoú.>   ÚmodalÚdockerÚdaytonaÚsingularityÚvercel_sandbox)ÚlocalÚsshr   r   r
   r   ÚpathÚreturnc                 ó  — | rd| vr| S 	 ddl m}  |«       }|r@| dk(  s| j                  d«      r*| dk(  r|S t        j
                  j                  || dd «      S t        j
                  j                  | «      S # t        $ r d}Y Œnw xY w)ao  Expand ``~`` using the effective profile home (``get_subprocess_home``) so
    gateway/cron runs, whose process HOME may differ, agree with interactive CLI sessions.

    This mirrors ``hermes_constants.get_subprocess_home()`` so that ``~`` resolves consistently regardless
    of whether the tool runs interactively or inside a gateway-driven cron job (#48552).
    Ú~r   )Úget_subprocess_homeNz~/é   )Úhermes_constantsr   Ú	ExceptionÚ
startswithÚosr   ÚjoinÚ
expanduser)r   r   Úhomes      ú;/home/ubuntu/.hermes/hermes-agent/tools/file_tools_paths.pyÚ_expand_tilder      s‰   € ñ �3˜d‘?ØˆðÝ8á"Ó$ˆñ �˜’ §¡°Ô 5Ø˜s’{ˆtÐD¬¯©¯©°T¸4ÀÀ¸8Ó(DÐDÜ�7‰7×Ñ˜dÓ#Ð#øô	 ò ØŠðús   ŠA8 Á8BÂBÚtask_idc                 ó¢  ‡	— 	 ddl m}m}m}m} 	  || «      }|5  |j                  |«      xs |j                  | «      }ddd«       �d|j                  j                  j                  «       Š	t        ˆ	fd„t        D «       d«      }t        |dd«      }|st        |t        «      r|r|xs |S t         |«       j                  d«      xs t        j                   d«      xs d«      j                  «       S # t
        $ r | }Y Œêw xY w# 1 sw Y   ŒÈxY w# t
        $ r3 t        t        j                   d«      xs d«      j                  «       cY S w xY w)	z@Best-effort terminal backend type for path-resolution decisions.r   )Ú_active_environmentsÚ	_env_lockÚ_get_env_configÚ_resolve_container_task_idNc              3   ó,   •K  — | ]  }|‰v sŒ|–— Œ y ­w)N© )Ú.0ÚhÚnames     €r   ú	<genexpr>z._terminal_env_type_for_task.<locals>.<genexpr>8   s   øè ø€ ÒG˜q¸QÀ$ºYœÑGùs   ƒ	�Ú_hermes_backend_nameÚenv_typeÚTERMINAL_ENVr   )Útools.terminal_toolr"   r#   r$   r%   r   ÚgetÚ	__class__Ú__name__ÚlowerÚnextÚ_ENV_CLASS_NAME_HINTSÚgetattrÚ
isinstanceÚstrr   Úgetenv)
r    r"   r#   r$   r%   Úcontainer_keyÚenvÚhintÚstampedr*   s
            @r   Ú_terminal_env_type_for_taskr>   *   s;  ø€ ðA÷	Zó 	Zð	$Ù6°wÓ?ˆMð ñ 	_Ø&×*Ñ*¨=Ó9Ò^Ð=Q×=UÑ=UÐV]Ó=^ˆC÷	_àˆ?Ø—=‘=×)Ñ)×/Ñ/Ó1ˆDÜÓGÔ$9ÔGÈÓNˆDÜ˜cÐ#9¸4Ó@ˆGÙœ
 7¬CÔ0±WØ’˜wÐ&Ü‘?Ó$×(Ñ(¨Ó4Ò\¼¿	¹	À.Ó8QÒ\ÐU\Ó]×cÑcÓeÐeøô ò 	$Ø#ŠMð	$ú÷	_ð 	_ûô ò AÜ”2—9‘9˜^Ó,Ò7°Ó8×>Ñ>Ó@Ò@ðAúsQ   ƒD �C5 ˜D š%D¿A-D Â-AD Ã5DÄ D ÄDÄD ÄDÄD Ä9EÅEc                 ód   — t        | «      }	 ddlm}  ||«      S # t        $ r |t        v cY S w xY w)Nr   )Ú_is_container_backend)r>   r/   r@   r   Ú!_CONTAINER_PATH_BACKENDS_FALLBACK)r    r-   r@   s      r   Ú_uses_container_pathsrB   A   s:   € Ü*¨7Ó3€Hð=Ý=á$ XÓ.Ð.øÜò =ØÔ<Ð<Ò<ð=ús   � ›/®/c                 ó2   — t        | «      rt        | «      S dS )zMThe task's backend name when its file paths belong to a container, else None.N)rB   r>   )r    s    r   Úcontainer_backend_for_taskrD   K   s   € ä3HÈÔ3QÔ& wÓ/Ð[ÐW[Ð[ó    c                 óP   — t        t        j                  t        | «      «      «      S )z«Normalize path syntax without following host symlinks: container paths are
    meaningful inside the sandbox, and a host-side ``/workspace`` symlink must not rewrite them.)r   Ú	posixpathÚnormpathr8   )r   s    r   Ú_normalize_without_host_derefrI   P   s   € ô œ×+Ñ+¬C°«IÓ6Ó7Ð7rE   Úrawc                 óÆ   — t        | xs d«      j                  «       } | j                  «       t        v ryt	        | «      }t
        j                  j                  |«      r|S dS )zžReturn *raw* expanded when it is a non-sentinel ABSOLUTE anchor, else ``None``
    (a relative anchor is exactly the ambiguity that misroutes worktree edits).r   N)r8   Ústripr3   Ú_TERMINAL_CWD_SENTINELSr   r   r   Úisabs)rJ   Úexpandeds     r   Ú_sentinel_free_abs_cwdrP   V   sP   € ô ˆcŠi�R‹.×
Ñ
Ó
 €CØ
‡y�yƒ{Ô-Ñ-ØÜ˜SÓ!€HÜ—w‘w—}‘} XÔ.ˆ8Ð8°DÐ8rE   c                  ó6   — ddl m}  t         | «       xs d«      S )zµReturn ``$TERMINAL_CWD`` only when it names a real (absolute, non-sentinel) anchor.
    Scope-aware: under gateway multiplexing the routed profile's cwd lives in the per-turn scope.r   ©Úscope_terminal_cwdN)Úagent.runtime_cwdrS   rP   rR   s    r   Ú_configured_terminal_cwdrU   `   s   € õ 5ä!Ñ"4Ó"6Ò">¸$Ó?Ð?rE   c                 ór   — 	 ddl m}  || «      }t        |j	                  d«      «      S # t        $ r Y yw xY w)zÝReturn a registered cwd override keyed by the RAW task id, when available.

    ``terminal_tool`` collapses CWD-only overrides to the shared ``"default"``
    env, but the cwd value stays keyed by the raw session id.
    r   )Úresolve_task_overridesNr   )r/   rW   r   rP   r0   )r    rW   Ú	overridess      r   Ú_registered_task_cwd_overriderY   i   s>   € ðÝ>á*¨7Ó3ˆ	ô " )§-¡-°Ó"6Ó7Ð7øô ò Ùðús   ‚* ª	6µ6c                 óx   — 	 ddl m}  || «      }|xs t        | «      xs
 t	        «       S # t        $ r d}Y Œ(w xY w)a6  Best-effort absolute workspace root, or ``None`` when no reliable anchor exists.

    Order: (1) the session's own cwd record (per-session, so one session's
    ``cd`` never leaks into another); (2) a registered raw-keyed cwd override
    (TUI/Desktop/ACP); (3) a sentinel-free absolute ``$TERMINAL_CWD``.
    r   )Úget_session_cwdN)r/   r[   r   rY   rU   )r    r[   Úrecordeds      r   Ú_authoritative_workspace_rootr]   y   sF   € ðÝ7á" 7Ó+ˆð Ò[Ô4°WÓ=Ò[ÔAYÓA[Ð[øô ò ØŠðús   ‚+ «9¸9ÚtextÚcontainer_pathsc                 ó8   — |sddl m}  || «      } t        | «      S )z�Expand ``~``; on host backends also translate Git Bash ``/c/Users/...`` drive
    paths before Path sees them. Container/WSL Linux paths are never rewritten.r   )Ú_msys_to_windows_path)Útools.environments.localra   r   )r^   r_   ra   s      r   Ú
_host_textrc   ‰   s   € ñ ÝBá$ TÓ*ˆÜ˜ÓÐrE   c                 óÎ  — |rDt        j                  | «      s$t        j                  t         |«       «      | «      } t	        | «      S t
        j                  dk(  rOddl}|j                  | «      s |j                  t         |«       «      | «      } t        |j                  | «      «      S t        | «      }|j                  «       st         |«       «      |z  }|j                  «       S )z¬Return *text* as an absolute, normalized path, joining it onto ``base()`` when
    relative. Container: pure-posix, no host deref. Host: resolve() (win32: ntpath normpath).Úwin32r   N)rG   rN   r   r8   rI   ÚsysÚplatformÚntpathr   rH   Úis_absoluteÚresolve)r^   Úbaser_   rh   Úps        r   Ú_anchorrm   “   s§   € ñ Ü�‰˜tÔ$Ü—>‘>¤#¡d£f£+¨tÓ4ˆDÜ,¨TÓ2Ð2Ü
‡|�|�wÒÛà�|‰|˜DÔ!Ø—;‘;œs¡4£6›{¨DÓ1ˆDÜ�F—O‘O DÓ)Ó*Ð*ÜˆT‹
€AØ�=‰=Œ?Ü‘“‹L˜1ÑˆØ�9‰9‹;ÐrE   ©r_   c                ó¨   — t        | «      }|€t        | «      }t        t        |xs t	        j
                  «       |«      t        j
                  |«      S )zŽReturn the ABSOLUTE base directory for resolving relative paths:
    ``_authoritative_workspace_root``, else the process cwd as a last resort.)r]   rB   rm   rc   r   Úgetcwd)r    r_   Úroots      r   Ú_resolve_base_dirrr   ¦   sD   € ô )¨Ó1€DØÐÜ/°Ó8ˆä”:˜dÒ1¤b§i¡i£k°?ÓCÄRÇYÁYÐP_Ó`Ð`rE   Úfilepathc                 óR   ‡‡— t        ‰«      Št        t        | ‰«      ˆˆfd„‰«      S )zyResolve *filepath* against the task's absolute base directory
    (absolute inputs are returned resolved-but-unanchored).c                  ó   •— t        ‰‰ ¬«      S )Nrn   )rr   )r_   r    s   €€r   ú<lambda>z(_resolve_path_for_task.<locals>.<lambda>¶   s   ø€ Ô,¨WÀoÔV€ rE   )rB   rm   rc   )rs   r    r_   s    `@r   Ú_resolve_path_for_taskrw   ±   s-   ù€ ô ,¨GÓ4€OÜ”:˜h¨Ó8ÜVÐXgóið irE   Úresolvedc                 óz  — 	 t        t        | «      «      j                  «       ryt        |«      }|syt	        |«      rt        t        t        |«      «      «      }n"t        t        |«      «      j                  «       }|j                  |«      ryd| ›dt        |«      ›dt        |«      ›d�S # t        $ r Y yw xY w)záWarn when a RELATIVE path resolved OUTSIDE the task's workspace root (the
    edit is about to land in a different checkout than the terminal's cwd).
    ``None`` for absolute paths, an unknown root, or a path under the root.NzRelative path z resolved to z), which is OUTSIDE the active workspace (zÐ). The edit will land in a different directory than the terminal's cwd. If this is not intended (e.g. a git-worktree session writing into the main checkout), pass an absolute path under the workspace instead.)
r   r   ri   r]   rB   rI   rj   Úis_relative_tor8   r   )rs   rx   r    Úworkspace_rootrq   s        r   Ú_path_resolution_warningr|   º   s¼   € ðÜ”˜hÓ'Ó(×4Ñ4Ô6ØÜ6°wÓ?ˆÙØÜ  Ô)Ü0´´mÀNÓ6SÓ1TÓU‰Däœ nÓ5Ó6×>Ñ>Ó@ˆDØ×"Ñ" 4Ô(Øà˜X˜L¨´c¸(³mÐ5Fð G-Ü-0°«Y¨Mð :LðMð	Nøô ò Ùðús"   ‚"B. ¥B. ³AB. ÂB. Â.	B:Â9B:)Údefault)Ú__doc__r   rG   rf   Úpathlibr   r   Ú	frozensetrM   rA   r5   r8   r   r>   ÚboolrB   rD   rI   rP   rU   rY   r]   rc   rm   rr   rw   r|   r'   rE   r   ú<module>r‚      sÅ  ðñó 
Û Û 
ß 'ñ $Ò$BÓCÐ Ù$-Ò.mÓ$nÐ !àUÐ ð$˜ð $ ó $ñ(A¨ð A¸Só Añ.= 3ð =°tó =ñ\¨ð \¸CÀ$¹Jó \ð
8¨¨d©
°]Ñ(Bð 8À}ó 8ð9  d¡
ð 9¨s°T©zó 9ð@ #¨¡*ó @ñ8¨3ð 8¸sÀT¹zó 8ñ \¨3ð \¸sÀT¹zó \ð �Sð ¨4ð °Có ð�#ð ¨dð °t¸mÑ7Kó ð( ðaØ@DòaØðaØ26¸±+ðaØIMÐP]ÑI]óañi Sð i°3ð iÀtÈmÑG[ó iñ sð °dð ÀSð ÐY\Ð_cÑYcô rE   