+
    iHàj1P  ã                  ó@  € R t ^ RIHt ^ RIt^ RIt^ RIHt ^ RIt^ RIt^ RI	t	^ RI
t
^ RIt^ RIt^ RIt^ RIHt ^ RIHtHtHtHtHt ]P,                  ! ]4      t. R9OtR:t]P6                  R8X  d   ]MR	tR
tRt ! R R]4      t  ! R R]4      t!R R lt"]! RRR7       ! R R4      4       t#RRRR/R R llt$R R lt%R R lt&R R lt'RR/R  R! llt(R" R# lt)R$ R% lt*R& R' lt+R( R) lt,R*R+R,RR-RR.R/R/ R0 llt-R*R+R1RR.R/R2 R3 llt.]R4 R5 l4       t/R6R/R7 R8 llt0R# );u]  Unified deadline layer â€” one bounded-execution primitive, one timeout resolver (#85125).

* :func:`resolve_timeout` â€” ``timeouts:`` in config.yaml > legacy env var > default.
* :func:`clamp_timeout` â€” huge timeouts overflow ``time_t`` in ``Lock.acquire`` /
  ``Thread.join`` on macOS (#83220), so every timeout is capped.
* :func:`run_bounded_async` / :func:`run_bounded_sync` â€” wall-clock deadlines driven by
  a daemon ``threading.Timer`` / worker thread, so a blocked event loop cannot disable them.
* :func:`kill_process_tree` â€” portable whole-tree termination.

Invariants: operation exceptions propagate unchanged (only the *timeout* outcome is reified
as :class:`BoundedResult`); a timeout here is OUR deadline, not the provider's (classify
:class:`DeadlineExpired` distinctly from transport timeouts); ``None`` / non-positive means unbounded.
)ÚannotationsN)Úcontextmanager)Ú	dataclass)ÚAnyÚ	AwaitableÚCallableÚOptionalÚProtocolÚBoundedResultÚDeadlineExpiredÚwin32g    8~Ag      @gš™™™™™É?c                  ó2   a € ] tR t^GtRtR V 3R lltRtV ;t# )r   zSA deadline enforced by this layer expired (Hermes's own bound, not the provider's).c               ó    € V ^8„  d   QhRRRR/# )é   ÚlabelÚstrÚ	timeout_sÚfloat© )Úformats   "Ú3/home/ubuntu/.hermes/hermes-agent/agent/deadline.pyÚ__annotate__ÚDeadlineExpired.__annotate__J   s   € ÷ #ñ #˜cð #¨eñ #ó    c                	óL   <€ \         SV `  R VR RV 24       Wn        W n        R# )zdeadline expired after ú.1fzs: N)ÚsuperÚ__init__r   r   )Úselfr   r   Ú	__class__s   &&&€r   r   ÚDeadlineExpired.__init__J   s*   ø€ Ü‰ÑÐ2°9¸S°/ÀÀUÀGÐLÔMØŒ
Ø"Žr   ©r   r   )Ú__name__Ú
__module__Ú__qualname__Ú__firstlineno__Ú__doc__r   Ú__static_attributes__Ú__classcell__)r   s   @r   r   r   G   s   ø† Ù]÷#ö #r   c                  ó2   € ] tR t^PtRtR R ltR R ltRtR# )ÚSuspectableBackenduv  A stateful backend (MCP connection, browser session, LSP client) ``run_bounded_*`` flags via
``mark_suspect`` on timeout so the owner can health-check/recycle it before reuse. ``mark_suspect``
MUST be cheap, non-blocking, and must not acquire locks the guarded operation may hold â€” it runs
inline on the event loop / caller's thread while the wedged worker is still alive.c               ó    € V ^8„  d   QhRRRR/# )r   Úreasonr   ÚreturnÚNoner   )r   s   "r   r   ÚSuspectableBackend.__annotate__V   s   € ×4Ñ4 3Ð4¨4Ñ4r   c                	ó   € R # ©Nr   )r   r,   s   &&r   Úmark_suspectÚSuspectableBackend.mark_suspectV   s   € ±r   c               ó   € V ^8„  d   QhRR/# )r   r-   Úboolr   )r   s   "r   r   r/   X   s   € ×)Ñ) Ñ)r   c                	ó   € R # r1   r   )r   s   &r   Úensure_healthyÚ!SuspectableBackend.ensure_healthyX   s   € ¡cr   r   N)r"   r#   r$   r%   r&   r2   r7   r'   r   r   r   r*   r*   P   s   † ñZõ
 5ç)Ñ)r   r*   c               ó(   € V ^8„  d   QhRRRRRRRR/# )	r   Úbackendúobject | Noner   r   r   r   r-   r.   r   )r   s   "r   r   r   [   s/   € ÷ 	Dñ 	D =ð 	D¸ð 	DÈð 	DÐSWñ 	Dr   c                óÄ   € V f   R#  \        V RR4      p\        V4      '       d   V! V RVR R24       R# R#   \         d    \        P	                  RRR7        R# i ; i)	zLBest-effort ``mark_suspect``; never raises, non-adopting backends tolerated.Nr2   z timed out after r   Úszdeadline mark_suspect failedT©Úexc_info)ÚgetattrÚcallableÚ	ExceptionÚloggerÚdebug)r:   r   r   Úmarks   &&& r   Ú_mark_backend_suspectrF   [   sf   € à‚ÙðDÜ�w °Ó5ˆÜ�D�>Š>Ù�E�7Ð+¨I°c¨?¸!Ð<Ö=ñ øäô DÜ�‰Ð3¸dˆ×CðDús   ˆ-9 ¹"AÁAT)ÚfrozenÚkw_onlyc                  óN   € ] tR t^gt$ RtR]R&   R]R&   R]R&   R]R	&   R
]R&   RtR# )r
   zMOutcome of a bounded operation; operation exceptions are never captured here.r5   Ú	timed_outr   Úvaluer   Ú	elapsed_súOptional[float]r   r   r   r   N)r"   r#   r$   r%   r&   Ú__annotations__r'   r   r   r   r
   r
   g   s    ‡ áWàƒOØƒJØÓØÓØ‡Jr   rK   rJ   Fc               ó0   € V ^8„  d   QhRRRRRRRRR	R
