+
    jHàjm‡  ã                  ó   € R t ^ RIH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 ^ RIHtHt ^ RIHtHtHtHtHtHtHtHtHtHt ^ RIHt R R	 ltR
 R ltRER R llt R R lt!Rt"R R lt#R R lt$R R lt%R R lt&RFR R llt'R R lt(R R lt)RGR  R! llt*R" R# lt+R$t,R%R&RR'/t-R( R) lt.R* R+ lt/R, R- lt0RHR. R/ llt1R0 R1 lt2]! R24      R3 R4 l4       t3R5 R6 lt4]! 4       R7 R8 l4       t5]! 4       R9 R: l4       t6RIt7]! 4       R; R< l4       t8R= R> lt9]! 4       R? R@ l4       t:]! 4       RA RB l4       t;]! 4       RC RD l4       t<R# )Ja  Host-platform checks for hermes doctor: interpreter, SQLite, certificates, macOS TCC, gateway supervision, command install.
Split out of ``hermes_cli/doctor.py``, which re-exports every name so ``hermes_cli.doctor.<name>`` keeps resolving (and monkeypatching).)ÚannotationsN)ÚPath)ÚColorsÚcolor)Úis_nix_install_methodÚ%recommended_update_command_for_method)
ÚFindingÚ_fail_and_issueÚ_sectionÚ
check_boolÚ
check_failÚ
check_infoÚcheck_okÚ
check_warnÚdoctor_checkÚwarn_on_error)Ú	is_termuxc               ó   € V ^8„  d   QhRR/# )é   ÚreturnÚstr© )Úformats   "Ú?/home/ubuntu/.hermes/hermes-agent/hermes_cli/doctor_platform.pyÚ__annotate__r      s   € ÷ 
9ñ 
9˜Sñ 
9ó    c                 óÂ   € ^ RI Hp  ^ RIHp V ! V4      p\	        V4      '       d   \        V4      # VR	9   d(   \        V4      pRV R2VR8X  d	   R,           # R,           # R# )
é    ©Údetect_install_method©ÚPROJECT_ROOTÚdockerzRun `Ú`z$, then recreate the Hermes containerÚ z+Run `hermes pm repair`, then restart Hermes©r"   Úapt)Úhermes_cli.configr   Úhermes_cli.doctorr!   r   r   )r   r!   ÚmethodÚcommands       r   Ú_python_repair_hintr+      sd   € Ý7Ý.á" <Ó0€FÜ˜V×$Ò$Ü4°VÓ<Ð<ØÐ"Ô"Ü7¸Ó?ˆØ�w�i˜qÐ!ÈvÐYaÔOaÐ%KÕjÐjÐgiÕjÐjÙ8r   c               ó    € V ^8„  d   QhRRRR/# )r   Úpkgr   r   r   )r   s   "r   r   r   "   s   € ÷ lñ l Sð l¨Sñ lr   c                ób   € \        4       '       d   R M\        P                  R8X  d   RMR RV  2# )r-   ÚdarwinÚbrewzsudo aptz	 install )Ú
_is_termuxÚsysÚplatform)r-   s   &r   Ú_system_package_install_cmdr4   "   s-   € Ü!—|’|‰e´3·<±<À8Ô3K©ÐQ[Ð\Ð\eÐfiÐejÐkÐkr   c               ó    € V ^8„  d   QhRRRR/# )r   Úinstall_methodú
str | Noner   r   r   )r   s   "r   r   r   &   s   € ÷ tñ t¨ð t¸sñ tr   c                óÂ   € ^ RI Hp ^ RIHp T ;'       g	    V! V4      p\	        V4      p\        V4      '       d   TMRRV R2RRV R2/P                  VR4      pR	V R
2# )zAReturn an actionable SQLite upgrade hint for this install layout.r    r   r"   zrun `z&`, then recreate all Hermes containersr&   r#   zrun `hermes update`Ú(u\   ; fixed versions: 3.51.3+ / 3.50.7 / 3.44.6 â€” see https://sqlite.org/wal.html#walresetbug))r(   r!   r'   r   r   r   Úget)r6   r!   r   r)   ÚcmdÚactions   &     r   Ú_sqlite_upgrade_hintr=   &   s   € å.Ý7Ø×BÐBÑ4°\ÓB€FÜ
/°Ó
7€CÜ)¨&×1Ò1‰SØ�E˜#˜ÐDÐEÀuÐPUÐVYÐUZÐZ[Ènð8^ß^aÑ^aÐbhÐjó  _Að àˆvˆhÐrÐsÐsr   c               ó    € V ^8„  d   QhRRRR/# )r   Úhermes_homer   r   zlist[tuple[str, Path]]r   )r   s   "r   r   r   1   s   € ÷ ñ ¨ð Ð1Gñ r   c                ó2  € ^ RI Hp V Uu. uF%  q"P                  R4      '       g   K  W V,          3NK'  	  pp\        V R,          R,          P	                  R4      4       F.  pVP                  \        VP                  V 4      4      V34       K0  	  V# u upi )zy(display name, path) pairs for Hermes-managed SQLite databases: backup.py's per-profile store list + per-board kanban.db.)Ú_QUICK_STATE_FILESz.dbÚkanbanÚboardsz*/kanban.db)Úhermes_cli.backuprA   ÚendswithÚsortedÚglobÚappendr   Úrelative_to)r?   rA   ÚnameÚentriesÚboard_dbs   &    r   Ú_hermes_database_pathsrM   1   s�   € å4Ù6HÓaÑ6H¨dÏMÉMÐZ_×L`Ô)� DÕ(Ó)Ñ6H€GÐaÜ˜K¨(Õ2°XÕ=×CÑCÀMÓRÖSˆØ�‰œ˜H×0Ñ0°Ó=Ó>ÀÐIÖJñ Tà€Nùò bs
   ‹B¨Bs   SQLite format 3 c               ó    € V ^8„  d   QhRRRR/# ©r   Údb_pathr   r   r   r   )r   s   "r   r   r   =   s   € ÷ 
hñ 
h ð 
h¨ñ 
hr   c                óÎ   €  V P                  4        \        P                  ! T \        P
                  4      '       d   R# RT  2#   \         d   p\        T4      u Rp?# Rp?ii ; i)u  Explain why a database file could not be read, without opening it.

