+
    lHàjÄO  ã                   óX  € R t ^ RIt^ RIt^ RIt^ RIt^ RIt^ RIHt ^ RIH	t	 ^ RI
HtHtHt ^ RIHt ^ RIHt ^ RIHtHt ^ RIHt R!tR"t ! R	 R
4      tR R ltR R ltR R ltR#R R llt ! R R]4      t ! R R4      tR#R R llt R#R R llt!R R lt"R#R R llt#R#R R  llt$R# )$a  Process-handle plumbing for ``tools.environments.base``.

Bounded output capture (head/tail window + disk spill), the ``ProcessHandle``
duck type, the SDK adapter ``_ThreadedProcessHandle``, stdin piping, and the
stdout drain thread used by ``BaseEnvironment._wait_for_process``.
N)Údeque)ÚPath)ÚIOÚCallableÚProtocol)Úget_hermes_home)Úopen_fd_waiter)Úhead_tail_splitÚtruncation_notice)Úwindows_hide_flagsc                   óÆ   a € ] tR t^t o RtRtRV 3R lR lltV 3R lR ltV 3R lR	 lt]	V 3R
 lR l4       t
]	V 3R lR l4       tV 3R lR ltRR/V 3R lR lltRtV tR# )Ú_BoundedOutputCollectorzõRetain a bounded 40/60 head-tail window of streamed text. When ``spill_path`` is set,
the FULL stream is also teed to that file once eviction begins (up to ``_SPILL_CAP_CHARS``)
so a truncated foreground result is recoverable without re-running.i@KL Nc                ó4   <€ V ^8„  d   QhRS[ RS[R,          /# )é   Ú	max_charsÚ
spill_pathN)Úintr   )ÚformatÚ__classdict__s   "€ÚC/home/ubuntu/.hermes/hermes-agent/tools/environments/base_output.pyÚ__annotate__Ú$_BoundedOutputCollector.__annotate__%   s   ø€ ÷ #ñ #¡#ð #±4¸$µ;ñ #ó    c                ó€  € \        ^\        V4      4      V n        \        V P                  R,          4      V n        V P                  V P                  ,
          V n        . V n        \        4       V n        ^ V n        ^ V n	        ^ V n
        \        P                  ! 4       V n        W n        RV n        ^ V n        RV n        R# )é   gš™™™™™Ù?NF)Úmaxr   r   Ú_head_limitÚ_tail_limitÚ_headr   Ú_tailÚ_head_charsÚ_tail_charsÚ_total_charsÚ	threadingÚLockÚ_lockÚ_spill_pathÚ	_spill_fhÚ_spill_charsÚ_spill_capped)Úselfr   r   s   &&&r   Ú__init__Ú _BoundedOutputCollector.__init__%   s”   € Ü˜Q¤ I£Ó/ˆŒÜ˜tŸ~™~°Õ3Ó4ˆÔØŸ>™>¨D×,<Ñ,<Õ<ˆÔØ "ˆŒ
Ü!&£ˆŒ
ØˆÔØˆÔØˆÔÜ—^’^Ó%ˆŒ
Ø%ÔØ)-ˆŒØˆÔØ"ˆÖr   c                ó$   <€ V ^8„  d   QhRS[ RR/# ©r   ÚtextÚreturnN©Ústr)r   r   s   "€r   r   r   4   s   ø€ ÷ &ñ &¡ð &¨ñ &r   c                ó^  € V P                   e   V P                  '       d   R#  V P                  f§   ^ RIHpHp V! V P                   P                  RR7       V! V P                   RRR7      V n        RP                  V P                  4      RP                  V P                  4      ,           pV P                  P                  V4       \        V4      V n        V P                  V P                  ,
          pV^ 8:  g   \        V4      V8”  dL   V P                  P                  VR\        ^ V4       4       V P                  P                  R4       RV n        MV P                  P                  V4       V ;P                  \        V4      ,          un        R#   \         d    RT n         R# i ; i)	zATee ``text`` to the spill file (opened lazily on first overflow).N)Úensure_spill_dirÚopen_exclusiveT)ÚprivateÚreplace)r6   ÚerrorsÚ z+
