+
    jHàjéŒ  ã                  ó”  a € 0 t $ R t^ RIHt ^ RIt^ RIt^ RIt^ RIHt ^ RI	H
t
 ^ RIHtHt ^ RIHtHtHtHtHtHtHt ]P,                  ! ]4      tRR/tR	 R
 ltR R ltRR/R R lltRR/R R lltRR/R R lltR R ltRR/R R llt RR/R R llt!RR/R R llt"]! RR 7       ! R! R"4      4       t#]#! R#R$]R%RvRwRxRyR#RvRzR&7      ]#! R'R(]R)R'R*7      ]#! R+R,] R-R{R|R.R/7      ]#! R0R1R2 R3R0R4R57      ]#! R6R7]!R8R6R97      ]#! R:R;]"R<R=R}R>7      3t$R?]%R@&   RA RB lt&RC RD lt'RE RF lt(RG RH lt)RI RJ lt*R~RK RL llt+RM RN lt,]-! 4       t.RO]%RP&   / t/RQ]%RR&   RS RT lt0RU RV lt1RWt2RXt3RY RZ lt4R[ R\ lt5R] R^ lt6R_ R` lt7RRRaR/Rb Rc llt8RdR/Re Rf llt9Rg Rh lt:Ri Rj lt;Rk]<RR/Rl Rm llt=Rk]</Rn Ro llt>Rp Rq lt?RkR/Rr Rs llt@Rt Ru ltAR# )a]  Move a home onto the catalog plugin of a feature that left core.

A feature (gateway platform, toolset, bundled plugin) that moves from core into a standalone catalog
plugin keeps its names, config keys and env vars, so migrating is only "install the plugin". Each row of
:data:`LEFT_CORE` names the catalog plugin and a read-only predicate "does this home use it". The
contract is the one memory providers established (``memory_provider_migration``, whose helpers this
reuses; memory is not a row because its plugin name comes from ``memory.provider``, not a table):

* ``hermes update`` installs the plugin for every profile home sharing the venv that uses the feature.
* Agent start and gateway start retry once per process for the active home (Desktop users update
  through the app and never run ``hermes update``), honouring ``security.allow_lazy_installs``.
* After a failed attempt (catalog miss or unreachable, failed install) starts skip the row for
  an hour, doubling with each further failure up to a week, so an offline
  machine pays the network round trip once, not on every ``hermes chat``, and a home whose install
  cannot succeed stops failing every hour; ``hermes update`` always retries.
* A home gets the plugin automatically at most once (``_left_core_installed`` in its config.yaml):
  ``hermes plugins remove`` afterwards is the user's choice and sticks.

Installs go through the normal catalog install path at the reviewed pin (kill list, dependency
constraints, enable). Unattended dependency consent covers only these rows: the feature shipped in
core, so its users already accepted its dependencies. Agent/gateway start always installs with it
(nothing can answer a prompt there); ``hermes update`` in a terminal still asks. Every outcome
reaches the user (terminal, Desktop, chat); a gateway-start outcome waits for the home's first agent
to deliver it.
)ÚannotationsN)Ú	dataclass)ÚPath)ÚCallableÚOptional)Ú_failed_recentlyÚ_home_consentÚ_home_labelÚ_install_commandÚ_interactiveÚ_note_failureÚ_unattended_consentzterminal.singularity_imageÚTERMINAL_SINGULARITY_IMAGEc               ó    € V ^8„  d   QhRRRR/# )é   Úhomer   ÚreturnÚdict© )Úformats   "ÚC/home/ubuntu/.hermes/hermes-agent/hermes_cli/left_core_migration.pyÚ__annotate__r   2   s   € ÷ 2ñ 2�tð 2 ñ 2ó    c                ó¶   € ^ RI p VP                  V R,          P                  RR7      4      p\	        T\
        4      '       d   T# / #   \         d    / u # i ; i)é    Núconfig.yamlú	utf-8-sig©Úencoding)ÚutilsÚfast_safe_loadÚ	read_textÚ	ExceptionÚ