``read_header_bytes_preopen`` collapses every ``OSError`` into ``None``, but doctor must say *which*
problem it hit. ``stat()``/``access()`` answer from directory metadata alone â€” no descriptor, no lock loss.
Nzfile could not be readzpermission denied: )ÚstatÚOSErrorr   ÚosÚaccessÚR_OK)rP   Úexcs   & r   Ú_unreadable_reasonrX   =   sW   € ðØ�‰Œô (*§y¢y°¼"¿'¹'×'BÒ'BÐ#ÐgÐJ]Ð^eÐ]fÐHgÐgøô ô Ü�3‹x�ûðús   ‚A ÁA$Á
AÁA$ÁA$c               ó    € V ^8„  d   QhRRRR/# )r   rP   r   r   ztuple[str | None, str | None]r   )r   s   "r   r   r   J   s   € ÷ ^ñ ^ ð ^Ð)Fñ ^r   c                óT  € ^ RI HpHp V! V ^R7      pVf   RV! V 4      '       d   R3# \        V 4      3# \	        V4      ^ 8X  d   R# \	        V4      ^8  g   VP                  \        4      '       g   R	# ^R^R/P                  V^,          4      pV'       d   VR3# RRV^,           23# )
uþ  Return (journal mode, error) from header byte 18 (2=WAL, 1=rollback) without opening the database.

Opening through SQLite â€” even read-only â€” creates -wal/-shm sidecars, which a diagnostic must not do.
``read_header_bytes_preopen`` rather than a bare ``open()``: closing *any* descriptor cancels this
process's POSIX advisory locks (see ``hermes_cli.sqlite_safe_read``), and the dashboard console runs
``run_doctor`` in-process with live ``SessionDB`` connections â€” the helper refuses then (unreadable).
)Úhas_live_connectionÚread_header_bytes_preopen)ÚlengthNz database is open in this processÚwalÚrollbackz!unrecognized file-format version )Nzfile is empty)Nzfile is not a database)Úhermes_cli.sqlite_safe_readr[   r\   rX   ÚlenÚ
startswithÚ_SQLITE_HEADER_MAGICr:   )rP   r[   r\   ÚheaderÚmodes   &    r   Ú_read_journal_moderf   J   s¶   € ÷ [Ù& w°rÔ:€FØ‚~ØÑ;NÈw×;WÒ;WÐ7ÐxÐxÔ]oÐpwÓ]xÐxÐxÜ
ˆ6ƒ{�aÔØ$Ð$Ü
ˆ6ƒ{�RÔ˜v×0Ñ0Ô1E×FÒFØ-Ð-Øˆu�a˜Ð$×(Ñ(¨°­Ó4€DßˆD�$ˆ<Ð] dÐ.OÐPVÐWYÕPZÈ|Ð,\Ð%]Ð]r   c               ó    € V ^8„  d   QhRRRR/# rO   r   )r   s   "r   r   r   ^   s   € ÷ ñ ˜Tð  cñ r   c                ót   € ^ RI Hp  V! V P                  4       P                  4      #   \         d     R# i ; i)r   )Úformat_byteszsize unknown)Úhermes_cli.sizefmtri   rR   Úst_sizerS   )rP   Ú_format_sizes   & r   Ú_format_db_sizerm   ^   s3   € Ý?ðÙ˜GŸL™L›N×2Ñ2Ó3Ð3øÜô Úðús   ˆ( ¨7¶7c               ó$   € V ^8„  d   QhRRRRRR/# )r   rJ   r   rP   r   r   ÚNoner   )r   s   "r   r   r   f   s&   € ÷ fñ f 3ð f°ð f¸$ñ fr   c                ó¶  € ^ RI HpHp . p/ pV! V4       F�  w  rgV^ 8:  g   VP                  R4      '       d   VP	                  V4       K6  VP                  V\        4       4      P                  \        VP                  R4      4      P                  4       Kƒ  	  \        V4       F:  p\        V  RV! V4       RRP                  \        WV,          4      4       24       K<  	  V'       dW   \        V  R2RV^ ,          R	,           2\        V4      ^8”  d   R
\        V4      ^,
           R2MR,           R,           4       R# V'       g   \        V  R24       R# R# )a7  Name the processes holding ``db_path`` (or a WAL sidecar) so the operator knows what to stop before the
offline journal-mode conversion; a partial or unavailable scan is reported as "cannot prove quiet", never as
an all-clear (the scan is the same fail-closed authority repair/VACUUM/checkpoint admission uses).)Údescribe_holder_pidÚforeign_state_db_holdersÚuninspectablez
 (deleted)z is held by ú: ú, z$: cannot prove the database is quietz(holder scan incomplete: :Néx   Nz; +z morer$   Ú)uH   : no other process holds it right now â€” the offline conversion can runN)Úhermes_state_holdersrq   rr   rb   rH   Ú
setdefaultÚsetÚaddr   ÚremovesuffixrJ   rF   r   Újoinr   ra   )rJ   rP   rq   rr   ÚunknownÚby_pidÚpidÚtargets   &&      r   Ú_report_database_holdersr‚   f   s7  € ÷ SØ€GØ"$€FÙ/°Ö8‰ˆØ�!Œ8�v×(Ñ(¨×9Ò9Ø�N‰N˜6Ö"à×Ñ˜c¤3£5Ó)×-Ñ-¬d°6×3FÑ3FÀ|Ó3TÓ.U×.ZÑ.ZÖ[ñ	 9ô
 �fŽ~ˆÜ�d�V˜<Ñ(;¸CÓ(@Ð'AÀÀDÇIÁIÌfÐU[ÕU`ÓNaÓDbÐCcÐdÖeñ çÜ�d�VÐ?Ð@Ø.¨w°q­z¸$Õ/?Ð.@ÐAÔfiÐjqÓfrÐuvÔfvÀsÌ3ÈwË<ÐZ[ÕK[ÐJ\Ð\aÑEbÐ|~Õð  CFõ  Fö	GçÜ�d�VÐcÐdÖeñ r   c               ó$   € V ^8„  d   QhRRRRRR/# )r   r?   úPath | NoneÚversion_infoztuple[int, ...] | Noner   ro   r   )r   s   "r   r   r   {   s(   € ÷ 9Iñ 9I°ð 9IÐRhð 9IÐtxñ 9Ir   c                óP  € ^ RI Hp ^ RIHpHpHpHp V! V4      pV! 4       p \        V e   T MT4      p	. pT	 EF¥  w  rÍTP                  4       '       g   K  \        T4      w  rï\        T4      pTfo   TR8X  dh   TR8X  da   T'       d   TP                  T4       \        T RT R2R	T'       d   R
MR,           RTR8X  d   RMRT 2 R2,           4       \        YÍ4       K¨  Te1   T'       d   \        T R2RT R24       KÉ  \        T RT R24       KÜ  TR8X  dV   T! \!        T4      4      '       d?   T'       d   TP                  T4       \        T RT R2RTR8X  d   RMRT 2 R24       EK8  TR8X  d/   T'       d'   TP                  T4       \        T RT R2R4       EKm  TR8X  d   \        T RT R24       EKˆ  \        T RT T'       d   RMR R24       EK¨  	  T'       d   \        RT! 4        24       R# R#   \         d   p
\        RT
 24        Rp
?
R# Rp
?
ii ; i)z—List each database's journal mode; warn on WAL under a vulnerable SQLite, and on a configured
``database.journal_mode: delete`` that never took effect.)ÚHERMES_HOME)Ú_path_on_cross_vm_fsÚ_wal_reset_repair_hintÚis_sqlite_wal_reset_vulnerableÚresolve_journal_modeNz!Could not list Hermes databases: r^   Údeletez is in WAL mode (z&) despite database.journal_mode=deletezM(the setting never applied: an existing WAL database is never live-downgradedz#; also exposed to the WAL-reset bugr$   z_. Stop every Hermes process for this profile, then run `hermes sessions set-journal-mode deletezstate.dbz --db z`)z : journal mode could not be readr9   z; cannot rule out WAL exposure)z": journal mode could not be read (rw   z7 is in WAL mode on a cross-VM filesystem (virtiofs/9p, z|(WAL can silently corrupt across the VM boundary; stop every Hermes process and run `hermes sessions set-journal-mode deleteu`   `, then set `database.journal_mode: delete` â€” or move the database onto a native/named volume)z7(exposed to the WAL-reset bug until SQLite is upgraded)z: WAL journal mode (z: rollback journal mode (z, not exposedzTo clear the exposure: )r(   r‡   Úhermes_state_walrˆ   r‰   rŠ   r‹   rM   Ú	Exceptionr   Úis_filerf   rm   rH   r‚   r   r   )r?   r…   r‡   rˆ   r‰   rŠ   r‹   Ú
vulnerableÚ
configuredÚ	databasesrW   ÚexposedrJ   Úpathre   ÚerrorÚsizes   &&               r   Ú_report_database_journal_modesr—   {   s\  € õ .÷ó ñ 0°Ó=€JÙ%Ó'€JðÜ*¸+Ò:Q©;ÐWbÓcˆ	ð €GÜ‰
ˆØ�|‰|�~Š~ÙÜ(¨Ó.‰ˆÜ˜tÓ$ˆØŠ=˜T Uœ]¨z¸XÔ/E÷ Ø—‘˜tÔ$Ü˜$˜Ð0°°Ð6\Ð]ØfßCMÑ?ÐSUõWðBØHLÐPZÔHZÁ"ÐbhÐimÐhnÐ`oÐApÐprðtõtôuô
 % TÖ0ØÒßÜ˜d˜VÐ#CÐDÈÈ%ÈÐPoÐFpÖqä˜d˜VÐ#EÀeÀWÈAÐNÖOØ�UŒ]Ñ3´C¸³I×>Ò>÷ Ø—‘˜tÔ$Ü˜$˜ÐVÐW[ÐV\Ð\]Ð^ðBØHLÐPZÔHZÁ"ÐbhÐimÐhnÐ`oÐApð qrðr÷sð �UŒ]ŸzØ�N‰N˜4Ô Ü˜$˜Ð0°°°aÐ8Ð:s×tØ�UŒ]Ü˜$˜Ð3°D°6¸Ð;×<ä˜$˜Ð8¸¸×R\¹ÐbdÐ>eÐefÐg×hñQ  ÷R ÜÐ,Ñ-CÓ-EÐ,FÐGÖHñ øô[ ô ÜÐ6°s°eÐ<Ô=Ýûðús   £H ÈH%ÈH È H%c               ó    € V ^8„  d   QhRRRR/# ©r   Úissuesz	list[str]r   ro   r   )r   s   "r   r   r   ·   s   € ÷ +ñ + )ð +°ñ +r   c                ó  €  ^ RI HpHp T! 4       R8w  d   R# \	        R4       T! 4       pR F>  pTP                  T4      pT'       d   \        M\        ! T'       d   T R2MT R24       K@  	  \        Y04       R#   \         d     R# i ; i)z¢Under our s6 /init, report static services and the ONE host gateway slot; no-op elsewhere.
Counterpart to :func:`_check_gateway_service_linger` (systemd-on-host).)ÚS6ServiceManagerÚdetect_service_managerNÚs6zs6 Supervisionz: upz(: down (expected if not enabled via env))zmain-hermesÚ	dashboard)	Úhermes_cli.service_managerrœ   r�   rŽ   r
   Ú
