+
    jHàj!Ó ã                   óØ  a € ERM tÍ0 t R t^ RIt^ RIt^ RIt^ RIt^ RI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Ht ^ RIHt ^ RIHtHtHtHt ^ RIHt ^ RIHtHtHtHt ^ RIH t  ^ RI!H"t"H#t#H$t$ ^ R	I%H&t&H't'H(t(H)t)H*t*H+t+H,t, ]PZ                  ! ].4      t/]'t0. ERNOt1. EROOt2RR.t3. ERPOt4] ^ k ]5! 0 ERQm4      ]&,          t6] ^k ]5! 0 ERRm4      t7] ^k Rt8R t9R! R" lt:R# R$ lt;. ]OR%N5t<]5! 0 R&kRkR'kR(kR)kR*kR+kR,kR-kR.kR/kR0kR1kR2kR3kR4kR5kR6kR7kR8kR9kR:kR;kR<kR=kR>kR?kR@kRAkRBkRCkRDkREkRFkRGkRHkRIkRJkRKkRLkRMkRkRkRk]<m4      t=]>;QJ d    . RN ]= 4       F  NK  	  5M! RN ]= 4       4      t?]P€                  ! RO4      tARP RQ ltBRR RS ltCRT RU ltD]5! 0 RkRkRkRkRkRkRkRkRkRkRVkRWkRXkRYkRkRkRkR&kRkRZkR[kR\kR]kR^kR_kR`kRakRbkRckRkRdkR
k4      ] ,          ;tEtF]5! 0 ERSm4      tG]5! 0 ERTm4      tH]5! 0 ERUm4      tIRf Rg ltJRh Ri ltKRj Rk ltLRl Rm ltMRn Ro ltNRp Rq ltORr Rs ltPRt Ru ltQRv Rw ltRRx Ry ltSRztTR{ R| ltUR} R~ ltVR R€ ltWR� R‚ ltXRƒ R„ ltYR… R† ltZR‡ Rˆ lt[R‰ RŠ lt\R‹ RŒ lt]ERVR� RŽ llt^R�R�/R‘ R’ llt_R“ R” lt`R• R– ltaR— R˜ ltbERVR™ Rš lltcR› Rœ ltdR� Rž lteRŸ R  ltfR¡tgR¢ R£ lth] ! R¤ R¥4      4       tiR¦ R§ ltj/ tk] ^k R¨tlR© Rª ltmR« R¬ ltnR­ R® ltoR¯ R° ltpR± R² ltqR³ R´ ltrRµ R¶ lts/ tt] ^k R·tuR¸tv/ tw] ^k ]Pð                  ! 4       ty/ tz] ^k 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ÆRRÇRRÈR/RÉ RÊ llt�RË RÌ lt‚RÍ RÎ ltƒRÏRRÐRÑ/RÒ RÓ llt„RÐRÑ/RÔ RÕ llt…/ t†] ^k RÑs‡RÖtˆR× RØ lt‰RÙ RÚ ltŠRÛ RÜ lt‹RÝ RÞ ltŒ]�! 4       tŽ] ^k RßRÑRàRÑ/Rá Râ llt�Rã Rä lt�ERVRå Ræ llt‘Rç Rè lt’ERWt“Ré Rê lt”Rë Rì lt•ERXRí Rî llt–Rï Rð lt—Rñ Rò lt˜Ró Rô lt™Rõ Rö ltšR÷ Rø lt›ERXRù Rú lltœERYRû Rü llt�Rý Rþ ltžRÿ ER  ltŸER ER lt ER ER lt¡ERXER ER llt¢ERXER ER llt£]5! 0 ERZm4      t¤ER[t¥]P€                  ! ER	4      t¦]5! 0 ER\m4      t§ER
 ER lt¨ER ER lt©ER ER ltªERER/ER ER llt«ER ER lt¬ER ER lt­ER ER lt® ! ER ER]¯4      t°ERXER ER llt±ER t²ER ER  lt³ER! ER" lt´ER# ER$ ltµER% ER& lt¶ERVER' ER( llt·ER) ER* lt¸ER+ ER, lt¹ER- ER. ltºERVER/ ER0 llt»ER1 ER2 lt¼ER3 ER4 lt½ER5R/ER6 ER7 llt¾ER8 ER9 lt¿]5! 0 ER]m]<m4      tÀ]>;QJ d    . ER: ]À 4       F  NK  	  5M! ER: ]À 4       4      tÁER; ER< ltÂ]5! 0 ER^m4      tÃ]5! Re04      tÄER= ER> ltÅER? ER@ ltÆERVERA ERB lltÇERVERC ERD lltÈERE ERF ltÉERG ERH ltÊERI ERJ ltËERK ERL ltÌR# (_  z:Profile management for multiple isolated Hermes instances.N)Ú	dataclassÚfield©ÚPath)ÚDictÚListÚOptionalÚTuple)ÚHOME_CREDENTIAL_DIRS)Úarchive_root_dirsÚ
make_targzÚnormalize_archive_partsÚsafe_extract_targz)ÚPM_RUNTIME_ROOT_DIRS)Ú_rmtree_make_writableÚ_rmtree_with_retryÚwait_profile_unowned)ÚLOCAL_RUNTIME_ROOT_DIRSÚPROFILE_ID_REÚclear_named_profile_deletedÚmark_named_profile_deletedÚnamed_profile_has_identityÚnamed_profile_is_deletedÚnamed_profile_is_liveÚlogsÚhomeú.envzmemories/MEMORY.mdzmemories/USER.mdúgateway.pidúgateway_state.jsonúprocesses.jsonúhermes-agentú
.worktreesÚprofilesÚbinÚnode_modulesú.hermes-runtimeÚnodeústate.dbústate.db-walústate.db-shmÚbackupsústate-snapshotsÚcheckpointsz.no-bundled-skillsz¥# Per-profile secrets for this Hermes profile.
# API keys and tokens set here override the shell environment.
# Behavioral settings belong in config.yaml, not here.
c                ó<   € V ^8„  d   QhR\         R\        R\        /# ©é   Ú	directoryÚcontentsÚreturn©ÚstrÚlistÚset)Úformats   "Ú8/home/ubuntu/.hermes/hermes-agent/hermes_cli/profiles.pyÚ__annotate__r9   h   s!   € ÷ ñ ¤sð ´dð ¼sñ ó    c                ó(  € \        4       pV FÝ  pVR8X  g   VP                  R4      '       d   VP                  V4       K4   \        P                  ! \        P
                  P                  W4      4      P                  p\        P                  ! T4      '       d   K�  \        P                  ! T4      '       d   K®  \        P                  ! T4      '       d   KÌ  TP                  T4       Kß  	  V#   \         d    TP                  T4        EK  i ; i)u»  Entries under *directory* that must never be copied out of a profile: bytecode caches,
``*.sock``/``*.tmp`` names, and anything that is not a regular file, directory, or symlink.
:func:`shutil.copytree` cannot copy special files, so a single live Unix socket without a
``.sock`` name (or a FIFO, or a device node) would abort the whole export or clone with
``[Errno 6] No such device or address``. Symlinks survive â€” copytree recreates them.Ú__pycache__)z.sockú.tmpz.pycz.pyo)r6   ÚendswithÚaddÚosÚlstatÚpathÚjoinÚst_modeÚOSErrorÚstatÚS_ISREGÚS_ISDIRÚS_ISLNK)r0   r1   ÚignoredÚentryÚmodes   &&   r8   Ú_non_exportable_entriesrM   h   sÁ   € ô “5€GÛˆØ�MÔ! U§^¡^Ð4U×%VÒ%VØ�K‰K˜ÔÙð	Ü—8’8œBŸG™GŸL™L¨Ó:Ó;×CÑCˆDô —’˜T×"Ô"¤d§l¢l°4×&8Ô&8¼D¿LºLÈ×<NÔ<NØ�K‰K˜Öñ ð €Nøô ô 	Ø�K‰K˜ÔÛð	ús   Á=C0Ã0DÄDc                ó$   € V ^8„  d   QhR\         /# )r/   Ú
source_dirr   )r7   s   "r8   r9   r9   }   s   € ÷ ñ ¬4ñ r:   c                ó°   aa€ V P                  4       o\        \        4      oS\        4       P                  4       8X  d   S\        ,          oR VV3R llpV# )zŸcopytree ignore for --clone-all: history artifacts for any source, infrastructure
only when the source is the default profile (see the two exclude sets above).c                óR   € V ^8„  d   QhR\         R\        \         ,          R\        /# ©r/   r0   Únamesr2   r3   )r7   s   "r8   r9   Ú0_clone_all_copytree_ignore.<locals>.__annotate__…   s%   € ÷ 
ñ 
œ3ð 
¤t¬C¥yð 
´Sñ 
r:   c                 óÜ   <€  \        V 4      P                  4       S8H  p\	        W4      pV'       d"   VP                  S\        V4      ,          4       V#   \        \        3 d    R p LKi ; i©F)r   ÚresolverE   Ú
ValueErrorrM   Úupdater6   )r0   rS   Úat_rootrJ   Úroot_excludeÚsource_resolveds   &&  €€r8   Ú_ignoreÚ+_clone_all_copytree_ignore.<locals>._ignore…   se   ø€ ð	Ü˜9“o×-Ñ-Ó/°?ÑBˆGô
 *¨)Ó;ˆßØ�N‰N˜<¬#¨e«*Õ4Ô5Øˆøô œÐ$ô 	ð ŠGð	ús   ƒA ÁA+Á*A+)rW   r6   Ú_CLONE_ALL_HISTORY_EXCLUDE_ROOTÚ_get_default_hermes_homeÚ_CLONE_ALL_DEFAULT_EXCLUDE_ROOT)rO   r]   r[   r\   s   & @@r8   Ú_clone_all_copytree_ignorerb   }   sO   ù€ ð !×(Ñ(Ó*€OÜÔ6Ó7€LØÔ2Ó4×<Ñ<Ó>Ô>ØÔ7Õ7ˆ÷
ñ 
ð €Nr:   z.envrcú	auth.jsonzauth/google_oauth.jsonz.op.envÚnpmrcz.anthropic_oauth.jsonzgoogle_token.jsonzgoogle_oauth_pending.jsonzgoogle_client_secret.jsonÚgoogle_chat_user_tokensz#google_chat_user_client_secret.jsonz#google_chat_user_oauth_pending.jsonzgoogle_chat_user_token.jsonÚgoogle_chat_user_oauth_pendingzslack_tokens.jsonzhoncho.jsonz	mem0.jsonzwebhook_subscriptions.jsonzteams_pipeline_store.jsonz
mcp-tokensÚvaultzbrowser-profileÚbrowser_authúbot-desktopzbrowser-profilesÚbrowser_profilesÚpairingzplatforms/pairingzfeishu_comment_pairing.jsonzwhatsapp/sessionzplatforms/whatsapp/sessionzmatrix/storezplatforms/matrix/storezcache/bws_cache.jsonzcache/bws_cache.enc.jsonz"workspace/meetings/node_token.jsonzweixin/accountsz.copilot_jwt.jsonzruntime/photon-sidecar.jsonÚproxyzchrome-debugc              #   ór   "  € T F-  p\        VP                  4       P                  R 4      4      x € K/  	  R# 5i©Ú/N)ÚtupleÚcasefoldÚsplit©Ú.0Úps   & r8   Ú	<genexpr>rv   ¸   s+   é € Ð`ÑG_À!œu Q§Z¡Z£\×%7Ñ%7¸Ó%<×=Ð=ÓG_ùs   ‚57zpauth\.json\..+|\.env\.bak.*|config\.yaml\.(?:bak-\d{8}t\d{6}z(?:\.\d+)?|bak\.\d+|corrupt\..*|bak-pre-migrate-.*)c                ód   € V ^8„  d   QhR\         \        R3,          R\         \        R3,          /# ©r/   Úparts.r2   )rp   r4   )r7   s   "r8   r9   r9   Ä   s*   € ÷ 4ñ 4””s˜C�x•ð 4¤U¬3°¨8¥_ñ 4r:   c                 óZ   € \         ;QJ d    . R  V  4       F  NK  	  5# ! R  V  4       4      # )c              3   ó@   "  € T F  qP                  4       x € K  	  R # 5i©N)rq   )rt   Úparts   & r8   rv   Ú_fold.<locals>.<genexpr>Å   s   é € Ð3©U T—‘—�«Uùs   ‚©rp   )ry   s   &r8   Ú_foldr€   Ä   s$   € ßŒ5Ñ3©UÓ3�5Ð3ˆ5Ñ3©UÓ3Ó3Ð3r:   c                óJ   € V ^8„  d   QhR\         \        R3,          R\        /# rx   ©rp   r4   Úbool)r7   s   "r8   r9   r9   È   s&   € ÷ Qñ Q¤5¬¨c¨¥?ð Q´tñ Qr:   c                ó  a€ \        V 4      o\        S4      ^8X  d%   \        P                  S^ ,          4      '       d   R# \        ;QJ d#    V3R l\
         4       F  '       g   K   R# 	  R# ! V3R l\
         4       4      # )z¯True for a PROFILE_CREDENTIAL_PATHS store, anything below one, or a root copy of one.