... [spill capped at 5,000,000 chars] ...
)r&   r)   r'   Útools.spill_safetyr4   r5   ÚparentÚjoinr   r   ÚwriteÚlenr(   Ú_SPILL_CAP_CHARSr   ÚOSError)r*   r/   r4   r5   ÚbacklogÚbudgets   &&    r   Ú_maybe_spillÚ$_BoundedOutputCollector._maybe_spill4   s?  € à×ÑÒ# t×'9×'9Ð'9Ùð	&Ø�~‰~Ò%ßOñ ! ×!1Ñ!1×!8Ñ!8À$ÕGÙ!/°×0@Ñ0@È$ÐW`Ô!a�”àŸ'™' $§*¡*Ó-°·±¸¿
¹
Ó0CÕC�Ø—‘×$Ñ$ WÔ-Ü$'¨£L�Ô!Ø×*Ñ*¨T×->Ñ->Õ>ˆFØ˜Œ{œc $›i¨&Ô0Ø—‘×$Ñ$ T¨/¬3¨q°&«>Ð%:Ô;Ø—‘×$Ñ$Ð%TÔUØ%)�Õ"à—‘×$Ñ$ TÔ*Ø×Ò¤ T£Õ*×øÜô 	&à!%ˆD×ð	&ús   ¤E0F ÆF,Æ+F,c                ó.   <€ V ^8„  d   QhRS[ R,          /# ©r   r0   Nr1   )r   r   s   "€r   r   r   O   s   ø€ ÷ 
)ñ 
)™S 4�Zñ 
)r   c                ó*  € V P                   ;_uu_ 4        V P                  f    RRR4       R#  V P                  P                  4        RV n        \	        V P
                  4      uuRRR4       #   \         d     L3i ; i  + '       g   i     R# ; i)z8Close the spill file and return its path if it was used.N)r%   r'   Úcloser@   r2   r&   ©r*   s   &r   Úclose_spillÚ#_BoundedOutputCollector.close_spillO   sp   € à�Z�Z‹ZØ�~‰~Ò%Ø÷ ‰ZðØ—‘×$Ñ$Ô&ð "ˆDŒNÜ�t×'Ñ'Ó(÷ ŠZøô
 ô Ùðú÷ �ZˆZús.   •B°A0Á
BÁ0A>Á;BÁ=A>Á>BÂB	c                ó    <€ V ^8„  d   QhRS[ /# ©r   r0   ©r   )r   r   s   "€r   r   r   \   s   ø€ ÷ 7ñ 7¡ñ 7r   c                ó¢   € V P                   ;_uu_ 4        V P                  V P                  ,           uuR R R 4       #   + '       g   i     R # ; i©N)r%   r    r!   rI   s   &r   Úbuffered_charsÚ&_BoundedOutputCollector.buffered_chars[   s+   € à�Z�Z‹ZØ×#Ñ# d×&6Ñ&6Õ6÷ �Z�Z‹Zús	   •=½A	c                ó    <€ V ^8„  d   QhRS[ /# rM   rN   )r   r   s   "€r   r   r   a   s   ø€ ÷ %ñ %™Sñ %r   c                ó€   € V P                   ;_uu_ 4        V P                  uuR R R 4       #   + '       g   i     R # ; irP   )r%   r"   rI   s   &r   Útotal_charsÚ#_BoundedOutputCollector.total_chars`   s    € à�Z�Z‹ZØ×$Ñ$÷ �Z�Z‹Zús   •,¬=	c                ó$   <€ V ^8„  d   QhRS[ RR/# r.   r1   )r   r   s   "€r   r   r   e   s   ø€ ÷ &/ñ &/™3ð &/ 4ñ &/r   c                ó„  € V'       g   R # V P                   ;_uu_ 4        \        V4      pV P                  eB   V P                  f#   V P                  V,           V P
                  8”  d   V P                  V4       V ;P                  V,          un        ^ pV P                  V P                  8  di   \        V P                  V P                  ,
          V4      pV'       d:   V P                  P                  VR V 4       V ;P                  V,          un        TpW#,
          pV^ 8:  g   V P                  ^ 8:  d    R R R 4       R # WPP                  8¼  d_   V P                  P                  4        V P                  P                  WP                  ) R  4       V P                  V n         R R R 4       R # WR  pV P                  P                  V4       V ;P                  \        V4      ,          un        V P                  V P                  ,
          ;p^ 8”  dŽ   V P                  ^ ,          p\        V4      V8:  d?   V P                  P!                  4        V ;P                  \        V4      ,          un        K…  W‡R  V P                  ^ &   V ;P                  V,          un        K±   R R R 4       R #   + '       g   i     R # ; irP   )r%   r>   r&   r'   r"   r   rC   r    r   Úminr   Úappendr   r   Úclearr!   Úpopleft)	r*   r/   Útext_lenÚstartÚtakeÚ	remainingÚchunkÚexcessÚfirsts	   &&       r   rZ   Ú_BoundedOutputCollector.appende   s  € ßÙØ�Z�Z‹ZÜ˜4“yˆHà×ÑÒ+Ø—‘Ò*¨d×.?Ñ.?À(Õ.JÈTÏ^É^Ô.[Ø×!Ñ! $Ô'Ø×Ò Õ)ÕØˆEà×Ñ $×"2Ñ"2Ô2Ü˜4×+Ñ+¨d×.>Ñ.>Õ>ÀÓI�ßØ—J‘J×%Ñ% d¨5¨D kÔ2Ø×$Ò$¨Õ,Õ$Ø �Eà Õ(ˆIØ˜AŒ~ ×!1Ñ!1°QÔ!6Ø÷% ‰Zð& ×,Ñ,Ô,Ø—
‘
× Ñ Ô"Ø—
‘
×!Ñ! $×(8Ñ(8Ð'8Ð':Ð";Ô<Ø#'×#3Ñ#3�Ô Ø÷/ ‰Zð2 ˜�LˆEØ�J‰J×Ñ˜eÔ$Ø×Ò¤ E£
Õ*ÕØ!×-Ñ-°×0@Ñ0@Õ@Ð@�6ÀAÔEØŸ
™
 1��Ü�u“: Ô'Ø—J‘J×&Ñ&Ô(Ø×$Ò$¬¨E«
Õ2×$à$)¨' N�D—J‘J˜q‘MØ×$Ò$¨Õ.×$ð F÷9 �Z�ZŠZús   ŸDJ.ÅA$J.Æ1C2J.Ê.J?	Úsuffixr9   c                ó&   <€ V ^8„  d   QhRS[ RS[ /# )r   re   r0   r1   )r   r   s   "€r   r   r   �   s   ø€ ÷ Sñ S¡ð S©Sñ Sr   c               óD  € V P                   ;_uu_ 4        \        V4      V P                  8¼  d   WP                  ) R uuRRR4       # RP                  V P                  4      pRP                  V P
                  4      pV P                  \        V4      ,
          pV P                  V8:  d   W#,           V,           uuRRR4       # Rp\        ^4       FY  p\        ^ V P                  \        ^ V\        V4      ,
          4      ,
          4      p\        WpP                  4      pW…8X  d    MTpK[  	  \        ^ V\        V4      ,
          4      p	\        V	4      w  r«V'       d   W;) R MRpVRV
 VRV ,           V,           V,           uuRRR4       #   + '       g   i     R# ; i)zARender within ``max_chars``, preserving a required status suffix.Nr9   )r%   r>   r   r<   r   r   r"   Úranger   r
   r	   )r*   re   ÚheadÚtailÚ	availableÚnoticeÚ_ÚomittedÚupdatedÚcontent_budgetÚ
head_charsÚ
tail_charsÚrendered_tails   &$           r   ÚrenderÚ_BoundedOutputCollector.render�   sB  € à�Z�Z‹ZÜ�6‹{˜dŸn™nÔ,ØŸ~™~˜oÐ/Ð0÷ ŠZð —7‘7˜4Ÿ:™:Ó&ˆDØ—7‘7˜4Ÿ:™:Ó&ˆDØŸ™¬¨V«Õ4ˆIØ× Ñ  IÔ-Ø•{ VÕ+÷ ŠZð ˆFÜ˜1–X�Ü˜a ×!2Ñ!2´S¸¸IÌÈFËÕ<SÓ5TÕ!TÓU�Ü+¨G×5FÑ5FÓG�ØÔ$ÙØ ’ñ ô !  I´°F³Õ$;Ó<ˆNÜ%4°^Ó%DÑ"ˆJß2<˜D  Ñ.À"ˆMØ˜˜Ð$ v¨j¨yÐ'9Õ9¸MÕIÈFÕR÷/ �Z�Z‹Zús   •)FÁ	A1FÃB>FÆF	)r   r    r   r%   r)   r(   r'   r&   r   r!   r   r"   r   rP   )Ú__name__Ú
__module__Ú__qualname__Ú__firstlineno__Ú__doc__r?   r+   rC   rJ   ÚpropertyrQ   rU   rZ   rt   Ú__static_attributes__Ú__classdictcell__©r   s   @r   r   r      s~   ø‡ € ñKð
 !Ð÷#ò #÷&ð &÷6
)ð 
)ð ÷7ó ð7ð ÷%ó ð%÷&/ð &/ðPS b÷ S÷ Sð Sr   r   c                ó0   € V ^8„  d   QhR\         R\        /# )r   Úbounded_capturer0   )Úboolr   )r   s   "r   r   r   ©   s   € ÷ Iñ I´ð IÔ:Qñ Ir   c           	     ó²  € V'       g   \        \        4      #  ^ RIHp V! 4       pRp \        4       R,          R,          pVR\        \        P                  ! 4       4       R\        P                  ! 4        R\        V 4      R,          R	 R
2,          pVP                  4       '       dk   \        P                  ! 4       \        ,
          pVP                  R4       F5  p VP                  4       P                  V8  d   VP!                  4        K5  K7  	  \        Y4R7      #   \         d    Rp EL
i ; i  \"         d     Kg  i ; i  \         d    Rp LAi ; i)a¢  Build the collector for one ``_wait_for_process`` call. ``bounded_capture`` (foreground
terminal path only) caps retention at ``tool_output.max_bytes`` and tees overflow to a
spill file under ``$HERMES_HOME/cache/terminal-output`` (created only on actual overflow;
spills older than 7 days are pruned opportunistically). Otherwise the collector is
effectively unbounded so internal consumers keep full-fidelity output.)Úget_max_bytesiPÃ  NÚcachezterminal-outputzout-Ú-iÿÿ  Úxz.logz	out-*.log)r   )r   Ú_UNBOUNDED_CAPTURE_CHARSÚtools.tool_output_limitsrƒ   Ú	Exceptionr   r   ÚtimeÚosÚgetpidÚidÚis_dirÚ_SPILL_MAX_AGE_SÚglobÚstatÚst_mtimeÚunlinkr@   )Úprocr€   rƒ   Úcapture_limitr   Ú	spill_dirÚcutoffÚolds   &&      r   Ú_new_output_collectorr™   ©   s$  € ÷ Ü&Ô'?Ó@Ð@ðÝ:Ù%›ˆð €JðÜ#Ó%¨Õ/Ð2CÕCˆ	Ø 4¬¬D¯IªI«KÓ(8Ð'9¸¼2¿9º9»;¸-ÀqÌÈDËÐTZÕIZÐ[\ÐH]Ð]aÐ!bÕbˆ
Ø×Ñ×ÒÜ—Y’Y“[Ô#3Õ3ˆFØ —~‘~ kÖ2�ðØ—x‘x“z×*Ñ*¨VÔ3ØŸ
™
žñ 4ñ 3ô # =ÔHÐHøô! ô Ø‹ðûô ô Úðûäô ØŠ
ðúsG   ™D  ©B5E Ã/D4ÄE Ä D1Ä0D1Ä4EÄ?E ÅEÅE ÅEÅEc                óV   € V ^8„  d   QhR\         R\        R\        R,          R\        /# )r   Ú	collectorÚrenderedÚ
returncodeNr0   )r   r2   r   Údict)r   s   "r   r   r   Ç   s1   € ÷ ñ Ô%<ð Ìð ÔY\Ð_cÕYcð Ôhlñ r   c                óh   € RVRV/pV P                  4       pV'       d   V P                  VR&   WCR&   V# )zHAssemble a wait result, attaching spill metadata when overflow occurred.Úoutputr�   Úoutput_total_charsÚfull_output_path)rJ   rU   )r›   rœ   r�   ÚresultÚspills   &&&  r   Ú_finalize_wait_resultr¥   Ç   s@   € à˜ ,°
Ð;€FØ×!Ñ!Ó#€EßØ'0×'<Ñ'<ˆÐ#Ñ$Ø%*Ð!Ñ"Ø€Mr   c                óH   € V ^8„  d   QhR\         P                  R\        RR/# )r   r”   Údatar0   N)Ú
subprocessÚPopenr2   )r   s   "r   r   r   Ò   s'   € ÷ &ñ &”j×&Ñ&ð &¬cð &°dñ &r   c                óŒ   a aa€ . oSS n         VVV 3R lp\        P                  ! VRR7      pVS n        VP	                  4        R# )a5  Write *data* to proc.stdin on a daemon thread to avoid pipe-buffer deadlocks.
Writes go through ``proc.stdin.buffer`` as UTF-8 bytes we encode ourselves: Windows
text-mode stdin would translate ``\n`` -> ``\r\n`` and corrupt every write_file/patch
payload. Encoding uses ``surrogateescape`` (exact inverse of the read-side decode);
surrogates outside U+DC80-U+DCFF raise, the error is recorded on
``proc._hermes_stdin_errors`` (surfaced by ``_wait_for_process`` as ``stdin_error``) and
stdin is still closed in ``finally`` so the child sees EOF instead of hanging.
c                  óx  <€ SP                   f   SP                  \        R4      4       R # \        SP                   RSP                   4      p  \	        S\
        4      '       d   SP                  RR4      MSpV P                  V4      pV\        V4      8w  d   \        RV R\        V4       R24      h  V P                  4        R #   \        \        3 d     L&\         d   pSP                  T4        R p?LFR p?ii ; i  \         d     R # i ; i   T P                  4        i   \         d     i i ; i; i)Nzprocess stdin unavailableÚbufferúutf-8Úsurrogateescapezshort stdin write: z of z bytes)ÚstdinrZ   ÚRuntimeErrorÚgetattrÚ