is_runningr   r   Ú_report_host_gateway_slot)rš   rœ   r�   ÚmgrÚstaticÚups   &     r   Ú_check_s6_supervisionr¦   ·   s‚   € ðßWñ Ó 4Ô'ÙÜÐÔÙ
Ó
€CÛ.ˆØ�^‰^˜FÓ#ˆß�œZÐ	'¿B¨F¨8°4©ÀvÀhÐNvÐDwÖxñ /ô ˜cÖ*øô ô Úðús   ‚A; Á;B
Â	B
c               ó    € V ^8„  d   QhRRRR/# r™   r   )r   s   "r   r   r   È   s   € ÷ Nñ N¨9ð N¸ñ Nr   c           
     óJ  a € ^ RI Hp \        S P                  4       4      pV! 4       pVf‰   V'       g   \	        R4      # V Uu. uF!  pS P                  RV 24      '       g   K  VNK#  	  ppVP                  R4       \        R\        V4       R\        V4       RR	P                  V4       R
2R4      # \        RVP                  4        24       \        V 3R lV 4       4      pV'       d2   \        RR	P                  V4       2R4       VP                  R4       R# R# u upi )u  Multiplex-only: ONE gateway process serves N profiles, so report THAT process and its
roster. The old ``Per-profile gateways: up/total`` line described a topology we no longer
run â€” it counted supervision slots and never said which profiles were actually served.)Úhost_gateway_topologyNu:   No gateway registered yet â€” run `hermes gateway install`úgateway-up   No host gateway owns the gateway role â€” start the ONE host multiplexer: hermes --profile default gateway startz'No host gateway owns the gateway role (Ú/z supervision slots up: ru   rw   z#(nothing is serving these profiles)zHost gateway: c              3  óp   <"  € T F+  qR 8w  g   K  SP                  RV 24      '       g   K'  Vx € K-  	  R# 5i)Údefaultrª   N)r¡   )Ú.0Úpr£   s   & €r   Ú	<genexpr>Ú,_report_host_gateway_slot.<locals>.<genexpr>Ø   s,   øé € Ð]¡%˜Q°	©>”q¸c¿n¹nÈxÐXYÐWZÈ^×>\—q’q£%ùs   ƒ6�6¬
6z3LEGACY per-profile gateway slots still supervised: zP(multiplex-only: the host gateway already serves every profile from one process)zpFold the legacy per-profile gateways into the host gateway: hermes --profile default gateway migrate --multiplex)Úgateway.host_topologyr©   rF   Úlist_profile_gatewaysr   r¡   rH   r   ra   r}   r   Údescribe)r£   rš   r©   ÚslotsÚtopologyr¯   r¥   Ú	legacy_ups   f&      r   r¢   r¢   È   s   ø€ õ <Ü�3×,Ñ,Ó.Ó/€EÙ$Ó&€HØÒßÜÐZÓ[Ð[ÙÓA™�A #§.¡.°8¸A¸3°×"@�aˆa™ˆÐAØ�‰ð ?ô 	@äÐCÄCÈÃGÀ9ÈAÌcÐRWËjÈ\ð Z'Ø'+§y¡y°Ó'7Ð&8¸ð;Ø<aócð 	cäˆ~˜h×/Ñ/Ó1Ð2Ð3Ô4ÜÔ]¡%Ó]Ó]€IßÜÐHÈÏÉÐS\ÓI]ÐH^Ð_Øeô	gà�‰ð Mö 	Nñ ùò Bs   ÁD Á$D Fc               ó$   € V ^8„  d   QhRRRRRR/# )r   Ú
should_fixÚboolrš   zlist | Noner   ro   r   )r   s   "r   r   r   à   s'   € ÷ Lñ L 4ð L¸ð LÐPTñ Lr   c                óš  €  ^ RI Hp Tf   . pT! 4       pT'       g   \        RR4        \
        P                  ! 4        T'       d   \        R4       R# \        R	4       R#   \         d    p\        R\	        T4      4      u Rp?# Rp?ii ; i  \         d2   p\        R\	        T4      \        4       R,           T4        Rp?R# Rp?ii ; i)
ad  Verify the actual TLS policy is usable before the first HTTPS call tracebacks.

The policy is ``agent.ssl_verify``: the platform verifier (truststore) is
installed process-wide and every stack builds SSL contexts through it. There
is no certifi bundle to validate anymore; the check is that the platform
store is in force and a default context constructs.
)Úinstall_truststorezTLS trust check skippedNz$TLS platform trust store unavailableztOpenSSL default trust paths are in use; certificates trusted only by the OS store (a corporate root) will not verifyz-TLS default SSL context cannot be constructedzC; if TLS still fails, repair Python through the installation owner.zBTLS platform trust store configured; default SSL context availablez7TLS default SSL context available (OpenSSL trust paths))
Úagent.ssl_verifyr¼   rŽ   r   r   ÚsslÚcreate_default_contextr	   r+   r   )r¹   rš   r¼   ÚeÚplatform_stores   &&   r   Úcheck_certificatesrÂ   à   s´   € ð=Ý7ð ‚~ØˆÙ'Ó)€NßÜÐ9ð Jô	KðÜ×"Ò"Ô$÷
 ÜÐUÖVäÐJÖKøô# ô =ÜÐ3´S¸³VÓ<Õ<ûð=ûô ô ÜÐGÌÈQËÜ+Ó-Ð0uÕuÐw}ô	åûðús4   ‚A! ªB Á!BÁ,BÂ BÂBÂC
