+
    lHàjØ×  ã                  ó2  € R t ^ RIHt ^ RIt^ RIHt ^ RIHt ^RIH	t	 R R lt
RuR R	 lltR
 R ltR R ltR R ltR R ltR R ltR R ltR R ltR R ltR R ltR R ltR R ltR  R! ltR" R# ltR$ R% ltR& R' ltR(0tR) R* ltR+ R, ltR- R. ltR/ R0 ltR1 R2 lt R3 R4 lt!R5 R6 lt"R7 R8 lt#R9 R: lt$R; R< lt%R= R> lt&R? R@ lt'RA RB lt(RC RD lt)RE RF lt*RG RH lt+RI RJ lt,RK RL lt-RM RN lt.RO RP lt/RQ RR lt0Rvt1RS RT lt2RU RV lt3RWt4RX RY lt5RuRZ R[ llt6RuR\ R] llt7R^ R_ lt8]9! 4       t:]Pv                  R` Ra l4       t<]Pv                  Rb Rc l4       t=RdRe/Rf Rg llt>Rh Ri lt?Rj Rk lt@Rl Rm ltARnR/Ro Rp lltBRq Rr ltCRs Rt ltDR# )wa  Session working-directory + durable session row: cwd resolution/healing, session.db row ensure,
branch seed, history rewind, git meta persistence. Bodies are rebound onto server.py's globals at
install time (method_ctx.bind_module), so they reference server.py globals bare.
)ÚannotationsN)ÚAny)Ú	git_probe)Úbind_modulec               ó    € V ^8„  d   QhRRRR/# )é   Ú	path_partÚstrÚreturn© )Úformats   "Ú@/home/ubuntu/.hermes/hermes-agent/tui_gateway/session_workdir.pyÚ__annotate__r      s   € ÷ ñ ¨#ð °#ñ ó    c                ól  € \         P                  P                  V 4      p\         P                  R 8w  d€   VP	                  RR4      p\        V4      ^8¼  d^   V^,          R8X  dP   V^,          R8X  dB   V^ ,          P                  4       '       d%   RV^ ,          P                  4        RVR,           2# V# )ÚntÚ\Ú/Ú:z/mnt/:é   NN)ÚosÚpathÚ
expanduserÚnameÚreplaceÚlenÚisalphaÚlower)r   ÚexpandedÚ
normalizeds   &  r   Ú_normalize_completion_pathr       s•   € Ü�w‰w×!Ñ! )Ó,€HÜ	‡w�w�$„Ø×%Ñ% d¨CÓ0ˆ
Üˆz‹?˜aÔ J¨q¥M°SÔ$8¸ZÈ½]ÈcÔ=QÐV`ÐabÕVc×VkÑVk×VmÒVmØ˜: a�=×.Ñ.Ó0Ð1°°:¸bµ>Ð2BÐCÐCØ€Or   c               ó    € V ^8„  d   QhRRRR/# )r   Úparamsúdict | Noner
   r	   r   )r   s   "r   r   r      s   € ÷ .ñ .˜Kð .°3ñ .r   c                ó>  € T ;'       g    / p V P                  R 4      pV P                  R4      p\        P                  V P                  R4      ;'       g    R/ 4      P                  R 4      p V'       d   \        V4      MRpV P                  R4      '       g   V'       d   \	        V4      ;p'       d   V# VRJ;'       d    \        V4      p\        T;'       g’    T;'       gˆ    \        V4      ;'       gu    V'       d   RMR;'       ga    \        4       ;'       gO    \        P                  P                  R4      ;'       g(    \        R4      ;'       g    \        P                  4       4      pV'       d)   \        V4      '       d   V# \        V4      ;'       g    R# Vf+   VP                  R4      '       d   \        R4      '       d   V# \         P"                  ! \$        4      ;_uu_ 4        \        P&                  P)                  \        P&                  P+                  V4      4      p\        P&                  P-                  V4      '       d   VuuRRR4       #  RRR4       Vf%   \        V4      '       d   \        R4      '       d   V# \/        V4      '       d   \1        V4      R8w  d   V# \        P                  4       #   \         d7    T'       d   T P                  R4      '       d   T'       g
   T'       g   h Rp EL…i ; i  + '       g   i     L³; i)	ÚcwdÚprofileÚ
session_idÚ NÚcwd_explicitÚ~ÚTERMINAL_CWDÚlocal)ÚgetÚ	_sessionsÚ_profile_homeÚProfileUnavailableErrorÚ_profile_workspace_cwdÚ_cwd_is_remoter	   Ú_profile_default_cwdÚ_launch_configured_cwdr   ÚenvironÚ_sandbox_workspace_cwdÚgetcwdÚ_is_remote_cwd_shapeÚ_declared_remote_profile_cwdÚ
startswithÚ
contextlibÚsuppressÚ	Exceptionr   Úabspathr   ÚisdirÚ_is_container_pathÚ_bound_terminal_backend)	r"   Ú
client_cwdr&   Úsession_cwdÚprofile_homeÚprofile_cwdÚ	named_sshÚrawÚresolveds	   &        r   Ú_completion_cwdrI      s|  € Ø�\ˆ\�r€Fð —‘˜EÓ"€JØ�j‰j˜Ó#€GÜ—-‘- §
¡
¨<Ó 8× >Ð >¸BÀÓC×GÑGÈÓN€Kðß18”} WÔ-¸dˆð �:‰:�n×%Ò%¯*Ü0°Ó>Ð>ˆ;Ö>ØÐð  DÐ(×IÐI¬^¸LÓ-I€IÜ
ˆj÷ _ð _˜K÷ _ð _Ô+?ÀÓ+M÷ _ð _ç"‘#¨÷_ð _ä/EÓ/G÷_ð _ô —‘—‘ Ó/÷_ð _ô 4JÈ$Ó3O÷_ð _ô TV×S\ÑS\ÓS^ó`€C÷ Ü*¨3×/Ò/ˆsÐhÔ6RÐS_Ó6`×6gÐ6gÐdgÐhØÒ §¡¨s× 3Ò 3¼Àt×8LÒ8LØˆ
Ü	×	Ò	œY×	'Õ	'Ü—7‘7—?‘?¤2§7¡7×#5Ñ#5°cÓ#:Ó;ˆÜ�7‰7�=‰=˜×"Ò"Ø÷ 
(Ò	'à"÷ 
(ð ÒÔ 4°S× 9Ò 9¼nÈT×>RÒ>RØˆ
ô ˜#×ÒÔ#:¸<Ó#HÈGÔ#SØˆ
Ü�9‰9‹;ÐøôC #ô ç˜vŸz™z¨.×9Ò9Ç:×Q\ØØ‹ð	ú÷, 
(×	'ús=   Á.K Á6K Ç2A#LËL	ËL	Ë2L	Ë:L	ÌL	ÌL	ÌL	c               ó    € V ^8„  d   QhRRRR/# )r   Úkeyr	   r
   r   )r   s   "r   r   r   J   s   € ÷ ñ ˜sð  sñ r   c                ó^  € \         P                  ! \        4      ;_uu_ 4        \        4       P	                  R/ 4      p\        V\        4      '       d=   \        VP	                  V 4      ;'       g    R4      P                  4       uuRRR4       #  RRR4       R#   + '       g   i     R# ; i)zEStripped ``terminal.<key>`` from config, or "" when unset/unreadable.Úterminalr(   N)	r;   r<   r=   Ú	_load_cfgr-   Ú
isinstanceÚdictr	   Ústrip)rK   Úterminal_cfgs   & r   Ú_workdir_terminal_cfgrS   J   sy   € ä	×	Ò	œY×	'Õ	'Ü “{—‘ z°2Ó6ˆÜ�l¤D×)Ò)Ü�|×'Ñ'¨Ó,×2Ð2°Ó3×9Ñ9Ó;÷ 
(Ò	'à)÷ 
(ñ ÷	 
(Ö	'ñ ús   £ABÁ1BÂB,	c               ó   € V ^8„  d   QhRR/# )r   r
   rP   r   )r   s   "r   r   r   S   s   € ÷ 
ñ 
¨dñ 
r   c                óh   € V '       g   / # ^ RI HpHp  V! \        V 4      4      #   T d    / u # i ; i)uÒ   A named profile's effective ``TERMINAL_*`` policy â€” the one its turns run under
(``build_profile_terminal_scope``: defaults <- ``.env`` <- ``config.yaml``). {} for the launch profile or an
unreadable profile.)ÚTerminalPolicyUnavailableÚbuild_profile_terminal_scope)Útools.terminal_scoperV   rW   ÚPath)rD   rV   rW   s   &  r   Ú_profile_terminal_policyrZ   S   s8   € ÷ Øˆ	ß\ðÙ+¬D°Ó,>Ó?Ð?øØ$ô ØŠ	ðús   ”% ¥	1°1c               ó    € V ^8„  d   QhRRRR/# )r   ÚpolicyrP   r
   r	   r   )r   s   "r   r   r   `   s   € ÷ Lñ L˜Dð L Sñ Lr   c                ó–   € \        V P                  R 4      ;'       g    R4      P                  4       P                  4       ;'       g    R# )ÚTERMINAL_ENVr(   r,   )r	   r-   rQ   r   )r\   s   &r   Ú_policy_backendr_   `   s8   € Üˆv�z‰z˜.Ó)×/Ð/¨RÓ0×6Ñ6Ó8×>Ñ>Ó@×KÐKÀGÐKr   c               ó   € V ^8„  d   QhRR/# ©r   r
   r	   r   )r   s   "r   r   r   d   s   € ÷ vñ v¨Sñ vr   c                óN   € V '       d   \        \        V 4      4      # \        4       # )a!  Terminal backend of the profile a session/RPC is bound to. A named profile reads ITS policy: at
``session.create`` the multiplex gateway has not rebound HERMES_HOME yet, so ``_effective_terminal_backend()``
would report the LAUNCH profile's backend, which must never leak into a named one.)r_   rZ   Ú_effective_terminal_backend©rD   s   &r   rA   rA   d   s"   € ÷ GSŒ?Ô3°LÓAÓBÐuÔXsÓXuÐur   c               ó   € V ^8„  d   QhRR/# ©r   r
   Úboolr   )r   s   "r   r   r   k   s   € ÷ :ñ : Dñ :r   c                ó   € \        V 4      R8H  # )zÊWhether the bound profile's working directory lives on another host (ssh), so a host ``isdir`` check cannot
vouch for it. Docker and the other backends mount or copy HOST paths and keep the host checks.Ússh)rA   rd   s   &r   r2   r2   k   s   € ô # <Ó0°EÑ9Ð9r   c               ó   € V ^8„  d   QhRR/# ©r   r
   ú