isinstancer2   Úencoder=   r>   ÚBrokenPipeErrorr@   r‰   rH   )ÚtargetÚrawÚwrittenÚexcr§   r8   r”   s       €€€r   Ú_writeÚ_pipe_stdin.<locals>._writeÞ   s  ø€ Ø�:‰:ÒØ�M‰Mœ,Ð'BÓCÔDÙô ˜Ÿ™ X¨t¯z©zÓ:ˆð	Ü=GÈÌc×=RÒ=R�$—+‘+˜gÐ'8Ô9ÐX\ˆCØ—l‘l 3Ó'ˆGØœ#˜c›(Ô"ä"Ð%8¸¸	ÀÄcÈ#ÃhÀZÈvÐ#VÓWÐWð #ðØ—‘–øô  ¤Ð)ô 	ÙÜô 	à�M‰M˜#×Ñûð	ûô ô ÚðûðØ—‘•øÜô Ùðýsy   ÁA&C Â4D Â6D ÃD ÃD ÃD Ã$D Ã%C;Ã6D Ã;D Ä D ÄDÄDÄD9ÄD(Ä'D9Ä(D6Ä3D9Ä5D6Ä6D9T©rµ   ÚdaemonN)Ú_hermes_stdin_errorsr#   ÚThreadÚ_hermes_stdin_threadr^   )r”   r§   r¹   Úthreadr8   s   ff  @r   Ú_pipe_stdinrÁ   Ò   s<   ú€ ð #%€FØ &€DÔ÷ô0 ×Ò V°DÔ9€FØ &€DÔØ
‡L�L†Nr   c                ót   € V ^8„  d   QhR\         \        ,          R\        R,          R\        P                  /# )r   ÚcmdÚ
stdin_dataNr0   )Úlistr2   r¨   r©   )r   s   "r   r   r   û   s/   € ÷ ñ ”Tœ#•Yð ¬C°$­Jð ÌJ×L\ÑL\ñ r   c                ó  € VP                  R\        4       4       \        P                  ! V 3R\        P                  R\        P
                  RVe   \        P                  M\        P                  RRRRR	R