isinstancer   )r   r   Údatas   &  r   Ú_read_configr%   2   s\   € ÛðØ×#Ñ# T¨MÕ%9×$DÑ$DÈkÐ$DÓ$ZÓ[ˆô ˜d¤D×)Ò)ˆ4Ð1¨rÐ1øô ô ØŠ	ðús   †(A ÁAÁAc               ó$   € V ^8„  d   QhRRRRRR/# )r   r   r   ÚnameÚstrr   Úboolr   )r   s   "r   r   r   ;   s&   € ÷ dñ d ð d¨Sð d°Tñ dr   c                óf  € ^ RI Hp ^ RIHp VP	                  V 4      p\        V\        4      '       d   TM/ p VP                  V 4      p\        V\        4      '       d   TM/ pVP                  WUP                  R4      V\        V04      R7      P                  V4      p\        V\        4      '       g   R# VP                  V4      pVP                  ;'       gD    RV9  ;'       d7    \        \        VP                   ;'       g    R4      P#                  4       4      #   \         d    / p Låi ; i)aÏ  Platform *name* is on in *home*'s config files as the gateway loader reads them: legacy
``gateway.json`` base layer, then config.yaml's ``gateway.platforms`` / ``platforms`` /
``gateway.<name>`` blocks merged in the loader's order (managed overlay and ``${VAR}`` applied),
so the last explicit ``enabled`` wins. A stored token with no ``enabled`` anywhere counts too.
Env credentials are the caller's to check. Read-only; works before the platform's plugin loads.©Úconfig_loader)ÚPlatformConfigÚgateway)ÚalsoFÚenabledÚ )r.   r,   Úgateway.configr-   Úload_legacy_gateway_jsonr#   r   Úread_yaml_layersr"   Úmerge_platform_sectionsÚgetÚ	frozensetÚ	from_dictr0   r)   r(   ÚtokenÚstrip)r   r'   r,   r-   Úgw_dataÚyaml_cfgÚblockÚplatforms   &&      r   Úplatform_configured_onr?   ;   s  € õ &Ý-Ø×4Ñ4°TÓ:€GÜ# G¬T×2Ò2‰g¸€GðØ ×1Ñ1°$Ó7ˆô & h´×5Ò5‰x¸2€HØ×1Ñ1Ø—,‘,˜yÓ)¨7¼ÀDÀ6Ó9Jð 2ó LßLOÉCÐPTËIð 
ä�eœT×"Ò"ÙØ×'Ñ'¨Ó.€HØ×Ñ×cÐc 	°Ñ 6× bÐ b¼4ÄÀHÇNÁN×DXÐDXÐVXÓ@Y×@_Ñ@_Ó@aÓ;bÐcøô ô ØŠðús   ¹D  Ä D0Ä/D0Úown_platformr1   c               ó(   € V ^8„  d   QhRRRRRRRR/# )	r   Úconfigr   Únameszfrozenset[str]r@   r(   r   r)   r   )r   s   "r   r   r   R   s/   € ÷ 
hñ 
h˜Dð 
h¨ð 
hÈ#ð 
hÐW[ñ 
hr   c               ón  a€ V P                  R4      p\        V\        4      '       d-   VP                  4        UUu. uF  w  rEWB8w  g   K  VNK  	  uppM. pVP	                  V P                  R4      4       \
        ;QJ d    V3R lV 4       F  '       g   K   R# 	  R# ! V3R lV 4       4      # u uppi )a§  A toolset in *names* is selected in ``platform_toolsets`` or the top-level ``toolsets`` list.

*own_platform*'s row is skipped: it scopes that platform's own sessions, which only exist once the
platform is on (:func:`platform_configured_on`). The installers copy cli-config.yaml.example into
config.yaml, and it carried ``homeassistant: [hermes-homeassistant]`` until Home Assistant left core,
so that row alone is not use.Úplatform_toolsetsÚtoolsetsc              3  óÈ   <"  € T FW  p\        V\        4      ;'       d;    \        ;QJ d    V3R  lV 4       F  '       g   K   RM	  RM! V3R  lV 4       4      x € KY  	  R# 5i)c              3  ó@   <"  € T F  p\        V4      S9   x € K  	  R # 5i©N©r(   )Ú.0ÚitemrC   s   & €r   Ú	<genexpr>Ú,_toolset_listed.<locals>.<genexpr>.<genexpr>\   s   øé € Ð,PÉCÀD¬S°«Y¸%Ö-?ËCùs   ƒTFN)r#   ÚlistÚany)rK   ÚselrC   s   & €r   rM   Ú"_toolset_listed.<locals>.<genexpr>\   sA   øé € ÐgÑ\fÐUXŒz˜#œtÓ$×PÐP¯«Ô,PÉCÓ,P¯¯ªÔ,PÉCÓ,PÓ)PÔPÓ\fùs   ƒA"ŸA"«A"Á A"TF)r6   r#   r   ÚitemsÚappendrP   )rB   rC   r@   Úrowsr>   rQ   Ú
selectionss   &f$    r   Ú_toolset_listedrW   R   s�   ø€ ð �:‰:Ð)Ó*€DÜXbÐcgÔim×XnÒXn¨4¯:©:¬<ÔT©<™-˜(¸8Ñ;S—#�#©<ÓTÐtv€JØ×Ñ�f—j‘j Ó,Ô-ß‹3ÔgÑ\fÓg�3Œ3ÐgŠ3Ðgˆ3ÔgÑ\fÓgÓgÐgùó Us   ¼
B1ÁB1Úprocess_envFc               ó$   € V ^8„  d   QhRRRRRR/# ©r   r   r   rX   r)   r   r   )r   s   "r   r   r   _   s&   € ÷ pñ p˜tð p°Tð pÀdñ pr   c               óŠ  € ^ RI Hp V! V R,          4      P                  R4      ;'       g    RP                  4       '       d   R# V'       d2    ^ RI Hp V! RR4      ;'       g    RP                  4       '       d   R#  \        V R4      '       d   R# \        \        V 4      \        RR04      RR	7      #   \
         d     LCi ; i)
aè  What made core run Home Assistant for *home*: ``HASS_TOKEN`` in its ``.env`` (it enabled both
the gateway platform and the tools), the platform on in its gateway config
(:func:`platform_configured_on`), or the ``homeassistant`` / ``hermes-homeassistant`` toolset selected for
another platform or in the top-level ``toolsets`` list. *process_env* (the active home at startup only)
also counts a ``HASS_TOKEN`` the process received from its environment (systemd unit, Docker, shell export).)Úload_env_filez.envÚ
HASS_TOKENr1   T)Ú
get_secretÚhomeassistantzhermes-homeassistant)r@   )
Úagent.secret_scoper\   r6   r:   r^   r"   r?   rW   r%   r7   )r   rX   r\   r^   s   &$  r   Úhomeassistant_in_usera   _   s³   € õ 1Ù�d˜V•mÓ$×(Ñ(¨Ó6×<Ð<¸"×CÑC×EÒEÙßð	Ý5Ù˜<¨Ó,×2Ð2°×9Ñ9×;Ò;Ùð <ô ˜d O×4Ò4ÙÜÜ�TÓœI Ð8NÐ&OÓPÐ_nôpð pøô	 ô 	Ùð	ús   ÁB4 Á$B4 Â4CÃCc               ó$   € V ^8„  d   QhRRRRRR/# rZ   r   )r   s   "r   r   r   u   s&   € ÷ Gñ G˜ð G¨tð GÀñ Gr   c               óü  € ^ RI p VP                  V R,          P                  RR7      4      p\        V\        4      '       d   VP                  R4      MRp\        V\        4      '       d   VP                  R4      MRp\        V\        4      '       d1   VP                  R4      '       g   VP                  R4      '       d   R	# \        \        V 4      \        R04      4      #   \        \        3 d    / p LÌi ; i)
a  What made core's Spotify tools usable for *home*: a login stored in its ``auth.json``
(``providers.spotify``, written by ``hermes auth spotify``) or the ``spotify`` toolset selected
for a platform. The tools were opt-in and login-gated, so a client id alone is not use.Nz	auth.jsonr   r   Ú	providersÚspotifyÚaccess_tokenÚrefresh_tokenT)ÚjsonÚloadsr!   ÚOSErrorÚ
ValueErrorr#   r   r6   rW   r%   r7   )r   rX   rh   Ústorerd   Ústates   &$    r   Úspotify_in_usern   u   sÇ   € ó ðØ—
‘
˜D ;Õ.×9Ñ9À;Ð9ÓOÓPˆô +5°U¼D×*AÒ*A�—	‘	˜+Ô&Àt€IÜ(2°9¼d×(CÒ(CˆI�M‰M˜)Ô$È€EÜ�%œ×Ò E§I¡I¨n×$=Ò$=ÀÇÁÈ?×A[ÒA[ÙÜœ<¨Ó-¬y¸)¸Ó/EÓFÐFøô ”ZÐ ô ØŠðús   †(C% Ã%C;Ã:C;c               ó$   € V ^8„  d   QhRRRRRR/# )r   r   r   Úpluginr(   r   r)   r   )r   s   "r   r   r   …   s!   € ÷ 8ñ 8 4ð 8°ð 8¸ñ 8r   c                ó^  aaa€ ^ RI Hp \        V3R l\         4       4      o VP	                  V 4      P                  R4      o\        S\        4      '       d   SM/ oR TT3R	 llpT! R
4      ;'       d    T! R4      '       * #   \         d    \        P                  RT RR7        R# i ; i)zÿ*plugin*'s bundled copy was on for *home*: its key or name in ``plugins.enabled`` and neither in
``plugins.disabled`` (which wins, as in the loader), read with the managed overlay applied like the
loader's config, so an administrator's pinned list counts.r+   c              3  óL   <"  € T F  qP                   S8X  g   K  Vx € K  	  R # 5irI   )rp   )rK   Úfrp   s   & €r   rM   Ú+_bundled_plugin_selected.<locals>.<genexpr>Š   s   øé € Ð>™i˜¯8©8°vÑ+=—1’1›iùs   ƒ$š
$Úpluginsú#left-core: unreadable config for %sT©Úexc_infoFc               ó    € V ^8„  d   QhRRRR/# )r   Úkeyr(   r   r)   r   )r   s   "r   r   Ú._bundled_plugin_selected.<locals>.__annotate__’   s   € ÷ nñ n�Cð n˜Dñ nr   c                óÊ   <€ SP                  V 4      p\        V\        4      ;'       d;    \        ;QJ d    V3R  lV 4       F  '       g   K   R# 	  R# ! V3R  lV 4       4      # )c              3  ól   <"  € T F)  p\        V4      SP                  SP                  39   x € K+  	  R # 5irI   )r(   Ú
plugin_keyrp   )rK   ÚnÚfeatures   & €r   rM   Ú;_bundled_plugin_selected.<locals>.listed.<locals>.<genexpr>”   s,   øé € Ð.mÑglÐbc¬s°1«v¸'×:LÑ:LÈgÏnÉnÐ9]Ö/]Óglùs   ƒ14TF)r6   r#   rO   rP   )rz   rC   r€   ru   s   & €€r   ÚlistedÚ(_bundled_plugin_selected.<locals>.listed’   sK   ø€ Ø—‘˜CÓ ˆÜ˜%¤Ó&×mÐm¯3«3Ô.mÑglÓ.m¯3¬3Ðmª3Ðm¨3Ô.mÑglÓ.mÓ+mÐmr   r0   Údisabled)r.   r,   ÚnextÚ	LEFT_COREr4   r6   r"   ÚloggerÚdebugr#   r   )r   rp   r,   r‚   r€   ru   s   &f  @@r   Ú_bundled_plugin_selectedr‰   …   s�   ú€ õ &ÜÔ>�iÓ>Ó>€GðØ×0Ñ0°Ó6×:Ñ:¸9ÓEˆô $ G¬T×2Ò2‰g¸€G÷nñ nñ �)Ó×7Ð7¡V¨JÓ%7Ô!7Ð7øô ô Ü�‰Ð:¸DÈ4ˆÔPÚðús   ¤ B Â#B,Â+B,c               ó$   € V ^8„  d   QhRRRRRR/# rZ   r   )r   s   "r   r   r   ˜   s!   € ÷ 6ñ 6˜$ð 6°ð 6Àñ 6r   c               ó   € \        V R4      # )z¾What made core trace to Langfuse for *home*: the bundled ``observability/langfuse`` selected
(:func:`_bundled_plugin_selected`). The plugin was opt-in, so keys in ``.env`` alone are not use.Úlangfuse)r‰   ©r   rX   s   &$r   Úlangfuse_in_userŽ   ˜   s   € ô $ D¨*Ó5Ð5r   c               ó$   € V ^8„  d   QhRRRRRR/# rZ   r   )r   s   "r   r   r   ž   s!   € ÷ /ñ /˜Tð /°4ð /ÀDñ /r   c               ó¼  € ^ RI Hp  VP                  V 4      P                  R4      p\        V\        4      '       d   TM/ p\        VP                  R4      ;'       g    VP                  R4      ;'       g    R	4      P                  4       pV'       g-   ^ R
IHp V! V 4      P                  RR	4      P                  4       pV'       gW   V'       dO   ^ RIHpHp V! V 4      V! V! 4       4      8X  d/   \         P"                  P                  RR	4      P                  4       pVP%                  4       R8H  #   \         d    \
        P                  RT RR7       Rp EL2i ; i)a/  What made core run its Singularity backend for *home*: ``terminal.backend`` (or the legacy
``terminal.env_type``) set to ``singularity`` in its config (managed overlay applied, as the bridge
reads it), else ``TERMINAL_ENV=singularity`` from its dotenv layers as ``load_hermes_dotenv`` resolves
them (the home's ``.env``, then the administrator-managed ``.env`` with override, ``${VAR}``
references expanded: :func:`~hermes_cli.env_loader.resolve_home_dotenv`). config.yaml wins over
both, as in the bridge. *process_env* (startup) also counts a ``TERMINAL_ENV`` the process received
from its environment (systemd unit, Docker, shell export), for the launch home only: ``TERMINAL_*``
is process-global (``get_secret`` never scopes it), so for any other served home it is the launch
profile's backend, not this one's.r+   Úterminalrv   Trw   NÚbackendÚenv_typer1   )Úresolve_home_dotenvÚTERMINAL_ENV)Úget_routing_process_hermes_homeÚhermes_home_keyÚsingularity)r.   r,   r4   r6   r"   r‡   rˆ   r#   r   r(   r:   Úhermes_cli.env_loaderr”   Úhermes_constantsr–   r—   ÚosÚenvironÚlower)r   rX   r,   r‘   Ú
configuredr”   r–   r—   s   &$      r   Úsingularity_in_userŸ   ž   s  € õ &ðØ ×1Ñ1°$Ó7×;Ñ;¸JÓGˆô & h´×5Ò5‰x¸2€HÜ�X—\‘\ )Ó,×NÐN°·±¸ZÓ0H×NÐNÈBÓO×UÑUÓW€JßÝ=Ù(¨Ó.×2Ñ2°>À2ÓF×LÑLÓNˆ
ßŸ+ßUÙ˜4Ó ¡OÑ4SÓ4UÓ$VÔVÜŸ™Ÿ™¨¸Ó;×AÑAÓCˆJØ×ÑÓ Ñ.Ð.øô ô Ü�‰Ð:¸DÈ4ˆÔPØ‹ðús   ˆ D2 Ä2%EÅEc               ó$   € V ^8„  d   QhRRRRRR/# rZ   r   )r   s   "r   r   r   º   s!   € ÷ 1ñ 1˜tð 1°Tð 1Àdñ 1r   c               ó0   € V R,          P                  4       # )a  *home* registered a ``hermes import-agent`` source for ``--sync`` (its ``import-sync.json``,
which scheduled syncs read). A one-shot import leaves no other trace, and installing the plugin
for every home would add a command nobody asked for; the old spelling names the install.zimport-sync.json)Úis_filer�   s   &$r   Úagent_imports_in_user£   º   s   € ð Ð%Õ%×.Ñ.Ó0Ð0r   T)Úfrozenc                  óö   € ] tR t^Át$ R]R&   R]R&   R]R&   R]R&   RtR]R&   RtR]R	&   RtR]R
&   RtR]R&   Rt	R]R&   Rt
R]R&   RtR]R&   RtR]R&   RtR]R&   RtR]R&   RtR]R&   RtR]R&   RtR]R&   RtR# )ÚLeftCoreFeaturer(   rp   ÚlabelzCallable[..., bool]Úin_useÚ	unchangedztuple[str, ...]Ú
secret_envÚprivate_envrF   Úoff_platformsr1   r>   Ú
enable_envÚchannel_env_prefixesÚcliÚcommandÚold_commandÚold_clir~   Úterminal_backendr   N)Ú__name__Ú
__module__Ú__qualname__Ú__firstlineno__Ú__annotations__rª   r«   rF   r¬   r>   r­   r®   r¯   r°   r±   r²   r~   r³   Ú__static_attributes__r   r   r   r¦   r¦   Á   s¨   ‡ àƒKØƒJØÓØƒNð #%€J�Ó$à#%€K�Ó%ð
 !#€HˆoÓ"à%'€M�?Ó'à€HˆcÓð
 #%€J�Ó$Ø,.Ð˜/Ó.ð €CˆƒMð €GˆSÓØ€K�Óð  "€Gˆ_Ó!ð €J�ÓàÐ�c×r   r¦   r_   zHome AssistantzRHASS_TOKEN/HASS_URL, platforms.homeassistant and the ha_* tool names are unchanged)rp   r§   r¨   r©   rª   r«   rF   r¬   r>   r­   r®   re   ÚSpotifyz‚your Spotify login, the spotify toolset and the spotify_* tools are unchanged; `hermes auth spotify` is now `hermes spotify login`)rp   r§   r¨   r©   r¯   rŒ   ÚLangfusezzyour Langfuse keys and HERMES_LANGFUSE_* settings are unchanged; the plugin is now `langfuse` (was observability/langfuse)zobservability/langfuse)rp   r§   r¨   r©   rª   r«   r~   z	mcp-servezHermes as an MCP serverc                ó   € R # )Fr   )r   Ú_s   &,r   Ú<lambda>r¾     s   € ÑV[r   zWthe conversation tools keep their names; MCP clients change their args to ["mcp-serve"]zhermes mcp serve)rp   r§   r¨   r©   r°   r±   r˜   z&Singularity/Apptainer terminal backendzterminal.backend: singularity, terminal.singularity_image (TERMINAL_SINGULARITY_IMAGE) and the container_* limits are unchanged)rp   r§   r¨   r©   r³   zagent-importersz`hermes import-agent`zU`hermes import-agent`, its flags and your import-sync.json sync sources are unchangedzimport-agent)rp   r§   r¨   r©   r°   r²   ztuple[LeftCoreFeature, ...]r†   c               ó    € V ^8„  d   QhRRRR/# )r   r€   r¦   r   r(   r   )r   s   "r   r   r     s   € ÷ Nñ N˜ð N°3ñ Nr   c                ó�   € ^ RI Hp V P                   RV P                   R\	        V P                  \        V! 4       4      4       R2# )r   ©Úget_hermes_homeú moved out of core into the 'z' plugin: install it with `Ú`)rš   rÂ   r§   rp   r
   r   )r€   rÂ   s   & r   Ú_install_sentencerÅ     sG   € Ý0Ø�}‰}ˆoÐ:¸7¿>¹>Ð:Jð KÜ  §¡´±oÓ6GÓ1HÓIÐJÈ!ðMð Nr   c               ó    € V ^8„  d   QhRRRR/# )r   r>   r(   r   r   )r   s   "r   r   r     s   € ÷ @ñ @ Cð @¨Cñ @r   c                óh   a € \        V 3R l\         4       R4      pV'       d   R\        V4       2# R# )z´For an unknown platform name that left core: the sentence that names its install command for