str | Noner   )r   s   "r   r   r   q   s   € ÷ [ñ [°*ñ [r   c                óÆ   € \        V 4      p\        VP                  R4      ;'       g    R4      P                  4       p\	        V4      R8X  d   \        V4      '       d   V# R# )u=  A named ssh profile's own ``terminal.cwd`` (``~``, ``~/â€¦`` or absolute), unchecked against this host.

``_profile_configured_cwd`` requires ``os.path.isdir``; an ssh working directory lives on the remote, so that
check drops it (or expands ``~`` to THIS host's home) and the launch profile's ``TERMINAL_CWD`` wins.
r+   r(   ri   N)rZ   r	   r-   rQ   r_   r8   )rD   r\   rG   s   &  r   r9   r9   q   sU   € ô & lÓ3€FÜ
ˆf�j‰j˜Ó(×.Ð.¨BÓ
/×
5Ñ
5Ó
7€CÜ! &Ó)¨UÔ2Ô7KÈC×7PÒ7Pˆ3ÐZÐVZÐZr   c               ó    € V ^8„  d   QhRRRR/# ©r   rG   r	   r
   rg   r   )r   s   "r   r   r   |   s   € ÷ Fñ F˜cð F dñ Fr   c                ón   € ^ RI Hp V! RV 4      ;'       g     \        P                  P	                  V 4      # )u¦   An ssh working directory the remote shell can resolve: ``~``, ``~/â€¦`` or absolute (a relative one would be
stored and git-probed relative to the gateway's own cwd).)Ú_is_ssh_remote_tilde_cwdri   )Úhermes_cli.configrq   r   r   Úisabs)rG   rq   s   & r   r8   r8   |   s)   € õ ;á# E¨3Ó/×EÐE´2·7±7·=±=ÀÓ3EÐEr   c               ó    € V ^8„  d   QhRRRR/# ro   r   )r   s   "r   r   r   „   s   € ÷ <ñ <˜Cð < Dñ <r   c                ó`   € V P                  R4      ;'       d    V P                  R4      '       * # )zUAn absolute POSIX path, the only shape a container backend's working directory takes.r   z//)r:   )rG   s   &r   r@   r@   „   s%   € à�>‰>˜#Ó×;Ð; s§~¡~°dÓ';Ô#;Ð;r   c               ó   € V ^8„  d   QhRR/# rk   r   )r   s   "r   r   r   ‰   s   € ÷ ñ ¨Jñ r   c                óº  € V '       dI   \        V 4      p\        V4      \        VP                  R4      ;'       g    R4      P	                  4       r2MK\        4       p\        P                  P                  RR4      P	                  4       ;'       g    \        R4      pVR9   g7   \        V4      '       d&   \        P                  P                  V4      '       d   R# V# )a“  A container backend's configured ``terminal.cwd`` (docker ``/workspace``), unchecked against this host.

``_profile_configured_cwd``/``_launch_configured_cwd`` require ``os.path.isdir``, which a path inside the
sandbox fails. Only a path missing on the host qualifies: an existing host dir keeps the host path (it is the
``docker_mount_cwd_to_workspace`` source). ssh has its own remote-cwd rules above.r+   r(   r%   N>   ri   r,   )rZ   r_   r	   r-   rQ   rc   r   r5   rS   r@   r   r?   )rD   r\   ÚbackendrG   s   &   r   r6   r6   ‰   s    € ÷ Ü)¨,Ó7ˆÜ& vÓ.´°F·J±J¸~Ó4N×4TÐ4TÐRTÓ0U×0[Ñ0[Ó0]‘ä-Ó/ˆÜ�j‰j�n‰n˜^¨RÓ0×6Ñ6Ó8×XÐXÔ<QÐRWÓ<XˆØÐ"Ô"Ô*<¸S×*AÒ*AÄRÇWÁWÇ]Á]ÐSV×EWÒEWÙØ€Jr   c               ó   € V ^8„  d   QhRR/# rk   r   )r   s   "r   r   r   š   s   € ÷ Qñ Q¨Jñ Qr   c                óx   € \        V 4      ;'       g)    \        V 4      ;'       g    V '       d   \        V 4      # R# )zfA named profile's configured workspace: an ssh profile's remote dir, a host dir, else a container dir.N)r9   Ú_profile_configured_cwdr6   rd   s   &r   r1   r1   š   sE   € ä(¨Ó6÷ Pð PÔ:QÐR^Ó:_÷ Pð Pß8DÔ& |Ó4ðQØJNðQr   c               ó   € V ^8„  d   QhRR/# rk   r   )r   s   "r   r   r       s   € ÷ ñ ¨*ñ r   c                ón   € \        V 4      ;p'       d   V# V e   \        V 4      R8X  d   \        V 4      # R# )aH  Where a session for ``profile_home`` lands when nothing else is known: its configured workspace, else a NAMED
local profile's own home. Never the LAUNCH profile's ``terminal.cwd``/``TERMINAL_CWD`` (#87584): those name
another profile's workspace (``/opt/data`` in the Docker image). Its home is what its standalone gateway uses.Nr,   )r1   rA   r	   )rD   Ú	workspaces   & r   r3   r3       s;   € ô +¨<Ó8Ð8€yÖ8ØÐØÒÔ$;¸LÓ$IÈWÔ$TÜ�<Ó Ð Ùr   c               ó    € V ^8„  d   QhRRRR/# )r   rG   r	   r
   r   )r   s   "r   r   r   «   s   € ÷ 
ñ 
 cð 
¨cñ 
r   c                óH  € \        V 4      '       d"   \        V4      '       d   V# \        RV 24      h\        P                  P                  \        P                  P                  V4      4      p\        P                  P                  V4      '       g   \        RV 24      hV# )z˜A picked workspace for a session bound to ``profile_home``: an ssh dir raw, else an existing host dir.
Raises ValueError when a host dir does not exist.z9remote working directory must be absolute or ~-relative: z"working directory does not exist: )r2   r8   Ú
ValueErrorr   r   r>   r   r?   )rD   rG   rH   s   && r   Ú_workspace_cwdr‚   «   s€   € ô �l×#Ò#Ü ×$Ò$ØˆJÜÐTÐUXÐTYÐZÓ[Ð[Ü�w‰w�‰œrŸw™w×1Ñ1°#Ó6Ó7€HÜ�7‰7�=‰=˜×"Ò"ÜÐ=¸c¸UÐCÓDÐDØ€Or   c               ó    € V ^8„  d   QhRRRR/# ©r   Úsessionr#   r
   r	   r   )r   s   "r   r   r   ¸   s   € ÷ 6ñ 6 ð 6°ñ 6r   c                ó&   € \        V 4      ^ ,          # )zµThe cwd terminal_tool should use for this TUI session (NOT host-validated: a non-local backend's cwd lives
inside the target environment). "" when the backend's own default applies.)Ú_terminal_task_cwd_with_source©r…   s   &r   Ú_terminal_task_cwdr‰   ¸   s   € ô *¨'Ó2°1Õ5Ð5r   c               ó    € V ^8„  d   QhRRRR/# )r   r…   r#   r
   ztuple[str, str]r   )r   s   "r   r   r   ¾   s   € ÷ (ñ (¨Kð (¸Oñ (r   c                ó  € T ;'       g    / P                  R4      p\        V4      ;'       d    \        V4      pV'       d   RM	\        4       pVR8w  dÉ   V '       dC   V P                  R4      '       d,   V P                  R4      '       d   \	        V R,          4      R3# V'       d   \        V4      pV'       d   VR3# R
# \        P                  P                  RR	4      P                  4       ;'       g    \        R4      pV'       d   VR9  d   VR3# VR8X  d   R
# \        V 4      '       d   R# V '       d,   V P                  R4      '       d   \	        V R,          4      R3# \        V4      '       g   R# \        4       R3# )u.  ``(cwd, source)``: ``"session"`` for THIS session's workspace (``explicit_cwd``/tracked dir), ``"process"`` for
the global ``TERMINAL_CWD``/``terminal.cwd`` fallback â€” under per-session docker isolation that is a PREVIOUS
session's launch artifact, so terminal_tool refuses it as a bind-mount source.rD   ri   r,   Úexplicit_cwdr%   r…   Úprocessr+   r(   )r*   r�   >   Ú.r%   Úauto)r(   r�   )r-   rg   r2   rc   r	   r9   r   r5   rQ   rS   Ú_is_remote_launch_cwdÚ_host_cwd_is_terminal_cwdrI   )r…   rD   rF   rx   Ú
remote_cwdrG   s   &     r   r‡   r‡   ¾   sA  € ð —M�M˜r×&Ñ& ~Ó6€Lô �\Ó"×CÐC¤~°lÓ'C€Iß ‰eÔ&AÓ&C€GØ�'Ôç�w—{‘{ >×2Ò2°w·{±{À5×7IÒ7IÜ�w˜u•~Ó&¨	Ð1Ð1çÜ5°lÓCˆJß.8�J 	Ð*ÐNÐ>NÐNÜ�j‰j�n‰n˜^¨RÓ0×6Ñ6Ó8×XÐXÔ<QÐRWÓ<Xˆß�3Ð2Ô2Ø˜	�>Ð!Ø�eÔØ!Ð!ô ˜W×%Ò%ØÐß�7—;‘;˜u×%Ò%Ü�7˜5•>Ó" IÐ-Ð-Ü$ \×2Ò2ØÐÜÓ˜iÐ'Ð'r   c               ó    € V ^8„  d   QhRRRR/# r„   r   )r   s   "r   r   r   ß   s   € ÷ Xñ X˜+ð X¨#ñ Xr   c                óx   € V '       d*   V P                  R 4      '       d   \        V R ,          4      # \        4       # )r%   )r-   r	   rI   rˆ   s   &r   Ú_session_cwdr•   ß   s)   € ß")¨g¯k©k¸%×.@Ò.@Œ3ˆw�u�~ÓÐWÄoÓFWÐWr   Údesktopc               ó    € V ^8„  d   QhRRRR/# ©r   r…   r#   r
   rg   r   )r   s   "r   r   r   ç   s   € ÷ yñ y¨[ð y¸Tñ yr   c                óˆ   € \        T ;'       d1    V P                  R4      '       * ;'       d    \        V 4      \        9   4      # )zEWhether the session cwd came from app launch rather than user intent.rŒ   )rg   r-   Ú_session_sourceÚ_LAUNCH_CWD_NOT_A_WORKSPACErˆ   s   &r   Ú_context_cwd_is_launch_artifactrœ   ç   s5   € ä�×wÐw §¡¨NÓ ;Ô;×wÐwÄÐPWÓ@XÔ\wÑ@wÓxÐxr   c               ó$   € V ^8„  d   QhRRRRRR/# )r   r"   rP   Úsourcer	   r
   ztuple[bool, str, bool]r   )r   s   "r   r   r   ì   s"   € ÷ 1ñ 1 ð 1¨cð 1ÐDZñ 1r   c           	     óN  € \        V P                  R4      ;'       g    R4      P                  4       p\        V4      ;'       d    \	        V4      ;'       d    \        V4      pRp\        P                  ! \        4      ;_uu_ 4        \        V4      ;'       dd    T;'       gZ    \        P                  P                  \        P                  P                  \        P                  P                  V4      4      4      pRRR4       \        V 4      pV'       dw   V'       go   VR8X  dh   V P                  R4      '       d   RpTpMKV'       dD   V\        P                  P                  \        P                  P                  V4      4      8X  d   RpWVV3#   + '       g   i     L�; i)uk  ``(explicit_cwd, session_cwd, remote_cwd)`` for a freshly created session.

