+
    „WÝjÂ  ã                  ó¨  € R t ^ RIH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 ^ RIHt R tR R	 ltR
 R ltR R lt]! 0 R\m4      t]! ^^}04      tR R ltR R lt^tR^/R 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./R/ R0 llt)R1 R2 lt*R3R4/R5 R6 llt+R7 R8 lt,R9 R: lt-R; R< lt.R= R> lt/R? R@ lt0R]RAR4RBR./RC RD lllt1RE t2RF t3RG RH lt4RI RJ lt5RK RL lt6RM t7RN RO lt8R^RP RQ llt9RR t:RSt;R];RTRRURVRWR/RX RY llt<R]RZ R[ llt=R# )_aC  Gateway launchd (macOS LaunchAgent) backend: plist generation/refresh, bootstrap, start/stop/restart/status.

Extracted from ``hermes_cli/gateway.py``. Bodies read facade helpers through ``_gw()`` (late
binding on ``hermes_cli.gateway``) so the seams tests and callers patch on the facade keep
intercepting the moved code.
)Úannotations)ÚPathN©Úescape)ÚUTC)Úgateway_service_ownerc                 ó   € ^ RI Hp  V # )é    ©Úgateway)Ú
hermes_clir   r
   s    ÚNC:\Users\johnn\AppData\Local\hermes\hermes-agent\hermes_cli\gateway_launchd.pyÚ_gwr      s
   € Ý"Ø€Nó    c               ó   € V ^8„  d   QhRR/# ©é   ÚreturnÚstr© )Úformats   "r   Ú__annotate__r      s   € ÷ Lñ L˜3ñ Lr   c                 óP   € \        4       P                  4       p V '       d   RV  2# R# )z5Return the launchd service label, scoped per profile.zai.hermes.gateway-zai.hermes.gateway)r   Ú_profile_suffix)Úsuffixs    r   Úget_launchd_labelr      s(   € ä‹U×"Ñ"Ó$€Fß,2Ð ˜xÐ(ÐKÐ8KÐKr   c               ó    € V ^8„  d   QhRRRR/# )r   Úlabelr   r   r   )r   s   "r   r   r   "   s   € ÷ ñ ¨3ð °3ñ r   c                óÂ  € \         P                  ! 4       pRV 2RV 2r2\        P                  \        P                  \
        3pW#3 F(  p \        P                  ! RRV RV  2.R^RR7       Vu # 	   \        P                  ! RR.3R	^/\        4       P                  BR
R/B pRVP                  ;'       g    R9   d   V#  V#   T d     Kˆ  i ; i  T d     T# i ; i)a
  Launchd domain managing ``label`` (uncached): ``gui/<uid>`` (Aqua), then ``user/<uid>``
(Background/SSH), else the ``launchctl managername`` heuristic. Sibling profiles may live in
different domains, so never reuse the cached ``_launchd_domain()`` for another label.zgui/zuser/Ú	launchctlÚprintÚ/T)ÚcheckÚtimeoutÚcapture_outputÚmanagernamer#   r"   FÚAquaÚ )
ÚosÚgetuidÚ
subprocessÚCalledProcessErrorÚTimeoutExpiredÚFileNotFoundErrorÚrunr   Ú_CAPTURE_TEXTÚstdout)r   ÚuidÚ
gui_domainÚuser_domainÚlaunchctl_errorsÚdomainÚresults   &      r   Ú_probe_launchd_domain_for_labelr7   "   sý   € ô �)Š)‹+€CØ $ S E˜l¨e°C°5¨M�ä"×5Ñ5´z×7PÑ7PÔRcÐdÐØÓ+ˆð	Ü�NŠN˜K¨°V°H¸A¸e¸WÐ2EÐFÈdÐ\]ÐnrÕsØŠMñ ,ðÜ—’ ¨mÐ <ÑlÀaÐlÌ3Ë5×K^ÑK^ÑlÐfkÒlˆØ�f—m‘m×)Ð) rÔ*ØÐð +ð Ðøð  ô 	Úð	ûð ô ØØÐðús+   Á#CÁ4AC Â9C ÃCÃCÃCÃCc               ó   € V ^8„  d   QhRR/# r   r   )r   s   "r   r   r   <   s   € ÷ 	'ñ 	'˜ñ 	'r   c                 ó†   € \        4       p V P                  f   \        V P                  4       4      V n        V P                  # )ztDomain managing the current profile's gateway; cached per process so start/stop/restart agree.

See #40831, #23387.
)r   Ú_resolved_launchd_domainr7   r   )Úgws    r   Ú_launchd_domainr<   <   s9   € ô 
‹€BØ	×"Ñ"Ò*Ü&EÀb×FZÑFZÓF\Ó&]ˆÔ#Ø×&Ñ&Ð&r   c               ó    € V ^8„  d   QhRRRR/# )r   Úexcúsubprocess.CalledProcessErrorr   Úboolr   )r   s   "r   r   r   W   s   € ÷ >ñ >Ð+Hð >ÈTñ >r   c                ó(   € V P                   \        9   # )zJTrue when launchctl failed because the job isn't loaded (retry bootstrap).)Ú
returncodeÚ _LAUNCHD_JOB_UNLOADED_EXIT_CODES)r>   s   &r   Ú!_launchd_error_indicates_unloadedrD   W   s   € à�>‰>Ô=Ñ=Ð=r   c               ó    € V ^8„  d   QhRRRR/# )r   rB   Úintr   r@   r   )r   s   "r   r   r   \   s   € ÷ =ñ =¨cð =°dñ =r   c                ó   € V \         9   # )um   True when launchctl can't manage the domain even after a fresh bootstrap (macOS 26+) â€” degrade to detached.)Ú#_LAUNCHCTL_DOMAIN_UNSUPPORTED_CODES)rB   s   &r   Ú_launchctl_domain_unsupportedrI   \   s   € àÔ<Ñ<Ð<r   r#   c               ó(   € V ^8„  d   QhRRRRRRRR/# )r   r5   r   r   r#   rF   r   ÚNoner   )r   s   "r   r   r   e   s)   € ÷ ?ñ ? ð ?¸ð ?È#ð ?ÐW[ñ ?r   c               óf  € RRV \        V4      .p \        P                  ! VRVR7       R
#   \        P                   dp   pTP                  \
        8w  d   h \        P                  ! RRT  RT 2.3RRR	T/\        4       P                  B  \        P                  ! TRTR7        R
p?R
# R
p?ii ; i)zãBootstrap a launchd job, recovering from a stale still-registered label (EIO 5). Without the
bootout + retry that case is misread as an unmanageable domain and degrades to detached, silently
losing auto-start and crash-restart.r   Ú	bootstrapT©r"   r#   Úbootoutr!   r"   Fr#   N)r   r*   r.   r+   rB   Ú_LAUNCHCTL_BOOTSTRAP_EIOr   r/   )r5   Ú
plist_pathr   r#   rM   r>   s   &&&$  r   Ú_launchctl_bootstraprR   e   s­   € ð ˜k¨6´3°z³?ÐC€Ið?Ü�Š�y¨°g×>øÜ×(Ñ(ô 	?Ø�>‰>Ô5Ô5Øô 	�ŠØ˜)¨ x¨q°°Ð%8Ð9ñ	Aàð	Aà!(ð	Aä,/«E×,?Ñ,?ò	Aô 	�Š�y¨°g×>Ó>ûð	?ús   ‘, ¬B0ÁA$B+Â+B0c               ó   € V ^8„  d   QhRR/# ©r   r   r   r   )r   s   "r   r   r   x   s   € ÷ Cñ C $ñ Cr   c                 óN   € \        4       P                  4       R,          R,          # )zGPath the launchd reload watchdog tails for persistent-orphan detection.Úlogszlaunchd-reload.log©r   Úget_hermes_homer   r   r   Ú_launchd_reload_log_pathrY   x   s   € ä‹5× Ñ Ó" VÕ+Ð.BÕBÐBr   c               ó    € V ^8„  d   QhRRRR/# ©r   Úmessager   r   rK   r   )r   s   "r   r   r   }   s   € ÷ 
ñ 
¨ð 
°ñ 
r   c           	     ó€  € \        4       p VP                  P                  RRR7       ^ RIHp VP	                  4       P                  4       P                  R4      pVP                  RRR7      ;_uu_ 4       pVP                  RV R	V  R
24       RRR4       R#   + '       g   i     R# ; i  \         d     R# i ; i)zBAppend a timestamped line to the launchd reload log (best-effort).T©ÚparentsÚexist_ok)Údatetimez%Y-%m-%d %H:%M:%S %zÚaúutf-8©ÚencodingÚ[z] Ú
N)
rY   ÚparentÚmkdirra   ÚnowÚ
astimezoneÚstrftimeÚopenÚwriteÚOSError)r\   ÚpathÚ_dtÚstampÚfhs   &    r   Ú_append_launchd_reload_logrt   }   s™   € ä#Ó%€DðØ�‰×Ñ $°ÐÔ6Ý,Ø—‘“	×$Ñ$Ó&×/Ñ/Ð0FÓGˆØ�Y‰Y�s WˆY×-Ô-°Ø�H‰H�q˜˜˜r ' ¨"Ð-Ô.÷ .×-×-Ò-ûäô Úðús0   ŒA+B. Á7BÂB. ÂB+	Â%B. Â+B. Â.B=Â<B=c               ó   € V ^8„  d   QhRR/# )r   r   Úfloatr   )r   s   "r   r   r   Š   s   € ÷ 9ñ 9 ñ 9r   c                 óF   € \        R\        4       P                  4       4      # )z¨Bootstrap retry window for a plist reload: the failure happens while the old gateway is still
draining (default 180s), so size it to the drain timeout with a 30s floor.g      >@)Úmaxr   Ú_get_restart_drain_timeoutr   r   r   Ú_launchd_reload_budgetrz   Š   s   € ô ˆt”S“U×5Ñ5Ó7Ó8Ð8r   c               ó    € V ^8„  d   QhRRRR/# )r   r   r   r   ú
int | Noner   )r   s   "r   r   r   �   s   € ÷ Dñ D Sð D¨Zñ Dr   c                ó  €  \         P                  ! RRV .3RRR^
/\        4       P                  B pTP                  ^ 8w  d   R# \        4       P                  TP                  4      #   \         P                  \
        3 d     R# i ; i)u›  PID launchd currently runs for ``label``, or None when it runs none. ``launchctl list`` exits 0 for