the active home, else ``""``. Appended to "unknown platform" errors (``send_message``).c              3  ót   <"  € T F-  qP                   '       g   K  VP                   S8X  g   K)  Vx € K/  	  R # 5irI   )r>   )rK   rs   r>   s   & €r   rM   Ú(platform_install_hint.<locals>.<genexpr>"  s$   øé € ÐR™y˜!¯J­J”A¸1¿:¹:ÈÑ;Q—A’A›yùó   ƒ8›8®
8Nú. r1   ©r…   r†   rÅ   )r>   r€   s   f r   Úplatform_install_hintrÍ     s3   ø€ ô ÔR�yÓRÐTXÓY€Gß07ˆRÔ! 'Ó*Ð+Ð,Ð?¸RÐ?r   c               ó    € V ^8„  d   QhRRRR/# )r   r’   r(   r   r   )r   s   "r   r   r   &  s   € ÷ @ñ @¨3ð @°3ñ @r   c                óh   a € \        V 3R l\         4       R4      pV'       d   R\        V4       2# R# )z­For a ``terminal.backend`` value that left core: the sentence that names its install command for
the active home, else ``""``. Appended to "unknown terminal backend" errors.c              3  ót   <"  € T F-  qP                   '       g   K  VP                   S8X  g   K)  Vx € K/  	  R # 5irI   )r³   )rK   rs   r’   s   & €r   rM   Ú0terminal_backend_install_hint.<locals>.<genexpr>)  s)   øé € Ða™y˜!×,>Õ,>”AÀ1×CUÑCUÐY`ÑC`—A’A›yùrÊ   NrË   r1   rÌ   )r’   r€   s   f r   Úterminal_backend_install_hintrÒ   &  s3   ø€ ô Ôa�yÓaÐcgÓh€Gß07ˆRÔ! 'Ó*Ð+Ð,Ð?¸RÐ?r   c               ó    € V ^8„  d   QhRRRR/# ©r   r'   r(   r   r   )r   s   "r   r   r   -  s   € ÷ \ñ \˜cð \ cñ \r   c                ó8   a € \        V 3R l\         4       R4      # )ztThe catalog plugin a bundled key that left core now names (``observability/langfuse`` ->
``langfuse``), else ``""``.c              3  óˆ   <"  € T F7  qP                   '       g   K  VP                   S8X  g   K)  VP                  x € K9  	  R # 5irI   ©r~   rp   ©rK   rs   r'   s   & €r   rM   Ú&legacy_plugin_alias.<locals>.<genexpr>0  s)   øé € ÐV¡9˜a·µ”ÀÇÁÐQUÑAU”�—–£9ùs   ƒA›A®Ar1   )r…   r†   )r'   s   fr   Úlegacy_plugin_aliasrÚ   -  s   ø€ ô ÔV¥9ÓVÐXZÓ[Ð[r   c               ó    € V ^8„  d   QhRRRR/# )r   rp   r(   r   úset[str]r   )r   s   "r   r   r   3  s   € ÷ Tñ T˜sð T xñ Tr   c                ó˜   € \          Uu0 uF5  qP                  '       g   K  VP                  V 8X  g   K)  VP                  kK7  	  up# u upi )zUBundled keys that now name catalog *plugin* (inverse of :func:`legacy_plugin_alias`).)r†   r~   rp   )rp   rs   s   & r   Úlegacy_plugin_keysrÞ   3  s1   € å"+ÓS¡)˜Q¯|­|ŒLÀÇÁÈFÑ@RŒLˆA�LŒL¡)ÑSÐSùÒSs   ‰A¡A´Ac               ó(   € V ^8„  d   QhRRRRRRRR/# )r   Úprogr(   ÚvalueÚactionr   r   )r   s   "r   r   r   8  s.   € ÷ fñ f˜Sð f¨ð f°cð fÀ3ñ fr   c                ó°  a a€ ^ RI Hp \        V! 4       4      p\        V V3R l\         4       R4      pVes   \        VP                  V4      pV'       d   RMR\        VP                  V4       R2pVP                   RVP                   RVP                   R	VP                   RV 2	# S R
8X  d   \        V3R l\         4       R4      pM$S R8X  d   \        V3R l\         4       R4      pMRpVf   R# \        VP                  V4      p	\        VP                  V4      '       g   RV	 R2pMS R8X  d   RV	P                  RR4       R2MRpS R
8X  dM   RP                  R R
VS3 4       4      p
VP                   RVP                   RT
 R	S RT;'       g    R RV 2# SVP                  9   d   RS R2MVP                  pV RVP                   RV 2# )aa  For a command a left-core plugin took over: ``hermes auth [<action>] <cli>`` (core's old login