Case-folded: on a case-insensitive filesystem ``Platforms/Pairing`` IS the pairing store.Tc              3   óF   <"  € T F  pSR \        V4       V8H  x € K  	  R # 5ir|   ©Úlen©rt   ÚstoreÚfoldeds   & €r8   rv   Ú*profile_path_is_private.<locals>.<genexpr>Î   s#   øé € ÐPÑ9O°ˆv�k”s˜5“zÐ" eÖ+Ó9Oùs   ƒ!F)r€   r‡   Ú_STORE_COPY_REÚ	fullmatchÚanyÚ_CREDENTIAL_PATH_PARTS©ry   rŠ   s   &@r8   Úprofile_path_is_privater‘   È   s\   ø€ ô �5‹\€FÜ
ˆ6ƒ{�aÔœN×4Ñ4°V¸AµY×?Ò?Ùß‹3ÔPÕ9OÓP�3Œ3ÐPŠ3ÐPˆ3ÔPÕ9OÓPÓPÐPr:   c                óJ   € V ^8„  d   QhR\         \        R3,          R\        /# rx   r‚   )r7   s   "r8   r9   r9   Ñ   s&   € ÷ oñ o¬u´S¸#°X­ð oÄ4ñ or:   c                óž   a€ \        V 4      o\        ;QJ d#    V3R l\         4       F  '       g   K   R# 	  R# ! V3R l\         4       4      # )zRTrue for a strict ancestor of a store (``platforms`` holds ``platforms/pairing``).c              3   ó„   <"  € T F5  p\        V4      \        S4      8„  ;'       d    VR \        S4       S8H  x € K7  	  R # 5ir|   r†   rˆ   s   & €r8   rv   Ú6profile_path_contains_private_store.<locals>.<genexpr>Ô   s;   øé € ÐnÑWmÈeŒs�5‹zœC ›KÑ'×IÐI¨E°,´3°v³;Ð,?À6Ñ,IÔIÓWmùs
   ƒ"A ¦A TF)r€   rŽ   r�   r�   s   &@r8   Ú#profile_path_contains_private_storer–   Ñ   s7   ø€ ä�5‹\€Fß‹3ÔnÕWmÓn�3Œ3ÐnŠ3Ðnˆ3ÔnÕWmÓnÓnÐnr:   zhermes_state.dbzresponse_store.dbzresponse_store.db-shmzresponse_store.db-walz	auth.lockÚactive_profilez.update_checkzsource-checksz
errors.logz.hermes_historyÚimage_cacheÚaudio_cacheÚdocument_cacheÚbrowser_screenshotsÚ	sandboxesú.cursorrulesc                ó$   € V ^8„  d   QhR\         /# ©r/   r2   r   )r7   s   "r8   r9   r9     s   € ÷ 3ñ 3œDñ 3r:   c                 ó$   € \        4       R,          # )zšNamed-profiles root, anchored to the hermes root (NOT the current HERMES_HOME, which
may itself be a profile) so ``coder profile list`` sees all profiles.r"   ©r`   © r:   r8   Ú_get_profiles_rootr£     s   € ô $Ó%¨
Õ2Ð2r:   c                ó$   € V ^8„  d   QhR\         /# rŸ   r   )r7   s   "r8   r9   r9   !  s   € ÷ %ñ %¤$ñ %r:   c                 ó   € ^ RI Hp  V ! 4       # )zzDefault (pre-profile) HERMES_HOME: ``~/.hermes``, or HERMES_HOME itself in
Docker/custom deployments (e.g. ``/opt/data``).©Úget_default_hermes_root)Úhermes_constantsr§   r¦   s    r8   r`   r`   !  s   € õ 9Ù"Ó$Ð$r:   c                ó$   € V ^8„  d   QhR\         /# rŸ   r   )r7   s   "r8   r9   r9   (  s   € ÷ 9ñ 9¤$ñ 9r:   c                  ó$   € \        4       R ,          # )r—   r¡   r¢   r:   r8   Ú_get_active_profile_pathr«   (  s   € Ü#Ó%Ð(8Õ8Ð8r:   c                ó$   € V ^8„  d   QhR\         /# rŸ   r   )r7   s   "r8   r9   r9   ,  s   € ÷ *ñ *œ$ñ *r:   c                  óH   € \         P                  ! 4       R ,          R,          # )z.localr#   )r   r   r¢   r:   r8   Ú_get_wrapper_dirr®   ,  s   € Ü�9Š9‹;˜Õ! EÕ)Ð)r:   c                ó0   € V ^8„  d   QhR\         R\        /# ©r/   Úaliasr2   ©r4   r   )r7   s   "r8   r9   r9   0  s   € ÷ Wñ Wœð W¤ñ Wr:   c                ód   € \        4       \        P                  R8X  d   V  R2,          # T ,          # )zQWrapper script path for *alias*: ``<alias>.bat`` on Windows, bare name elsewhere.Úwin32ú.bat)r®   ÚsysÚplatform)r±   s   &r8   Ú_wrapper_pathr¸   0  s*   € äÓ´3·<±<À7Ô3J E 7¨$ ÕVÐVÐPUÕVÐVr:   c                óF   € V ^8„  d   QhR\         R\        \        ,          /# r°   ©r4   r   r   )r7   s   "r8   r9   r9   5  s"   € ÷ Eñ EœSð E¤X¬d¥^ñ Er:   c                ó¢   € \         P                  R8X  d   \        V 4      \        4       V ,          .M\        V 4      .p\	        R V 4       R4      # )z\The Hermes wrapper for *alias*: :func:`_wrapper_path`, else a pre-``.bat`` bare Windows one.r´   c              3   óL   "  € T F  p\        V4      '       g   K  Vx € K  	  R # 5ir|   )Ú_is_our_wrapperrs   s   & r8   rv   Ú$_find_our_wrapper.<locals>.<genexpr>8  s   é € Ð=™J�q¬/¸!×*<—’›Jùs   ‚$š
$N)r¶   r·   r¸   r®   Únext)r±   Ú
candidatess   & r8   Ú_find_our_wrapperrÁ   5  sE   € äGJÇ|Á|ÐW^ÔG^”- Ó&Ô(8Ó(:¸UÕ(BÑCÔerÐsxÓeyÐdz€JÜÑ=™JÓ=¸tÓDÐDr:   c                ó0   € V ^8„  d   QhR\         R\        /# ©r/   rB   r2   ©r   rƒ   )r7   s   "r8   r9   r9   ;  s   € ÷ ñ œ$ð ¤4ñ r:   c                óÀ   €  \        V RR7      ;_uu_ 4       pRVP                  \        4      9   uuRRR4       #   + '       g   i     R# ; i  \         d     R# i ; i)zQTrue when *path* reads as a Hermes-generated wrapper (``hermes -p`` in its head).ú	utf-8-sig©Úencodingz	hermes -pNF)ÚopenÚreadÚ_WRAPPER_READ_LIMITÚ	Exception)rB   Úfs   & r8   r½   r½   ;  sH   € ðÜ�$ ×-Õ-°Ø !§&¡&Ô)<Ó"=Ñ=÷ .×-×-Ó-ûäô Úðús+   ‚A —:¯
A ºA	ÁA ÁA ÁAÁAc                ó0   € V ^8„  d   QhR\         R\        /# ©r/   Úcanonr2   ©r4   ÚFileNotFoundError)r7   s   "r8   r9   r9   D  s   € ÷ qñ q¤#ð qÔ*;ñ qr:   c                 ó$   € \        R V  RV  24      # )ú	Profile 'z8' does not exist. Create it with: hermes profile create ©rÒ   ©rÐ   s   &r8   Ú_missing_profile_errorr×   D  s   € Ü˜y¨¨Ð/gÐhmÐgnÐoÓpÐpr:   c                ó0   € V ^8„  d   QhR\         R\        /# rÏ   rÑ   )r7   s   "r8   r9   r9   H  s   € ÷ iñ i¤#ð iÔ*;ñ ir:   c                ó    € \        RV  R24      # )zKFor delete/rename/export of a name that matches no profile (likely a typo).zNo profile named 'z.'. See your profiles with: hermes profile listrÕ   rÖ   s   &r8   Ú_unknown_profile_errorrÚ   H  s   € äÐ1°%°Ð8fÐgÓhÐhr:   c                ó0   € V ^8„  d   QhR\         R\        /# rÏ   )r4   ÚFileExistsError)r7   s   "r8   r9   r9   M  s   € ÷ ñ ¤ð ¬ñ r:   c                 ó&   € \        R V  RV  R24      # )zA profile named 'z8' already exists. Switch to it with `hermes profile use zK`, see all profiles with `hermes profile list`, or choose a different name.)rÜ   rÖ   s   &r8   Ú_profile_exists_errorrÞ   M  s,   € ÜØ
˜E˜7Ð"ZÐ[`ÐZað bSð 	Sóð r:   zaUse lowercase letters, numbers, '-' or '_', starting with a letter or number, up to 64 charactersc                ó0   € V ^8„  d   QhR\         R\         /# ©r/   Únamer2   ©r4   )r7   s   "r8   r9   r9   Z  s   € ÷ Gñ G¤ð G¬ñ Gr:   c                óÔ   € \         P                  ! RRV P                  4       P                  4       4      P                  R4      R,          p\        P                  V4      '       d   V# R# )ziBest-effort valid id derived from *name* (``'My Work'`` -> ``'my-work'``); ``my-work`` if nothing usable.z[^a-z0-9_-]+Ú-z-_:Né@   Nzmy-work)ÚreÚsubÚstripÚlowerÚ_PROFILE_ID_REÚmatch)rá   Ú	candidates   & r8   Ú_suggest_profile_namerí   Z  sN   € ä—’�¨¨T¯Z©Z«\×-?Ñ-?Ó-AÓB×HÑHÈÓNÈsÕS€IÜ&×,Ñ,¨Y×7Ò7ˆ9ÐF¸YÐFr:   c                ó0   € V ^8„  d   QhR\         R\        /# rà   )r4   rX   )r7   s   "r8   r9   r9   `  s   € ÷ ñ ¤cð ¬jñ r:   c           
      óP   € \        V 4      p\        V : R \         RV RV R24      # )z is not a valid profile name. z (for example: z#). Then run `hermes profile create z`.)rí   rX   Ú_PROFILE_NAME_RULE)rá   Ú
suggestions   & r8   Ú_invalid_profile_name_errorrò   `  sA   € Ü& tÓ,€JÜØ‰(Ð0Ô1CÐ0DÀOÐT^ÐS_ð `+Ø+5¨,°bð	:óð r:   c                ó0   € V ^8„  d   QhR\         R\         /# rà   râ   )r7   s   "r8   r9   r9   j  s   € ÷ ñ ¤ð ¬ñ r:   c                ó  € \        V \        4      '       g&   \        R\        V 4      P                   RV : 24      hV P                  4       pV'       g   \        R4      hVP                  4       R8X  d   R# VP                  4       # )u  Canonical profile id used on disk and in ``-p`` argv: lowercase, ``default`` matched
case-insensitively. Dashboards/tools may pass title-cased labels â€” normalize before
validation, assignment, and subprocess spawn.

Named profiles are stored lowercase under ``profiles/<id>/``. The special
alias ``default`` is matched case-insensitively (``Default`` â†’ ``default``).
Dashboards and tools may pass title-cased display labels; normalize before
validation, assignment, and subprocess spawn (see issue #18498).

Raises ``ValueError`` for non-string input: a numeric profile id (e.g. a
DB row id or a falsy sentinel) silently coerced via ``str()`` becomes a
real on-disk profile directory (``profiles/0/``, #88842). Callers that
hold a numeric id must resolve it to an actual profile name first.
z#profile name must be a string, got ú: zprofile name cannot be emptyÚdefault)Ú
isinstancer4   rX   ÚtypeÚ__name__rè   rq   ré   )rá   Ústrippeds   & r8   Únormalize_profile_namerû   j  sy   € ô �dœC× Ò ÜØ1Ü�D‹z×"Ñ"Ð# 2 d¡Xð/ó
ð 	
ð �z‰z‹|€HßÜÐ7Ó8Ð8Ø×ÑÓ˜iÔ'ÙØ�>‰>ÓÐr:   c                ó(   € V ^8„  d   QhR\         RR/# ©r/   rá   r2   Nrâ   )r7   s   "r8   r9   r9   †  s   € ÷ 
ñ 
¤ð 
¨ñ 
r:   c                óš   € V R8X  d   R# \         P                  V 4      '       g   \        V 4      hV \        9   d   \	        RV : R24      hR# )uÜ  Raise ``ValueError`` unless *name* is a valid profile id (strict as-given lowercase â€”
normalize mixed-case input first) and not in ``_RESERVED_NAMES``; ``default`` passes.

Callers that accept mixed-case or title-cased input from users (dashboard UI, CLI args) should call
:func:`normalize_profile_name` first. This separation keeps validate honest about what the on-disk
directory name must look like, while ingress-point normalization handles UX flexibility (see #18498).
rö   NzProfile name uz    is reserved â€” it collides with either the Hermes installation itself or a common system binary.  Pick a different name.)rê   rë   rò   Ú_RESERVED_NAMESrX   ©rá   s   &r8   Úvalidate_profile_namer  †  sV   € ð ˆyÔÙÜ×Ñ ×%Ò%Ü)¨$Ó/Ð/ØŒÔÜØ˜D™8ð $%ð &ó
ð 	
ñ r:   c                ó(   € V ^8„  d   QhR\         RR/# rý   râ   )r7   s   "r8   r9   r9   š  s   € ÷ Pñ Pœcð P dñ Pr:   c                ój   € \         P                  V 4      '       g   \        RV : R\         R24      hR# )z¢Raise ``ValueError`` unless *name* is a safe wrapper filename: it is used verbatim
under ``~/.local/bin``, so ``../../.bashrc`` must never escape the wrapper dir.zInvalid alias name z. Ú.N)rê   rë   rX   rð   r   s   &r8   Úvalidate_alias_namer  š  s7   € ô ×Ñ ×%Ò%ÜÐ.¨t©h°bÔ9KÐ8LÈAÐNÓOÐOñ &r:   c                ó0   € V ^8„  d   QhR\         R\         /# rà   râ   )r7   s   "r8   r9   r9   ¡  s   € ÷ ñ ”sð œsñ r:   c                ó2   € \        V 4      p\        V4       V# )z;normalize + validate in one step; returns the canonical id.)rû   r  ©rá   rÐ   s   & r8   Ú_canon_validr	  ¡  s   € ä" 4Ó(€EÜ˜%Ô Ø€Lr:   c                óR   € V ^8„  d   QhR\         R\        \         \        3,          /# rà   )r4   rp   r   )r7   s   "r8   r9   r9   ¨  s#   € ÷ ñ ¤ð ¬¬c´4¨iÕ(8ñ r:   c                óv   € \        V 4      p\        V4      pVP                  4       '       g   \        V4      hW3# )zN``(canon, profile_dir)`` for an existing profile; FileNotFoundError otherwise.)r	  Úget_profile_dirÚis_dirrÚ   ©rá   rÐ   Úprofile_dirs   &  r8   Ú_existing_profile_dirr  ¨  s9   € ä˜Ó€EÜ! %Ó(€KØ×Ñ×ÒÜ$ UÓ+Ð+ØÐÐr:   c                ó0   € V ^8„  d   QhR\         R\        /# rà   r²   )r7   s   "r8   r9   r9   ±  s   € ÷ (ñ (œ#ð (¤$ñ (r:   c                ó¨   € \        V 4      pVR8X  d   \        4       # \        P                  V4      '       g   \	        V4      h\        4       V,          # )z4Resolve a profile name to its HERMES_HOME directory.rö   )rû   r`   rê   rë   rò   r£   r  s   & r8   r  r  ±  sI   € ä" 4Ó(€EØ�	ÔÜ'Ó)Ð)ô ×Ñ ×&Ò&Ü)¨%Ó0Ð0ÜÓ %Õ'Ð'r:   c                ó0   € V ^8„  d   QhR\         R\        /# rà   ©r4   rƒ   )r7   s   "r8   r9   r9   À  s   € ÷ 	.ñ 	.œð 	.¤ñ 	.r:   c                ó|   €  \        V 4      p\        V4      pTR8X  d   R# \        T4      #   \         d     R# i ; i)z?Check whether a live (non-tombstoned) profile directory exists.Frö   T)rû   r  rX   r   r  s   &  r8   Úprofile_existsr  À  sG   € ðÜ& tÓ,ˆÜ% eÓ,ˆð �	ÔÙÜ  Ó-Ð-øô	 ô Úðús   ‚, ¬;º;c                óJ   € V ^8„  d   QhR\         R\        R,          R\        /# )r/   rá   r   Nr2   ©r4   r   rƒ   )r7   s   "r8   r9   r9   Ì  s%   € ÷ ñ œsð ¬$°­+ð Äñ r:   c                ó  €  \        V 4      pVf   ^ RIHp V! 4       p\        V4      P	                  4       P                  RR7      \        V4      P	                  4       P                  RR7      8H  #   \         d     R# i ; i)aM  True when *name* refers to the profile served from *home* (default: current home).

Lets single-profile gateways decide whether a ``/p/<profile>/`` URL prefix is
self-referential (safe on the bare route) or names a different profile, which must fail
closed rather than silently resolve the owner's config. Invalid names return False.©Úget_hermes_homeF)Ústrict)r  r¨   r  r   Ú
expanduserrW   rÌ   )rá   r   Útargetr  s   &&  r8   Úprofile_matches_homer  Ì  su   € ðÜ  Ó&ˆØŠ<Ý8Ù"Ó$ˆDÜ�F‹|×&Ñ&Ó(×0Ñ0¸Ð0Ó>Ä$ÀtÃ*×BWÑBWÓBY×BaÑBaÐinÐBaÓBoÑoÐoøÜô Úðús   ‚A.A1 Á1B Á?B Ú	live_onlyTc                óF   € V ^8„  d   QhR\         R\        \        ,          /# )r/   r   r2   )rƒ   r5   r   )r7   s   "r8   r9   r9   Ü  s   € ÷ ñ ¬4ð ¼4Ä½:ñ r:   c                ó¢  € \        4       pVP                  4       '       g   . # \        VP                  4       4       Uu. uF…  pVP                  4       '       g   K  VP                  R8w  g   K.  \
        P                  VP                  4      '       g   KU  \        V4      '       g   Kh  V '       d   \        V4      '       d   Kƒ  VNK‡  	  up# u upi )u¿  Sorted named-profile dirs (valid ids, never ``default``); ``live_only`` skips tombstones.

A dir is a profile only when it carries an identity marker (``named_profile_has_identity``):
cron/logging side-effects and pre-tombstone ghost shells leave marker-less dirs that must
not be listed, served, ticked, or ``.env``-seeded â€” that seeding is what turned a ghost
shell into a "real" profile on the next ``hermes update`` (#95188, #94823, #99392).rö   )	r£   r  ÚsortedÚiterdirrá   rê   rë   r   r   )r   Úprofiles_rootrK   s   $  r8   Ú_iter_named_profile_dirsr&  Ü  s©   € ô 'Ó(€MØ×Ñ×!Ò!Øˆ	ä! -×"7Ñ"7Ó"9Ô:óÙ:�%Ø�<‰<�>ô 	à�J‰J˜)Ñ#ô 	ô × Ñ  §¡×,ô 	ô ' u×-ô	 	÷
 Ô7¸×>÷ 	ˆÑ:ñð ùò s)   ¾CÁCÁ."CÂCÂ(CÂ0CÃCc                ó:   € V ^8„  d   QhR\         \        ,          /# rŸ   ©r5   r4   )r7   s   "r8   r9   r9   ð  s   € ÷ ñ œD¤�Iñ r:   c                 óÊ   € R.p \         P                  ! \        4      ;_uu_ 4        V P                  R \	        4        4       4       RRR4       V #   + '       g   i     T # ; i)ug  Cheap name-only listing (``default`` + LIVE profile dirs). Unlike :func:`list_profiles` this
reads NO per-profile config â€” safe for hot paths (cron target listings, create validation).
Tombstoned shells are skipped like everywhere else: a stale process that re-mkdirs a deleted
profile's directory must not resurface it as a ``bot-chat:<name>`` cron target.rö   c              3   ó8   "  € T F  qP                   x € K  	  R # 5ir|   r   ©rt   rK   s   & r8   rv   Ú%list_profile_names.<locals>.<genexpr>÷  s   é € ÐHÑ-G E—Z–ZÓ-Gùs   ‚N)Ú
contextlibÚsuppressrE   Úextendr&  )rS   s    r8   Úlist_profile_namesr0  ð  sJ   € ð
 ˆK€EÜ	×	Ò	œW×	%Õ	%Ø�‰ÑHÔ-EÔ-GÓHÔH÷ 
&à€L÷ 
&Ö	%à€Lús   ¦!AÁA"	c                óF   € V ^8„  d   QhR\         R\        \         ,          /# rà   ©r4   r   )r7   s   "r8   r9   r9   ý  s   € ÷ ñ ¤ð ¬´­ñ r:   c           
     ó`  € \        V 4      p \        V4       T\        9   d   RT R2# T\
        9   d   RT R2#  \        P                  ! \        P                  R8X  d   RMRT.RRR	R
^RR7      pTP                  ^ 8X  dg   TP                  P                  4       P                  4       ^ ,          p\        T4      pT\        T4      8X  d   \        T4      '       d   R# RT RT R2#  R#   \         d   p\        T4      u Rp?# Rp?ii ; i  \         \        P"                  3 d     R# i ; i)zGReturn a human-readable collision message, or None if the name is safe.NÚ'z' is a reserved namez$' conflicts with a hermes subcommandr´   ÚwhereÚwhichTúutf-8ÚreplaceF)Úcapture_outputÚtextrÈ   ÚerrorsÚtimeoutÚcheckz&' conflicts with an existing command (Ú))rû   r  rX   r4   rÿ   Ú_HERMES_SUBCOMMANDSÚ
subprocessÚrunr¶   r·   Ú
returncodeÚstdoutrè   Ú
splitlinesr¸   r½   rÒ   ÚTimeoutExpired)rá   rÐ   ÚexcÚresultÚexisting_pathÚexpecteds   &     r8   Úcheck_alias_collisionrJ  ý  s3  € ä" 4Ó(€EðÜ˜EÔ"ð ”ÔØ�5�'Ð-Ð.Ð.ØÔ#Ô#Ø�5�'Ð=Ð>Ð>ðÜ—’ÜŸ™¨Ô/‰W°W¸eÐDØ d°WÀYÐXYØô
ˆð
 ×Ñ Ô!Ø"ŸM™M×/Ñ/Ó1×<Ñ<Ó>¸qÕAˆMÜ$ UÓ+ˆHØ¤ H£Ô-´/À(×2KÒ2KÙØ�u�gÐCÀMÀ?ÐRSÐTÐTð "ñ øô) ô Ü�3‹x�ûðûô$ œz×8Ñ8Ð9ô ØÙðús5   �C+ »B"D ÃD Ã+DÃ6
DÄ DÄDÄD-Ä,D-c                ó$   € V ^8„  d   QhR\         /# rŸ   ©rƒ   )r7   s   "r8   r9   r9     s   € ÷ Sñ S¤ñ Sr:   c                  ó¤   € \        \        4       4      \        P                  P	                  R R4      P                  \        P                  4      9   # )ÚPATHÚ )r4   r®   r@   ÚenvironÚgetrr   Úpathsepr¢   r:   r8   Ú_is_wrapper_dir_in_pathrS    s4   € ÜÔÓ!Ó"¤b§j¡j§n¡n°V¸RÓ&@×&FÑ&FÄrÇzÁzÓ&RÑRÐRr:   c                óh   € V ^8„  d   QhR\         R\        \         ,          R\        \        ,          /# )r/   rá   r  r2   rº   )r7   s   "r8   r9   r9     s)   € ÷ ñ ¤ð ¬X´c­]ð ÄhÌtÅnñ r:   c                ó   € \        V 4      pV'       d   \        V4      MTp\        V4       \        4       p VP                  RRR7       \        T4      p \        P                  R8X  d   TP                  RT R2R	R
7       T# \        P                  ! R4      ;'       g    RpTP                  R\        P                  ! T4       RT R2R	R
7       TP                  TP                  4       P                   \        P"                  ,          \        P$                  ,          \        P&                  ,          4       T#   \         d   p\        RT RT 24        Rp?R# Rp?ii ; i  \         d   p\        RT RT 24        Rp?R# Rp?ii ; i)z¤Create ``~/.local/bin/<name>`` activating profile *target* (default: *name*), so a
custom alias can point at a differently-named profile without a post-hoc rewrite.T©ÚparentsÚexist_oku   âš  Could not create rõ   Nr´   z@echo off
hermes -p z %*
r7  rÇ   Úhermesz#!/bin/sh
exec z -p z "$@"
u    âš  Could not create wrapper at )rû   r  r®   ÚmkdirrE   Úprintr¸   r¶   r·   Ú
write_textÚshutilr6  ÚshlexÚquoteÚchmodrF   rD   ÚS_IEXECÚS_IXGRPÚS_IXOTH)rá   r  rÐ   ÚprofileÚwrapper_dirÚeÚwrapper_pathÚ
hermes_exes   &&      r8   Úcreate_wrapper_scriptri    sg  € ô # 4Ó(€Eß06Ô$ VÔ,¸E€GÜ˜ÔÜ"Ó$€KðØ×Ñ $°ÐÔ6ô ! Ó'€Lð
Ü�<‰<˜7Ô"Ø×#Ñ#Ð&=¸g¸YÀgÐ$NÐY`Ð#Ôað
 Ðô  Ÿš hÓ/×;Ð;°8ˆJØ×#Ñ#Ð&6´u·{²{À:Ó7NÐ6OÈtÐT[ÐS\Ð\cÐ$dÐovÐ#ÔwØ×Ñ˜|×0Ñ0Ó2×:Ñ:¼T¿\¹\ÕIÌDÏLÉLÕXÔ[_×[gÑ[gÕgÔhØÐøô ô ÜÐ% k ]°"°Q°CÐ8Ô9Ýûðûô ô ÜÐ0°°¸bÀÀÐDÔEÝûðús<   ·D< Á-E& ÂE& Â!BE& Ä<E#ÅEÅE#Å&FÅ1FÆFc                ó0   € V ^8„  d   QhR\         R\        /# rà   r  )r7   s   "r8   r9   r9   7  s   € ÷ ñ ¤ð ¬ñ r:   c                ó  € \        V 4      p \        V4       \        T4      pTf   R# \        P
                  ! \        4      ;_uu_ 4        TP                  4         RRR4       R#   \         d     R# i ; i  + '       g   i     R# ; i)zARemove the wrapper script for a profile. Returns True if removed.FNT)rû   r  rX   rÁ   r-  r.  rÌ   Úunlink)rá   rÐ   rg  s   &  r8   Úremove_wrapper_scriptrm  7  sx   € ä" 4Ó(€EðÜ˜EÔ"ô % UÓ+€LØÒÙÜ	×	Ò	œY×	'Õ	'Ø×ÑÔØ÷ 
(Ñ	'øô ô Úðú÷ 
(Ö	'ñ ús   �A' ÁA9Á'A6Á5A6Á9B
	c                ó(   € V ^8„  d   QhR\         RR/# ©r/   r  r2   Nr   )r7   s   "r8   r9   r9   I  s   € ÷ .ñ .´Tð .¸dñ .r:   c                ód  € V R,          P                  4       '       g   R# \        P                  ! \        4      ;_uu_ 4        ^ RIHpHp ^ RIHpH	p V! \        V 4      4      p V! 4       w  rgWg8  d   V! RRR7       V! V4        RRR4       R#   T! T4       i ; i  + '       g   i     R# ; i)z°Migrate a copied config.yaml to the current schema (non-interactive, scoped to the new
profile); otherwise the first desktop/doctor view shows a scary ``v0 -> latest`` warning.úconfig.yamlN©Úreset_hermes_home_overrideÚset_hermes_home_override)Úcheck_config_versionÚmigrate_configFT)ÚinteractiveÚquiet)Úexistsr-  r.  rÌ   r¨   rs  rt  Úhermes_cli.configru  rv  r4   )r  rs  rt  ru  rv  ÚtokenÚcurrent_verÚ
latest_vers   &       r8   Ú#_migrate_profile_config_if_outdatedr~  I  s‹   € ð ˜-Õ'×/Ñ/×1Ò1Ùô 
×	Ò	œY×	'Õ	'ßYßJÙ(¬¨[Ó)9Ó:ˆð	.Ù&:Ó&<Ñ#ˆKØÔ'Ù¨5¸Õ=á& uÕ-÷ 
(Ñ	'øñ ' uÕ-ú÷ 
(×	'Ð	'ús$   Á"BÁ%BÁ>BÂ
BÂBÂB/	c                óF   € V ^8„  d   QhR\         R\        \         ,          /# ©r/   Úprofile_namer2   r2  )r7   s   "r8   r9   r9   \  s"   € ÷ Gñ G¬ð G´¼#µñ Gr:   c                óF   € \        4       P                  \        V 4      4      # )a	  Alias name of the wrapper activating *profile_name*, or None. For listing ALL profiles
prefer :func:`build_alias_map`: per-profile calls re-read every wrapper N times (O(N*M)),
which on a ``~/.local/bin`` full of large binaries meant multi-second ``list_profiles``.)Úbuild_alias_maprQ  rû   )r�  s   &r8   Úfind_alias_for_profiler„  \  s   € ô Ó× Ñ Ô!7¸Ó!EÓFÐFr:   i    c                óF   € V ^8„  d   QhR\         \        \        3,          /# rŸ   )Údictr4   )r7   s   "r8   r9   r9   j  s   € ÷ %ñ %œœc¤3˜h�ñ %r:   c                 óŠ  € \        4       p / pV P                  4       '       g   V# \        P                  R8H  pRp\	        V P                  4       4       EF?  pVP                  4       '       g   K  VP                  '       d   V'       d   VP                  R8X  g   KI   \        VRRRR7      ;_uu_ 4       pVP                  \        4      pRRR4       XP                  T4      pTR
8X  d   K™  Yg\        T4      ,           R pTP                  4       '       d(   TP!                  R^4      ^ ,          P                  4       MR	p	T	'       g   Kö  \#        T	4      p	T'       d   TP$                  MTP&                  p
Y©8X  d   TP)                  Yš4       EK;  Y¡T	&   EKB  	  V#   + '       g   i     L×; i  \        \        3 d     EKn  i ; i)a  Single-pass reverse map ``{canonical_profile -> alias_name}``.