RR/# )r   Ústartr   r   rM   r   r   rK   r   rJ   r5   r-   r
   r   )r   s   "r   r   r   r   s<   € ÷ ñ �5ð  _ð ¸Sð ÈCð Ðcgð ð  uBñ r   c               óR   € \        WC\        P                  ! 4       V ,
          WR 7      # ))rJ   rK   rL   r   r   )r
   ÚtimeÚ	monotonic)rP   r   r   rK   rJ   s   &&&$$r   Ú_resultrT   r   s#   € ÜØ´D·N²NÓ4DÀuÕ4LÐXaôð r   c               ó    € V ^8„  d   QhRRRR/# )r   ÚtimeoutrM   r-   r   )r   s   "r   r   r   x   s   € ÷ Bñ B˜?ð B¨ñ Br   c                óî   € V f   R#  \        V 4      pY8w  d   \        P	                  R4       R# T^ 8:  d   R# \        T\        4      #   \        \        3 d    \        P	                  RT 4        R# i ; i)zXNormalize a timeout: None/non-positive/non-numeric/NaN -> None (unbounded), else capped.Nz<clamp_timeout: non-numeric timeout %r; treating as unboundedz1clamp_timeout: NaN timeout; treating as unbounded)r   Ú	TypeErrorÚ
ValueErrorrC   ÚwarningÚminÚMAX_SAFE_TIMEOUT_S)rV   rK   s   & r   Úclamp_timeoutr]   x   sq   € à‚ÙðÜ�g“ˆð „~Ü�‰ÐJÔKÙØ˜A”:ˆ4ÐA¤3 uÔ.@Ó#AÐAøô ”zÐ"ô Ü�‰ÐUÐW^Ô_Úðús   ˆA	 Á	'A4Á3A4c               ó   € V ^8„  d   QhRR/# )r   r-   Údictr   )r   s   "r   r   r   Š   s   € ÷ ñ ˜4ñ r   c                 óÄ   €  ^ RI Hp  V ! 4       P                  R4      p\        V\        4      '       d   V# / #   \
         d    \        P                  RRR7       / u # i ; i)zLRead the ``timeouts:`` root section from config.yaml (read-only, fail-open).)Úload_config_readonlyÚtimeoutsz,timeouts: config read failed; using defaultsTr>   )Úhermes_cli.configra   ÚgetÚ