spelling), core's old nested spelling (``hermes mcp serve``), or the plugin's own ``hermes <cli>`` /
``hermes <command>`` / ``hermes <old_cli>`` while the plugin is not loaded, the line saying where it
went and how to get it for the active home, else ``""``.rÁ   c              3  ó~   <"  € T F2  qP                   '       g   K  VP                   S R S 28X  g   K.  Vx € K4  	  R# 5i)Ú N)r±   )rK   rs   rà   rá   s   & €€r   rM   Ú%moved_command_hint.<locals>.<genexpr>?  s3   øé € Ð_™Y˜¯-­-”!¸A¿M¹MÐPTÈvÐUVÐW\ÐV]ÐM^Ñ<^—!’!›Yùs   ƒ=›=³
=Nr1   z Install it with: `ú`.rÃ   z' plugin: `z` is now `hermes zhermes authc              3  ót   <"  € T F-  qP                   '       g   K  VP                   S8X  g   K)  Vx € K/  	  R # 5irI   )r¯   ©rK   rs   rá   s   & €r   rM   ræ   F  s#   øé € ÐI¡9˜a·µœ¸!¿%¹%À5¹.Ÿš£9ùrÊ   Úhermesc              3  ó”   <"  € T F=  pS'       g   K  SVP                   VP                  .VP                  O59   g   K9  Vx € K?  	  R # 5irI   )r¯   r°   r²   ré   s   & €r   rM   ræ   H  s7   øé € Ðb¡9˜a´œ¸%ÀAÇEÁEÈ1Ï9É9ÐCaÐWX×W`ÑW`ÑCaÑ:aŸš£9ùs   ƒ
A’'A¾
Az Enable it with: `z	 install z enable rå   c              3  ó8   "  € T F  q'       g   K  Vx € K  	  R # 5irI   r   )rK   Úps   & r   rM   ræ   S  s   é € ÐFÑ"@˜QÃA—q’qÓ"@ùs   ‚	�
Úloginz`hermes rÄ   z' plugin, which is not loaded.)rš   rÂ   r   r…   r†   Úplugin_presentrp   r
   r§   r±   r°   ÚreplaceÚjoinr²   )rà   rá   râ   rÂ   r   ÚmovedÚpresentr6   r€   ÚinstallÚoldr§   s   ff&         r   Úmoved_command_hintrö   8  sá  ù€ õ
 1Ü‘Ó!Ó"€DÜÕ_�YÓ_ÐaeÓf€EØÒÜ  §¡¨tÓ4ˆß‰bÐ#6Ô7GÈÏÉÐVZÓ7[Ð6\Ð\^Ð!_ˆØ—;‘;�-Ð<¸U¿\¹\¸NÈ+ÐV[×VgÑVgÐUhð iØ Ÿ=™=˜/¨¨C¨5ð2ð 	3àˆ}ÔÜÔI¥9ÓIÈ4ÓP‰Ø	�Ô	ÜÔb¥9ÓbÐdhÓi‰àˆØ‚ÙÜ˜wŸ~™~¨tÓ4€GÜ˜'Ÿ.™.¨$×/Ò/Ø# G 9¨BÐ/‰àSWÐ[cÔScÐ" 7§?¡?°;À