Only a chosen workspace persists as cwd; the launch-dir fallback is "No workspace". A
chosen workspace is one the gateway host can ``isdir``-probe, an ssh-shaped cwd on a remote
profile, or â€” the #108205 desktop arm â€” a nonblank desktop-sourced cwd the host probe could
not vouch for: the client names a workspace its gateway host cannot see (Docker/remote
backend topology), and a failed host-side isdir is a topology artifact, not a verdict on
the client's path. The CLIENT vouches instead, with #52589 provenance: a deliberate pick
(``cwd_explicit``) adopts the raw path outright; an inherited app-global workspace only
counts once the completion resolution actually adopted it, so a launch-dir fallback still
persists nothing and a named profile's configured ``terminal.cwd`` keeps winning.
r%   r(   FNr–   r)   T)r	   r-   rQ   rg   r8   r2   r;   r<   r=   r   r   r?   r>   r   rI   )r"   rž   rD   Úraw_cwdr’   rŒ   rC   s   &&&    r   Ú_resolve_create_cwdr¡   ì   s$  € ô �&—*‘*˜UÓ#×)Ð) rÓ*×0Ñ0Ó2€GÜ�g“×aÐaÔ#7¸Ó#@×aÐaÄ^ÐT`ÓEa€JØ€LÜ	×	Ò	œY×	'Õ	'Ü˜G“}÷ Wð WØ×UÐUœ"Ÿ'™'Ÿ-™-¬¯©¯©¼¿¹×8JÑ8JÈ7Ó8SÓ(TÓUð 	÷ 
(ô " &Ó)€Kß—|¨°)Ô(;Ø�:‰:�n×%Ò%ØˆLØ!‰Kß˜[¬B¯G©G¯O©O¼B¿G¹G×<NÑ<NÈwÓ<WÓ,XÔXØˆLØ jÐ0Ð0÷ 
(×	'ús   ÂFÂ%AFÆF$	c               ó    € V ^8„  d   QhRRRR/# )r   r…   rP   r
   rl   r   )r   s   "r   r   r   	  s   € ÷ 1ñ 1 Dð 1¨Zñ 1r   c                óð   € V P                  R4      '       d   \        V 4      # \        V 4      \        9   g   \	        V 4      '       d   R# \        V P                  R4      ;'       g    R4      ;'       g    R# )zrThe cwd to stamp on the session's DB row, or None to leave it unset (launch-dir rule: ``_ensure_session_db_row``).rŒ   Nr%   r(   )r-   r•   rš   r›   r�   r	   rˆ   s   &r   Ú_persisted_session_cwdr¤   	  s]   € à‡{�{�>×"Ò"Ü˜GÓ$Ð$Ü�wÓÔ#>Ô>ÔBWÐX_×B`ÒB`ÙÜˆw�{‰{˜5Ó!×'Ð' RÓ(×0Ð0¨DÐ0r   c               ó    € V ^8„  d   QhRRRR/# r˜   r   )r   s   "r   r   r     s   € ÷ \ñ \ ;ð \°4ñ \r   c                óh  € V '       d   V P                  R4      '       d   R# V P                  R4      p\        V4      '       d   R# \        V P                  R4      ;'       g    R4      p\        V4      ;'       d8    \	        V4      '       * ;'       d     \
        P                  P                  V4      # )aü  A cwd nobody picked for a session whose terminal does not run in host directories: an ssh session's, or a
sandbox backend's (modal, daytona, singularity, sprites, ...) when it is a directory on THIS host: the gateway's
launch directory (``/opt/data`` in the Docker image). Host-side context discovery reads it from memory, but it
never becomes the terminal cwd and is never persisted: a resume adopts a stored cwd as the session's workspace.
A sandbox path (``/workspace``) is not a host directory and stays.rŒ   FrD   Tr%   r(   )r-   r2   r	   rg   r‘   r   r   r?   )r…   rD   r%   s   &  r   r�   r�     s€   € ÷ �g—k‘k .×1Ò1ÙØ—;‘;˜~Ó.€LÜ�l×#Ò#ÙÜ
ˆg�k‰k˜%Ó ×&Ð& BÓ
'€CÜ�‹9×[Ð[Ô6°|ÓDÔD×[Ð[ÌÏÉÏÉÐWZÓI[Ð[r   c               ó   € V ^8„  d   QhRR/# rf   r   )r   s   "r   r   r   !  s   € ÷ Nñ N¨tñ Nr   c                óÆ   € \        V 4      pVR	9   d   R# ^ RIHp W9   d   R# ^ RIHp V '       d   \        V 4      MRpV! VRRVR7      ;'       g    V! VRRVR7      '       * # )
a²  Whether a host directory can be the terminal cwd of a session bound to ``profile_home``: the local backend runs
in it, docker mounts it at ``/workspace`` (``docker_mount_cwd_to_workspace``) or creates it (``docker run -w``),
and a plugin backend declaring neither ``is_remote`` nor ``is_container`` runs on this host. ssh, modal, daytona,
singularity, sprites and the other sandboxes run somewhere the host's directories do not exist.T)Ú_BUILTIN_BACKENDSF)Úprovider_flagNÚ	is_remote)ÚscopeÚis_container>   r,   Údocker)rA   Útools.terminal_tool_configr©   Úagent.terminal_env_registryrª   r	   )rD   rx   r©   rª   r¬   s   &    r   r‘   r‘   !  sm   € ô
 & lÓ3€GØÐ%Ô%ÙÝ<ØÔ#Ùõ :ß!-ŒC�Ô°4€EÙ˜g {°DÀÔF÷ Mð MÙ  ¨.¸$ÀeÔLôNð Nr   c               ó    € V ^8„  d   QhRRRR/# ©r   r%   r	   r
   rg   r   )r   s   "r   r   r   4  s   € ÷ añ a˜cð a°Dñ ar   c                ó  a€ ^ RI Hp ^ RIHp \        P
                  P                  V 4      '       g   R#  \        V 4      P                  4       o\        T;'       g    \        4       4      P                  4       pVP                  4       V! VR7      P                  4       0p\        ;QJ d    T3R lT 4       F  '       g   K   RM	  RM! T3R lT 4       4      ;'       g	    T! S4      #   \        \        3 d     R# i ; i)a  Whether ``cwd`` is inside Hermes's own host tree: the Hermes root (``/opt/data`` and its ``/opt/data/home``