Scans the wrapper dir ONCE, reading only a head slice of each candidate and skipping
binaries. A custom alias (file name != profile) wins over the profile-named wrapper;
deterministic via sorted iteration.r´   z
hermes -p rµ   ÚrrÆ   r  )rÈ   r;  NrO  éÿÿÿÿ)r®   r  r¶   r·   r#  r$  Úis_fileÚsuffixrÉ   rÊ   rË   rE   ÚUnicodeDecodeErrorÚfindr‡   rè   rr   rû   Ústemrá   Ú
setdefault)re  rG  Ú
is_windowsÚprefixrK   rÍ   ÚcontentÚidxÚrestrÐ   r±   s              r8   rƒ  rƒ  j  s_  € ô #Ó$€KØ€FØ×Ñ×ÒØˆÜ—‘ Ñ(€JØ€FÜ˜×+Ñ+Ó-×.ˆØ�}‰}�ŠÙà�<�<ˆ<§°·±ÀÔ0FÙð	Ü�e˜S¨;¸x×HÕHÈAØŸ&™&Ô!4Ó5�÷ Ið �l‰l˜6Ó"ˆØ�"Œ9ÙØœS ›[Õ(Ð)Ð*ˆà26·*±*·,²,�—
‘
˜4 Ó# AÕ&×,Ñ,Ô.ÀBˆßÙÜ& uÓ-ˆß(�—
’
¨e¯j©jˆØŒ>Ø×Ñ˜e×+à!�5ŒMñ1 /ð2 €M÷% I×HûäÔ+Ð,ô 	Ûð	ús0   ÂF,Â4FÃ
F,ÆF)Æ$F,Æ)F,Æ,GÇGc                   óv   a € ] tR tRt o RtRtRtRt^ tRt	Rt
RtRtRtRtRtRtRt]! ]R7      tV 3R ltRtV tR# )	ÚProfileInfoi”  z$Summary information about a profile.NFrO  )Údefault_factoryc                ór  <€ V ^8„  d   Qh/ S[ ;R&   S[;R&   S[;R&   S[;R&   S[S[ ,          ;R&   S[S[ ,          ;R&   S[;R&   S[;R&   S[S[,          ;R	&   S[S[ ,          ;R
&   S[S[ ,          ;R&   S[S[ ,          ;R&   S[S[ ,          ;R&   S[ ;R&   S[;R&   S[ ;R&   S[ ;R&   S[S[ ,          ;R&   # )r/   rá   rB   Ú
is_defaultÚgateway_runningÚmodelÚproviderÚhas_envÚskill_countÚ
alias_pathÚ
alias_nameÚdistribution_nameÚdistribution_versionÚdistribution_sourceÚdescriptionÚdescription_autoÚdisplay_nameÚ	bot_titleÚprevious_names)r4   r   rƒ   r   Úintr5   )r7   Ú__classdict__s   "€r8   r9   ÚProfileInfo.__annotate__”  s  ø‡ ‚ ñ �Iñ ñ �Jñ	 ñ
 Ññ ñ Ññ ñ ‘C�=Ññ ñ ‘s�mÑ"ñ ñ Ññ ñ Ññ ñ ™•Ñ%ñ ñ ™•Ñ$ñ ñ   ¡•}Ñ+ñ! ñ" #¡3�-Ñ.ñ# ñ$ "¡#�Ñ-ñ% ñ* Ññ+ ñ0 Ñ"ñ1 ñ4 Ññ5 ñ: Ññ; ñB ™•IÑ;òC r:   r¢   )rù   Ú
__module__Ú__qualname__Ú__firstlineno__Ú__doc__r›  rœ  r�  rž  rŸ  r   r¡  r¢  r£  r¤  r¥  r¦  r§  r   r5   r¨  Ú__annotate_func__Ú__static_attributes__Ú__classdictcell__)rª  s   @r8   r–  r–  ”  sk   ø‡ € á.ð
  €EØ"€HØ€GØ€KØ!%€Jð !%€Jà'+ÐØ*.ÐØ)-Ðð €Kð #Ðà€Lð €Iñ !&°dÔ ;€N÷C ƒ r:   r–  c                óF   € V ^8„  d   QhR\         R\        \        ,          /# rÃ   )r   r   r†  )r7   s   "r8   r9   r9   ¸  s   € ÷ 	4ñ 	4œ$ð 	4¤8¬D¥>ñ 	4r:   c                óê   € V P                  4       '       g   R#  ^ RIpVP                  V P                  RR7      4      ;'       g    / p\        T\        4      '       d   T# R#   \         d     R# i ; i)zQReturn the mapping in a YAML file, or None when missing/unreadable/not a mapping.NrÆ   rÇ   )rŠ  Úhermes_yamlÚ	safe_loadÚ	read_textrÌ   r÷   r†  )rB   ÚyamlÚdatas   &  r8   Ú_load_yaml_dictrº  ¸  sf   € à�<‰<�>Š>ÙðÛ"Ø�~‰~˜dŸn™n°k˜nÓBÓC×IÐIÀrˆô ˜d¤D×)Ò)ˆ4Ð3¨tÐ3øô ô Úðús   š+A# ÁA# Á#A2Á1A2i   c                óF   € V ^8„  d   QhR\         R\        \        ,          /# rÃ   )r   r   rp   )r7   s   "r8   r9   r9   Î  s   € ÷ 9ñ 9¤$ð 9¬8´E­?ñ 9r:   c                óŽ   €  V P                  4       pTP                  TP                  TP                  3#   \         d     R# i ; i)z±``(mtime_ns, size, inode)``, or None when the file is absent. The atomic writers rename a
temp file into place, so a rewrite always lands a new inode even within one mtime tick.N)rF   rE   Úst_mtime_nsÚst_sizeÚst_ino)rB   rF   s   & r8   Ú_profile_file_signaturerÀ  Î  sC   € ðØ�y‰y‹{ˆð ×Ñ˜dŸl™l¨D¯K©KÐ8Ð8øô ô Úðús   ‚5 µAÁAc                ó0   € V ^8„  d   QhR\         R\        /# )r/   rB   Úkind©r   r4   )r7   s   "r8   r9   r9   Ø  s   € ÷ ñ œtð ¬3ñ r:   c                ó&  € \        V 4      pVf   V! 4       # \        V 4      V3p\        P                  V4      pVe   V^ ,          V8X  d
   V^,          # V! 4       p\	        \        4      \
        8¼  d   \        P                  4        W63\        V&   V# )zž``compute()``'s value, reused while *path* has not changed. A missing file is never cached:
reading it costs nothing, and one created later must be picked up.)rÀ  r4   Ú_PROFILE_FILE_CACHErQ  r‡   Ú_PROFILE_FILE_CACHE_MAXÚclear)rB   rÂ  ÚcomputeÚ	signatureÚkeyÚcachedÚvalues   &&&    r8   Ú_cached_profile_readrÍ  Ø  sŠ   € ô (¨Ó-€IØÒÙ‹yÐÜˆt‹9�dÐ
€CÜ ×$Ñ$ SÓ)€FØÒ˜f Q�i¨9Ô4Ø�a�yÐÙ‹I€EÜ
ÔÓÔ#:Ô:Ü×!Ñ!Ô#Ø )Ð1Ô˜ÑØ€Lr:   c                ó0   € V ^8„  d   QhR\         R\        /# ©r/   r  r2   ©r   rp   )r7   s   "r8   r9   r9   é  s   € ÷ Zñ Z¬ð Z´%ñ Zr:   c                ó>   a € R V 3R llp\        S R,          RV4      # )zY``(name, version, source)`` from ``distribution.yaml``; ``(None, None, None)`` if absent.c                ó$   € V ^8„  d   QhR\         /# rŸ   r   )r7   s   "r8   r9   Ú-_read_distribution_meta.<locals>.__annotate__ë  s   € ÷ Iñ I”5ñ Ir:   c                  ó˜   <€ \        SR ,          4      p V f   R# V P                  R4      V P                  R4      V P                  R4      3# )údistribution.yamlrá   ÚversionÚsource)NNN)rº  rQ  )r¹  r  s    €r8   Ú_readÚ&_read_distribution_meta.<locals>._readë  sF   ø€ Ü˜{Ð-@Õ@ÓAˆØŠ<Ø#Ð#Ø�x‰x˜Ó §¡¨)Ó!4°d·h±h¸xÓ6HÐHÐHr:   rÕ  Údistribution)rÍ  )r  rØ  s   f r8   Ú_read_distribution_metarÛ  é  s'   ø€ ÷Ið Iô   Ð.AÕ AÀ>ÐSXÓYÐYr:   c                ó0   € V ^8„  d   QhR\         R\        /# rÏ  rÐ  )r7   s   "r8   r9   r9   ô  s   € ÷ Dñ D¤Dð D¬Uñ Dr:   c                ór   a€ V R,          oSP                  4       '       g   R# R V3R llp\        SRV4      # )zLRead model/provider from a profile's config.yaml. Returns (model, provider).rq  c                ó$   € V ^8„  d   QhR\         /# rŸ   r   )r7   s   "r8   r9   Ú(_read_config_model.<locals>.__annotate__ú  s   € ÷ ñ ”5ñ r:   c                  óB  <€  ^ RI Hp  V ! S4      P                  R/ 4      p\        V\        4      '       d   VR3# \        V\
        4      '       d<   VP                  R4      ;'       g    VP                  R4      VP                  R4      3#  R#   \         d     R# i ; i)é    ©Úread_user_config_rawr›  Nrö   rœ  ©NN)rz  rã  rQ  r÷   r4   r†  rÌ   )rã  Ú	model_cfgÚconfig_paths     €r8   rØ  Ú!_read_config_model.<locals>._readú  sœ   ø€ ð		å>Ù,¨[Ó9×=Ñ=¸gÀrÓJˆIÜ˜)¤S×)Ò)Ø  $�Ð&Ü˜)¤T×*Ò*Ø —}‘} YÓ/×IÐI°9·=±=ÀÓ3IÈ9Ï=É=ÐYcÓKdÐdÐdð +ð Ðøô ô 	ØØÐð	ús!   ƒ3B ·B »-B Á)"B ÂBÂBzconfig-modelrä  )ry  rÍ  )r  rØ  ræ  s   & @r8   Ú_read_config_modelrè  ô  s=   ø€ à Õ-€KØ×Ñ×ÒØÐ÷ð ô   ¨^¸UÓCÐCr:   c                ó(   € V ^8„  d   QhR\         RR/# ro  r   )r7   s   "r8   r9   r9   
  s   € ÷ 3ñ 3¤Dð 3¨Tñ 3r:   c                óv  € V R,          pVP                  4       '       d   R# \        P                  ! \        4      ;_uu_ 4        ^ RIHp ^ RIHpHp ^ RI	H
p V! 4       R,          pVP                  4       '       d   V! V! V4      4      M/ pV'       d	   V! W4       RRR4       R#   + '       g   i     R# ; i)z„Copy (not link) the active profile's model block into a fresh profile so it is usable;
profiles stay independent islands afterwards.rq  Nr  )Úatomic_config_writerã  )Úlaunch_model_seed)ry  r-  r.  rÌ   r¨   r  rz  rë  rã  Úhermes_cli.profile_model_seedrì  rŠ  )r  ræ  r  rë  rã  rì  r×  Úseeds   &       r8   Ú_seed_model_configrï  
  s�   € ð  Õ-€KØ×Ñ×ÒÙÜ	×	Ò	œY×	'Õ	'Ý4ßOÝCÙ Ó" ]Õ2ˆØBHÇ.Á.×BRÒBRÑ Ñ!5°fÓ!=Ô>ÐXZˆßÙ Ô2÷ 
(×	'×	'Ò	'ús   ÁAB'ÂB'Â'B8	c                ó0   € V ^8„  d   QhR\         R\        /# rÏ  rÄ   )r7   s   "r8   r9   r9     s   € ÷ Sñ S¬ð S´ñ Sr:   c                óF   a€ ^ RI HoHp V! V RV3R lR7      P                  # )a{  Gateway liveness for a profile dir, never mutating HERMES_HOME.

Primary signal is ``gateway.pid`` verified against the runtime lock (fails closed when
the lock isn't held by *this* reader: dashboard as a separate s6 service, launch-service
gateways with no live PID file); fallback validates the PID in ``gateway_state.json``
against the process table, matching ``/api/status``.)Úget_running_pidÚresolve_gateway_livenessFc                 ó   <€ S! V R R7      # )F)Úcleanup_staler¢   )rB   rò  s   &€r8   Ú<lambda>Ú(_check_gateway_running.<locals>.<lambda>%  s   ø€ ™¨tÀ5ÕIr:   )r  Ú	use_cacheÚ	pid_probe)Úgateway.statusrò  ró  Úrunning)r  ró  rò  s   & @r8   Ú_check_gateway_runningrü    s%   ø€ ÷ Iá#Ø¨5ÜIôKçKRÉ7ðSr:   c                ó0   € V ^8„  d   QhR\         R\        /# r€  r  )r7   s   "r8   r9   r9   (  s   € ÷ 
ñ 
´ð 
¼ñ 
r:   c                óD   €  ^ RI Hp V! V 4      #   \         d     R# i ; i)zýTrue when the live default gateway multiplexes ``profile_name`` (such a profile has no
gateway.pid of its own, so ``_check_gateway_running`` alone reports it stopped).

Single shared lookup with the named-profile start guard and cron liveness (#97120).
)Ú+named_profile_served_by_running_multiplexerF)Úhermes_cli.gatewayrÿ  rÌ   )r�  rÿ  s   & r8   Ú_served_by_running_multiplexerr  (  s'   € ðÝRÙ:¸<ÓHÐHøÜô Úðús   ‚ �žg     À‚@g      N@c                ó0   € V ^8„  d   QhR\         R\        /# ©r/   Ú
skills_dirr2   )r   Úfloat)r7   s   "r8   r9   r9   F  s   € ÷ ñ ¤dð ¬uñ r:   c           
     ó²  €  V P                  4       P                  p \        P                  ! T 4      ;_uu_ 4       pT FC  p TP                  RR7      '       d(   \        YP                  RR7      P                  4      pKC  KE  	  RRR4       T#   \         d     R# i ; i  \         d     Kq  i ; i  + '       g   i     T# ; i  \         d     T# i ; i)z«Max mtime of ``skills_dir`` and its immediate children (adding/removing a category
bumps the root, a skill bumps its category). One scandir: O(#categories), not O(#files).ç        F)Úfollow_symlinksN)rF   Úst_mtimerE   r@   Úscandirr  Úmax)r  ÚsigÚitrK   s   &   r8   Ú_skills_dir_signaturer  F  sÊ   € ðØ�o‰oÓ×(Ñ(ˆð	Ü�ZŠZ˜
×#Ô# rÛ�ðØ—|‘|°E�|×:Ò:Ü! #§z¡zÀ% zÓ'H×'QÑ'QÓRšñ ;ñ ÷ $ð €Jøô ô Úðûô ô Úðú÷ $Ö#ð €Jûô ô ØØ€Jðúsc   ‚B �C »B3Á=B!Á?B3ÂC ÂBÂBÂ!B0	Â,B3Â/B0	Â0B3Â3C	Â>C ÃC ÃCÃCc                ó0   € V ^8„  d   QhR\         R\        /# r  ©r   r©  )r7   s   "r8   r9   r9   Z  s   € ÷ Jñ J¤$ð J¬3ñ Jr:   c                ó@   € ^ RI Hp \        R V! V R4       4       4      # )uW  One ``os.walk`` over the skills tree (prunes ``.git``/``node_modules``/support dirs
instead of statting them). Best-effort: a subtree that vanishes mid-walk (a concurrent
skill install/update) is skipped, never raised â€” ``os.walk`` (``onerror=None``) swallows
scandir errors itself, so one profile's churn cannot abort the whole enumeration.)Úiter_skill_index_filesc              3   ó&   "  € T F  p^x € K	  	  R# 5i)é   Nr¢   )rt   Ú_s   & r8   rv   Ú$_walk_skill_count.<locals>.<genexpr>`  s   é € ÐIÑH�Q�qÓHùs   ‚zSKILL.md)Úagent.skill_utilsr  Úsum)r  r  s   & r8   Ú_walk_skill_countr  Z  s    € õ
 9ÜÑIÑ0°¸ZÔHÓIÓIÐIr:   c                ó0   € V ^8„  d   QhR\         R\        /# rÏ  r  )r7   s   "r8   r9   r9   c  s   € ÷ ñ œtð ¬ñ r:   c                óZ  € V R,          pVP                  4       '       g   ^ # \        V4      p\        V4      p\        P	                  V4      pVeD   V^ ,          V8X  d6   \
        P
                  ! 4       V^,          ,
          \        8  d
   V^,          # \        ;_uu_ 4        \        P                  V\        P                  ! 4       4      pRRR4       X;_uu_ 4        \        V4      p\        P	                  V4      pVeN   V^ ,          V8X  d@   \
        P
                  ! 4       V^,          ,
          \        8  d   V^,          uuRRR4       # \        V4      pV\
        P
                  ! 4       V3\        V&   VuuRRR4       #   + '       g   i     LÂ; i  + '       g   i     R# ; i)uû   Count installed skills in a profile (cached by skills-dir signature + TTL). Walks
synchronously when stale â€” detail surfaces (``hermes profile info``, ``profiles.describe``)
want the fresh number; polled lists go through :func:`_cached_skill_count`.ÚskillsN)r  r4   r  Ú_SKILL_COUNT_CACHErQ  ÚtimeÚ_SKILL_COUNT_TTL_SECONDSÚ_SKILL_COUNT_LOCKÚ_SKILL_COUNT_SCAN_LOCKSr�  Ú	threadingÚLockr  )r  r  rÊ  rÉ  rË  Ú	scan_lockÚcounts   &      r8   Ú_count_skillsr&  c  s.  € ð ˜xÕ'€JØ×Ñ×ÒÙÜ
ˆj‹/€CÜ% jÓ1€IÜ×#Ñ# CÓ(€FØÒ˜f Q�i¨9Ô4¼$¿)º)»+ÈÈqÍ	Õ:QÔUmÔ9mØ�a�yÐß	Ö	Ü+×6Ñ6°s¼I¿NºNÓ<LÓMˆ	÷ 
ç	Šä)¨*Ó5ˆ	Ü#×'Ñ'¨Ó,ˆØÒ &¨¥)¨yÔ"8¼d¿iºi»kÈFÐSTÍIÕ>UÔYqÔ=qØ˜!•9÷ 
Šô " *Ó-ˆà#,¬d¯iªi«k¸5Ð"AÔ˜3ÑØ÷ 
Š÷ 
×	úç	�ˆús   Â"*FÃA'FÅ+FÆF	ÆF*	c                ó0   € V ^8„  d   QhR\         R\        /# rÏ  r  )r7   s   "r8   r9   r9   }  s   € ÷ 2ñ 2¤Tð 2¬cñ 2r:   c                óÀ  € \        V R,          4      p\        P                  ! 4       p\        ;_uu_ 4        \        P	                  VR4      V8*  pV'       d   V\
        ,           \        V&   RRR4       X'       d.   \        P                  ! \        V 3RRR7      P                  4        \        P	                  V4      pVe
   V^,          # ^ #   + '       g   i     Li; i)a2  Last known skill count with ZERO skill-tree I/O on the calling thread. A never-counted
or aged entry schedules one background :func:`_count_skills` per profile per recheck
window (which itself re-walks only on signature change / TTL); the next poll picks the
result up. ``0`` until the first refresh lands.r  r  Nzhermes-skill-countT)r  Úargsrá   Údaemon)r4   r  r   Ú_SKILL_COUNT_NEXT_CHECKrQ  Ú_SKILL_COUNT_RECHECK_SECONDSr"  ÚThreadr&  Ústartr  )r  rÊ  ÚnowÚduerË  s   &    r8   Ú_cached_skill_countr1  }  s§   € ô
 ˆk˜HÕ$Ó
%€CÜ
�)Š)‹+€Cß	Ö	Ü%×)Ñ)¨#¨sÓ3°sÑ:ˆßØ+.Ô1MÕ+MÔ# CÑ(÷ 
÷ Ü×Ò¤°[°NØ2¸4ô	AßAFÁÄÜ×#Ñ# CÓ(€FØÒ*ˆ6�!�9Ð1°Ð1÷ 
×	ús   ¶6CÃC	c                ó0   € V ^8„  d   QhR\         R\        /# rÏ  )r   r†  )r7   s   "r8   r9   r9   •  s   € ÷ ñ ¤4ð ¬Dñ r:   c                ó~   a € R V 3R llp\        \        S R,          RV4      4      p\        VR,          4      VR&   V# )uÛ   Read ``profile.yaml`` -> ``{description, description_auto, display_name,
previous_names}`` (empty defaults when missing/unreadable). Never raises â€” a
corrupt file on one profile must not break ``hermes profile list``.c                ó$   € V ^8„  d   QhR\         /# rŸ   )r†  )r7   s   "r8   r9   Ú'read_profile_meta.<locals>.__annotate__™  s   € ÷ 
ñ 
”4ñ 
r:   c                  óz  <€ \        SR ,          4      ;'       g    / p V P                  R4      pRp\        V\        4      '       dZ   VP                  R4      p\        V\        4      '       d3   \	        VP                  R4      ;'       g    R4      P                  4       pR\	        V P                  R4      ;'       g    R4      P                  4       R\        V P                  RR4      4      R\	        V P                  R4      ;'       g    R4      P                  4       R	VR
\        V P                  R
4      4      /# )úprofile.yamlÚui_metarO  zhermes-botsÚtitler¤  r¥  Fr¦  r§  r¨  )rº  rQ  r÷   r†  r4   rè   rƒ   Ú_clean_previous_names)r¹  r8  r§  Úhermes_botsr  s       €r8   rØ  Ú read_profile_meta.<locals>._read™  sû   ø€ Ü˜{¨^Õ;Ó<×BÐBÀˆØ—(‘(˜9Ó%ˆØˆ	Ü�gœt×$Ò$Ø!Ÿ+™+ mÓ4ˆKÜ˜+¤t×,Ò,Ü §¡°Ó 8× >Ð >¸BÓ?×EÑEÓG�	àœ3˜tŸx™x¨Ó6×<Ð<¸"Ó=×CÑCÓEØ¤ T§X¡XÐ.@À%Ó%HÓ IØœC §¡¨Ó 8× >Ð >¸BÓ?×EÑEÓGØ˜ØÔ3°D·H±HÐ=MÓ4NÓOð
ð 	
r:   r7  zprofile-metar¨  )r†  rÍ  r5   )r  rØ  Úmetas   f  r8   Úread_profile_metar>  •  sD   ø€ ÷
ð 
ô$ Ô$ [°>Õ%AÀ>ÐSXÓYÓZ€DÜ! $Ð'7Õ"8Ó9€DÐ	ÑØ€Kr:   c                ó:   € V ^8„  d   QhR\         \        ,          /# rŸ   r(  )r7   s   "r8   r9   r9   °  s   € ÷ ñ ¤$¤s¥)ñ r:   c                ó  € \        V \        4      '       g   . # . p\        4       pV  FZ  p\        T;'       g    R4      P	                  4       pV'       g   K0  WB9  g   K8  VP                  V4       VP                  V4       K\  	  V# )z‚Normalize the ``previous_names`` list from ``profile.yaml``: strings only,
stripped, de-duplicated preserving order. Never raises.rO  )r÷   r5   r6   r4   rè   r?   Úappend)ÚrawÚcleanedÚseenÚitemrá   s   &    r8   r:  r:  °  sl   € ô �cœ4× Ò Øˆ	Ø€GÜ‹5€DÛˆÜ�4—:�:˜2‹×$Ñ$Ó&ˆß‰4�DÖ$Ø�H‰H�TŒNØ�N‰N˜4Ö ñ	 ð
 €Nr:   r¤  r¥  r¦  r¨  c                óÆ   € V ^8„  d   QhR\         R\        \        ,          R\        \        ,          R\        \        ,          R\        \        \        ,          ,          RR/# )r/   r  r¤  r¥  r¦  r¨  r2   N)r   r   r4   rƒ   r5   )r7   s   "r8   r9   r9   ¿  sT   € ÷  7ñ  7Üð 7Ü'/´¥}ð 7ÜOWÔX\Í~ð 7äœ3•-ð 7ä8@ÄÄcÅÕ8Kð 7ð 