Â&CÃC
c               ó    € V ^8„  d   QhRRRR/# r™   r   )r   s   "r   r   r   þ   s   € ÷ gñ g¨)ð g¸ñ gr   c                óð  €  ^ RI HpHpHpHpHp ^ RIHp T! 4       '       d   T! 4       R8X  d   R# T! 4       T R2,          pT! 4       P                  4       '       g   TP                  4       '       g   R# \        R	4       T! 4       w  ršT	f   \        R
RT
 R24      # \        T	RR4      '       g   \        R4       T P                  R4       R# R#   \         d   p\        RRT R24      u Rp?# Rp?ii ; i)uk  Warn when a systemd user gateway service will stop after logout (skipped under s6: no linger concept).

Multiplex-only: the HOST gateway runs under the default profile's unit, so a doctor run from a
SERVED profile must still check it â€” gating on the active profile's own unit silently skipped
the check for every profile that does not own a service of its own.
)Ú_SERVICE_BASEÚget_systemd_linger_statusÚget_systemd_unit_pathÚis_linuxÚuser_systemd_unit_dir)r�   zGateway service lingerz#(could not import gateway helpers: rw   Nrž   z.servicezGateway ServicezCould not verify systemd lingerr9   z&Run: sudo loginctl enable-linger $USERzMEnable linger for the gateway user service: sudo loginctl enable-linger $USER)zSystemd linger enabledz!(gateway service survives logout))zSystemd linger disabledz(gateway may stop after logout))Úhermes_cli.gatewayrÅ   rÆ   rÇ   rÈ   rÉ   r    r�   rŽ   r   Úexistsr
   r   r   rH   )rš   rÅ   rÆ   rÇ   rÈ   rÉ   r�   rÀ   Ú	host_unitÚlinger_enabledÚlinger_details   &          r   Ú_check_gateway_service_lingerrÏ   þ   sù   € ð`÷	#õ 	#õ 	Fñ �:Š:Ñ/Ó1°TÔ9ÙÙ%Ó'¨]¨O¸8Ð*DÕD€IÙ!Ó#×*Ñ*×,Ò,°	×0@Ñ0@×0BÒ0BÙÜÐÔÙ$=Ó$?Ñ!€NØÒÜÐ;¸qÀÀÈqÐ=QÓRÐRÜ�nÐ&eØT÷Vò VäÐ;Ô<Ø�‰ÐeÖfñVøô ô `ÜÐ2Ð6YÐZ[ÐY\Ð\]Ð4^Ó_Õ_ûð`ús   ‚C ÃC5ÃC0Ã*C5Ã0C5uè   the desktop bundle's designated requirement is cdhash-pinned (pre-#73681 build) â€” rebuilds invalidate all permission grants. Run `hermes update` to get the stable identifier-pinned signing identity, then re-grant permissions once.Tz2(certificate-anchored DR; grants survive rebuilds)uw   (identifier-pinned DR; grants survive rebuilds â€” for the strongest anchor, see `hermes desktop --setup-tcc-identity`)c               ó   € V ^8„  d   QhRR/# ©r   r   ro   r   )r   s   "r   r   r   %  s   € ÷ Kñ K ñ Kr   c                 óB  € \         P                  R8X  d   \        4       MRp V f   R# \        V 4      pV'       g   \	        RR4      # RVP                  4       9   d   \	        R\        4      # \        R\        RVP                  4       9   ,          4       \        R	4       R# )
a  Check macOS TCC grant persistence for a locally-built desktop bundle; silent on non-macOS / no bundle.

TCC keys grants to the app's designated requirement (DR). A cdhash-pinned ad-hoc DR changes on every
rebuild, so grants silently stop matching while the Settings toggle stays ON; identifier-pinned builds
survive rebuilds, but grants made to older binaries stay stale until re-granted once. TCC.db needs Full
Disk Access, so the DR string is the only readable signal (a proxy for the signing class, not DR wording).

See #86385.
r/   NzmacOS TCC grant checkz?(could not read code-signing requirement of the desktop bundle)Úcdhashz.macOS TCC grants will reset after every updatez$macOS TCC signing identity is stableÚcertificateuü   If macOS still re-prompts for permissions (toggle shows ON): the stored grant is stale â€” run `tccutil reset ScreenCapture com.nousresearch.hermes` (repeat per affected service), toggle it ON in System Settings, then fully quit & relaunch Hermes once.)
r2   r3   Ú_desktop_app_bundleÚ_macos_desktop_drr   ÚlowerÚ_TCC_CDHASH_DETAILr   Ú_TCC_STABLE_DETAILr   )ÚappÚdrs     r   Úcheck_macos_tcc_grantsrÜ   %  sŠ   € ô $'§<¡<°8Ô#;Ô
Ô
À€CØ
‚{ÙÜ	˜3Ó	€BßÜÐ1Ð3tÓuÐuØ�2—8‘8“:ÔÜÐJÔL^Ó_Ð_äÐ3Ô5GÈÐY[×YaÑYaÓYcÑHcÕ5dÔeÜð Jö Kr   c               ó   € V ^8„  d   QhRR/# ©r   r   r„   r   )r   s   "r   r   r   >  s   € ÷ Tñ T˜[ñ Tr   c                 ó0  € \        \        4      P                  4       P                  ^,          R,          R,          R,          p V P	                  R4       Uu. uF  qP                  4       '       g   K  VNK  	  ppV'       d   \        VR R7      # R# u upi )a4  Locate the locally-built desktop bundle (``apps/desktop/release/mac-<arch>/Hermes.app``), newest first.

The only layout whose ad-hoc re-signed bundle can invalidate TCC grants. ``/Applications/Hermes.app`` is
deliberately not probed: it is the separately-signed, certificate-anchored Hermes-Setup launcher.
ÚappsÚdesktopÚreleasezmac*/Hermes.appc                ó6   € V P                  4       P                  # ©N)rR   Úst_mtime)r¯   s   &r   Ú<lambda>Ú%_desktop_app_bundle.<locals>.<lambda>F  s   € ¨¯©«×):Ò):r   )ÚkeyN)r   Ú__file__ÚresolveÚparentsrG   Úis_dirÚmax)Úrelease_dirr¯   Ú
candidatess      r   rÕ   rÕ   >  su   € ô ”x“.×(Ñ(Ó*×2Ñ2°1Õ5¸Õ>ÀÕJÈYÕV€KØ(×-Ñ-Ð.?Ô@ÓOÑ@˜ÇHÁHÇJ—!�!Ñ@€JÐOß?IŒ3ˆzÑ:Ô;ÐSÈtÐSùò Ps   ÁBÁ3Bc               ó    € V ^8„  d   QhRRRR/# )r   rÚ   r   r   r7   r   )r   s   "r   r   r   I  s   € ÷ gñ g˜4ð g Jñ gr   c           
     ón  € \         P                  ! R4      p V'       d,   \        P                  ! VRRR\	        V 4      .RRRR^RR	7      MR
pTe   TP                  ^ 8w  d   R
# TP                  ;'       g    RTP                  ;'       g    R,           #   \
        \        P                  3 d     R
# i ; i)zsReturn the bundle's designated requirement string, or None on failure (a hanging codesign must never abort doctor).Úcodesignz-dz--requirementsÚ-Túutf-8ÚreplaceF)Úcapture_outputÚtextÚencodingÚerrorsÚtimeoutÚcheckNr$   )
ÚshutilÚwhichÚ
subprocessÚrunr   ÚFileNotFoundErrorÚTimeoutExpiredÚ
returncodeÚstdoutÚstderr)rÚ   rò   Úprocs   &  r   rÖ   rÖ   I  sÁ   € ä�|Š|˜JÓ'€Hð÷ rzŒz�~Š~˜x¨Ð/?ÀÄcÈ#ÃhÐOÐ`dÐkoð  {Bð  KTð  ^`ð  hmõ  nð  @Dˆð ’< 4§?¡?°aÔ#7ˆ4Ðf¸d¿k¹k×>OÐ>OÈRÐTX×T_ÑT_×TeÐTeÐceÕ=fÐføô œz×8Ñ8Ð9ô Úðús   ˜B  -B ÂB4Â3B4c               ó    € V ^8„  d   QhRRRR/# )r   r¹   rº   r   ro   r   )r   s   "r   r   r   S  s   € ÷ sñ s tð s¸ñ sr   c                óž  € \        R4      ;_uu_ 4        ^ RIHp VP                  4       w  r#VR8X  d    RRR4       R# VR8X  d   \	        RRV R24      uuRRR4       # V '       d   VP                  4       MRpVe   \	        R	RV R24      uuRRR4       # \        VR
8X  d   RMRRV R24       RRR4       R#   + '       g   i     R# ; i)záReport (and with --fix install) the dylib-complete TCC anchor; silent on non-macOS / non-uv interpreters.
Never raises. Install is gated by the module's pre-install boot probe, so ``--fix`` cannot brick the CLI.

See #95596.
zmacOS TCC anchor check failed)Úmacos_tcc_anchorÚskipNÚactivezmacOS TCC anchor activer9   rw   zmacOS TCC anchor installedÚmissingzmacOS TCC anchor missingzmacOS TCC anchor stale)r   Ú
hermes_clir  Útcc_anchor_stater   Úensure_tcc_anchorr   )r¹   ÚtccÚstatusÚdetailÚanchoreds   &    r   Úcheck_macos_tcc_anchorr  S  sÃ   € ô 
Ð6×	7Õ	7Ý6Ø×-Ñ-Ó/‰ˆØ�VÔØ÷	 
8Ñ	7ð
 �XÔÜÐ5¸¸6¸(À!°}ÓE÷ 
8Ò	7÷ /9�3×(Ñ(Ô*¸dˆØÒÜÐ8¸A¸h¸ZÀq¸/ÓJ÷ 
8Ò	7ô 	°¸9Ô1DÑ-ÐJbÐfgÐhnÐgoÐopÐdqÔr÷ 
8×	7×	7Ò	7ús"   ”!B;¿B;Á B;Á(%B;ÂB;Â;C	c               ó   € V ^8„  d   QhRR/# rÑ   r   )r   s   "r   r   r   f  s   € ÷ dñ d dñ dr   c                 ó  € \         P                  R8w  d   R#  \        P                  ! \        P
                  ! 4       R,          R,          R,          4       \        RR4       R#   \         d    \        R4        R# \         d     R# i ; i)	u  One-grant guidance: Full Disk Access silences every per-folder TCC prompt. Silent on non-macOS.

Probe: listdir of ``~/Library/Application Support/com.apple.TCC`` â€” FDA-gated, and probing it does NOT
trigger a prompt (the TCC dir just returns EPERM). A missing dir / other error is indeterminate: stay silent.

macOS TCC prompts per-category (Desktop, then Downloads, then Documents, ...), so first-run agents
drip-feed permission dialogs as they touch each folder. ONE Full Disk Access grant covers all of them,
permanently â€” and with the stable signing identities now in place (#73681/#95091/#95131), it survives
updates too. This check probes whether the terminal context already has FDA and, when it doesn't, prints
the exact one-switch setup with the System Settings deep link.
r/   NÚLibraryzApplication Supportzcom.apple.TCCzmacOS Full Disk Access grantedz-(no per-folder permission prompts will occur)uó  One switch silences all macOS folder prompts: grant your terminal app Full Disk Access and Hermes will never trip per-folder dialogs (Desktop/Downloads/Documents/...) again. Open: System Settings â†’ Privacy & Security â†’ Full Disk Access â€” or run:
      open "x-apple.systempreferences:com.apple.preference.security?Privacy_AllFiles"
    then enable your terminal (and Hermes.app if you use Desktop), and restart them once. With Hermes' stable signing identities the grant survives every update.)
r2   r3   rT   Úlistdirr   Úhomer   ÚPermissionErrorr   rS   r   r   r   Úcheck_macos_full_disk_accessr  f  sw   € ô ‡|�|�xÔÙðdÜ
�
Š
”4—9’9“; Õ*Ð-BÕBÀ_ÕTÔUô 	Ð1Ð3bÖcøô ô ^Üð ]÷ 	^ô ô Úðús   ™>A% Á%BÁ>BÂBÂBz#Security advisory check failed: {e}c               ó$   € V ^8„  d   QhRRRRRR/# ©r   r¹   rº   Úfr   r   ro   r   )r   s   "r   r   r   „  s&   € ÷ vñ v¨4ð v°Gð vÀñ vr   c                óæ  € ^ RI HpHpHpHp V! 4       pV! V4      pV'       g   \        R4      # V FÓ  p\        VP                  P                   RVP                   RVP                   R2RVP                  P                   RVP                   RVP                   RVP                  P                   R	2	VP                  4       V! V4       F3  p	\        V	'       d   R
\        V	\        P                   4       2MR4       K5  	  KÕ  	  V! 4       p
V F\  pVP                  P                  V
9   g   K   \#        VP                   RVP                   RVP                  P                   R24       K^  	  R# )zmCompromised-package advisories, funnelled into manual issues; a bug here must never block the rest of doctor.)Údetect_compromisedÚfilter_unackedÚfull_remediation_textÚget_acked_idszNo active security advisoriesr9   z==rw   zResolve security advisory z: uninstall z7 and rotate credentials, then run `hermes doctor --ack z`.z    r$   z still installed (advisory z acknowledged)N)Úhermes_cli.security_advisoriesr  r   r!  r"  r   r	   ÚadvisoryÚtitleÚpackageÚinstalled_versionÚidÚmanual_issuesÚprintr   r   ÚYELLOWr   )r¹   r  r  r   r!  r"  Úall_hitsÚ
fresh_hitsÚhitÚlineÚ	acked_idsÚhs   &&          r   Ú_check_security_advisoriesr2  ƒ  sL  € ÷ xÓwÙ!Ó#€HÙ Ó)€JßÜÐ7Ó8Ð8Ûˆä˜3Ÿ<™<×-Ñ-Ð.°1°S·[±[°MÀÀC×DYÑDYÐCZÐZ[Ð1\Ø4°S·\±\·_±_Ð4EÀ\ÐRU×R]ÑR]ÐQ^Ð^`Ðad×avÑavÐ`wð xQØQT×Q]ÑQ]×Q`ÑQ`ÐPaÐacðeØfg×fuÑfuô	wñ *¨#Ö.ˆDÜ¿�Dœ˜t¤V§]¡]Ó3Ð4Ñ5À2ÖFó /ñ ñ “€IÛˆØ�:‰:�=‰=˜IÖ%Ü˜!Ÿ)™)˜ B q×':Ñ':Ð&;Ð;VÐWX×WaÑWa×WdÑWdÐVeÐesÐtÖuó r   c               ó   € V ^8„  d   QhRR/# rÞ   r   )r   s   "r   r   r   ˜  s   € ÷ ñ ˜+ñ r   c                 óÔ   €  ^ RI p ^ RIHp V! 4       P                  4       pTe2   \        T4      R,          P                  4       '       d   \        T4      # R#   \         d     R# i ; i)uÆ  pm's provisioned runtime venv, or None when nothing is staged.

``pm.packages.Venv().venv_dir()`` is pm's public authority for where
the runtime venv lives, including an external selected generation or
the original source/payload environment before first sync. A resolved
path without a venv marker is not a provisioned venv â€” pm also returns
the intended location before first sync, and
doctor must not read an empty directory as staged dependencies.
N)ÚVenvz
pyvenv.cfg)ÚpmÚpm.packagesr5  Úvenv_dirrŽ   r   r�   )r6  r5  r8  s      r   Ú_staged_venv_dirr9  ˜  s[   € ðÛÝ$á“6—?‘?Ó$ˆð Ò¤ h£°,Õ!>× GÑ G× IÒ IÜ�H‹~ÐÙøô	 ô Úðús   ‚A ÁA'Á&A'c               ó$   € V ^8„  d   QhRRRRRR/# r  r   )r   s   "r   r   r   ¯  s!   € ÷ *ñ *¨$ð *°7ð *¸tñ *r   c           	     ó¤  a€ \         P                  RRP                  \        \        \         P                  R,          4      4       2r2VR8  d   \        VRRVP                  4       M)\        VR8¬  W3R34      '       d   VR8  d   \        R4       \        RR	4      ;_uu_ 4        ^ R
I
p^ RIHpHp V! 4       p\        V! 4       '       * RVP                   2RVP                   R2\        4       34       V'       d/   \!        R\#        V4      ^08”  d   VR,          R,           MT 24       \%        4        R
R
R
4       \'        4       pVe¦   ^ RIHp	 V	! V4      P-                  4       oSP/                  4       ;'       dW    \0        ;QJ d-    V3R l\         P2                   4       F  '       g   K   RM"	  RM! V3R l\         P2                   4       4      p
\5        RV R2V
'       d   RMR4       M,\        \         P6                  \         P8                  8g  RR4       \;        V R7       \=        4        \?        4        R
#   + '       g   i     EL; i)zSInterpreter, linked SQLite, venv, macOS TCC anchors/FDA/grants, version-file drift.zPython Ú.:Né   Nz(3.10+ required)zUpgrade Python to 3.10+z(3.10+ recommended)zHPython 3.11+ recommended for RL Training tools (tinker requires >= 3.11)z SQLite version probe failed: {e}r$   N)rŠ   Úsqlite_source_idzSQLite z (WAL-reset bug)zSQLite source id: :Né0   Nu   â€¦)Úsite_packagesc              3  ó\   <"  € T F!  p\        V4      P                  4       S8H  x € K#  	  R # 5irä   )r   rê   )r®   ÚentryÚselected_sites   & €r   r°   Ú,_check_python_environment.<locals>.<genexpr>É  s&   øé € Ð5sÑjrÐaf´d¸5³k×6IÑ6IÓ6KÈ}Ö6\Ójrùs   ƒ),TFzRuntime venv staged (rw   z(active in this process)z(this process runs outside it)zVirtual environment active)r¹   )r=  é   )r=  é
   )r=  é   )zNot in virtual environmentz(recommended)) r2   r…   r}   Úmapr   r	   rš   r   r   r   Úsqlite3r�   rŠ   r>  Úsqlite_versionr=   r   ra   r—   r9  Úpm.environmentsr@  rê   rì   Úanyr”   r   ÚprefixÚbase_prefixr  r  rÜ   )r¹   r  ÚvÚlabelrI  rŠ   r>  ÚsrcÚstagedr@  Úrunning_hererC  s   &&         @r   Ú_check_python_environmentrT  ®  sÓ  ø€ ô ×Ñ 7¨3¯8©8´C¼¼S×=MÑ=MÈbÕ=QÓ4RÓ+SÐ*TÐ!U€uØˆ6„zÜ˜Ð1Ð3LÈaÏhÉhÕWÜ	�A˜‘L %Ð1FÐ)G×	HÒ	HÈQÐQXÌ[ÜÐ]Ô^ô 
Ð9¸2×	>Õ	>ÛßUÙÓ ˆäÑ5Ó7Ô7¸7À7×CYÑCYÐBZÐ9[Ø˜g×4Ñ4Ð5Ð5EÐFÔH\ÓH^Ð_ô	açÜÐ+Ä#ÀcÃ(ÈRÄ-¨S°­X¸Ö-=ÐUXÐ+YÐZÔ[Ü&Ô(÷ 
?ô Ó€FØÒÝ1á% fÓ-×5Ñ5Ó7ˆØ$×+Ñ+Ó-×sÐs·#³#Ô5sÔjm×jrÒjrÓ5s·#·#²#Ô5sÔjm×jrÒjrÓ5sÓ2sˆÜÐ(¨¨°Ð2ß/;Ñ+ÐAaõ	cô 	”3—:‘:¤§¡Ñ0Ð2NØBô	Dô  jÕ1ô !Ô"ô
 Ö÷C 
?×	>Ð	>ús   Â%BH>È>I	c               ó$   € V ^8„  d   QhRRRRRR/# r  r   )r   s   "r   r   r   Ý  s&   € ÷ Fñ F Dð F¨Wð F¸ñ Fr   c                ó2   € \        WP                  R 7       R# ))r¹   rš   N)rÂ   r)  ©r¹   r  s   &&r   Ú_check_certificatesrX  Ü  s   € ä *·_±_×Er   c               ó$   € V ^8„  d   QhRRRRRR/# r  r   )r   s   "r   r   r   ê  s&   € ÷ 	hñ 	h¨ð 	h°'ð 	h¸dñ 	hr   c                ó  € \          F'  w  r#p \        V4       \        Y4'       d   R MR4       K)  	  R#   \         dB    T'       d   \	        TR4        KO  \        TRRT R\        4        2TP                  4        Kx  i ; i)z
(optional)r$   z(optional, not installed)z	(missing)zRepair rt   N)Ú	_PACKAGESÚ
__import__r   ÚImportErrorr   r	   r+   rš   )r¹   r  ÚmodulerJ   Úoptionals   &&   r   Ú_check_required_packagesr`  é  su   € ç"+Ñˆ�hð	hÜ�vÔÜ�T®8™<¸Ö<ó #,øô ô 	hßÜ˜4Ð!<×=ä  k°W¸T¸FÀ"ÔEXÓEZÐD[Ð3\Ð^_×^fÑ^f×gð		hús   Ž 4´B ÁB Á&B Á?B c               ó$   € V ^8„  d   QhRRRRRR/# r  r   )r   s   "r   r   r   ö  s!   € ÷ )ñ )°ð )¸'ð )Àdñ )r   c                ó  € \         P                  R8w  d   R# ^ RIHp VP	                  4       pV'       g   R# \        R4       V '       g7   V F  p\        RRV R24       K  	  VP                  P                  R4       R# VP                  4       w  rVV F  p\        V4       K  	  V F  p\        V4       K  	  V'       d"   V'       g   V;P                  ^,          un        V'       d   VP                  P                  V4       R# R# )	u’   Windows: the gateway must start at logon from ONE mechanism â€” a Scheduled Task and a
Startup-folder entry side by side launch it twice (#80569).Úwin32N)Úgateway_windowszWindows Gateway AutostartzRedundant gateway login itemr9   rw   zGRemove duplicate Windows gateway autostart entries: hermes doctor --fix)r2   r3   r  rd  Úredundant_autostart_entriesr
   r   rš   rH   Úreconcile_autostart_launchersr   Úfixedr)  Úextend)r¹   r  rd  Ú	redundantr”   ÚdoneÚwarningsÚmessages   &&      r   Ú _check_windows_gateway_autostartrm  ö  sÇ   € ô ‡|�|�wÔÙÝ*Ø×;Ñ;Ó=€IßÙÜÐ(Ô)ßÛˆDÜÐ5¸¸4¸&À°{ÖCñ à	�‰�‰ÐaÔbÙØ$×BÑBÓD�N€DÛˆÜ�Öñ ãˆÜ�7Öñ ç—HØ	�Š�1��ßØ	�‰×Ñ˜xÖ(ñ r   c               ó$   € V ^8„  d   QhRRRRRR/# r  r   )r   s   "r   r   r     s!   € ÷ 0ñ 0¨Dð 0°Wð 0Àñ 0r   c                óZ  € ^ RI Hp \        \        P                  RR7      p \
        P                  ! \        P                  RR.RRRR^x\        V4      VR	R
7	      pTP                  ;'       g    RP                  4       pTP                  ^ 8X  d   \!        RR4      # RT9   d   \#        RR4      # T'       d   TP%                  4       R,          MRTP                   R2p\        RTRTP                  4       R#   \
        P                   d    \        RRRTP                  4        R# i ; i)uM  Import the dashboard web surface in a subprocess so an import-time crash lands in the report.

When starlette is updated past the fastapi pinned beside it (the CVE starlette pin ships in
several extras on its own), ``hermes dashboard`` dies constructing ``FastAPI(...)`` with a
TypeError â€” not an ImportError â€” so the module's own lazy-install fallback never fires and the
process exits before a single log line. Importing in a subprocess keeps a dead web surface
from taking the doctor down with it; lazy installs stay off so the probe never mutates the
environment it is diagnosing.
r    Ú1)ÚHERMES_DISABLE_LAZY_INSTALLSz-czimport hermes_cli.web_serverTrô   rõ   F)rö   r÷   rø   rù   rú   ÚcwdÚenvrû   zDashboard web surfacez(import probe timed out)zJRepair the dashboard dependencies: `hermes pm repair`, then restart HermesNr$   z(imports cleanly)z#Web UI requires fastapi and uvicornz"(optional web extra not installed)z(exited with code rw   éÿÿÿÿ)r(   r!   ÚdictrT   Úenvironrþ   rÿ   r2   Ú
executabler   r  r	   rš   r  Ústripr  r   r   Ú
splitlines)r¹   r  r!   rs  r  r  r  s   &&     r   Ú_check_web_dashboard_importrz    s  € õ /ä
Œr�z‰z¸Ô
<€CðÜ�~Š~Ü�^‰^˜TÐ#AÐBØØØØØÜ�LÓ!ØØô

