Ë
    ãß²j°)  ã                   ó:  — d Z ddlZddlZddlmZ dZ ej                  d«      ZdZdZ	de
d	e
fd
„Zde
d	e
fd„Zdde
dee
   d	e
fd„Zde
de
de
dee
   de
d	e
fd„Zdee
   d	eee
   ee
   f   fd„Zde
de
de
de
dee
   dede
d	e
fd„Zde
de
d	ee
dz  e
f   dz  fd„Zy)a"  Bash session-snapshot scripting for ``tools.environments.base``.

Pure string builders: the CWD marker, the ``export -p`` dump that strips
per-session vars, the ``init_session`` bootstrap, and the per-command wrapper.
No module state lives here; ``BaseEnvironment`` supplies quoting hooks.
é    N)ÚIterablez—^declare -x (HERMES_SESSION_|HERMES_UI_SESSION_ID|HERMES_CRON_AUTO_DELIVER_|HERMES_CRON_SESSION|HERMES_BROWSER_CONTROL_|HERMES_DELEGATED_CHILD_CONTEXT)z^[A-Za-z_][A-Za-z0-9_]*$z.tmp.XXXXXXXXXXz"$__hermes_snap_tmp"Ú
session_idÚreturnc                 ó   — d| › d�S )NÚ__HERMES_CWD_Ú__© )r   s    úH/home/ubuntu/.hermes/hermes-agent/tools/environments/base_session_env.pyÚ_cwd_markerr   '   s   € Ø˜:˜, bÐ)Ð)ó    Úmarkerc                 ó   — d| › d| › d�S )z™Emit the CWD marker on its own line (leading ``\n`` guards against a
    command whose output lacks a trailing newline; ``_split_cwd_marker`` strips it).z
printf '\nz%sz\n' "$(pwd -P)"r	   )r   s    r
   Ú_cwd_marker_printfr   +   s   € ð ˜˜  6 (Ð*<Ð=Ð=r   Útmp_pathÚexcluded_namesc                 ó¤   — |D �ch c]  }t        |t        «      sŒ|sŒ|’Œ }}dj                  d„ t        |«      D «       «      }d|› d| › �S c c}w )u  Shell snippet dumping ``export -p`` to *tmp_path* minus the per-session bridged vars (see
    ``_SNAPSHOT_EXCLUDED_ENV_REGEX``) and *excluded_names*. The vars are ``unset`` in a subshell
    BEFORE ``export -p``: a line-based ``grep -vE`` is unsafe because bash 3.2 prints a value
    containing a newline as a multi-line ``declare -x`` block, so smuggled continuation lines would
    survive into the snapshot and execute on the next ``source``. ``|| true`` keeps the success
    contract. The dump is a brace group with the redirection on the group: *tmp_path* is usually a
    shell-variable expansion, and a redirect on a pipeline segment would expand it inside that
    segment's subshell, inconsistently with the parent that expands the follow-up ``mv``.

    ``curl â€¦ | bash #`` smuggled into a Matrix room/display name via ``HERMES_SESSION_CHAT_NAME``) land in
    the snapshot and execute on the next ``source`` (issue #71296). Unsetting first means ``export -p``
    never emits those vars â€” including any continuation lines.
    Ú c              3   óL   K  — | ]  }d t        j                  |«      › �–— Œ y­w)Ú N)ÚshlexÚquote)Ú.0Únames     r
   ú	<genexpr>z6_export_dump_excluding_session_vars.<locals>.<genexpr>C   s!   è ø€ ÒQ°d˜AœeŸk™k¨$Ó/Ð0Ô1ÑQùs   ‚"$z¸{ ( unset ${!HERMES_SESSION_*} ${!HERMES_CRON_AUTO_DELIVER_*} ${!HERMES_BROWSER_CONTROL_*} AI_AGENT HERMES_AGENT HERMES_DELEGATED_CHILD_CONTEXT HERMES_CRON_SESSION HERMES_UI_SESSION_IDz( 2>/dev/null; export -p; ) || true; } > )Ú
isinstanceÚstrÚjoinÚsorted)r   r   r   Ú
safe_namesÚextra_unsets        r
   Ú#_export_dump_excluding_session_varsr!   1   sa   € ð" $2ÖT˜4´ZÀÄcÕ5JÊt’$ÐT€JÐTØ—'‘'ÑQ¼fÀZÓ>PÔQÓQ€Kð
	ð  +˜mð ,àˆJð	ðùò Us   …A›AžAÚ