ñ 7r:   c               óØ  € V P                  4       '       g   \        RV  24      hV R,          p\        V4      ;'       g    / pVe   VP                  4       VR&   Ve   \	        V4      VR&   Ve=   VP                  4       '       d   VP                  4       VR&   MVP                  RR4       Ve+   \        V4      pV'       d   WvR&   MVP                  RR4       ^ RIHp V! WVR	R
7       R# )zŽUpdate ``profile.yaml`` in place: only passed fields are overwritten; the file is
created if missing. The profile directory itself must exist.z"profile directory does not exist: r7  Nr¤  r¥  r¦  r¨  )Úatomic_yaml_writeF)Ú	sort_keys)	r  rÒ   rº  rè   rƒ   Úpopr:  ÚutilsrH  )	r  r¤  r¥  r¦  r¨  rB   ÚexistingrC  rH  s	   &$$$$    r8   Úwrite_profile_metarM  ¿  sä   € ð ×Ñ×ÒÜÐ"DÀ[ÀMÐ RÓSÐSØ˜Õ'€DÜ$ TÓ*×0Ð0¨b€HØÒØ"-×"3Ñ"3Ó"5ˆ�ÑØÒ#Ü'+Ð,<Ó'=ˆÐ#Ñ$ØÒà×Ñ×ÒØ'3×'9Ñ'9Ó';ˆH�^Ò$à�L‰L˜¨Ô.ØÒ!ô (¨Ó7ˆßØ)0Ð%Ò&à�L‰LÐ)¨4Ô0õ (Ù�d°×6r:   c                óR   € V ^8„  d   QhR\         R\        \         ,          R\         /# )r/   rá   r¦  r2   r2  )r7   s   "r8   r9   r9   â  s%   € ÷ ;ñ ;œsð ;´(¼3µ-ð ;ÄCñ ;r:   c                óf   € T;'       g    RP                  4       pV'       d   W 8w  d	   V RV  R2# T # )uŽ   ``display_name (canonical_id)``, or the bare id when no display name is set (or it
equals the id) â€” byte-for-byte the pre-feature rendering.rO  ú (r>  )rè   )rá   r¦  Údns   && r8   Úformat_profile_labelrR  â  s8   € ð ×
Ð
˜"×	#Ñ	#Ó	%€Bß! b¤jˆbˆT��D�6˜ÐÐ:°dÐ:r:   c                ó<   € V ^8„  d   QhR\         R\         R\         /# )r/   r�  r¦  r2   râ   )r7   s   "r8   r9   r9   é  s!   € ÷ ñ ¬3ð ¼cð Äcñ r:   c                ó¼   € \        V 4      w  r#T;'       g    RP                  4       p\        V4      ^@8”  d   \        R\        V4       R24      h\	        W4R7       V# )z|Set (or clear, with ``""``) a presentation-only display name. Returns the stored value;
raises ``ValueError`` over 64 chars.rO  zDisplay name too long (z chars, max 64).)r¦  )r  rè   r‡   rX   rM  )r�  r¦  Ú_canonr  rC  s   &&   r8   Úset_profile_display_namerV  é  sZ   € ô 0°Ó=Ñ€FØ×!Ð!˜r×(Ñ(Ó*€GÜ
ˆ7ƒ|�bÔÜÐ2´3°w³<°.Ð@PÐQÓRÐRÜ�{Õ9Ø€Nr:   r   Úlazy_skill_countFc                óv   € V ^8„  d   QhR\         R\        R\        R\        \         ,          R\        R\        /# )r/   rá   rB   r™  r   rW  r2   )r4   r   rƒ   r   r–  )r7   s   "r8   r9   r9   ö  s=   € ÷ ñ œð ¤4ð ¼ð Ì(ÔSVÍ-ð Ü$(ðÜ5@ñr:   c               óx  € \        V4      w  rV\        V4      w  rxp	\        V4      p
V'       d   \        V4      MRp\	        V4      pV'       g   T;'       g    \        V 4      pV'       d   \        V4      M
\        V4      p\        RRV RVRVRVRVRVRVR	,          P                  4       R
VRVRVRVRVRV	/V
B # )z8Build one :class:`ProfileInfo` from a profile directory.Nrá   rB   r™  rš  r›  rœ  r�  r   rž  rŸ  r   r¡  r¢  r£  r¢   )
rè  rÛ  r>  rÁ   rü  r  r1  r&  r–  ry  )rá   rB   r™  r   rW  r›  rœ  Ú	dist_nameÚdist_versionÚdist_sourcer=  rŸ  rš  rž  s   &&$$$         r8   Ú_profile_infor]  ö  s  € ô )¨Ó.�O€EÜ+BÀ4Ó+HÑ(€I˜[Ü˜TÓ"€Dß2<Ô" :Ô.À$€JÜ,¨TÓ2€OßØ)×QÐQÔ-KÈDÓ-Qˆß/?Ô% dÔ+Ä]ÐSWÓEX€KÜñ ØðØðØ)3ðØETðØ\aðàðà$(¨6¥M×#9Ñ#9Ó#;ðàITðð ðð +5ðð IRðð *ð	ð @Kð	ð
 ñð r:   c                óF   € V ^8„  d   QhR\         R\        \        ,          /# )r/   rW  r2   )rƒ   r5   r–  )r7   s   "r8   r9   r9   
  s   € ÷ ñ ¤tð ¼¼[Õ8Iñ r:   c                ój  € . p\        4       pVP                  4       '       d   VP                  \        RVRV R7      4       \	        4       pV'       da   \        4       pV FP  pVP                  \        VP                  4      4      pVP                  \        VP                  VRVV R7      4       KR  	  V# )a@  Return info for all profiles, including the default.

``lazy_skill_count=True`` is for POLLED callers (``GET /api/profiles``, ``profiles.list``):
``skill_count`` is the last known value, refreshed off-request, so the request never walks
a skill tree (#114041). Default ``False`` counts synchronously (CLI, detail views).rö   T)r™  rW  F)r™  r   rW  )	r`   r  rA  r]  r&  rƒ  rQ  rû   rá   )rW  r"   Údefault_homeÚnamedÚ	alias_maprK   r   s   $      r8   Úlist_profilesrc  
  sŸ   € ð €HÜ+Ó-€LØ×Ñ×ÒØ�‰œ i°È$Ø7GôIô 	Jä$Ó&€EßÜ#Ó%ˆ	ÛˆEØ"Ÿ™Ô'=¸e¿j¹jÓ'IÓJˆJØ�O‰OœM¨%¯*©*°eÈÐZdØ;KôMö Nñ ð €Or:   zLgateway.standalone is ignored on the default profile: it is the host gatewayc                ó0   € V ^8„  d   QhR\         R\        /# ©r/   r   r2   rÄ   )r7   s   "r8   r9   r9   )  s   € ÷ /ñ /¤ð /¬ñ /r:   c                ób  € ^ RI Hp ^ RIHp \	        V 4      p V R,          p\        V 4      p V! VP                  4       4      p\        P                  T4      pTe#   T^ ,          T8X  d   T^,          e
   T^,          # RpTeW   ^ RIHp	  T	! T4      ;'       g    / p
\'        T
P                  R	4      \(        4      '       d   T
R	,          P                  R
4      p\+        T4      pT \-        4       8X  d2   T'       d(   \.        '       g   \        P                  \0        4       RsRpY[3\        T&   T#   \         d    Rp Lý\         dk   pRTP                  3p\        P                  T4      TR38w  d+   \        P                  RT\        T4      P                  4       TR3\        T&    Rp?R# Rp?ii ; i  T\        \$        3 df   pTe   T^ ,          T8w  d+   \        P                  RT\        T4      P                  4       T\'        Ya4      '       d   RMR3\        T&    Rp?R# Rp?ii ; i)uû   Does ``home``'s own config.yaml opt this profile out of the host multiplexer
(``gateway.standalone: true``)? Memoised by file signature. The DEFAULT profile is
never standalone â€” it IS the host â€” and warns once per process if the key is set there.)Ú	YAMLError)Úfile_signaturerq  Nz
stat-errorFzGCannot read gateway.standalone from %s (%s); treating as not standalonerâ  ÚgatewayÚ
standaloneT)rµ  rg  rK  rh  r   r4   rF   rÒ   rE   ÚerrnoÚ_STANDALONE_MEMOrQ  ÚloggerÚwarningrø   rù   rz  rã  ÚUnicodeErrorr÷   r†  Ú_standalone_truthyr`   Ú_STANDALONE_WARNEDÚ_STANDALONE_DEFAULT_WARNING)r   rg  rh  Úcfg_pathrÊ  rÉ  rF  rË  rÌ  rã  ÚcfgrG  s   &           r8   Úprofile_is_standaloneru  )  së  € õ
 &Ý$ä�‹:€DØ�mÕ#€HÜ
ˆd‹)€Cð
Ù" 8§=¡=£?Ó3ˆ	ô ×!Ñ! #Ó&€FØÒ˜f Q�i¨9Ô4¸À½Ò9NØ�a�yÐØ€EØÒÝ:ð		Ù& xÓ0×6Ð6°BˆCô �c—g‘g˜iÓ(¬$×/Ò/Ø˜	•N×&Ñ& |Ó4ˆEÜ Ó&€FØÔ'Ó)Ô)ß×,Ó,Ü�N‰NÔ6Ô7Ø!%ÐØˆØ&Ð/Ô�SÑØ€MøôE ô ØŠ	Üô Ø! 3§9¡9Ð-ˆ	Ü×Ñ Ó$¨°EÐ(:Ô:Ü�N‰NÐdØ#¤T¨#£Y×%7Ñ%7ô9à!*¨EÐ 2Ô˜ÑÝûðûð œ7¤LÐ1ô 	ØŠ~ ¨¥¨iÔ!7Ü—‘ÐhØ'¬¨c«×);Ñ);ô=ð &/¼ÀC×9SÒ9S±ÐY]Ð$^Ô˜SÑ!Ýûð	úsC   ­D1 ÂF7 ÂF7 Ä1F4Å F4Å	F4Å
AF/Æ/F4Æ7H.Ç	AH)È)H.c                ó0   € V ^8„  d   QhR\         R\        /# )r/   rÌ  r2   )Úobjectrƒ   )r7   s   "r8   r9   r9   [  s   € ÷ ñ œfð ¬ñ r:   c                ód   € ^ RI Hp \        V \        4      '       d   V! V 4      RJ # \	        V 4      # )zŽ``gateway.standalone`` truthiness via the shared bool parser; only the
``gateway:`` section's ``standalone`` key is read (no top-level alias).)Ú_bool_tokenT)Úgateway.configry  r÷   r4   rƒ   )rÌ  ry  s   & r8   rp  rp  [  s.   € õ +Ü�%œ×ÒÙ˜5Ó! TÐ)Ð)Ü�‹;Ðr:   c                ó0   € V ^8„  d   QhR\         R\         /# re  r   )r7   s   "r8   r9   r9   d  s   € ÷ )ñ )œTð )¤dñ )r:   c                 ó&   € \        V 4      R ,          # )zgateway.parkedr   ©r   s   &r8   Úparked_marker_pathr~  d  s   € Ü�‹:Ð(Õ(Ð(r:   c                ó0   € V ^8„  d   QhR\         R\        /# re  rÄ   )r7   s   "r8   r9   r9   h  s   € ÷ -ñ -œDð -¤Tñ -r:   c                ó4   € \        V 4      P                  4       # )zHMarker contents are deliberately irrelevant, including for provisioning.)r~  ry  r}  s   &r8   Úprofile_is_parkedr�  h  s   € ä˜dÓ#×*Ñ*Ó,Ð,r:   Úinclude_standaloneÚinclude_parkedc                ó€   € V ^8„  d   QhR\         R\         R\         R\        \        \        \        3,          ,          /# )r/   Ú	multiplexr‚  rƒ  r2   )rƒ   r5   rp   r4   r   )r7   s   "r8   r9   r9   p  s8   € ÷ ñ ¤ð ¼dð Ü&*ðÜ7;¼EÄ#ÄtÀ)Õ<LÕ7Mñr:   c               óP  aa€ \        4       ;'       g    Rp\        4       p\        V4      '       d6   V\        9  d+   \        P                  R4       \        P                  V4       V '       g   V\        V4      3.# RV3.pVP                  VV3R l\        4        4       4       V# )uO  ``(profile_name, hermes_home)`` pairs a gateway should serve â€” the single chokepoint
for "which profiles does the inbound gateway handle".

``multiplex=False``: exactly one entry for the *active* profile (byte-for-byte the
historical single-profile behavior; name is ``"default"`` or the named profile's id).
``multiplex=True``: default plus every live named profile under ``profiles/`` (tombstoned
and parked profiles skipped). Pure directory read: never creates a profile dir (#94590).

Named profiles that authored ``gateway.standalone: true`` are skipped because they opted
out of the host multiplexer; a ``gateway.parked`` marker (``hermes -p X gateway stop``) skips
a profile the host would otherwise serve. Callers enumerating INSTALLED profiles pass
``include_standalone=True, include_parked=True``; serving/ticking callers pass neither.rö   zNIgnoring gateway.parked for the default profile; stop the host gateway insteadc              3   ó¬   <"  € T FI  pS'       g   \        V4      '       d   K  S'       g   \        V4      '       d   K9  VP                  V3x € KK  	  R # 5ir|   )ru  r�  rá   )rt   rK   rƒ  r‚  s   & €€r8   rv   Ú$profiles_to_serve.<locals>.<genexpr>†  s?   øé € ð GÑ2L¨ß'Ô/DÀU×/Kô %ç$Ô,=¸e×,Dô %�%—*‘*˜eÕ$Ó2Lùs   ƒA�A£A«A¾A)
Úget_active_profile_namer`   r�  Ú_parked_default_warnedrm  rn  r?   r  r/  r&  )r…  r‚  rƒ  Úactiverö   Úserves   &dd   r8   Úprofiles_to_server�  p  s”   ù€ ô %Ó&×3Ð3¨)€FÜ&Ó(€GÜ˜×!Ò! gÔ5KÔ&KÜ�‰ÐgÔhÜ×"Ñ" 7Ô+ßØœ¨Ó0Ð1Ð2Ð2Ø&/°Ð%9Ð$:€EØ	‡L�Lõ GÔ2JÔ2Ló Gô Gð €Lr:   c                óF   € V ^8„  d   QhR\         \        ,          R\        /# )r/   Ú
clone_fromr2   )r   r4   r   )r7   s   "r8   r9   r9   Œ  s   € ÷ 
ñ 
¤h¬s¥mð 
¼ñ 
r:   c                ó¸   € V f   ^ RI Hp V! 4       pM\        V 4      p \        V 4      pVP	                  4       '       g   \        RT ;'       g    R RV 24      hV# )zPDirectory to clone from: the named profile, or the active profile when ``None``.r  zSource profile 'r‹  z' does not exist at )r¨   r  r	  r  r  rÒ   )r�  r  rO   s   &  r8   Ú_resolve_clone_sourcer‘  Œ  sa   € àÒÝ4Ù$Ó&‰
ä! *Ó-ˆ
Ü$ ZÓ0ˆ
Ø×Ñ×ÒÜÐ"2°:×3IÐ3IÀÐ2JÐJ^Ð_iÐ^jÐ kÓlÐlØÐr:   c                óV   € V ^8„  d   QhR\         R\        R\        \        ,          RR/# )r/   rB   r:  rL   r2   N)r   r4   r   r©  )r7   s   "r8   r9   r9   ™  s-   € ÷ &ñ &¤ð &¬Cð &´xÄµ}ð &ÐPTñ &r:   c                ó"  € V P                  4       '       d   R# \        P                  ! \        4      ;_uu_ 4        V P	                  VRR7       Ve!   \
        P                  ! \        V 4      V4       RRR4       R#   + '       g   i     R# ; i)zKBest-effort: write *text* to *path* unless it already exists; never raises.Nr7  rÇ   )ry  r-  r.  rE   r\  r@   r`  r4   )rB   r:  rL   s   &&&r8   Ú_seed_file_if_missingr”  ™  sX   € à‡{�{‡}‚}ÙÜ	×	Ò	œW×	%Õ	%Ø�‰˜ wˆÔ/ØÒÜ�HŠH”S˜“Y Ô%÷ 
&×	%×	%Ò	%ús   »8A=Á=B	c                ó@   € V ^8„  d   QhR\         R\         R\        RR/# )r/   rO   r  Úrelpathr2   NrÃ  )r7   s   "r8   r9   r9   £  s(   € ÷ &ñ &œDð &¬tð &¼cð &Àdñ &r:   c                óŒ  € W,          pVP                  4       '       g   R# W,          pVP                  P                  RRR7       \        P                  ! W44       VR8X  dN   \
        P                  ! \        4      ;_uu_ 4        \        P                  ! \        V4      R4       RRR4       R# R#   + '       g   i     R# ; i)z£Copy one profile-relative file if it exists. ``.env`` is tightened to owner-only:
``copy2`` preserves source mode bits, so a loose source (umask 0o644) would leak.NTrV  r   é€  )ry  ÚparentrZ  r]  Úcopy2r-  r.  rE   r@   r`  r4   )rO   r  r–  ÚsrcÚdsts   &&&  r8   Ú_clone_filer�  £  s‡   € ð Õ
€CØ�:‰:�<Š<ÙØ
Õ
€CØ‡J�J×Ñ˜T¨DÐÔ1Ü
‡L‚L�ÔØ�&ÔÜ× Ò ¤×)Õ)Ü�HŠH”S˜“X˜uÔ%÷ *Ñ)ñ ß)×)Ð)ús   Â!B2Â2C	c                óF   € V ^8„  d   QhR\         R\        \        ,          /# rÏ  ©r   r5   r4   )r7   s   "r8   r9   r9   ·  s   € ÷ ñ ¬dð ´t¼Cµyñ r:   c                óN  € . p\          F˜  pW,          pVP                  4       '       g   K#  \        \        P                  P                  V4      4      pVP                  4        VP                  4       '       d   \        P                  ! WC4       VP                  V4       Kš  	  V# )zœReplace symlinked root files the clone will edit with private copies of their targets (a
dangling link is dropped). Returns the relative names materialized.)Ú_CLONE_MATERIALIZEÚ
is_symlinkr   r@   rB   Úrealpathrl  rŠ  r]  rš  rA  )r  Údonerá   rB   r  s   &    r8   Ú_materialize_symlinked_filesr¥  ·  sy   € ð €Dß"ˆØÕ!ˆØ�‰× Ò ÙÜ”b—g‘g×&Ñ& tÓ,Ó-ˆØ�‰ŒØ�>‰>×ÒÜ�LŠL˜Ô&Ø�‰�DÖñ #ð €Kr:   c                óF   € V ^8„  d   QhR\         R\        \         ,          /# rÃ   r2  )r7   s   "r8   r9   r9   Ç  s   € ÷ *ñ *œ3ð *¤8¬C¥=ñ *r:   c                ó\  € \         P                  R8w  d   R#  \         P                  ! V 4      P                  \        P
                  8w  d   R# \         P                  ! V 4      pTP                  R4      '       d   RTR,          ,           # TP                  R4      #   \         d     R# i ; i)z¹Target of an NTFS directory junction, else ``None``. A junction is a reparse point, not a
symlink: ``os.path.islink()`` is False and ``shutil.copytree(symlinks=True)`` descends into it.ÚntNz\\?\UNC\Ú\:é   NNz\\?\)
r@   rá   rA   Úst_reparse_tagrF   ÚIO_REPARSE_TAG_MOUNT_POINTÚreadlinkrE   Ú
startswithÚremoveprefix)rB   r  s   & r8   Ú_junction_targetr°  Ç  s‹   € ô 
‡w�w�$„ÙðÜ�8Š8�D‹>×(Ñ(¬D×,KÑ,KÔKÙÜ—’˜TÓ"ˆð ×Ñ˜×(Ò(Ø�f˜R•jÕ Ð Ø×Ñ˜yÓ)Ð)øô ô Úðús   ™3B ÁB ÂB+Â*B+c                ó@   € V ^8„  d   QhR\         R\         R\        RR/# )r/   r›  rœ  Údirs_exist_okr2   NrÄ   )r7   s   "r8   r9   r9   Ø  s/   € ÷ Wñ W¤$ð W¬Tð WÌ$ð WÐ[_ñ Wr:   c                óš  aa	€ / o	R VV	3R llp\         P                  ! WRW4R7       S	'       d   ^ RIpS	P                  4        FS  w  rg XP	                  V\
        P                  P                  V\
        P                  P                  W`4      4      4       KU  	  R#   \         d#   p\        P                  RYgT4        Rp?K�  Rp?ii ; i)a_  ``shutil.copytree(symlinks=True)`` that re-creates NTFS junctions as junctions instead of
traversing them. A ``skills/foo`` junction into a ``skills.external_dirs`` root copied as a
physical tree is a second same-named candidate and ``locate_skill`` refuses to guess (#113471).
A junction whose target is gone is skipped with a warning, never a crash.c                óR   € V ^8„  d   QhR\         R\        \         ,          R\        /# rR   r3   )r7   s   "r8   r9   Ú._copytree_keep_junctions.<locals>.__annotate__ß  s%   € ÷ ñ œ3ð ¤t¬C¥yð ´Sñ r:   c                 óþ   <€ \        S! W4      4      pV Fd  p\        \        P                  P	                  W4      4      pVf   K1  VS\        P                  P	                  W4      &   VP                  V4       Kf  	  V# r|   )r6   r°  r@   rB   rC   r?   )r0   rS   rJ   rá   r  ÚignoreÚ	junctionss   &&   €€r8   r]   Ú)_copytree_keep_junctions.<locals>._ignoreß  sc   ø€ Ü‘f˜YÓ.Ó/ˆÛˆDÜ%¤b§g¡g§l¡l°9Ó&CÓDˆFØÔ!Ø;A�	œ"Ÿ'™'Ÿ,™, yÓ7Ñ8Ø—‘˜DÖ!ñ	 ð
 ˆr:   T)Úsymlinksr²  r·  Nz%clone: skipped junction %s -> %s (%s))r]  ÚcopytreeÚ_winapiÚitemsÚCreateJunctionr@   rB   rC   r–  rE   rm  rn  )
r›  rœ  r·  r²  r]   r¼  Úlinkr  rF  r¸  s
   &&f&     @r8   Ú_copytree_keep_junctionsrÀ  Ø  sš   ù€ ð
 !#€I÷ñ ô ‡O‚O�C t¸=ÕYßÛØ!Ÿ™Ö)‰ˆð	WØ×"Ñ" 6¬2¯7©7¯<©<¸¼R¿W¹W¿_¹_ÈTÓ=WÓ+XÖYó *øô ô 	WÜ�N‰NÐBÀDÐRU×VÒVûð	Wús   Á