subprocess home in the Docker image, which also holds every named profile) or the install tree
(``/opt/hermes``). A ``~`` path is the remote's home, never this host's.©Ú_is_install_tree©Úget_default_hermes_rootF©Úhomec              3  ó\   <"  € T F!  pSV8H  ;'       g    VSP                   9   x € K#  	  R # 5i©N)Úparents)Ú.0Úrootr   s   & €r   Ú	<genexpr>Ú'_is_hermes_owned_cwd.<locals>.<genexpr>C  s)   øé € ÐFÁ¸ˆt�t‰|×3Ð3˜t t§|¡|Ñ3Ô3Ãùs   ƒ,”,T)Úagent.runtime_cwdrµ   Úhermes_constantsr·   r   r   rs   rY   ÚresolveÚget_hermes_homer   ÚOSErrorÚRuntimeErrorÚany)r%   rD   rµ   r·   r¹   Úrootsr   s   &&    @r   Ú_is_hermes_owned_cwdrÉ   4  sÀ   ø€ õ 3Ý8ä�7‰7�=‰=˜×ÒÙðÜ�C‹y× Ñ Ó"ˆÜ�L×5Ð5¤OÓ$5Ó6×AÑAÓCˆØ—‘“Ñ!8¸dÔ!C×!KÑ!KÓ!MÐNˆ÷ ‹3ÔFÁÓF�3�3Š3ÔFÁÓFÓF×`Ð`ÑJZÐ[_ÓJ`Ð`øô ”\Ð"ô Úðús   ¶&C+ ÁAC+ Ã+D Ã?D c               ó    € V ^8„  d   QhRRRR/# r²   r   )r   s   "r   r   r   F  s   € ÷ 4ñ 4˜ð 4¨dñ 4r   c           	     ó`  € ^ RI Hp ^ RIHpHp \
        P                  P                  V 4      '       g   R#  \        V 4      P                  4       p\        T;'       g    \        4       4      P                  4       P                  4       pV! VR7      P                  4       pWfR,          WwR,          \        VP                  4      \        V! 4       4      P                  4       \        P                  4       P                  4       0pYX9   ;'       g	    T! T4      #   \        \        3 d     R# i ; i)af  Whether ``cwd`` IS a directory a Hermes process is launched from rather than a folder someone picked: the
Hermes root (``/opt/data`` in the Docker image), a subprocess home (``/opt/data/home``), the bound profile's
home, the install tree, the OS user's home or ``/`` (the desktop's launch dirs). Folders below them are not: a
user may keep a workspace there.r´   )r·   Úget_real_homeFr¸   r¹   )rÁ   rµ   rÂ   r·   rÌ   r   r   rs   rY   rÃ   rÄ   r   Úanchorr¹   rÅ   rÆ   )	r%   rD   rµ   r·   rÌ   r   r¹   r¾   Úlaunchs	   &&       r   Ú_is_launch_dirrÏ   F  sæ   € õ
 3ßGä�7‰7�=‰=˜×ÒÙðÜ�C‹y× Ñ Ó"ˆÜ�L×5Ð5¤OÓ$5Ó6×AÑAÓC×KÑKÓMˆÙ&¨DÔ1×9Ñ9Ó;ˆØ˜v� t°F­]¼DÀÇÁÓ<MÜ‘}“Ó'×/Ñ/Ó1´4·9±9³;×3FÑ3FÓ3HðJˆð ‰>×3Ð3Ñ-¨dÓ3Ð3øô ”\Ð"ô Úðús   ·&D ÁB&D ÄD-Ä,D-c               ó    € V ^8„  d   QhRRRR/# r²   r   )r   s   "r   r   r   [  s   € ÷ jñ j ð j°dñ jr   c                ó  € Ve7   \        V4      '       g&   \        P                  P                  V 4      '       g   R# ^ RIHp ^ RIHp  \        V 4      P                  4       \        V4      P                  4       P                  4       rTV! VR7      P                  4       pYE8X  g   YTP                  9   d   R# YFTR,          39   ;'       g'    TR,          TP                  9   ;'       g	    T! T4      #   \        \        3 d     R# i ; i)aœ  Whether a NAMED local profile's stored cwd is a directory that belongs to another profile or to Hermes itself:
the root (``/opt/data``), its subprocess home (``/opt/data/home``), a sibling profile's tree, or the install tree.
Those are launch-profile workspaces that leaked into this profile's row before #87584, never a folder chosen for
it. Other folders under the root stay: a user may keep a workspace there.Fr´   r¶   r¸   r¹   Úprofiles)r2   r   r   rs   rÁ   rµ   rÂ   r·   rY   rÃ   r   rÅ   rÆ   r¼   )r%   rD   rµ   r·   r   Úownr¾   s   &&     r   Ú_is_other_profiles_cwdrÔ   [  sÖ   € ð
 Òœ~¨l×;Ò;Ä2Ç7Á7Ç=Á=ÐQT×CUÒCUÙÝ2Ý8ðÜ˜“I×%Ñ%Ó'¬¨lÓ);×)FÑ)FÓ)H×)PÑ)PÓ)RˆcÙ&¨CÔ0×8Ñ8Ó:ˆð „{�cŸ\™\Ô)ÙØ˜$ �-Ð(Ñ(×iÐi¨T°JÕ->À4Ç<Á<Ñ,O×iÐiÑScÐdhÓSiÐiøô	 ”\Ð"ô Úðús   Á
AC3 Ã3DÄDc               ó   € V ^8„  d   QhRR/# ra   r   )r   s   "r   r   r   o  s   € ÷ ñ °ñ r   c                ó8  € \        T ;'       g    R4      p V '       d%   \        V4      '       d   \        W4      '       d   R# V '       d6   \        V4      '       g%   \        V4      '       g   \	        W4      '       d   R# V '       d   \        W4      '       d   R# V # )a~  A session row's stored cwd as a resume may adopt it: empty when an ssh session's row holds a path in Hermes's
own host tree (a host launch directory, never a remote workspace), when a sandbox session's row holds a launch
directory itself (:func:`_is_launch_dir`: rows written before launch dirs stopped being persisted), or when a
named profile's row holds another profile's (the resume then lands in :func:`_profile_default_cwd` and
re-persists it). Hydration and ``session.resume`` both adopt through here, then treat the result as the
session's workspace. A folder a sandbox user picked (even under the Hermes root or ``$HOME``) stays.r(   )r	   r2   rÉ   r‘   rÏ   rÔ   )r%   rD   s   &&r   Ú_resumable_stored_cwdr×   o  sk   € ô ˆc�iˆi�R‹.€Cß
Œ~˜l×+Ò+Ô0DÀS×0WÒ0WÙß
”> ,×/Ò/Ô8QÐR^×8_Ò8_Ü˜s×1Ò1Ùß
Ô% c×8Ò8ÙØ€Jr   c               ó    € V ^8„  d   QhRRRR/# )r   r%   r	   r
   r   )r   s   "r   r   r   �  s   € ÷ ñ ˜ð  ñ r   c                ó¸  € T ;'       g    RP                  4       pV'       d&   \        P                  P                  V4      '       d   V# Tp\	        ^@4       F[  p\        P                  P                  V4      pV'       d   WB8X  d    M-Tp\        P                  P                  V4      '       g   K[   M	  \        P                  P                  V4      '       g   V# \        P                  ! \        4      ;_uu_ 4        \        P                  ! V4      ;'       g!    \        P                  ! V4      ;'       g    TuuRRR4       #   + '       g   i     T# ; i)uR  Resolve a session cwd inside a now-deleted directory (e.g. a removed linked worktree, which probes to no branch
while the sidebar folds it to the main lane): walk up to the first existing ancestor and take its common git root.
Local backends only â€” a remote/SSH cwd may legitimately not exist on the host, so callers skip healing there.r(   N)rQ   r   r   r?   ÚrangeÚdirnamer;   r<   r=   r   Úcommon_repo_rootÚ	repo_root)r%   rG   ÚprobeÚ_Úparents   &    r   Ú_heal_dead_cwdrá   �  så   € ð �9ˆ9�"×
Ñ
Ó
€Cß”"—'‘'—-‘- ×$Ò$Øˆ
Ø€EÜ�2ŽYˆÜ—‘—‘ Ó'ˆß˜œÙØˆÜ�7‰7�=‰=˜×ÔÙñ ô �7‰7�=‰=˜×ÒØˆ
Ü	×	Ò	œY×	'Õ	'Ü×)Ò)¨%Ó0×WÐW´I×4GÒ4GÈÓ4N×WÐWÐRW÷ 
(×	'×	'Ñ	'à€Lús   Ã?;EÄ;EÅE	c               ó    € V ^8„  d   QhRRRR/# r˜   r   )r   s   "r   r   r   —  s   € ÷ 	4ñ 	4 {ð 	4°tñ 	4r   c                óŒ   € V '       d1   V P                  R4      '       d   \        V R,          4      R8w  d   R# \        4       R8H  # )a›  Whether THIS session's cwd can be stat'ed / git-probed here. A session bound to a named ssh profile never can,
whatever the launch process runs (one multiplexed gateway serves many profiles), and a per-profile gateway
(``hermes -p x``) may set ``terminal.backend: ssh`` in config without ``TERMINAL_ENV``: an env-only check would
heal a live remote cwd to its nearest host ancestor (``/home``) and persist that.rD   r,   F)r-   rA   rc   rˆ   s   &r   Ú_session_is_local_backendrä   —  s<   € ÷
 �7—;‘;˜~×.Ò.Ô3JÈ7ÐSaÕKbÓ3cÐgnÔ3nÙô 'Ó(¨GÑ3Ð3r   c               ó   € V ^8„  d   QhRR/# ra   r   )r   s   "r   r   r   £  s   € ÷ ñ  Sñ r   c                 óô   € \         P                  P                  R4      ;'       g    RP                  4       P	                  4       p V '       d   V R8X  d   \        R4      P	                  4       p T ;'       g    R# )zàActive terminal backend name (``local``, ``docker``, ``ssh``, ...): ``TERMINAL_ENV`` when set (launchers bridge
``terminal.backend`` into env), else the ``terminal.backend`` config key (in-process gateways skip that bridge).r^   r(   r,   rx   )r   r5   r-   rQ   r   rS   )rx   s    r   rc   rc   £  s[   € ô �z‰z�~‰~˜nÓ-×3Ð3°×:Ñ:Ó<×BÑBÓD€Gß�g Ô(Ü'¨	Ó2×8Ñ8Ó:ˆØ×Ð�gÐr   c               ó    € V ^8„  d   QhRRRR/# r„   r   )r   s   "r   r   r   ¬  s   € ÷ 	ñ 	 +ð 	°#ñ 	r   c                óš   € \        V 4      p\        V 4      '       g   V# \        V4      pV'       d   W!8w  d   V e   W R&   \        W4       V# )zpSession cwd for display/probe surfaces, healed past deleted worktrees (healed value persisted back; local only).r%   )r•   rä   rá   Ú*_persist_session_cwd_and_schedule_git_meta)r…   r%   Úhealeds   &  r   Ú_display_session_cwdrë   ¬  sF   € ä
�wÓ
€CÜ$ W×-Ò-Øˆ
Ü˜CÓ €Fß�&”- GÒ$7Ø�‰Ü2°7ÔCØ€Mr   c               ó    € V ^8„  d   QhRRRR/# r˜   r   )r   s   "r   r   r   ¸  s   € ÷ (ñ (°+ð (À$ñ (r   c                óä  € V '       d/   V P                  R4      '       d   V P                  R4      '       g   R# \        V 4      '       g   R#  ^ RIHp T! V P                  R4      ;'       g    R4      ;p'       g   R#  \
        P                  P                  \
        P                  P                  \        T4      4      4      p\
        P                  P                  \
        P                  P                  \        T 4      4      4      pY48X  g&   \
        P                  P                  T4      '       g   R# \        P                  ! T4      \        P                  ! T4      reT'       d   T'       d   YV8X  d   R# \        P                  ! T4      pT'       d   T\        P                  ! T4      8w  d   R# T P                  TRRR7       \!        T 4       \#        Y4       R#   \         d     R# i ; i)	a2  Re-anchor a session that SETTLED in another worktree of the SAME repo. Returns moved. An agent told to work in
a fresh worktree `git worktree add`s and `cd`s in while the session stays pinned (labelled with the primary
checkout's branch). A plain `cd` is deliberately NOT a workspace move (see ``_apply_project_workspace``): a non-git
workspace stepping into a repo or a visit to an unrelated repo is browsing, and a workspace the user deliberately
moved the chat into is never overridden. Local backends only (a remote cwd cannot be stat'ed or git-probed
here).Ú
cwd_pinnedÚcwd_from_settleF)Úget_session_cwdÚsession_keyr(   T)r%   rŒ   rï   )r-   rä   Útools.terminal_toolrð   r=   r   r   r>   r   r	   r•   r?   r   rÝ   rÜ   ÚupdateÚ_register_session_cwdré   )r…   rð   ÚrecordedrH   ÚcurrentÚlandedÚcurrent_rootÚlanded_commons   &       r   Ú$_reconcile_session_cwd_from_terminalrú   ¸  s^  € ÷ �w—{‘{ <×0Ò0¸¿¹ÐEV×9WÒ9WÙÜ$ W×-Ò-ÙðÝ7Ù+¨G¯K©K¸Ó,F×,LÐ,LÈ"ÓMÐM�ÖMÙð Nô �w‰w�‰œrŸw™w×1Ñ1´#°h³-Ó@ÓA€HÜ�g‰g�o‰oœbŸg™g×0Ñ0´¸gÓ1FÓGÓH€GØÔ¤"§'¡'§-¡-°×"9Ò"9Ùô %×.Ò.¨xÓ8¼)×:MÒ:MÈgÓ:VˆLßŸ¨Ô)?ÙÜ×.Ò.¨xÓ8€Mß˜M¬Y×-GÒ-GÈÓ-PÔPÙð ‡N�N�x¨dÀD€NÔIÜ˜'Ô"Ü.¨wÔAÙøô' ô Úðús   ÁG  Á-G  Ç G/Ç.G/c               ó$   € V ^8„  d   QhRRRRRR/# )r   Úsidr	   r…   rP   r
   ÚNoner   )r   s   "r   r   r   ã  s!   € ÷ >ñ > Cð >°$ð >À$ñ >r   c                óš   €  \        V4       \	        RV \        W!4      4       R#   \         d    \        P                  RRR7        L<i ; i)z Emit end-of-turn ``session.info``, reconciling a settled cwd first (the agent has stopped moving; riding the
turn-end event needs no new event type/round trip).z'failed to reconcile settled session cwdT©Úexc_infozsession.infoN)rú   r=   ÚloggerÚdebugÚ_emitÚ_session_info)rü   r…   Úagents   &&&r   Ú_emit_settled_session_infor  ã  sG   € ðOÜ,¨WÔ5ô 
ˆ.˜#œ}¨UÓ<Ö=øô ô OÜ�‰Ð>ÈˆÖNðOús   ‚% ¥"A
Á	A
c               ó    € V ^8„  d   QhRRRR/# r„   r   )r   s   "r   r   r   í  s   € ÷ 1ñ 1˜[ð 1¨Sñ 1r   c                ó¢   € V '       d3   \        V P                  R 4      ;'       g    R4      P                  4       MRpT;'       g    \        4       # )rž   r(   )r	   r-   rQ   Ú_resolve_session_platform)r…   rž   s   & r   rš   rš   í  s<   € ß9@ŒS�—‘˜XÓ&×,Ð,¨"Ó-×3Ñ3Ô5Àb€FØ×0Ð0Ô.Ó0Ð0r   c               ó    € V ^8„  d   QhRRRR/# )r   r…   r#   r
   rý   r   )r   s   "r   r   r   ò  s   € ÷ hñ h ;ð h°4ñ hr   c                ó°  € V '       g   R # \        V P                  R4      ;pR4      '       d!   V P                  R4      ;'       g    R Vn        V P                  R4      '       d   \        VRR 4      MR pVe<   \        VR4      '       d*   VP	                  \        V P                  R4      4      4       \        P                  ! \        4      ;_uu_ 4        ^ RI	H
p \        V 4      w  rE^ R Ip\        P                  ! 4       ;_uu_ 4       pV P                  R4      pV'       dh   VP                  VP                  4       4      VP                  V4      8w  d5   VP!                  VP"                  VP%                  \        V4      4      4       V! V R,          RVR	V/4       R R R 4       R R R 4       R #   + '       g   i     L; i  + '       g   i     R # ; i)
Nr  rC   r%   Ú_subdirectory_hintsÚrebind_working_dir)Úregister_task_env_overridesrD   rñ   Ú
cwd_source)Úhasattrr-   rC   Úgetattrr  r	   r;   r<   r=   rò   r  r‡   rÂ   Ú	ExitStackÚhermes_home_keyrÄ   ÚcallbackÚreset_hermes_home_overrideÚset_hermes_home_override)	r…   r  Úhintsr  r%   r  ÚhcÚstackrD   s	   &        r   rô   rô   ò  s_  € ßÙô ˜Ÿ™ GÓ,Ð,ˆu¨m×<Ò<Ø#ŸK™K¨Ó.×6Ð6°$ˆÔð
 <C¿;¹;Àu×;MÒ;MŒG�EÐ0°$Ô7ÐSW€EØÒœW UÐ,@×AÒAØ× Ñ ¤ W§[¡[°Ó%7Ó!8Ô9Ü	×	Ò	œY×	'Õ	'ÝCÜ8¸ÓA‰ˆó
 	&ä×!Ò!×#Ô# uØ"Ÿ;™; ~Ó6ˆLß × 2Ñ 2°2×3EÑ3EÓ3GÓ HÈB×L^ÑL^Ð_kÓLlÔ lØ—‘˜r×<Ñ<¸b×>YÑ>YÔZ]Ð^jÓZkÓ>lÔmÙ'¨°Õ(>ÀÈÈ\Ð[eÐ@fÔg÷	 $÷ 
(Ñ	'÷ $×#ú÷ 
(×	'Ð	'ús%   Ã5GÄ
BF1	ÆGÆ1GÆ<GÇG	c               ó    € V ^8„  d   QhRRRR/# )r   r…   rP   r
   ztuple[str, dict]r   )r   s   "r   r   r     s   € ÷ %Xñ %X tð %XÐ0@ñ %Xr   c                ó–  € \        V P                  R4      ;p\        4      '       d   TM/ p\        VP                  R4      ;'       g    R4      P	                  4       ;'       g    \        V 4      ^ ,          pR Uu/ uF)  qBP                  V4      ;p'       g   K  V\        V4      bK+  	  pp\        VP                  R4      ;'       g    R4      P	                  4       P                  4       R8X  dZ    ^ RIHp T! VP                  R4      ;'       g    RVP                  R4      ;'       g    T;'       g    RR	7      pV'       d   W†R&   V P                  R4      ;p	e   W–R&   V P                  R4      ;p
e   T
;'       g    RVR&   V P                  R4      ;p'       d   W¶R&   R F   pV P                  V4      '       g   K  RWl&   K"  	  \        V P                  R4      ;p\        4      '       d   WÖR&   ^ RIHp Y>! Y`P                  R4      ;'       g    R4      3# u upi   \         d    \        P                  R
RR7        Lüi ; i)a¢  ``(model, model_config)`` for a fresh session row. The session's own model/effort/fast pick (composer override
or restored /model switch) must own the row: the agent isn't built yet at first prompt.submit, and writing the
global default here wins the INSERT-OR-IGNORE race (a reconnect silently reverts to the profile default).
model_config carries provider/reasoning/service_tier so resume restores effort + fast too.Úmodel_overrideÚmodelr(   ÚproviderÚbase_urlÚcustom)Úcanonical_custom_identityN)r  r  z1custom provider identity recovery failed (db row)Trÿ   Úcreate_reasoning_overrideÚreasoning_configÚcreate_service_tier_overrideÚnormalÚservice_tierÚparent_session_idÚ_branched_fromÚcomposer_override_profile)Úwith_session_yolorñ   )r  r  r  Úapi_mode)Úroom_plumbingÚfollow_profile_config)rO   r-   rP   r	   rQ   Ú_session_default_router   Úhermes_cli.runtime_providerr!  r=   r  r  Útools.approval_yolor*  )r…   rG   ÚoverrideÚ	row_modelÚkÚvÚmodel_configr!  rê   Ú	reasoningr&  r'  ÚflagÚcomposer_profiler*  s   &              r   Ú_workdir_row_model_configr9    s#  € ô
 !¨¯©Ð4DÓ(EÐ!E Ät×LÒL‰sÐRT€HÜ�H—L‘L Ó)×/Ð/¨RÓ0×6Ñ6Ó8×^Ð^Ô<RÐSZÓ<[Ð\]Õ<^€IÙ-ZÓuÑ-Z¨×dpÑdpÐqrÓdsÐ_sÐ_`Ó_sœ)˜!œS ›Vš)Ñ-Z€LÐuô ˆ<×Ñ˜JÓ'×-Ð-¨2Ó.×4Ñ4Ó6×<Ñ<Ó>À(ÔJð	]ÝMÙ.Ø%×)Ñ)¨*Ó5×=Ð=¸À\×EUÑEUÐV]ÓE^×EsÐEsÐbk×EsÐEsÐosôuˆFçØ+1˜ZÑ(ð —[‘[Ð!<Ó=Ð=ˆ	ÒJØ+4Ð'Ñ(ØŸ™Ð$BÓCÐCˆÒPð (4×'?Ð'?°xˆ�^Ñ$à#ŸK™KÐ(;Ó<Ð<ÐÖ<Ø):Ð%Ñ&ó ;ˆØ�;‰;�t×ÔØ!%ˆLÓñ ;ô  g§k¡kÐ2MÓ&NÐNÐ"ÔPT×UÒUØ4DÐ0Ñ1Ý5ØÐ'¨·k±kÀ-Ó6P×6VÐ6VÐTVÓWÐWÐWùò= vøô ô 	]Ü�L‰LÐLÐW[ˆLÖ\ð	]ús6   Á<HÂHÃ3H# ÄH# Ä-	H# Ä7H# ÅH# È#"IÉIc               ó    € V ^8„  d   QhRRRR/# )r   r…   rP   r
   rg   r   )r   s   "r   r   r   8  s   € ÷ >ñ > Dð >¨Tñ >r   c                ó  € V P                  R4      ;p'       g   R# V P                  R4      p\        V R4      ;_uu_ 4       pV\        J d    RRR4       R# Vf   \        RJ uuRRR4       # \	        V 4      w  rE TP                  T\        V 4      YE;'       g    RV P                  R4      ;'       g    R\        V 4      \        V 4      \        V4      ;'       g    \        4       R7       V P                  R4      '       d,    VP                  VR	4      '       d   V P                  RR4       V P                  R4      '       d,    VP!                  VR	4      '       d   V P                  RR4       \#        WV4       RRR4       R	#   \         d    \        P                  R
R	R7        L|i ; i  \         d    \        P                  RR	R7        Lbi ; i  \         d   p\%        TR4        Rp?LvRp?ii ; i  + '       g   i     R	# ; i)uÐ  Idempotently persist the session's DB row on first real activity (prompt.submit), so abandoned drafts never
leave an empty "Untitled" session. INSERT OR IGNORE: re-calls and the AIAgent's lazy create are no-ops. Returns
False only when the store is unavailable (no openable state.db) â€” prompt.submit fails the send loudly instead of
streaming into a store that will never save it; no key / best-effort / success are all True.

A cwd the user *chose* is always persisted. Otherwise the launch directory stands in only for terminal sessions
(the user deliberately ``cd``'d there; dropping it left the sidebar with no cwd AND no git_repo_root); desktop
launch dirs (``/``, home) stay null -> "No workspace".

See #98924.
rñ   NrD   z)failed to open profile db for session rowFr'  )rž   r  r5  r'  r%   Úuser_idÚprofile_nameÚpending_hiddenTz#failed to apply pending hidden flagrÿ   Úpending_archivedz%failed to apply pending archived flagz%failed to persist desktop session row)r-   Ú_workdir_owner_dbÚ_WORKDIR_DB_OPEN_FAILEDÚ	_db_errorr9  Úcreate_sessionrš   r¤   Ú_session_auth_user_idÚprofile_name_for_homeÚ_current_profile_nameÚset_session_hiddenÚpopr=   r  r  Úset_session_archivedÚ_schedule_row_git_metaÚ_workdir_reraise_disk_full)r…   rK   rD   Údbr2  r5  Úexcs   &      r   Ú_ensure_session_db_rowrN  8  sñ  € ð —;‘;˜}Ó-Ð-ˆCÖ-Ùð —;‘;˜~Ó.€LÜ	˜7Ð$O×	PÔ	PÐTVØÔ(Ó(Ø÷ 
QÑ	Pð Š:ô
  Ð$÷ 
QÒ	Pô #<¸GÓ"DÑˆ	ð"	UØ×ÑØœO¨GÓ4¸I×ThÐThÐdhØ")§+¡+Ð.AÓ"B×"JÐ"JÀdÔPfÐgnÓPoô
 .¨gÓ6ô 3°<Ó@×[Ð[ÔDYÓD[ð ô ]ð  �{‰{Ð+×,Ò,ðWØ×,Ñ,¨S°$×7Ò7ØŸ™Ð$4°dÔ;ð �{‰{Ð-×.Ò.ðYØ×.Ñ.¨s°D×9Ò9ØŸ™Ð$6¸Ô=ô # 7°Ô4÷Q 
QñZ øô !ô WÜ—L‘LÐ!FÐQU�LÖVðWûô !ô YÜ—L‘LÐ!HÐSW�LÖXðYûô ô 	Uô ' sÐ,S×TÑTûð	Uú÷S 
QÖ	PñZ ús—   ÁG:ÁG:Á-G:Á;8GÂ4AGÄFÄFÄ.GÅF.ÅF.Å0GÆ"F+Æ(GÆ*F+Æ+GÆ."GÇGÇGÇGÇG7Ç!G2Ç-G:Ç2G7Ç7G:Ç:H	c               ó$   € V ^8„  d   QhRRRRRR/# )r   r…   rP   rK   r	   r
   rý   r   )r   s   "r   r   r   y  s&   € ÷ Hñ H Dð H¨sð H¸4ñ Hr   c                ó’  € V P                  R4      '       d   R# RV R&   \        VR4      '       d   VP                  V4      MR;'       g    / p\        VP                  R4      ;'       g    R4      P	                  4       pV'       d@   VP                  R4      '       d   VP                  R4      '       g   \        WVR	7       R# R# R# )
a”  Git-enrich a lazily created row once per live session. The row lands here with its cwd on the first submit, so
``_hydrate_session_cwd`` (which ran when no row existed) never claimed a probe, and a desktop row kept NULL
git_branch/git_repo_root for life: its lane fell back to a fake ``main`` label (#108784). Probes the row's own
cwd (the upsert never overwrites it), and only when enrichment is missing.Úrow_git_meta_checkedNTÚget_sessionr%   r(   Ú
git_branchÚgit_repo_root)rL  )r-   r  rR  r	   rQ   ré   )r…   rK   rL  Úrowr%   s   &&&  r   rJ  rJ  y  sš   € ð
 ‡{�{Ð)×*Ò*ÙØ&*€GÐ"Ñ#Ü")¨"¨m×"<Ò"<ˆ2�>‰>˜#ÔÀ$×
MÐ
MÈ2€CÜ
ˆc�g‰g�e‹n×"Ð" Ó
#×
)Ñ
)Ó
+€Cß
�C—G‘G˜L×)Ò)¨c¯g©g°o×.FÒ.FÜ2°7ÀB×Gñ /G�sr   c               ó$   € V ^8„  d   QhRRRRRR/# )r   rM  ÚBaseExceptionÚlog_msgr	   r
   rý   r   )r   s   "r   r   r   ‡  s!   € ÷ )ñ ) Mð )¸Cð )ÀDñ )r   c                ó`   € ^ RI Hp V! V 4      '       d   V h\        P                  VRR7       R# )zRRe-raise a disk-full write error (the caller must surface it); debug-log the rest.)Úis_disk_full_errorTrÿ   N)Úhermes_state_errorsrZ  r  r  )rM  rX  rZ  s   && r   rK  rK  ‡  s%   € å6Ù˜#×ÒØˆ	Ü