quoted_cwdÚquoted_snapÚsnap_tmp_templateÚ
cwd_markerc                 ó¶   — d|› dt        t        |«      › dt        › dt        › dt        › dt        › dt        › dt        › d	|› d
t        › d| › dt        |«      › d�S )a  Login-shell bootstrap that captures env/functions/aliases into the snapshot. Atomic publish:
    assemble in a ``mktemp`` file, then ``mv`` over the final path so a concurrent ``source`` never
    reads a half-written snapshot (``$$`` is the parent PID in ``&``-launched subshells and macOS
    bash 3.2 lacks ``$BASHPID``, so only ``mktemp`` is portable). Functions are filtered by NAME via
    ``declare -F`` (a line-based ``declare -f | grep -v`` strips the header and leaves an orphaned
    body that breaks every sourced command); the non-empty guard matters because bare ``declare -f``
    dumps ALL functions. The trailing ``cd`` restores the configured cwd after profile scripts (e.g.
    ``cd ~``) so ``pwd -P`` reports terminal.cwd, not the profile's directory.z%umask 077
__hermes_snap_tmp=$(mktemp z) || exit 1
z�
__hermes_fns=$(declare -F | awk '{print $3}' | grep -vE '^_[^_]') || true
[ -n "$__hermes_fns" ] && declare -f $__hermes_fns >> z! 2>/dev/null || true
alias -p >> z#
echo 'shopt -s expand_aliases' >> z
echo 'set +e' >> z
echo 'set +u' >> z
mv -f r   z
 || rm -f z
builtin cd -- z 2>/dev/null || true
Ú
)r!   Ú	_SNAP_TMPr   )r"   r#   r$   r   r%   s        r
   Ú_snapshot_bootstrap_scriptr)   T   s‹   € ð	&Ø&7Ð%8¸Ü.¬y¸.ÓIÐ
Jð KCäCLÀ+ð NÜ �kð "-Ü-6¨Kð 8Ü%˜;ð 'Ü%˜;ð 'ä�˜1˜[˜M¨´I°;ð ?Ø#˜Ð$:Ü˜jÓ)Ð
*¨"ð	.ð/r   Únamesc                 ó˜   — g }g }| D ]>  }d|› �}|› d�|› d�}}||› d|› d�|› d|› d�gz  }|d|› d|› d	|› d
|› d�	d|› d|› �gz  }Œ@ ||fS )u  Shell lines that save profile-scoped passthrough vars before the snapshot is sourced
    and restore (or unset) them afterwards â€” a shared snapshot may hold the previous
    profile's value. Values stay in environment memory and never enter the command string.Ú_HERMES_RUNTIME_PASSTHROUGH_Ú_PRESENTÚ_VALUEz=${z+x}z-}zif [ "$z" = x ]; then export z="$z"; else unset z; fizunset r   r	   )r*   ÚsaveÚrestorer   r   ÚpresentÚvalues          r
   Ú_passthrough_save_restorer3   o   s¶   € ð €DØ€GØò (ˆØ/°¨vÐ6ˆØ"˜8 8Ð,°°¸Ð.?�ˆØ�G�9˜D   dÐ+°¨w°d¸4¸&ÀÐ-DÐEÑEˆØØ�g�YÐ3°D°6¸¸U¸GÀ>ÐRVÐQWÐW[Ð\Ø�W�I˜Q˜u˜gÐ&ð(ñ 	(‰ð	(ð �ˆ=Ðr   ÚcommandÚpassthrough_namesÚsnapshot_readyc                ój  — | j                  dd«      }t        |«      \  }}	t        |«      }
|r|
j                  d|› d�«       |
|	z  }
|
ddd|› d�d	|› d�d
dgz  }
|r7|
j                  d|› dt	        t
        |«      › dt
        › d|› dt
        › d�«       |