ABÂC
Â(CÃC
c                ó@   € V ^8„  d   QhR\         R\         R\        RR/# )r/   rO   r  rÐ   r2   NrÃ  )r7   s   "r8   r9   r9   ò  s(   € ÷ 
ñ 
¤ð 
´4ð 
Äð 
Èñ 
r:   c                ó¤  € \        W\        V 4      4       \        V4      pV'       d   \        P	                  RW#V 4       \
         F  pW,          P                  RRR7       K  	  \         F  pW,          P                  RR7       K  	  ^ RI	H
p V! V4      p\        VP                  4       4      '       d   \        P	                  RW'4       R# R# )zu--clone-all: full copytree minus infrastructure/history, then strip runtime files
and cloned single-use OAuth grants.zMprofile %s: materialized symlinked %s so the clone never writes through to %sTrV  ©Ú
missing_ok)Ú$strip_cloned_single_use_oauth_grantszWprofile %s: dropped cloned single-use OAuth grants %s (inherits the root grant instead)N)rÀ  rb   r¥  rm  ÚinfoÚ_PROFILE_DIRSrZ  Ú_CLONE_ALL_STRIPrl  Úhermes_cli.authrÅ  rŽ   Úvalues)rO   r  rÐ   ÚmaterializedÚsubdirÚstalerÅ  rú   s   &&&     r8   Ú_clone_all_intorÎ  ò  s±   € ô ˜ZÔ6PÐQ[Ó6\Ô]Ü/°Ó<€LßÜ�‰ÐcØ¨ô	5÷  ˆØ	Õ	×$Ñ$¨T¸DÐ$ÖAñ  ç!ˆØ	Õ	×$Ñ$°Ð$Ö5ñ "õ EÙ3°KÓ@€HÜ
ˆ8�?‰?Ó×ÒÜ�‰ð0Ø16ö	
ñ r:   c                ó(   € V ^8„  d   QhR\         RR/# )r/   ræ  r2   Nr   )r7   s   "r8   r9   r9     s   € ÷ 0ñ 0¤tð 0°ñ 0r:   c                ó  € V P                  4       '       g   R# \        P                  ! \        4      ;_uu_ 4        ^ RIHpHp V! V 4      p\        VP                  R4      \        4      '       d   VP                  R4      M/ pRV9  d   RV9  d    RRR4       R# VP                  RR4       VP                  RR4       V'       g   RV9   d   VP                  R4       V! W4       RRR4       R#   + '       g   i     R# ; i)z¢Multiplexing belongs to the default profile; a clone that keeps the flag would start its
own multiplexer (or be refused at boot) the first time it runs a gateway.N)Úatomic_config_replacerã  ri  Úmultiplex_profiles)rŠ  r-  r.  rÌ   rz  rÑ  rã  r÷   rQ  r†  rJ  )ræ  rÑ  rã  rt  ri  s   &    r8   Ú_strip_multiplex_flagrÓ    sÄ   € ð ×Ñ× Ò ÙÜ	×	Ò	œY×	'Õ	'ßQÙ" ;Ó/ˆÜ(2°3·7±7¸9Ó3EÄt×(LÒ(L�#—'‘'˜)Ô$ÐRTˆØ sÔ*Ð/CÈ7Ô/RØ÷ 
(Ñ	'ð 	�‰Ð$ dÔ+Ø�‰Ð(¨$Ô/ß˜9¨Ô+Ø�G‰G�IÔñ 	˜kÔ/÷ 
(×	'×	'Ò	'ús   »AC3Â+C3Ã	 C3Ã3D	c                ó$   € V ^8„  d   QhR\         /# )r/   Úplugins_rootr   )r7   s   "r8   r9   r9      s   € ÷ ñ ¬ñ r:   c                ó0   a€ \        V 4      oR V3R llpV# )z®copytree ignore for a cloned ``plugins/``: :func:`_non_exportable_entries` everywhere, plus
the installer's in-flight ``.install-*`` / ``.update-*`` staging dirs at the root.c                óR   € V ^8„  d   QhR\         R\        \         ,          R\        /# rR   r3   )r7   s   "r8   r9   Ú+_clone_plugins_ignore.<locals>.__annotate__%  s%   € ÷ ñ œ3ð ¤t¬C¥yð ´Sñ r:   c                 óf   <a € \        S V4      pS S8X  d   VP                  V 3R  lV 4       4       V# )c              3   óâ   <"  € T Fd  qP                  R4      '       g   K  \        P                  P                  \        P                  P	                  SV4      4      '       g   K`  Vx € Kf  	  R# 5i)ú	.install-N)rÛ  z.update-)r®  r@   rB   ÚisdirrC   )rt   Únr0   s   & €r8   rv   Ú9_clone_plugins_ignore.<locals>._ignore.<locals>.<genexpr>)  sD   øé € ð J¡e ¯|©|Ð<U×/Vœ1Ü!Ÿw™wŸ}™}¬R¯W©W¯\©\¸)ÀQÓ-G×H÷ š1£eùs   ƒA/ A A/Á%
A/)rM   rY   )r0   rS   rJ   Úroots   f& €r8   r]   Ú&_clone_plugins_ignore.<locals>._ignore%  s7   ù€ Ü)¨)°UÓ;ˆØ˜Ôà�N‰Nô J¡eó Jô Jàˆr:   râ   )rÕ  r]   rß  s   & @r8   Ú_clone_plugins_ignorerá     s    ø€ ô ˆ|Ó€D÷ð ð €Nr:   c                ó4   € V ^8„  d   QhR\         R\         RR/# )r/   rO   r  r2   Nr   )r7   s   "r8   r9   r9   /  s&   € ÷ \ñ \œtð \´$ð \¸4ñ \r:   c                ó„   € V R,          pVP                  4       '       d!   \        W!R,          \        V4      RR7       R# R# )aX  Copy the source's user-installed plugins (``plugins/`` with ``.install-metadata.json``).

``config.yaml`` already carries ``plugins.enabled`` and ``memory.provider``; without the code a
catalog-installed memory provider resolves nowhere in the clone, so the clone silently runs
without its memory (or, with lazy installs on, re-fetches the latest catalog pin instead of the
revision the source runs). The copy keeps each plugin's tree, revision and catalog provenance
(the install record). Python dependencies live in the shared venv, where the source's
selection of the same plugin already put them.ÚpluginsT©r²  N)r  rÀ  rá  )rO   r  Úsource_pluginss   && r8   Ú_clone_pluginsrç  /  s=   € ð   )Õ+€NØ×Ñ×ÒÜ  ¸yÕ1HÜ!6°~Ó!FÐVZ÷	\ñ r:   c                óF   € V ^8„  d   QhR\         R\        \        ,          /# rÏ  rŸ  )r7   s   "r8   r9   r9   >  s   € ÷ ñ ¤Tð ¬d´3­iñ r:   c                óx   €  \        R V R,          P                  4        4       4      #   \         d    . u # i ; i)z@Plugins a clone now carries in ``plugins/``, for the CLI notice.c              3   óÜ   "  € T Fb  pVP                   P                  R 4      '       d   K&  VP                  4       '       g   VP                  4       '       g   KT  VP                   x € Kd  	  R# 5i)r  N)rá   r®  r  r¢  rs   s   & r8   rv   Ú&cloned_plugin_names.<locals>.<genexpr>A  sH   é € ð XÑ&I ØŸV™V×.Ñ.¨s×3ô Ø9:¿¹¿ºÀqÇ|Á|Ç~ô �a—f–fÓ&Iùs   ‚#A,ªA,Á A,ÁA,rä  )r#  r$  rE   )r  s   &r8   Úcloned_plugin_namesrì  >  sF   € ðÜñ X {°YÕ'>×&GÑ&GÔ&Ió Xó Xð 	Xøäô ØŠ	ðús   ‚&) ©9¸9c                óV   € V ^8„  d   QhR\         R\        \         ,          R\        RR/# )r/   r  rO   Úsync_importsr2   N)r   r   rƒ   )r7   s   "r8   r9   r9   G  s4   € ÷ Añ A¬ð A¼(Ä4½.ð AÜ)-ðAØ:>ñAr:   c           
     ó"  € V P                  RRR7       \         F  pW,          P                  RRR7       K  	  Vf   \        V 4       R# \         F  p\	        WV4       K  	  \        V R,          4       VR,          pVP                  4       '       d   \        WPR,          \        RR7       \         F  p\	        WV4       K  	  \        W4       ^ RIHpHp V! WV! \        VR,          4      4      4       V'       d   \	        WR4       R# R# )	ah  Fresh layout: bootstrap dirs, then either seed a model block (no source) or clone
config files, installed skills (the dashboard's "clone from default" must keep bundled
AND user-installed skills), and memory/identity files from *source_dir*.

``sync_imports`` also copies the source's ``import-sync.json`` (the manifest the agent-importers
plugin's ``hermes import-agent`` writes) so the clone stays registered against the same external trees
and ``hermes -p <clone> import-agent --sync`` keeps pulling from them. The link is to the
external tree, never to the source profile: both profiles stay independent islands.TrV  Nrq  r  rå  )Úactive_memory_providerÚclone_memory_provider_configzimport-sync.json)rZ  rÇ  rï  Ú_CLONE_CONFIG_FILESr�  rÓ  r  rÀ  rM   Ú_CLONE_SUBDIR_FILESrç  Ú hermes_cli.profile_memory_configrð  rñ  rº  )r  rO   rî  rÌ  r–  Úsource_skillsrð  rñ  s   &&&     r8   Ú_bootstrap_profile_dirrö  G  så   € ð ×Ñ˜d¨TÐÔ2ßˆØ	Õ	×$Ñ$¨T¸DÐ$ÖAñ  àÒÜ˜;Ô'Ùß&ˆÜ�J¨WÖ5ñ 'ä˜+¨Õ5Ô6Ø Õ)€MØ×Ñ×ÒÜ  ¸hÕ0FÔH_ÐosÕtß&ˆÜ�J¨WÖ5ñ 'ä�:Ô+ßeÙ  Ù!7¼È
ÐUbÕHbÓ8cÓ!dôfçÜ�JÐ-?Ö@ñ r:   c                óÞ   € V ^8„  d   QhR\         R\        \         ,          R\        R\        R\        R\        R\        \         ,          R\        R	\        R
\        \         ,          R\        /# )r/   rá   r�  Ú	clone_allÚclone_configÚno_aliasÚ	no_skillsr¤  Úclone_channelsrî  Úsoulr2   )r4   r   rƒ   r   )r7   s   "r8   r9   r9   g  s‡   € ÷ Tñ TÜ
ðTÜ#¤C�=ðTÜ<@ðTÜX\ðTäðTä'+ðTäBJÌ3Å-ðTô ðTô 15ðTô EMÌSÅMðTô 
ñ	Tr:   c
                ó  € V'       d    Vf   V'       g	   V'       d   \        R4      hV'       d   V'       g   V'       g   \        R4      hVRJ;'       g    T;'       g    Tp
V'       d   V
'       g   \        R4      h\        V 4      pVR8X  d   \        R4      h\        V4      pVP                  4       '       dp   \	        V4      '       g_   \        V4      '       d<   \        V^ R7      '       g   \        RV R	V 24      h\        P                  ! V4       M\        RV R
V R24      hVP                  4       '       d   \        V4      hV
'       d   \        V4      MRpVeF   V'       d>   ^ RIHp T! YÑ;'       g    \        4       ;'       g    R4      pV'       d   \        V4      h\        V4       \!        V4      p V'       d   V'       d   \#        VVV4       M\%        VWØR7       Ve8   V'       g0   ^ RIHp V! VW-R7      pV'       d   \(        P+                  RVV4       ^ RIHp V! VWRWiR7       \0        P2                  ! VV4       \7        T4       \9        T4       T#   \4         d    \        P                  ! TRR7       h i ; i)u§  Create a new profile directory and return its path.