/VB pVe   \        W14       V# )zòSpawn a subprocess with standard stdout/stderr/stdin setup; *stdin_data* is written
asynchronously via :func:`_pipe_stdin`. Backends with special Popen needs (e.g. local's
``preexec_fn``) can bypass this and call :func:`_pipe_stdin` directly.ÚcreationflagsÚstdoutÚstderrr¯   r/   TÚencodingr­   r8   r7   )Ú
setdefaultr   r¨   r©   ÚPIPEÚSTDOUTÚDEVNULLrÁ   )rÃ   rÄ   Úkwargsr”   s   &&, r   Ú_popen_bashrÐ   û   sŸ   € ð ×Ñ�oÔ'9Ó';Ô<Ü×ÒØñä�‰ðô × Ñ ðð ",Ò!7Œj�oŠo¼Z×=OÑ=Oð	ð
 ðð
 $ðð
 -6ðð ñ€Dð ÒÜ�DÔ%Ø€Kr   c                   ó–   a € ] tR tRt o RtV 3R lR ltV 3R lR ltRV 3R lR	 llt]V 3R
 lR l4       t	]V 3R lR l4       t
RtV tR# )ÚProcessHandlei  z™Duck type every backend's _run_bash() must return. subprocess.Popen satisfies this
natively; SDK backends (Modal, Daytona) return _ThreadedProcessHandle.c                ó.   <€ V ^8„  d   QhRS[ R,          /# rF   rN   )r   r   s   "€r   r   ÚProcessHandle.__annotate__  s   ø€ ×%Ñ%‘c˜D•jÑ%r   c                ó   € R # rP   © rI   s   &r   ÚpollÚProcessHandle.poll  s   € ¡#r   c                ó   <€ V ^8„  d   QhRR/# rF   rÖ   )r   r   s   "€r   r   rÔ     s   ø€ ×Ñ�dÑr   c                ó   € R # rP   rÖ   rI   s   &r   ÚkillÚProcessHandle.kill  s   € ™Cr   Nc                ó4   <€ V ^8„  d   QhRS[ R,          RS[/# ©r   ÚtimeoutNr0   ©Úfloatr   )r   r   s   "€r   r   rÔ     s   ø€ ×<Ñ<™E D�LÐ<±CÑ<r   c                ó   € R # rP   rÖ   ©r*   rß   s   &&r   ÚwaitÚProcessHandle.wait  s   € ¹r   c                ó>   <€ V ^8„  d   QhRS[ S[,          R,          /# rF   )r   r2   )r   r   s   "€r   r   rÔ     s   ø€ ×+Ñ+™™3� $�Ñ+r   c                ó   € R # rP   rÖ   rI   s   &r   rÈ   ÚProcessHandle.stdout  ó   € Ù(+r   c                ó.   <€ V ^8„  d   QhRS[ R,          /# rF   rN   )r   r   s   "€r   r   rÔ     s   ø€ ×+Ñ+™C $�JÑ+r   c                ó   € R # rP   rÖ   rI   s   &r   r�   ÚProcessHandle.returncode  ré   r   rÖ   rP   )rv   rw   rx   ry   rz   r×   rÛ   rä   r{   rÈ   r�   r|   r}   r~   s   @r   rÒ   rÒ     s;   ø‡ € ñN÷ &Ð%ßÐß<Ò<àß+ó Ø+àß+ó Þ+r   rÒ   c                   ó”   a € ] tR tRt o RtRV 3R lR llt]R 4       t]V 3R lR l4       tV 3R	 lR
 lt	R t
RV 3R lR lltRtV tR# )Ú_ThreadedProcessHandlei  a  Adapter for SDK backends (Modal, Daytona) that have no real subprocess: runs a blocking
``exec_fn() -> (output_str, exit_code)`` on a background thread behind a ProcessHandle
interface. ``cancel_fn`` is invoked on ``kill()`` for backend-specific cancellation.Nc                óp   <€ V ^8„  d   QhRS[ . S[S[S[3,          3,          RS[ . R3,          R,          /# )r   Úexec_fnÚ	cancel_fnN)r   Útupler2   r   )r   r   s   "€r   r   Ú#_ThreadedProcessHandle.__annotate__!  s?   ø€ ÷ >ñ >¡¨©U±3¹°8­_Ð)<Õ =ð >É(ÐSUÐW[ÐS[ÕJ\Ð_cÕJcñ >r   c                ó.  a a€ VS n         \        P                  ! 4       S n        R S n        \
        P                  ! 4       w  r4\
        P                  ! VRRRR7      S n        VS n	        VV 3R lp\        P                  ! VRR7      P                  4        R # )NÚrz	utf-8-sigr7   )rÊ   r8   c                  ó  <€  S! 4       w  rVSn          \        P                  ! SP                  V P	                  R RR7      4        \        P                  ! SP                  4       SP                  P                  4        R#   \
         d     LJi ; i  \         d    ^Sn          Lbi ; i  \
         d     LRi ; i   \        P                  ! SP                  4       M  \
         d     Mi ; iSP                  P                  4        i ; i)r­   r7   ©r8   N)
Ú_returncoder‹   r=   Ú	_write_fdr³   r@   r‰   rH   Ú_doneÚset)r    Ú	exit_coderð   r*   s     €€r   Ú_workerÚ0_ThreadedProcessHandle.__init__.<locals>._worker+  sÖ   ø€ ð!Ù$+£IÑ!�Ø#,�Ô ðÜ—H’H˜TŸ^™^¨V¯]©]¸7È9¨]Ó-UÔVðÜ—H’H˜TŸ^™^Ô,ð —
‘
—‘Ö øô ô Ùðûäô %Ø#$�Ö ð%ûô
 ô ÙðûðÜ—H’H˜TŸ^™^Õ,øÜô Ùðúà—
‘
—‘Õ ús|   ƒB ”2B Á B, ÂBÂB ÂB= ÂBÂB ÂB)Â&B= Â(B)Â)B= Â,B:Â9B:Â=DÂ? C ÃDÃ C.Ã+DÃ-C.Ã.DTr»   )Ú
_cancel_fnr#   ÚEventrú   rø   r‹   ÚpipeÚfdopenÚ_stdoutrù   r¾   r^   )r*   rð   rñ   Úread_fdÚwrite_fdrý   s   ff&   r   r+   Ú_ThreadedProcessHandle.__init__!  sm   ù€ Ø#ˆŒÜ—_’_Ó&ˆŒ
Ø'+ˆÔô ŸGšG›IÑˆÜ—y’y ¨#¸ÈIÔVˆŒØ!ˆŒö	!ô" 	×Ò °Ô5×;Ñ;Ö=r   c                ó   € V P                   # rP   )r  rI   s   &r   rÈ   Ú_ThreadedProcessHandle.stdout>  s   € à�|‰|Ðr   c                ó.   <€ V ^8„  d   QhRS[ R,          /# rF   rN   )r   r   s   "€r   r   ró   C  s   ø€ ÷  ñ  ™C $�Jñ  r   c                ó   € V P                   # rP   )rø   rI   s   &r   r�   Ú!_ThreadedProcessHandle.returncodeB  s   € à×ÑÐr   c                ó.   <€ V ^8„  d   QhRS[ R,          /# rF   rN   )r   r   s   "€r   r   ró   F  s   ø€ ÷ Añ A‘c˜D•jñ Ar   c                ó^   € V P                   P                  4       '       d   V P                  # R # rP   )rú   Úis_setrø   rI   s   &r   r×   Ú_ThreadedProcessHandle.pollF  s%   € Ø#'§:¡:×#4Ñ#4×#6Ò#6ˆt×ÑÐ@¸DÐ@r   c                ót   € V P                   '       d    V P                  4        R # R #   \         d     R # i ; irP   )rÿ   r‰   rI   s   &r   rÛ   Ú_ThreadedProcessHandle.killI  s3   € Ø�?�?ˆ?ðØ—‘Ö!ñ øô ô Úðús   ”( ¨7¶7c                ó4   <€ V ^8„  d   QhRS[ R,          RS[/# rÞ   rà   )r   r   s   "€r   r   ró   P  s   ø€ ÷  ñ  ™E D�Lð  ±Cñ  r   c                óR   € V P                   P                  VR 7       V P                  # ))rß   )rú   rä   rø   rã   s   &&r   rä   Ú_ThreadedProcessHandle.waitP  s    € Ø�
‰
�‰ ˆÔ(Ø×ÑÐr   )rÿ   rú   rø   r  rù   rP   )rv   rw   rx   ry   rz   r+   r{   rÈ   r�   r×   rÛ   rä   r|   r}   r~   s   @r   rî   rî     s]   ø‡ € ñ\÷>ò >ð: ñó ðð ÷ ó ð ÷Að Aò÷ ÷  ð  r   rî   c                ób   € V ^8„  d   QhR\         R\        R\        P                  R,          RR/# ©r   r”   r    ÚstopNr0   )rÒ   r   r#   r   )r   s   "r   r   r   V  s4   € ÷ 4ñ 4œð 4Ô/Fð 4ÌiÏoÉoÐ`dÕNdð 4Ðptñ 4r   c                ó  € V P                   pVf   R# \        P                  ! R4      ! RR7      p VP                  4       p \        V\        4      '       d   V^ 8  dR   V FJ  pVf   K	  TP                  \        V\        4      '       d   VP                  V4      M
\        V4      4       KL  	  M1\        P                  R8X  d   \        WWV4       M\        WWV4         VP                  RRR7      pV'       d   VP                  V4       R# R#   \         d    Rp Lài ; i  \         d     LQi ; i  \         d     R# i ; i   TP                  RRR7      pT'       d   TP                  T4       i i   \         d     i i ; i; i)	uP  Drain ``proc.stdout`` into *output* until EOF or shortly after exit.
``for line in proc.stdout`` would block on ``readline()`` until EOF, and a backgrounded
grandchild (``cmd &``, ``setsid cmd & disown``) inherits the pipe's write end â€” so the
tool would hang for the grandchild's lifetime. Instead we ``select()`` with a short poll
and stop ~300ms after bash exits even if the pipe has not EOF'd. Raw 4096-byte ``os.read``
chunks can split a multibyte UTF-8 sequence, so an incremental decoder with
``errors="replace"`` buffers partial sequences across chunks. Streams without a real
integer ``fileno()`` (mocks, in-memory adapters) are iterated to EOF instead â€” otherwise
the thread would die silently and lose all output. ``select()`` does not work on pipe fds
on Windows, so :func:`_drain_fd_windows` polls ``PeekNamedPipe`` there instead.
Nr­   r7   r÷   Úntr   T)Úfinal)rÈ   ÚcodecsÚgetincrementaldecoderÚfilenor‰   r²   r   rZ   ÚbytesÚdecoder2   r‹   ÚnameÚ_drain_fd_windowsÚ_drain_fd_select)r”   r    r  ÚstreamÚdecoderÚfdÚpiecerj   s   &&&     r   Ú_drain_stdoutr'  V  sW  € ð �[‰[€FØ‚~Ùô ×*Ò*¨7Ô3¸9ÔE€GðØ�]‰]‹_ˆðÜ˜"œc×"Ò" b¨1¤fÛ�ØÔ$Ø—M‘M¼:ÀeÌU×;SÒ;S '§.¡.°Ô"7ÔY\Ð]bÓYcÖdò  ô �W‰W˜Œ_Ü˜d¨¸Õ>ä˜T v¸Õ=ð
	Ø—>‘> #¨T�>Ó2ˆDßØ—‘˜dÖ#ñ øô# ô ØŠðûô ô Ùðûô ô 	Úð	ûð		Ø—>‘> #¨T�>Ó2ˆDßØ—‘˜dÕ#ð øäô 	Ùð	ýs�   ±D Á#D% Á*AD% Â/E Â0"D% ÃE ÃD% Ã E Ã",D6 ÄD"Ä!D"Ä%D3Ä0E Ä2D3Ä3E Ä6EÅEÅF	Å