Ó#KÐ"LÈBÑOÐikˆØˆ}ÔØ�h‰hÑF =°&¸%Ñ"@ÓFÓFˆØ—=‘=�/Ð!>¸w¿~¹~Ð>NÈkÐZ]ÐY^ð _Ø ˜'  6×#4Ð#4¨WÐ"5°R¸°uð>ð 	?à#(¨G¯O©OÔ#;ˆh�u�g˜QÑÀÇÁ€EØˆWÐ1°'·.±.Ð1AÐA_Ð`cÐ_dÐeÐer   c               ó    € V ^8„  d   QhRRRR/# rÔ   r   )r   s   "r   r   r   Z  s   € ÷ ?ñ ?˜Cð ? Cñ ?r   c                óh   a € \        V 3R l\         4       R4      pV'       d   \        V4       R2# R# )a  For a plugin name nothing resolves to (so the plugin is not installed): the bundled key of a
plugin that left core (``observability/langfuse``) or its catalog name, the line naming the install
command for the active home, else ``""``. Appended to "No plugin named ..." errors.c              3  óŒ   <"  € T F9  qP                   '       g   K  SVP                   VP                  39   g   K5  Vx € K;  	  R # 5irI   r×   rØ   s   & €r   rM   Ú$moved_plugin_hint.<locals>.<genexpr>^  s0   øé € Ð^™y˜!¯L­L”A¸TÀaÇlÁlÐTU×T\ÑT\ÐE]Ñ=]—A’A›yùs   ƒA›Aº
ANÚ.r1   rÌ   ©r'   r€   s   f r   Úmoved_plugin_hintrý   Z  s3   ø€ ô Ô^�yÓ^Ð`dÓe€Gß/6Ô Ó(Ð)¨Ð+Ð>¸BÐ>r   rÜ   Ú
_attemptedzdict[str, list[str]]Ú_undeliveredc               ó$   € V ^8„  d   QhRRRRRR/# )r   rp   r(   r   r   r   r)   r   )r   s   "r   r   r   f  s!   € ÷ 0ñ 0˜3ð 0 dð 0¨tñ 0r   c                ó>   € VR,          V ,          P                  4       # )zQInstalled in *home* (enabled or not: a user who disabled it chose to). Read-only.ru   )Úis_dir)rp   r   s   &&r   rï   rï   f  s   € à�9Õ˜vÕ%×-Ñ-Ó/Ð/r   c               ó$   € V ^8„  d   QhRRRRRR/# )r   r€   r¦   Ú	selectionrO   r   r)   r   )r   s   "r   r   r   k  s!   € ÷ 9ñ 9˜?ð 9°tð 9Àñ 9r   c                óŒ   a a€ R V 3R llo\         ;QJ d    V3R lV 4       F  '       g   K   R# 	  R# ! V3R lV 4       4      # )z±Whether core resolved *feature*'s toolsets on for a platform selecting *selection*: named
directly, or through a ``hermes`` / ``hermes-<platform>`` composite that included them.c               ó    € V ^8„  d   QhRRRR/# )r   r'   r(   r   r)   r   )r   s   "r   r   Ú#_core_carried.<locals>.__annotate__n  s   € ÷ sñ s�cð s˜dñ sr   c                óÀ   <€ V SP                   9   g   V R 8X  d   R# V P                  R4      ;'       d,    V \        R4      R P                  RR4      SP                  9  # )rê   Tzhermes-NÚ-r½   )rF   Ú
startswithÚlenrð   r¬   rü   s   &€r   ÚcarriesÚ_core_carried.<locals>.carriesn  sW   ø€ Ø�7×#Ñ#Ô# t¨xÔ'7ÙØ�‰˜yÓ)×rÐr¨d´3°y³>°?Ð.C×.KÑ.KÈCÐQTÓ.UÐ]d×]rÑ]rÑ.rÐrr   c              3  óF   <"  € T F  pS! \        V4      4      x € K  	  R # 5irI   rJ   )rK   r'   r  s   & €r   rM   Ú _core_carried.<locals>.<genexpr>r  s   øé € Ð8©i d‰w”s˜4“y×!Ð!«iùs   ƒ!TF)rP   )r€   r  r  s   f&@r   Ú_core_carriedr  k  s:   ù€ ÷sð s÷ ‹3Ô8©iÓ8�3Œ3Ð8Š3Ð8ˆ3Ô8©iÓ8Ó8Ð8r   Ú_left_core_scopedÚ_left_core_installedc               ó(   € V ^8„  d   QhRRRRRRRR/# )	r   rB   r   rz   r(   r€   r¦   r   r)   r   )r   s   "r   r   r   {  s.   € ÷ Gñ G�Dð G˜sð G¨_ð GÀñ Gr   c                óŽ   € V P                  V4      p\        V\        4      ;'       d    VP                  \	        \
        V4      9   # rI   )r6   r#   rO   rp   Úmapr(   ©rB   rz   r€   Údones   &&& r   Ú_markedr  {  s3   € Ø�:‰:�c‹?€DÜ�dœDÓ!×FÐF g§n¡n¼¼CÀ»Ñ&FÐFr   c               ó$   € V ^8„  d   QhRRRRRR/# )r   rB   r   r€   r¦   r   r)   r   )r   s   "r   r   r   €  s&   € ÷ Iñ I˜ð I ð I¸4ñ Ir   c                óV   € VP                   '       * ;'       g    \        V \        V4      # rI   )rF   r  Ú_SCOPED_KEY)rB   r€   s   &&r   Ú_scope_keptr  €  s"   € Ø×ÑÔ×HÐH¤7¨6´;ÀÓ#HÐHr   c               ó(   € V ^8„  d   QhRRRRRRRR/# )	r   rB   r   rz   r(   r€   r¦   r   ÚNoner   )r   s   "r   r   r   „  s.   € ÷ `ñ `�$ð `˜Sð `¨?ð `¸tñ `r   c                óª   € V P                  V4      p\        0 \        V\        4      '       d   \	        \
        V4      MRmVP                  k4      W&   R # )Nr   )r6   Úsortedr#   rO   r  r(   rp   r  s   &&& r   Ú_markr!  „  s>   € Ø�:‰:�c‹?€DÜÐ^¬j¸¼t×.DÒ.DœC¤ TœNÈ"Ð^ÈwÏ~É~Ð^Ó_€FƒKr   c               ó$   € V ^8„  d   QhRRRRRR/# )r   r   r   r€   r¦   r   r  r   )r   s   "r   r   r   ‰  s!   € ÷ '&ñ '&˜Dð '&¨?ð '&¸tñ '&r   c                óŒ  € ^ RI HpHp ^ RIHp V R,          pV! V4      p\        VP                  V 4      ;'       d    \        V\        V4      '       * p\        Wa4      '       d   V'       g   R# V'       d   \        V\        V4       \        Wa4      '       Eg˜   VP                  R4      p\        V\        4      '       d   TM/ pVP                  4        U	U
u/ uF  w  rš\        V	4      V! V
4      bK  	  pp	p
VP                    F  pVP#                  VR4       K  	  VP                  R4      p\        V\        4      '       d   TM/ pVP                  4        F¸  w  rÎVf   WÁP                   9  d   K  Ve   \%        W4      '       d   K2  \        VP                  V4      \&        4      '       d   VP                  V4      M. pVP(                   Uu. uF  pVV9  g   K  VNK  	  up;p'       g   K™  \+        0 \-        \        V4      mVm4      WÜ&   Kº  	  V'       d   WÖR&   \        V\.        V4       V! WV4       R# u up
p	i u upi )aé  Keep *feature*'s core-era toolset scope, and mark it installed once its plugin is in *home*,
in one config write.

Scope: record the toolsets in ``known_plugin_toolsets[platform]`` (= off) for every platform
where core had them off: a saved ``platform_toolsets`` list that does not carry them, or no list
on an ``off_platforms`` platform. Platforms core resolved them on for are left alone. A one-time
conversion per home and row, independent of installation: a plugin installed before the update
(it stays inert on a core that still ships the feature) still needs it. Completion is marked
under ``_left_core_scoped`` so a later run never undoes a choice the user made since
(``hermes tools``). Raises when config.yaml cannot be read or written.)Úatomic_config_writeÚread_user_config_raw)Úparse_platform_toolsets_valuer   NrE   Úknown_plugin_toolsets)Úhermes_cli.configr$  r%  Úhermes_cli.toolset_validationr&  rï   rp   r  Ú_INSTALLED_KEYr  r!  r6   r#   r   rS   r(   r¬   Ú
setdefaultr  rO   rF   r   r  r  )r   r€   r$  r%  r&  ÚpathrB   Ú	installedÚsavedrí   ÚvrV   r>   Úknownr  ÚcurrentÚtsÚmissings   &&                r   Ú_record_migrationr4  ‰  sÚ  € ÷ LÝKØ�-Õ€DÙ! $Ó'€FÜ˜wŸ~™~¨tÓ4×eÐe¼WÀVÌ^Ð]dÓ=eÔ9e€IÜ�6×#Ò#¯IÙßÜˆf”n gÔ.Ü�v×'Ó'Ø—
‘
Ð.Ó/ˆÜ# E¬4×0Ò0‘°bˆØKPÏ;É;Ì=ÔYÉ=Á4À1”c˜!“fÑ;¸AÓ>Ò>É=ˆ
ÑYØ×-Ô-ˆHØ×!Ñ! (¨DÖ1ñ .à—
‘
Ð2Ó3ˆÜ# E¬4×0Ò0‘°bˆØ#-×#3Ñ#3Ö#5ÑˆHØÒ  X×5JÑ5JÔ%JÙØÒ$¬°w×)JÒ)JÙÜ-7¸¿	¹	À(Ó8KÌT×-RÒ-R�e—i‘i Ô)ÐXZˆGØ(/×(8Ò(8ÓNÑ(8 "¸BÀgÑ<MŸ2˜2Ñ(8ÑNÐNˆw×NÐNÜ"(Ð)G¬3¬s°GÓ+<Ð)G¸wÐ)GÓ"H�“ñ $6÷ Ø.3Ð*Ñ+Üˆf”k 7Ô+Ù˜Ö%ùó! Zùò Os   ÃH;Ç	IÇIÚbackoffc          
     ó,   € V ^8„  d   QhRRRRRRRRRR	/# )
r   r   r   ÚsayúCallable[[str], None]rX   r)   r5  r   zlist[LeftCoreFeature]r   )r   s   "r   r   r   ³  s2   € ÷ #ñ #�4ð #Ð!6ð #ÀTð #Øð#Ø'<ñ#r   c               óP  € ^ RI Hp . p\         EF)  p\        \	        V 4      \
        V4      '       d   K&  VP                  WR7      '       g   K@  \        VP                  V 4      p \        W4       T'       d   Kl  T'       d?   \        YP                  4      '       d$   \        P                  RTP                  T 4       K²  T! TP                  4      fS   \!        YP                  4       T! RTP                   RTP                   R\        TP                  T 4       R24       EK  TP#                  T4       EK,  	  V#   \         d\   pT! RTP                   RTP                   RT R2T'       d   RMR\        TP                  T 4       R	2,           4        R