isinstancer_   rB   rC   rD   )ra   Úsections     r   Ú_timeouts_sectionrg   Š   sY   € ðÝ:Ù&Ó(×,Ñ,¨ZÓ8ˆÜ$ W¬d×3Ò3ˆwÐ;¸Ð;øÜô Ü�‰ÐCÈdˆÔSØŠ	ðús   ‚38 ¶8 ¸$AÁAc               ó$   € V ^8„  d   QhRRRRRR/# )r   rf   r_   Úkeyr   r-   r   r   )r   s   "r   r   r   •   s!   € ÷ ñ ˜Dð  sð ¨sñ r   c                óˆ   € T pVP                  R4       F*  p\        V\        4      '       d   W29  d    R# W#,          pK,  	  V# )z=Walk ``a.b.c`` through nested dicts; return None when absent.Ú.N)Úsplitre   r_   )rf   ri   ÚnodeÚparts   &&  r   Ú_lookup_dottedro   •   s<   € à€DØ—	‘	˜#–ˆÜ˜$¤×%Ò%¨Ô)9ÚØ�zŠñ ð €Kr   Úenv_varc               ó(   € V ^8„  d   QhRRRRRRRR/# )r   ri   r   ÚdefaultrM   rp   zOptional[str]r-   r   )r   s   "r   r   r   Ÿ   s)   € ÷ "ñ "˜ð "¨/ð "ÀMð "Ð]lñ "r   c               óì  € \        \        4       V 4      pVeK   \        V\        4      '       g    \	        V4      pWD8X  d   \        V4      #  \        P                  RW4       V'       dC   \        P                  ! VR4      P                  4       pV'       d    \        \	        V4      4      # \        V4      #   \        \        3 d     L~i ; i  \         d    \        P                  RY%4        LEi ; i)z¹Resolve a timeout (seconds): dotted ``timeouts.<key>`` > ``env_var`` > ``default``; the winner
goes through :func:`clamp_timeout`, invalid config/env values fall through with a warning.z6timeouts.%s: invalid value %r in config.yaml; ignoringÚ zinvalid %s=%r; ignoring)ro   rg   re   r5   r   r]   rX   rY   rC   rZ   ÚosÚgetenvÚstrip)ri   rr   rp   ÚrawrK   Úenv_raws   &$$   r   Úresolve_timeoutrz   Ÿ   sØ   € ô Ô*Ó,¨cÓ
2€CØ
‚ô ˜#œt×$Ò$ðÜ˜c›
�Ø”>Ü(¨Ó/Ð/ð "ô 	�‰ÐOÐQTÔZçÜ—)’)˜G RÓ(×.Ñ.Ó0ˆßðLÜ$¤U¨7£^Ó4Ð4ô ˜Ó!Ð!øô œzÐ*ô Ùðûô ô LÜ—‘Ð8¸'ÖKðLús#   °B8 ÂC Â8CÃCÃ!C3Ã2C3c               ó    € V ^8„  d   QhRRRR/# ©r   Útaskzasyncio.Future[Any]r-   r.   r   )r   s   "r   r   r   Æ   s   € ÷ ñ Ð0ð °Tñ r   c                ó|   €  V P                  4       '       g   V P                  4        R# R#   \         d     R# i ; i)zGObserve an abandoned task's outcome so it never logs 'never retrieved'.N)Ú	cancelledÚ	exceptionrB   ©r}   s   &r   Ú_consume_abandonedr‚   Æ   s5   € ðØ�~‰~×ÒØ�N‰NÖñ  øäô Úðús   ‚, ˜, ¬;º;c               ó    € V ^8„  d   QhRRRR/# r|   r   )r   s   "r   r   r   Ï   s   € ÷ /ñ /Ð&ð /¨4ñ /r   c                óP   € V P                  4        V P                  \        4       R# )zXCancel ``task`` and never await it; its outcome is consumed so it stays unobserved-safe.N)ÚcancelÚadd_done_callbackr‚   r�   s   &r   Ú_abandonr‡   Ï   s   € à‡K�K„MØ×ÑÔ-Ö.r   c               ó    € V ^8„  d   QhRRRR/# )r   Ú
on_abandonzCallable[[], Awaitable[Any]]r-   r.   r   )r   s   "r   r   r   Õ   s   € ÷ Gñ GÐ+Gð GÈDñ Gr   c              ƒ  ó„   "  €  V ! 4       G Rj  x€L
  R#  L  \          d    \        P                  RRR7        R# i ; i5i)zARun abandonment cleanup fire-and-forget (its failures swallowed).Nzdeadline abandon-cleanup failedTr>   )rB   rC   rD   )r‰   s   &r   Ú_run_abandon_cleanupr‹   Õ   s7   é € ðGÙ‹l×ÔøÜô GÜ�‰Ð6Àˆ×FðGüs,   ‚A „
 Ž� “A • —"=¹A ¼=½A c               ó$   € V ^8„  d   QhRRRRRR/# )r   r   r   r   r   r-   r.   r   )r   s   "r   r   r   Ý   s&   € ÷ Jñ J¨#ð J¸%ð JÀDñ Jr   c                ó¾   € \         P                  R W\        4        \        P                  ! RR7       R#   \
         d    \         P                  RRR7        R# i ; i)u  [deadline] %r deadline (%.0fs) expired but the event loop has not processed the expiry after a further %.0fs â€” the loop thread appears BLOCKED in a synchronous call, which is why no asyncio timeout can fire. Dumping all thread stacks to stderr to identify the blocking frame.T)Úall_threadsz"faulthandler traceback dump failedr>   N)rC   rZ   Ú_LOOP_BLOCKED_DUMP_GRACE_SÚfaulthandlerÚdump_tracebackrB   rD   r!   s   &&r   Ú_dump_blocked_loop_diagnosticsr’   Ý   sQ   € Ü