``clone_from`` defaults to the active profile when cloning. ``clone_all`` copies all state;
``clone_config`` copies config.yaml/.env/SOUL.md, installed skills, and identity files.
Either clone strips the source's messaging channels â€” bot tokens, allowlists, platform
sections, pairing/session state â€” unless ``clone_channels`` opts in: a copied bot credential
makes two gateways fight over one bot (``hermes_cli.profile_channels``; callers list what
was left behind with ``channel_platforms_configured(source_dir)``).
``no_skills`` creates an empty profile and writes a marker so ``hermes update`` skips
re-seeding its skills; it is mutually exclusive with the clone options, which copy skills.
``sync_imports`` (``--clone`` only; ``--clone-all`` copies the file anyway) also copies the
``import-agent`` sync manifest so the clone can keep pulling the same external agent trees.Nz‡--no-skills is mutually exclusive with --clone / --clone-from / --clone-all (cloning explicitly copies skills from the source profile).zu--sync-imports requires --clone or --clone-from (there is no import manifest to carry over without a source profile).zP--clone-channels only applies to a clone (--clone, --clone-from or --clone-all).rö   uS   Cannot create a profile named 'default' â€” it is the built-in profile (~/.hermes).)r<  zCannot create profile 'z ': a running gateway still owns ú': zt exists but carries no profile identity file, so it is not listed as a profile. Move or remove that directory first.)Úclone_channels_refusal)rî  )Ústrip_channel_settings)Úinclude_staterO   z0profile %s: cloned without messaging channels %s)Úfinish_profile_layout)rû  rø  r¤  rý  T©Úignore_errors)rX   r	  r  ry  r   r   r   rÜ   r]  ÚrmtreerÞ   r‘  Úhermes_cli.profile_channelsr   r‰  r   Ú_clone_staging_dirrÎ  rö  r  rm  rÆ  Ú"hermes_cli.profiles_initializationr  r@   ÚrenameÚBaseExceptionÚ_maybe_register_gateway_serviceÚ_notify_multiplexer)rá   r�  rø  rù  rú  rû  r¤  rü  rî  rý  ÚcloningrÐ   r  rO   r   ÚrefusalÚstagingr  rú   r  s   &&&&&&&&&&          r8   Úcreate_profiler  g  s7  € ÷" �jÒ,·Ç	ÜðJó
ð 	
÷ Ÿ\¯YÜð Mó Nð 	Nà Ð$×AÐA¨	×AÐA°\€GßŸgÜÐkÓlÐlÜ˜Ó€EØ�	ÔÜÐnÓoÐoÜ! %Ó(€KØ×Ñ×ÒÔ$>¸{×$KÒ$KÜ# K×0Ò0ô (¨¸Q×?Ó?Ü%Ð(?À¸wÐFfÐgrÐfsÐ&tÓuÐuÜ�MŠM˜+Õ&ô "Ø)¨%¨°°K°=ð A_ð _óð ð ×Ñ×ÒÜ# EÓ*Ð*ß6=Ô& zÔ2À4€JØÒ§.ÝFÙ(¨×5iÐ5iÔCZÓC\×5iÐ5iÐ`iÓjˆßÜ˜WÓ%Ð%Ü Ô,ô
 ! Ó-€GðßŸÜ˜J¨°Õ7ä" 7¨JÕRØÒ!¯.ÝJÙ-¨gÀYÔfˆHßÜ—‘ÐNÐPUÐW_Ô`ÝLÙ˜g°Ð]hÕtÜ
�	Š	�'˜;Ô'ô $ EÔ*ô ˜ÔØÐøô ô Ü�Š�g¨TÕ2Øðús   ÇI' Ç&I' Ç8AI' É'%Jc                ó0   € V ^8„  d   QhR\         R\         /# rÏ  r   )r7   s   "r8   r9   r9   ¾  s   € ÷ 	ñ 	¤Dð 	¬Tñ 	r:   c                ó„  € V P                   RV P                   R\        P                  ! 4        2,          pV P                   P	                  RRR7       VP                  4       '       g   VP                  4       '       d   VP                  4        V# VP                  4       '       d   \        P                  ! VRR7       V# )z Fresh ``profiles/.<name>.staging-<pid>`` beside the final dir (same filesystem, so the publish
rename is atomic). A leftover from a crashed create is discarded.r  z	.staging-TrV  r  )r™  rá   r@   ÚgetpidrZ  r¢  rŠ  rl  r  r]  r  )r  r  s   & r8   r  r  ¾  s•   € ð × Ñ  Q {×'7Ñ'7Ð&8¸	Ä"Ç)Â)Ã+ÀÐ#OÕO€GØ×Ñ×Ñ T°DÐÔ9Ø×Ñ×Ò˜wŸ™×0Ò0Ø�‰Ôð €Nð 
�‰×	Ò	Ü�Š�g¨TÕ2Ø€Nr:   c                ó(   € V ^8„  d   QhR\         RR/# )r/   rÐ   r2   Nrâ   )r7   s   "r8   r9   r9   Ê  s   € ÷ /ñ /œsð / tñ /r:   c                 ó"   € ^ RI Hp V! V 4       R# )rá  )Ú#notify_multiplexer_profiles_changedN)Ú#hermes_cli.gateway_multiplex_servedr  )rÐ   r  s   & r8   r  r  Ê  s   € ÝWÙ'¨Ö.r:   c                ó0   € V ^8„  d   QhR\         R\        /# rÏ   r  )r7   s   "r8   r9   r9   Ï  s   € ÷ )ñ )œ3ð )¤4ñ )r:   c                ó   € ^ RI Hp V! V 4      # )uû   Settle a deleted profile's durable identity (``profile_identity.purge_profile_identity``).

False means the filesystem delete happened but the identity settlement did not â€” the caller
reports that as a pending settlement rather than a clean success.)Úpurge_profile_identity)Úhermes_cli.profile_identityr  )rÐ   r  s   & r8   Ú_purge_identityr  Ï  s   € õ
 CÙ! %Ó(Ð(r:   c                ó$   € V ^8„  d   QhR\         /# rŸ   rL  )r7   s   "r8   r9   r9   Ø  s   € ÷ ñ ¤4ñ r:   c                 óF   €  ^ RI Hp  V ! 4       RJ#   \         d     R# i ; i)z¨True when a live default gateway has recorded a served-profile set: every dir under
profiles/ is then served by it, so a profile-identity change must be unrouted first.©Úrecorded_served_profilesNF)r  r!  rÌ   r   s    r8   Ú_live_default_multiplexerr"  Ø  s*   € ðÝPÙ'Ó)°Ð5Ð5øÜô Úðús   ‚ ‘ Ÿ c                óR   € V ^8„  d   QhR\         R\        R\        \        ,          /# )r/   r  rx  r2   )r   rƒ   r   r†  )r7   s   "r8   r9   r9   â  s%   € ÷ ñ ¤Tð ´$ð Ä8ÌDÅ>ñ r:   c                ó`  € \        \        4      P                  P                  P                  4       p \        P
                  ! \        P                  RR./ \        P                  CR\        V 4      /C\        V4      RRRR^<RR7	      pVP                  ^ 8X  dO   VP                  P                  4       '       d/   \        P                  ! VP                  P                  4       4      # V'       gf   \!        R	VP                   24       VP"                  P                  4       '       d.   \!        R
VP"                  P                  4       R,           24       R#   \        P$                   d    T'       g   \!        R4        R# \&         d"   pT'       g   \!        RT 24        Rp?R# Rp?ii ; i)a  Seed bundled skills into a profile via subprocess (sync_skills() caches HERMES_HOME at
module level). Returns the sync result dict, or None on failure. ``--no-skills`` profiles
still run the sync: ``sync_skills()`` detects the marker and seeds only essentials.z-cziimport json; from tools.skills_sync import sync_skills; r = sync_skills(quiet=True); print(json.dumps(r))ÚHERMES_HOMETr7  r8  F)ÚenvÚcwdr9  r:  rÈ   r;  r<  r=  u%   âš  Skill seeding returned exit code z  :NéÈ   NNu!   âš  Skill seeding timed out (60s)u   âš  Skill seeding failed: )r   Ú__file__r™  rW   r@  rA  r¶   Ú
executabler@   rP  r4   rB  rC  rè   ÚjsonÚloadsr[  ÚstderrrE  rÌ   )r  rx  Úproject_rootrG  rf  s   &&   r8   Úseed_profile_skillsr/  â  sO  € ô œ“>×(Ñ(×/Ñ/×7Ñ7Ó9€LðÜ—’Ü�^‰^˜TðAðBð @”2—:‘:Ð?˜}¬c°+Ó.>Ñ?Ü�LÓ!Ø d°WÀYÐXZØô
ˆð ×Ñ Ô! f§m¡m×&9Ñ&9×&;Ò&;Ü—:’:˜fŸm™m×1Ñ1Ó3Ó4Ð4ßÜÐ9¸&×:KÑ:KÐ9LÐMÔNØ�}‰}×"Ñ"×$Ò$Ü˜˜6Ÿ=™=×.Ñ.Ó0°Õ6Ð7Ð8Ô9ÙøÜ×$Ñ$ô ßÜÐ5Ô6ÚÜô ßÜÐ.¨q¨cÐ2Ô3Ýûðús=   ³BE Â:-E Ã(E Ã0A%E ÅF-Å4F-ÆF-ÆF-ÆF(Æ(F-c                óF   € V ^8„  d   QhR\         R\        \        ,          /# )r/   rx  r2   )rƒ   r5   r4   )r7   s   "r8   r9   r9     s   € ÷ ñ ¤ð ´$´sµ)ñ r:   c                ó  € . p\        4       R,          p\        4        F¤  pVR,          pVP                  4       '       d   K$   VP                  4       '       d   \        P
                  ! W$4       MVP                  \        RR7       \        P                  ! \        V4      R4       VP                  VP                  4       K¦  	  V#   \         d5   pT '       g"   \        RTP                   RT 24        Rp?KÞ   Rp?Kä  Rp?ii ; i)uØ  Give every named profile predating per-profile ``.env`` one (copy of the default's, or
the placeholder header). Never overwrites an existing profile ``.env``.

Profiles created before the dashboard/CLI started seeding a ``.env`` (PR #44792) have none, so once the
Channels/Keys endpoints became profile-scoped those profiles stopped inheriting the root install's
credentials and showed everything as unconfigured. To avoid breaking anyone on update, copy the DEFAULT
install's ``.env`` into each named profile that lacks one â€” that preserves the effective credentials
those profiles were already running with (they previously read the root ``.env`` via the process
environment). Users can then diverge per profile from there.
r   r7  rÇ   r˜  u%   âš  Could not seed .env for profile 'rÿ  N)r`   r&  ry  rŠ  r]  rš  r\  Ú_PLACEHOLDER_ENVr@   r`  r4   rA  rá   rE   r[  )rx  Ú
backfilledÚdefault_envrK   Úenv_pathrf  s   &     r8   Úbackfill_profile_envsr6    sÖ   € ð €JÜ*Ó,¨vÕ5€KÜ)Ö+ˆØ˜6•>ˆØ�?‰?×ÒÙð		RØ×"Ñ"×$Ò$Ü—’˜[Õ3à×#Ñ#Ô$4¸wÐ#ÔGÜ�HŠH”S˜“] EÔ*Ø×Ñ˜eŸj™jÖ)ñ ,ð Ðøô ô 	RßÜÐ=¸e¿j¹j¸\ÈÈQÈCÐP×QÒQõ ûð	Rús   ÁCÁA)CÃDÃ#DÄDz^python[\d.]*w?(\.exe)?$c                ó0   € V ^8„  d   QhR\         R\        /# )r/   Úargvr2   )r5   rƒ   )r7   s   "r8   r9   r9   -  s   € ÷ 
ñ 
œ$ð 
¤4ñ 
r:   c                ód  a€ RP                  V 4      o\        P                  P                  V ^ ,          4      P	                  4       p\
        ;QJ d#    V3R l\         4       F  '       g   K   RM	  RM! V3R l\         4       4      '       g   VP                  R4      '       d   R# \        V 4      ^8¼  dy   \        P                  V4      '       d^   \        P                  P                  \        V ^,          4      4      P	                  4       pVP                  R^4      ^ ,          \        9   # R# )z¥True for a Hermes process: entrypoint marker in argv, executable named ``hermes*``,
or a python interpreter directly exec'ing a known ``hermes`` console-script shim.Ú c              3   ó,   <"  € T F	  qS9   x € K  	  R # 5ir|   r¢   )rt   ÚmarkerÚjoineds   & €r8   rv   Ú"_is_hermes_argv.<locals>.<genexpr>2  s   øé € Ð
?Ñ*> �VÖÓ*>ùs   ƒTFrY  r  )rC   r@   rB   Úbasenameré   rŽ   Ú_HERMES_ARGV_MARKERSr®  r‡   Ú_PYTHON_INTERPRETER_RErë   r4   ÚrsplitÚ_HERMES_CONSOLE_SCRIPT_NAMES)r8  Úexe_nameÚscript_namer=  s   &  @r8   Ú_is_hermes_argvrF  -  sÌ   ø€ ð �X‰X�d‹^€FÜ�w‰w×Ñ  Q¥Ó(×.Ñ.Ó0€Hß
ƒsÔ
?Õ*>Ó
?‡s‡s‚sÔ
?Õ*>Ó
?×?Ò?À8×CVÑCVÐW_×C`ÒC`ÙÜ
ˆ4ƒy�A„~Ô0×6Ñ6°x×@Ò@Ü—g‘g×&Ñ&¤s¨4°­7£|Ó4×:Ñ:Ó<ˆØ×!Ñ! # qÓ)¨!Õ,Ô0LÑLÐLÙr:   c                ó$   € V ^8„  d   QhR\         /# )r/   r8  )r5   )r7   s   "r8   r9   r9   :  s   € ÷ 'ñ '¤$ñ 'r:   c              #  ó   "  € \        V 4       Fj  w  rVR9   d+   V^,           \        V 4      8  d   W^,           ,          x € K6  VP                  R4      '       g   KO  VP                  R^4      ^,          x € Kl  	  R# 5i)zSYield every profile name selected via ``-p X`` / ``--profile X`` / ``--profile=X``.z
--profile=Ú=N>   ú-pú	--profile)Ú	enumerater‡   r®  rr   )r8  ÚiÚtoks   &  r8   Ú_argv_profile_selectorsrO  :  s^   é € ä˜D–/‰ˆØÐ%Ô%¨!¨a­%´#°d³)Ô*;Ø˜1•u•+ÔØ�^‰^˜L×)Ô)Ø—)‘)˜C Ó# AÕ&Ô&ó	 "ùs   ‚AA>Á!A>c                óR   € V ^8„  d   QhR\         R\        R\        \        ,          /# )r/   rÐ   r  r2   )r4   r   r5   r©  )r7   s   "r8   r9   r9   C  s%   € ÷ 3ñ 3¤sð 3¼ð 3Ä$ÄsÅ)ñ 3r:   c                óX  a €  ^ RI p TP                  4       p\        P
                  ! 4       0p\        P                  ! \        4      ;_uu_ 4        TP                  \        P
                  ! 4       4      P                  4       pTe.   TP                  TP                  4       TP                  4       pK1   RRR4        TP                  \        P
                  ! 4       4      P                  4       p. pTP                  . R
O4       EF¦  p TP                  p	T	P                  R4      p
T
e   Y¤9   d   K.  Te   T	P                  R4      T8w  d   KJ  T	P                  R4      ;'       g    . pT'       d   \!        T4      '       g   K€  T Uu0 uF  qÌP#                  4       kK  	  up\$        ,          '       g   K²  \&        ;QJ d(    T 3R l\)        T4       4       F  '       g   K   RM	  RM! T 3R l\)        T4       4       4      pT'       g…   \        P                  ! \        4      ;_uu_ 4        TP+                  4       ;'       g    / P                  RR	4      p\-        T4      ;'       d    \/        T4      P                  4       T8H  pRRR4       T'       d   TP1                  T
4       EK¦  EK©  	  T#   \         d    . u # i ; i  \         d    Tp EL½i ; i  + '       g   i     EL-; i  \         d    Rp ELi ; iu upi   + '       g   i     L‡; i  \         d     EK#  i ; i)a)  PIDs of running Hermes *backends* bound to this profile (``gateway.pid`` only tracks
the messaging gateway). Tightly scoped: current-user processes, backend subcommands only
(never an interactive ``chat``/``tui``), never this process or its ancestors. Empty when
``psutil`` can't inspect anything.NÚpidÚusernameÚcmdlinec              3   ó@   <"  € T F  p\        V4      S8H  x € K  	  R # 5ir|   )rû   )rt   ÚselrÐ   s   & €r8   rv   Ú._profile_bound_backend_pids.<locals>.<genexpr>m  s   øé € ÐfÑHeÀÔ.¨sÓ3°uÖ<ÓHeùs   ƒTFr%  rO  )rR  rá   rS  rT  )ÚpsutilrÌ   rW   rE   r@   r  r-  r.  ÚProcessr™  r?   rR  rS  Úprocess_iterrÆ  rQ  rF  ré   Ú_BACKEND_TOKENSrŽ   rO  rP  rƒ   r   rA  )rÐ   r  rX  Úresolved_dirÚskipr™  Úcurrent_userÚpidsÚprocrÆ  rR  r8  rN  ÚboundÚenv_homes   f&             r8   Ú_profile_bound_backend_pidsrc  C  sc  ø€ ð
Ûð#Ø"×*Ñ*Ó,ˆô —i’i“k�]€DÜ	×	Ò	œY×	'Õ	'Ø—‘¤§	¢	£Ó,×3Ñ3Ó5ˆØÒ Ø�H‰H�V—Z‘ZÔ Ø—]‘]“_ŠFð !÷ 
(ð
Ø—~‘~¤b§i¢i£kÓ2×;Ñ;Ó=ˆð €DØ×#Ñ#Ò$J×Kˆð	Ø—9‘9ˆDØ—(‘(˜5“/ˆCØŠ{˜cœkÙØÒ'¨D¯H©H°ZÓ,@ÀLÔ,PÙØ—8‘8˜IÓ&×,Ð,¨"ˆDßœ¨t×4Ò4ÙÙ,0Ó1©D S—Y‘Y–[©DÑ1´O×CÔCÙ÷ “CÔfÔH_Ð`dÔHeÓf—C—C’CÔfÔH_Ð`dÔHeÓfÓfˆEßÜ×(Ò(¬×3Õ3Ø $§¡£× 4Ð 4°"×9Ñ9¸-ÈÓL�HÜ  ›N×WÐW¬t°H«~×/EÑ/EÓ/GÈ<Ñ/W�E÷ 4÷ Ø—‘˜C× ò ñ) Lð0 €KøôY ô ØŠ	ðûô ô #Ø"‹ð#ú÷ 
(×	'Ð	'ûô ô Ø‹ðüò 2÷ 4×3ûô
 ô 	Ûð	ús¿   ƒJ2 ˆK ÁA$KÂ>2K- Ä
'LÄ3LÅLÅ'
LÅ2LÆLÆ	LÆ!LÆ7
LÇLÇ"(LÈ"LÈ-<LÉ*LÊLÊLÊ2KËKËKËKËK*	Ë-K>Ë=K>ÌLÌLÌLÌL)Ì(L)Úwaitg      $@c                ó^   € V ^8„  d   QhR\         \        ,          R\        R\        R\        /# )r/   r_  Ústart_timesrd  r2   )r5   r©  r†  r  rƒ   )r7   s   "r8   r9   r9   y  s-   € ÷ ñ ¤¤S¥	ð ¼ð Äuð ÔX\ñ r:   c               ó  a€ ^ RI HoHpHp \	        \        VR,          4      4       F\  p\        P                  ! R4       \        ;QJ d    V3R lV  4       F  '       g   K   RM	  RM! V3R lV  4       4      '       d   K[   R# 	  V  Fh  pS! V4      '       g   K  \        P                  ! \        \        \        4      ;_uu_ 4        V! VRVP                  Wc! V4      4      R7       RRR4       Kj  	  R#   + '       g   i     K  ; i)zùAfter a graceful ``terminate_pid``, wait up to *wait* seconds (0.5s polls) for *pids*
to exit, then force-kill stragglers. True when every pid exited gracefully.
``start_times`` pins each force kill to the same process incarnation (PID reuse guard).)Ú_pid_existsÚget_process_start_timeÚterminate_pidg      à?c              3   ó4   <"  € T F  pS! V4      x € K  	  R # 5ir|   r¢   )rt   rR  rh  s   & €r8   rv   Ú(_wait_then_force_kill.<locals>.<genexpr>€  s   øé € Ð4©t¨‘;˜s×#Ð#«tùs   ƒTF)ÚforceÚexpected_start_timeN)rú  rh  ri  rj  Úranger©  r  ÚsleeprŽ   r-  r.  ÚProcessLookupErrorÚPermissionErrorrE   rQ  )r_  rf  rd  ri  rj  r  rR  rh  s   &&$    @r8   Ú_wait_then_force_killrs  y  s¹   ø€ ÷ RÑQÜ”3�t˜c•z“?Ö#ˆÜ�
Š
�3Œß‹sÔ4©tÓ4�s�sŠsÔ4©tÓ4×4Ô4Úñ $ó ˆÙ�s×ÔÜ×$Ò$Ô%7¼Ì'×RÕRÙ˜c¨À;Ç?Á?ÐSVÐXnÐorÓXsÓCtÕu÷ SÑRñ ñ ÷ S×RÐRús   Ã!C7Ã7Dc                ó4   € V ^8„  d   QhR\         R\        RR/# )r/   rÐ   r  r2   Nr²   )r7   s   "r8   r9   r9   ‰  s&   € ÷ Bñ B¤#ð B´Dð B¸Tñ Br:   c                ó  € \        W4      pV'       g   R#  ^ RIHp T F  p T! T4       K  	  \        T/ 4       \        R\        T4       R24       R#   \         d     R# i ; i  \        \
        \        3 d     Ka  i ; i)zûTerminate Desktop-spawned / stray backends bound to this profile. Complements
``_stop_gateway_process`` (which only knows ``gateway.pid``): a live ``serve``/``dashboard``
keeps creating files while ``rmtree`` walks, so the final rmdir fails ENOTEMPTY.N)rj  u   âœ“ Stopped z profile backend process(es))
rc  rú  rj  rÌ   rq  rr  rE   rs  r[  r‡   )rÐ   r  r_  rj  rR  s   &&   r8   Ú_stop_profile_backendsrv  ‰  s…   € ô ' uÓ:€DßÙðÝ0ó ˆð	Ù˜#Öñ ô
 ˜$ Ô#Ü	ˆLœ˜T›˜Ð#?Ð
@ÖAøô ô Úðûô
 #¤O´WÐ=ô 	Úð	ús"   —A £A'ÁA$Á#A$Á'BÂ Bc                ó(   € V ^8„  d   QhR\         RR/# ro  r   )r7   s   "r8   r9   r9   �  s   € ÷ *ñ *¤4ð *¨Dñ *r:   c                óX  € ^ RI HpHp ^ RIHp VP                  4       '       g   R# V! V 4      p VP                  4       '       d"   \        R4       ^ RIHp VP                  4        T! T4       R#   \         d!   p\        P                  RY4        Rp?L0Rp?ii ; i  T! T4       i ; i)a}  Stop the profile's Bot Desktop (Xvnc + Xfce launcher) before its directory is removed or renamed;
gateway shutdown does not reach it (its own session, its own pid file). Scoped through the hermes-home
override so the runtime reads THIS profile's bot-desktop/ state, whichever profile invoked the op.
A failure here is logged, never fatal: the profile op is what the user asked for.rr  )ÚruntimeNu   âœ“ Bot Desktop stopped)Úleasez(Could not stop the Bot Desktop of %s: %s)r¨   rs  rt  Útools.bot_desktopry  Úis_supported_hostÚstopr[  rz  ÚreleaserÌ   rm  rn  )r  rs  rt  ry  r{  rz  rf  s   &      r8   Ú_stop_bot_desktopr  �  s‰   € ÷
 VÝ)Ø×$Ñ$×&Ò&ÙÙ$ [Ó1€Eð*Ø�<‰<�>Š>ÜÐ+Ô,õ 0Ø�M‰MŒOñ 	# 5Ö)øô ô SÜ�‰ÐAÀ;×RÑRûðSûñ 	# 5Õ)ús)   °7A1 Á1BÁ<BÂB ÂBÂB Â
B)c          
      ób   € V ^8„  d   QhR\         R\        R\        R\        \        ,          RR/# )r/   rÐ   r  Ú
gw_runningrg  r2   N)r4   r   rƒ   r   )r7   s   "r8   r9   r9   µ  s>   € ÷ Bñ B¤ð B´4ð BÄTð BÔYaÔbfÕYgð BÐlpñ Br:   c                óú  € \        V4      w  rE\        V4      p\        V4      w  rxp	\        RV  24       \        RV 24       V'       d$   \        RV 2V'       d   RV R2MR,           4       V'       d   \        RV 24       V'       d2   \        RT R	T;'       g    R
 24       V	'       d   \        RV	 24       \        R4       \        R4       Ve   \        RV R24       V'       d   \        R4       R# R# )z0Show what ``delete_profile`` is about to remove.z

Profile: z	Path:    z	Model:   rP  r>  rO  z	Skills:  zDistribution: Ú@Ú?zInstalled from: z
This will permanently delete:uA     â€¢ All config, API keys, memories, sessions, skills, cron jobsNu     â€¢ Command alias (u0     âš  Gateway is running â€” it will be stopped.)rè  r&  rÛ  r[  )
rÐ   r  r�  rg  r›  rœ  rž  rZ  r[  r\  s
   &&&&      r8   Ú_print_delete_summaryr…  µ  sê   € ä(¨Ó5�O€EÜ Ó,€KÜ+BÀ;Ó+OÑ(€I˜[Ü	ˆK˜�wÐ
Ô Ü	ˆI�k�]Ð
#Ô$ßÜ�	˜%˜Ð!¿ r¨(¨°1Ñ%5ÀrÕJÔKßÜ�	˜+˜Ð'Ô(ßÜ�˜y˜k¨¨<×+>Ð+>¸3Ð*?Ð@ÔAßÜÐ$ [ MÐ2Ô3Ü	Ð
+Ô,Ü	Ð
MÔNØÒÜÐ% l ^°1Ð5Ô6ßÜÐ@ÖAñ r:   c                   óB   a a€ ] tR tRt oRtV3R lV 3R lltRtVtV ;t# )Ú ProfileIdentitySettlementPendingiÌ  u  The profile's directory was deleted, but its durable session/routing identity was not
settled (``hermes_cli.profile_identity.purge_profile_identity`` returned False).

Subclasses ``RuntimeError`` so delete-failure handling that treats the error as fatal (the
CLI's ``hermes profile delete``) keeps working unchanged; surfaces that can report a partial
success (the dashboard's ``DELETE /api/profiles/{name}``) catch this type â€” it carries the
profile, its now-removed path, and the retry command â€” instead of matching on the message.
c                ó&   <€ V ^8„  d   QhRS[ RS[/# )r/   rd  rB   r²   )r7   rª  s   "€r8   r9   Ú-ProfileIdentitySettlementPending.__annotate__Ö  s   ø€ ÷ <ñ <¡ð <©4ñ <r:   c                ór   <€ Wn         W n        R V 2V n        \        SV `  RV RV P                   24       R# )zhermes profile purge-identity rÔ   uU   ' was deleted, but its session/routing identity settlement is still pending â€” run: N)rd  rB   Úretry_commandÚsuperÚ__init__)Úselfrd  rB   Ú	__class__s   &&&€r8   r�  Ú)ProfileIdentitySettlementPending.__init__Ö  sF   ø€ ØŒØŒ	Ø=¸g¸YÐGˆÔÜ‰ÑØ˜�yð !&Ø&*×&8Ñ&8Ð%9ð;ö	<r:   )rB   rd  r‹  )	rù   r¬  r­  r®  r¯  r�  r±  r²  Ú__classcell__)r�  rª  s   @@r8   r‡  r‡  Ì  s   ù‡ € ñ÷<÷ <ó <r:   r‡  c                ó<   € V ^8„  d   QhR\         R\        R\        /# )r/   rá   Úyesr2   )r4   rƒ   r   )r7   s   "r8   r9   r9   ß  s&   € ÷ eñ eœð e¤4ð e´Dñ er:   c                ó–  € \        V 4      pVR8X  d   \        R4      h\        V4      w  r#\        V4      p\	        V4      p\        W#WE4       V'       g<   \        4         \        RV R24      P                  4       pWb8w  d   \        R4       V# \        W#4       \        V4       V'       d   \        V4       \        W#4       \        V4       \!        V4       \#        V4       \%        V4      p^ RIHp ^ RIHp	 V	! V! V4      R	7       \.        P0                  ! \2        4      ;_uu_ 4        ^ R
IHp
 V
! RR4      P8                  P;                  V4      pV'       d   \        RV R24       RRR4       \.        P0                  ! \2        4      ;_uu_ 4        ^ RIHp V! V4      pV'       d   \        RV R24       RRR4       \.        P0                  ! \2        4      ;_uu_ 4        ^ RI H!p V! V4      pV'       d   \        RV R24       RRR4       V'       d    \E        V4      '       d   \        RV 24       Rp \G        V4      '       g   \I        R4      h\K        V\L        4       \        RV 24       \O        VRR4       Ve   \I        RV RV 24      Vh\        RV R24       V'       g   \Q        W#4      hV#   \        \        3 d    Rp\        4         ELci ; i  + '       g   i     EL€; i  + '       g   i     ELD; i  + '       g   i     EL; i  \2         d   p\        RT RT 24       Tp Rp?LÊRp?ii ; i)z‹Delete a profile, its wrapper script, and its gateway service (service disabled first
to prevent auto-restart, gateway stopped if running).rö   zZCannot delete the default profile (~/.hermes).
To remove everything, use: hermes uninstallzType 'z' to confirm: Nz
Cancelled.©Úhermes_home_key©Úshutdown_mcp_servers©Úscope)Úimport_provider_moduleÚholographicr‰   u   âœ“ Released z0 memory-store connection(s) held by this process)Úclose_all_underz4 session database connection(s) held by this process)Úrelease_profile_log_handlersz, profile log handler(s) held by this processu   âœ“ Removed zKa running gateway still owns this profile; retry the delete once it settlesu   âš  Could not remove rõ   u#   âœ“ Active profile reset to defaultz#Could not remove profile directory z