p?EK‘  R
p?ii ; i)a²  Rows *home* uses whose plugin it never had and that the catalog ships (a catalog miss is
reported through *say*). Converts the toolset scope of every row *home* uses once
(:func:`_record_migration`), installed or not; a row whose scope cannot be recorded is
reported and skipped, never installed unscoped. A row marked installed is done for good.
*backoff* (startup) skips a row whose last attempt failed recently, before any network.)Úcatalog_source)rX   õ     âš  rÃ   z@' plugin: its per-platform toolset selection could not be kept (z). Check `hermes tools`rû   z
 and run `rç   NzN%s plugin install failed recently for %s; retrying later or on `hermes update`zH' plugin, which this Hermes cannot find in the plugin catalog yet. Run `z` once it is listed.)Ú$hermes_cli.memory_provider_migrationr:  r†   r  r%   r*  r¨   rï   rp   r4  r"   r§   r
   r   r‡   Úinfor   rT   )	r   r7  rX   r5  r:  Úoutr€   ró   Úexcs	   &$$$     r   Ú_pendingr@  ³  s}  € õ DØ
€Cß�9ˆÜ”< Ó%¤~°w×?Ò?ÙØ�~‰~˜dˆ~×<Ò<ÙÜ  §¡°Ó6ˆð	Ü˜dÔ,÷ ÙßÔ'¨¯n©n×=Ò=Ü�K‰KÐhØŸ™ tô-áÙ˜'Ÿ.™.Ó)Ò1Ü˜$§¡Ô/Ù�&˜Ÿ™˜Ð'DÀWÇ^Á^ÐDTð UFÜFVÐW^×WeÑWeÐgkÓFlÐEmð n%ð&ô 'ò Ø�
‰
�7×ñ3 ð4 €Jøô% ô 	Ù�&˜Ÿ™˜Ð'DÀWÇ^Á^ÐDTð U8Ø8;°uÐ<SðUç!‘3¨Ô4DÀWÇ^Á^ÐUYÓ4ZÐ3[Ð[]Ð'^õ`ô aö ûð		ús   Á&D?Ä?F%Å
AF Æ F%Úconsentc               ó$   € V ^8„  d   QhRRRRRR/# )r   r   r   rA  zOptional[bool]r   úCallable[[str], dict]r   )r   s   "r   r   r   Ù  s"   € ÷ ñ ˜ð ¨.ð ÐDYñ r   c               ó   a a€ R  VV 3R llpV# )c               ó    € V ^8„  d   QhRRRR/# )r   r'   r(   r   r   r   )r   s   "r   r   Ú#_install_into.<locals>.__annotate__Ú  s   € ÷ 	.ñ 	.�sð 	.˜tñ 	.r   c                ó’   <€ ^ RI Hp ^ RIHpHp V! S4      p T! RRRT Sf   \        4       MSR7      V! V4       #   T! T4       i ; i)r   )Údashboard_install_plugin)Úreset_hermes_home_overrideÚset_hermes_home_overrider1   FT)ÚforceÚenableÚcatalog_nameÚassume_deps_consent)Úhermes_cli.plugins_cmdrH  rš   rI  rJ  r   )r'   rH  rI  rJ  r9   rA  r   s   &    €€r   Ú_installÚ_install_into.<locals>._installÚ  sL   ø€ ÝCßYÙ(¨Ó.ˆð	.Ù+¨B°eÀDÐW[ØY`ÒYhÔ@SÔ@UØ18ô:ñ ' uÕ-øÑ& uÕ-ús	   ™< ¼
Ar   )r   rA  rP  s   fd r   Ú_install_intorR  Ù  s   ù€ ÷	.ñ 	.ð €Or   c               ó    € V ^8„  d   QhRRRR/# )r   Úerrorr(   r   r   )r   s   "r   r   r   ç  s   € ÷ Lñ L˜ð L ñ Lr   c                ó0  € V P                  4        Uu. uF*  qP                  4       '       g   K  VP                  4       NK,  	  pp\        R V 4       R4      pT;'       g#    V'       d   V^ ,          P                  R4      # RP                  R4      # u upi )z”One line for a notice: git's own ``fatal:`` / ``error:`` line when *error* ends with raw git
stderr (a failed clone), else its first non-empty line.c              3  ó    "  € T FD  qP                  R4      '       g   K  VP                  R^4      ^,          P                  4       x € KF  	  R# 5i)úfatal:Ú:N)rW  zerror:)r
  Úsplitr:   )rK   Úlines   & r   rM   Ú_first_cause.<locals>.<genexpr>ë  s9   é € Ðk¹E°DÇ_Á_ÐUi×EjÔ/�$—*‘*˜S !Ó$ QÕ'×-Ñ-×/Ð/»Eùs
   ‚AŸ/ANzunknown errorrË   )Ú
splitlinesr:   r…   Úrstrip)rT  rZ  ÚlinesÚcauses   &   r   Ú_first_causer`  ç  sy   € ð ',×&6Ñ&6Ô&8ÓIÑ&8˜d¿J¹J¿LŒ\ˆT�Z‰ZŽ\Ñ&8€EÐIÜÑk¹EÓkÐmqÓr€EØ×=Ð=§%�e˜A•h×EÑEÀdÓKÐK¨_×EÑEÀdÓKÐKùò Js
   “B¯Bc          
     ó,   € V ^8„  d   QhRRRRRRRRR	R
/# )r   r   r   r€   r¦   rô   rC  r7  r8  r   r)   r   )r   s   "r   r   r   ï  s2   € ÷ ñ �tð  oð ÐCXð Ø+ðØ04ñr   c               ó€  €  V! VP                   4      pVP                  R 4      '       d?    \	        W4       V! RVP                   RVP                    RVP                   R24       R	# \        WP                   4       \        \        VP                  R4      ;'       g    R
4      4      pV! RVP                   RVP                    RV R\        VP                   V 4       R2	4       R#   \         d   pR RR\        T4      /p Rp?LõRp?ii ; i  \         d"   p\
        P                  RY4        Rp?ELRp?ii ; i)ÚokFrT  Nz/left-core install marker not written for %s: %su     âœ“ u&    moved out of core â€” installed the 'z' plugin from the catalog (z).Tr1   r;  ú moved out of core and its 'z/' plugin could not be installed automatically: z. Run `rç   )rp   r"   r(   r6   r4  r‡   rˆ   r§   r©   r   r`  r
   )r   r€   rô   r7  Úresultr?  rT  s   &&$$   r   Ú_install_onerf  ï  s-  € ð2Ù˜Ÿ™Ó(ˆð ‡z�z�$×Òð	WÜ˜dÔ,ñ 	ˆf�W—]‘]�OÐ#IÈ'Ï.É.ÐIYð ZØ×)Ñ)Ð*¨"ð.ô 	/áÜ�$Ÿ™Ô'Üœ˜VŸZ™Z¨Ó0×6Ð6°BÓ7Ó8€EÙˆ&�—‘�Ð;¸G¿N¹NÐ;Kð LØ˜ Ô(8¸¿¹ÈÓ(NÐ'OÈrð	Sô Táøô ô 2Ø˜˜w¬¨C«Ð1�ûð2ûô
 ô 	WÜ�L‰LÐJÈD×VÒVûð	Wús.   ‚C* ¬D Ã*DÃ5D	Ä	DÄD=ÄD8Ä8D=r7  c          
     ó,   € V ^8„  d   QhRRRRRRRRR	R