‡L�L� 4€LÖ(r   c               ó    € V ^8„  d   QhRRRR/# )r   r…   rP   r
   rý   r   )r   s   "r   r   r   –  s   € ÷ Jñ J $ð J¨4ñ Jr   c                ó„  € V P                  R4      ;p'       d/   V P                  R4      '       d   V P                  R4      '       d   R# ^ RIHp ^ RIHp V R,          ;_uu_ 4        \        V P                  R4      ;'       g    . 4      pV UUu. uFD  pR	VP                  R	R
4      /\         Uu/ uF  qfVP                  V4      bK  	  upCV! V4      CNKF  	  pppRRR4       X'       g   R# \        V 4      ;_uu_ 4       pVf    RRR4       R#  VP                  WRR7       V R,          ;_uu_ 4        V! XV4       RRR4       RV R&   RRR4       R# u upi u uppi   + '       g   i     LŽ; i  + '       g   i     L=; i  \         d   p	\        T	R4        Rp	?	LWRp	?	ii ; i  + '       g   i     R# ; i)a2  Persist a seeded transcript once its row exists. Seeded messages (a branch's copied parent, a client's
opening turns) live only in ``session["history"]`` (ridden into the agent as ``conversation_history``, which
``_flush_messages_to_session_db`` skips by identity), so the row would otherwise resume without them. Runs
once: at create for a seeded session, else at the first submit after ``_ensure_session_db_row`` wrote the
row. ``seeded`` is stamped by session.create; a resumed session carries its stored transcript in
``history`` and must never re-append it.rñ   ÚseededÚ_branch_seed_persistedN)Úmessage_identity)Úsync_flushed_message_markersÚhistory_lockÚhistoryÚroleÚuseriô  )Ú
chunk_rowsTzbranch seed persist failed)r-   Úagent.message_metadatar`  Úagent.transcript_repairra  ÚlistÚ_WORKDIR_SEED_FIELDSÚ_session_dbÚappend_messages_batchr=   rK  )
r…   rK   r`  ra  ÚliveÚmsgÚfÚseedrL  rM  s
   &         r   Ú_persist_branch_seedrq  –  s‚  € ð —;‘;˜}Ó-Ð-ˆCÖ-°g·k±kÀ(×6KÒ6KÈwÏ{É{Ð[s×OtÒOtÙÝ7ÝDØ	�×	 ×	 Ü�G—K‘K 	Ó*×0Ð0¨bÓ1ˆá59ô;Ù59¨cð ˜Ÿ™ ¨Ó0ð *ÕL`Ó4aÑL`Àq¸¿¹À»
²]ÑL`Ñ4að *Ù# CÓ(ó*Ù59ð 	ñ ;÷ 
!÷ ÙÜ	�W×	Ô	 ØŠ:Ø÷ 
Ñ	ð
	Jð
 ×$Ñ$ S¸3Ð$Ô?Ø˜×(×(Ù,¨T°4Ô8÷ )à04ˆGÐ,Ñ-÷ 
Ñ	ùò	 5bùó ;÷ 
!×	 ú÷ )×(ûô ô 	JÜ& sÐ,H×IÑIûð	Jú÷ 
×	Ð	úsx   Á'*E$Â E
Â1EÃE
ÃE$ÄF.Ä$F
Ä8
E7	ÅF
ÅE
ÅE$Å$E4	Å7FÆF
Æ
F+ÆF&Æ!F.Æ&F+Æ+F.Æ.F?	c               ó    € V ^8„  d   QhRRRR/# )r   r…   rP   r
   r	   r   )r   s   "r   r   r   ·  s   € ÷ qñ q Dð q¨Sñ qr   c                ó¸   € \        \        V P                  R4      RR4      ;'       g    R4      ;'       g%    \        V P                  R4      ;'       g    R4      # )uF  The session row an off-turn submit write must use: the live ``agent.session_id`` when it has
rotated off ``session_key``, else ``session_key`` itself.

The turn's own transcript is flushed under ``agent.session_id`` (``_db_flush_write``), while an
off-turn write only has ``session_key`` to go on â€” and those diverge for the whole of a turn that
begins after the agent's session rotated: a compression publish, an adopted continuation tip, or a
lease-wait re-resolve all move ``agent.session_id`` while ``session_key`` is re-anchored only at
TURN END (``_absorb_turn_result`` -> ``_sync_session_key_after_compress``). Writing the submit row
to the stale key splits one turn's rows across two sessions: the user row in the parent, every tool
row and the final text in the child (#123545, evidence A + B).

The live id IS the authority â€” it is the value the turn will flush under, and the same
``getattr(agent, "session_id", None) or session_key`` the sibling system-prompt persist already uses
against this handle (``_persist_live_session_system_prompt``). Do NOT re-resolve through the lineage
here: ``resolve_resume_session_id`` returns the deepest node that has MESSAGES, so the freshly-minted
child of a just-published rotation resolves back to the parent and the fix would no-op exactly when
it is needed. The choice is made ONCE here and recorded on the staged dict under
``_SUBMIT_ROW_SESSION_KEY`` so every later addresser of that row â€” the @-expansion rewrite, the
queue merge, the drain deactivation â€” reads the same key instead of re-deriving one that a rotation
can invalidate mid-turn.
r  r'   Nr(   rñ   )r	   r  r-   rˆ   s   &r   Ú_submit_row_target_keyrt  ·  sI   € ô, Œw�w—{‘{ 7Ó+¨\¸4Ó@×FÐFÀBÓG×pÐpÌ3ÈwÏ{É{Ð[hÓOi×OoÐOoÐmoÓKpÐpr   Ú_submit_row_session_idc               ó$   € V ^8„  d   QhRRRRRR/# )r   ÚstagedrP   r…   r
   r	   r   )r   s   "r   r   r   Õ  s!   € ÷ 7ñ 7 $ð 7°ð 7¸#ñ 7r   c                ó|   € \        V P                  \        4      ;'       g    R4      pT;'       g    \        V4      # )a%  The session id a staged submit row lives under: recorded at write time, else the current best.
Every caller narrows to a dict (and checks ``_row_id``) immediately before, so the recorded value is
the answer whenever the row exists; the re-derivation only covers a dict that predates the stamp.r(   )r	   r-   Ú_SUBMIT_ROW_SESSION_KEYrt  )rw  r…   rõ   s   && r   Ú_submit_row_owner_keyrz  Õ  s4   € ô �6—:‘:Ô5Ó6×<Ð<¸"Ó=€HØ×6Ð6Ô-¨gÓ6Ð6r   c          
     ó,   € V ^8„  d   QhRRRRRRRRR	R/# )
r   r…   rP   Útextr   Údisplay_kindrl   Úaccept_metadatar#   r
   r   )r   s   "r   r   r   Ý  s1   € ÷ %ñ % Dð %°ð %À:ð %Ø,7ð%ØCNñ%r   c                óp  € V P                  R4      '       d-   \        V\        4      '       d   VP                  4       '       g   R# ^ RIHp ^ RIHpHp V! RRRV/4      pV'       d   W'R&   V'       d   / VCVR	&   \        V 4      ;_uu_ 4       pVf    RRR4       R# \        V 4      p	 VP                  V	RWVR
,          V! V4      VP                  R	4      R7      VR&    RRR4       RYt&   X	T\        &   T#   \         d    p
\        T
R4        Rp
?
RRR4       R# Rp
?
ii ; i  + '       g   i     LL; i)u\  Write the submitted user turn to the transcript and RETURN the durable dict (stamped
``_DB_PERSISTED_MARKER``/``_row_id``) WITHOUT slotting it on the session. The write half of
:func:`_persist_submit_user_row`, shared by the busy-queue accept (which attaches the dict to
the queue envelope, never the shared session slot a possibly-still-staged in-flight turn owns).
``accept_metadata`` merges into ``display_metadata`` (the busy-queue accept's never-drained
marker, retired by ``reopen_session`` â€” #125577).
Returns None when nothing was written (no key / non-text / store unavailable / failed write).rñ   N)Ú_DB_PERSISTED_MARKER)Ústamp_message_timestampÚstamp_message_uidrd  re  Úcontentr}  Údisplay_metadataÚ	timestamp)rƒ  r}  r…  Úmessage_uidr„  Ú_row_idz#submit-time user row persist failedT)r-   rO   r	   rQ   Úagent.context_compressorr€  rg  r�  r‚  rk  rt  Úappend_messager=   rK  ry  )r…   r|  r}  r~  r€  r�  r‚  rw  rL  ÚtargetrM  s   &&&&       r   Ú_write_submit_user_rowr‹  Ý  s#  € ð �;‰;�}×%Ò%¬Z¸¼c×-BÒ-BÈ$Ï*É*Ï,Ê,ÙÝ=ßQÙ$ f¨f°iÀÐ%FÓG€FßØ!-ˆ~ÑßØ%8¨Ð%8ˆÐ!Ñ"Ü	�W×	Ô	 ØŠ:Ø÷ 
Ñ	ô (¨Ó0ˆð	Ø "× 1Ñ 1Ø˜¨ÐSYÐZeÕSfÙ-¨fÓ5Ø!'§¡Ð,>Ó!?ð !2ó !AˆF�9Ò÷ 
ð $(€FÑ ð '-€FÔ"Ñ#Ø€Møô ô 	Ü& sÐ,QÔRÛ÷ 
Ñ	ûð	ú÷ 
×	ús6   ÂD%ÂD%Â*6C8Ã8D"ÄDÄD%ÄD"Ä"D%Ä%D5	c          
     ó,   € V ^8„  d   QhRRRRRRRRR	R
/# )r   r…   rP   r|  r   r}  rl   r~  r#   r
   rý   r   )r   s   "r   r   r     s1   € ÷ -ñ - dð -°#ð -ÀZð -Ø.9ð-ØEIñ-r   c                óV   € V P                  RR4       \        WW#4      ;pe   W@R&   R# R# )a˜  Write the submitted user turn at send time, before the agent build and turn: the agent's own
crash persist only runs once the build finished, so quitting a frozen app during a slow first build
left a session row with no message (#111868). The dict is staged on the session already stamped
durable (the shape ``quiet_single_query`` re-stages an unanswered DM in) so the turn adopts it via
``_stage_turn_user_message`` and the flush writes no second row. A failed write stages nothing:
the turn's crash persist then writes the row as before. ``accept_metadata`` marks a row that
belongs to a still-QUEUED envelope (#125577); a dispatching turn's row is never marked.Ú_submit_user_rowN)rH  r‹  )r…   r|  r}  r~  rw  s   &&&& r   Ú_persist_submit_user_rowr�    s4   € ð ‡K�KÐ" DÔ)Ü(¨¸ÓVÐVˆÒcØ&,Ð"Ó#ñ dr   c               ó(   € V ^8„  d   QhRRRRRRRR/# )r   r…   rP   Úpersist_user_messager   r|  r
   rý   r   )r   s   "r   r   r     s*   € ÷ 1ñ 1 Dð 1Àsð 1ÐRUð 1ÐZ^ñ 1r   c           	     ód  € V P                  RR4      p\        V\        4      '       d   Ve   VP                  R4      V8w  d   R# VR,          V8w  da   ^ RIHp \        V 4      ;_uu_ 4       pVf    RRR4       R#  VP                  \        W@4      VR,          V! V4      4        RRR4       Y$R&   ^ R	IHp V! V4      ;_uu_ 4        WAn        RRR4       R#   \         d$    \        P                  RRR7        RRR4       R# i ; i  + '       g   i     Ll; i  + '       g   i     R# ; i)
aV  Hand the row written at submit to the turn as its user dict (``agent._pending_cli_user_message``,
adopted by ``_stage_turn_user_message`` when the content matches). A prompt the prologue rewrote
(@-expansion, image parts) first updates that row so the durable transcript replays what the model
was sent and the ``api_content`` sidecar can address it; ``_row_id`` rides along for that stamp.
``text`` is THIS turn's raw submit: a staged row from an earlier send (its turn ended before the agent
ran) is discarded untouched, so the DB row stays the user's message and never a synthesized turn's text.rŽ  Nrƒ  )Ú_durable_contentr‡  z?submit-time user row update failed; the turn writes its own rowTrÿ   )Ú_persist_lock)rH  rO   rP   r-   Úagent.session_persistencer“  rk  Úset_user_message_contentrz  r=   r  r  r”  Ú_pending_cli_user_message)r…   r  r‘  r|  rw  r“  rL  r”  s   &&&&    r   Ú_adopt_submit_user_rowr˜    s  € ð �[‰[Ð+¨TÓ2€FÜ�fœd×#Ò# u¢}¸¿
¹
À9Ó8MÐQUÔ8UÙØˆiÕÐ0Ô0Ý>Ü˜×!Ô! RØŠzØ÷ "Ñ!ð	ð ×+Ñ+Ü)¨&Ó:¸FÀ9Õ<MÙ$Ð%9Ó:õ<÷ "ð 1ˆyÑÝ7Ù	�u×	Õ	Ø*0Ô'÷ 
Ñ	øô ô Ü—‘Ð^Ðim�ÔnØ÷ "Ñ!ðú÷ "×!ú÷ 
×	Ð	ús6   Á,DÁ=)CÃ	DÃ"DÃ<DÄDÄDÄD	ÄD/	c               ó    € V ^8„  d   QhRRRR/# )r   r…   rP   Úfail_logr	   r   )r   s   "r   r   r   7  s   € ÷ %ñ %˜tð %¨sñ %r   c           	   #  óz  "  € RRr2V P                  R4      ;p'       d"    ^ RIHp V! \        V4      R,          4      Rr2M
\        4       p Vx € V'       dB   Ve<   \        P                  ! \        4      ;_uu_ 4        ^ RIHp V! V4       RRR4       R# R# R#   \         d!    \
        P                  TRR7       \        p Lzi ; i  + '       g   i     R# ; i  T'       dS   TeN   \        P                  ! \        4      ;_uu_ 4        ^ RIHp T! T4       RRR4       i   + '       g   i     i ; ii i ; i5i)	zwBody of :func:`_session_db`; ``_ensure_session_db_row`` uses it directly so a patched ``_session_db`` can't alter rows.NFrD   )Úacquirezstate.dbTrÿ   )Úrelease_or_close)r-   Úhermes_state_registryrœ  rY   r=   r  r  rA  Ú_get_dbr;   r<   r�  )r…   rš  rL  Úclose_dbrD   rœ  r�  s   &&     r   r@  r@  6  sò   é € ð ˜ˆØ—{‘{ >Ó2Ð2€|Ö2ð	)Ý5Ù"¤4¨Ó#5¸
Õ#BÓCÀT‘ô
 ‹Yˆð%ØŠç˜šÜ×$Ò$¤Y×/Õ/ÝBÙ  Ô$÷ 0Ñ/ñ '‰8øô ô 	)Ü�L‰L˜¨DˆLÔ1Ü(ŠBð	)ú÷ 0×/Ð/û÷ ˜šÜ×$Ò$¤Y×/Õ/ÝBÙ  Ô$÷ 0×/×/Ð/úð 'ˆ8üso   ‚D; B ¿D;ÁC Á.D;Á=CÂD;Â(CÃD;ÃCÃD;ÃC	Ã	D;Ã/D8ÄD#	Ä	D8Ä#D3Ä.
D8Ä8D;c               ó   € V ^8„  d   QhRR/# )r   r…   rP   r   )r   s   "r   r   r   M  s   € ÷ <ñ <˜ñ <r   c              #  ó�   "  € \        V R4      ;_uu_ 4       pV\        J d   RMTx € RRR4       R#   + '       g   i     R# ; i5i)zîYield the SessionDB that owns this session's row (profile-aware): a remote/profile session persists into its own
profile's ``state.db`` (fresh handle, closed on exit); else the shared ``_get_db()`` handle (left open). None if unavailable.z%failed to open profile db for sessionN)r@  rA  )r…   rL  s   & r   rk  rk  L  s7   é € ô 
˜7Ð$K×	LÔ	LÐPRØÔ3Ó3‰d¸Ò;÷ 
M×	L×	LÒ	Lüs   ‚A—2¨
A²A	½	AÚrequire_retryableFc               ó(   € V ^8„  d   QhRRRRRRRR/# )	r   r…   rP   Úuser_ordinalÚintr£  rg   r
   ztuple[list[dict], dict, int]r   )r   s   "r   r   r   T  s,   € ÷ %/ñ %/Øð%/Ø!$ð%/Ø<@ð%/ØMiñ%/r   c          
     ó`  € ^ RI HpHpHp \	        V P                  R. 4      4      p\        V4       UUu. uF  w  rxV! V4      f   K  VNK  	  p	ppV^ 8  g   V\        V	4      8¼  d   \        R4      h\        V P                  R4      ;'       g    R4      P                  4       p
V
'       dd   \        V 4      ;_uu_ 4       pVf   \        R4      hVP                  W¡WbRR	7      pRRR4       XP                  VP                  VP                   rþpMDW‘,          pV! VV4      w  rÞ\        V4      V,
          pV'       d   V! VP                  R
4      4       V Uu. uF  pVP#                  4       NK  	  ppWÐR&   \%        V P                  R^ 4      4      ^,           V R&   V P                  R4      pVe^   VVn        \)        VR4      '       d   V
'       d   \        V4      M^ Vn        \)        VR4      '       d   V
'       d
   VR,          MRVn        WÞV3# u uppi   + '       g   i     EL=; iu upi )a.  Rewind one canonical user turn while retaining carrier scaffolding. Caller holds ``history_lock``. Persistent
sessions go through ``SessionDB.rewind_user_turn`` (the durable transcript is the authority; memory is installed
only after the commit); a session without a key rewinds the warm history alone.)Ú#history_before_user_originated_turnÚretryable_user_textÚuser_originated_turn_viewrc  Nz3target user message is no longer in session historyrñ   r(   zsession database is unavailableT)Úwarm_historyr£  Úadopt_row_idsrƒ  Úhistory_versionr  Ú_last_flushed_db_idxÚ_db_flush_scan_prefix:NNN)rˆ  r¨  r©  rª  Ú&_history_without_ephemeral_scaffoldingr-   Ú	enumerater   r�   r	   rQ   rk  rÆ   Úrewind_user_turnÚprefixÚ	live_viewÚrewound_countÚcopyr¦  Ú_session_messagesr  r®  r¯  )r…   r¥  r£  r¨  r©  rª  rc  ÚiÚmÚuser_indicesrñ   rL  ÚoutcomeÚ	installedr´  rµ  Útarget_indexÚmessager  s   &&$                r   Ú_rewind_active_session_historyr¿  T  sä  € ÷
 }Ñ|ä4°W·[±[ÀÈBÓ5OÓP€GÜ"+¨GÔ"4ÔaÑ"4™$˜!Ñ8QÐRSÓ8T—A�AÑ"4€LÑaØ�aÔ˜<¬3¨|Ó+<Ô<ÜÐNÓOÐOÜ�g—k‘k -Ó0×6Ð6°BÓ7×=Ñ=Ó?€KßÜ˜×!Ô! RØŠzÜ"Ð#DÓEÐEØ×)Ñ)Ø¸Ø"ð *ó $ˆG÷ "ð /6¯n©n¸g×>OÑ>OÐQX×QfÑQf˜mˆ	˜mà#Õ1ˆÙBÀ7ÈLÓYÑˆ	Ü˜G› |Õ3ˆßÙ 	§¡¨iÓ 8Ô9á/8Ó9©y G�—‘–©y€IÐ9Ø"ˆIÑÜ!$ W§[¡[Ð1BÀAÓ%FÓ!GÈ!Õ!K€GÐÑØ�K‰K˜Ó €EØÒØ"+ˆÔÜ�5Ð0×1Ò1ß;F¬¨Y¬ÈAˆEÔ&Ü�5Ð1×2Ò2ß:E¨)°A®,È4ˆEÔ'Ø Ð.Ð.ùó; b÷
 "×!Ð!üò :s   ´HÁHÂ?$HÅH+ÈH(	c               ó    € V ^8„  d   QhRRRR/# )r   rc  z
list[dict]r
   r   )r   s   "r   r   r   |  s   € ÷ ]ñ ]°Jð ]À:ñ ]r   c                óv   € ^ RI Hp V  Uu. uF"  q!! V4      '       d   K  VP                  4       NK$  	  up# u upi )zDReturn the durable transcript shape without transient recovery rows.)Ú_is_ephemeral_scaffolding)r•  rÂ  r¶  )rc  rÂ  r¾  s   &  r   r°  r°  |  s.   € åCÙ*1Ó\©'˜wÐ9RÐSZ×9[ŒNˆG�L‰LŽN©'Ñ\Ð\ùÒ\s   ‹6Ÿ6c               ó   € V ^8„  d   QhRR/# rf   r   )r   s   "r   r   r   ‚  s   € ÷ `ñ `¨Tñ `r   c                óv   € \        V \        4      '       * ;'       d    \        V \        4      ;'       d    V ^8¬  # )z>A claimed DB probe generation: a positive int (bool excluded).)rO   rg   r¦  )Ú
generations   &r   Ú_workdir_valid_generationrÆ  ‚  s0   € ä˜*¤dÓ+Ô+×_Ð_´
¸:ÄsÓ0K×_Ð_ÐPZÐ^_ÑP_Ð_r   c               ó(   € V ^8„  d   QhRRRRRRRR/# )	r   r…   rP   r%   r	   rÅ  r¦  r
   rý   r   )r   s   "r   r   r   ‡  s.   € ÷ Hñ H tð H°#ð HÀ3ð HÈ4ñ Hr   c                ó  aaaa€ V P                  RR4      oS'       d   S'       d   \        S4      '       g   R# RSRV P                  R4      /oR VVVV3R llp\        P                  VRRR	7      P	                  4        R# )
a=  Resolve + persist a session's git branch / repo root on a daemon thread: inline ``git`` probes on the
session-init / cwd-set path would stall startup on a slow or unreachable ``cwd``. Persists via the same
profile-aware db the caller wrote ``cwd`` to. Best-effort: a probe failure leaves the enrichment columns unset.rñ   r(   NrD   c               ó   € V ^8„  d   QhRR/# ©r   r
   rý   r   )r   s   "r   r   Ú/_persist_session_git_meta.<locals>.__annotate__‘  s   € ÷ 	Rñ 	R�$ñ 	Rr   c            	     óf  <€  \         P                  ! S4      \         P                  ! S4      rV '       g   V'       g   R # \        S4      ;_uu_ 4       pVe   VP	                  SSSW4       R R R 4       R #   + '       g   i     R # ; i  \
         d    \        P                  RRR7        R # i ; i)Nz&failed to persist session git metadataTrÿ   )r   ÚbranchrÜ   rk  Úpublish_session_git_metadatar=   r  r  )rÍ  r¾   rL  r%   Ú
db_sessionrÅ  rñ   s      €€€€r   Ú_runÚ'_persist_session_git_meta.<locals>._run‘  s‡   ø€ ð	RÜ$×+Ò+¨CÓ0´)×2LÒ2LÈSÓ2Q�DßŸdÙÜ˜Z×(Ô(¨BØ’>Ø×3Ñ3°KÀÀjÐRXÔ_÷ )×(×(Ò(ûô ô 	RÜ�L‰LÐAÈDˆL×Qð	Rús5   ƒ:B
 Á B
 ÁA6Á,B
 Á6B	ÂB
 ÂB
 Â
"B0Â/B0zgit-metaT)rŠ  r   Údaemon)r-   rÆ  Ú	threadingÚThreadÚstart)r…   r%   rÅ  rÐ  rÏ  rñ   s   &ff @@r   Ú_persist_session_git_metarÖ  ‡  sk   û€ ð —+‘+˜m¨RÓ0€KßŸcÔ)BÀ:×)NÒ)NÙà ¨n¸g¿k¹kÈ.Ó>YÐZ€J÷	Ró 	Rô ×Ñ˜D z¸$ÐÓ?×EÑEÖGr   rL  c               ó$   € V ^8„  d   QhRRRRRR/# )r   r…   rP   r%   r	   r
   z
int | Noner   )r   s   "r   r   r   Ÿ  s"   € ÷ ñ ¸ð À3ð ÐWañ r   c               óŒ  €  Ve   \         P                  ! V4      M
\        V 4      ;_uu_ 4       pVf    RRR4       R# VP                  V P	                  RR4      V4      pRRR4       \        X4      '       g   R# \        YT4       T#   + '       g   i     L1; i  \
         d    \        P                  RRR7        R# i ; i)z>Claim a DB-backed probe generation, then start Git enrichment.Nrñ   r(   zfailed to persist session cwdTrÿ   )
r;   Únullcontextrk  Úupdate_session_cwdr-   r=   r  r  rÆ  rÖ  )r…   r%   rL  Úowner_dbrÅ  s   &&$  r   ré   ré   Ÿ  s°   € ðØ,.ªNŒj×$Ò$ RÔ(ÄÈGÓ@T×TÐTÐYaØÒØ÷ UÑTð "×4Ñ4°W·[±[ÀÐPRÓ5SÐUXÓYˆJ÷ Uô % Z×0Ò0ÙÜ˜g¨JÔ7ØÐ÷ U×Tûô ô Ü�‰Ð4¸tˆÔDÚðús8   ‚-B ¯B
µB ¿"B
Á!B Â
B	ÂB ÂB Â"CÃCc               ó$   € V ^8„  d   QhRRRRRR/# )r   r…   rP   r%   r	   r
   r   )r   s   "r   r   r   ¯  s!   € ÷ ñ ˜dð ¨ð °ñ r   c                óh  € ^ RI Hp V! \        V4      4      p\        V P	                  R4      V4      pV P                  VRRRR7       \        V 4       \        W4       \        P                  ! \        4      ;_uu_ 4        ^ RIHp V! V R,          4       RRR4       V#   + '       g   i     T# ; i)	é    )Útranslate_cwd_for_wsl_backendrD   TF)r%   rŒ   rî   rï   )Ú
cleanup_vmrñ   N)rÂ   rß  r	   r‚   r-   ró   rô   ré   r;   r<   r=   Útools.terminal_tool_lifecyclerà  )r…   r%   rß  rH   rà  s   &&   r   Ú_set_session_cwdrâ  ¯  sŒ   € Ý>Ù
'¬¨C«Ó
1€CÜ˜gŸk™k¨.Ó9¸3Ó?€Hð ‡N�N�x¨d¸tÐUZ€NÔ[Ü˜'Ô"ä.¨wÔAÜ	×	Ò	œY×	'Õ	'Ý<Ù�7˜=Õ)Ô*÷ 
(ð €O÷ 
(Ö	'ð €Oús   Â B Â B1	c               ó   € V ^8„  d   QhRR/# rÊ  r   )r   s   "r   r   r   ¿  s   € ÷ 0ñ 0˜ñ 0r   c                ó2   € \        \        4       V RR7       R# )zFPublish this module's helpers onto ``server``, rebound to its globals.)ÚskipN)rß   )r   Úglobals)Úservers   &r   Úregisterrè  ¿  s   € ä”“	˜6¨×/r   r»   )	rƒ  r6  Úreasoning_contentÚreasoning_detailsÚcodex_reasoning_itemsÚcodex_message_itemsr}  r„  r…  )EÚ__doc__Ú
__future__r   r;   Útypingr   Útui_gatewayr   Ú
method_ctxr   r    rI   rS   rZ   r_   rA   r2   r9   r8   r@   r6   r1   r3   r‚   r‰   r‡   r•   r›   rœ   r¡   r¤   r�   r‘   rÉ   rÏ   rÔ   r×   rá   rä   rc   rë   rú   r  rš   rô   r9  rN  rJ  rK  rj  rq  rt  ry  rz  r‹  r�  r˜  ÚobjectrA  Úcontextmanagerr@  rk  r¿  r°  rÆ  rÖ  ré   râ  rè  r   r   r   Ú<module>rô     sž  ðñõ
 #ã Ý å !å #õ÷.õbõ
õLõvõ:õ[õFõ<õ
õ"Qõõ
õ6õ(õBXð
  )˜kÐ õyõ
1õ:1õ\õNõ&aõ$4õ*jõ(õ$õ,	4õõ	õ(õV>õ1õ
hõ<%XõP>õBHõ)ðLÐ õ
JõBqð6 3Ð õ7÷%÷P-õ1ñ@ !›(Ð ð ×Ñô%ó ð%ð* ×Ñô<ó ð<ð%/ØCH÷%/õP]õ`õ
Hð0Èd÷ õ ÷ 0r   