‡N�Nð	ð 	Ô4ôðJÜ×#Ò#°×5øÜô JÜ�‰Ð9ÀDˆ×IðJús   �6 ¶"AÁAr   Ú	operationr‰   Údump_on_blocked_loopr:   c               ó4   € V ^8„  d   QhRRRRRRRRR	R
RRRR/# )r   Ú	awaitablezAwaitable[Any]rV   rM   r   r   r‰   z&Optional[Callable[[], Awaitable[Any]]]r”   r5   r:   r;   r-   r
   r   )r   s   "r   r   r   ë   sN   € ÷ ?$ñ ?$Øð?$àð?$ð ð	?$ð
 7ð?$ð ð?$ð ð?$ð ñ?$r   c             ƒ  ór  aaaaaa"  € \        V4      o\        P                  ! 4       pSf   \        TRSV G Rj  x€L
 R7      # \        P
                  ! V 4      p\        P                  ! 4       oSP                  4       o\        P                  ! 4       oR VV3R lloR VVV3R llp\        P                  ! SVV3R l4      .p	V'       d2   V	P                  \        P                  ! S\        ,           V4      4       V	 F  p
RV
n        V
P                  4        K  	    \        P                  ! VS0\        P                   R	7      G Rj  x€L
 w  r¼Y{9   dg   SP'                  4       '       g   SP)                  4        \        TSSTG Rj  x€L
 R7      T	 F  p
T
P)                  4        K  	  SP+                  4        # \%        T4       Te3   \        P
                  ! \-        T4      4      P/                  \0        4       \3        TSS4       \4        P7                  R
SS4       \        TSSRR7      T	 F  p
T
P)                  4        K  	  SP+                  4        #  EL" EL  \        P"                   d    \%        T4       h i ; i Lú  T	 F  p
T
P)                  4        K  	  SP+                  4        i ; i5i)uS  Await ``awaitable`` under a wall-clock deadline independent of loop timers.