/# )r   r   r   rô   rC  r7  r8  rX   r)   r   ú	list[str]r   )r   s   "r   r   r     s3   € ÷ ñ �tð Ð)>ð ÐEZð Ø"ðØ/8ñr   c               ó’   € . p\        WVR7       F3  p\        WWR7      '       g   K  VP                  VP                  4       K5  	  V# )zcInstall every left-core plugin *home* uses and lacks. Returns installed plugin names; never raises.)r7  rX   ©rô   r7  )r@  rf  rT   rp   )r   rô   r7  rX   r-  r€   s   &$$$  r   Úmigrate_homerk    sB   € ð €IÜ˜D°{×CˆÜ˜¨w×@Õ@Ø×Ñ˜WŸ^™^Ö,ñ Dð Ðr   c               ó    € V ^8„  d   QhRRRR/# )r   r7  r8  r   rh  r   )r   s   "r   r   r     s   € ÷ *ñ *Ð3ð *À	ñ *r   c                ó’  a a€ ^ RI Hp ^ RIHp R V 3R llp/ pV! 4        Fs  p \	        WS! V4      R7      p\        V4      ;'       d    \        V4      pT F9  oTP                  SP                  T3S. 34      ^,          P                  T4       K;  	  Ku  	  . p	 VP                  4        EF8  w  op
\        V
4      ^8”  dL   \        4       '       d<   S ! RSP                    R	\        V
4       R
RP#                  R V
 4       4       R24       V! 4       ;_uu_ 4        \%        V
4       F¯  w  rµ\'        VS\)        V4      V! V4      R7      '       d   V	P                  SP                  4       KF  W«^,           R pV'       dW   S ! RSP                   RRP#                  R V 4       4       R2RP#                  V3R lV 4       4      ,           R,           4        M	  RRR4       EK;  	  V	#   \         d#   p\        P                  RYX4        Rp?EKñ  Rp?ii ; i  + '       g   i     EK�  ; i  \*         d    S ! R4        T	# i ; i)a  ``hermes update`` hook: every profile home sharing this venv. Grouped by plugin and each home's
unattended consent like the memory migration: homes of one group share dependency answers, and a
failure names the rest of its group in one line instead of failing them one by one.)Úshared_dependency_answers)Údependency_homesc               ó    € V ^8„  d   QhRRRR/# )r   r   r   r   r8  r   )r   s   "r   r   Ú'migrate_all_homes.<locals>.__annotate__  s   € ÷ Rñ R�tð RÐ 5ñ Rr   c                ó   <a € V V3R  l# )c                óN   <€ S! R \        S4       RV P                  4        24      # )z  [z] )r	   Úlstrip)Úmessager   r7  s   &€€r   r¾   Ú5migrate_all_homes.<locals>.labelled.<locals>.<lambda>  s%   ø€ ™s S¬°TÓ):Ð(;¸2¸g¿n¹nÓ>NÐ=OÐ#PÔQr   r   )r   r7  s   f€r   ÚlabelledÚ#migrate_all_homes.<locals>.labelled  s	   ù€ ÝQÐQr   ©r7  z&left-core migration skipped for %s: %sNz  z is used in z profiles (z, c              3  ó8   "  € T F  p\        V4      x € K  	  R # 5irI   ©r	   ©rK   Úhs   & r   rM   Ú$migrate_all_homes.<locals>.<genexpr>(  s   é € Ð!@¹%°Q¤+¨a§. .»%ùó   ‚zA); your answers to its dependency questions apply to all of them.rj  u     âš  The 'z' plugin was not installed for c              3  ó8   "  € T F  p\        V4      x € K  	  R # 5irI   r{  r|  s   & r   rM   r~  2  s   é € Ð(FÁ¸A¬°Q¯¨Ãùr  z either. Run c              3  óX   <"  € T F  pR \        SP                  V4       R 2x € K!  	  R# 5i)rÄ   N)r
   rp   )rK   r}  r€   s   & €r   rM   r~  3  s+   øé € Ð'aÑ\`ÐWX¨!Ô,<¸W¿^¹^ÈQÓ,OÐ+PÐPQÕ(RÓ\`ùs   ƒ'*rû   u–     âš  Plugin migration cancelled. Profiles already migrated keep their plugin; run `hermes plugins install <name>` (with `-p <profile>`) for the rest.)Úhermes_cli.plugins_cmd_installrn  Úpm.plugins_statero  r@  r)   r   r"   r‡   rˆ   r+  rp   rT   Úvaluesr  r   r§   rñ   Ú	enumeraterf  rR  ÚKeyboardInterrupt)r7  rn  ro  rw  Úpendingr   ÚfeaturesrA  r?  r-  ÚhomesÚindexÚrestr€   s   d            @r   Úmigrate_all_homesrŒ    s)  ù€ õ IÝ1÷Rð Rð KM€GÙ Ö"ˆð	Ü ¨(°4«.Ô9ˆHÜ˜8“n×<Ð<¬°tÓ)<ˆGó  ˆGØ×Ñ §¡°Ð8¸7ÀB¸-ÓHÈÕK×RÑRÐSWÖXó  ñ #ð €IðSØ%Ÿn™n×.‰NˆG�UÜ�5‹z˜AŒ~¤,§.¢.Ù�b˜Ÿ™˜ |´C¸³J°<ð @ØŸ	™	Ñ!@¹%Ó!@Ó@ÐAð B6ð7ô 8ñ +×,Õ,Ü#,¨UÖ#3‘K�EÜ# D¨'¼=ÈÓ;NÑT\Ð]aÓTb×cÓcØ!×(Ñ(¨¯©Ô8Ù Ø ¨¥ Ð,�DßÙ˜k¨'¯.©.Ð)9Ð9XØ#Ÿy™yÑ(FÁÓ(FÓFÐGÀ}ðVà"Ÿi™iÔ'aÑ\`Ó'aÓaõbàdgõhô iñ ñ $4÷ -Ò,ñ /ð& Ðøô7 ô 	Ü�L‰LÐAÀ4ÔMÞûð	ú÷ -×,Ñ,ûô ô SÙð Rõ 	SàÐðSúsC   ¥0G*ÂBH/ ÄB?HÇH/ Ç*HÇ5HÈHÈH,È%