ˆð& �k‰k×Ð˜R×&Ñ&Ó(€FØ‡�˜!ÔÜÐ/Ð1DÓEÐEØ,°Ô6ô Ð1Ð3WÓXÐXç#)ˆ×ÑÓ˜BÖÐ1CÀDÇOÁOÐCTÐTUÐ/Vð ô ØØØTØ	�‰ö	øô% ×$Ñ$ô ÜØ#Ø&ØXØ�H‰Hô		
ò 	ðús   £9C9 Ã9-D*Ä)D*c               ó$   € V ^8„  d   QhRRRRRR/# r  r   )r   s   "r   r   r   E  s!   € ÷ 4ñ 4¨4ð 4°Gð 4Àñ 4r   c                óp   € \        VP                  4       \        VP                  4       \        W4       R # rä   )rÏ   rš   r¦   rm  rW  s   &&r   Ú_check_gateway_supervisionr}  D  s"   € ä! !§(¡(Ô+Ü˜!Ÿ(™(Ô#Ü$ ZÖ3r   c               ó$   € V ^8„  d   QhRRRRRR/# r  r   )r   s   "r   r   r   L  s&   € ÷ F>ñ F>¨Dð F>°Wð F>Àñ F>r   c                óÔ	  € ^ RI Hp \        P                  R8X  d   R# \	        R4       ^ RIHp V! V4      p\        V4      '       g   VR89   dg   \        P                  ! R4      pV'       d   \        RV RV R	24       R# \        R
V R24       VP                  P                  \        4       4       R# ^ RIHp ^ RIHpHp  V! V4      p	Y—! T4      8g  ;'       g    T! T4      RJpT'       d
   TR,          MT	R,          R,          pTP3                  4       '       g,   \        RRT R	24       TP                  P                  R4      # \        RT R	24       \4        P6                  P9                  RR4      pT;'       d-    \4        P6                  P9                  R4      ;'       g    RT9   pT'       d   \;        T4      R,          R3M$\:        P<                  ! 4       R,          R,          R3w  ppTR,          pTP?                  4       '       dÐ   TPA                  4       TPA                  4       ppTT8X  d   \        T R24      # \        T R2RT RT R	24       R9 Uu0 uF(  pTT,          R,          R,          PA                  4       kK*  	  ppTT9  d    TP                  P                  RT R 24      # T '       g    TPB                  P                  R!T R"24      # R#pMoTPE                  4       '       d   \        T R$24      # \/        T R%2R&4       T '       g    TPB                  P                  R'T R(24      # TPG                  R)R)R*7       R+pT'       dJ   ^ R,IH$p T! RY/4      f'   \/        R-4       TP                  P                  R.4      # \        T R/T R024       MJTP?                  4       '       d   TPK                  4        TPM                  T4       \        T R1T R2T 24       T;PN                  ^,          un'        TR+8X  d~   \1        T4      \4        P6                  P9                  R3R4      PQ                  \4        PR                  4      9  d1   \        T R42R54       TP                  P                  R6T R724       R# R# R#   \(        \*        \,        3 dC   p