Operation exceptions (incl. ``CancelledError`` from a caller cancelling *us*) propagate
unchanged. On timeout the task is cancelled and **abandoned** (never awaited â€”
cancellation-shielded scopes are exactly the paths that wedge); ``on_abandon`` runs detached.N©rK   c               ó   € V ^8„  d   QhRR/# ©r   r-   r.   r   )r   s   "r   r   Ú'run_bounded_async.<locals>.__annotate__  s   € ÷ &ñ &˜4ñ &r   c                 óz   <€ SP                  4        S P                  4       '       g   S P                  R 4       R # R # r1   )ÚsetÚdoneÚ
set_result)ÚdeadlineÚloop_processed_expirys   €€r   Ú_mark_expiredÚ(run_bounded_async.<locals>._mark_expired  s-   ø€ Ø×!Ñ!Ô#Ø�}‰}�ŠØ×Ñ Ö%ñ r   c               ó   € V ^8„  d   QhRR/# rš   r   )r   s   "r   r   r›     s   € ÷ =ñ =˜Tñ =r   c                 óP   <€ SP                  4       '       g   \        S S4       R # R # r1   )Úis_setr’   )r   r¡   r   s   €€€r   Ú_watchdog_checkÚ*run_bounded_async.<locals>._watchdog_check  s!   ø€ Ø$×+Ñ+×-Ò-Ü*¨5°)Ö<ñ .r   c                 ó&   <€ SP                  S 4      # r1   )Úcall_soon_threadsafe)r¢   Úloops   €€r   Ú<lambda>Ú#run_bounded_async.<locals>.<lambda>  s   ø€ °×1JÑ1JÈ=Ô1Yr   T)Úreturn_whenz3[deadline] %r timed out after %.1fs; task abandoned©rJ   )r]   rR   rS   rT   ÚasyncioÚensure_futureÚget_running_loopÚcreate_futureÚ	threadingÚEventÚTimerÚappendr�   ÚdaemonrP   ÚwaitÚFIRST_COMPLETEDÚCancelledErrorr‡   rž   r…   r�   r‹   r†   r‚   rF   rC   rZ   )r–   rV   r   r‰   r”   r:   rP   r}   r§   ÚtimersÚtrž   Ú_r¢   r    r«   r¡   r   s   &&d$$$       @@@@@r   Úrun_bounded_asyncr¿   ë   s!  ýé € ô ˜gÓ&€IÜ�NŠNÓ€EØÒÜ�u˜d E°y·ÔAÐAä× Ò  Ó+€DÜ×#Ò#Ó%€DØ%)×%7Ñ%7Ó%9€HÜ%ŸOšOÓ-Ð÷&ñ &÷
=ò =ô �oŠo˜iÕ)YÓZÐ[€FßØ�‰”i—o’o iÔ2LÕ&LÈoÓ^Ô_ÛˆØˆŒØ	�‰Ž	ñ ð$ð	Ü#ŸLšL¨$°Ð)9Äw×G^ÑG^Ô_×_‰GˆDð Œ<Ø—=‘=—?’?Ø—‘Ô!Ü˜5 )¨UÀ¿*ÔEó ˆAØ�H‰HŽJñ ð 	×!Ñ!Õ#ô 	�ŒØÒ!Ü×!Ò!Ô"6°zÓ"BÓC×UÑUÔVhÔiô 	˜g u¨iÔ8Ü�‰ÐLÈeÐU^Ô_Ü�u˜i¨¸$Ô?ãˆAØ�H‰HŽJñ ð 	×!Ñ!Õ#ò] 2Aò0 `øÜ×%Ñ%ô 	Ü�TŒNØð	úñ ;Eøó ˆAØ�H‰HŽJñ ð 	×!Ñ!Õ#üsr   ˆ2J7ºI»BJ7ÃAJ7Ä!+I" ÅIÅI" ÅJ	 Å/J	 ÆJÆJ	 Æ*J7Æ?A3J	 È2+J7ÉI" É""JÊJ	 Ê	+J4Ê4J7Ú
on_timeoutc               ó0   € V ^8„  d   QhRRRRRRRRR	R
RR/# )r   ÚfnzCallable[[], Any]rV   rM   r   r   rÀ   zOptional[Callable[[], None]]r:   r;   r-   r
   r   )r   s   "r   r   r   0  sL   € ÷ 6Dñ 6DØð6Dàð6Dð ð	6Dð
 -ð6Dð ð6Dð ñ6Dr   c               óR  a a
aa€ \        V4      p\        P                  ! 4       pVf   \        VRVS ! 4       R7      # / o
\        P
                  ! 4       o\        P                  ! 4       oR V
VVV 3R llp\        P                  ! VRV 2RR7      P                  4        We,           pSP                  4       '       gF   V\        P                  ! 4       ,
          p	V	^ 8:  d   M!SP                  \        \        V	4      4       K[  SP                  4       '       g=   \        P                  RW%4       \!        WBV4       Ve	    V! 4        \        WeVRR7      # RS
9   d
   S
R,          h\        WeVS
P'                  R4      R7      #   \"         d    \        P%                  R	RR
7        L_i ; i)a|  Run ``fn`` in a daemon worker thread under a wall-clock deadline; exceptions re-raise in
the caller. On expiry the worker is **abandoned** (every timeout leaks one daemon thread, so
do NOT use per-item in hot loops) and ``on_timeout`` runs best-effort in the caller's thread.
The worker runs under ``contextvars.copy_context()`` so secret scope / session id survive.