H/ È/IÉIc               ó    € V ^8„  d   QhRRRR/# )r   r   r   r   r)   r   )r   s   "r   r   r   ;  s   € ÷ ñ ˜$ð  4ñ r   c                ó\   €  ^ RI Hp V! V RR7      P                  #   \         d     R# i ; i)zVA live gateway serves *home*: it loaded its platforms before this agent-start install.)Úresolve_gateway_livenessF)Úprofile_dirÚ	use_cache)Úgateway.statusr�  Úrunningr"   )r   r�  s   & r   Ú_gateway_servesr”  ;  s/   € ðÝ;Ù'°DÀEÔJ×RÑRÐRøÜô Úðús   ‚ œ+ª+c               ó    € V ^8„  d   QhRRRR/# )r   r7  zOptional[Callable[[str], None]]r   rh  r   )r   s   "r   r   r   D  s   € ÷ ;ñ ;Ð>ð ;È)ñ ;r   c                ó„  a aa€ ^ RI Hp V! 4       e   . # ^ RIHpHp \        V! 4       4      pV! V4      oR VV 3R lloS e&   \        P                  S. 4       F  pS! V4       K  	  S\        9   d   . # \        P                  S4       R V3R llp \        WFRRR	7      pV'       g   . # ^ R
IHp V! 4       '       gF   V F=  p	V! RV	P                   RV	P                   R\        V	P                  V4       R24       K?  	  . # . p
V F‚  p	\!        WI\#        VRR7      VR7      '       g   K$  V
P%                  V	P                  4       S f   KE  V	P&                  '       g   KY  \)        V4      '       g   Kl  V! RV	P                   R24       K„  	  V
#   \*         d%   p\,        P/                  RTRR7       . u Rp?# Rp?ii ; i)a:  Agent/gateway start hook for the active home: one attempt per process per home. With *say*
(an agent's startup-warning sink) outcomes are delivered now, together with any a gateway-start
attempt queued for this home; without it they are logged and queued for the home's first agent.
Returns installed plugin names.)Úworker_config_snapshotN)rÂ   r—   c               ó    € V ^8„  d   QhRRRR/# ©r   ru  r(   r   r  r   )r   s   "r   r   Ú(recover_at_startup.<locals>.__annotate__S  s   € ÷ Sñ S˜ð S ñ Sr   c                óÂ   <€ Sf(   \         P                  S. 4      P                  V 4       R #  S! V 4       R #   \         d    \        P                  RRR7        R # i ; i)Nz'left-core migration notification failedTrw   )rÿ   r+  rT   r"   r‡   rˆ   )ru  rz   r7  s   &€€r   ÚdeliverÚ#recover_at_startup.<locals>.deliverS  sU   ø€ ØŠ;Ü×#Ñ# C¨Ó,×3Ñ3°GÔ<Ùð	SÙ�ŽLøÜô 	SÜ�L‰LÐBÈTˆL×Rð	Sús   ®8 ¸"AÁAc               ó    € V ^8„  d   QhRRRR/# r™  r   )r   s   "r   r   rš  c  s   € ÷ ñ ˜ð  ñ r   c                ób   <€ V P                  4       p \        P                  V 4       S! V 4       R # rI   )r:   r‡   Úwarning)ru  rœ  s   &€r   ÚreportÚ"recover_at_startup.<locals>.reportc  s"   ø€ Ø—-‘-“/ˆÜ�‰�wÔÙ�Ör   T)r7  rX   r5  )Úlazy_installs_allowedu   âš  rd  zo' plugin is not installed, so it is off. security.allow_lazy_installs is off, so Hermes did not fetch it: run `rç   )rA  rj  z<Restart the gateway (`hermes gateway restart`) so it serves rû   z%left-core plugin migration failed: %srw   )Úagent.safe_worker_policyr—  rš   rÂ   r—   r   rÿ   Úpoprþ   Úaddr@  Ú
pm.installr£  r§   rp   r
   rf  rR  rT   r>   r”  r"   r‡   r   )r7  r—  rÂ   r—   r   ru  r¡  rˆ  r£  r€   r-  r?  rœ  rz   s   d           @@r   Úrecover_at_startupr¨  D  sž  ú€ õ
 @ÙÓÒ+ð ˆ	ßAä‘Ó!Ó"€DÙ
˜$Ó
€C÷Sñ Sð ‚Ü#×'Ñ'¨¨RÖ0ˆGÙ�GÖñ 1à
ŒjÔØˆ	Ü‡N�N�3Ô÷ð ð
Ü˜D¸$ÈÔMˆßØˆIÝ4Ù$×&Ò&Û#�Ù˜˜gŸm™m˜_Ð,HÈÏÉÐHXð Y)ä)9¸'¿.¹.È$Ó)OÐ(PÐPRðTö Uñ $ð ˆIØˆ	ó  ˆGÜ˜D´=ÀÈtÔ3TÐZ`×aÕaØ× Ñ  §¡Ô0Ø”? w×'7×'7Ò'7¼OÈD×<QÔ<QÙÐYÐZa×ZgÑZgÐYhÐhiÐjÖkñ	  ð
 ÐøÜô Ü�‰Ð>ÀÈdˆÔSØ�	ûðúsI   ÂF Â,F Â?AF Ä#F Ä,F ÅF Å!F Å4F ÆF?ÆF:Æ4F?Æ:F?c               ó    € V ^8„  d   QhRRRR/# )r   r'   zOptional[str]r   r  r   )r   s   "r   r   r   ‚  s   € ÷ 
Pñ 
P˜mð 
P°ñ 
Pr   c                óè   a a€ ^ RI Hp \        V! 4       4      o\        ;QJ d$    VV 3R l\         4       F  '       g   K   RM	  RM! VV 3R l\         4       4      '       d   \        R R7       R# R# )aÀ  ``hermes <name>`` names a command a left-core plugin registers, and the active home uses that
feature but lacks the plugin: run :func:`recover_at_startup` now, before plugin commands are
discovered, so the command it installs runs in this same invocation. A home nothing migrated yet
(a Docker image swap runs no ``hermes update``) whose only Hermes process is a scheduled
``hermes import-agent --sync`` never starts an agent or a gateway to do it.rÁ   c              3  ó   <"  € T Fs  pS;'       de    SVP                   VP                  .VP                  O59   ;'       d5    \        VP                  S4      '       * ;'       d    VP                  S4      x € Ku  	  R # 5irI   )r¯   r°   r²   rï   rp   r¨   )rK   rs   r   r'   s   & €€r   rM   Ú&recover_for_command.<locals>.<genexpr>Š  sw   øé € ð 2Ù'0 !ð ÷ ð �D˜QŸU™U A§I¡IÐ:°·	±	Ñ:Ñ:÷ ð Ä>ÐRS×RZÑRZÐ\`ÓCaÔ?a÷ ð Ø�x‰x˜‹~ôÛ'0ùs   ƒA>‘/A>Á"A>Á$A>TFc                ó8   € \        V \        P                  R 7      # ))Úfile)ÚprintÚsysÚstderr)ru  s   &r   r¾   Ú%recover_for_command.<locals>.<lambda>Œ  s   € ¬u°WÄ3Ç:Á:Õ/Nr   ry  N)rš   rÂ   r   rP   r†   r¨  )r'   rÂ   r   s   f @r   Úrecover_for_commandr³  ‚  sR   ù€ õ 1Ü‘Ó!Ó"€Dß
ƒsõ 2Ý'0ó2‡s‡s‚sõ 2Ý'0ó2÷ 2ò 2äÑN×Oñ2r   )r]   )ÚHASS_URL)r_   )ÚacpÚwebhook)ÚHASS_)ÚHERMES_LANGFUSE_SECRET_KEY)ÚHERMES_LANGFUSE_PUBLIC_KEYÚHERMES_LANGFUSE_BASE_URL)Úclaw)r1   )BÚ__conditional_annotations__Ú__doc__Ú
__future__r   Úloggingr›   r°  Údataclassesr   Úpathlibr   Útypingr   r   r<  r   r   r	   r
   r   r   r   Ú	getLoggerr´   r‡   ÚLEFT_CORE_TERMINAL_KEYSr%   r?   rW   ra   rn   r‰   rŽ   rŸ   r£   r¦   r†   r¸   rÅ   rÍ   rÒ   rÚ   rÞ   rö   rý   Úsetrþ   rÿ   rï   r  r  r*  r  r  r!  r4  r@  rR  r`  rf  r¯  rk  rŒ  r”  r¨  r³  )r¼  s   @r   Ú<module>rÆ     so  øðôõ4 #ã Û 	Û 
Ý !Ý ß %÷÷ ñ ð
 
×	Ò	˜8Ó	$€ð 8Ð9UÐVÐ õ2õdð.
hÐPR÷ 
hðp¸E÷ pð,G°e÷ Gõ 8ð&6°u÷ 6ð/¸%÷ /ð81¸E÷ 1ñ �$Ô÷*ð *ó ð*ñ\ ØÐ&6Ð?SØfØ"°Ø#Ð3EÐP_Ø"¸ôñ Ø 	°.ðHàô	ñ Ø °Oð<à2ØNØ+ôñ ð Ð";ÑD[ØmØÐ);ôñ ØÐ$LÐUgð=à&ô	ñ Ø Ð(?ÐH\ØiØ¨	ôðG(*€	Ð&ó (õTNõ@õ@õ\õT÷
fõD?ñ “u€
ˆHÓ Ø%'€Ð"Ó 'õ0õ
9ð "€ð (€õGõ
Iõ`õ
'&ðT#ÈEð #Ø"÷#ðL¸4÷ õLõð*Ð]bð Ø%*÷ð*°e÷ *õZð;À÷ ;÷|
Pr   