Profile 'z
' deleted.))rû   rX   r  rü  rÁ   r…  r[  Úinputrè   ÚKeyboardInterruptÚEOFErrorÚ_cleanup_gateway_serviceÚ!_maybe_unregister_gateway_serviceÚ_stop_gateway_processrv  r  r   r  r  r¨   r–  Útools.mcp_tool_lifecycler˜  r-  r.  rÌ   Úplugins.memoryr›  ÚMemoryStoreÚrelease_all_underÚhermes_state_registryr�  Úhermes_loggingrž  rm  r   ÚRuntimeErrorr   r   Ú_retarget_active_profiler‡  )rá   r“  rÐ   r  r�  rg  ÚconfirmÚidentity_settledr–  r˜  r›  Ú	_releasedÚ_close_session_dbs_underÚ_closedrž  Ú_released_logsÚremove_errorrf  s   &&                r8   Údelete_profiler´  ß  sÛ  € ô # 4Ó(€EØ�	ÔÜÐvÓwÐwÜ.¨uÓ5Ñ€EÜ'¨Ó4€JÜ$ UÓ+€LÜ˜%¨jÔGßÜŒð	Ü˜f U G¨>Ð:Ó;×AÑAÓCˆGð ÔÜ�,ÔØÐô ˜UÔ0Ü% eÔ,÷
 Ü˜kÔ*Ü˜5Ô.Ü�kÔ"ô ˜{Ô+ô
 ˜ÔÜ& uÓ-Ðõ 1Ý=Ù™¨{Ó;Õ<ô 
×	Ò	œY×	'Õ	'å9Ù*¨=¸'ÓB×NÑN×`Ñ`ÐalÓmˆ	ßÜ�M ) Ð,\Ð]Ô^÷ 
(ô 
×	Ò	œY×	'Õ	'ÝUÙ*¨;Ó7ˆßÜ�M ' Ð*^Ð_Ô`÷	 
(ô 
×	Ò	œY×	'Õ	'Ý?Ù5°kÓBˆßÜ�M .Ð!1Ð1]Ð^Ô_÷	 
(÷ Ô-¨e×4Ò4Ü�˜\˜NÐ+Ô,ð &*€Lð	ô $ K×0Ò0ÜÐlÓmÐmÜ˜;Ô(=Ô>Ü�˜[˜MÐ*Ô+ô ˜U IÐ/TÔUØÒÜÐ@ÀÀÈRÐP\È~Ð^Ó_ÐeqÐqÜ	ˆK˜�w˜jÐ
)Ô*ßô
 /¨uÓBÐBØÐøôo "¤8Ð,ô 	ØˆGÜ�Gð	ú÷L 
(×	'Ð	'ú÷ 
(×	'Ð	'ú÷ 
(×	'Ð	'ûô& ô ÜÐ% k ]°"°Q°CÐ8Ô9Ø�ûðúsO   Á K  Ä-A K$Æ&K8Ç'&LÈ?:L  Ë K!Ë K!Ë$K5	Ë8L		ÌL	Ì MÌ+MÍMc                 ó–   €  ^ RI Hp Hp V ! 4       R8w  d   R# V! 4       pTP	                  4       '       d   T# R#   \         d     R# i ; i)z¢The s6 service manager inside the container, else None. Silent on host: a failing/
absent detector must never print a confusing s6 warning to non-container users.)Údetect_service_managerÚget_service_managerÚs6N)Úhermes_cli.service_managerr¶  r·  rÌ   Úsupports_runtime_registration)r¶  r·  Úmgrs      r8   Ú_s6_runtime_managerr¼  G  sO   € ðßZÙ!Ó# tÔ+ÙÙ!Ó#ˆð ×3Ñ3×5Ò5ˆ3Ð?¸4Ð?øô ô Úðús   ‚9 ˜9 ¹AÁAc                ó(   € V ^8„  d   QhR\         RR/# ©r/   r�  r2   Nrâ   )r7   s   "r8   r9   r9   T  s   € ÷ Cñ C´#ð C¸$ñ Cr:   c                ó¶   € \        4       pVf   R#  VP                  V RR7       R#   \         d     R# \         d   p\	        RT 24        Rp?R# Rp?ii ; i)uñ  Register a profile's gateway with s6 inside the container. Best-effort: profile
creation must not fail over a supervision-tree hiccup; `gateway start` re-registers.

Port selection: each supervised profile gateway loads its own ``HERMES_HOME`` and binds the port
resolved by ``gateway/config.py`` from that profile's environment â€” ``API_SERVER_PORT`` (or
``platforms.api_server.extra.port`` in the profile's ``config.yaml``), defaulting to 8642. There is no
``[gateway] port`` key and no Python-side allocator (PR #30136 review item I5 retired the
SHA-256-derived range [9200, 9800) as dead code), so two profiles that both leave the port at its
default will both try to bind 8642 â€” give each profile a distinct ``API_SERVER_PORT`` in its ``.env``.
NF)Ú	start_nowu+   âš  Could not register s6 gateway service: )r¼  Úregister_profile_gatewayrX   rÌ   r[  ©r�  r»  rF  s   &  r8   r  r  T  s]   € ô Ó
€CØ
‚{ÙðCØ×$Ñ$ \¸UÐ$ÖCøÜô ÚÜô CÜÐ;¸C¸5ÐA×BÒBûðCús   ’' §AµA¾A¿AÁAc                ó(   € V ^8„  d   QhR\         RR/# r¾  râ   )r7   s   "r8   r9   r9   j  s   € ÷ Eñ E´Cð E¸Dñ Er:   c                ó˜   € \        4       pVf   R#  VP                  V 4       R#   \         d   p\        RT 24        Rp?R# Rp?ii ; i)zVTear down a profile's s6 gateway service inside the container; host no-op, idempotent.Nu-   âš  Could not unregister s6 gateway service: )r¼  Úunregister_profile_gatewayrÌ   r[  rÂ  s   &  r8   r£  r£  j  sK   € ä
Ó
€CØ
‚{ÙðEØ×&Ñ& |Ö4øÜô EÜÐ=¸c¸UÐC×DÒDûðEús   ’% ¥A	°AÁA	c                ó<   € V ^8„  d   QhR\         R\        R\        /# )r/   rá   r  r2   r  )r7   s   "r8   r9   r9   u  s!   € ÷ 3ñ 3¤3ð 3´Tð 3¼dñ 3r:   c                ó  € ^ RI p^ RIHpHp \        P
                  P                  R4      pV! \        V4      4      p \        V4      \        P
                  R&   ^ RIH	pH
pHp	 R R lp
^ RIHpHpHp VP!                  4       pRpVR	8X  d”   V! 4       pV	! 4       V R
2,          pVP#                  4       '       dS   V! VV4      '       dD   V
! RRRV4       V
! RRRV4       VP%                  RR7       V
! RRR4       \'        RV R24       RpV! V4      ;'       g    TpMtVR8X  d`   V! 4       pVP#                  4       '       dB   V! VV4      '       d3   V
! RR\        V4      4       VP%                  RR7       \'        R4       RpMVR8X  d   V! 4       pTV! V4       \        P
                  P)                  RR4       Ve   V\        P
                  R&   # #   \*         d   p\'        RT 24        Rp?MRp?ii ; i T! T4       \        P
                  P)                  RR4       Te   T\        P
                  R&   R#   T! T4       \        P
                  P)                  RR4       Te   T\        P
                  R&   i i ; i)zWDisable and remove systemd/launchd service for a profile; True when a unit was removed.Nrr  r%  )Úget_service_nameÚget_launchd_plist_pathÚuser_systemd_unit_dirc                ó(   € V ^8„  d   QhR\         RR/# )r/   Úcmdr2   Nrâ   )r7   s   "r8   r9   Ú._cleanup_gateway_service.<locals>.__annotate__ƒ  s   € ÷ 	Tñ 	T”sð 	T˜tñ 	Tr:   c                  óL   € \         P                  ! \        V 4      R R^
R7       R# )TF)r9  r=  r<  N)r@  rA  r5   )rÌ  s   *r8   Ú_runÚ&_cleanup_gateway_service.<locals>._runƒ  s   € Ü�NŠNœ4 ›9°TÀÐPR×Sr:   )Úowned_by_profileÚremove_system_systemd_unitÚremove_windows_taskFÚLinuxz.serviceÚ	systemctlz--userÚdisabler}  TrÃ  zdaemon-reloadu   âœ“ Service z removedÚDarwinÚ	launchctlÚunloadu   âœ“ Launchd service removedÚWindowsu   âš  Service cleanup: )r·   r¨   rs  rt  r@   rP  rQ  r4   r   rÈ  rÉ  rÊ  Ú#hermes_cli.profiles_service_cleanuprÑ  rÒ  rÓ  Úsystemry  rl  r[  rJ  rÌ   )rá   r  Ú	_platformrs  rt  Úold_homeÚ
home_tokenrÈ  rÉ  rÊ  rÏ  rÑ  rÒ  rÓ  rÜ  ÚremovedÚsvc_nameÚsvc_fileÚ
plist_pathrf  s   &&                  r8   r¢  r¢  u  s>  € ã ÷
 VÜ�z‰z�~‰~˜mÓ,€HÙ)¬#¨kÓ*:Ó;€Jð(1Ü$'¨Ó$4Œ�
‰
�=Ñ!ßfÑfõ	T÷ 	zÑyà×!Ñ!Ó#ˆØˆØ�WÔÙ'Ó)ˆHÙ,Ó.°H°:¸XÐ1FÕFˆHØ�‰× Ò Ñ%5°hÀ×%LÒ%LÙ�[ (¨I°xÔ@Ù�[ (¨F°HÔ=Ø—‘¨4�Ô0Ù�[ (¨OÔ<Ü˜ X J¨hÐ7Ô8Ø�ñ 1°Ó=×HÐHÀ‰GØ�xÔÙ/Ó1ˆJØ× Ñ ×"Ò"Ñ'7¸
ÀK×'PÒ'PÙ�[ (¬C°
«OÔ<Ø×!Ñ!¨TÐ!Ô2ÜÐ3Ô4Ø�øØ�yÔ Ù)Ó+ˆGØñ 	# :Ô.Ü
�
‰
�‰�} dÔ+ØÒØ(0ŒB�J‰J�}Ò%ð  øô ô +ÜÐ% a SÐ)×*Ñ*ûð+úØ*á" :Ô.Ü
�
‰
�‰�} dÔ+ØÒØ(0ŒB�J‰J�}Ñ%Ùøñ	 	# :Ô.Ü
�
‰
�‰�} dÔ+ØÒØ(0ŒB�J‰J�}Ò%ð  úsK   ¾A<G Â;G Ã
AG Ä'G ÅG ÅAG ÇG9Ç!G4Ç/H> Ç4G9Ç9H> È>AJ c                ó(   € V ^8„  d   QhR\         RR/# ro  r   )r7   s   "r8   r9   r9   «  s   € ÷ !2ñ !2¤tð !2°ñ !2r:   c                ó¸  € V R,          pVP                  4       '       g   R#  VP                  RR7      P                  4       pVP                  R4      '       d   \        P
                  ! V4      MR\        V4      /p\        VR,          4      p^ RIHpH	pH
p V! W0R7      '       d   \        R	V R
V  R24       R# VP                  R4      pVf	   V! V4      pV! V4       \        V.WH/4      '       d   \        RV R24       R# \        RV R24       R#   \        \        3 d    \        R4        R# \          d   p	\        RT	 24        Rp	?	R# Rp	?	ii ; i)z0Stop a running gateway process via its PID file.r   NrÆ   rÇ   Ú{rR  )ri  Úrecorded_gateway_home_conflictsrj  )Úexpected_homeu   âœ— Refusing to stop PID z?: its recorded HERMES_HOME belongs to a different profile than z% (stale/poisoned PID record, #89315).Ú
start_timeu   âœ“ Gateway stopped (PID r>  u   âœ“ Gateway force-stopped (PID u   âœ“ Gateway already stoppedu   âš  Could not stop gateway: )ry  r·  rè   r®  r+  r,  r©  rú  ri  rç  rj  r[  rQ  rs  rq  rr  rÌ   )
r  Úpid_filerB  r¹  rR  ri  rç  rj  rn  rf  s
   &         r8   r¤  r¤  «  sG  € à˜]Õ*€HØ�?‰?×ÒÙð2Ø× Ñ ¨+Ð Ó6×<Ñ<Ó>ˆØ"%§.¡.°×"5Ò"5Œt�zŠz˜#Œ¸EÄ3ÀsÃ8Ð;LˆÜ�$�u•+Óˆ÷ 	jÑiÙ*¨4×KÓKÜØ+¨C¨5ð 17Ø7B°mð D7ð7ôñ
 ð #Ÿh™h |Ó4ÐØÒ&Ù"8¸Ó"=ÐÙ�cÔÜ  # ¨Ð(B×CÒCÜÐ-¨c¨U°!Ð4Ö5äÐ3°C°5¸Ð:Ö;øÜ¤Ð0ô -ÜÐ+×,Üô 2ÜÐ,¨Q¨CÐ0×1Ò1ûð2ús7   £6D ÁA D Â<AD ÄD ÄEÄ6EÄ?EÅ EÅEc                ó>   € V ^8„  d   QhR\         R,          R\        /# )r/   rß  Nr2   rÃ  )r7   s   "r8   r9   r9   Ñ  s   € ÷ 	ñ 	œT D�[ð 	´Cñ 	r:   c                óÄ   € V e
   V R,          M	\        4       p VP                  RR7      P                  4       pV'       g   R# V#   \        \        \
        3 d     R# i ; i)zURead the sticky active profile name (of *root*, default: this process's Hermes root).r—   rÆ   rÇ   rö   )r«   r·  rè   rÒ   rŒ  rE   )rß  rB   rá   s   &  r8   Úget_active_profilerí  Ñ  s[   € à&*Ò&6ˆ4Ð"Ö"Ô<TÓ<V€DðØ�~‰~ {ˆ~Ó3×9Ñ9Ó;ˆßÙØˆøÜÔ1´7Ð;ô Úðús   ™'A ÁA ÁAÁAc                ó(   € V ^8„  d   QhR\         RR/# rý   râ   )r7   s   "r8   r9   r9   Ý  s   € ÷ ñ œSð  Tñ r:   c                ó^  € \        V 4      pVR8w  d   \        V4      '       g   \        V4      h\        4       pVP                  P                  RRR7       VR8X  d   VP                  RR7       R	# VP                  R4      pVP                  VR,           RR7       VP                  V4       R	# )
z>Set the sticky active profile (``default`` = remove the file).rö   TrV  rÃ  r=   Ú
r7  rÇ   N)
r	  r  r×   r«   r™  rZ  rl  Úwith_suffixr\  r8  )rá   rÐ   rB   Útmps   &   r8   Úset_active_profileró  Ý  sŽ   € ä˜Ó€EØ�	Ô¤.°×"7Ò"7Ü$ UÓ+Ð+Ü#Ó%€DØ‡K�K×Ñ˜d¨TÐÔ2Ø�	ÔØ�‰˜tˆÖ$à×Ñ˜vÓ&ˆØ�‰�u˜t•|¨gˆÔ6Ø�‰�DÖr:   c                ó@   € V ^8„  d   QhR\         R\         R\         RR/# )r/   ÚoldÚnewÚmessager2   Nrâ   )r7   s   "r8   r9   r9   ì  s(   € ÷ ñ ¤#ð ¬Cð ¼#ð À$ñ r:   c                óÎ   € \         P                  ! \        4      ;_uu_ 4        \        4       V 8X  d   \	        V4       \        V4       RRR4       R#   + '       g   i     R# ; i)z[If the sticky active profile is *old*, point it at *new* and print *message*. Never raises.N)r-  r.  rÌ   rí  ró  r[  )rõ  rö  r÷  s   &&&r8   r¬  r¬  ì  s<   € ä	×	Ò	œY×	'Õ	'ÜÓ 3Ô&Ü˜sÔ#Ü�'ŒN÷ 
(×	'×	'Ò	'ús   £&AÁA$	c                ó$   € V ^8„  d   QhR\         /# rŸ   râ   )r7   s   "r8   r9   r9   ô  s   € ÷ ñ ¤ñ r:   c                 ó|  € ^ RI Hp  V ! 4       P                  4       pV\        4       P                  4       8X  d   R# \	        4       P                  4       p VP                  V4      P                  p\        V4      ^8X  d,   \        P                  V^ ,          4      '       d
   V^ ,          # R#   \         d     R# i ; i)z¡Profile name inferred from HERMES_HOME: ``"default"`` when unset or ``~/.hermes``, the
name under ``~/.hermes/profiles/<name>``, ``"custom"`` for any other path.r  rö   Úcustom)r¨   r  rW   r`   r£   Úrelative_tory   r‡   rê   rë   rX   )r  Úresolvedr%  ry   s       r8   r‰  r‰  ô  s    € õ 1ÙÓ ×(Ñ(Ó*€HØÔ+Ó-×5Ñ5Ó7Ô7ÙÜ&Ó(×0Ñ0Ó2€MðØ×$Ñ$ ]Ó3×9Ñ9ˆÜˆu‹:˜Œ?œ~×3Ñ3°E¸!µH×=Ò=Ø˜•8ˆOñ øô ô ØÙðús   ÁAB, Â!B, Â,B;Â:B;c                óL   € V ^8„  d   QhR\         R,          R\         R,          /# )r/   rö   Nr2   râ   )r7   s   "r8   r9   r9     s"   € ÷ ñ ¤#¨¥*ð ¼¸d½
ñ r:   c                ó  € ^ RI Hp V! 4       fM   R FF  p\        P                  P	                  V4      ;'       g    RP                  4       pV'       g   KD  Vu # 	   \        4       ;'       g    T #   \         d    T u # i ; i)a   Identity of the profile the current task runs FOR: the ``HERMES_HOME`` override when one is
bound (a multiplexed cron tick, a routed gateway turn), else a launcher-pinned
``HERMES_PROFILE_NAME``/``HERMES_PROFILE`` (the kanban dispatcher pins it on its workers), else
the name derived from the process's ``HERMES_HOME``; *default* when nothing names a profile.

The env pin is read only outside an override: ``os.environ`` is the LAUNCH profile's, so under
an override it would re-label a served profile's board writes with the host's identity.
)Úget_hermes_home_overriderO  )ÚHERMES_PROFILE_NAMEÚHERMES_PROFILE)r¨   r   r@   rP  rQ  rè   r‰  rÌ   )rö   r   Úenv_namerÌ  s   &   r8   Úcurrent_profile_namer    sr   € õ :ÙÓ!Ò)ÛAˆHÜ—Z‘Z—^‘^ HÓ-×3Ð3°×:Ñ:Ó<ˆEß‰uØ’ñ BðÜ&Ó(×3Ð3¨GÐ3øÜô ØŠðús   ÁA1 Á.A1 Á1BÂ Bc                ó0   € V ^8„  d   QhR\         R\        /# rÃ   rÄ   )r7   s   "r8   r9   r9     s   € ÷ ]ñ ]œtð ]¬ñ ]r:   c                óð   €  V P                  4       p\        ;QJ d)    R T.TP                  O 4       F  '       g   K   R# 	  R# ! R T.TP                  O 4       4      #   \        \        3 d     R# i ; i)zûTrue when *path* lies inside a Git checkout. Walks the path's OWN resolved ancestry
(not cwd) so the check holds when HERMES_HOME sits in a checkout but the process runs
elsewhere (cron, service manager). Resolution failure reports True (fail closed).Tc              3   óN   "  € T F  qR ,          P                  4       x € K  	  R# 5i)z.gitN)ry  )rt   rì   s   & r8   rv   Ú'_inside_git_checkout.<locals>.<genexpr>$  s!   é € Ð\Ñ>[°˜FÕ"×*Ñ*×,Ð,Ó>[ùs   ‚#%F)rW   rE   r«  rŽ   rW  )rB   rý  s   & r8   Ú_inside_git_checkoutr	    sr   € ðØ—<‘<“>ˆ÷ ‹3Ñ\¸xÐ>[È(×JZÑJZÑ>[Ó\�3Œ3Ð\Š3Ð\ˆ3Ñ\¸xÐ>[È(×JZÑJZÑ>[Ó\Ó\Ð\øô ”\Ð"ô Úðús   ‚A  Á A5Á4A5c                ó$   € V ^8„  d   QhR\         /# rŸ   r   )r7   s   "r8   r9   r9   '  s   € ÷ ñ ¤4ñ r:   c                 ó‚  € ^ RI p \        4       R,          p\        V4      '       g   V# \        \        R4      '       d   R\        P
                  ! 4        2MRp\        P                  ! 4       R,          \        V P                  4       4      RV 2,          3pV F  p\        V4      '       d   K  Vu # 	  \        R4      h)	z@Choose an export directory that cannot become source-tree input.Nzprofile-exportsÚgetuidrä   rO  z.hermes-profile-exportszhermes-profile-exportsz»No safe automatic export destination: every candidate directory is inside a Git checkout. Provide an explicit output path outside the checkout (CLI: -o /path/outside/repo/profile.tar.gz).)
Útempfiler`   r	  Úhasattrr@   r  r   r   Ú
gettempdirrX   )r  Ú
export_dirÚ
uid_suffixrÀ   rì   s        r8   Ú_profile_export_directoryr  '  s­   € ãÜ)Ó+Ð.?Õ?€JÜ 
×+Ò+ØÐô '.¬b°(×&;Ò&;�1”R—Y’Y“[�MÑ"À€Jä�	Š	‹Ð/Õ/´°h×6IÑ6IÓ6KÓ1LÐQgÐhrÐgsÐOtÕ1tð€Jó  ˆ	Ü# I×.Ô.ØÒñ  ô
 ð	@óð r:   Ú	timestampc                óR   € V ^8„  d   QhR\         R\        \         ,          R\        /# )r/   rá   r  r2   rº   )r7   s   "r8   r9   r9   C  s%   € ÷ 2ñ 2¤#ð 2´X¼cµ]ð 2Ìdñ 2r:   c               ó¦  € \        V 4      p\        4       pVP                  RRR7       VP                  4       '       d   \	        RV R24      h\        \        R4      '       dB   VP                  4       P                  \        P                  ! 4       8w  d   \	        RV R24      hT;'       g    \        P                  ! R4      pW2 RV R	2,          # )
u²   Managed destination for an export with no explicit output â€” outside the cwd and every
profile, since a ``<name>.tar.gz`` default in a source checkout got committed by accident.TrV  zExport directory z_ is a symlink; refusing to write a profile archive through it. Provide an explicit output path.r  zf is owned by another user; refusing to write a profile archive there. Provide an explicit output path.z%Y%m%d-%H%M%Srä   ú.tar.gz)r	  r  rZ  r¢  rX   r  r@   rF   Úst_uidr  r  Ústrftime)rá   r  rÐ   r  Ústamps   &$   r8   Úget_profile_export_pathr  C  sÑ   € ô ˜Ó€EÜ*Ó,€JØ×Ñ˜T¨DÐÔ1ð ×Ñ×ÒÜØ 
˜|ð ,Mð Mó
ð 	
ô Œr�8×Ò §¡Ó!2×!9Ñ!9¼R¿YºY»[Ô!HÜØ 
˜|ð ,Zð Zó
ð 	
ð ×7Ð7œŸš Ó7€EØ˜'  5 '¨Ð1Õ1Ð1r:   c                ó$   € V ^8„  d   QhR\         /# )r/   Úroot_dirr   )r7   s   "r8   r9   r9   Y  s   € ÷ ñ ¤Tñ r:   c                ó   a € R V 3R llpV# )u  copytree ignore for the default-profile export: root-level allow-list
(``_DEFAULT_EXPORT_INCLUDE_ROOT``) plus universal exclusions. Surviving text files are
then force-redacted by :func:`_scrub_export_secrets`.

* **Root-level allow-list** â€” only entries whose name appears in ``_DEFAULT_EXPORT_INCLUDE_ROOT``
survive. Everything else (such as an unrelated ``x11-dev/`` directory in a Docker deployment where
HERMES_HOME equals the cwd) is excluded. Blacklisting was tried first and proved unable to anticipate
every non-Hermes file the user may have lying alongside HERMES_HOME (#58394). * **Universal exclusions
at any depth** â€” ``__pycache__``, sockets and other special files, temp files
(:func:`_non_exportable_entries`); plus npm lockfiles, which may appear at the root.
c                ó<   € V ^8„  d   QhR\         R\        R\        /# r.   r3   )r7   s   "r8   r9   Ú,_default_export_ignore.<locals>.__annotate__f  s!   € ÷ ñ œ3ð ¬$ð ´3ñ r:   c                 óè   <€ \        W4      pVP                  R R0\        V4      ,          4       VP                  \        W4      4       \	        V 4      S8X  d   VP                  R V 4       4       V# )zpackage.jsonzpackage-lock.jsonc              3   ó>   "  € T F  q\         9  g   K  Vx € K  	  R # 5ir|   )Ú_DEFAULT_EXPORT_INCLUDE_ROOTr+  s   & r8   rv   Ú:_default_export_ignore.<locals>._ignore.<locals>.<genexpr>l  s   é € Ðd©h UÔGcÑ:cŸ5š5«hùs   ‚“
)rM   rY   r6   Ú_export_credential_entriesr   )r0   r1   rJ   r  s   && €r8   r]   Ú'_default_export_ignore.<locals>._ignoref  s]   ø€ ä)¨)Ó>ˆØ�‰˜Ð(;Ð<¼sÀ8»}ÕLÔMØ�‰Ô1°)ÓFÔGÜ�	‹?˜hÔ&Ø�N‰NÑd©hÓdÔdØˆr:   r¢   )r  r]   s   f r8   Ú_default_export_ignorer&  Y  s   ø€ ÷ð ð €Nr:   c              #   óV   "  € T F  p\        VP                  R 4      4      x € K!  	  R# 5irn   )rp   rr   rs   s   & r8   rv   rv   w  s"   é € Ð WÑ>V¸¤ q§w¡w¨s£|×!4Ð!4Ó>Vùs   ‚')c                ó<   € V ^8„  d   QhR\         R\        R\        /# r.   r3   )r7   s   "r8   r9   r9   z  s&   € ÷ Yñ Y¬#ð Y¼ð YÄ#ñ Yr:   c           
     óö   € \        V 4      P                  pV UUu0 uFP  p\         FC  pW4R,          8X  g   K  V\        V4      ^,           \        V4      ,
          R VRR 8X  g   KA  VkKE  	  KR  	  upp# u uppi )z±Entries of *directory* that are an _EXPORT_CREDENTIAL_FILES store: matched on trailing path
components, so ``.config/gh`` drops at any depth while the rest of ``.config`` ships.Nr‰  )r   ry   Ú_EXPORT_CREDENTIAL_PARTSr‡   )r0   r1   ry   rK   r‰   s   &&   r8   r$  r$  z  s~   € ô �‹O×!Ñ!€EÙ'ô Y™x�e×5M¨EØ˜b�	Ñ!ô Ø&+¬C°«J¸­N¼SÀ»ZÕ,GÐ,HÐ&IÈUÐSVÐTVÈZÑ&W÷ ˆEÑ5M‰E™xò Yð Yùó Ys   ›A5¸*A5Á'
A5c                ó0   € V ^8„  d   QhR\         R\        /# rÃ   rÄ   )r7   s   "r8   r9   r9   ‹  s   € ÷ ñ ¤Tð ¬dñ r:   c                 ó  € V P                   pV\        9   ;'       gp    VP                  4       P                  R 4      ;'       gI    VP                  4       P	                  R4      ;'       g"    V P
                  P                  4       \        9   # )z.env.examplezconfig.yaml.)rá   Ú_EXPORT_REDACT_NAMESré   r>   r®  r‹  Ú_EXPORT_REDACT_SUFFIXES)rB   rá   s   & r8   Ú_should_redact_export_filer/  ‹  sw   € Ø�9‰9€DàÔ$Ñ$÷ 	:ð 	:Ø�:‰:‹<× Ñ  Ó0÷	:ð 	:à�:‰:‹<×"Ñ" >Ó2÷	:ð 	:ð �;‰;×ÑÓÔ"9Ñ9ð	r:   c                ó(   € V ^8„  d   QhR\         RR/# )r/   Ústagedr2   Nr   )r7   s   "r8   r9   r9   •  s   € ÷ 4ñ 4¤$ð 4¨4ñ 4r:   c                ó°  € ^ RI Hp V P                  R4       F�  p VP                  4       pVP	                  4       '       g   K,   \        T4      '       g   K@   TP                  RR7      pT! TRR7      pYT8X  d   Ke  T'       d   TP                  4        TP                  TRR7       K’  	  R#   \
         d     K¤  i ; i  \        \
        3 d     K¼  i ; i)	a  Force-redact secret-shaped strings in a staged export tree (same pass as ``hermes
sessions export --redact``). Runs on the staged copy only; symlinks to text files are
materialized when content changes so redaction never follows a link back into the source.)Úredact_sensitive_textÚ*rÆ   rÇ   T)rm  r7  N)Úagent.redactr3  Úrglobr¢  rŠ  rE   r/  r·  rŒ  rl  r\  )r1  r3  rB   Úis_linkr:  Úredacteds   &     r8   Ú_scrub_export_secretsr9  •  sÂ   € õ 3Ø—‘˜SÖ!ˆð	Ø—o‘oÓ'ˆGØ—<‘<—>’>Ùð "ô *¨$×/Ò/Ùð	Ø—>‘>¨;�>Ó7ˆDñ )¨°TÔ:ˆØÔÙßØ�K‰KŒMØ�‰˜¨7ˆÖ3ó% "øô
 ô 	Úð	ûô #¤GÐ,ô 	Úð	ús#   œ&B.ÁC Â.B=Â<B=Ã CÃCc          	      ó€   € V ^8„  d   QhR\         R\         R\        \        \         \         3,          ,          R\        /# )r/   rá   Úoutput_pathÚextra_filesr2   )r4   r   r†  r   )r7   s   "r8   r9   r9   ¯  s7   € ÷ 5ñ 5œð 5¬3ð 5¼XÄdÌ3ÔPSÈ8ÅnÕ=Uð 5Ôaeñ 5r:   c           	     ó¤  a€ ^ RI p\        V 4      w  po\        \        V4      4      P	                  R4      P	                  R4      pR V3R llpVR8X  d   \        S4      MTpVP                  4       ;_uu_ 4       p\        V4      V,          p	\        P                  ! SV	RVR7       T;'       g    / P                  4        FN  w  r«V	P                  ! \        V
4      !  pVP                  P                  RRR	7       VP                  VR
R7       KP  	  \        V	4       \        \!        WXV4      4      uuRRR4       #   + '       g   i     R# ; i)zŠExport a profile to a tar.gz archive; credential files are excluded and staged text is
force-redacted first. Returns the output file path.Nr  z.tgzc                ó<   € V ^8„  d   QhR\         R\        R\        /# r.   r3   )r7   s   "r8   r9   Ú$export_profile.<locals>.__annotate__º  s!   € ÷ ñ ¤sð ´dð ¼sñ r:   c                 ó,  <a€ \        W4      pVP                  \        W4      4       \        V 4      P	                  S4      P
                  oVP                  V3R  lV 4       4       \        V 4      S8X  d   V\        \        V4      ,          ,          pV# )c              3   óX   <"  € T F  p\        . SOVN54      '       g   K  Vx € K!  	  R # 5ir|   )r‘   )rt   rf  Úrels   & €r8   rv   Ú>export_profile.<locals>._ignore_credentials.<locals>.<genexpr>¾  s#   øé € ÐQ¡(˜QÔ.EÀiÈÀiÈQÁi×.P—q’q£(ùs   ƒ* 
*)rM   rY   r$  r   rü  ry   r   r6   )r0   r1   rJ   rB  r  s   && @€r8   Ú_ignore_credentialsÚ+export_profile.<locals>._ignore_credentialsº  sp   ù€ Ü)¨)Ó>ˆØ�‰Ô1°)ÓFÔGÜ�9‹o×)Ñ)¨+Ó6×<Ñ<ˆØ�‰ÔQ¡(ÓQÔQÜ�	‹?˜kÔ)ØÔ+¬c°(«mÕ;Õ;ˆGØˆr:   rö   T)rº  r·  rV  r7  rÇ   )r  r  r4   r   Úremovesuffixr&  ÚTemporaryDirectoryr]  r»  r½  Újoinpathr   r™  rZ  r\  r9  r   )rá   r;  r<  r  rÐ   ÚbaserD  r·  Útmpdirr1  rB  r’  r  r  s   &&&          @r8   Úexport_profilerK  ¯  s  ø€ ó Ü.¨tÓ4Ñ€Eˆ;äŒt�KÓ Ó!×.Ñ.¨yÓ9×FÑFÀvÓN€D÷
ð ð 5:¸YÔ4FÔ# KÔ0ÐL_€FØ	×	$Ñ	$×	&Ô	&¨&Ü�f“ Õ%ˆÜ�Š˜ V°dÀ6ÕJØ(×.Ð.¨B×5Ñ5Ö7‰LˆCØ—_’_Ô&=¸cÓ&BÑCˆFØ�M‰M×Ñ¨°tÐÔ<Ø×Ñ˜g°ÐÖ8ñ 8ô 	˜fÔ%Ü”J˜t¨UÓ3Ó4÷ 
'×	&×	&Ó	&ús   Á;B8D>Ä>E	c                óR   € V ^8„  d   QhR\         R\        \         ,          R\        /# )r/   Úarchive_pathrá   r2   rº   )r7   s   "r8   r9   r9   Ï  s%   € ÷ 0ñ 0¤ð 0¬H´S­Mð 0ÄTñ 0r:   c                óH  € ^ RI p\        V 4      pVP                  4       '       g   \        RV 24      h\	        V4      p\        V4      ^8X  d   VP                  4       MRpT;'       g    TpV'       g   \        R4      hVf   \        R4      h\        V4      pVR8X  d   \        R4      h\        V4      pVP                  4       '       d   \        V4      h\        4       P                  RRR7       VP                  R	R
7      ;_uu_ 4       p	\        V	4      p
\        W:4       W¥,          pVP                  4       '       g   \        RV 24      hTpWW8w  d   W§,          pVP!                  V4       VP#                  4        FX  pVP$                  \&        9   g   K  VP                  4       '       d   \(        P*                  ! V4       KH  VP-                  4        KZ  	  \(        P.                  ! \1        V4      \1        V4      4       RRR4       V#   + '       g   i     T# ; i)z'Import a profile from a tar.gz archive.NzArchive not found: zpCannot determine profile name from archive. Specify it explicitly: hermes profile import <archive> --name <name>z=Profile archive must contain exactly one top-level directory.rö   u•   Cannot import as 'default' â€” that is the built-in root profile (~/.hermes). Specify a different name: hermes profile import <archive> --name <name>TrV  Úhermes_profile_import_)r‘  z,Profile archive root is missing or invalid: )r  r   ry  rÒ   r   r‡   rJ  rX   r	  r  rÞ   r£   rZ  rG  r   r  r
  r$  rá   r   r]  r  rl  Úmover4   )rM  rá   r  ÚarchiveÚtop_dirsÚarchive_rootÚinferred_namerÐ   r  rJ  Ústaging_rootÚ	extractedÚfinal_sourceÚchilds   &&            r8   Úimport_profilerY  Ï  sÚ  € ãÜ�<Ó €GØ�>‰>×ÒÜÐ"5°g°YÐ ?Ó@Ð@Ü  Ó)€HÜ%(¨£]°aÔ%7�8—<‘<”>¸T€LØ×(Ð(˜L€MßÜðSó
ð 	
ð ÒÜÐXÓYÐYô ˜Ó'€EØ�	ÔÜðVó
ð 	
ô " %Ó(€KØ×Ñ×ÒÜ# EÓ*Ð*ÜÓ×Ñ t°dÐÔ;Ø	×	$Ñ	$Ð,DÐ	$×	EÔ	EÈÜ˜F“|ˆÜ˜7Ô1Ø Õ/ˆ	Ø×Ñ×!Ò!ÜÐKÈLÈ>ÐZÓ[Ð[Ø ˆØÔ Ø'Õ/ˆLØ×Ñ˜\Ô*ð "×)Ñ)Ö+ˆEØ�z‰zÔ1Ö1Ø—<‘<—>’>Ü—M’M %Ö(à—L‘L–Nñ ,ô 	�Š”C˜Ó%¤s¨;Ó'7Ô8÷% 
Fð& Ð÷' 
FÖ	Eð& Ðús   ÄB	HÆHÆ1AHÈH!	c                ó4   € V ^8„  d   QhR\         R\        RR/# )r/   Únew_dirÚ	old_canonr2   NrÃ  )r7   s   "r8   r9   r9   	  s&   € ÷ mñ m¤Dð m´Sð m¸Tñ mr:   c                óà   €  \        V 4      P                  R4      ;'       g    . pW9  d   . VOVNp\        WR7       R#   \         d#   p\        P                  RYT4        Rp?R# Rp?ii ; i)u:  Append ``old_canon`` to the renamed profile's ``previous_names`` history.
Best-effort: never raises, so a metadata write failure cannot fail the rename.

Only reached for a real slug change â€” ``rename_profile`` returns early for the
default profile (display-name only) and refuses ``old == new`` (target exists).r¨  )r¨  z;profile rename: could not record previous name %r in %s: %sN)r>  rQ  rM  rÌ   rm  Údebug)r[  r\  ÚhistoryrF  s   &&  r8   Ú_record_profile_renamer`  	  sk   € ðmÜ# GÓ,×0Ñ0Ð1AÓB×HÐHÀbˆØÔ#Ø+˜Ð+ Ð+ˆGÜ˜7×;øÜô mÜ�‰ÐRÐT]Ðhk×lÒlûðmús   ‚ A  £A  Á A-ÁA(Á(A-c                ó<   € V ^8„  d   QhR\         R\         R\        /# )r/   Úold_nameÚnew_namer2   r²   )r7   s   "r8   r9   r9   	  s&   € ÷ gñ gœSð g¬Cð g´Dñ gr:   c                ó   € \        V 4      pVR8X  dQ   T;'       g    RP                  4       '       g   \        R4      h\        RV4      p\	        RV R24       \        4       # \        V4      pVR8X  d   \        R4      h\        V4      p\        V4      pVP                  4       '       g   \        V4      hVP                  4       '       d   \        V4      h\        V4      p\        W%4      p\        V4       V'       d   \        V4       \        V4       \!        4       p	V	'       d   \#        V4       \%        V4       ^ RIHp
 ^ RIHp V! V
! V4      R	7        V	'       d   \/        V4      '       g   \1        R
4      hVP3                  V4       \	        RTP:                   RTP:                   24       T	'       d   \7        T4       \=        Yb4       ^ RIH p T! Y$T4       \C        T4       \E        T4      pT'       g   \G        T4       \	        RT 24       M\	        RT RT 24       \I        Y$RT 24       ^ RI%H&p T! Y$T	4       T	'       d   \%        T4       \9        T4       T'       d   \	        RT R24       T#   \4         dC    T	'       d   \7        T4       \%        T4       \9        T4       T'       d   \	        RT R24       h i ; i)uå   Rename a profile: directory, wrapper script, service, active_profile. The default
profile's home IS the installation root, so "renaming" it sets a presentation-only
``display_name`` instead â€” the canonical id stays ``default``.rö   rO  zDisplay name cannot be empty.u   âœ“ Display name set: z! (canonical id remains 'default')u.   Cannot rename to 'default' â€” it is reserved.r•  r—  r™  zKa running gateway still owns this profile; retry the rename once it settlesuB   âš  The gateway service was removed. Reinstall it with: hermes -p z gateway installu   âœ“ Renamed u    â†’ )Úmigrate_honcho_profile_hostu   âœ“ Alias updated: u   âš  Cannot create alias 'u   ' â€” u   âœ“ Active profile updated: )Ú_migrate_profile_identity)'r	  rè   rX   rV  r[  r`   r  r  rÚ   ry  rÞ   rü  r¢  r£  r¤  r  r"  r   r  r¨   r–  r¥  r˜  r   r«  r
  rÌ   r   r  rá   r`  Úhermes_cli.profiles_honchore  rm  rJ  ri  r¬  r  rf  )rb  rc  r\  rC  Ú	new_canonÚold_dirr[  r�  Úservice_removedÚlive_muxr–  r˜  re  Ú	collisionrf  s   &&             r8   Úrename_profilerm  	  sz  € ô ˜XÓ&€IØ�IÔØ—�˜B×%Ñ%×'Ò'ÜÐ<Ó=Ð=Ü*¨9°hÓ?ˆÜÐ& w iÐ/PÐQÔRÜ'Ó)Ð)Ü˜XÓ&€IØ�IÔÜÐIÓJÐJÜ˜iÓ(€GÜ˜iÓ(€GØ�>‰>×ÒÜ$ YÓ/Ð/Ø‡~�~×ÒÜ# IÓ.Ð.ô (¨Ó0€JÜ.¨yÓB€OÜ% iÔ0ßÜ˜gÔ&Ü�gÔô )Ó*€HßÜ" 7Ô+Ü˜IÔ&õ
 1Ý=Ù™¨wÓ7Õ8ðßÔ0°×9Ò9ÜÐlÓmÐmØ�‰�wÔô 
ˆL˜Ÿ™˜ e¨G¯L©L¨>Ð
:Ô;÷ Ü# GÔ,ô
 ˜7Ô.õ GÙ 	°gÔ>ô ˜)Ô$Ü% iÓ0€IßÜ˜iÔ(ÜÐ# I ;Ð/Õ0äÐ)¨)¨°F¸9¸+ÐFÔGô ˜YÐ5QÐR[ÐQ\Ð3]Ô^õ
 FÙ˜i°HÔ=÷ Ü˜IÔ&Ü# IÔ.ßÜÐRÐS\ÐR]Ð]mÐnÔoØ€Nøô_ ô ßÜ'¨Ô0Ü 	Ô*Ü'¨	Ô2ßÜÐVÐW`ÐVaÐaqÐrÔsØðús   ÅJ  Å#-J  Ê KÊ:Kc                ó<   € V ^8„  d   QhR\         R\        R\        /# )r/   rb  Údefault_rootr2   r²   )r7   s   "r8   r9   r9   	  s&   € ÷ Vñ V¬ð V¼4ð VÄDñ Vr:   c                ó²   € V P                  4       p V '       g   V# \        V 4      pVP                  P                  R8X  d   VP                  P                  # T# )a  Hermes root named by an exported ``HERMES_HOME``: the grandparent of a profile-shaped value