a mere registered definition (``state = not running`` on macOS 26+), so a PID â€” not the exit code â€” is
the answer. Domain-agnostic on purpose: ``launchctl print`` domain probes fail on macOS-26 per-user
domains, which is why the invoking profile verifies through this and not ``_launchd_print_service_pid``.r   Úlistr"   Fr#   N)	r*   r.   r   r/   r,   ro   rB   Ú#_parse_launchd_pid_from_list_outputr0   )r   r6   s   & r   Ú_launchctl_supervised_pidr€   �   s   € ð
Ü—’ ¨f°eÐ <ÑmÀEÐmÐSUÐmÔY\ÓY^×YlÑYlÑmˆð ×Ñ˜AÔÙÜ‹5×4Ñ4°V·]±]ÓCÐCøô	 ×%Ñ%¤wÐ/ô Úðús   ‚0A( Á(BÂBc               ó    € V ^8„  d   QhRRRR/# )r   r   r   r   r@   r   )r   s   "r   r   r   ž   s   € ÷ >ñ >°ð >¸ñ >r   c                ó8   € \        4       P                  V 4      RJ# )z<True when launchd knows ``label`` AND runs a process for it.N)r   r€   ©r   s   &r   Ú$_launchctl_label_supervising_processr„   ž   s   € ä‹5×*Ñ*¨5Ó1¸Ð=Ð=r   c               ó(   € V ^8„  d   QhRRRRRRRR/# )r   r5   r   r   Údeadlinerv   r   r@   r   )r   s   "r   r   r   £   s,   € ÷ ñ ØðØ$'ðØ6;ðà	ñr   c               óú  € ^ p V^,          p \        4       P                  WV^R7       \        4       P                  V4      '       d   R# RV  RV R2p\        4       P                  R
V RV R24       \        P                  ! 4       V8¼  d   R# \        P                  ! ^4       K¥    \        P                   d    pRTP
                   RT  RT 2p Rp?LƒRp?i\        P                   d    R	T  RT 2p L¥i ; i)uÂ   Retry ``_launchctl_bootstrap`` until the label supervises a process or ``deadline`` passes. Under
load bootstrap can fail even after bootout, during a drain (default 180s) â€” ~10s is too short.T©r#   zexited 0 but r!   z+ has no supervised process (launchctl list)zfailed (rc=z) for Nztimed out for zbootstrap attempt Ú u    â€” retryingF)r   rR   r„   r*   r+   rB   r,   rt   ÚtimeÚ	monotonicÚsleep)r5   rQ   r   r†   ÚattemptÚoutcomer>   s   &&&$   r   Ú+_retry_launchctl_bootstrap_until_registeredr�   £   sò   € ð
 €GØ
Ø�1�ˆð	8Ü‹E×&Ñ& v¸5È"Ð&ÔMÜ‹u×9Ñ9¸%×@Ò@ÙØ% f X¨Q¨u¨gÐ5`ÐaˆGô
 	‹×(Ñ(Ð+=¸g¸YÀaÈÀyÐP]Ð)^Ô_Ü�>Š>Ó˜xÔ'ÙÜ�
Š
�1Žøô ×,Ñ,ô 	KØ# C§N¡NÐ#3°6¸&¸ÀÀ5À'ÐJ�GûÜ×(Ñ(ô 	8Ø& v h¨a°¨wÐ7ŠGð	8ús)   Ž;B( Á	B( Â(C:Â=CÃC:Ã.	C:Ã9C:c               ó   € V ^8„  d   QhRR/# rT   r   )r   s   "r   r   r   ¼   s   € ÷ Dñ D¨$ñ Dr   c                 ó@   € \        4       P                  4       R ,          # )z.gateway-launchd-unsupportedrW   r   r   r   Ú _launchd_unsupported_marker_pathr’   ¼   s   € Ü‹5× Ñ Ó"Ð%CÕCÐCr   c               ó   € V ^8„  d   QhRR/# ©r   r   rK   r   )r   s   "r   r   r   À   s   € ÷ ]ñ ]¨4ñ ]r   c                 ó@  € ^ RI H p Hp RV P                  \        4      P	                  4       RR/p\
        P                  ! \        4      ;_uu_ 4        \        4       P                  \        P                  ! V4      RR7       RRR4       R#   + '       g   i     R# ; i)z?Persist that launchd cannot supervise the gateway on this host.)ra   ÚtimezoneÚ
written_atÚreasonz'launchd domain unsupported (exit 5/125)rc   rd   N)ra   r–   rj   r   Ú	isoformatÚ
contextlibÚsuppressro   r’   Ú
write_textÚjsonÚdumps)ra   r–   Úpayloads      r   Ú!_write_launchd_unsupported_markerr    À   sk   € ç+à�h—l‘l¤3Ó'×1Ñ1Ó3ØÐ;ð€Gô 
×	Ò	œW×	%Õ	%Ü(Ó*×5Ñ5´d·j²jÀÓ6IÐT[Ð5Ô\÷ 
&×	%×	%Ò	%ús   Á0BÂB	c               ó   € V ^8„  d   QhRR/# r”   r   )r   s   "r   r   r   Ë   s   € ÷ Cñ C¨4ñ Cr   c                 ó¸   € \         P                  ! \        4      ;_uu_ 4        \        4       P	                  RR7       RRR4       R#   + '       g   i     R# ; i)z=Clear the unsupported marker when launchd bootstrap succeeds.T)Ú
missing_okN)rš   r›   ro   r’   Úunlinkr   r   r   Ú!_clear_launchd_unsupported_markerr¥   Ë   s6   € ä	×	Ò	œW×	%Õ	%Ü(Ó*×1Ñ1¸TÐ1ÔB÷ 
&×	%×	%Ò	%ús   £AÁA	c               ó   € V ^8„  d   QhRR/# ©r   r   r@   r   )r   s   "r   r   r   Ñ   s   € ÷ 7ñ 7¨Dñ 7r   c                 ó2   € \        4       P                  4       # )N)r’   Úexistsr   r   r   Ú"_launchd_unsupported_marker_existsrª   Ñ   s   € Ü+Ó-×4Ñ4Ó6Ð6r   c               ó   € V ^8„  d   QhRR/# )r   r   ú	list[str]r   )r   s   "r   r   r   Õ   s   € ÷ 	;ñ 	;˜iñ 	;r   c                 ó|  € ^ RI Hp  ^ RIHp \        P
                  ! \        4       P                  4       4      pV'       gC   \        4       P                  4       P                  4       V! 4       P                  4       8X  d   RR.pV ! \        4       P                  . VORNRNRN\        4       P                  4       R7      # )	r	   )Úruntime_command)Úget_default_hermes_rootz	--profileÚdefaultr   r.   ú	--replace©Úpython)Úhermes_cli._launchersr®   Úhermes_constantsr¯   ÚshlexÚsplitr   Ú_profile_argrX   ÚresolveÚPROJECT_ROOTÚget_python_path)r®   r¯   Úselectors      r   Ú_gateway_run_commandr½   Õ   s”   € Ý5Ý8ô �{Š{œ3›5×-Ñ-Ó/Ó0€Hßœ›×-Ñ-Ó/×7Ñ7Ó9Ñ=TÓ=V×=^Ñ=^Ó=`Ô`Ø Ð+ˆÙœ3›5×-Ñ-Ð/Y°Ð/Y¸9Ð/YÀeÐ/YÈ[Ð/YÜ"%£%×"7Ñ"7Ó"9ô;ð ;r   c               ó(   € V ^8„  d   QhRRRRRRRR/# )r   Úcommandr¬   Ú
stdout_logr   Ú
stderr_logr   r   )r   s   "r   r   r   á   s0   € ÷ Hñ H yð H¸dð HÐPTð HÐYbñ Hr   c           
     óö   € R\         P                  ! V 4       R\         P                  ! \        V4      4       R\         P                  ! \        V4      4       2pR\        P
                  ! V4       R2pRRRR	V.# )
uW  launchd ``ProgramArguments`` that run ``command`` with a Local Network identity macOS accepts (#71206).

macOS Local Network Privacy attributes a socket to the process launchd spawned for the job. A bare
venv Python has no application ID and is not platform-entitled, so every LAN connect from the
launchd gateway dies with ``EHOSTUNREACH`` while the same code works from Terminal (whose grant it
inherits). An ad-hoc-signed helper .app does not help: nehelper never prompts for it and denies
(#57812 dead-end table, re-verified live on macOS 26.3). ``/usr/bin/osascript`` spawning the child
makes it osascript-responsible â€” an Apple platform binary â€” so the child is exempt; ``/bin/sh -c
exec â€¦`` and ``/usr/bin/time`` wrappers are NOT (the launchd job identity is the non-entitled first
executable).

Standard Additions' ``do shell script`` polls WindowServer for a user-cancel event while it waits.
That is appropriate for a short interactive script but, for the gateway's process lifetime, burns CPU
and keeps a WindowServer event connection busy (external-display wake stalls ~10s on macOS 27, #123595).
JXA calling libc ``system()`` waits in the kernel instead while retaining osascript as the responsible
process. The shell's ``exec`` keeps the gateway in the launchd job's process group, so ``launchctl
bootout`` / ``kickstart -k`` still deliver SIGTERM to it. stdout/stderr are appended inside the shell
command because ``system()`` otherwise inherits osascript's plist log handles. The encoded wait status
is translated back to a process exit code so KeepAlive's ``SuccessfulExit`` semantics are preserved.
zexec z >> z 2>> z-ObjC.import("stdlib"); const status=$.system(zl); const signal=status & 127; $.exit(status === -1 ? 1 : signal === 0 ? (status >> 8) & 255 : 128 + signal);z/usr/bin/osascriptú-lÚ
JavaScriptú-e)r¶   ÚjoinÚquoter   r�   rž   )r¿   rÀ   rÁ   ÚshellÚ
javascripts   &&&  r   Úlaunchd_program_argumentsrÊ   á   s€   € ð* ”E—J’J˜wÓ'Ð(¨¬U¯[ª[¼¸Z»Ó-IÐ,JÈ%ÔPU×P[ÒP[Ô\_Ð`jÓ\kÓPlÐOmÐn€Eð	!Ü!%§¢¨EÓ!2Ð 3ð 4Yð	Yð ð ! $¨°d¸JÐGÐGr   Úexternal_supervisorFc               ó$   € V ^8„  d   QhRRRRRR/# )r   Ú	error_logr   rË   r@   r   r¬   r   )r   s   "r   r   r      s(   € ÷ Yñ Y°4ð YÐQUð YÐbkñ Yr   c               ó   € ^ RI HpHp \        4       P	                  4       pV'       d•   V! \        4       P
                  . \        P                  ! \        4       P                  4       4      ORNRN\        4       P                  4       R7      pV Uu. uF  qUR8w  g   K  VNK  	  ppRV9  d   VP                  R4       V'       d   TMTpV! \        4       P
                  R\        V 4      R.VOR	\        4       P                  4       R
7      # u upi )uä  Wrap gateway run so raw stderr lines are timestamped before file write. ``external_supervisor``
(launchd ProgramArguments only) adds ``--external-supervisor`` so ``hermes update`` hands back to
launchd, and drops ``--replace``: KeepAlive respawns would re-arm takeover, so two profiles sharing
a token would kill each other forever.

``external_supervisor=True`` is for launchd ProgramArguments only: the inner ``gateway run`` must carry
``--external-supervisor`` so ``hermes update`` sees the flag on the live grandchild argv and hands the
process back to launchd instead of starting a detached watcher (#86893 / #87005). The detached nohup
fallback stays unmarked.
Supervised starts also drop ``--replace`` (issue #79048): a launchd service is respawned by KeepAlive,
so takeover authority would be re-armed on every respawn â€” two profiles legitimately sharing one
platform token would each terminate the sibling, and launchd would revive the victim forever. Bounded
replacement is the lifecycle commands' job (``launchctl kickstart -k``, drain in ``launchd_restart()``,
bootout+bootstrap in install/refresh), which run before supervision resumes. Mirrors
``generate_systemd_unit``, whose ExecStart also runs ``gateway run`` without ``--replace``.
)Úinstallation_commandr®   r   r.   r²   r±   z--external-supervisorz--error-logú--zhermes_cli.stderr_timestamp)Úmoduler³   )r´   rÏ   r®   r   r½   rº   r¶   r·   r¸   r»   Úappendr   )rÍ   rË   rÏ   r®   ÚinnerÚpartr¿   s   &$     r   Ú#_timestamped_stderr_gateway_commandrÕ      sá   € ÷" LÜ‹E×&Ñ&Ó(€EßÙ$¤S£U×%7Ñ%7Ð9o¼5¿;º;ÄsÃu×GYÑGYÓG[Ó;\Ð9oÐ^gÐ9oÐinÐ9oÜ,/«E×,AÑ,AÓ,CôEˆá"'Ó?¡%˜$°;Ñ+>—�¡%ˆÐ?Ø"¨%Ô/Ø�L‰LÐ0Ô1ß&9Ñ"¸€GÙ”3“5×%Ñ%¨´s¸9³~ÀtÐ'TÈeÐ'TØ7ÄÃ×@UÑ@UÓ@WôYð Yùò	 @s   ÂDÂDc               ó   € V ^8„  d   QhRR/# r§   r   )r   s   "r   r   r     s   € ÷ ñ  ñ r   c                 ó  € ^ RI Hp  ^ RIHp ^ RIHp \        4       P                  4       R,          pVP                  RRR7       V! V! 4       RR7      pVP                  RR	4        \        VR
,          R4      ;_uu_ 4       p\        P                  ! \        VR,          4      3R\        P                  RVR\        P                  RV/V ! 4       B  R	R	R	4       R#   + '       g   i     R# ; i  \         d     R# i ; i)u7  Launch the gateway detached (launchd fallback for macOS 26+). CLI-managed nohup equivalent:
stdout â†’ gateway.log, timestamped stderr â†’ gateway.error.log, PID via gateway.pid so stop/status work.