,E8Å6F	Å8FÆF	ÆFÆF	c                ó4   € V ^8„  d   QhR\         R\        RR/# ©r   r%  r    r0   N©r   r   )r   s   "r   r   r   �  s#   € ÷ 
ñ 
œsð 
Ô,Cð 
Ð\`ñ 
r   c                óŽ   € \        V4      pVf   R#  \        WWRW44       VP                  4        R#   TP                  4        i ; i)uÑ   POSIX drain: selector readiness (no FD_SETSIZE ceiling, #94928), stopping ~300ms after
bash exits with the pipe idle, or when *stop* is set (the pipe is being handed to another
reader â€” yield-to-background).N)r   Ú_drain_fd_waiterrH   )r”   r%  r    r$  r  Úwaiters   &&&&& r   r"  r"  �  s:   € ô ˜BÓ€FØ‚~ÙðÜ˜ 6°7ÔAà�‰Žøˆ�‰�ús	   “2 ²Ac                ó4   € V ^8„  d   QhR\         R\        RR/# r)  r*  )r   s   "r   r   r   š  s#   € ÷ ñ œsð Ô4Kð Ð_cñ r   c                 óz  € ^ p Ve   VP                  4       '       d   R# VP                  R4      '       dG    \        P                  ! VR4      pT'       g   R# TP                  TP                  T4      4       ^ pKz  V P                  4       f   KŽ  V^,          pV^8¼  g   K   R#   \        \
        3 d     R# i ; i)é    Nçš™™™™™¹?é   )	r  rä   r‹   ÚreadÚ
ValueErrorr@   rZ   r  r×   )r”   r%  r-  r    r$  r  Úidle_after_exitra   s   &&&&&&  r   r,  r,  š  sŸ   € Ø€OØ
ØÒ §¡§¢ÙØ�;‰;�s×ÒðÜŸš  DÓ)�÷ ÙØ�M‰M˜'Ÿ.™.¨Ó/Ô0ØŠOØ�Y‰Y‹[Ô$ð ˜qÕ ˆOØ !Ö#Ùøô ¤Ð(ô Úðús   ¸B% Â%B:Â9B:c                ó4   € V ^8„  d   QhR\         R\        RR/# r)  r*  )r   s   "r   r   r   °  s#   € ÷ -ñ -¤ð -Ô-Dð -Ð]añ -r   c           	     ó0  € ^ RI p^ RIp VP                  V4      pTR9   d   R# TP	                  T4      pTP
                  P                  p	TP                  ^ 4      p
^ p Te   TP                  4       '       d   R#  T	P                  TR^ RTP                  T
4      R4      pT'       g   R# T
P                  '       dd    \        P                  ! T\        \        T
P                  4      R4      4      pT'       g   R# TP#                  TP%                  T4      4       ^ pKÂ  T P'                  4       e   T^,          pT^8¼  d   R# \(        P*                  ! R4       Kþ    \         d     R# i ; i  \         d     R# i ; i  \         \        3 d     R# i ; i)ac  Windows drain: poll ``PeekNamedPipe`` because ``select`` cannot poll pipes.

``os.read`` on a Windows pipe blocks until data is available or every writer
closes the pipe.  A backgrounded grandchild can retain a writer indefinitely,
so use the Win32 pipe API to check availability before reading and apply the
same post-exit idle bound as the POSIX drain.
Nr2  r1  )éÿÿÿÿr0  )ÚctypesÚmsvcrtÚget_osfhandler@   Úc_void_pÚwindllÚkernel32Úc_ulongr  ÚPeekNamedPipeÚbyrefÚvaluer‹   r3  rY   r   r4  rZ   r  r×   rŠ   Úsleep)r”   r%  r    r$  r  r9  r:  Ú
raw_handleÚhandler>  rk   r5  Úokra   s   &&&&&         r   r!  r!  °  sb  € ó ÛðØ×)Ñ)¨"Ó-ˆ
ð �WÔÙà�_‰_˜ZÓ(€FØ�}‰}×%Ñ%€HØ—‘˜qÓ!€IØ€OØ
ØÒ §¡§¢Ùð	Ø×'Ñ'¨°°a¸¸v¿|¹|ÈIÓ?VÐX\Ó]ˆB÷ ÙØ�?�?ˆ?ðÜŸš ¤C¬¨I¯O©OÓ(<¸dÓ$CÓD�÷ ÙØ�M‰M˜'Ÿ.™.¨Ó/Ô0ØˆOÙØ�9‰9‹;Ò"Ø˜qÕ ˆOØ !Ô#ÙÜ�
Š
�3ŽøôA ô Úðûô ô 	Úð	ûô ¤Ð(ô Úðús5   ŠE Á<%E. Â>4F  ÅE+Å*E+Å.E=Å<E=Æ FÆFc                ó~   € V ^8„  d   QhR\         R\        R\        P                  R,          R\        P                  /# r  )rÒ   r   r#   r   r¾   )r   s   "r   r   r   à  s<   € ÷ ñ ÜðÜ%<ðÜDMÇOÁOÐVZÕDZðä×Ññr   c                ód   € \         P                  ! \        WV3RR7      pVP                  4        V# )zLStart the daemon thread running :func:`_drain_stdout`; *stop* ends it early.T)rµ   Úargsr¼   )r#   r¾   r'  r^   )r”   r    r  rÀ   s   &&& r   Ú_start_drain_threadrJ  à  s,   € ô ×Ò¤]¸$ÈÐ9MÐVZÔ[€FØ
‡L�L„NØ€Mr   l   ÿÿÿÿ i€:	 rP   )%rz   r  r‹   r¨   r#   rŠ   Úcollectionsr   Úpathlibr   Útypingr   r   r   Úhermes_constantsr   Útools.environments.fd_waitr   Útools.tool_output_truncater	   r
   Úhermes_cli._subprocess_compatr   r‡   r�   r   r™   r¥   rÁ   rÐ   rÒ   rî   r'  r"  r,  r!  rJ  rÖ   r   r   Ú<module>rR     s�   ðñó Û 	Û Û Û Ý Ý ß )Ñ )å ,Ý 5ß IÝ <ð %Ð àÐ ÷ISñ ISõXIõ<õ&÷Rô$,�Hô ,÷6 ñ 6 ÷t4÷n
õ÷,-÷`ñ r   