See #94285.
Nr˜   c               ó   € V ^8„  d   QhRR/# rš   r   )r   s   "r   r   Ú&run_bounded_sync.<locals>.__annotate__H  s   € ÷ ñ �Tñ r   c                 ó¶   <€  SP                  S4      SR &   SP                  4        R#   \         d   p T SR&    Rp ? L'Rp ? ii ; i  SP                  4        i ; i)rK   ÚexcN)ÚrunÚBaseExceptionr�   )rÇ   ÚboxÚctxrž   rÂ   s    €€€€r   Ú_workerÚ!run_bounded_sync.<locals>._workerH  sK   ø€ ð	ØŸ7™7 2›;ˆC�‰Lð �H‰HŽJøô ô 	ØˆC�ŽJûð	ûð �H‰H�Jús#   ƒ) ©A´>¹A ¾AÁA ÁAz	deadline-T)ÚtargetÚnamer¸   z5[deadline] %r timed out after %.1fs; worker abandonedz#deadline on_timeout callback failedr>   r¯   rÇ   rK   )r]   rR   rS   rT   r´   rµ   ÚcontextvarsÚcopy_contextÚThreadrP   r¦   r¹   r[   Ú_BOUNDED_SYNC_WAIT_SLICE_SrC   rZ   rF   rB   rD   rd   )rÂ   rV   r   rÀ   r:   r   rP   rÌ   r    Ú	remainingrÊ   rË   rž   s   f&$$$     @@@r   Úrun_bounded_syncrÕ   0  sY  û€ ô ˜gÓ&€IÜ�NŠNÓ€EØÒÜ�u˜d E±³Ô6Ð6à€CÜ�?Š?Ó€DÜ
×
"Ò
"Ó
$€C÷ó ô ×Ò˜G¨I°e°WÐ*=ÀdÔK×QÑQÔSØÕ €HØ�k‰k�mŠmØœtŸ~š~Ó/Õ/ˆ	Ø˜Œ>ØØ�	‰	”#Ô0°)Ó<Ö=à�;‰;�=Š=Ü�‰ÐNÐPUÔaô 	˜g¨iÔ8ØÒ!ðSÙ”ô �u¨¸$Ô?Ð?à�„|Ø�%�jÐÜ�5 U°#·'±'¸'Ó2BÔCÐCøô ô SÜ—‘ÐBÈT�ÖRðSús   Ä?F Æ"F&Æ%F&c               ó    € V ^8„  d   QhRRRR/# )r   ÚpidÚintÚ	hard_killr5   r   )r   s   "r   r   r   m  s   € ÷ 6hñ 6h ð 6h°4ñ 6hr   c          	   #  óþ  "  € . p. p  ^ RI pVP                  V 4      pVP                  RR7      pV'       Edè   V.p\        P                  ! 4       0pV Uu/ uF  qˆP
                  VbK  	  p	p\        P                  ! 4       R,           p
V'       Ed�   V EF  pVP
                  V9   d   K  VP                  VP
                  4       \        P                  ! 4       V
8¼  d   \        R4      h VP                  4       pW´P                  VP                  39   d   K†  W´P                  8w  d"   VP                  4        VP                  V4       VP                  4       VP                  8w  d>   \        P                  ! 4       V
8¼  d   \        R4      h\        P                   ! R4       K\  EK  	  VP                  RR7       F  pV	P%                  VP
                  V4       K!  	  \'        V	P)                  4       4      pV Uu. uF  qˆP
                  V9  g   K  VNK  	  ppEK—  Tx € T F  p TP1                  4        K  	  R# u upi   TP"                   d     EKÆ  i ; iu upi   \*         d    \,        P/                  RT RR	7        Lhi ; i  \*         d    \,        P/                  R