Used when launchctl can no longer bootstrap/kickstart the gateway on macOS 26+ (issue #23387). Mirrors
the `nohup hermes gateway run --replace` workaround but keeps it CLI-managed: stdout goes to
gateway.log, stderr is timestamped into gateway.error.log, and the PID is tracked via the gateway.pid
file that `run_gateway` writes, so stop/status/restart keep working.
)Úwindows_detach_popen_kwargs)rX   )Úserved_profile_child_envrV   Tr^   )Útarget_homeÚinherit_credentialsÚ_HERMES_GATEWAYNúgateway.logÚabúgateway.error.logÚstdinr0   ÚstderrÚenvF)Úhermes_cli._subprocess_compatrØ   rµ   rX   Útools.environments.localrÙ   r   ri   Úpoprm   r*   ÚPopenrÕ   ÚDEVNULLro   )rØ   rX   rÙ   Úlog_dirÚ	child_envÚouts         r   Ú_spawn_detached_gatewayrë     sñ   € õ JÝ0ÝAÜ‹e×#Ñ#Ó%¨Õ.€GØ‡M�M˜$¨€MÔ.Ù(Ù#Ó%¸4ô€Ið ‡M�MÐ# TÔ*ð	Ü�'˜MÕ)¨4×0Ô0°CÜ×ÒÜ3°GÐ>QÕ4QÓRñä ×(Ñ(ðà14ðä=G×=OÑ=Oðð ðñ .Ó/ò	÷ 1ñ ÷ 1Ö0ñ ûô ô Úðús1   Á'C1 ÂACÃC1 ÃC.	Ã(C1 Ã.C1 Ã1D Ã?D Úexit_on_failureTc               ó$   € V ^8„  d   QhRRRRRR/# )r   r˜   r   rì   r@   r   r   )r   s   "r   r   r   =  s"   € ÷ ñ ¨#ð À4ð ÐSWñ r   c               ó   € ^ RI Hp \        4       P                  4        \	        RV  R24       \        4       P                  4       '       d8   \	        R4       \	        R4       \	        RV! 4        R24       \	        R4       R	# \        4       P                  R
4       \	        RV! 4        R24       V'       d   \        P                  ! ^4       R# )zxStart the gateway detached when launchd can't manage it; on failure print the manual workaround
and (by default) exit 1.©Údisplay_hermes_homeu=   âš  launchd cannot manage the gateway on this macOS version (z).u3   âœ“ Started gateway as a background process insteadz;  It will NOT auto-start at login or auto-restart on crash.z  Logs: z/logs/gateway.logz#  Stop it with: hermes gateway stopTz4Failed to start the gateway as a background process.z5  Try manually: nohup hermes gateway run --replace > z/logs/gateway.log 2>&1 &F)	rµ   rð   r   r    r    rë   Úprint_errorÚsysÚexit)r˜   rì   Ú_dhhs   &$ r   Ú_launchd_fallback_to_detachedrõ   =  s¢   € õ =ÜƒE×+Ñ+Ô-Ü	ÐIÈ&ÈÐQSÐ
TÔUÜ
ƒu×$Ñ$×&Ò&ÜÐCÔDÜÐKÔLÜ�™›˜Ð 1Ð2Ô3ÜÐ3Ô4ÙÜƒE×ÑÐLÔMÜ	ÐAÁ$Ã&ÀÐIaÐ
bÔcßÜ�Š�ŒÙr   c               ó$   € V ^8„  d   QhRRRRRR/# )r   r>   r?   Úwhatr   r   rK   r   )r   s   "r   r   r   P  s(   € ÷ Cñ CÐ#@ð CÈð CÐPTñ Cr   c                óN  € \        V P                  4      '       g   V h\        4       P                  4       p\        4       P	                  V4      '       d7   \        RV RV P                   RV 24       \        R4       \        R4       V h\        V RV P                   24       R# )uV  Shared launchctl failure policy: domain unmanageable (5/125) â†’ detached fallback; else re-raise.