t        |«      dgz  }
dj                  |
«      S )aý  Per-command bash script: source snapshot, cd, run, re-dump env, emit CWD marker.
    ``source`` stdout goes to /dev/null because macOS bash 3.2 / some Homebrew builds echo
    ``declare -x`` lines when sourcing. AI_AGENT/HERMES_AGENT advertise the harness to remote
    backends (whose env is not inherited); ``${VAR:-default}`` never clobbers an outer harness.
    GIT_PAGER/PAGER=cat stop pager-happy tools hanging a PTY-backed command. The env re-dump
    uses the same mktemp+mv atomic publish as the bootstrap and chains ``mv`` on the dump
    succeeding so a failed dump never replaces a good snapshot. ``umask 077`` is applied after
    the user's command so snapshot files (which may carry secrets) are private without
    changing the command's umask.
    ú'z'\''zsource z >/dev/null 2>&1 || truezPexport AI_AGENT="${AI_AGENT:-hermes-agent}" HERMES_AGENT="${HERMES_AGENT:-true}"z:export GIT_PAGER="${GIT_PAGER:-cat}" PAGER="${PAGER:-cat}"zbuiltin cd -- z || exit 126zeval 'z__hermes_ec=$?z	umask 077z__hermes_snap_tmp=$(mktemp z) && { z
 && mv -f r   z; } 2>/dev/null || rm -f z 2>/dev/null || truezexit $__hermes_ecr'   )Úreplacer3   ÚlistÚappendr!   r(   r   r   )r4   r"   r#   r$   r5   r6   r%   Úescapedr/   r0   Úpartss              r
   Ú_wrap_command_scriptr>      sû   € ð �o‰o˜c 7Ó+€GÜ-Ð.?Ó@�M€Dˆ'Ü�‹J€EÙØ�‰�w˜{˜mÐ+CÐDÔEØ	ˆWÑ€EØ	ØZØDà
˜˜ LÐ1Ø
��	˜ÐØØðñ €Eñ Ø�‰Ø)Ð*;Ð)<ð =Ü5´iÐARÓSÐTð UÜ!�{ ! K =ð 1$Ü$- ;Ð.BðDô	Eð
 
Ô  Ó,Ð.AÐBÑB€EØ�9‰9�UÓÐr   Úoutputc                 ó„  — | j                  |«      }|dk(  ryt        d|dz
  «      }| j                  |||«      }|dk(  s||k(  ry| |t        |«      z   | j                  «       xs d}| j                  dd|«      }|dk(  r|}| j	                  d|t        |«      z   «      }|dk7  r|dz   n
t        | «      }|| d| | |d z   fS )a  Locate the last ``marker<path>marker`` pair in *output*. Returns
    ``(cwd_path_or_None, output_without_marker_line)``, or ``None`` when no complete pair
    exists. The stripped span runs from the ``\n`` the wrapper injected before the marker
    through the end of the marker line.éÿÿÿÿNr   i   r'   é   )ÚrfindÚmaxÚlenÚstripÚfind)r?   r   ÚlastÚsearch_startÚfirstÚcwd_pathÚ
line_startÚline_ends           r
   Ú_split_cwd_markerrN   ¤   sÜ   € ð
 �<‰<˜Ó€DØˆr‚zØÜ�q˜$ ™+Ó&€LØ�L‰L˜ ¨tÓ4€EØ�‚{�e˜t’mØØ�eœc &›kÑ)¨DÐ1×7Ñ7Ó9ÒA¸T€HØ—‘˜d A uÓ-€JØ�RÒØˆ
Ø�{‰{˜4 ¬¨F«Ñ!3Ó4€HØ'¨2š~ˆx˜!Š|´3°v³;€HØ�V˜K˜ZÐ(¨6°(°)Ð+<Ñ<Ð<Ð<r   )r	   )Ú__doc__Úrer   Útypingr   Ú_SNAPSHOT_EXCLUDED_ENV_REGEXÚcompileÚ_SHELL_ENV_NAME_REÚ_SNAP_TMP_SUFFIXr(   r   r   r   r!   r)   Útupler:   r3   Úboolr>   rN   r	   r   r
   ú<module>rX      sb  ðñó 
Û Ý ð(Rð ð  �R—Z‘ZÐ ;Ó<Ð ð %Ð Ø"€	ð*˜Cð * Có *ð>˜sð > só >ñ °#ð  ÀxÐPSÁ}ð  Ð^aó  ðF/Øð/Ø%(ð/Ø=@ð/ØRZÐ[^ÑR_ð/Ømpð/àó/ð6 X¨c¡]ð °u¸TÀ#¹YÈÈSÉ	Ð=QÑ7Ró ð "Øð"Ø!$ð"Ø36ð"ØKNð"à ‘}ð"à6:ð"àHKð"àPSó"ðJ=˜cð =¨3ð =°5¸¸t¹ÀS¸Ñ3IÈDÑ3Pô =r   