RR	7        K‹  i ; i  T F=  p TP1                  4        K    \*         d    \,        P/                  R
RR	7        K;  i ; i	  i ; i5i)a  Stop each hard-kill target before discovering its children: a running
parent can fork after psutil builds its PID map and escape the final signal.
Resume anything we stopped if signalling fails. Graceful signals never stop
their recipients, since their handlers must remain able to run.
NT)Ú	recursiveg      ð?z2process tree did not stop before snapshot deadlinez-process did not stop before snapshot deadlinegü©ñÒMbP?z1kill_process_tree: snapshot incomplete for pid %sr>   z8kill_process_tree: target already gone or resume refused)ÚpsutilÚProcessÚchildrenru   Úgetpidr×   rR   rS   ÚaddÚTimeoutErrorÚstatusÚSTATUS_ZOMBIEÚSTATUS_DEADÚSTATUS_STOPPEDÚsuspendr·   ÚsleepÚNoSuchProcessÚ
setdefaultÚlistÚvaluesrB   rC   rD   Úresume)r×   rÙ   ÚdescendantsÚstoppedrÜ   ÚrootÚpendingÚseenÚprocessÚknownÚstop_deadlinerâ   s   &$          r   Ú_process_tree_snapshotrõ   l  s‹  é € ð €KØ€Gð.hð&	bÛØ—>‘> #Ó&ˆDØŸ-™-°$˜-Ó7ˆKßˆyØ˜&�ÜŸ	š	›�}�Ù=HÓI¹[°'Ÿ™ gÒ-¹[�ÐIÜ $§¢Ó 0°3Õ 6�ß�gÜ#*˜Ø"Ÿ;™;¨$Ô.Ù$ØŸ™ §¡Ô-ÜŸ>š>Ó+¨}Ô<Ü".Ð/cÓ"dÐdð%Ø%,§^¡^Ó%5˜FØ%×*>Ñ*>À×@RÑ@RÐ)SÔSÙ (Ø%×)>Ñ)>Ô>Ø '§¡Ô 1Ø '§¡¨wÔ 7Ø")§.¡.Ó"2°f×6KÑ6KÔ"KÜ#'§>¢>Ó#3°}Ô#DÜ*6Ð7fÓ*gÐ$gÜ $§
¢
¨5Ö 1ò #Lñ $+ð* $(§=¡=¸4 =Ö#@˜Ø×(Ñ(¨¯©°gÖ>ñ $Aä"& u§|¡|£~Ó"6�KÙ6AÓ]±k¨7Ç[Á[ÐX\ÑE\Ÿw˜w±k�GÐ]’Gð
 ÒãˆGðhØ—‘Ö ó ùòE Jøð(  &×3Ñ3ô %Û$ð%üò ^øÜô 	bô �L‰LÐLÈcÐ\`ˆLÖað	bûô ô hÜ—‘ÐWÐbf�×gðhûó ˆGðhØ—‘Ö øÜô hÜ—‘ÐWÐbf�×gðhúò üsà   ‚K=‰AI# ÁI Á+&I# ÂAI# Ã,,IÄI# ÄBIÆ'AI# Ç>IÈIÈI# È J5 È$K=È*JÈ:K=É I# ÉIÉI# ÉIÉI# É##J	ÊJ5 ÊJ	Ê	J5 Ê"J2Ê.K=Ê1J2Ê2K=Ê5K:Ê<KËK:Ë"K4	Ë0K:Ë3K4	Ë4K:Ë:K=Úsigc               ó$   € V ^8„  d   QhRRRRRR/# )r   r×   rØ   rö   zOptional[int]r-   r5   r   )r   s   "r   r   r   ¦  s!   € ÷ ;ñ ;˜3ð ;¨ð ;Àñ ;r   c          	     ó
  € \         P                  R8X  dW    ^ RIHp V! 4       p \
        P                  ! RRRR\        V 4      .\
        P                  R^RVR	7      pVP                  ^ 8H  # ^ RIpVf   VP                  p\        \        V 4      WP                  8H  R7      ;_uu_ 4       pRp\!        V4       F/  p VP#                  4       '       d   VP%                  V4       RpK/  K1  	   \&        P(                  ! V 4      p	 V	e   W�8X  d   \&        P0                  ! W‘4       M\&        P2                  ! W4       RpVuuRRR4       #   \         d    ^ p EL4i ; i  \         d    \        P                  R
T RR7        R# i ; i  \         d     KÜ  i ; i  \*        \,        \.        3 d    Rp	 L°i ; i  \*         d     L‡\,        \.        3 d    \        P                  RT RR7        L±i ; i  + '       g   i     R# ; i)a  Terminate ``pid`` and all its descendants, portably; True when anything was signalled.

Windows: ``taskkill /F /T`` (``sig`` ignored). POSIX: snapshot descendants via
psutil; for SIGKILL, stop and rescan the live tree so a concurrent fork cannot
escape a stale snapshot. Signal identity-checked descendants before their
parent, then its group when ``pid`` leads one. Stopping is best-effort with a
bounded wait; unavailable psutil still leaves process-group cleanup. Other
signals do not suspend recipients. ``sig`` defaults to ``SIGKILL``.r   )Úwindows_hide_flagsÚtaskkillz/Fz/Tz/PIDTF)ÚstdinÚcapture_outputrV   ÚcheckÚcreationflagsz-kill_process_tree: taskkill failed for pid %sr>   N)rÙ   z+kill_process_tree: signal failed for pid %s)ÚsysÚplatformÚhermes_cli._subprocess_compatrù   rB   Ú
subprocessrÈ   r   ÚDEVNULLÚ
returncoderC   rD   ÚsignalÚSIGKILLrõ   rØ   ÚreversedÚ
is_runningÚsend_signalru   ÚgetpgidÚProcessLookupErrorÚPermissionErrorÚOSErrorÚkillpgÚkill)
r×   rö   rù   rþ   ÚprocÚ_signalrí   Ú	signalledÚchildÚpgids
   &$        r   Úkill_process_treer  ¦  sÖ  € ô ‡|�|�wÔð	ÝHÙ.Ó0ˆMð		Ü—>’>Ø˜T 4¨´°S³Ð:Ü ×(Ñ(¸ÀrÐQVÐfsôˆDð
 —?‘? aÑ'Ð'ó
 Ø
‚{Ø�o‰oˆä	¤ C£°C¿?¹?Ñ4J×	KÕ	KÈ{Øˆ	ô ˜kÖ*ˆEðØ×#Ñ#×%Ò%Ø×%Ñ% cÔ*Ø $’Iñ &ñ +ð	ô —:’:˜c“?ˆDð
	\ØÒ D¤Kä—	’	˜$Õ$ä—’˜Ô!ØˆIð ÷; 
LÒ	Køô# ô 	Ø‹Mð	ûô ô 	Ü�L‰LÐHÈ#ÐX\ˆLÔ]Úð	ûô" ô Úðûô #¤O´WÐ=ô 	ØŠDð	ûô "ô 	ÙÜ¤Ð)ô 	\Ü�L‰LÐFÈÐVZˆLÖ[ð	\ú÷5 
L×	KÐ	Kús§   —E ¥AE Â*G1Â<)FÃ%G1Ã,FÄ9F6Ä<G1ÅEÅEÅ#FÆFÆF	ÆG1ÆF	ÆG1ÆF3Æ0G1Æ2F3Æ3G1Æ6G.ÇG1ÇG.ÇG.Ç+G1Ç-G.Ç.G1Ç1H	)r\   r
   r   r]   r  rz   r¿   rÕ   g®Gá’MbPA)1r&   Ú
__future__r   r°   rÐ   Ú
contextlibr   r�   Úloggingru   r  rÿ   r´   rR   Údataclassesr   Útypingr   r   r   r   r	   Ú	getLoggerr"   rC   Ú__all__Ú_WINDOWS_MAX_WAIT_Sr   r\   r�   rÓ   rá   r   r*   rF   r
   rT   r]   rg   ro   rz   r‚   r‡   r‹   r’   r¿   rÕ   rõ   r  r   r   r   Ú<module>r     s€  ðñõ #ã Û Ý %Û Û Û 	Û Û 
Û Û Ý !ß ?Õ ?à	×	Ò	˜8Ó	$€ò	€ð0 3Ð àŸ<™<¨7Ô2Ñ¸ð ð
 !Ð ð !Ð ô#�lô #ô*˜ô *õ	Dñ �$ Ô%÷ð ó &ððÐRVð Ðjo÷ õBõ$õð"ÐTX÷ "õNõ/õGõJð?$ð ð	?$ð
 :>ð?$ð "&ð?$ð "÷?$ðJ6Dð ð	6Dð
 04ð6Dð "÷6Dðx ô6hó ð6hðr;¸÷ ;ñ ;r   