A 5/125 exit is evidence about the *domain* only when launchd is not already supervising this job.
EIO (5) is ``launchctl bootstrap``'s answer for a label that is already loaded, so the ordinary
"reinstall/restart over the live gateway" case lands here with the service up and supervised.
Degrading there is not a graceful fallback: it writes the permanent launchd-unsupported marker and
starts a detached gateway *beside* the supervised one, and the marker makes
:func:`wait_for_launchd_gateway_supervision` answer True unconditionally â€” so no later
install/update can tell that nothing ties the gateway to launchd any more. A live supervised PID is
direct evidence this macOS does manage the job, so surface the failure instead of branding the host.
u   âš  z failed (exit z ), but launchd still supervises uG     Not switching to the detached fallback â€” this host manages the job.zR  Apply the definition with: hermes gateway stop && hermes gateway install --forcez exit N)rI   rB   r   r   r„   r    rõ   )r>   r÷   r   s   && r   Ú_launchd_degrade_or_raiserù   P  s�   € ô )¨¯©×8Ò8Øˆ	Ü‹E×#Ñ#Ó%€EÜ
ƒu×1Ñ1°%×8Ò8Ü��T�F˜.¨¯©Ð(8Ð8XÐY^ÐX_Ð`ÔaÜÐWÔXÜÐbÔcØˆ	Ü! T F¨&°·±Ð0@Ð"AÖBr   c               ó   € V ^8„  d   QhRR/# r   r   )r   s   "r   r   r   g  s   € ÷ jñ j ñ jr   c                 óž  a€ ^ RI Ho \        4       P                  4       p \	        \        4       P                  4       P                  4       4      p\        4       P                  4       R,          pVP                  RRR7       \        4       P                  4       p\        4       P                  4       p\        4       P                  V4       RP                  \        P                  T\        P                  P!                  RR4      P#                  R4       Uu. uF  qU'       g   K  VNK  	  up,           4      4      pVR,          VR	,          r‡\%        VRR
7      p	RP                  V3R l\'        W—V4       4       4      p
Rp ^ RIHp V! 4       pV'       d   RV R2pRV RV
 RV  RV RV RV RV RV R2# u upi   \,         d    Rp L=i ; i)r	   r   rV   Tr^   Ú:ÚPATHr'   rÝ   rß   )rË   z	
        c              3  ó<   <"  € T F  pR S! V4       R2x € K  	  R# 5i)z<string>z	</string>Nr   )Ú.0rÔ   r   s   & €r   Ú	<genexpr>Ú)generate_launchd_plist.<locals>.<genexpr>z  s"   øé € ð &Ù7q¨tˆ(‘6˜$“<�. 	Õ*Ó7qùs   ƒ)Úconfigured_nofile_soft_limitNz`
    <key>SoftResourceLimits</key>
    <dict>
        <key>NumberOfFiles</key>
        <integer>z</integer>
    </dict>
zÌ<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>Label</key>
    <string>z?</string>

    <key>ProgramArguments</key>
    <array>
        z?
    </array>
    
    <key>WorkingDirectory</key>
    <string>zf</string>
    
    <key>EnvironmentVariables</key>
    <dict>
        <key>PATH</key>
        <string>z:</string>

        <key>HERMES_HOME</key>
        <string>u_  </string>
        <key>HERMES_SUPERVISED_CHILD</key>
        <string>1</string>
    </dict>

    <key>LimitLoadToSessionType</key>
    <array>
        <string>Aqua</string>
        <string>Background</string>
    </array>
    
    <key>RunAtLoad</key>
    <true/>
    
    <key>KeepAlive</key>
    <dict>
        <key>SuccessfulExit</key>
        <false/>
    </dict>

    <!-- SuccessfulExit=false parks a clean stop (exit 0), including gateway
         EX_CONFIG 78 after stderr_timestamp maps it to 0 â€” launchd cannot
         honor RestartPreventExitStatus, and KeepAlive=true respawned token
         collisions forever (#89477). Exit 75 and crashes still relaunch.
         ThrottleInterval raises launchd's default 10s minimum respawn interval
         to 30s so a crash-looping gateway can't hammer launchd into a rapid
         respawn storm; ExitTimeOut is the graceful-drain headroom before
         launchd escalates from SIGTERM to SIGKILL on stop. The per-user
         (gui) launchd domain clamps it to 60s regardless of what is written
         here, so 60 is the most a LaunchAgent can get; the gateway reads
         the live value at boot and fits its signal-driven drain inside it
         (gateway.restart.read_launchd_exit_timeout_s). -->
    <key>ThrottleInterval</key>
    <integer>30</integer>

    <key>ExitTimeOut</key>
    <integer>60</integer>
z,
    <key>StandardOutPath</key>
    <string>z<</string>
    
    <key>StandardErrorPath</key>
    <string>z</string>
</dict>
</plist>
)Úhtmlr   r   Ú_stable_service_working_dirr   rX   r¹   ri   r   Ú_build_service_path_dirsÚ_append_node_dir_for_servicerÆ   ÚdictÚfromkeysr(   ÚenvironÚgetr·   rÕ   rÊ   Úhermes_cli.resource_limitsr  Ú	Exception)Úworking_dirÚhermes_homerè   r   Úpriority_dirsÚpÚ	sane_pathrÀ   rÁ   r¿   Úprog_args_xmlÚnofile_blockr  Únofile_targetr   s                 @r   Úgenerate_launchd_plistr  g  sâ  ø€ Ýä“%×3Ñ3Ó5€KÜ”c“e×+Ñ+Ó-×5Ñ5Ó7Ó8€KÜ‹e×#Ñ#Ó%¨Õ.€GØ‡M�M˜$¨€MÔ.Ü‹E×#Ñ#Ó%€Eô “E×2Ñ2Ó4€MÜƒE×&Ñ& }Ô5Ø—‘œŸ™ }Ä2Ç:Á:Ç>Á>ÐRXÐZ\ÓC]×CcÑCcÐdgÔChÓ7nÑCh¸aÓlm¿¸ÑChÑ7nÕ'nÓoÓp€Ið % }Õ4°gÐ@SÕ6S�
Ü1°*ÐRVÔW€GØ ×%Ñ%ô &Ü7PÐQXÐfpÔ7qó&ó €Mð €LðÝKÙ4Ó6ˆ÷ ðð  �ð !ð	ˆðð
 ˆGð 	ð 
ˆð ð ˆMð ð
 �ð ð �ð %ðJ €ð àˆLð ð ˆLð ðBð Bùò7 8oøô  ô ØŠðús   Ä	F7Ä$F7ÆF< Æ<GÇGc               ó   € V ^8„  d   QhRR/# r§   r   )r   s   "r   r   r   Ô  s   € ÷ Cñ C $ñ Cr   c                 óü   € \        4       P                  4       p V P                  4       '       g   R# V P                  RR7      p\        4       P                  pV! V4      V! \        4       P                  4       4      8H  # )zICheck if the installed launchd plist matches the currently generated one.Fz	utf-8-sigrd   )r   Úget_launchd_plist_pathr©   Ú	read_textÚ'_normalize_launchd_plist_for_comparisonr  )rQ   Ú	installedÚnorms      r   Úlaunchd_plist_is_currentr  Ô  sc   € ä“×-Ñ-Ó/€JØ×Ñ×ÒÙØ×$Ñ$¨kÐ$Ó:€IÜ‹5×8Ñ8€DÙ�	‹?™d¤3£5×#?Ñ#?Ó#AÓBÑBÐBr   c               ó0   € V ^8„  d   QhRRRRRRRRRRR	R
/# )r   r5   r   r   ÚtargetrQ   r   Úgateway_pidrF   r   r@   r   )r   s   "r   r   r   Þ  sD   € ÷ Añ AØðAØðAØ(+ðAØ9=ðAØLOðAà	ñAr   c                ó   € \        4       p\        P                  ! \        4      ;_uu_ 4        VP                  P                  RRR7       RRR4       \        4       P                  RV 24       \        \        4       4      p\        P                  ! V4      \        P                  ! V4      \        P                  ! \        V4      4      r˜pRp
RV R2pV R\        P                  ! 4        R	\        \        P                  ! 4       4       2pR
P!                  . RNV NRNV NRNV NRNV
 NRNV NRNV NRNV	 NRNV NRN\        P                  ! V 4       NRN\        P                  ! \        V4      4       NRNV NRNV
 NRNV NRNV	 NRNV NRNV
 NRNV NRNV NRNV	 NRN\        P                  ! V4       NRN4      p \"        P$                  ! R R!R"VR#\        V4      R$\        V4      R%R&R'V.\"        P&                  \"        P&                  R(7       R#   + '       g   i     ELÝ; i  \(         dP   p\        4       P*                  P-                  R)T4       \        4       P                  R*T R+T R,24        Rp?R-# Rp?ii ; i).a  Hand the bootout/bootstrap cycle to a transient ``launchctl submit`` job; True if spawned. The
helper waits for the OLD gateway to exit (bootstrap during drain fails EIO), then retries bootstrap
until ``launchctl list`` shows a positive PID or the drain budget elapses.Tr^   Nz"Launchd reload helper started for z$(date '+%Y-%m-%d %H:%M:%S %z')zlaunchctl list z+ 2>/dev/null | grep -qE '\"PID\" = [0-9]+;'z.reload.Ú.r'   zsleep 2; launchctl bootout z. 2>/dev/null; _wait_deadline=$(($(date +%s) + z)); while kill -0 zK 2>/dev/null; do   if [ $(date +%s) -ge $_wait_deadline ]; then     echo "[z] old gateway pid ú still alive after u*   s drain wait â€” bootstrapping anyway" >> zH;     break;   fi;   sleep 1; done; sleep 1; _deadline=$(($(date +%s) + z&)); while :; do   launchctl bootstrap r‰   z 2>/dev/null;   if z; then break; fi;   echo "[z#] bootstrap not yet registered for u    â€” retrying" >> zM;   if [ $(date +%s) -ge $_deadline ]; then break; fi;   sleep 2; done; if ! z; then   echo "[z] FAILED launchd reload for u"    â€” service NOT registered after zs of retries" >> z; fi; launchctl remove z 2>/dev/nullr   ÚsubmitrÃ   z-orÅ   rÐ   z	/bin/bashz-c)r0   rá   z0Deferred launchd reload could not be spawned: %sz*FAILED to spawn launchd reload helper for z: u1    â€” falling back to in-process bootout/bootstrapF)rY   rš   r›   ro   rh   ri   r   rt   rF   rz   r¶   rÇ   r   r(   ÚgetpidrŠ   rÆ   r*   ræ   rç   r  ÚloggerÚwarning)r5   r   r  rQ   r   Úreload_log_pathÚ_reload_budgetÚq_targetÚq_labelÚq_logrr   ÚlistedÚsubmit_labelÚreload_scriptÚes   $$$$$          r   Ú_spawn_deferred_launchd_reloadr1  Þ  sÍ  € ô /Ó0€OÜ	×	Ò	œW×	%Õ	%Ø×Ñ×$Ñ$¨T¸DÐ$ÔA÷ 
&ô ƒE×$Ñ$Ð'IÈ&ÈÐ%RÔSäÔ/Ó1Ó2€NÜ$Ÿ{š{¨6Ó2´E·K²KÀÓ4FÌÏÊÔTWÐXgÓThÓHi�u€HØ-€Eð ˜w˜iÐ'VÐW€Fà�W˜H¤R§Y¢Y£[ M°´3´t·y²y³{Ó3CÐ2DÐE€L÷	Dó 	Dð ð 	DØ%˜Jð	Dð'+ð	Dð ,:Ð*:ð	Dð;ð	Dð %˜ð		Dð&ð		Dð
 �gð	Dð
 0ð	Dð
 1<¨}ð	Dð
 =Pð	Dð
 Q_ÐO_ð	Dð
 `Kð	Dð
 LQð  KRð	Dð
R/ð	Dð 0>Ð.>ð	Dð?!ð	Dô "'§¢¨VÓ!4Ð 5ð	Dð 67ð	Dô 8=·{²{Ä3ÀzÃ?Ó7SÐ6Tð	DðUð	Dð ˆxð	Dðð	Dð �Gð	Dð ?ð	Dð @H¸jð	Dð I\ð	Dð ]bÐ[bð	Dðcð	Dð ˆxð	Dðð	Dð �Gð	Dð 8ð	Dð 9A°zð	Dð Bdð	Dð esÐcsð	Dð tFð	Dð GLð  FMð	DðMð	Dô" "ŸKšK¨Ó5Ð6ð#	Dð" 7Cô#	Dð ð(ô 	×Òà˜X t¨\¸4ÄÀ_ÓAUÐW[Ô]`ÐapÓ]qØ�k 4¨ðô ×%Ñ%Ü×%Ñ%õ	
ñ ÷u 
&×	%Ð	%ûôf ô ä‹�‰×ÑÐOÐQRÔSÜ‹×(Ñ(Ø8¸¸ÀÀ1À#ÐEvÐwô	
õ ûðús%   ­HÇ
AH3 ÈH0	È3JÈ>AJÊJc               ó   € V ^8„  d   QhRR/# r§   r   )r   s   "r   r   r   "  s   € ÷ Bñ B¨ñ Br   c            	     óP  € \        4       P                  4       p V P                  4       '       d   \        4       P                  4       '       d   R# ^ RIHp V! V \        4       P                  4       R4      '       g   R# \        4       P                  4       p\        P                  ! VR4      '       d   R# \        4       P                  4        V P                  VRR7       \        4       P                  4       p\        4       P                  4       pV RV 2p ^ RIHp V! 4       pVe8   \#        \$        R
4      '       d"   \'        WCWPVR7      '       d   \)        R4       R# \*        P,                  ! RRV.3RRR^Z/\        4       P.                  B  \1        4       pVeL   \        4       P3                  Wx4      '       g-   \        4       P5                  RV R\7        V4       RV R24       \8        P:                  ! 4       V,           p	\        4       P=                  W@W9R7      '       gc   \        4       P5                  RV R\7        V4       R24       \        4       P>                  PA                  RV\7        V4      \C        4       4       R# \)        R4       R#   \          d    R	p EL€i ; i)zvRewrite the installed plist when the generated one differs, then bootout/bootstrap so launchd
re-reads it immediately.F©Údefinition_belongs_to_homeÚrewriteúlaunchd plistrc   rd   r!   ©Úget_running_pidNÚsetsid)r5   r   r  rQ   r   u�   â†» Updated gateway launchd service definition; reload deferred to a transient launchd job (survives the bootout of this process)Tr   rO   r"   r#   zold gateway pid r#  u   s drain wait â€” bootstrapping z anyway)r†   zFAILED launchd reload of u/    â€” service NOT registered after retrying for zs (in-process fallback path)uS   launchd reload of %s failed â€” service not registered after %ds of retries; see %suR   â†» Updated gateway launchd service definition to match the current Hermes install)"r   r  r©   r  Ú hermes_cli.gateway_service_ownerr5  rX   r  r   Úrefuse_temp_home_service_writeÚ_prepare_service_launcherrœ   r   r<   Úgateway.statusr9  r  Úhasattrr(   r1  r    r*   r.   r/   rz   Ú_wait_for_pid_exitrt   rF   rŠ   r‹   r�   r&  ÚerrorrY   )
rQ   r5  Ú	new_plistr   r5   r  r9  r   r)  Ú	_deadlines
             r   Úrefresh_launchd_plist_if_neededrD  "  sK  € ô “×-Ñ-Ó/€JØ×Ñ×Ò¤#£%×"@Ñ"@×"BÒ"BÙåKÙ% j´#³%×2GÑ2GÓ2IÈ9×UÒUÙä“×,Ñ,Ó.€IÜ×;Ò;¸IÀ×WÒWÙäƒE×#Ñ#Ô%Ø×Ñ˜)¨gÐÔ6Ü‹E×#Ñ#Ó%€EÜ‹U×"Ñ"Ó$€FØˆx�q˜˜Ð €FðÝ2Ù%Ó'ˆð 	ÒÜ”B˜×!Ò!Ü
(Ø¨6ÐVa÷ó ô 	ðMô	
ñ ô
 ‡N‚N�K ¨FÐ3Ñd¸5ÐdÈ"ÐdÔPSÓPU×PcÑPcÒdÜ+Ó-€NàÒ¤s£u×'?Ñ'?À×'\Ò'\Ü‹×(Ñ(Ø˜{˜mÐ+>Ü�>Ó"Ð#Ð#BÀ6À(È'ðSô	
ô —’Ó  >Õ1€IÜ‹5×<Ñ<¸VÐQVÐ<×kÒkÜ‹×(Ñ(Ø'¨ xð 0Ü Ó/Ð0Ð0LðNô	
ô 	‹�‰×ÑØaØ”C˜Ó'Ô)AÓ)Cô	
ñ Ü	Ð
^Ô_ÙøôQ ô Ø‹ðús   ÄJ ÊJ%Ê$J%Ú	start_nowÚforce_unit_pathc               ó$   € V ^8„  d   QhRRRRRR/# )r   Úforcer@   rE  rF  r   )r   s   "r   r   r   g  s'   € ÷ B?ñ B?˜4ð B?°tð B?ÐUYñ B?r   c               óª  € \        4       P                  4       p\        4       P                  4       p^ RIHp V'       g=   V! V\        4       P                  4       R4      '       g   \        P                  ! ^4       T;'       g    \        4       P                  V4      pVP                  4       '       d§   V '       gŸ   V'       g—   \        4       P                  4       '       d   \        RV 24       \        R4       R# V'       dV   \        RV 24       \        4       P                  4       '       d   \        R4       R# ^ RIHp \        R	V! 4        R
24       R# VP                  P!                  RRR7       \        4       P#                  4       p\$        P&                  ! VR4      '       d   R# \        RV 24       \        4       P)                  4        VP+                  VRR7       V'       gŽ   \,        P.                  ! RR\        4       P1                  4        RV 2.3RRR^Z/\        4       P2                  B  \        4        \        R4       \        4        \        R4       \        R4       \        R4       R#  \        4       P5                  \        4       P1                  4       W4^R7       \        4        \        R4       \        4       P;                  4        \        4        \        R4       \        R4       ^ RIHp
 \        RT
! 4        R24       R#   \,        P6                   d&   p	\        4       P9                  T	R4        Rp	?	R# Rp	?	ii ; i) r	   r4  Ú	overwritezService already installed at: zUse --force to reinstallNu+   â†» Repairing outdated launchd service at: u   âœ“ Service definition updatedrï   ui   âš  Service definition could not be reloaded with launchd. Run 'hermes gateway install --force' or check z%/logs/launchd-reload.log for details.Tr^   r7  zInstalling launchd service to: rc   rd   r   rO   r!   r"   Fr#   uI   âœ“ Service installed, not started (launchd starts it at your next login)zNext steps:z2  hermes gateway start              # Start it nowz2  hermes gateway status             # Check statusrˆ   zlaunchctl bootstrapu!   âœ“ Service installed and loaded!z
  tail -f z/logs/gateway.log  # View logs)r   r  r   r;  r5  rX   rò   ró   r„   r©   r  r    rD  rµ   rð   rh   ri   r  r   r<  r=  rœ   r*   r.   r<   r/   rR   r+   rù   r¥   )rH  rE  rF  rQ   r   r5  Úloadrð   rB  r0  rô   s   &$$        r   Úlaunchd_installrL  g  sœ  € Ü“×-Ñ-Ó/€JÜ‹E×#Ñ#Ó%€EåKßÑ#=¸jÌ#Ë%×J_ÑJ_ÓJaÐcn×#oÒ#oÜ�Š�Œð ×IÐIœ›×BÑBÀ5ÓI€Dà×Ñ×Ò§E¯_Ü‹5×)Ñ)×+Ò+ÜÐ2°:°,Ð?Ô@ÜÐ,Ô-ÙßÜÐ?À
¸|ÐLÔMÜ‹u×4Ñ4×6Ò6ÜÐ6Ô7ñ õ AÜðEá*Ó,Ð-Ð-RðTôñ
 à×Ñ×Ñ D°4ÐÔ8Ü“×,Ñ,Ó.€IÜ×;Ò;¸IÀ×WÒWÙÜ	Ð+¨J¨<Ð
8Ô9ÜƒE×#Ñ#Ô%Ø×Ñ˜)¨gÐÔ6çô 	�ŠØ˜)¬«×(=Ñ(=Ó(?Ð'@ÀÀ%ÀÐ%IÐJñ	<àð	<à!#ð	<ä'*£u×':Ñ':ò	<ô 	ŒÜÐYÔZÜŒÜˆmÔÜÐBÔCÜÐBÔCÙðÜ‹×"Ñ"¤3£5×#8Ñ#8Ó#:¸JÐWYÐ"ÔZô
 
„GÜ	Ð
-Ô.ÜƒE×+Ñ+Ô-Ü	„GÜ	ˆ-ÔÜ	Ð
>Ô?Ý<Ü	ˆJ‘t“v�hÐ<Ð
=Ö>øô ×(Ñ(ô Ü‹×'Ñ'¨Ð+@ÔAÝûðús   É=2L ÌMÌ-MÍMc                 ój  € \         P                  ! R 4       \        4       P                  4       p \        P
                  ! RR\        4        R\        4        2.3RRR^Z/\        4       P                  B  V P                  4       '       d   V P                  4        \        RV  24       \        R4       R	# )
Ú	uninstallr   rO   r!   r"   Fr#   u   âœ“ Removed u   âœ“ Service uninstalledN)r   Úrefuse_foreign_launchd_plistr   r  r*   r.   r<   r   r/   r©   r¤   r    )rQ   s    r   Úlaunchd_uninstallrP  ¬  sŸ   € Ü×6Ò6°{ÔCÜ“×-Ñ-Ó/€Jä‡N‚NØ	�i¤OÓ$5Ð#6°aÔ8IÓ8KÐ7LÐ!MÐNñ8àð8àð8ä#&£5×#6Ñ#6ò8ð ×Ñ×ÒØ×ÑÔÜ�˜Z˜LÐ)Ô*Ü	Ð
#Ö$r   c                 ó@  € \         P                  ! R 4       \        4       P                  4       p \        4       P	                  4       pV P                  4       '       g½   \        4       P                  4       p\         P                  ! VR4      '       d   \        P                  ! ^4       \        R4       V P                  P                  RRR7       \        4       P                  4        V P                  VRR7       \        W4      '       d   \!        R4       R# \        4       P#                  4         \%        V4       \!        R4       R#   \&        P(                   d?   p\+        T4      '       g   h \        R	4       \        Y4      '       g    Rp?R#  Rp?L[Rp?ii ; i)
Ústartr7  u:   â†» launchd plist missing; regenerating service definitionTr^   rc   rd   u   âœ“ Service startedNu:   â†» launchd job was unloaded; reloading service definition)r   rO  r   r  r   r©   r  r<  rò   ró   r    rh   ri   r=  rœ   Ú _launchd_bootstrap_and_kickstartÚ_launchd_okrD  Ú_launchctl_kickstart_currentr*   r+   rD   )rQ   r   rB  r0  s       r   Úlaunchd_startrV  ¹  s2  € Ü×6Ò6°wÔ?Ü“×-Ñ-Ó/€JÜ‹E×#Ñ#Ó%€Eð ×Ñ×ÒÜ“E×0Ñ0Ó2ˆ	Ü ×?Ò?À	È?×[Ò[Ü�HŠH�QŒKÜÐJÔKØ×Ñ×Ñ¨°tÐÔ<Ü‹×'Ñ'Ô)Ø×Ñ˜i°'ÐÔ:Ü+¨J×>Ò>ÜÐ-Ô.ÙäƒE×)Ñ)Ô+ðÜ$ UÔ+ô Ð%Ö&øô ×(Ñ(ô Ü0°×3Ò3ØäÐJÔKÜ/°
×BÒBÝô Cûðús   Ä2E
 Å
FÅ.FÆFc               ó    € V ^8„  d   QhRRRR/# )r   r   r   r   rK   r   )r   s   "r   r   r   Ø  s   € ÷ gñ g¨ð g°ñ gr   c                óX   € \         P                  ! R R\        4        RV  2.R^R7       R# )r   Ú	kickstartr!   TrN   N)r*   r.   r<   rƒ   s   &r   rU  rU  Ø  s*   € Ü‡N‚N�K ´Ó1BÐ0CÀ1ÀUÀGÐ.LÐMÐUYÐce×fr   c               ó$   € V ^8„  d   QhRRRRRR/# )r   rQ   r   r   r   r   r@   r   )r   s   "r   r   r   Ü  s!   € ÷ ñ °ð ¸cð Àdñ r   c                óü   €  \        4       P                  \        4       P                  4       W^R7       \        V4       R#   \        P
                   d&   p\        4       P                  TR4        Rp?R# Rp?ii ; i)ziBootstrap then kickstart; False after degrading to detached (domain unsupported). Other errors propagate.rˆ   r   NFT)r   rR   r<   rU  r*   r+   rù   )rQ   r   r0  s   && r   rS  rS  Ü  sd   € ðÜ‹×"Ñ"¤3£5×#8Ñ#8Ó#:¸JÐWYÐ"ÔZÜ$ UÔ+ñ øô ×(Ñ(ô Ü‹×'Ñ'¨¨;Ô7Ýûðús   ‚=A ÁA;ÁA6Á6A;c               ó    € V ^8„  d   QhRRRR/# r[   r   )r   s   "r   r   r   ç  s   € ÷ .ñ .˜ð . ñ .r   c                óL   € \        V 4       \        4       P                  4        R# )zaPrint a launchd success line and clear the unsupported marker (an OS fix recovers automatically).N)r    r   r¥   )r\   s   &r   rT  rT  ç  s   € ä	ˆ'„NÜƒE×+Ñ+Ö-r   c                 óÜ  € \         P                  ! R 4       \        4        R\        4        2p \	        4       P                  4         \        P                  ! RRV .3RRR^Z/\	        4       P                  B  \	        4       P                  RR	R
7       \        R4       R#   \        P                   d8   p\        T4      '       g   \        TP                  4      '       g   h  Rp?LoRp?ii ; i)Ústopr!   r   rO   r"   Tr#   Nç      $@g      @)r#   Úforce_afteru   âœ“ Service stopped)r   rO  r<   r   r   Ú_mark_planned_stopr*   r.   r/   r+   rD   rI   rB   Ú_wait_for_gateway_exitr    )r  r0  s     r   Úlaunchd_stoprd  í  sÅ   € Ü×6Ò6°vÔ>ÜÓ!Ð" !Ô$5Ó$7Ð#8Ð9€FÜƒE×ÑÔð	ô 	�Š˜ Y°Ð7Ñg¸tÐgÈRÐgÔSVÓSX×SfÑSfÒgô ƒE× Ñ ¨¸3Ð Ô?Ü	Ð
Ö øô ×(Ñ(ô ô 2°!×4Ò4Ô8UÐVW×VbÑVb×8cÒ8cØÿøðús   Á0B ÂC+Â4-C&Ã&C+c               ó$   € V ^8„  d   QhRRRRRR/# )r   r   r   r5   r   rK   r   )r   s   "r   r   r      s&   € ÷ yñ y˜cð y¨3ð y°4ñ yr   c                ór   € \         P                  ! RRRV RV  2.3RRR^Z/\        4       P                  B  R# )	z\``launchctl kickstart -k domain/label``; raises so callers own per-label failure accounting.r   rY  ú-kr!   r"   Tr#   N)r*   r.   r   r/   )r   r5   s   &&r   Ú_launchd_kickstartrh     s=   € ä‡N‚N�K ¨d°v°h¸aÀ¸wÐ4GÐHÑxÐPTÐxÐ^`ÐxÔdgÓdi×dwÑdwÔxr   c          
     ó,   € V ^8„  d   QhRRRRRRRRRR	/# )
r   r   r   Úold_pidr|   r#   rv   r5   r   r@   r   )r   s   "r   r   r     s4   € ÷ ñ ØðØ#ðØ.3ðØGJðà	ñr   c               ó  € \         P                  ! 4       \        VR4      ,           p \        4       P	                  W04      w  rVVe   V^ 8”  d	   Wa8w  d   R# \         P                  ! 4       V8¼  d   R# \         P
                  ! R4       Kc  )uÃ   Poll ``domain/label`` (0.5s) until it runs on a fresh PID or ``timeout`` passes â€” KeepAlive respawn
isn't instantaneous. launchctl ``TimeoutExpired`` propagates; callers own failure accounting.ç      à?TF)rŠ   r‹   rx   r   Ú_launchd_print_service_pidrŒ   )r   rj  r#   r5   r†   Ú_loadedÚpids   &&&$   r   Ú_wait_for_launchd_service_pidrp    sb   € ô
 �~Š~Ó¤# g¨sÓ"3Õ3€HØ
Ü“u×7Ñ7¸ÓF‰ˆØŠ?˜s Qœw¨3¬>ÙÜ�>Š>Ó˜xÔ'ÙÜ�
Š
�3Žr   c                 óP  € \         P                  ! R 4       \        4       P                  4       p \        4       P	                  4       pV RV  2p\        4       P                  4       p^ RIHp  V! 4       pVe-   \        4       P                  V4      '       d   \        R4       R# Ve[   \        4       P                  V4      \        4       P                  8X  d+   \        RV R24       \        4       P                  V4       RpVe¥   \        4       P                  4       p\        RV RVR	 R
24       ^ RIHp \        4       P#                  WVV! VR7      R7      '       d<   \        4       P%                  WRVR7      '       d   \        R4       R# \        R4       M\        RVR	 R24       V'       gÓ   \        4       P'                  4       P)                  4       '       d§   \        4       P+                  4       '       g‰   \        R4       \-        \        4       P'                  4       4      p\.        P0                  ! RR\        4       P	                  4       V.R^R7       \.        P0                  ! RRV.R^R7       \        R4       R# \        4       P3                  4        \.        P0                  ! RRRV.3RRR^Z/\        4       P4                  B  \        R4       R#   \.        P6                   Ed6   p	\9        T	4      '       g!   \        4       P;                  T	R4        Rp	?	R# \        R4        \.        P0                  ! RRT.3RR R^Z/\        4       P4                  B  \-        \        4       P'                  4       4      p\.        P0                  ! RR\        4       P	                  4       T.R^R7       \.        P0                  ! RRT.R^R7       MA  \.        P6                   d*   p
\        4       P;                  T
R4        Rp
?
 Rp	?	R# Rp
?
ii ; i\        R4        Rp	?	R# Rp	?	ii ; i)!Úrestartr!   r8  Nu   âœ“ Service restart requestedu   âš  Gateway PID uL    event loop is unresponsive â€” skipping drain and forcing a bounded stop...u   â†’ Stopping gateway (PID u%   ) â€” draining in-flight runs (up to z.0fzs)...)Údrain_progress_reporter)Úbudget_s)Úon_progressg      .@)r#   r5   uR   âš  launchd did not revive the gateway after its graceful exit â€” forcing restartu"   âš  Gateway drain timed out after u   s â€” forcing launchd restartuE   â†» launchd job was not re-registered by the plist refresh; reloadingr   rM   TrN   rY  u   âœ“ Service restartedrg  r"   r#   zlaunchctl kickstartu'   â†» launchd job was unloaded; reloadingrO   F)r   rO  r   r   r<   rD  r>  r9  Ú_request_gateway_self_restartrT  Úprobe_gateway_loop_livenessÚGATEWAY_LOOP_WEDGEDr    Ú_escalate_wedged_gatewayÚ_get_restart_exit_wait_budgetÚ"hermes_cli.update_cmd_drain_reportrs  Ú_graceful_restart_via_sigusr1rp  r  r©   r  r   r*   r.   Ú_wait_for_api_server_port_freer/   r+   rD   rù   )r   r5   r  Ú
refresh_okr9  ro  Úwait_budgetrs  rQ   r0  Úe2s              r   Úlaunchd_restartr�    sP  € Ü×6Ò6°yÔAÜ‹E×#Ñ#Ó%€EÜ‹U×"Ñ"Ó$€FØˆx�q˜˜Ð €Fô “×6Ñ6Ó8€JÝ.ð>-ÙÓˆØŠ?œs›u×BÑBÀ3×GÒGÜÐ7Ô8ÙØŠ?œs›u×@Ñ@ÀÓEÌË×IbÑIbÔbô Ð$ S EÐ)yÐyÔzÜ‹E×*Ñ*¨3Ô/ØˆCØŠ?ô ›%×=Ñ=Ó?ˆKÜÐ.¨s¨eÐ3XÐYdÐehÐXiÐinÐoÔpÝRÜ‹u×2Ñ2°3ÑQhÐr}ÔQ~Ð2×Òô “5×6Ñ6°uÈ4ÐX^Ð6×_Ò_ÜÐ ?Ô@ÙÜÐjÕkäÐ:¸;ÀsÐ:KÐKhÐiÔjßœc›e×:Ñ:Ó<×CÑC×EÒEÌcËe×NlÑNl×NnÒNnô ÐYÔZÜœS›U×9Ñ9Ó;Ó<ˆJÜ�NŠN˜K¨´c³e×6KÑ6KÓ6MÈzÐZÐbfÐprÕsÜ�NŠN˜K¨°fÐ=ÀTÐSUÕVÜÐ/Ô0Ùô 	‹×,Ñ,Ô.Ü�Š˜ [°$¸Ð?ÑoÀtÐoÐUWÐoÔ[^Ó[`×[nÑ[nÒoÜÐ+Ö,øÜ×(Ñ(õ -Ü0°×3Ò3Ü‹E×+Ñ+¨AÐ/DÔEÝäÐ7Ô8ð
	ô �NŠN˜K¨°FÐ;ÑlÀ5ÐlÐRTÐlÔX[ÓX]×XkÑXkÒlÜœS›U×9Ñ9Ó;Ó<ˆJÜ�NŠN˜K¨´c³e×6KÑ6KÓ6MÈzÐZÐbfÐprÕsÜ�NŠN˜K¨°fÐ=ÀTÐSUÖVøÜ×,Ñ,ô 	Ü‹E×+Ñ+¨B°Ô<ß‰Fûð	úô 	Ð+×,Ò,ûð#-úsd   Á-5K Â$C(K Æ#K Æ2CK ÊAK ËP%Ë0+P Ì!P Ì-B OÏP ÏPÏ#PÏ=P ÐPÐP Ð P%g      4@r   Úpoll_intervalrl  rj  c          
     ó,   € V ^8„  d   QhRRRRRRRRRR	/# )
r   r#   rv   r   z
str | Noner‚  rj  r|   r   r@   r   )r   s   "r   r   r   i  s<   € ÷ #-ñ #-àð#-ð ð#-ð ð	#-ð
 ð#-ð 
ñ#-r   c                óš  € \        4       P                  4       '       d   R# T;'       g    \        4       P                  4       p\        P                  ! 4       \        V R4      ,           p \        4       P                  V4      pVe	   WS8w  d   R# \        P                  ! 4       V8¼  d   R# \        P                  ! \        VR4      4       Kd  )u  Poll launchd until it supervises a live gateway; True at once if the detached fallback is active.
``launchd_restart`` returns once the restart is *requested* (asynchronous), so it can't see a helper
dying before bootstrap or a ``launchctl bootstrap`` that exits 0 without registering.

The ``_request_gateway_self_restart`` branch hands the work to the running gateway and returns
immediately, and a plist reload is handed to a detached helper. Both are asynchronous, so a caller that
reads "returned without raising" as "the service is up" cannot see a helper that dies before its first
bootstrap (#88848) â€” nor a ``launchctl bootstrap`` that exits 0 without registering, which the reporter
measured on macOS 26.6.1.
Judge the outcome the way #80491 taught the helper to judge it: by a live supervised pid, never by an
exit code.  :func:`_launchctl_supervised_pid` is already that probe, so this only adds the wait.

``old_pid`` is the pid launchd ran for the label *before* the restart: a restart that leaves the same
process running is not a restart, so passing it holds the invoking profile to the same fresh-pid
contract :func:`_wait_for_launchd_service_pid` enforces for sibling labels. With ``old_pid=None``
(no pre-restart pid was observable) any supervised pid counts, as before.
Tg        Fg{®Gáz„?)r   rª   r   rŠ   r‹   rx   r€   rŒ   )r#   r   r‚  rj  r†   ro  s   $$$$  r   Ú$wait_for_launchd_gateway_supervisionr…  i  sŽ   € ô0 ƒu×/Ñ/×1Ò1Ùà×.Ð.”S“U×,Ñ,Ó.€EÜ�~Š~Ó¤# g¨sÓ"3Õ3€HØ
Ü‹e×-Ñ-¨eÓ4ˆØŠ?˜sœ~ÙÜ�>Š>Ó˜xÔ'ÙÜ�
Š
”3�} dÓ+Ö,r   c               ó   € V ^8„  d   QhRR/# )r   Údeepr@   r   )r   s   "r   r   r   �  s   € ÷ >Tñ >T˜ñ >Tr   c                ó”  € \        4       P                  4       p\        4       P                  4       p \        P                  ! R RV.3R^
/\        4       P
                  BRR/B pVP                  ^ 8H  pVP                  pV'       d   \        4       P                  V4      MRp^ RI
Hp V! RR7      pVe	   W†8X  d   Rp\        4       P                  4       p	\        R	V 24       \        4       P                  4       '       d   \        R
4       M\        R4       \        R4       V'       g:   \        R4       \        R4       \        R4       V'       d   \        RV R24       MÂVe/   \        RV R24       \        R4       V	'       d   \        R4       M�V	'       d\   \        R4       \        R4       V'       d   \        RV R24       \        R4       M\        R4       \        R4       \        R4       M-\        R4       \        V4       V'       d   \        RV R24       V '       d{   \        4       P                  4       R,          R,          p
V
P!                  4       '       d=   \        4        \        R4       \        P                  ! RR \#        V
4      .^
RR!7       R# R# R#   \        P                   d	    RpRp ELGi ; i)"r   r~   r#   r"   Fr'   Nr8  )Úcleanup_stalezLaunchd plist: u9   âœ“ Service definition matches the current Hermes installuF   âš  Service definition is stale relative to the current Hermes installz  Run: hermes gateway startu!   âœ— Gateway service is not loadedzB  Service definition exists locally but launchd has not loaded it.z3  Note: a detached gateway process is running (PID Ú)u*   âœ“ Gateway is supervised by launchd (PID z>  Auto-start at login and auto-restart on crash are available.z@  (launchd domain was previously unavailable but is now working)uC   âš  Gateway service is registered but launchd is not supervising itz:  launchd cannot manage the gateway on this macOS version.u.   âœ“ Detached fallback process is running (PID z5  Cron jobs will fire. Stop with: hermes gateway stopu"   âœ— No fallback process is runninguF     âš  Auto-start at login and auto-restart on crash are NOT available.u.   âœ“ Gateway service is registered with launchdz+  Detached gateway process is running (PID rV   rÝ   zRecent logs:Útailz-20)r#   r"   )r   r  r   r*   r.   r/   rB   r0   r,   r   r>  r9  rª   r    r  rX   r©   r   )r‡  rQ   r   r6   Úservice_listedÚlist_outputÚlaunchd_pidr9  Úfallback_pidÚlaunchd_unsupportedÚlog_files   &          r   Úlaunchd_statusr’  �  sK  € Ü“×-Ñ-Ó/€JÜ‹E×#Ñ#Ó%€EðÜ—’ ¨f°eÐ <ÑmÀbÐmÌCËE×L_ÑL_ÑmÐglÒmˆØ×*Ñ*¨aÑ/ˆØ—m‘mˆ÷ M[”#“%×;Ñ;¸KÔHÐ`d€Kõ /Ù"°Ô7€LØÒ <Ô#>Øˆô ›%×BÑBÓDÐä	ˆO˜J˜<Ð
(Ô)Ü
ƒu×%Ñ%×'Ò'ÜÐIÕJäÐVÔWÜÐ+Ô,çÜÐ1Ô2ÜÐRÔSÜÐ+Ô,ßÜÐGÈÀ~ÐUVÐWÔXøØ	Ò	 ÜÐ:¸;¸-ÀqÐIÔJÜÐNÔOßÜÐTÔUøß	ÜÐSÔTÜÐJÔKßÜÐBÀ<À.ÐPQÐRÔSÜÐIÕJäÐ6Ô7ÜÐ/Ô0ÜÐVÕWäÐ>Ô?ÜˆkÔßÜÐ?À¸~ÈQÐOÔPçÜ“5×(Ñ(Ó*¨VÕ3°mÕCˆØ�?‰?×ÒÜŒGÜ�.Ô!Ü�NŠN˜F E¬3¨x«=Ð9À2ÈU×Sñ ñ øôe ×$Ñ$ô ØˆØ‹ðús   ²AJ* Ê*KËK>   é   éq   é}   )F)r`  )>Ú__doc__Ú
__future__r   Úpathlibr   rš   r�   r(   r¶   r*   rò   rŠ   Úxml.sax.saxutilsr   ra   r   r   r   r   r   r7   r<   Ú	frozensetrC   rH   rD   rI   rP   rR   rY   rt   rz   r€   r„   r�   r’   r    r¥   rª   r½   rÊ   rÕ   rë   rõ   rù   r  r  r1  rD  rL  rP  rV  rU  rS  rT  rd  rh  rp  r�  Ú"LAUNCHD_SUPERVISION_VERIFY_TIMEOUTr…  r’  r   r   r   Ú<module>rœ     s”  ðñõ #å Û Û Û 	Û Û Û 
Û Ý #Ý å ,òõ
Lõõ4	'ñ $-ª]Ó#;Ð  ñ '0°°C°Ó&9Ð #õ>õ
=ð Ð ð?ÐPR÷ ?õ&Cõ

õ9õDõ>õ
õ2Dõ]õCõ7õ	;õHð>YÐX]÷ Yõ<ð>È$÷ õ&Cõ.jõZCõAõHBñJB?¸dð B?Ð\a÷ B?ð B?òJ
%ò'õ>gõõ.ò!õ&y÷
òN-ðd &*Ð "ð#-à7ð#-ð ð#-ð ð	#-ð
 ÷#-÷L>Tñ >Tr   