\/        R\1        T
4      4       TP                  P                  \        4       4      u Rp
?
# Rp
?
ii ; iu upi ):zJCheck the install-owned launch contract without replacing custom commands.r    rc  NzCommand Installationr   ÚhermeszHermes command managed by z (rw   zHermes command not on PATH (z	-managed))Úresolve_store_python)Ú	base_venvÚselected_venvz$Cannot resolve selected dependenciesÚbinzHermes entry point not foundr9   zFRepair or reinstall the Hermes launcher through the installation ownerzHermes entry point exists (ÚPREFIXr$   ÚTERMUX_VERSIONzcom.termux/files/usrz$PREFIX/binz.localz~/.local/binu   /hermes â†’ correct targetz/hermes points to wrong targetu   (â†’ u   , expected â†’ zReview z@/hermes manually; its target is user-managed and was not changedzBroken symlink at u%   /hermes â€” run 'hermes doctor --fix'ÚFixedz/hermes exists (non-symlink)z/hermes not foundz.(hermes command may not work outside the venv)zMissing u-   /hermes symlink â€” run 'hermes doctor --fix'T)rë   Úexist_okÚCreated)Ústage_launcherz!Could not publish Hermes launcherz`Repair the PM store interpreter through the installation owner, then rerun 'hermes doctor --fix'z PM launcher: z/hermesz
 symlink: u   /hermes â†’ ÚPATHz is not on your PATHzC(add it to your shell config: export PATH="$HOME/.local/bin:$PATH")zAdd z to your PATHr%   )Úvenvz.venv)*r(   r!   r2   r3   r
   r'   r   r   rü   rý   r   r   r)  rH   r+   Úhermes_cli._launchersr�  rK  r‚  rƒ  rS   Ú
ValueErrorÚRuntimeErrorr   r   r�   rT   rv  r:   r   r  Ú
is_symlinkrê   rš   rË   ÚmkdirrŠ  ÚunlinkÚ
symlink_torg  ÚsplitÚpathsep)r¹   r  r!   r   r)   r*   r�  r‚  rƒ  ÚselectedrW   Úpm_launcherÚvenv_binrM  ÚtermuxÚlink_dirÚdisplayÚlinkr�   ÚexpectedrJ   Úowned_targetsÚverbrŠ  s   &&                      r   Ú_check_command_installationr   K  sB  € õ /Ü
‡|�|�wÔÙÜÐ#Ô$Ý7á" <Ó0€FÜ˜V×$Ò$¨Ð2CÔ(CÜ—,’,˜xÓ(ˆßÜÐ1°&°¸¸G¸9ÀAÐFÔGñ 	ô Ð5°f°X¸YÐGÔHØ�O‰O×"Ñ"Ô#6Ó#8Ô9ÙÝ:ß8ð=Ù  Ó.ˆð ˜i¨Ó5Ñ5×gÐgÑ9MÈlÓ9[ÐcgÐ9g€Kß*5ˆ|˜hÖ&¸8ÀeÕ;KÈhÕ;V€HØ×Ñ×ÒÜÐ1°Q°x°jÀ°?ÔCØ�‰×%Ñ%Ð&nÓoÐoÜÐ*¨8¨*°AÐ6Ô7ä�Z‰Z�^‰^˜H bÓ)€FØ×^Ð^œŸ™Ÿ™Ð(8Ó9×]Ð]Ð=SÐW]Ñ=]€FßAGœ˜f›¨Õ-¨}Ñ=ÌdÏiÊiËkÐ\dÕNdÐglÕNlÐn|ÐM}Ñ€HˆgØ�hÕ€DØ‡�×ÒØŸ<™<›>¨8×+;Ñ+;Ó+=�ˆØ�XÔÜ˜w˜iÐ'AÐBÓCÐCÜ�g�YÐ<Ð=ÀÀvÀhÈoÐ^fÐ]gÐghÐ?iÔjÙXiÓjÑXiÐPT˜,¨Õ-°Õ5¸Õ@×IÑIÖKÑXiˆÐjØ˜Ô&Ø—?‘?×)Ñ)¨G°G°9Ð<|Ð*}Ó~Ð~ßØ—8‘8—?‘?Ð%7¸°yÐ@eÐ#fÓgÐgØ‰Ø	�‰�ŠÜ˜7˜)Ð#?Ð@ÓAÐAä�g�YÐ/Ð0Ð2bÔcßØ—8‘8—?‘? X¨g¨YÐ6cÐ#dÓeÐeØ�‰˜t¨dˆÔ3ØˆßÝ8á˜( LÓ;ÒCÜÐ:Ô;Ø—?‘?×)Ñ)ð  +Mó  Nð  NÜ�D�6˜¨ y°Ð8Õ9à�?‰?×ÒØ�K‰KŒMØ�‰˜Ô!Ü�D�6˜ G 9¨L¸¸
ÐCÔDØ‡G‚Gˆq…L…GØˆyÔœS ›]´"·*±*·.±.ÀÈÓ2L×2RÑ2RÔSU×S]ÑS]Ó2^Ô^Ü�g�YÐ2Ð3Ð5|Ô}Ø	�‰×Ñ  g Y¨mÐ<Ö=ñ _Ñøô] ”Z¤Ð.ô =ÜÐ9¼3¸s»8ÔDØ�‰×%Ñ%Ô&9Ó&;Ó<Õ<ûð=üò& ks$   ÃR
 É!.S%Ò
S"Ò 7SÓS"ÓS"rä   )NN)FN)F))Úopenaiz
OpenAI SDKF)ÚrichzRich (terminal UI)F)Údotenvzpython-dotenvF)úruamel.yamlr¤  F)ÚhttpxÚHTTPXF)ÚcroniterzCroniter (cron expressions)T)Útelegramzpython-telegram-botT)Údiscordz
discord.pyT)=Ú__doc__Ú
__future__r   rT   rü   r¾   rþ   r2   Úpathlibr   Úhermes_cli.colorsr   r   r'   r   r   Úhermes_cli.doctor_reportr   r	   r
   r   r   r   r   r   r   r   Úhermes_constantsr   r1   r+   r4   r=   rM   rc   rX   rf   rm   r‚   r—   r¦   r¢   rÂ   rÏ   rØ   rÙ   rÜ   rÕ   rÖ   r  r  r2  r9  rT  rX  r[  r`  rm  rz  r}  r   r   r   r   Ú<module>r°     s‰  ðñLõ #ã 	Û Û 
Û Û 
Ý ß +ß Z÷÷ ÷ õ 5õ
9õl÷tõð .Ð õ
hõ^õ(õf÷*9Iõx+õ"N÷0Lõ<gð<&ð ð
 	Ð
>Ø	ð  EðÐ õKõ2Tõg÷sõ&dñ: Ð3Ó4ôvó 5ðvõ(ñ, ƒô*ó ð*ñZ ƒôFó ðFð
€	ñ ƒô	hó ð	hõ)ñ4 ƒô0ó ð0ñf ƒô4ó ð4ñ ƒôF>ó òF>r   