(``<root>/profiles/<name>``, mirrors ``get_default_hermes_root()``), the value itself otherwise,
*default_root* when unset. Pure: callers pass any process's env, not only ``os.environ``.r"   )rè   r   r™  rá   )rb  ro  r5  s   && r8   Úprofile_root_for_env_homerq  	  sH   € ð �~‰~Ó€HßØÐÜ�H‹~€HØ%-§_¡_×%9Ñ%9¸ZÔ%Gˆ8�?‰?×!Ñ!ÐUÈXÐUr:   c                ó0   € V ^8„  d   QhR\         R\         /# r€  râ   )r7   s   "r8   r9   r9   Š	  s   € ÷ ñ ¤cð ¬cñ r:   c                ó  € \        V 4      p\        \        P                  P	                  RR4      \        4       4      pVR8X  d   \        V4      # VR,          V,          p\        V4      '       g   \        V4      h\        V4      # )aY  Resolve a profile name to a HERMES_HOME path string. Called early in the CLI entry
point, before hermes modules are imported, to set HERMES_HOME.

When HERMES_HOME is already set, the configured spelling IS the launch root (it may be a
junction/symlink alias of the platform default). Keep that spelling so profile re-home does not destroy
the launcher's lexical provenance -- the subprocess sanitizer needs it to match Hermes-owned PYTHONPATH
entries written in the same spelling (#82581 junction follow-up). Physically the paths are identical
(junction-transparent); only the spelling is preserved.
r%  rO  rö   r"   )	r	  rq  r@   rP  rQ  r`   r4   r   r×   )r�  rÐ   rß  r  s   &   r8   Úresolve_profile_envrt  Š	  so   € ô ˜Ó&€EÜ$¤R§Z¡Z§^¡^°MÀ2Ó%FÔH`ÓHbÓc€DØ�	ÔÜ�4‹yÐØ˜Õ# eÕ+€KÜ  ×-Ò-Ü$ UÓ+Ð+Üˆ{ÓÐr:   c                ó  € V ^8„  d   Qh/ ^ \         9   d   \        \        ,          ;R&   ^\         9   d   \        \        ,          ;R&   ^\         9   d   \        \        ,          ;R&   ^\         9   d   \        \
        \
        3,          ;R&   ^\         9   d1   \        \        \
        \        \        \        3,          3,          ;R&   ^\         9   d   \        \        \        3,          ;R&   ^\         9   d%   \        \        \        P                  3,          ;R&   ^\         9   dB   \        \        \
        \        \
        ,          \        \        ,          3,          3,          ;R&   ^\         9   d   \        \        ,          ;R	&   # )
r/   rÈ  ra   r_   rÅ  r  r+  r!  rl  rŠ  )Ú__conditional_annotations__r5   r4   Ú	frozensetr†  rp   r  r©  r"  r#  r   rƒ   r6   r   )r7   s   "r8   r9   r9      s4  € × @Ñ @÷Xò ”$”s•)ñ ñY A÷D
ò 
¤¬3¥ñ 
ñE A÷jò ¤¬3¥ñ ñk A÷R -Ò ,”Tœ%¤˜,Õ'Ñ ,ñS A÷v =Ò <”Dœœe¤E¬5´#Ð$5Õ6Ð6Õ7Ñ <ñw A÷| /Ò .œœc¤5˜jÕ)Ñ .ñ} A÷D 8Ò 7œœc¤9§>¡>Ð1Õ2Ñ 7ñE A÷B! IÒ H”$”sœE¤(¬5¥/´8¼Dµ>Ð"AÕBÐBÕCÑ HñC! A÷X# *Ò )œœD�	Ñ )òY# Ar:   )	ÚmemoriesÚsessionsr  Úskinsr   ÚplansÚ	workspaceÚcronr   )rq  r   úSOUL.md)r   r   r   zbot-desktop/launcher.pidzbot-desktop/envzbot-desktop/rfb.sockzbot-desktop/lease.jsonzbot-desktop/lease.lockz.bot-desktop/browser-profile/DevToolsActivePortz)bot-desktop/browser-profile/SingletonLockz+bot-desktop/browser-profile/SingletonCookiez+bot-desktop/browser-profile/SingletonSocket>   r#   r&   r"   r$   r!   r    r%   >   r}  r*   ry  r,   r'   r)   r(   r+   >   r}  r  rä  Úscriptsrx  ry  Ú	knowledgeÚpreferencesr~  úUSER.mdú	AGENTS.mdú	CLAUDE.mdú	MEMORY.mdú	todo.jsonrq  r�   údesktop.jsonúsystem_prompt.md>   rò  rß  ÚsudoÚtestrY  rö   >   ÚacpÚmcpÚchatr}  ÚdumpÚloginr›  ÚsetupÚtoolsÚconfigÚdoctorÚhonchoÚlogoutr  ÚstatusrY   ri  rk   rä  rd  rÖ  Úinsightsry  ÚwhatsappÚ	uninstallÚ
connectorsr|   )r   rq  rc   r~  rV   )	NFFFFNFFN>   rŒ  ri  Ú	dashboard)zhermes_cli.mainzhermes-gatewayÚtui_gateway>   rY  ú
hermes-acpr    >   r   rc   ri   >   ú.jsú.mdú.pyú.shú.tsú.cfgú.cssú.csvú.iniú.jsxú.tsxú.txtú.xmlú.ymlú.zshú.bashú.confú.htmlú.jsonú.tomlú.yamlú.jsonl)Îrv  r¯  r-  r+  Úloggingr@   ræ   r^  r]  rF   r@  r¶   r"  r  Údataclassesr   r   Úpathlibr   Útypingr   r   r   r	   Úagent.file_safetyr
   Úhermes_cli.archive_safer   r   r   r   Úhermes_cli.home_data_layoutr   Úhermes_cli.profiles_remover   r   r   r¨   r   r   r   r   r   r   r   Ú	getLoggerrù   rm  rê   rÇ  rò  ró  rÈ  rw  ra   r_   ÚNO_BUNDLED_SKILLS_MARKERr2  rM   rb   Ú_OS_CREDENTIAL_STORESÚPROFILE_CREDENTIAL_PATHSrp   r�   ÚcompilerŒ   r€   r‘   r–   Ú_DEFAULT_EXPORT_EXCLUDE_ROOTÚDEFAULT_EXPORT_EXCLUDE_ROOTr"  rÿ   r?  r£   r`   r«   r®   r¸   rÁ   r½   r×   rÚ   rÞ   rð   rí   rò   rû   r  r  r	  r  r  r  r  r&  r0  rJ  rS  ri  rm  r~  r„  rË   rƒ  r–  rº  rÅ  rÆ  rÀ  rÍ  rÛ  rè  rï  rü  r  r  r  r,  r+  r#  r   r!  r  r  r&  r1  r>  r:  rM  rR  rV  r]  rc  rl  rq  rr  ru  rp  r~  r�  r6   rŠ  r�  r‘  r”  r�  r¡  r¥  r°  rÀ  rÎ  rÓ  rá  rç  rì  rö  r  r  r  r  r"  r/  r6  r[  r@  rA  rC  rF  rO  rc  rs  rv  r  r…  r«  r‡  r´  r¼  r  r£  r¢  r¤  rí  ró  r¬  r‰  r  r	  r  r  r&  Ú_EXPORT_CREDENTIAL_FILESr*  r$  r.  r-  r/  r9  rK  rY  r`  rm  rq  rt  r9   )rv  s   @r8   Ú<module>rÄ     só  øðß @ã Û Û Û 	Û 	Û Û Û Û Û 
Û Û ß (Ý ß .Ó .å 2ß nÓ nÝ <ß fÑ f÷÷ ñ ð
 
×	Ò	˜8Ó	$€à€ó
 j€ó 9Ð ð ,Ð-?Ð@Ð óÐ ó ñ, 4=ó 
>ó 
4ð õ
4Ð ó 
ñ& 3<ó =ó 3Ð ó ð 0Ð ð?ð õõ*ð0 :Ð.Ð9°Ñ9Ð ñ
 %ð &Øð&Øð&Ø1ð&àð&ð ð&ð ð	&ð
 ð&ð
 5ð&ð
 7Rð&ð ð&ð  Eð&ð Glð&ð "ð&ð $Dð&ð ð&ð ð&ð ð&ð !ð&ð  ð&ð ð&ð ð&ð ð&ð &ð&ð (5ð&ð  ð!&ð  +ð!&ð" ð#&ð" #ð#&ð" %Bð#&ð$ ð%&ð$ 5ð%&ð$ 7Eð%&ð$ G_ð%&ð& ð'&ð& 7ð'&ð( )ð)&ð* ð+&ð, ð-&ð. "ð/&ð0 ð1&ð2 ð3&ð4 ð5&ð6 ð7&ð6 !ð7&ð8 ð9&ó Ð ÷< ˜Ñ`ÑG_Ó`Ÿ™Ñ`ÑG_Ó`Ó`Ð ð —’ð]ó€õ4õQõoñ >Gð HàðHð ðHð ð	Hð
 
ðHð ðHð ðHð ðHð ðHð ðHð !/ðHð ðHð ðHð 1ðHð 3JðHð ðHð (ðHð *:ðHð ðHð ðHð  ð!Hð  "ð!Hð  $3ð!Hð  5Dð!Hð" ð#Hð$ ð%Hð( ð)Hð( !ð)Hð( #3ð)Hð* ð+Hð* )ð+Hð, ð-Hð. ð/Hó >ð0 õ1>ð Ð Ð:ñF  )ó 
*ó 
 Ð ñ ÓPÓQ€ñ  ó !ó Ð õ3õ%õ9õ*õWõ
Eõõqõiõ
ðð õGõõõ8
õ(Põõõ(õ	.÷ð ð °$÷ õ(õõ8S÷ð õ4õ$.õ&Gð Ð õ%ðT ÷ <ð  <ó ð <õF	4ð$ +-Ð Ó ,ØÐ õ9õõ"ZõDõ,3õ Sõ
ð( ;=Ð Ó <Ø Ð Ø#Ð Ø,.Ð Ó .Ø—N’NÓ$Ð ð 68Ð Ó 7õõ(Jõõ42õ0õ6ð 7Ø7;ð 7Ø`dð 7à"&ð 7àNR÷ 7õF;õðÐZ^ð Ø+0÷ð(¨e÷ ð0 GIÐ Ó HØÐ ð Sð õ/õdõ)õ-ñ
 %(£EÐ Ó )ðÀUð Ø-2÷õ8
÷&ð &õ&ñ" EÐ õõ *÷"Wð Wõ4
õ40õ(õ\õ÷Að A÷@Tð Tõn	ö/÷
)÷÷ò ÷@ò ñ< Ó=Ó>€ÙKÐ ð
 ŸšÑ$?Ó@Ð ñ  )Ó)QÓRÐ ÷
÷'÷3ñlÉt÷ ñ ÷ B÷(*÷0Bö.< |ô <÷&eò eóP
@÷C÷,E÷3÷l!2÷L	ò 	÷÷÷÷"ò ÷.]÷ñ82ÀT÷ 2ñ 2÷,ñ: %Ó%aÐK`Ð%aÓbÐ ß ˜5Ò WÑ>VÓ WŸ5™5Ò WÑ>VÓ WÓWÐ ÷Yñ $ó %ó Ð ñ ! .Ð!1Ó2Ð ÷÷4÷45ò 5÷@0ò 0÷jm÷g÷XV÷ñ r:   